2021-04-02 12:13:45 +02:00
|
|
|
//
|
|
|
|
// UserProviderFacade.swift
|
|
|
|
// Mastodon
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021-4-1.
|
|
|
|
//
|
|
|
|
|
|
|
|
import UIKit
|
|
|
|
import Combine
|
|
|
|
import CoreData
|
|
|
|
import CoreDataStack
|
|
|
|
import MastodonSDK
|
|
|
|
|
|
|
|
enum UserProviderFacade { }
|
|
|
|
|
|
|
|
extension UserProviderFacade {
|
|
|
|
|
|
|
|
static func toggleUserFollowRelationship(
|
|
|
|
provider: UserProvider
|
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
// prepare authentication
|
|
|
|
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
|
|
|
assertionFailure()
|
|
|
|
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
|
|
|
}
|
|
|
|
|
|
|
|
return _toggleUserFollowRelationship(
|
|
|
|
context: provider.context,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
mastodonUser: provider.mastodonUser().eraseToAnyPublisher()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
private static func _toggleUserFollowRelationship(
|
|
|
|
context: AppContext,
|
|
|
|
activeMastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox,
|
|
|
|
mastodonUser: AnyPublisher<MastodonUser?, Never>
|
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
mastodonUser
|
|
|
|
.compactMap { mastodonUser -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>? in
|
|
|
|
guard let mastodonUser = mastodonUser else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return context.apiService.toggleFollow(
|
|
|
|
for: mastodonUser,
|
2021-04-21 08:46:31 +02:00
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
needFeedback: true
|
2021-04-02 12:13:45 +02:00
|
|
|
)
|
|
|
|
}
|
|
|
|
.switchToLatest()
|
|
|
|
.eraseToAnyPublisher()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extension UserProviderFacade {
|
|
|
|
|
|
|
|
static func toggleUserBlockRelationship(
|
2021-04-28 13:56:30 +02:00
|
|
|
provider: UserProvider,
|
|
|
|
cell: UITableViewCell?,
|
|
|
|
indexPath: IndexPath?
|
2021-04-02 12:13:45 +02:00
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
// prepare authentication
|
|
|
|
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
|
|
|
assertionFailure()
|
|
|
|
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
|
|
|
}
|
2021-04-28 13:56:30 +02:00
|
|
|
if let cell = cell, let indexPath = indexPath {
|
|
|
|
return _toggleUserBlockRelationship(
|
|
|
|
context: provider.context,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
mastodonUser: provider.mastodonUser(for: cell, indexPath: indexPath).eraseToAnyPublisher()
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return _toggleUserBlockRelationship(
|
|
|
|
context: provider.context,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
mastodonUser: provider.mastodonUser().eraseToAnyPublisher()
|
|
|
|
)
|
|
|
|
}
|
2021-04-02 12:13:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static func _toggleUserBlockRelationship(
|
|
|
|
context: AppContext,
|
|
|
|
activeMastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox,
|
|
|
|
mastodonUser: AnyPublisher<MastodonUser?, Never>
|
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
mastodonUser
|
|
|
|
.compactMap { mastodonUser -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>? in
|
|
|
|
guard let mastodonUser = mastodonUser else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return context.apiService.toggleBlock(
|
|
|
|
for: mastodonUser,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.switchToLatest()
|
|
|
|
.eraseToAnyPublisher()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extension UserProviderFacade {
|
|
|
|
|
|
|
|
static func toggleUserMuteRelationship(
|
2021-04-28 13:56:30 +02:00
|
|
|
provider: UserProvider,
|
|
|
|
cell: UITableViewCell?,
|
|
|
|
indexPath: IndexPath?
|
2021-04-02 12:13:45 +02:00
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
// prepare authentication
|
|
|
|
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
|
|
|
assertionFailure()
|
|
|
|
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
|
|
|
}
|
2021-04-28 13:56:30 +02:00
|
|
|
if let cell = cell, let indexPath = indexPath {
|
|
|
|
return _toggleUserMuteRelationship(
|
|
|
|
context: provider.context,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
mastodonUser: provider.mastodonUser(for: cell, indexPath: indexPath).eraseToAnyPublisher()
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
return _toggleUserMuteRelationship(
|
|
|
|
context: provider.context,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox,
|
|
|
|
mastodonUser: provider.mastodonUser().eraseToAnyPublisher()
|
|
|
|
)
|
|
|
|
}
|
2021-04-02 12:13:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private static func _toggleUserMuteRelationship(
|
|
|
|
context: AppContext,
|
|
|
|
activeMastodonAuthenticationBox: AuthenticationService.MastodonAuthenticationBox,
|
|
|
|
mastodonUser: AnyPublisher<MastodonUser?, Never>
|
|
|
|
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error> {
|
|
|
|
mastodonUser
|
|
|
|
.compactMap { mastodonUser -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>? in
|
|
|
|
guard let mastodonUser = mastodonUser else {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return context.apiService.toggleMute(
|
|
|
|
for: mastodonUser,
|
|
|
|
activeMastodonAuthenticationBox: activeMastodonAuthenticationBox
|
|
|
|
)
|
|
|
|
}
|
|
|
|
.switchToLatest()
|
|
|
|
.eraseToAnyPublisher()
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
extension UserProviderFacade {
|
|
|
|
|
|
|
|
static func createProfileActionMenu(
|
|
|
|
for mastodonUser: MastodonUser,
|
|
|
|
isMuting: Bool,
|
|
|
|
isBlocking: Bool,
|
2021-04-28 13:56:30 +02:00
|
|
|
canReport: Bool,
|
2021-04-08 12:52:35 +02:00
|
|
|
provider: UserProvider,
|
2021-04-28 13:56:30 +02:00
|
|
|
cell: UITableViewCell?,
|
|
|
|
indexPath: IndexPath?,
|
2021-04-08 12:52:35 +02:00
|
|
|
sourceView: UIView?,
|
2021-04-28 13:56:30 +02:00
|
|
|
barButtonItem: UIBarButtonItem?,
|
|
|
|
shareUser: MastodonUser?,
|
|
|
|
shareStatus: Status?
|
2021-04-02 12:13:45 +02:00
|
|
|
) -> UIMenu {
|
|
|
|
var children: [UIMenuElement] = []
|
|
|
|
let name = mastodonUser.displayNameWithFallback
|
|
|
|
|
|
|
|
// mute
|
|
|
|
let muteAction = UIAction(
|
|
|
|
title: isMuting ? L10n.Common.Controls.Firendship.unmuteUser(name) : L10n.Common.Controls.Firendship.mute,
|
|
|
|
image: isMuting ? UIImage(systemName: "speaker") : UIImage(systemName: "speaker.slash"),
|
|
|
|
discoverabilityTitle: isMuting ? nil : L10n.Common.Controls.Firendship.muteUser(name),
|
|
|
|
attributes: isMuting ? [] : .destructive,
|
|
|
|
state: .off
|
|
|
|
) { [weak provider] _ in
|
|
|
|
guard let provider = provider else { return }
|
|
|
|
|
|
|
|
UserProviderFacade.toggleUserMuteRelationship(
|
2021-04-28 13:56:30 +02:00
|
|
|
provider: provider,
|
|
|
|
cell: cell,
|
|
|
|
indexPath: indexPath
|
2021-04-02 12:13:45 +02:00
|
|
|
)
|
|
|
|
.sink { _ in
|
|
|
|
// do nothing
|
|
|
|
} receiveValue: { _ in
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
.store(in: &provider.context.disposeBag)
|
|
|
|
}
|
|
|
|
if isMuting {
|
|
|
|
children.append(muteAction)
|
|
|
|
} else {
|
|
|
|
let muteMenu = UIMenu(title: L10n.Common.Controls.Firendship.muteUser(name), image: UIImage(systemName: "speaker.slash"), options: [], children: [muteAction])
|
|
|
|
children.append(muteMenu)
|
|
|
|
}
|
|
|
|
|
|
|
|
// block
|
|
|
|
let blockAction = UIAction(
|
|
|
|
title: isBlocking ? L10n.Common.Controls.Firendship.unblockUser(name) : L10n.Common.Controls.Firendship.block,
|
|
|
|
image: isBlocking ? UIImage(systemName: "hand.raised.slash") : UIImage(systemName: "hand.raised"),
|
|
|
|
discoverabilityTitle: isBlocking ? nil : L10n.Common.Controls.Firendship.blockUser(name),
|
|
|
|
attributes: isBlocking ? [] : .destructive,
|
|
|
|
state: .off
|
|
|
|
) { [weak provider] _ in
|
|
|
|
guard let provider = provider else { return }
|
|
|
|
|
|
|
|
UserProviderFacade.toggleUserBlockRelationship(
|
2021-04-28 13:56:30 +02:00
|
|
|
provider: provider,
|
|
|
|
cell: cell,
|
|
|
|
indexPath: indexPath
|
2021-04-02 12:13:45 +02:00
|
|
|
)
|
|
|
|
.sink { _ in
|
|
|
|
// do nothing
|
|
|
|
} receiveValue: { _ in
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
.store(in: &provider.context.disposeBag)
|
|
|
|
}
|
|
|
|
if isBlocking {
|
|
|
|
children.append(blockAction)
|
|
|
|
} else {
|
|
|
|
let blockMenu = UIMenu(title: L10n.Common.Controls.Firendship.blockUser(name), image: UIImage(systemName: "hand.raised"), options: [], children: [blockAction])
|
|
|
|
children.append(blockMenu)
|
|
|
|
}
|
2021-04-28 13:56:30 +02:00
|
|
|
if canReport {
|
|
|
|
let reportAction = UIAction(title: L10n.Common.Controls.Actions.reportUser(name), image: UIImage(systemName: "flag"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
|
|
|
guard let provider = provider else { return }
|
|
|
|
guard let authenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
let viewModel = ReportViewModel(
|
|
|
|
context: provider.context,
|
|
|
|
domain: authenticationBox.domain,
|
|
|
|
user: mastodonUser,
|
|
|
|
status: nil)
|
|
|
|
provider.coordinator.present(
|
|
|
|
scene: .report(viewModel: viewModel),
|
|
|
|
from: provider,
|
|
|
|
transition: .modal(animated: true, completion: nil)
|
|
|
|
)
|
2021-04-26 09:58:49 +02:00
|
|
|
}
|
2021-04-28 13:56:30 +02:00
|
|
|
children.append(reportAction)
|
2021-04-26 09:58:49 +02:00
|
|
|
}
|
|
|
|
|
2021-04-28 13:56:30 +02:00
|
|
|
if let shareUser = shareUser {
|
2021-04-28 10:18:20 +02:00
|
|
|
let shareAction = UIAction(title: L10n.Common.Controls.Actions.shareUser(name), image: UIImage(systemName: "square.and.arrow.up"), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off) { [weak provider] _ in
|
|
|
|
guard let provider = provider else { return }
|
2021-04-28 13:56:30 +02:00
|
|
|
let activityViewController = createActivityViewControllerForMastodonUser(mastodonUser: shareUser, dependency: provider)
|
2021-04-28 10:18:20 +02:00
|
|
|
provider.coordinator.present(
|
|
|
|
scene: .activityViewController(
|
|
|
|
activityViewController: activityViewController,
|
|
|
|
sourceView: sourceView,
|
|
|
|
barButtonItem: barButtonItem
|
|
|
|
),
|
|
|
|
from: provider,
|
|
|
|
transition: .activityViewControllerPresent(animated: true, completion: nil)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
children.append(shareAction)
|
|
|
|
}
|
|
|
|
|
2021-04-02 12:13:45 +02:00
|
|
|
return UIMenu(title: "", options: [], children: children)
|
|
|
|
}
|
|
|
|
|
2021-04-08 12:52:35 +02:00
|
|
|
static func createActivityViewControllerForMastodonUser(mastodonUser: MastodonUser, dependency: NeedsDependency) -> UIActivityViewController {
|
|
|
|
let activityViewController = UIActivityViewController(
|
|
|
|
activityItems: mastodonUser.activityItems,
|
|
|
|
applicationActivities: [SafariActivity(sceneCoordinator: dependency.coordinator)]
|
|
|
|
)
|
|
|
|
return activityViewController
|
|
|
|
}
|
|
|
|
|
2021-04-02 12:13:45 +02:00
|
|
|
}
|