From 66f6ee9bd00f01f66cf19fce37341fc016b888f3 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Tue, 19 Mar 2024 16:39:00 +0100 Subject: [PATCH 01/12] Begin updating NavigationBar Layout --- .../HomeTimelineViewController.swift | 40 +++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 9666bf12e..189caba27 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -46,6 +46,38 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let titleView = HomeTimelineNavigationBarTitleView() + let timelineSelectorBarButtonItem: UIBarButtonItem = { + let menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: [ + UIAction(title: "Following", image: .init(systemName: "house")) { action in + }, + UIAction(title: "Local", image: .init(systemName: "building.2")) { action in + } + ]) + + let button = UIButton(type: .custom) + button.setTitle("Following", for: .normal) + button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + let imageConfiguration = UIImage.SymbolConfiguration(pointSize: 16, weight: .bold, scale: .medium) + button.setImage(.init(systemName: "arrowshape.down.circle", withConfiguration: imageConfiguration), for: .normal) + button.configuration = { + var config = UIButton.Configuration.plain() + config.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) + config.imagePadding = 8 + return config + }() + + button.semanticContentAttribute = + UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft ? + .forceLeftToRight : + .forceRightToLeft + button.showsMenuAsPrimaryAction = true + button.menu = menu + + let barButtonItem = UIBarButtonItem(customView: button) + return barButtonItem + }() + let settingBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() barButtonItem.tintColor = SystemTheme.tintColor @@ -79,7 +111,7 @@ extension HomeTimelineViewController { override func viewDidLoad() { super.viewDidLoad() - title = L10n.Scene.HomeTimeline.title + title = "" view.backgroundColor = .secondarySystemBackground viewModel?.$displaySettingBarButtonItem @@ -94,8 +126,10 @@ extension HomeTimelineViewController { settingBarButtonItem.target = self settingBarButtonItem.action = #selector(HomeTimelineViewController.settingBarButtonItemPressed(_:)) - navigationItem.titleView = titleView - titleView.delegate = self + self.navigationItem.leftBarButtonItem = self.timelineSelectorBarButtonItem + +// navigationItem.titleView = titleView +// titleView.delegate = self viewModel?.homeTimelineNavigationBarTitleViewModel.state .removeDuplicates() From 344385f5efcd8d21f32b36af6b70f53dc20fca26 Mon Sep 17 00:00:00 2001 From: Marcus Kida Date: Wed, 20 Mar 2024 09:50:34 +0100 Subject: [PATCH 02/12] Improve button image --- .../HomeTimeline/HomeTimelineViewController.swift | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 189caba27..28d2ae842 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -55,15 +55,22 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media ]) let button = UIButton(type: .custom) - button.setTitle("Following", for: .normal) - button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) - button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + button.setAttributedTitle( + .init(string: "Following", attributes: [ + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + ]), + for: .normal) let imageConfiguration = UIImage.SymbolConfiguration(pointSize: 16, weight: .bold, scale: .medium) - button.setImage(.init(systemName: "arrowshape.down.circle", withConfiguration: imageConfiguration), for: .normal) +// button.setImage( +// .init(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration)?.withRenderingMode(.alwaysTemplate), +// for: .normal) +// button.tintColor = Asset.Colors.disabled.color +// button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) button.configuration = { var config = UIButton.Configuration.plain() config.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) config.imagePadding = 8 + config.image = .init(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration)?.withRenderingMode(.alwaysTemplate).withTintColor(Asset.Colors.disabled.color) return config }() From 4eed7df729e1709867ac1704ab799a35a1158017 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 27 Mar 2024 15:38:26 +0100 Subject: [PATCH 03/12] Remove dead code (IOS-235) --- .../HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift | 5 ----- Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift | 4 +--- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index a88bafebe..54def3aa8 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -28,11 +28,6 @@ extension HomeTimelineViewModel { self.viewModel = viewModel } - override func didEnter(from previousState: GKState?) { - super.didEnter(from: previousState) - viewModel?.loadLatestStateMachinePublisher.send(self) - } - @MainActor func enter(state: LoadLatestState.Type) { stateMachine?.enter(state) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index f4efba2a3..ca49e182b 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -59,7 +59,6 @@ final class HomeTimelineViewModel: NSObject { stateMachine.enter(LoadLatestState.Initial.self) return stateMachine }() - lazy var loadLatestStateMachinePublisher = CurrentValueSubject(nil) // bottom loader private(set) lazy var loadOldestStateMachine: GKStateMachine = { @@ -74,10 +73,9 @@ final class HomeTimelineViewModel: NSObject { stateMachine.enter(LoadOldestState.Initial.self) return stateMachine }() - lazy var loadOldestStateMachinePublisher = CurrentValueSubject(nil) var cellFrameCache = NSCache() - + init(context: AppContext, authContext: AuthContext) { self.context = context self.authContext = authContext From 5e1bb2cfaad276482b1aba68612219c1e47c3764 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 27 Mar 2024 15:42:13 +0100 Subject: [PATCH 04/12] Differ between local and following-timeline (IOS-235) --- ...omeTimelineViewModel+LoadLatestState.swift | 18 ++++++++++---- ...omeTimelineViewModel+LoadOldestState.swift | 24 ++++++++++++------- .../HomeTimeline/HomeTimelineViewModel.swift | 10 ++++++-- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index 54def3aa8..e7702b47f 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -88,10 +88,20 @@ extension HomeTimelineViewModel.LoadLatestState { do { await AuthenticationServiceProvider.shared.fetchAccounts(apiService: viewModel.context.apiService) - let response = try await viewModel.context.apiService.homeTimeline( - authenticationBox: viewModel.authContext.mastodonAuthenticationBox - ) - + let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> + + switch viewModel.timelineContext { + case .following: + response = try await viewModel.context.apiService.homeTimeline( + authenticationBox: viewModel.authContext.mastodonAuthenticationBox + ) + case .community: + response = try await viewModel.context.apiService.publicTimeline( + query: .init(local: true), + authenticationBox: viewModel.authContext.mastodonAuthenticationBox + ) + } + await enter(state: Idle.self) viewModel.homeTimelineNavigationBarTitleViewModel.receiveLoadingStateCompletion(.finished) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift index 3e993141b..5c6ef59cf 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift @@ -53,9 +53,7 @@ extension HomeTimelineViewModel.LoadOldestState { } Task { - let _maxID = lastFeedRecord.status?.id - - guard let maxID = _maxID else { + guard let maxID = lastFeedRecord.status?.id else { await self.enter(state: Fail.self) return } @@ -63,11 +61,21 @@ extension HomeTimelineViewModel.LoadOldestState { do { await AuthenticationServiceProvider.shared.fetchAccounts(apiService: viewModel.context.apiService) - let response = try await viewModel.context.apiService.homeTimeline( - maxID: maxID, - authenticationBox: viewModel.authContext.mastodonAuthenticationBox - ) - + let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> + + switch viewModel.timelineContext { + case .following: + response = try await viewModel.context.apiService.homeTimeline( + maxID: maxID, + authenticationBox: viewModel.authContext.mastodonAuthenticationBox + ) + case .community: + response = try await viewModel.context.apiService.publicTimeline( + query: .init(local: true, maxID: maxID), + authenticationBox: viewModel.authContext.mastodonAuthenticationBox + ) + } + let statuses = response.value // enter no more state when no new statuses if statuses.isEmpty || (statuses.count == 1 && statuses[0].id == maxID) { diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index ca49e182b..cede4022e 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -18,7 +18,12 @@ import MastodonUI import MastodonSDK final class HomeTimelineViewModel: NSObject { - + + enum TimelineContext { + case following + case community + } + var disposeBag = Set() var observations = Set() @@ -35,7 +40,8 @@ final class HomeTimelineViewModel: NSObject { @Published var scrollPositionRecord: ScrollPositionRecord? = nil @Published var displaySettingBarButtonItem = true @Published var hasPendingStatusEditReload = false - + var timelineContext: TimelineContext = .following + weak var tableView: UITableView? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? From 1d2c08b997b0807d7549719dabcb1910e583e0ea Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 27 Mar 2024 16:18:42 +0100 Subject: [PATCH 05/12] Add basic implementation of timeline-switch (IOS-235) --- .../HomeTimelineViewController.swift | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 28d2ae842..ae8cb5d57 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -46,15 +46,40 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let titleView = HomeTimelineNavigationBarTitleView() - let timelineSelectorBarButtonItem: UIBarButtonItem = { - let menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: [ - UIAction(title: "Following", image: .init(systemName: "house")) { action in - }, - UIAction(title: "Local", image: .init(systemName: "building.2")) { action in - } - ]) - + lazy var timelineSelectorBarButtonItem: UIBarButtonItem = { let button = UIButton(type: .custom) + + let actions = [ + UIAction(title: "Following", image: .init(systemName: "house")) { [weak self] action in + guard let self, let viewModel = self.viewModel else { return } + + viewModel.timelineContext = .following + viewModel.dataController.records = [] + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + button.setAttributedTitle( + .init(string: "Following", attributes: [ + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + ]), + for: .normal) + button.sizeToFit() + }, + UIAction(title: "Local", image: .init(systemName: "building.2")) { [weak self] _ in + guard let self, let viewModel = self.viewModel else { return } + + viewModel.timelineContext = .community + viewModel.dataController.records = [] + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + button.setAttributedTitle( + .init(string: "Local", attributes: [ + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + ]), + for: .normal) + button.sizeToFit() + } + + ] + let menu = UIMenu(children: actions) + button.setAttributedTitle( .init(string: "Following", attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) From 67786e1675ad8ff2120652a71e45f5b972a34619 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 27 Mar 2024 19:27:33 +0100 Subject: [PATCH 06/12] Use correct icon for settings (IOS-235) --- Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift | 4 ++-- Mastodon/Scene/Profile/ProfileViewController.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index ae8cb5d57..ee24db144 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -112,8 +112,8 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let settingBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() - barButtonItem.tintColor = SystemTheme.tintColor - barButtonItem.image = Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate) + barButtonItem.tintColor = Asset.Colors.Brand.blurple.color + barButtonItem.image = UIImage(systemName: "gear") barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.settings return barButtonItem }() diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index 71b8b6a21..0e8500401 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -55,7 +55,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi private(set) lazy var settingBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem( - image: Asset.ObjectsAndTools.gear.image.withRenderingMode(.alwaysTemplate), + image: UIImage(systemName: "gear")?.withRenderingMode(.alwaysTemplate), style: .plain, target: self, action: #selector(ProfileViewController.settingBarButtonItemPressed(_:)) From ceca4f688742d86275c1640479ca277978301c99 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 27 Mar 2024 19:46:36 +0100 Subject: [PATCH 07/12] Style elements (IOS-235) --- .../HomeTimelineViewController.swift | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index ee24db144..ef346ad6f 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -55,10 +55,11 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media viewModel.timelineContext = .following viewModel.dataController.records = [] + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) button.setAttributedTitle( .init(string: "Following", attributes: [ - .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) button.sizeToFit() @@ -68,10 +69,11 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media viewModel.timelineContext = .community viewModel.dataController.records = [] + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) button.setAttributedTitle( .init(string: "Local", attributes: [ - .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) button.sizeToFit() @@ -82,23 +84,22 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media button.setAttributedTitle( .init(string: "Following", attributes: [ - .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .bold)) + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) - let imageConfiguration = UIImage.SymbolConfiguration(pointSize: 16, weight: .bold, scale: .medium) -// button.setImage( -// .init(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration)?.withRenderingMode(.alwaysTemplate), -// for: .normal) -// button.tintColor = Asset.Colors.disabled.color -// button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal) + + let imageConfiguration = UIImage.SymbolConfiguration(paletteColors: [.secondaryLabel, .secondarySystemFill]) + .applying(UIImage.SymbolConfiguration(textStyle: .subheadline)) + .applying(UIImage.SymbolConfiguration(pointSize: 16, weight: .bold, scale: .medium)) + button.configuration = { var config = UIButton.Configuration.plain() config.contentInsets = .init(top: 0, leading: 0, bottom: 0, trailing: 0) config.imagePadding = 8 - config.image = .init(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration)?.withRenderingMode(.alwaysTemplate).withTintColor(Asset.Colors.disabled.color) + config.image = UIImage(systemName: "chevron.down.circle.fill", withConfiguration: imageConfiguration) return config }() - + button.semanticContentAttribute = UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : From 4ae69c90364ecd47a53f82e44f6df82999a363a6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 28 Mar 2024 13:31:19 +0100 Subject: [PATCH 08/12] Add selection to menu (IOS-235) also refactor it into a function as we need to re-generate it for an updated version --- .../HomeTimelineViewController.swift | 102 ++++++++++-------- 1 file changed, 57 insertions(+), 45 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index ef346ad6f..32c9cb0d6 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -43,51 +43,17 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media emptyView.isLayoutMarginsRelativeArrangement = true return emptyView }() - + let titleView = HomeTimelineNavigationBarTitleView() - - lazy var timelineSelectorBarButtonItem: UIBarButtonItem = { + + lazy var timelineSelectorButton = { let button = UIButton(type: .custom) - - let actions = [ - UIAction(title: "Following", image: .init(systemName: "house")) { [weak self] action in - guard let self, let viewModel = self.viewModel else { return } - - viewModel.timelineContext = .following - viewModel.dataController.records = [] - - viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) - button.setAttributedTitle( - .init(string: "Following", attributes: [ - .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) - ]), - for: .normal) - button.sizeToFit() - }, - UIAction(title: "Local", image: .init(systemName: "building.2")) { [weak self] _ in - guard let self, let viewModel = self.viewModel else { return } - - viewModel.timelineContext = .community - viewModel.dataController.records = [] - - viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) - button.setAttributedTitle( - .init(string: "Local", attributes: [ - .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) - ]), - for: .normal) - button.sizeToFit() - } - - ] - let menu = UIMenu(children: actions) - button.setAttributedTitle( .init(string: "Following", attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) - + let imageConfiguration = UIImage.SymbolConfiguration(paletteColors: [.secondaryLabel, .secondarySystemFill]) .applying(UIImage.SymbolConfiguration(textStyle: .subheadline)) .applying(UIImage.SymbolConfiguration(pointSize: 16, weight: .bold, scale: .medium)) @@ -105,12 +71,10 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media .forceLeftToRight : .forceRightToLeft button.showsMenuAsPrimaryAction = true - button.menu = menu - - let barButtonItem = UIBarButtonItem(customView: button) - return barButtonItem + button.menu = generateTimeSelectorMenu() + return button }() - + let settingBarButtonItem: UIBarButtonItem = { let barButtonItem = UIBarButtonItem() barButtonItem.tintColor = Asset.Colors.Brand.blurple.color @@ -137,6 +101,54 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media }() let refreshControl = RefreshControl() + + private func generateTimeSelectorMenu() -> UIMenu { + let showFollowingAction = UIAction(title: "Following", image: .init(systemName: "house")) { [weak self] _ in + guard let self, let viewModel = self.viewModel else { return } + + viewModel.timelineContext = .following + viewModel.dataController.records = [] + + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + timelineSelectorButton.setAttributedTitle( + .init(string: "Following", attributes: [ + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) + ]), + for: .normal) + + timelineSelectorButton.sizeToFit() + timelineSelectorButton.menu = generateTimeSelectorMenu() + } + + let showLocalTimelineAction = UIAction(title: "Local", image: .init(systemName: "building.2")) { [weak self] action in + guard let self, let viewModel = self.viewModel else { return } + + viewModel.timelineContext = .community + viewModel.dataController.records = [] + + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + timelineSelectorButton.setAttributedTitle( + .init(string: "Local", attributes: [ + .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) + ]), + for: .normal) + timelineSelectorButton.sizeToFit() + timelineSelectorButton.menu = generateTimeSelectorMenu() + } + + if let viewModel { + switch viewModel.timelineContext { + case .community: + showLocalTimelineAction.state = .on + showFollowingAction.state = .off + case .following: + showLocalTimelineAction.state = .off + showFollowingAction.state = .on + } + } + + return UIMenu(children: [showFollowingAction, showLocalTimelineAction]) + } } extension HomeTimelineViewController { @@ -159,8 +171,8 @@ extension HomeTimelineViewController { settingBarButtonItem.target = self settingBarButtonItem.action = #selector(HomeTimelineViewController.settingBarButtonItemPressed(_:)) - self.navigationItem.leftBarButtonItem = self.timelineSelectorBarButtonItem - + self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: timelineSelectorButton) + // navigationItem.titleView = titleView // titleView.delegate = self From 86ab9101a3e11c1609b85c702a6678f1e34a93ef Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 28 Mar 2024 15:53:42 +0100 Subject: [PATCH 09/12] Fix loading of older posts (IOS-235) i.e. consider different timelines there as well --- .../HomeTimelineViewController.swift | 4 ++-- ...omeTimelineViewModel+LoadLatestState.swift | 2 +- ...omeTimelineViewModel+LoadOldestState.swift | 2 +- .../HomeTimeline/HomeTimelineViewModel.swift | 12 +++------- .../DataController/FeedDataController.swift | 23 +++++++++++++++---- .../Sources/MastodonSDK/MastodonFeed.swift | 8 ++++++- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 32c9cb0d6..37fde8e5c 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -123,7 +123,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let showLocalTimelineAction = UIAction(title: "Local", image: .init(systemName: "building.2")) { [weak self] action in guard let self, let viewModel = self.viewModel else { return } - viewModel.timelineContext = .community + viewModel.timelineContext = .localCommunity viewModel.dataController.records = [] viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) @@ -138,7 +138,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media if let viewModel { switch viewModel.timelineContext { - case .community: + case .localCommunity: showLocalTimelineAction.state = .on showFollowingAction.state = .off case .following: diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index e7702b47f..f9cf6a89e 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -95,7 +95,7 @@ extension HomeTimelineViewModel.LoadLatestState { response = try await viewModel.context.apiService.homeTimeline( authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) - case .community: + case .localCommunity: response = try await viewModel.context.apiService.publicTimeline( query: .init(local: true), authenticationBox: viewModel.authContext.mastodonAuthenticationBox diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift index 5c6ef59cf..4adb57133 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift @@ -69,7 +69,7 @@ extension HomeTimelineViewModel.LoadOldestState { maxID: maxID, authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) - case .community: + case .localCommunity: response = try await viewModel.context.apiService.publicTimeline( query: .init(local: true, maxID: maxID), authenticationBox: viewModel.authContext.mastodonAuthenticationBox diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index cede4022e..e2c9fed2b 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -18,12 +18,6 @@ import MastodonUI import MastodonSDK final class HomeTimelineViewModel: NSObject { - - enum TimelineContext { - case following - case community - } - var disposeBag = Set() var observations = Set() @@ -40,7 +34,7 @@ final class HomeTimelineViewModel: NSObject { @Published var scrollPositionRecord: ScrollPositionRecord? = nil @Published var displaySettingBarButtonItem = true @Published var hasPendingStatusEditReload = false - var timelineContext: TimelineContext = .following + var timelineContext: MastodonFeed.Kind.HomeTimeline = .following weak var tableView: UITableView? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? @@ -119,7 +113,7 @@ final class HomeTimelineViewModel: NSObject { }) .store(in: &disposeBag) - self.dataController.loadInitial(kind: .home) + self.dataController.loadInitial(kind: .home(timeline: timelineContext)) } } @@ -133,7 +127,7 @@ extension HomeTimelineViewModel { extension HomeTimelineViewModel { func timelineDidReachEnd() { - dataController.loadNext(kind: .home) + dataController.loadNext(kind: .home(timeline: timelineContext)) } } diff --git a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift index 6bf2dcf05..79bf82b08 100644 --- a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift +++ b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift @@ -164,12 +164,27 @@ final public class FeedDataController { } private extension FeedDataController { - func load(kind: MastodonFeed.Kind, maxID: MastodonStatus.ID?) async throws -> [MastodonFeed] { + func load(kind: MastodonFeed.Kind, maxID: MastodonStatus.ID?) async throws -> [MastodonFeed] { switch kind { - case .home: + case .home(let timeline): await context.authenticationService.authenticationServiceProvider.fetchAccounts(apiService: context.apiService) - return try await context.apiService.homeTimeline(maxID: maxID, authenticationBox: authContext.mastodonAuthenticationBox) - .value.map { .fromStatus(.fromEntity($0), kind: .home) } + + let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> + + switch timeline { + case .following: + response = try await context.apiService.homeTimeline( + maxID: maxID, + authenticationBox: authContext.mastodonAuthenticationBox + ) + case .localCommunity: + response = try await context.apiService.publicTimeline( + query: .init(local: true, maxID: maxID), + authenticationBox: authContext.mastodonAuthenticationBox + ) + } + + return response.value.map { .fromStatus(.fromEntity($0), kind: .home) } case .notificationAll: return try await getFeeds(with: .everything) case .notificationMentions: diff --git a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift index 3bd5c940d..d2684f1d8 100644 --- a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift +++ b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift @@ -6,9 +6,15 @@ import CoreDataStack public final class MastodonFeed { public enum Kind { - case home + + case home(timeline: HomeTimeline) case notificationAll case notificationMentions + + public enum HomeTimeline { + case following + case localCommunity + } } public let id: String From 1583ce0d9a8131546287a3c30c991e175f722d0d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 1 Apr 2024 20:10:41 +0200 Subject: [PATCH 10/12] Add a new loading-state for timeline-switches (IOS-235) Gosh, this took longer than expected. It didn't work for quite some time but the trick is to check for the states in several places, like in HomeTimelineViewModel+Diffable or when the timeline reached the end. Those triggered a reload and we don't want that in case the state is `contextSwitch`. --- ...ineViewController+DataSourceProvider.swift | 5 ++-- .../HomeTimelineViewController.swift | 12 ++++---- .../HomeTimelineViewModel+Diffable.swift | 3 ++ ...omeTimelineViewModel+LoadLatestState.swift | 30 +++++++++++++++++-- .../HomeTimeline/HomeTimelineViewModel.swift | 1 + 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DataSourceProvider.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DataSourceProvider.swift index 3a0457983..45ae33487 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DataSourceProvider.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DataSourceProvider.swift @@ -12,7 +12,7 @@ extension HomeTimelineViewController: DataSourceProvider { func item(from source: DataSourceItem.Source) async -> DataSourceItem? { var _indexPath = source.indexPath if _indexPath == nil, let cell = source.tableViewCell { - _indexPath = await self.indexPath(for: cell) + _indexPath = self.indexPath(for: cell) } guard let indexPath = _indexPath else { return nil } @@ -37,8 +37,7 @@ extension HomeTimelineViewController: DataSourceProvider { viewModel?.dataController.update(status: status, intent: intent) } - @MainActor - private func indexPath(for cell: UITableViewCell) async -> IndexPath? { + private func indexPath(for cell: UITableViewCell) -> IndexPath? { return tableView.indexPath(for: cell) } } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 37fde8e5c..1da17601b 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -109,7 +109,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media viewModel.timelineContext = .following viewModel.dataController.records = [] - viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) timelineSelectorButton.setAttributedTitle( .init(string: "Following", attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) @@ -124,9 +124,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media guard let self, let viewModel = self.viewModel else { return } viewModel.timelineContext = .localCommunity - viewModel.dataController.records = [] - - viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.LoadingManually.self) + viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) timelineSelectorButton.setAttributedTitle( .init(string: "Local", attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) @@ -591,8 +589,12 @@ extension HomeTimelineViewController: UITableViewDelegate, AutoGenerateTableView // sourcery:end func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { + guard let viewModel, + let currentState = viewModel.loadLatestStateMachine.currentState as? HomeTimelineViewModel.LoadLatestState, + (currentState.self is HomeTimelineViewModel.LoadLatestState.ContextSwitch) == false else { return } + if indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 { - viewModel?.timelineDidReachEnd() + viewModel.timelineDidReachEnd() } } } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift index c9e81737f..9d2ae90fc 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+Diffable.swift @@ -40,6 +40,9 @@ extension HomeTimelineViewModel { guard let self = self else { return } guard let diffableDataSource = self.diffableDataSource else { return } + guard let currentState = loadLatestStateMachine.currentState as? HomeTimelineViewModel.LoadLatestState, + (currentState.self is HomeTimelineViewModel.LoadLatestState.ContextSwitch) == false else { return } + Task { @MainActor in let oldSnapshot = diffableDataSource.snapshot() var newSnapshot: NSDiffableDataSourceSnapshot = { diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index f9cf6a89e..ed2793c74 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -70,7 +70,33 @@ extension HomeTimelineViewModel.LoadLatestState { class Idle: HomeTimelineViewModel.LoadLatestState { override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return stateClass == Loading.self || stateClass == LoadingManually.self + return stateClass == Loading.self || stateClass == LoadingManually.self || stateClass == ContextSwitch.self + } + } + + class ContextSwitch: HomeTimelineViewModel.LoadLatestState { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + return stateClass == Loading.self || stateClass == LoadingManually.self || stateClass == ContextSwitch.self + } + + override func didEnter(from previousState: GKState?) { + guard let viewModel else { return } + guard let diffableDataSource = viewModel.diffableDataSource else { + assertionFailure() + return + } + + OperationQueue.main.addOperation { + viewModel.dataController.records = [] + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + snapshot.appendItems([.topLoader], toSection: .main) + diffableDataSource.apply(snapshot) { [weak self] in + guard let self else { return } + + self.stateMachine?.enter(Loading.self) + } + } } } @@ -78,7 +104,7 @@ extension HomeTimelineViewModel.LoadLatestState { super.didEnter(from: previousState) guard let viewModel else { return } - + let latestFeedRecords = viewModel.dataController.records.prefix(APIService.onceRequestStatusMaxCount) Task { diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index e2c9fed2b..c87920e78 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -55,6 +55,7 @@ final class HomeTimelineViewModel: NSObject { LoadLatestState.LoadingManually(viewModel: self), LoadLatestState.Fail(viewModel: self), LoadLatestState.Idle(viewModel: self), + LoadLatestState.ContextSwitch(viewModel: self), ]) stateMachine.enter(LoadLatestState.Initial.self) return stateMachine From 26f3b5a7ce08036afd5bb8ed6299cd27f94f2f80 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 1 Apr 2024 20:20:35 +0200 Subject: [PATCH 11/12] Sprinkle in some localization (IOS-235) --- Localization/StringsConvertor/input/Base.lproj/app.json | 4 ++++ Localization/app.json | 4 ++++ .../Scene/HomeTimeline/HomeTimelineViewController.swift | 8 ++++---- .../Sources/MastodonLocalization/Generated/Strings.swift | 6 ++++++ .../Resources/Base.lproj/Localizable.strings | 2 ++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/Localization/StringsConvertor/input/Base.lproj/app.json b/Localization/StringsConvertor/input/Base.lproj/app.json index 4a680e512..8658e52d8 100644 --- a/Localization/StringsConvertor/input/Base.lproj/app.json +++ b/Localization/StringsConvertor/input/Base.lproj/app.json @@ -470,6 +470,10 @@ }, "home_timeline": { "title": "Home", + "timeline_menu": { + "following": "Following", + "local_community": "Local" + }, "navigation_bar_state": { "offline": "Offline", "new_posts": "See new posts", diff --git a/Localization/app.json b/Localization/app.json index 4a680e512..8658e52d8 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -470,6 +470,10 @@ }, "home_timeline": { "title": "Home", + "timeline_menu": { + "following": "Following", + "local_community": "Local" + }, "navigation_bar_state": { "offline": "Offline", "new_posts": "See new posts", diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 1da17601b..3cb6bf956 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -103,7 +103,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let refreshControl = RefreshControl() private func generateTimeSelectorMenu() -> UIMenu { - let showFollowingAction = UIAction(title: "Following", image: .init(systemName: "house")) { [weak self] _ in + let showFollowingAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.following, image: .init(systemName: "house")) { [weak self] _ in guard let self, let viewModel = self.viewModel else { return } viewModel.timelineContext = .following @@ -111,7 +111,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) timelineSelectorButton.setAttributedTitle( - .init(string: "Following", attributes: [ + .init(string: L10n.Scene.HomeTimeline.TimelineMenu.following, attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) @@ -120,13 +120,13 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media timelineSelectorButton.menu = generateTimeSelectorMenu() } - let showLocalTimelineAction = UIAction(title: "Local", image: .init(systemName: "building.2")) { [weak self] action in + let showLocalTimelineAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.localCommunity, image: .init(systemName: "building.2")) { [weak self] action in guard let self, let viewModel = self.viewModel else { return } viewModel.timelineContext = .localCommunity viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) timelineSelectorButton.setAttributedTitle( - .init(string: "Local", attributes: [ + .init(string: L10n.Scene.HomeTimeline.TimelineMenu.localCommunity, attributes: [ .font: UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 20, weight: .semibold)) ]), for: .normal) diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index 63d7a9945..6fddef9d2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -859,6 +859,12 @@ public enum L10n { public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel", fallback: "Mastodon") } } + public enum TimelineMenu { + /// Following + public static let following = L10n.tr("Localizable", "Scene.HomeTimeline.TimelineMenu.Following", fallback: "Following") + /// Local + public static let localCommunity = L10n.tr("Localizable", "Scene.HomeTimeline.TimelineMenu.LocalCommunity", fallback: "Local") + } } public enum Login { /// Log you in on the server you created your account on. diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings index 4287c248d..60fb82e8f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/Base.lproj/Localizable.strings @@ -304,6 +304,8 @@ uploaded to Mastodon."; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; "Scene.HomeTimeline.NavigationBarState.Publishing" = "Publishing post..."; +"Scene.HomeTimeline.TimelineMenu.Following" = "Following"; +"Scene.HomeTimeline.TimelineMenu.LocalCommunity" = "Local"; "Scene.HomeTimeline.Title" = "Home"; "Scene.Login.ServerSearchField.Placeholder" = "Enter URL or search for your server"; "Scene.Login.Subtitle" = "Log you in on the server you created your account on."; From 3fe855273be120483adbf195e34c82bb72cae5ef Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 4 Apr 2024 13:28:07 +0200 Subject: [PATCH 12/12] Rename a few things here and there (IOS-235) --- .../Scene/HomeTimeline/HomeTimelineViewController.swift | 8 ++++---- .../HomeTimelineViewModel+LoadLatestState.swift | 4 ++-- .../HomeTimelineViewModel+LoadOldestState.swift | 4 ++-- Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift | 2 +- .../MastodonCore/DataController/FeedDataController.swift | 4 ++-- MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift | 8 ++++---- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift index 3cb6bf956..100b41300 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController.swift @@ -106,7 +106,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let showFollowingAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.following, image: .init(systemName: "house")) { [weak self] _ in guard let self, let viewModel = self.viewModel else { return } - viewModel.timelineContext = .following + viewModel.timelineContext = .home viewModel.dataController.records = [] viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) @@ -123,7 +123,7 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media let showLocalTimelineAction = UIAction(title: L10n.Scene.HomeTimeline.TimelineMenu.localCommunity, image: .init(systemName: "building.2")) { [weak self] action in guard let self, let viewModel = self.viewModel else { return } - viewModel.timelineContext = .localCommunity + viewModel.timelineContext = .public viewModel.loadLatestStateMachine.enter(HomeTimelineViewModel.LoadLatestState.ContextSwitch.self) timelineSelectorButton.setAttributedTitle( .init(string: L10n.Scene.HomeTimeline.TimelineMenu.localCommunity, attributes: [ @@ -136,10 +136,10 @@ final class HomeTimelineViewController: UIViewController, NeedsDependency, Media if let viewModel { switch viewModel.timelineContext { - case .localCommunity: + case .public: showLocalTimelineAction.state = .on showFollowingAction.state = .off - case .following: + case .home: showLocalTimelineAction.state = .off showFollowingAction.state = .on } diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift index ed2793c74..aca9f5f45 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadLatestState.swift @@ -117,11 +117,11 @@ extension HomeTimelineViewModel.LoadLatestState { let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> switch viewModel.timelineContext { - case .following: + case .home: response = try await viewModel.context.apiService.homeTimeline( authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) - case .localCommunity: + case .public: response = try await viewModel.context.apiService.publicTimeline( query: .init(local: true), authenticationBox: viewModel.authContext.mastodonAuthenticationBox diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift index 4adb57133..668095b24 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel+LoadOldestState.swift @@ -64,12 +64,12 @@ extension HomeTimelineViewModel.LoadOldestState { let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> switch viewModel.timelineContext { - case .following: + case .home: response = try await viewModel.context.apiService.homeTimeline( maxID: maxID, authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) - case .localCommunity: + case .public: response = try await viewModel.context.apiService.publicTimeline( query: .init(local: true, maxID: maxID), authenticationBox: viewModel.authContext.mastodonAuthenticationBox diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift index c87920e78..a67d44f8d 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift @@ -34,7 +34,7 @@ final class HomeTimelineViewModel: NSObject { @Published var scrollPositionRecord: ScrollPositionRecord? = nil @Published var displaySettingBarButtonItem = true @Published var hasPendingStatusEditReload = false - var timelineContext: MastodonFeed.Kind.HomeTimeline = .following + var timelineContext: MastodonFeed.Kind.TimelineContext = .home weak var tableView: UITableView? weak var timelineMiddleLoaderTableViewCellDelegate: TimelineMiddleLoaderTableViewCellDelegate? diff --git a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift index 79bf82b08..793e1d436 100644 --- a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift +++ b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift @@ -172,12 +172,12 @@ private extension FeedDataController { let response: Mastodon.Response.Content<[Mastodon.Entity.Status]> switch timeline { - case .following: + case .home: response = try await context.apiService.homeTimeline( maxID: maxID, authenticationBox: authContext.mastodonAuthenticationBox ) - case .localCommunity: + case .public: response = try await context.apiService.publicTimeline( query: .init(local: true, maxID: maxID), authenticationBox: authContext.mastodonAuthenticationBox diff --git a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift index d2684f1d8..e512143fe 100644 --- a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift +++ b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift @@ -7,13 +7,13 @@ public final class MastodonFeed { public enum Kind { - case home(timeline: HomeTimeline) + case home(timeline: TimelineContext) case notificationAll case notificationMentions - public enum HomeTimeline { - case following - case localCommunity + public enum TimelineContext { + case home + case `public` } }