165 lines
6.5 KiB
Swift
165 lines
6.5 KiB
Swift
//
|
|
// DataSourceFacade+Follow.swift
|
|
// Mastodon
|
|
//
|
|
// Created by MainasuK on 2022-1-24.
|
|
//
|
|
|
|
import UIKit
|
|
import CoreDataStack
|
|
import class CoreDataStack.Notification
|
|
import MastodonCore
|
|
import MastodonSDK
|
|
import MastodonLocalization
|
|
|
|
extension DataSourceFacade {
|
|
static func responseToUserFollowAction(
|
|
dependency: NeedsDependency & AuthContextProvider,
|
|
user: ManagedObjectRecord<MastodonUser>
|
|
) async throws {
|
|
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
|
|
await selectionFeedbackGenerator.selectionChanged()
|
|
|
|
_ = try await dependency.context.apiService.toggleFollow(
|
|
user: user,
|
|
authenticationBox: dependency.authContext.mastodonAuthenticationBox
|
|
)
|
|
dependency.context.authenticationService.fetchFollowingAndBlockedAsync()
|
|
}
|
|
|
|
static func responseToUserFollowAction(
|
|
dependency: NeedsDependency & AuthContextProvider,
|
|
user: Mastodon.Entity.Account
|
|
) async throws -> Mastodon.Entity.Relationship {
|
|
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
|
|
await selectionFeedbackGenerator.selectionChanged()
|
|
|
|
let response = try await dependency.context.apiService.toggleFollow(
|
|
user: user,
|
|
authenticationBox: dependency.authContext.mastodonAuthenticationBox
|
|
).value
|
|
|
|
dependency.context.authenticationService.fetchFollowingAndBlockedAsync()
|
|
|
|
return response
|
|
}
|
|
|
|
}
|
|
|
|
extension DataSourceFacade {
|
|
static func responseToUserFollowRequestAction(
|
|
dependency: NeedsDependency & AuthContextProvider,
|
|
notification: ManagedObjectRecord<Notification>,
|
|
query: Mastodon.API.Account.FollowRequestQuery
|
|
) async throws {
|
|
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
|
|
await selectionFeedbackGenerator.selectionChanged()
|
|
|
|
let managedObjectContext = dependency.context.managedObjectContext
|
|
let _userID: MastodonUser.ID? = try await managedObjectContext.perform {
|
|
guard let notification = notification.object(in: managedObjectContext) else { return nil }
|
|
return notification.account.id
|
|
}
|
|
|
|
guard let userID = _userID else {
|
|
assertionFailure()
|
|
throw APIService.APIError.implicit(.badRequest)
|
|
}
|
|
|
|
let state: MastodonFollowRequestState = try await managedObjectContext.perform {
|
|
guard let notification = notification.object(in: managedObjectContext) else { return .init(state: .none) }
|
|
return notification.followRequestState
|
|
}
|
|
|
|
guard state.state == .none else {
|
|
return
|
|
}
|
|
|
|
try? await managedObjectContext.performChanges {
|
|
guard let notification = notification.object(in: managedObjectContext) else { return }
|
|
switch query {
|
|
case .accept:
|
|
notification.transientFollowRequestState = .init(state: .isAccepting)
|
|
case .reject:
|
|
notification.transientFollowRequestState = .init(state: .isRejecting)
|
|
}
|
|
}
|
|
|
|
do {
|
|
_ = try await dependency.context.apiService.followRequest(
|
|
userID: userID,
|
|
query: query,
|
|
authenticationBox: dependency.authContext.mastodonAuthenticationBox
|
|
)
|
|
} catch {
|
|
// reset state when failure
|
|
try? await managedObjectContext.performChanges {
|
|
guard let notification = notification.object(in: managedObjectContext) else { return }
|
|
notification.transientFollowRequestState = .init(state: .none)
|
|
}
|
|
|
|
if let error = error as? Mastodon.API.Error {
|
|
switch error.httpResponseStatus {
|
|
case .notFound:
|
|
let backgroundManagedObjectContext = dependency.context.backgroundManagedObjectContext
|
|
try await backgroundManagedObjectContext.performChanges {
|
|
guard let notification = notification.object(in: backgroundManagedObjectContext) else { return }
|
|
for feed in notification.feeds {
|
|
backgroundManagedObjectContext.delete(feed)
|
|
}
|
|
backgroundManagedObjectContext.delete(notification)
|
|
}
|
|
default:
|
|
let alertController = await UIAlertController(for: error, title: nil, preferredStyle: .alert)
|
|
let okAction = await UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default)
|
|
await alertController.addAction(okAction)
|
|
_ = await dependency.coordinator.present(
|
|
scene: .alertController(alertController: alertController),
|
|
from: nil,
|
|
transition: .alertController(animated: true, completion: nil)
|
|
)
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
try? await managedObjectContext.performChanges {
|
|
guard let notification = notification.object(in: managedObjectContext) else { return }
|
|
switch query {
|
|
case .accept:
|
|
notification.transientFollowRequestState = .init(state: .isAccept)
|
|
case .reject:
|
|
// do nothing due to will delete notification
|
|
break
|
|
}
|
|
}
|
|
|
|
let backgroundManagedObjectContext = dependency.context.backgroundManagedObjectContext
|
|
try? await backgroundManagedObjectContext.performChanges {
|
|
guard let notification = notification.object(in: backgroundManagedObjectContext) else { return }
|
|
switch query {
|
|
case .accept:
|
|
notification.followRequestState = .init(state: .isAccept)
|
|
case .reject:
|
|
// delete notification
|
|
for feed in notification.feeds {
|
|
backgroundManagedObjectContext.delete(feed)
|
|
}
|
|
backgroundManagedObjectContext.delete(notification)
|
|
}
|
|
}
|
|
} // end func
|
|
}
|
|
|
|
extension DataSourceFacade {
|
|
static func responseToShowHideReblogAction(
|
|
dependency: NeedsDependency & AuthContextProvider,
|
|
user: ManagedObjectRecord<MastodonUser>
|
|
) async throws {
|
|
_ = try await dependency.context.apiService.toggleShowReblogs(
|
|
for: user,
|
|
authenticationBox: dependency.authContext.mastodonAuthenticationBox)
|
|
}
|
|
}
|