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
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)
}

View File

@ -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()

View File

@ -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
)

View File

@ -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))
}
}
}

View File

@ -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

View File

@ -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(

View File

@ -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