Use authenticated domain for API calls. Modify URL scheme

This commit is contained in:
jinsu kim 2023-01-01 15:55:54 -08:00
parent de962a0c09
commit 5c82c04232
4 changed files with 67 additions and 67 deletions

View File

@ -17,42 +17,40 @@ final class RemoteProfileViewModel: ProfileViewModel {
init(context: AppContext, authContext: AuthContext, userID: Mastodon.Entity.Account.ID) {
super.init(context: context, authContext: authContext, optionalMastodonUser: nil)
Task { @MainActor in
let domain = authContext.mastodonAuthenticationBox.domain
let authorization = authContext.mastodonAuthenticationBox.userAuthorization
Just(userID)
.asyncMap { userID in
try await context.apiService.accountInfo(
domain: domain,
userID: userID,
authorization: authorization
)
let domain = authContext.mastodonAuthenticationBox.domain
let authorization = authContext.mastodonAuthenticationBox.userAuthorization
Just(userID)
.asyncMap { userID in
try await context.apiService.accountInfo(
domain: domain,
userID: userID,
authorization: authorization
)
}
.retry(3)
.sink { completion in
switch completion {
case .failure(let error):
// TODO: handle error
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription)
case .finished:
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID)
}
.retry(3)
.sink { completion in
switch completion {
case .failure(let error):
// TODO: handle error
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetch failed: %s", ((#file as NSString).lastPathComponent), #line, #function, userID, error.localizedDescription)
case .finished:
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: remote user %s fetched", ((#file as NSString).lastPathComponent), #line, #function, userID)
}
} receiveValue: { [weak self] response in
guard let self = self else { return }
let managedObjectContext = context.managedObjectContext
let request = MastodonUser.sortedFetchRequest
request.fetchLimit = 1
request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id)
guard let mastodonUser = managedObjectContext.safeFetch(request).first else {
assertionFailure()
return
}
DispatchQueue.main.async {
self.user = mastodonUser
}
} receiveValue: { [weak self] response in
guard let self = self else { return }
let managedObjectContext = context.managedObjectContext
let request = MastodonUser.sortedFetchRequest
request.fetchLimit = 1
request.predicate = MastodonUser.predicate(domain: domain, id: response.value.id)
guard let mastodonUser = managedObjectContext.safeFetch(request).first else {
assertionFailure()
return
}
.store(in: &disposeBag)
}
DispatchQueue.main.async {
self.user = mastodonUser
}
}
.store(in: &disposeBag)
}
init(context: AppContext, authContext: AuthContext, notificationID: Mastodon.Entity.Notification.ID) {

View File

@ -77,8 +77,7 @@ extension ThreadViewModel.LoadThreadState {
do {
let response = try await viewModel.context.apiService.statusContext(
statusID: threadContext.statusID,
authenticationBox: viewModel.authContext.mastodonAuthenticationBox,
domain: threadContext.domain
authenticationBox: viewModel.authContext.mastodonAuthenticationBox
)
await enter(state: NoMore.self)

View File

@ -245,29 +245,17 @@ extension SceneDelegate {
print("source application = \(sendingAppID ?? "Unknown")")
print("url = \(url)")
if let username = url.user {
guard let host = url.host else { return }
switch url.host {
case "post":
showComposeViewController()
case "profile":
let components = url.pathComponents
if components.count == 3 && components[1] == "status" {
let statusId = components[2]
// View post from user
print("view status \(statusId)")
if let authContext = coordinator?.authContext {
Task {
guard let thread = try await AppContext.shared.apiService.fetchThread(
statusID: statusId,
domain: host,
authenticationBox: authContext.mastodonAuthenticationBox
) else { return }
let threadViewModel = CachedThreadViewModel(context: AppContext.shared,
authContext: authContext,
status: thread)
coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
}
}
} else {
print("view profile \(username)@\(host)")
if components.count == 2 && components[0] == "/" {
let addr = components[1]
let tokens = addr.components(separatedBy: "@")
if tokens.count != 2 { return }
let username = tokens[0]
let host = tokens[1]
if let authContext = coordinator?.authContext {
Task { @MainActor in
guard let user = try await AppContext.shared.apiService.fetchUser(
@ -287,12 +275,28 @@ extension SceneDelegate {
}
}
}
} else {
guard let action = url.host else { return }
if action == "post" {
print("make post")
showComposeViewController()
case "status":
let components = url.pathComponents
if components.count == 2 && components[0] == "/" {
let statusId = components[1]
// View post from user
print("view status \(statusId)")
if let authContext = coordinator?.authContext {
Task {
guard let thread = try await AppContext.shared.apiService.fetchThread(
statusID: statusId,
authenticationBox: authContext.mastodonAuthenticationBox
) else { return }
let threadViewModel = CachedThreadViewModel(context: AppContext.shared,
authContext: authContext,
status: thread)
coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
}
}
}
default:
return
}
}
}

View File

@ -16,10 +16,9 @@ extension APIService {
public func statusContext(
statusID: Mastodon.Entity.Status.ID,
authenticationBox: MastodonAuthenticationBox,
domain: String? = nil
authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<Mastodon.Entity.Context> {
let domain = domain ?? authenticationBox.domain
let domain = authenticationBox.domain
let authorization = authenticationBox.userAuthorization
let response = try await Mastodon.API.Statuses.statusContext(
@ -54,9 +53,9 @@ extension APIService {
public func fetchThread(
statusID: Mastodon.Entity.Status.ID,
domain: String,
authenticationBox: MastodonAuthenticationBox
) async throws -> Status? {
let domain = authenticationBox.domain
let authorization = authenticationBox.userAuthorization
let managedObjectContext = self.backgroundManagedObjectContext