Show notifications from one account (IOS-241)

This commit is contained in:
Nathan Mattes 2024-07-17 18:04:22 +02:00
parent b424dab5b5
commit fb3dfb5a6a
7 changed files with 55 additions and 51 deletions

View File

@ -209,7 +209,7 @@ extension SceneCoordinator {
// Notifications // Notifications
case notificationPolicy(viewModel: NotificationFilterViewModel) case notificationPolicy(viewModel: NotificationFilterViewModel)
case notificationRequests(viewModel: NotificationRequestsViewModel) case notificationRequests(viewModel: NotificationRequestsViewModel)
case notificationtimeline(viewModel: NotificationTimelineViewModel) case notificationTimeline(viewModel: NotificationTimelineViewModel)
// report // report
case report(viewModel: ReportViewModel) case report(viewModel: ReportViewModel)
@ -568,7 +568,7 @@ private extension SceneCoordinator {
viewController = NotificationRequestsTableViewController(viewModel: viewModel, appContext: appContext, coordinator: self) viewController = NotificationRequestsTableViewController(viewModel: viewModel, appContext: appContext, coordinator: self)
case .notificationPolicy(let viewModel): case .notificationPolicy(let viewModel):
viewController = NotificationPolicyViewController(viewModel: viewModel) viewController = NotificationPolicyViewController(viewModel: viewModel)
case .notificationtimeline(let viewModel): case .notificationTimeline(let viewModel):
viewController = NotificationTimelineViewController(viewModel: viewModel, context: appContext, coordinator: self) viewController = NotificationTimelineViewController(viewModel: viewModel, context: appContext, coordinator: self)
} }

View File

@ -32,11 +32,12 @@ extension DataSourceFacade {
provider.coordinator.showLoading() provider.coordinator.showLoading()
do { do {
// load notifications for request.account // load notifications for request.account
// show NotificationTimelineViewController with NotificationTimelineViewModel // show NotificationTimelineViewController with NotificationTimelineViewModel
let notificationTimelineViewModel = NotificationTimelineViewModel(context: provider.context, authContext: provider.authContext, scope: .fromAccount(request.account))
provider.coordinator.hideLoading() provider.coordinator.hideLoading()
provider.coordinator.present(scene: .notificationTimeline(viewModel: notificationTimelineViewModel), transition: .show)
} catch { } catch {
//TODO: Error Handling //TODO: Error Handling
provider.coordinator.hideLoading() provider.coordinator.hideLoading()

View File

@ -9,6 +9,7 @@ import CoreDataStack
import Foundation import Foundation
import GameplayKit import GameplayKit
import MastodonSDK import MastodonSDK
import MastodonCore
extension NotificationTimelineViewModel { extension NotificationTimelineViewModel {
class LoadOldestState: GKState { class LoadOldestState: GKState {
@ -51,8 +52,22 @@ extension NotificationTimelineViewModel.LoadOldestState {
stateMachine.enter(Fail.self) stateMachine.enter(Fail.self)
return 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 { Task {
let _maxID: Mastodon.Entity.Notification.ID? = lastFeedRecord.notification?.id let _maxID: Mastodon.Entity.Notification.ID? = lastFeedRecord.notification?.id
@ -64,8 +79,8 @@ extension NotificationTimelineViewModel.LoadOldestState {
do { do {
let response = try await viewModel.context.apiService.notifications( let response = try await viewModel.context.apiService.notifications(
maxID: maxID, maxID: maxID,
//FIXME: Use correct scope for accounts accountID: accountID,
scope: .everything, scope: scope,
authenticationBox: viewModel.authContext.mastodonAuthenticationBox authenticationBox: viewModel.authContext.mastodonAuthenticationBox
) )

View File

@ -48,7 +48,7 @@ final class NotificationTimelineViewModel {
context: AppContext, context: AppContext,
authContext: AuthContext, authContext: AuthContext,
scope: Scope, scope: Scope,
notificationPolicy: Mastodon.Entity.NotificationPolicy? notificationPolicy: Mastodon.Entity.NotificationPolicy? = nil
) { ) {
self.context = context self.context = context
self.authContext = authContext self.authContext = authContext
@ -65,8 +65,7 @@ final class NotificationTimelineViewModel {
self.dataController.records = (try? FileManager.default.cachedNotificationsMentions(for: authContext.mastodonAuthenticationBox))?.map({ notification in self.dataController.records = (try? FileManager.default.cachedNotificationsMentions(for: authContext.mastodonAuthenticationBox))?.map({ notification in
MastodonFeed.fromNotification(notification, relationship: nil, kind: .notificationMentions) MastodonFeed.fromNotification(notification, relationship: nil, kind: .notificationMentions)
}) ?? [] }) ?? []
case .fromAccount(let account): case .fromAccount(_):
//TODO: Implement
self.dataController.records = [] self.dataController.records = []
} }
@ -84,14 +83,12 @@ final class NotificationTimelineViewModel {
case .mentions: case .mentions:
FileManager.default.cacheNotificationsMentions(items: items, for: authContext.mastodonAuthenticationBox) FileManager.default.cacheNotificationsMentions(items: items, for: authContext.mastodonAuthenticationBox)
case .fromAccount(_): case .fromAccount(_):
//TODO: Implement //TODO: we don't persist these
break break
} }
}) })
.store(in: &disposeBag) .store(in: &disposeBag)
} }
} }
extension NotificationTimelineViewModel { extension NotificationTimelineViewModel {
@ -114,9 +111,8 @@ extension NotificationTimelineViewModel {
dataController.loadInitial(kind: .notificationAll) dataController.loadInitial(kind: .notificationAll)
case .mentions: case .mentions:
dataController.loadInitial(kind: .notificationMentions) dataController.loadInitial(kind: .notificationMentions)
case .fromAccount(_): case .fromAccount(let account):
//TODO: Implement dataController.loadInitial(kind: .notificationAccount(account.id))
break
} }
didLoadLatest.send() didLoadLatest.send()
@ -129,9 +125,8 @@ extension NotificationTimelineViewModel {
dataController.loadNext(kind: .notificationAll) dataController.loadNext(kind: .notificationAll)
case .mentions: case .mentions:
dataController.loadNext(kind: .notificationMentions) dataController.loadNext(kind: .notificationMentions)
case .fromAccount(_): case .fromAccount(let account):
//TODO: Implement dataController.loadNext(kind: .notificationAccount(account.id))
break
} }
} }
} }

View File

@ -202,15 +202,14 @@ private extension FeedDataController {
return try await getFeeds(with: .everything) return try await getFeeds(with: .everything)
case .notificationMentions: case .notificationMentions:
return try await getFeeds(with: .mentions) return try await getFeeds(with: .mentions)
case .notificationAccount: case .notificationAccount(let accountID):
//TODO: Implement, inject account return try await getFeeds(with: nil, accountID: accountID)
return []
} }
} }
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 accounts = notifications.map { $0.account }
let relationships = try await context.apiService.relationship(forAccounts: accounts, authenticationBox: authContext.mastodonAuthenticationBox).value let relationships = try await context.apiService.relationship(forAccounts: accounts, authenticationBox: authContext.mastodonAuthenticationBox).value

View File

@ -20,38 +20,32 @@ extension APIService {
public func notifications( public func notifications(
maxID: Mastodon.Entity.Status.ID?, maxID: Mastodon.Entity.Status.ID?,
scope: MastodonNotificationScope, accountID: String? = nil,
scope: MastodonNotificationScope?,
authenticationBox: MastodonAuthenticationBox authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Notification]> { ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Notification]> {
let authorization = authenticationBox.userAuthorization 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( let query = Mastodon.API.Notifications.Query(
maxID: maxID, maxID: maxID,
types: { types: types,
switch scope { excludeTypes: excludedTypes,
case .everything: accountID: accountID
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]
}
}()
) )
let response = try await Mastodon.API.Notifications.getNotifications( let response = try await Mastodon.API.Notifications.getNotifications(

View File

@ -10,7 +10,7 @@ public final class MastodonFeed {
case home(timeline: TimelineContext) case home(timeline: TimelineContext)
case notificationAll case notificationAll
case notificationMentions case notificationMentions
case notificationAccount case notificationAccount(String)
public enum TimelineContext: Equatable { public enum TimelineContext: Equatable {
case home case home