User UserIdentification for search and accounts (IOS-192)
Thanks to @kimar!
This commit is contained in:
parent
2a14e293e9
commit
460ede4852
|
@ -27,7 +27,7 @@ extension DataSourceFacade {
|
|||
hashtag: nil
|
||||
)
|
||||
|
||||
try? FileManager.default.addSearchItem(searchEntry)
|
||||
try? FileManager.default.addSearchItem(searchEntry, for: provider.authContext.mastodonAuthenticationBox)
|
||||
case .hashtag(let tag):
|
||||
|
||||
let now = Date()
|
||||
|
@ -39,7 +39,7 @@ extension DataSourceFacade {
|
|||
hashtag: tag
|
||||
)
|
||||
|
||||
try? FileManager.default.addSearchItem(searchEntry)
|
||||
try? FileManager.default.addSearchItem(searchEntry, for: provider.authContext.mastodonAuthenticationBox)
|
||||
case .status:
|
||||
break
|
||||
case .user(_):
|
||||
|
|
|
@ -139,30 +139,23 @@ class MastodonLoginViewController: UIViewController, NeedsDependency {
|
|||
|
||||
@objc func login() {
|
||||
guard let server = viewModel.selectedServer else { return }
|
||||
|
||||
|
||||
authenticationViewModel
|
||||
.authenticated
|
||||
.asyncMap { domain, user -> Result<Mastodon.Entity.Account, Error> in
|
||||
do {
|
||||
let result = try await self.context.authenticationService.activeMastodonUser(domain: domain, userID: user.id)
|
||||
return .success(user)
|
||||
} catch {
|
||||
return .failure(error)
|
||||
}
|
||||
}
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
assertionFailure(error.localizedDescription)
|
||||
case .success(let account):
|
||||
FileManager.default.store(account: account, forUserID: account.id)
|
||||
self.coordinator.setup()
|
||||
.authenticated.sink { (domain, account) in
|
||||
Task {
|
||||
do {
|
||||
_ = try await self.context.authenticationService.activeMastodonUser(domain: domain, userID: account.id)
|
||||
FileManager.default.store(account: account, forUserID: MastodonUserIdentifier(domain: domain, userID: account.id))
|
||||
Task { @MainActor in
|
||||
self.coordinator.setup()
|
||||
}
|
||||
} catch {
|
||||
assertionFailure(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
|
||||
authenticationViewModel.isAuthenticating.send(true)
|
||||
context.apiService.createApplication(domain: server.domain)
|
||||
.tryMap { response -> AuthenticationViewModel.AuthenticateInfo in
|
||||
|
|
|
@ -50,8 +50,7 @@ extension SearchHistoryViewController {
|
|||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
let userID = authContext.mastodonAuthenticationBox.userID
|
||||
viewModel.items = (try? FileManager.default.searchItems(forUser: userID)) ?? []
|
||||
viewModel.items = (try? FileManager.default.searchItems(for: authContext.mastodonAuthenticationBox)) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,9 +102,7 @@ extension SearchHistoryViewController: SearchHistorySectionHeaderCollectionReusa
|
|||
_ searchHistorySectionHeaderCollectionReusableView: SearchHistorySectionHeaderCollectionReusableView,
|
||||
clearButtonDidPressed button: UIButton
|
||||
) {
|
||||
let userID = authContext.mastodonAuthenticationBox.userID
|
||||
|
||||
FileManager.default.removeSearchHistory(forUser: userID)
|
||||
FileManager.default.removeSearchHistory(for: authContext.mastodonAuthenticationBox)
|
||||
viewModel.items = []
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +110,6 @@ extension SearchHistoryViewController: SearchHistorySectionHeaderCollectionReusa
|
|||
//MARK: - SearchResultOverviewCoordinatorDelegate
|
||||
extension SearchHistoryViewController: SearchResultOverviewCoordinatorDelegate {
|
||||
func newSearchHistoryItemAdded(_ coordinator: SearchResultOverviewCoordinator) {
|
||||
let userID = authContext.mastodonAuthenticationBox.userID
|
||||
viewModel.items = (try? FileManager.default.searchItems(forUser: userID)) ?? []
|
||||
viewModel.items = (try? FileManager.default.searchItems(for: authContext.mastodonAuthenticationBox)) ?? []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ final class SearchHistoryViewModel {
|
|||
init(context: AppContext, authContext: AuthContext) {
|
||||
self.context = context
|
||||
self.authContext = authContext
|
||||
self.items = (try? FileManager.default.searchItems(forUser: authContext.mastodonAuthenticationBox.userID)) ?? []
|
||||
self.items = (try? FileManager.default.searchItems(for: authContext.mastodonAuthenticationBox)) ?? []
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ public extension AuthenticationServiceProvider {
|
|||
userID: authentication.userID,
|
||||
authorization: Mastodon.API.OAuth.Authorization(accessToken: authentication.userAccessToken)).value else { continue }
|
||||
|
||||
FileManager.default.store(account: account, forUserID: authentication.userID)
|
||||
FileManager.default.store(account: account, forUserID: authentication.userIdentifier())
|
||||
}
|
||||
|
||||
NotificationCenter.default.post(name: .userFetched, object: nil)
|
||||
|
|
|
@ -100,11 +100,19 @@ public struct MastodonAuthentication: Codable, Hashable {
|
|||
}
|
||||
|
||||
public func account() -> Mastodon.Entity.Account? {
|
||||
let account = FileManager.default.accounts(forUserID: userID).first(where: { $0.id == userID })
|
||||
|
||||
let account = FileManager
|
||||
.default
|
||||
.accounts(for: self.userIdentifier())
|
||||
.first(where: { $0.id == userID })
|
||||
|
||||
return account
|
||||
}
|
||||
|
||||
public func userIdentifier() -> MastodonUserIdentifier {
|
||||
MastodonUserIdentifier(domain: domain, userID: userID)
|
||||
}
|
||||
|
||||
func updating(instance: Instance) -> Self {
|
||||
copy(instanceObjectIdURI: instance.objectID.uriRepresentation())
|
||||
}
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
import Foundation
|
||||
import MastodonSDK
|
||||
|
||||
extension FileManager {
|
||||
public func store(account: Mastodon.Entity.Account, forUserID userID: String) {
|
||||
// store accounts for each loged in user
|
||||
var accounts = accounts(forUserID: userID)
|
||||
public extension FileManager {
|
||||
func store(account: Mastodon.Entity.Account, forUserID userID: UserIdentifier) {
|
||||
var accounts = accounts(for: userID)
|
||||
|
||||
if let index = accounts.firstIndex(of: account) {
|
||||
accounts.remove(at: index)
|
||||
|
@ -17,10 +16,10 @@ extension FileManager {
|
|||
storeJSON(accounts, userID: userID)
|
||||
}
|
||||
|
||||
public func accounts(forUserID userID: String) -> [Mastodon.Entity.Account] {
|
||||
func accounts(for userId: UserIdentifier) -> [Mastodon.Entity.Account] {
|
||||
guard let documentsDirectory else { return [] }
|
||||
|
||||
let accountPath = Persistence.accounts(userID: userID).filepath(baseURL: documentsDirectory)
|
||||
let accountPath = Persistence.accounts(userId).filepath(baseURL: documentsDirectory)
|
||||
|
||||
guard let data = try? Data(contentsOf: accountPath) else { return [] }
|
||||
|
||||
|
@ -35,8 +34,10 @@ extension FileManager {
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private func storeJSON(_ encodable: Encodable, userID: String) {
|
||||
private extension FileManager {
|
||||
private func storeJSON(_ encodable: Encodable, userID: UserIdentifier) {
|
||||
guard let documentsDirectory else { return }
|
||||
|
||||
let jsonEncoder = JSONEncoder()
|
||||
|
@ -44,7 +45,7 @@ extension FileManager {
|
|||
do {
|
||||
let data = try jsonEncoder.encode(encodable)
|
||||
|
||||
let accountsPath = Persistence.accounts(userID: userID).filepath(baseURL: documentsDirectory)
|
||||
let accountsPath = Persistence.accounts( userID).filepath(baseURL: documentsDirectory)
|
||||
try data.write(to: accountsPath)
|
||||
} catch {
|
||||
debugPrint(error.localizedDescription)
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
// Copyright © 2023 Mastodon gGmbH. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import MastodonCore
|
||||
|
||||
extension FileManager {
|
||||
public func searchItems(forUser userID: String) throws -> [Persistence.SearchHistory.Item] {
|
||||
return try searchItems().filter { $0.userID == userID }
|
||||
}
|
||||
|
||||
public func searchItems() throws -> [Persistence.SearchHistory.Item] {
|
||||
public extension FileManager {
|
||||
func searchItems(for userId: UserIdentifier) throws -> [Persistence.SearchHistory.Item] {
|
||||
guard let documentsDirectory else { return [] }
|
||||
|
||||
let searchHistoryPath = Persistence.searchHistory.filepath(baseURL: documentsDirectory)
|
||||
let searchHistoryPath = Persistence.searchHistory(userId).filepath(baseURL: documentsDirectory)
|
||||
|
||||
guard let data = try? Data(contentsOf: searchHistoryPath) else { return [] }
|
||||
|
||||
|
@ -28,16 +23,23 @@ extension FileManager {
|
|||
}
|
||||
}
|
||||
|
||||
public func addSearchItem(_ newSearchItem: Persistence.SearchHistory.Item) throws {
|
||||
var searchItems = (try? searchItems()) ?? []
|
||||
func addSearchItem(_ newSearchItem: Persistence.SearchHistory.Item, for userId: UserIdentifier) throws {
|
||||
var searchItems = (try? searchItems(for: userId)) ?? []
|
||||
|
||||
if let index = searchItems.firstIndex(of: newSearchItem) {
|
||||
searchItems.remove(at: index)
|
||||
}
|
||||
|
||||
|
||||
searchItems.append(newSearchItem)
|
||||
|
||||
storeJSON(searchItems, .searchHistory)
|
||||
storeJSON(searchItems, .searchHistory(userId))
|
||||
}
|
||||
|
||||
func removeSearchHistory(for userId: UserIdentifier) {
|
||||
let searchItems = (try? searchItems(for: userId)) ?? []
|
||||
let newSearchItems = searchItems.filter { $0.userID != userId.userID }
|
||||
|
||||
storeJSON(newSearchItems, .searchHistory(userId))
|
||||
}
|
||||
|
||||
private func storeJSON(_ encodable: Encodable, _ persistence: Persistence) {
|
||||
|
@ -53,13 +55,5 @@ extension FileManager {
|
|||
} catch {
|
||||
debugPrint(error.localizedDescription)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public func removeSearchHistory(forUser userID: String) {
|
||||
let searchItems = (try? searchItems()) ?? []
|
||||
let newSearchItems = searchItems.filter { $0.userID != userID }
|
||||
|
||||
storeJSON(newSearchItems, .searchHistory)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
import Foundation
|
||||
|
||||
public enum Persistence {
|
||||
case searchHistory
|
||||
case searchHistory(UserIdentifier)
|
||||
case homeTimeline(UserIdentifier)
|
||||
case notificationsMentions(UserIdentifier)
|
||||
case notificationsAll(UserIdentifier)
|
||||
case accounts(userID: String)
|
||||
case accounts(UserIdentifier)
|
||||
|
||||
private func uniqueUserDomainIdentifier(for userIdentifier: UserIdentifier) -> String {
|
||||
"\(userIdentifier.userID)@\(userIdentifier.domain)"
|
||||
|
@ -21,16 +21,16 @@ public enum Persistence {
|
|||
|
||||
private var filename: String {
|
||||
switch self {
|
||||
case .searchHistory:
|
||||
return "search_history" // todo: @zeitschlag should this be user-scoped as well?
|
||||
case .searchHistory(let userIdentifier):
|
||||
return "search_history_\(uniqueUserDomainIdentifier(for: userIdentifier))" // todo: @zeitschlag should this be user-scoped as well?
|
||||
case let .homeTimeline(userIdentifier):
|
||||
return "home_timeline_\(userIdentifier.uniqueUserDomainIdentifier)"
|
||||
return "home_timeline_\(uniqueUserDomainIdentifier(for: userIdentifier))"
|
||||
case let .notificationsMentions(userIdentifier):
|
||||
return "notifications_mentions_\(userIdentifier.uniqueUserDomainIdentifier)"
|
||||
case let .notificationsAll(userIdentifier):
|
||||
return "notifications_all_\(uniqueUserDomainIdentifier(for: userIdentifier))"
|
||||
case .accounts(let userID):
|
||||
return "account_\(userID)"
|
||||
case .accounts(let userIdentifier):
|
||||
return "account_\(uniqueUserDomainIdentifier(for: userIdentifier))"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue