Implement MastodonAccountInMemoryCache (I)OS-140)
This commit is contained in:
parent
9d2e8eca16
commit
c7c635d32a
|
@ -22,8 +22,8 @@ extension FollowingListViewModel {
|
|||
configuration: UserSection.Configuration(
|
||||
userTableViewCellDelegate: userTableViewCellDelegate
|
||||
),
|
||||
followedUsers: followedUserIds.eraseToAnyPublisher(),
|
||||
blockedUsers: blockedUserIds.eraseToAnyPublisher()
|
||||
followedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$followingUserIds.eraseToAnyPublisher(),
|
||||
blockedUsers: authContext.mastodonAuthenticationBox.inMemoryCache.$blockedUserIds.eraseToAnyPublisher()
|
||||
)
|
||||
|
||||
// workaround to append loader wrong animation issue
|
||||
|
|
|
@ -69,7 +69,8 @@ extension SendPostIntentHandler: SendPostIntentHandling {
|
|||
domain: authentication.domain,
|
||||
userID: authentication.userID,
|
||||
appAuthorization: .init(accessToken: authentication.appAccessToken),
|
||||
userAuthorization: .init(accessToken: authentication.userAccessToken)
|
||||
userAuthorization: .init(accessToken: authentication.userAccessToken),
|
||||
inMemoryCache: .sharedCache(for: authentication.objectID.description)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -15,19 +15,22 @@ public struct MastodonAuthenticationBox: UserIdentifier {
|
|||
public let userID: MastodonUser.ID
|
||||
public let appAuthorization: Mastodon.API.OAuth.Authorization
|
||||
public let userAuthorization: Mastodon.API.OAuth.Authorization
|
||||
|
||||
public let inMemoryCache: MastodonAccountInMemoryCache
|
||||
|
||||
public init(
|
||||
authenticationRecord: ManagedObjectRecord<MastodonAuthentication>,
|
||||
domain: String,
|
||||
userID: MastodonUser.ID,
|
||||
appAuthorization: Mastodon.API.OAuth.Authorization,
|
||||
userAuthorization: Mastodon.API.OAuth.Authorization
|
||||
userAuthorization: Mastodon.API.OAuth.Authorization,
|
||||
inMemoryCache: MastodonAccountInMemoryCache
|
||||
) {
|
||||
self.authenticationRecord = authenticationRecord
|
||||
self.domain = domain
|
||||
self.userID = userID
|
||||
self.appAuthorization = appAuthorization
|
||||
self.userAuthorization = userAuthorization
|
||||
self.inMemoryCache = inMemoryCache
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,8 +42,26 @@ extension MastodonAuthenticationBox {
|
|||
domain: authentication.domain,
|
||||
userID: authentication.userID,
|
||||
appAuthorization: Mastodon.API.OAuth.Authorization(accessToken: authentication.appAccessToken),
|
||||
userAuthorization: Mastodon.API.OAuth.Authorization(accessToken: authentication.userAccessToken)
|
||||
userAuthorization: Mastodon.API.OAuth.Authorization(accessToken: authentication.userAccessToken),
|
||||
inMemoryCache: .sharedCache(for: authentication.objectID.description)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MastodonAccountInMemoryCache {
|
||||
@Published public var followingUserIds: [String] = []
|
||||
@Published public var blockedUserIds: [String] = []
|
||||
|
||||
static var sharedCaches = [String: MastodonAccountInMemoryCache]()
|
||||
|
||||
public static func sharedCache(for key: String) -> MastodonAccountInMemoryCache {
|
||||
if let sharedCache = sharedCaches[key] {
|
||||
return sharedCache
|
||||
}
|
||||
|
||||
let sharedCache = MastodonAccountInMemoryCache()
|
||||
sharedCaches[key] = sharedCache
|
||||
return sharedCache
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@ import CoreData
|
|||
import CoreDataStack
|
||||
import MastodonSDK
|
||||
|
||||
private typealias IterativeResponse = (ids: [String], maxID: String?)
|
||||
|
||||
public final class AuthenticationService: NSObject {
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
|
@ -25,6 +27,46 @@ public final class AuthenticationService: NSObject {
|
|||
// output
|
||||
@Published public var mastodonAuthentications: [ManagedObjectRecord<MastodonAuthentication>] = []
|
||||
@Published public var mastodonAuthenticationBoxes: [MastodonAuthenticationBox] = []
|
||||
|
||||
private func fetchFollowedBlockedUserIds(
|
||||
_ authBox: MastodonAuthenticationBox,
|
||||
_ previousFollowingIDs: [String]? = nil,
|
||||
_ maxID: String? = nil
|
||||
) async throws {
|
||||
guard let apiService = apiService else { return }
|
||||
|
||||
let followingResponse = try await fetchFollowing(maxID, apiService, authBox)
|
||||
let followingIds = (previousFollowingIDs ?? []) + followingResponse.ids
|
||||
|
||||
if let nextMaxID = followingResponse.maxID {
|
||||
return try await fetchFollowedBlockedUserIds(authBox, followingIds, nextMaxID)
|
||||
}
|
||||
|
||||
let blockedIds = try await apiService.getBlocked(
|
||||
authenticationBox: authBox
|
||||
).value.map { $0.id }
|
||||
|
||||
authBox.inMemoryCache.followingUserIds = followingIds
|
||||
authBox.inMemoryCache.blockedUserIds = blockedIds
|
||||
}
|
||||
|
||||
private func fetchFollowing(
|
||||
_ maxID: String?,
|
||||
_ apiService: APIService,
|
||||
_ mastodonAuthenticationBox: MastodonAuthenticationBox
|
||||
) async throws -> IterativeResponse {
|
||||
let response = try await apiService.following(
|
||||
userID: mastodonAuthenticationBox.userID,
|
||||
maxID: maxID,
|
||||
authenticationBox: mastodonAuthenticationBox
|
||||
)
|
||||
|
||||
let ids: [String] = response.value.map { $0.id }
|
||||
let maxID: String? = response.link?.maxID
|
||||
|
||||
return (ids, maxID)
|
||||
}
|
||||
|
||||
public let updateActiveUserAccountPublisher = PassthroughSubject<Void, Never>()
|
||||
|
||||
init(
|
||||
|
@ -50,6 +92,18 @@ public final class AuthenticationService: NSObject {
|
|||
super.init()
|
||||
|
||||
mastodonAuthenticationFetchedResultsController.delegate = self
|
||||
|
||||
$mastodonAuthenticationBoxes
|
||||
.sink { [weak self] boxes in
|
||||
Task { [weak self] in
|
||||
for authBox in boxes {
|
||||
do { try await self?.fetchFollowedBlockedUserIds(authBox) }
|
||||
catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
|
||||
// TODO: verify credentials for active authentication
|
||||
|
||||
|
|
|
@ -267,7 +267,8 @@ extension NotificationService {
|
|||
domain: authentication.domain,
|
||||
userID: authentication.userID,
|
||||
appAuthorization: .init(accessToken: authentication.appAccessToken),
|
||||
userAuthorization: .init(accessToken: authentication.userAccessToken)
|
||||
userAuthorization: .init(accessToken: authentication.userAccessToken),
|
||||
inMemoryCache: .sharedCache(for: authentication.objectID.description)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue