diff --git a/DB/Sources/DB/Content/AccountAndRelationshipInfo.swift b/DB/Sources/DB/Content/AccountAndRelationshipInfo.swift new file mode 100644 index 0000000..ea4905f --- /dev/null +++ b/DB/Sources/DB/Content/AccountAndRelationshipInfo.swift @@ -0,0 +1,20 @@ +// Copyright © 2021 Metabolist. All rights reserved. + +import Foundation +import GRDB +import Mastodon + +struct AccountAndRelationshipInfo: Codable, Hashable, FetchableRecord { + let accountInfo: AccountInfo + let relationship: Relationship? +} + +extension AccountAndRelationshipInfo { + static func addingIncludes(_ request: T) -> T where T.RowDecoder == AccountRecord { + AccountInfo.addingIncludes(request).including(optional: AccountRecord.relationship) + } + + static func request(_ request: QueryInterfaceRequest) -> QueryInterfaceRequest { + addingIncludes(request).asRequest(of: self) + } +} diff --git a/DB/Sources/DB/Content/AccountListItemsInfo.swift b/DB/Sources/DB/Content/AccountListItemsInfo.swift index e2c85d8..14b8847 100644 --- a/DB/Sources/DB/Content/AccountListItemsInfo.swift +++ b/DB/Sources/DB/Content/AccountListItemsInfo.swift @@ -6,12 +6,13 @@ import Mastodon struct AccountListItemsInfo: Codable, Hashable, FetchableRecord { let accountList: AccountList - let accountInfos: [AccountInfo] + let accountAndRelationshipInfos: [AccountAndRelationshipInfo] } extension AccountListItemsInfo { static func addingIncludes(_ request: T) -> T where T.RowDecoder == AccountList { - request.including(all: AccountInfo.addingIncludes(AccountList.accounts).forKey(CodingKeys.accountInfos)) + request.including(all: AccountAndRelationshipInfo.addingIncludes(AccountList.accounts) + .forKey(CodingKeys.accountAndRelationshipInfos)) } static func request(_ request: QueryInterfaceRequest) -> QueryInterfaceRequest { diff --git a/DB/Sources/DB/Content/ContentDatabase.swift b/DB/Sources/DB/Content/ContentDatabase.swift index 89c9174..8e29260 100644 --- a/DB/Sources/DB/Content/ContentDatabase.swift +++ b/DB/Sources/DB/Content/ContentDatabase.swift @@ -528,7 +528,11 @@ public extension ContentDatabase { AccountListItemsInfo.request(AccountList.filter(AccountList.Columns.id == id)).fetchOne) .removeDuplicates() .publisher(in: databaseWriter) - .map { $0?.accountInfos.map { CollectionItem.account(.init(info: $0), configuration, nil) } } + .map { + $0?.accountAndRelationshipInfos.map { + CollectionItem.account(.init(info: $0.accountInfo), configuration, $0.relationship) + } + } .replaceNil(with: []) .map { [CollectionSection(items: $0)] } .eraseToAnyPublisher() @@ -574,17 +578,17 @@ public extension ContentDatabase { let statusIds = results.statuses.map(\.id) let accountsPublisher = ValueObservation.tracking( - AccountInfo.request( + AccountAndRelationshipInfo.request( AccountRecord.filter(accountIds.contains(AccountRecord.Columns.id))) .fetchAll) .removeDuplicates() .publisher(in: databaseWriter) .map { infos -> [CollectionItem] in var accounts = infos.sorted { - accountIds.firstIndex(of: $0.record.id) ?? 0 - < accountIds.firstIndex(of: $1.record.id) ?? 0 + accountIds.firstIndex(of: $0.accountInfo.record.id) ?? 0 + < accountIds.firstIndex(of: $1.accountInfo.record.id) ?? 0 } - .map { CollectionItem.account(.init(info: $0), .withoutNote, nil) } // TODO: revisit + .map { CollectionItem.account(.init(info: $0.accountInfo), .withoutNote, $0.relationship) } if let limit = limit, accounts.count >= limit { accounts.append(.moreResults(.init(scope: .accounts))) diff --git a/DB/Sources/DB/Entities/Profile.swift b/DB/Sources/DB/Entities/Profile.swift index d258374..56d63ff 100644 --- a/DB/Sources/DB/Entities/Profile.swift +++ b/DB/Sources/DB/Entities/Profile.swift @@ -9,9 +9,9 @@ public struct Profile: Codable, Hashable { public let identityProofs: [IdentityProof] public let featuredTags: [FeaturedTag] - public init(account: Account) { + public init(account: Account, relationship: Relationship?) { self.account = account - self.relationship = nil + self.relationship = relationship self.identityProofs = [] self.featuredTags = [] } diff --git a/ServiceLayer/Sources/ServiceLayer/Services/NavigationService.swift b/ServiceLayer/Sources/ServiceLayer/Services/NavigationService.swift index 4b4b83d..4b5655c 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/NavigationService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/NavigationService.swift @@ -59,8 +59,11 @@ public extension NavigationService { ProfileService(id: id, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase) } - func profileService(account: Account) -> ProfileService { - ProfileService(account: account, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase) + func profileService(account: Account, relationship: Relationship? = nil) -> ProfileService { + ProfileService(account: account, + relationship: relationship, + mastodonAPIClient: mastodonAPIClient, + contentDatabase: contentDatabase) } func statusService(status: Status) -> StatusService { diff --git a/ServiceLayer/Sources/ServiceLayer/Services/ProfileService.swift b/ServiceLayer/Sources/ServiceLayer/Services/ProfileService.swift index e3b098f..e7bbe1a 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/ProfileService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/ProfileService.swift @@ -13,21 +13,30 @@ public struct ProfileService { private let mastodonAPIClient: MastodonAPIClient private let contentDatabase: ContentDatabase - init(account: Account, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) { + init(account: Account, + relationship: Relationship?, + mastodonAPIClient: MastodonAPIClient, + contentDatabase: ContentDatabase) { self.init( id: account.id, account: account, + relationship: relationship, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase) } init(id: Account.Id, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) { - self.init(id: id, account: nil, mastodonAPIClient: mastodonAPIClient, contentDatabase: contentDatabase) + self.init(id: id, + account: nil, + relationship: nil, + mastodonAPIClient: mastodonAPIClient, + contentDatabase: contentDatabase) } private init( id: Account.Id, account: Account?, + relationship: Relationship?, mastodonAPIClient: MastodonAPIClient, contentDatabase: ContentDatabase) { self.id = id @@ -38,7 +47,7 @@ public struct ProfileService { if let account = account { profilePublisher = profilePublisher - .merge(with: Just(Profile(account: account)).setFailureType(to: Error.self)) + .merge(with: Just(Profile(account: account, relationship: relationship)).setFailureType(to: Error.self)) .removeDuplicates() .eraseToAnyPublisher() } diff --git a/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift b/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift index 3312c8c..283d2e1 100644 --- a/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift @@ -141,7 +141,7 @@ extension CollectionItemsViewModel: CollectionViewModel { let item = lastUpdate.sections[indexPath.section].items[indexPath.item] switch item { - case let .status(status, _, relationship): + case let .status(status, _, _): send(event: .navigation(.collection(collectionService .navigationService .contextService(id: status.displayStatus.id)))) @@ -151,7 +151,7 @@ extension CollectionItemsViewModel: CollectionViewModel { case let .account(account, _, relationship): send(event: .navigation(.profile(collectionService .navigationService - .profileService(account: account)))) + .profileService(account: account, relationship: relationship)))) case let .notification(notification, _): if let status = notification.status { send(event: .navigation(.collection(collectionService