forked from zelo72/mastodon-ios
feat: [WIP] add account list for multiple account switch
This commit is contained in:
parent
7a089831cd
commit
66af30da2a
|
@ -415,6 +415,9 @@
|
||||||
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C3725E508BE0051B173 /* Attachment.swift */; };
|
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C3725E508BE0051B173 /* Attachment.swift */; };
|
||||||
DB9D7C21269824B80054B3DF /* APIService+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D7C20269824B80054B3DF /* APIService+Filter.swift */; };
|
DB9D7C21269824B80054B3DF /* APIService+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D7C20269824B80054B3DF /* APIService+Filter.swift */; };
|
||||||
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; };
|
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; };
|
||||||
|
DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */; };
|
||||||
|
DB9F58EF26EF491E00E7BBE9 /* AccountListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */; };
|
||||||
|
DB9F58F126EF512300E7BBE9 /* AccountListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */; };
|
||||||
DBA088DF26958164003EB4B2 /* UserFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */; };
|
DBA088DF26958164003EB4B2 /* UserFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */; };
|
||||||
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; };
|
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; };
|
||||||
DBA1DB80268F84F80052DB59 /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA1DB7F268F84F80052DB59 /* NotificationType.swift */; };
|
DBA1DB80268F84F80052DB59 /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA1DB7F268F84F80052DB59 /* NotificationType.swift */; };
|
||||||
|
@ -1184,6 +1187,9 @@
|
||||||
DB9D6C3725E508BE0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
DB9D6C3725E508BE0051B173 /* Attachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Attachment.swift; sourceTree = "<group>"; };
|
||||||
DB9D7C20269824B80054B3DF /* APIService+Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Filter.swift"; sourceTree = "<group>"; };
|
DB9D7C20269824B80054B3DF /* APIService+Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Filter.swift"; sourceTree = "<group>"; };
|
||||||
DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterpolatingMotionEffect.swift; sourceTree = "<group>"; };
|
DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterpolatingMotionEffect.swift; sourceTree = "<group>"; };
|
||||||
|
DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = "<group>"; };
|
||||||
|
DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountListTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFetchedResultsController.swift; sourceTree = "<group>"; };
|
DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFetchedResultsController.swift; sourceTree = "<group>"; };
|
||||||
DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = "<group>"; };
|
DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = "<group>"; };
|
||||||
DBA1DB7F268F84F80052DB59 /* NotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationType.swift; sourceTree = "<group>"; };
|
DBA1DB7F268F84F80052DB59 /* NotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationType.swift; sourceTree = "<group>"; };
|
||||||
|
@ -2601,6 +2607,7 @@
|
||||||
DB6180E426391A500018D199 /* Transition */,
|
DB6180E426391A500018D199 /* Transition */,
|
||||||
DB8AF54E25C13703002E6C99 /* MainTab */,
|
DB8AF54E25C13703002E6C99 /* MainTab */,
|
||||||
DB01409B25C40BB600F9F3CF /* Onboarding */,
|
DB01409B25C40BB600F9F3CF /* Onboarding */,
|
||||||
|
DB9F58ED26EF435800E7BBE9 /* Account */,
|
||||||
2D38F1D325CD463600561493 /* HomeTimeline */,
|
2D38F1D325CD463600561493 /* HomeTimeline */,
|
||||||
2D76316325C14BAC00929FB9 /* PublicTimeline */,
|
2D76316325C14BAC00929FB9 /* PublicTimeline */,
|
||||||
5B24BBD6262DB14800A9381B /* Report */,
|
5B24BBD6262DB14800A9381B /* Report */,
|
||||||
|
@ -2775,6 +2782,16 @@
|
||||||
path = ViewModel;
|
path = ViewModel;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
DB9F58ED26EF435800E7BBE9 /* Account */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */,
|
||||||
|
DB9F58EE26EF491E00E7BBE9 /* AccountListViewModel.swift */,
|
||||||
|
DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */,
|
||||||
|
);
|
||||||
|
path = Account;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
DBA5E7A6263BD298004598BB /* ContextMenu */ = {
|
DBA5E7A6263BD298004598BB /* ContextMenu */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -3960,6 +3977,7 @@
|
||||||
2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */,
|
2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */,
|
||||||
DB4F096C269EFA2000D62E92 /* SearchResultViewController+StatusProvider.swift in Sources */,
|
DB4F096C269EFA2000D62E92 /* SearchResultViewController+StatusProvider.swift in Sources */,
|
||||||
DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */,
|
DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */,
|
||||||
|
DB9F58EF26EF491E00E7BBE9 /* AccountListViewModel.swift in Sources */,
|
||||||
DB6D9F7D26358ED4008423CD /* SettingsSection.swift in Sources */,
|
DB6D9F7D26358ED4008423CD /* SettingsSection.swift in Sources */,
|
||||||
DB0E91EA26A9675100BD2ACC /* MetaLabel.swift in Sources */,
|
DB0E91EA26A9675100BD2ACC /* MetaLabel.swift in Sources */,
|
||||||
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */,
|
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */,
|
||||||
|
@ -4017,6 +4035,7 @@
|
||||||
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */,
|
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */,
|
||||||
DB482A45261335BA008AE74C /* UserTimelineViewController+Provider.swift in Sources */,
|
DB482A45261335BA008AE74C /* UserTimelineViewController+Provider.swift in Sources */,
|
||||||
2D206B8625F5FB0900143C56 /* Double.swift in Sources */,
|
2D206B8625F5FB0900143C56 /* Double.swift in Sources */,
|
||||||
|
DB9F58F126EF512300E7BBE9 /* AccountListTableViewCell.swift in Sources */,
|
||||||
2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */,
|
2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */,
|
||||||
DB35FC252612FD7A006193C9 /* ProfileFieldView.swift in Sources */,
|
DB35FC252612FD7A006193C9 /* ProfileFieldView.swift in Sources */,
|
||||||
DB938F0326240EA300E5B6C1 /* CachedThreadViewModel.swift in Sources */,
|
DB938F0326240EA300E5B6C1 /* CachedThreadViewModel.swift in Sources */,
|
||||||
|
@ -4105,6 +4124,7 @@
|
||||||
2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */,
|
2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */,
|
||||||
DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */,
|
DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */,
|
||||||
DBB525302611EBF3002F1F29 /* ProfilePagingViewModel.swift in Sources */,
|
DBB525302611EBF3002F1F29 /* ProfilePagingViewModel.swift in Sources */,
|
||||||
|
DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */,
|
||||||
DBCBCC0B2680B03F000F5B51 /* AsyncHomeTimelineViewModel+LoadOldestState.swift in Sources */,
|
DBCBCC0B2680B03F000F5B51 /* AsyncHomeTimelineViewModel+LoadOldestState.swift in Sources */,
|
||||||
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */,
|
2D5A3D6225CFD9CB002347D6 /* HomeTimelineViewController+DebugAction.swift in Sources */,
|
||||||
DB49A62525FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift in Sources */,
|
DB49A62525FF334C00B98345 /* EmojiService+CustomEmojiViewModel+LoadState.swift in Sources */,
|
||||||
|
|
|
@ -7,17 +7,17 @@
|
||||||
<key>AppShared.xcscheme_^#shared#^_</key>
|
<key>AppShared.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>60</integer>
|
<integer>24</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>62</integer>
|
<integer>23</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
|
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>11</integer>
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Mastodon - RTL.xcscheme_^#shared#^_</key>
|
<key>Mastodon - RTL.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
<key>Mastodon - Release.xcscheme_^#shared#^_</key>
|
<key>Mastodon - Release.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>10</integer>
|
<integer>1</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>Mastodon - ar.xcscheme_^#shared#^_</key>
|
<key>Mastodon - ar.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -97,7 +97,7 @@
|
||||||
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
<key>MastodonIntent.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>56</integer>
|
<integer>25</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
<key>MastodonIntents.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
@ -112,12 +112,12 @@
|
||||||
<key>NotificationService.xcscheme_^#shared#^_</key>
|
<key>NotificationService.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>13</integer>
|
<integer>3</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>58</integer>
|
<integer>22</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
|
|
|
@ -141,8 +141,8 @@
|
||||||
"repositoryURL": "https://github.com/apple/swift-collections.git",
|
"repositoryURL": "https://github.com/apple/swift-collections.git",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "0959ba76a1d4a98fd11163aa83fd49c25b93bfae",
|
"revision": "9d8719c8bebdc79740b6969c912ac706eb721d7a",
|
||||||
"version": "0.0.5"
|
"version": "0.0.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,6 +87,7 @@ extension SceneCoordinator {
|
||||||
case activityViewController(activityViewController: UIActivityViewController, sourceView: UIView?, barButtonItem: UIBarButtonItem?)
|
case activityViewController(activityViewController: UIActivityViewController, sourceView: UIView?, barButtonItem: UIBarButtonItem?)
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
case accountList
|
||||||
case publicTimeline
|
case publicTimeline
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -321,6 +322,9 @@ private extension SceneCoordinator {
|
||||||
_viewController.viewModel = viewModel
|
_viewController.viewModel = viewModel
|
||||||
viewController = _viewController
|
viewController = _viewController
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
case .accountList:
|
||||||
|
let _viewController = AccountListViewController()
|
||||||
|
viewController = _viewController
|
||||||
case .publicTimeline:
|
case .publicTimeline:
|
||||||
let _viewController = PublicTimelineViewController()
|
let _viewController = PublicTimelineViewController()
|
||||||
_viewController.viewModel = PublicTimelineViewModel(context: appContext)
|
_viewController.viewModel = PublicTimelineViewModel(context: appContext)
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// AccountListTableViewCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by Cirno MainasuK on 2021-9-13.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class AccountListTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountListTableViewCell {
|
||||||
|
|
||||||
|
private func _init() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,80 @@
|
||||||
|
//
|
||||||
|
// AccountListViewModel.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by Cirno MainasuK on 2021-9-13.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
import CoreData
|
||||||
|
import CoreDataStack
|
||||||
|
|
||||||
|
final class AccountListViewModel {
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
// input
|
||||||
|
let context: AppContext
|
||||||
|
|
||||||
|
// output
|
||||||
|
let authentications = CurrentValueSubject<[Item], Never>([])
|
||||||
|
var diffableDataSource: UITableViewDiffableDataSource<Section, Item>!
|
||||||
|
|
||||||
|
init(context: AppContext) {
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
context.authenticationService.mastodonAuthentications
|
||||||
|
.map { authentications in
|
||||||
|
return authentications.map {
|
||||||
|
Item.authentication(objectID: $0.objectID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.assign(to: \.value, on: authentications)
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
|
authentications
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] authentications in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let diffableDataSource = self.diffableDataSource else { return }
|
||||||
|
|
||||||
|
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||||
|
snapshot.appendSections([.main])
|
||||||
|
snapshot.appendItems(authentications, toSection: .main)
|
||||||
|
|
||||||
|
diffableDataSource.apply(snapshot)
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountListViewModel {
|
||||||
|
enum Section: Hashable {
|
||||||
|
case main
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Item: Hashable {
|
||||||
|
case authentication(objectID: NSManagedObjectID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupDiffableDataSource(
|
||||||
|
tableView: UITableView,
|
||||||
|
managedObjectContext: NSManagedObjectContext
|
||||||
|
) {
|
||||||
|
diffableDataSource = UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item in
|
||||||
|
switch item {
|
||||||
|
case .authentication(let objectID):
|
||||||
|
let authentication = managedObjectContext.object(with: objectID) as! MastodonAuthentication
|
||||||
|
let user = authentication.user
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: AccountListTableViewCell.self), for: indexPath) as! AccountListTableViewCell
|
||||||
|
cell.textLabel?.text = user.acctWithDomain
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,98 @@
|
||||||
|
//
|
||||||
|
// AccountViewController.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by Cirno MainasuK on 2021-9-13.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
|
||||||
|
import os.log
|
||||||
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
import CoreDataStack
|
||||||
|
|
||||||
|
final class AccountListViewController: UIViewController, NeedsDependency {
|
||||||
|
|
||||||
|
let logger = Logger(subsystem: "AccountListViewController", category: "UI")
|
||||||
|
|
||||||
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
private(set) lazy var viewModel = AccountListViewModel(context: context)
|
||||||
|
|
||||||
|
private(set) lazy var addBarButtonItem: UIBarButtonItem = {
|
||||||
|
let barButtonItem = UIBarButtonItem(
|
||||||
|
image: UIImage(systemName: "plus"),
|
||||||
|
style: .plain,
|
||||||
|
target: self,
|
||||||
|
action: #selector(AccountListViewController.addBarButtonItem(_:))
|
||||||
|
)
|
||||||
|
return barButtonItem
|
||||||
|
}()
|
||||||
|
|
||||||
|
private(set) lazy var tableView: UITableView = {
|
||||||
|
let tableView = UITableView()
|
||||||
|
tableView.register(AccountListTableViewCell.self, forCellReuseIdentifier: String(describing: AccountListTableViewCell.self))
|
||||||
|
return tableView
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountListViewController {
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
view.backgroundColor = .systemBackground
|
||||||
|
navigationItem.rightBarButtonItem = addBarButtonItem
|
||||||
|
|
||||||
|
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.addSubview(tableView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||||
|
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
|
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
|
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
|
tableView.delegate = self
|
||||||
|
viewModel.setupDiffableDataSource(
|
||||||
|
tableView: tableView,
|
||||||
|
managedObjectContext: context.managedObjectContext
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AccountListViewController {
|
||||||
|
|
||||||
|
@objc private func addBarButtonItem(_ sender: UIBarButtonItem) {
|
||||||
|
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||||
|
coordinator.present(scene: .welcome, from: self, transition: .modal(animated: true, completion: nil))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - UITableViewDelegate
|
||||||
|
extension AccountListViewController: UITableViewDelegate {
|
||||||
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
|
||||||
|
guard let diffableDataSource = viewModel.diffableDataSource else { return }
|
||||||
|
guard case let .authentication(objectID) = diffableDataSource.itemIdentifier(for: indexPath) else { return }
|
||||||
|
assert(Thread.isMainThread)
|
||||||
|
|
||||||
|
let authentication = context.managedObjectContext.object(with: objectID) as! MastodonAuthentication
|
||||||
|
context.authenticationService.activeMastodonUser(domain: authentication.domain, userID: authentication.userID)
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { [weak self] result in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.coordinator.setup()
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -23,20 +23,9 @@ extension HomeTimelineViewController {
|
||||||
identifier: nil,
|
identifier: nil,
|
||||||
options: .displayInline,
|
options: .displayInline,
|
||||||
children: [
|
children: [
|
||||||
UIAction(title: "Show FLEX", image: nil, attributes: [], handler: { [weak self] action in
|
showMenu,
|
||||||
guard let self = self else { return }
|
|
||||||
self.showFLEXAction(action)
|
|
||||||
}),
|
|
||||||
moveMenu,
|
moveMenu,
|
||||||
dropMenu,
|
dropMenu,
|
||||||
UIAction(title: "Show Welcome", image: UIImage(systemName: "figure.walk"), attributes: []) { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.showWelcomeAction(action)
|
|
||||||
},
|
|
||||||
UIAction(title: "Show Confirm Email", image: UIImage(systemName: "envelope"), attributes: []) { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.showConfirmEmail(action)
|
|
||||||
},
|
|
||||||
UIAction(title: "Toggle EmptyView", image: UIImage(systemName: "clear"), attributes: []) { [weak self] action in
|
UIAction(title: "Toggle EmptyView", image: UIImage(systemName: "clear"), attributes: []) { [weak self] action in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if self.emptyView.superview != nil {
|
if self.emptyView.superview != nil {
|
||||||
|
@ -45,18 +34,6 @@ extension HomeTimelineViewController {
|
||||||
self.showEmptyView()
|
self.showEmptyView()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
UIAction(title: "Show Public Timeline", image: UIImage(systemName: "list.dash"), attributes: []) { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.showPublicTimelineAction(action)
|
|
||||||
},
|
|
||||||
UIAction(title: "Show Profile", image: UIImage(systemName: "person.crop.circle"), attributes: []) { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.showProfileAction(action)
|
|
||||||
},
|
|
||||||
UIAction(title: "Show Thread", image: UIImage(systemName: "bubble.left.and.bubble.right"), attributes: []) { [weak self] action in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.showThreadAction(action)
|
|
||||||
},
|
|
||||||
UIAction(title: "Settings", image: UIImage(systemName: "gear"), attributes: []) { [weak self] action in
|
UIAction(title: "Settings", image: UIImage(systemName: "gear"), attributes: []) { [weak self] action in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.showSettings(action)
|
self.showSettings(action)
|
||||||
|
@ -69,6 +46,45 @@ extension HomeTimelineViewController {
|
||||||
)
|
)
|
||||||
return menu
|
return menu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var showMenu: UIMenu {
|
||||||
|
return UIMenu(
|
||||||
|
title: "Show…",
|
||||||
|
image: UIImage(systemName: "plus.rectangle.on.rectangle"),
|
||||||
|
identifier: nil,
|
||||||
|
options: [],
|
||||||
|
children: [
|
||||||
|
UIAction(title: "FLEX", image: nil, attributes: [], handler: { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showFLEXAction(action)
|
||||||
|
}),
|
||||||
|
UIAction(title: "Welcome", image: UIImage(systemName: "figure.walk"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showWelcomeAction(action)
|
||||||
|
},
|
||||||
|
UIAction(title: "Confirm Email", image: UIImage(systemName: "envelope"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showConfirmEmail(action)
|
||||||
|
},
|
||||||
|
UIAction(title: "Account List", image: UIImage(systemName: "person"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showAccountList(action)
|
||||||
|
},
|
||||||
|
UIAction(title: "Public Timeline", image: UIImage(systemName: "list.dash"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showPublicTimelineAction(action)
|
||||||
|
},
|
||||||
|
UIAction(title: "Profile", image: UIImage(systemName: "person.crop.circle"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showProfileAction(action)
|
||||||
|
},
|
||||||
|
UIAction(title: "Thread", image: UIImage(systemName: "bubble.left.and.bubble.right"), attributes: []) { [weak self] action in
|
||||||
|
guard let self = self else { return }
|
||||||
|
self.showThreadAction(action)
|
||||||
|
},
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
var moveMenu: UIMenu {
|
var moveMenu: UIMenu {
|
||||||
return UIMenu(
|
return UIMenu(
|
||||||
|
@ -321,6 +337,10 @@ extension HomeTimelineViewController {
|
||||||
let mastodonConfirmEmailViewModel = MastodonConfirmEmailViewModel()
|
let mastodonConfirmEmailViewModel = MastodonConfirmEmailViewModel()
|
||||||
coordinator.present(scene: .mastodonConfirmEmail(viewModel: mastodonConfirmEmailViewModel), from: nil, transition: .modal(animated: true, completion: nil))
|
coordinator.present(scene: .mastodonConfirmEmail(viewModel: mastodonConfirmEmailViewModel), from: nil, transition: .modal(animated: true, completion: nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func showAccountList(_ sender: UIAction) {
|
||||||
|
coordinator.present(scene: .accountList, from: self, transition: .modal(animated: true, completion: nil))
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func showPublicTimelineAction(_ sender: UIAction) {
|
@objc private func showPublicTimelineAction(_ sender: UIAction) {
|
||||||
coordinator.present(scene: .publicTimeline, from: self, transition: .show)
|
coordinator.present(scene: .publicTimeline, from: self, transition: .show)
|
||||||
|
|
|
@ -222,7 +222,8 @@ extension MastodonPickServerViewController {
|
||||||
assertionFailure(error.localizedDescription)
|
assertionFailure(error.localizedDescription)
|
||||||
case .success(let isActived):
|
case .success(let isActived):
|
||||||
assert(isActived)
|
assert(isActived)
|
||||||
self.dismiss(animated: true, completion: nil)
|
// self.dismiss(animated: true, completion: nil)
|
||||||
|
self.coordinator.setup()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
|
|
|
@ -80,4 +80,4 @@ SPEC CHECKSUMS:
|
||||||
|
|
||||||
PODFILE CHECKSUM: 4db0bdf969729c5758bd923e33d9e097cb892086
|
PODFILE CHECKSUM: 4db0bdf969729c5758bd923e33d9e097cb892086
|
||||||
|
|
||||||
COCOAPODS: 1.10.2
|
COCOAPODS: 1.11.0
|
||||||
|
|
Loading…
Reference in New Issue