diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 7bfd4208b..54b63c4df 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -209,7 +209,7 @@ extension SceneCoordinator { // Notifications case notificationPolicy(viewModel: NotificationFilterViewModel) case notificationRequests(viewModel: NotificationRequestsViewModel) - case notificationtimeline(viewModel: NotificationTimelineViewModel) + case notificationTimeline(viewModel: NotificationTimelineViewModel) // report case report(viewModel: ReportViewModel) @@ -568,7 +568,7 @@ private extension SceneCoordinator { viewController = NotificationRequestsTableViewController(viewModel: viewModel, appContext: appContext, coordinator: self) case .notificationPolicy(let viewModel): viewController = NotificationPolicyViewController(viewModel: viewModel) - case .notificationtimeline(let viewModel): + case .notificationTimeline(let viewModel): viewController = NotificationTimelineViewController(viewModel: viewModel, context: appContext, coordinator: self) } diff --git a/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift b/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift index cb2d748e2..4718fc946 100644 --- a/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift +++ b/Mastodon/Protocol/Provider/DataSourceFacade+Notifications.swift @@ -32,11 +32,12 @@ extension DataSourceFacade { provider.coordinator.showLoading() do { - // load notifications for request.account // show NotificationTimelineViewController with NotificationTimelineViewModel + let notificationTimelineViewModel = NotificationTimelineViewModel(context: provider.context, authContext: provider.authContext, scope: .fromAccount(request.account)) provider.coordinator.hideLoading() + provider.coordinator.present(scene: .notificationTimeline(viewModel: notificationTimelineViewModel), transition: .show) } catch { //TODO: Error Handling provider.coordinator.hideLoading() diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+LoadOldestState.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+LoadOldestState.swift index 6c9ea1210..7c6d8a347 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+LoadOldestState.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel+LoadOldestState.swift @@ -9,6 +9,7 @@ import CoreDataStack import Foundation import GameplayKit import MastodonSDK +import MastodonCore extension NotificationTimelineViewModel { class LoadOldestState: GKState { @@ -51,8 +52,22 @@ extension NotificationTimelineViewModel.LoadOldestState { stateMachine.enter(Fail.self) return } - let scope = viewModel.scope + let scope: APIService.MastodonNotificationScope? + let accountID: String? + + switch viewModel.scope { + case .everything: + scope = .everything + accountID = nil + case .mentions: + scope = .mentions + accountID = nil + case .fromAccount(let account): + scope = nil + accountID = account.id + } + Task { let _maxID: Mastodon.Entity.Notification.ID? = lastFeedRecord.notification?.id @@ -64,8 +79,8 @@ extension NotificationTimelineViewModel.LoadOldestState { do { let response = try await viewModel.context.apiService.notifications( maxID: maxID, - //FIXME: Use correct scope for accounts - scope: .everything, + accountID: accountID, + scope: scope, authenticationBox: viewModel.authContext.mastodonAuthenticationBox ) diff --git a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift index c42bbe6be..653c597a8 100644 --- a/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift +++ b/Mastodon/Scene/Notification/NotificationTimeline/NotificationTimelineViewModel.swift @@ -48,7 +48,7 @@ final class NotificationTimelineViewModel { context: AppContext, authContext: AuthContext, scope: Scope, - notificationPolicy: Mastodon.Entity.NotificationPolicy? + notificationPolicy: Mastodon.Entity.NotificationPolicy? = nil ) { self.context = context self.authContext = authContext @@ -65,8 +65,7 @@ final class NotificationTimelineViewModel { self.dataController.records = (try? FileManager.default.cachedNotificationsMentions(for: authContext.mastodonAuthenticationBox))?.map({ notification in MastodonFeed.fromNotification(notification, relationship: nil, kind: .notificationMentions) }) ?? [] - case .fromAccount(let account): - //TODO: Implement + case .fromAccount(_): self.dataController.records = [] } @@ -84,14 +83,12 @@ final class NotificationTimelineViewModel { case .mentions: FileManager.default.cacheNotificationsMentions(items: items, for: authContext.mastodonAuthenticationBox) case .fromAccount(_): - //TODO: Implement + //TODO: we don't persist these break } }) .store(in: &disposeBag) } - - } extension NotificationTimelineViewModel { @@ -114,9 +111,8 @@ extension NotificationTimelineViewModel { dataController.loadInitial(kind: .notificationAll) case .mentions: dataController.loadInitial(kind: .notificationMentions) - case .fromAccount(_): - //TODO: Implement - break + case .fromAccount(let account): + dataController.loadInitial(kind: .notificationAccount(account.id)) } didLoadLatest.send() @@ -129,9 +125,8 @@ extension NotificationTimelineViewModel { dataController.loadNext(kind: .notificationAll) case .mentions: dataController.loadNext(kind: .notificationMentions) - case .fromAccount(_): - //TODO: Implement - break + case .fromAccount(let account): + dataController.loadNext(kind: .notificationAccount(account.id)) } } } diff --git a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift index ff7be6c43..d91a98c28 100644 --- a/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift +++ b/MastodonSDK/Sources/MastodonCore/DataController/FeedDataController.swift @@ -202,15 +202,14 @@ private extension FeedDataController { return try await getFeeds(with: .everything) case .notificationMentions: return try await getFeeds(with: .mentions) - case .notificationAccount: - //TODO: Implement, inject account - return [] + case .notificationAccount(let accountID): + return try await getFeeds(with: nil, accountID: accountID) } } - private func getFeeds(with scope: APIService.MastodonNotificationScope) async throws -> [MastodonFeed] { + private func getFeeds(with scope: APIService.MastodonNotificationScope?, accountID: String? = nil) async throws -> [MastodonFeed] { - let notifications = try await context.apiService.notifications(maxID: nil, scope: scope, authenticationBox: authContext.mastodonAuthenticationBox).value + let notifications = try await context.apiService.notifications(maxID: nil, accountID: accountID, scope: scope, authenticationBox: authContext.mastodonAuthenticationBox).value let accounts = notifications.map { $0.account } let relationships = try await context.apiService.relationship(forAccounts: accounts, authenticationBox: authContext.mastodonAuthenticationBox).value diff --git a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Notification.swift b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Notification.swift index fec0fe9f8..2497a64ea 100644 --- a/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Notification.swift +++ b/MastodonSDK/Sources/MastodonCore/Service/API/APIService+Notification.swift @@ -20,38 +20,32 @@ extension APIService { public func notifications( maxID: Mastodon.Entity.Status.ID?, - scope: MastodonNotificationScope, + accountID: String? = nil, + scope: MastodonNotificationScope?, authenticationBox: MastodonAuthenticationBox ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Notification]> { let authorization = authenticationBox.userAuthorization - + + let types: [Mastodon.Entity.Notification.NotificationType]? + let excludedTypes: [Mastodon.Entity.Notification.NotificationType]? + + switch scope { + case .everything: + types = [.follow, .followRequest, .mention, .reblog, .favourite, .poll, .status, .moderationWarning] + excludedTypes = nil + case .mentions: + types = [.mention] + excludedTypes = [.follow, .followRequest, .reblog, .favourite, .poll] + case nil: + types = nil + excludedTypes = nil + } + let query = Mastodon.API.Notifications.Query( maxID: maxID, - types: { - switch scope { - case .everything: - return [ - .follow, - .followRequest, - .mention, - .reblog, - .favourite, - .poll, - .status, - .moderationWarning - ] - case .mentions: - return [.mention] - } - }(), - excludeTypes: { - switch scope { - case .everything: - return nil - case .mentions: - return [.follow, .followRequest, .reblog, .favourite, .poll] - } - }() + types: types, + excludeTypes: excludedTypes, + accountID: accountID ) let response = try await Mastodon.API.Notifications.getNotifications( diff --git a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift index 5e0ad6656..df53767b3 100644 --- a/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift +++ b/MastodonSDK/Sources/MastodonSDK/MastodonFeed.swift @@ -10,7 +10,7 @@ public final class MastodonFeed { case home(timeline: TimelineContext) case notificationAll case notificationMentions - case notificationAccount + case notificationAccount(String) public enum TimelineContext: Equatable { case home