Use relationships in Report-process (IOS-192)
This commit is contained in:
parent
bb3ad77954
commit
47986262bc
|
@ -502,9 +502,7 @@ private extension SceneCoordinator {
|
||||||
_viewController.viewModel = viewModel
|
_viewController.viewModel = viewModel
|
||||||
viewController = _viewController
|
viewController = _viewController
|
||||||
case .report(let viewModel):
|
case .report(let viewModel):
|
||||||
let _viewController = ReportViewController()
|
viewController = ReportViewController(viewModel: viewModel)
|
||||||
_viewController.viewModel = viewModel
|
|
||||||
viewController = _viewController
|
|
||||||
case .reportServerRules(let viewModel):
|
case .reportServerRules(let viewModel):
|
||||||
let _viewController = ReportServerRulesViewController()
|
let _viewController = ReportServerRulesViewController()
|
||||||
_viewController.viewModel = viewModel
|
_viewController.viewModel = viewModel
|
||||||
|
|
|
@ -244,10 +244,13 @@ extension DataSourceFacade {
|
||||||
case .reportUser:
|
case .reportUser:
|
||||||
Task {
|
Task {
|
||||||
|
|
||||||
|
guard let relationship = try? await dependency.context.apiService.relationship(forAccounts: [menuContext.author], authenticationBox: dependency.authContext.mastodonAuthenticationBox).value.first else { return }
|
||||||
|
|
||||||
let reportViewModel = ReportViewModel(
|
let reportViewModel = ReportViewModel(
|
||||||
context: dependency.context,
|
context: dependency.context,
|
||||||
authContext: dependency.authContext,
|
authContext: dependency.authContext,
|
||||||
account: menuContext.author,
|
account: menuContext.author,
|
||||||
|
relationship: relationship,
|
||||||
status: menuContext.statusViewModel?.originalStatus
|
status: menuContext.statusViewModel?.originalStatus
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ class ReportViewController: UIViewController, NeedsDependency, ReportViewControl
|
||||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
var viewModel: ReportViewModel!
|
let viewModel: ReportViewModel
|
||||||
|
|
||||||
lazy var cancelBarButtonItem = UIBarButtonItem(
|
lazy var cancelBarButtonItem = UIBarButtonItem(
|
||||||
barButtonSystemItem: .cancel,
|
barButtonSystemItem: .cancel,
|
||||||
|
@ -28,10 +28,13 @@ class ReportViewController: UIViewController, NeedsDependency, ReportViewControl
|
||||||
action: #selector(ReportViewController.cancelBarButtonItemDidPressed(_:))
|
action: #selector(ReportViewController.cancelBarButtonItemDidPressed(_:))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
init(viewModel: ReportViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
|
||||||
}
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
}
|
||||||
|
|
||||||
extension ReportViewController {
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
@ -46,10 +49,9 @@ extension ReportViewController {
|
||||||
viewModel.reportStatusViewModel.delegate = self
|
viewModel.reportStatusViewModel.delegate = self
|
||||||
viewModel.reportSupplementaryViewModel.delegate = self
|
viewModel.reportSupplementaryViewModel.delegate = self
|
||||||
|
|
||||||
let reportReasonViewController = ReportReasonViewController()
|
let reportReasonViewController = ReportReasonViewController(viewModel: viewModel.reportReasonViewModel)
|
||||||
reportReasonViewController.context = context
|
reportReasonViewController.context = context
|
||||||
reportReasonViewController.coordinator = coordinator
|
reportReasonViewController.coordinator = coordinator
|
||||||
reportReasonViewController.viewModel = viewModel.reportReasonViewModel
|
|
||||||
|
|
||||||
addChild(reportReasonViewController)
|
addChild(reportReasonViewController)
|
||||||
reportReasonViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
reportReasonViewController.view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
@ -58,10 +60,6 @@ extension ReportViewController {
|
||||||
reportReasonViewController.view.pinToParent()
|
reportReasonViewController.view.pinToParent()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension ReportViewController {
|
|
||||||
|
|
||||||
@objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) {
|
@objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) {
|
||||||
dismiss(animated: true, completion: nil)
|
dismiss(animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
@ -85,6 +83,7 @@ extension ReportViewController: ReportReasonViewControllerDelegate {
|
||||||
context: context,
|
context: context,
|
||||||
authContext: viewModel.authContext,
|
authContext: viewModel.authContext,
|
||||||
account: viewModel.account,
|
account: viewModel.account,
|
||||||
|
relationship: viewModel.relationship,
|
||||||
isReported: false
|
isReported: false
|
||||||
)
|
)
|
||||||
_ = coordinator.present(
|
_ = coordinator.present(
|
||||||
|
@ -161,6 +160,7 @@ extension ReportViewController: ReportSupplementaryViewControllerDelegate {
|
||||||
context: context,
|
context: context,
|
||||||
authContext: viewModel.authContext,
|
authContext: viewModel.authContext,
|
||||||
account: viewModel.account,
|
account: viewModel.account,
|
||||||
|
relationship: viewModel.relationship,
|
||||||
isReported: true
|
isReported: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ReportViewModel {
|
||||||
let context: AppContext
|
let context: AppContext
|
||||||
let authContext: AuthContext
|
let authContext: AuthContext
|
||||||
let account: Mastodon.Entity.Account
|
let account: Mastodon.Entity.Account
|
||||||
|
let relationship: Mastodon.Entity.Relationship
|
||||||
let status: MastodonStatus?
|
let status: MastodonStatus?
|
||||||
|
|
||||||
// output
|
// output
|
||||||
|
@ -40,11 +41,13 @@ class ReportViewModel {
|
||||||
context: AppContext,
|
context: AppContext,
|
||||||
authContext: AuthContext,
|
authContext: AuthContext,
|
||||||
account: Mastodon.Entity.Account,
|
account: Mastodon.Entity.Account,
|
||||||
|
relationship: Mastodon.Entity.Relationship,
|
||||||
status: MastodonStatus?
|
status: MastodonStatus?
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.authContext = authContext
|
self.authContext = authContext
|
||||||
self.account = account
|
self.account = account
|
||||||
|
self.relationship = relationship
|
||||||
self.status = status
|
self.status = status
|
||||||
self.reportReasonViewModel = ReportReasonViewModel(context: context)
|
self.reportReasonViewModel = ReportReasonViewModel(context: context)
|
||||||
self.reportServerRulesViewModel = ReportServerRulesViewModel(context: context)
|
self.reportServerRulesViewModel = ReportServerRulesViewModel(context: context)
|
||||||
|
|
|
@ -25,8 +25,8 @@ final class ReportReasonViewController: UIViewController, NeedsDependency, Repor
|
||||||
var disposeBag = Set<AnyCancellable>()
|
var disposeBag = Set<AnyCancellable>()
|
||||||
private var observations = Set<NSKeyValueObservation>()
|
private var observations = Set<NSKeyValueObservation>()
|
||||||
|
|
||||||
var viewModel: ReportReasonViewModel!
|
let viewModel: ReportReasonViewModel
|
||||||
private(set) lazy var reportReasonView = ReportReasonView(viewModel: viewModel)
|
let reportReasonView: ReportReasonView
|
||||||
|
|
||||||
let navigationActionView: NavigationActionView = {
|
let navigationActionView: NavigationActionView = {
|
||||||
let navigationActionView = NavigationActionView()
|
let navigationActionView = NavigationActionView()
|
||||||
|
@ -35,10 +35,14 @@ final class ReportReasonViewController: UIViewController, NeedsDependency, Repor
|
||||||
return navigationActionView
|
return navigationActionView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
init(viewModel: ReportReasonViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
reportReasonView = ReportReasonView(viewModel: viewModel)
|
||||||
|
|
||||||
}
|
super.init(nibName: nil, bundle: nil)
|
||||||
|
}
|
||||||
|
|
||||||
extension ReportReasonViewController {
|
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct ReportResultView: View {
|
||||||
action: {
|
action: {
|
||||||
viewModel.followActionPublisher.send()
|
viewModel.followActionPublisher.send()
|
||||||
},
|
},
|
||||||
title: viewModel.relationshipViewModel.isFollowing ? L10n.Scene.Report.StepFinal.unfollow : L10n.Scene.Report.StepFinal.unfollowed,
|
title: viewModel.relationship.following ? L10n.Scene.Report.StepFinal.unfollow : L10n.Scene.Report.StepFinal.unfollowed,
|
||||||
isBusy: viewModel.isRequestFollow
|
isBusy: viewModel.isRequestFollow
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ struct ReportResultView: View {
|
||||||
action: {
|
action: {
|
||||||
viewModel.muteActionPublisher.send()
|
viewModel.muteActionPublisher.send()
|
||||||
},
|
},
|
||||||
title: viewModel.relationshipViewModel.isMuting ? L10n.Common.Controls.Friendship.muted : L10n.Common.Controls.Friendship.mute,
|
title: viewModel.relationship.muting ? L10n.Common.Controls.Friendship.muted : L10n.Common.Controls.Friendship.mute,
|
||||||
isBusy: viewModel.isRequestMute
|
isBusy: viewModel.isRequestMute
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ struct ReportResultView: View {
|
||||||
action: {
|
action: {
|
||||||
viewModel.blockActionPublisher.send()
|
viewModel.blockActionPublisher.send()
|
||||||
},
|
},
|
||||||
title: viewModel.relationshipViewModel.isBlocking ? L10n.Common.Controls.Friendship.blocked : L10n.Common.Controls.Friendship.block,
|
title: viewModel.relationship.blocking ? L10n.Common.Controls.Friendship.blocked : L10n.Common.Controls.Friendship.block,
|
||||||
isBusy: viewModel.isRequestBlock
|
isBusy: viewModel.isRequestBlock
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,11 @@ extension ReportResultViewController {
|
||||||
guard !self.viewModel.isRequestFollow else { return }
|
guard !self.viewModel.isRequestFollow else { return }
|
||||||
self.viewModel.isRequestFollow = true
|
self.viewModel.isRequestFollow = true
|
||||||
do {
|
do {
|
||||||
try await DataSourceFacade.responseToUserFollowAction(
|
let newRelationship = try await DataSourceFacade.responseToUserFollowAction(
|
||||||
dependency: self,
|
dependency: self,
|
||||||
account: self.viewModel.account
|
account: self.viewModel.account
|
||||||
)
|
)
|
||||||
|
self.viewModel.relationship = newRelationship
|
||||||
} catch {
|
} catch {
|
||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
|
@ -108,10 +109,11 @@ extension ReportResultViewController {
|
||||||
guard !self.viewModel.isRequestMute else { return }
|
guard !self.viewModel.isRequestMute else { return }
|
||||||
self.viewModel.isRequestMute = true
|
self.viewModel.isRequestMute = true
|
||||||
do {
|
do {
|
||||||
_ = try await DataSourceFacade.responseToUserMuteAction(
|
let newRelationship = try await DataSourceFacade.responseToUserMuteAction(
|
||||||
dependency: self,
|
dependency: self,
|
||||||
account: self.viewModel.account
|
account: self.viewModel.account
|
||||||
)
|
)
|
||||||
|
self.viewModel.relationship = newRelationship
|
||||||
} catch {
|
} catch {
|
||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
|
@ -128,10 +130,11 @@ extension ReportResultViewController {
|
||||||
guard !self.viewModel.isRequestBlock else { return }
|
guard !self.viewModel.isRequestBlock else { return }
|
||||||
self.viewModel.isRequestBlock = true
|
self.viewModel.isRequestBlock = true
|
||||||
do {
|
do {
|
||||||
_ = try await DataSourceFacade.responseToUserBlockAction(
|
let newRelationship = try await DataSourceFacade.responseToUserBlockAction(
|
||||||
dependency: self,
|
dependency: self,
|
||||||
account: self.viewModel.account
|
account: self.viewModel.account
|
||||||
)
|
)
|
||||||
|
self.viewModel.relationship = newRelationship
|
||||||
} catch {
|
} catch {
|
||||||
// handle error
|
// handle error
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ class ReportResultViewModel: ObservableObject {
|
||||||
let context: AppContext
|
let context: AppContext
|
||||||
let authContext: AuthContext
|
let authContext: AuthContext
|
||||||
let account: Mastodon.Entity.Account
|
let account: Mastodon.Entity.Account
|
||||||
|
var relationship: Mastodon.Entity.Relationship
|
||||||
let isReported: Bool
|
let isReported: Bool
|
||||||
|
|
||||||
var headline: String {
|
var headline: String {
|
||||||
|
@ -40,7 +41,6 @@ class ReportResultViewModel: ObservableObject {
|
||||||
@Published var avatarURL: URL?
|
@Published var avatarURL: URL?
|
||||||
@Published var username: String = ""
|
@Published var username: String = ""
|
||||||
|
|
||||||
let relationshipViewModel = RelationshipViewModel()
|
|
||||||
let muteActionPublisher = PassthroughSubject<Void, Never>()
|
let muteActionPublisher = PassthroughSubject<Void, Never>()
|
||||||
let followActionPublisher = PassthroughSubject<Void, Never>()
|
let followActionPublisher = PassthroughSubject<Void, Never>()
|
||||||
let blockActionPublisher = PassthroughSubject<Void, Never>()
|
let blockActionPublisher = PassthroughSubject<Void, Never>()
|
||||||
|
@ -49,11 +49,13 @@ class ReportResultViewModel: ObservableObject {
|
||||||
context: AppContext,
|
context: AppContext,
|
||||||
authContext: AuthContext,
|
authContext: AuthContext,
|
||||||
account: Mastodon.Entity.Account,
|
account: Mastodon.Entity.Account,
|
||||||
|
relationship: Mastodon.Entity.Relationship,
|
||||||
isReported: Bool
|
isReported: Bool
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.authContext = authContext
|
self.authContext = authContext
|
||||||
self.account = account
|
self.account = account
|
||||||
|
self.relationship = relationship
|
||||||
self.isReported = isReported
|
self.isReported = isReported
|
||||||
// end init
|
// end init
|
||||||
|
|
||||||
|
|
|
@ -94,25 +94,6 @@ extension ProfileRelationshipActionButton {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func configure(actionOptionSet: RelationshipActionOptionSet) {
|
|
||||||
setTitle(actionOptionSet.title, for: .normal)
|
|
||||||
|
|
||||||
configureAppearance()
|
|
||||||
|
|
||||||
titleEdgeInsets = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 4)
|
|
||||||
|
|
||||||
activityIndicatorView.stopAnimating()
|
|
||||||
|
|
||||||
if let option = actionOptionSet.highPriorityAction(except: .editOptions), option == .blocked || option == .suspended {
|
|
||||||
isEnabled = false
|
|
||||||
} else if actionOptionSet.contains(.updating) {
|
|
||||||
isEnabled = false
|
|
||||||
activityIndicatorView.startAnimating()
|
|
||||||
} else {
|
|
||||||
isEnabled = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func configureAppearance() {
|
private func configureAppearance() {
|
||||||
setTitleColor(Asset.Colors.Label.primaryReverse.color, for: .normal)
|
setTitleColor(Asset.Colors.Label.primaryReverse.color, for: .normal)
|
||||||
setTitleColor(Asset.Colors.Label.primaryReverse.color.withAlphaComponent(0.5), for: .highlighted)
|
setTitleColor(Asset.Colors.Label.primaryReverse.color.withAlphaComponent(0.5), for: .highlighted)
|
||||||
|
|
|
@ -1,269 +0,0 @@
|
||||||
//
|
|
||||||
// RelationshipViewModel.swift
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Created by MainasuK on 2022-4-14.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import Combine
|
|
||||||
import MastodonAsset
|
|
||||||
import MastodonLocalization
|
|
||||||
import CoreDataStack
|
|
||||||
|
|
||||||
public enum RelationshipAction: Int, CaseIterable {
|
|
||||||
case showReblogs
|
|
||||||
case isMyself
|
|
||||||
case followingBy
|
|
||||||
case blockingBy
|
|
||||||
case none // set hide from UI
|
|
||||||
case follow
|
|
||||||
case request
|
|
||||||
case pending
|
|
||||||
case following
|
|
||||||
case muting
|
|
||||||
case blocked
|
|
||||||
case blocking
|
|
||||||
case suspended
|
|
||||||
case edit
|
|
||||||
case editing
|
|
||||||
case updating
|
|
||||||
|
|
||||||
public var option: RelationshipActionOptionSet {
|
|
||||||
return RelationshipActionOptionSet(rawValue: 1 << rawValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct option set on the enum for safe iterator
|
|
||||||
public struct RelationshipActionOptionSet: OptionSet {
|
|
||||||
|
|
||||||
public let rawValue: Int
|
|
||||||
|
|
||||||
public init(rawValue: Int) {
|
|
||||||
self.rawValue = rawValue
|
|
||||||
}
|
|
||||||
|
|
||||||
public static let isMyself = RelationshipAction.isMyself.option
|
|
||||||
public static let followingBy = RelationshipAction.followingBy.option
|
|
||||||
public static let blockingBy = RelationshipAction.blockingBy.option
|
|
||||||
public static let none = RelationshipAction.none.option
|
|
||||||
public static let follow = RelationshipAction.follow.option
|
|
||||||
public static let request = RelationshipAction.request.option
|
|
||||||
public static let pending = RelationshipAction.pending.option
|
|
||||||
public static let following = RelationshipAction.following.option
|
|
||||||
public static let muting = RelationshipAction.muting.option
|
|
||||||
public static let blocked = RelationshipAction.blocked.option
|
|
||||||
public static let blocking = RelationshipAction.blocking.option
|
|
||||||
public static let suspended = RelationshipAction.suspended.option
|
|
||||||
public static let edit = RelationshipAction.edit.option
|
|
||||||
public static let editing = RelationshipAction.editing.option
|
|
||||||
public static let updating = RelationshipAction.updating.option
|
|
||||||
public static let showReblogs = RelationshipAction.showReblogs.option
|
|
||||||
public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating]
|
|
||||||
|
|
||||||
public func highPriorityAction(except: RelationshipActionOptionSet) -> RelationshipAction? {
|
|
||||||
let set = subtracting(except)
|
|
||||||
for action in RelationshipAction.allCases.reversed() where set.contains(action.option) {
|
|
||||||
return action
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
public var title: String {
|
|
||||||
guard let highPriorityAction = self.highPriorityAction(except: []) else {
|
|
||||||
assertionFailure()
|
|
||||||
return " "
|
|
||||||
}
|
|
||||||
switch highPriorityAction {
|
|
||||||
case .isMyself: return ""
|
|
||||||
case .followingBy: return " "
|
|
||||||
case .blockingBy: return " "
|
|
||||||
case .none: return " "
|
|
||||||
case .follow: return L10n.Common.Controls.Friendship.follow
|
|
||||||
case .request: return L10n.Common.Controls.Friendship.request
|
|
||||||
case .pending: return L10n.Common.Controls.Friendship.pending
|
|
||||||
case .following: return L10n.Common.Controls.Friendship.following
|
|
||||||
case .muting: return L10n.Common.Controls.Friendship.muted
|
|
||||||
case .blocked: return L10n.Common.Controls.Friendship.follow // blocked by user (deprecated)
|
|
||||||
case .blocking: return L10n.Common.Controls.Friendship.blocked
|
|
||||||
case .suspended: return L10n.Common.Controls.Friendship.follow
|
|
||||||
case .edit: return L10n.Common.Controls.Friendship.editInfo
|
|
||||||
case .editing: return L10n.Common.Controls.Actions.done
|
|
||||||
case .updating: return " "
|
|
||||||
case .showReblogs: return " "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, deprecated, message: "Replace with Mastodon.Entity.Relationship")
|
|
||||||
public final class RelationshipViewModel {
|
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
|
||||||
|
|
||||||
public var userObserver: AnyCancellable?
|
|
||||||
public var meObserver: AnyCancellable?
|
|
||||||
|
|
||||||
// input
|
|
||||||
@Published public var user: MastodonUser?
|
|
||||||
@Published public var me: MastodonUser?
|
|
||||||
public let relationshipUpdatePublisher = CurrentValueSubject<Void, Never>(Void()) // needs initial event
|
|
||||||
|
|
||||||
// output
|
|
||||||
@Published public var isMyself = false
|
|
||||||
@Published public var optionSet: RelationshipActionOptionSet?
|
|
||||||
|
|
||||||
@Published public var isFollowing = false
|
|
||||||
@Published public var isFollowingBy = false
|
|
||||||
@Published public var isMuting = false
|
|
||||||
@Published public var showReblogs = false
|
|
||||||
@Published public var isBlocking = false
|
|
||||||
@Published public var isBlockingBy = false
|
|
||||||
@Published public var isSuspended = false
|
|
||||||
|
|
||||||
public init() {
|
|
||||||
Publishers.CombineLatest3(
|
|
||||||
$user,
|
|
||||||
$me,
|
|
||||||
relationshipUpdatePublisher
|
|
||||||
)
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.sink { [weak self] user, me, _ in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.update(user: user, me: me)
|
|
||||||
|
|
||||||
guard let user = user, let me = me else {
|
|
||||||
self.userObserver = nil
|
|
||||||
self.meObserver = nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// do not modify object to prevent infinity loop
|
|
||||||
self.userObserver = RelationshipViewModel.createObjectChangePublisher(user: user)
|
|
||||||
.sink { [weak self] _ in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.relationshipUpdatePublisher.send()
|
|
||||||
}
|
|
||||||
|
|
||||||
self.meObserver = RelationshipViewModel.createObjectChangePublisher(user: me)
|
|
||||||
.sink { [weak self] _ in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.relationshipUpdatePublisher.send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.store(in: &disposeBag)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension RelationshipViewModel {
|
|
||||||
|
|
||||||
public static func createObjectChangePublisher(user: MastodonUser) -> AnyPublisher<Void, Never> {
|
|
||||||
return ManagedObjectObserver
|
|
||||||
.observe(object: user)
|
|
||||||
.map { _ in Void() }
|
|
||||||
.catch { error in
|
|
||||||
return Just(Void())
|
|
||||||
}
|
|
||||||
.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension RelationshipViewModel {
|
|
||||||
private func update(user: MastodonUser?, me: MastodonUser?) {
|
|
||||||
guard let user = user,
|
|
||||||
let me = me
|
|
||||||
else {
|
|
||||||
reset()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let optionSet = RelationshipViewModel.optionSet(user: user, me: me)
|
|
||||||
|
|
||||||
self.isMyself = optionSet.contains(.isMyself)
|
|
||||||
self.isFollowingBy = optionSet.contains(.followingBy)
|
|
||||||
self.isFollowing = optionSet.contains(.following)
|
|
||||||
self.isMuting = optionSet.contains(.muting)
|
|
||||||
self.isBlockingBy = optionSet.contains(.blockingBy)
|
|
||||||
self.isBlocking = optionSet.contains(.blocking)
|
|
||||||
self.isSuspended = optionSet.contains(.suspended)
|
|
||||||
self.showReblogs = optionSet.contains(.showReblogs)
|
|
||||||
|
|
||||||
self.optionSet = optionSet
|
|
||||||
}
|
|
||||||
|
|
||||||
private func reset() {
|
|
||||||
isMyself = false
|
|
||||||
isFollowingBy = false
|
|
||||||
isFollowing = false
|
|
||||||
isMuting = false
|
|
||||||
isBlockingBy = false
|
|
||||||
isBlocking = false
|
|
||||||
optionSet = nil
|
|
||||||
showReblogs = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension RelationshipViewModel {
|
|
||||||
|
|
||||||
public static func optionSet(user: MastodonUser, me: MastodonUser) -> RelationshipActionOptionSet {
|
|
||||||
let isMyself = user.id == me.id && user.domain == me.domain
|
|
||||||
guard !isMyself else {
|
|
||||||
return [.isMyself, .edit]
|
|
||||||
}
|
|
||||||
|
|
||||||
let isProtected = user.locked
|
|
||||||
let isFollowingBy = me.followingBy.contains(user)
|
|
||||||
let isFollowing = user.followingBy.contains(me)
|
|
||||||
let isPending = user.followRequestedBy.contains(me)
|
|
||||||
let isMuting = user.mutingBy.contains(me)
|
|
||||||
let isBlockingBy = me.blockingBy.contains(user)
|
|
||||||
let isBlocking = user.blockingBy.contains(me)
|
|
||||||
let isShowingReblogs = me.showingReblogsBy.contains(user)
|
|
||||||
|
|
||||||
var optionSet: RelationshipActionOptionSet = [.follow]
|
|
||||||
|
|
||||||
if isMyself {
|
|
||||||
optionSet.insert(.isMyself)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isProtected {
|
|
||||||
optionSet.insert(.request)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isFollowingBy {
|
|
||||||
optionSet.insert(.followingBy)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isFollowing {
|
|
||||||
optionSet.insert(.following)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isPending {
|
|
||||||
optionSet.insert(.pending)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isMuting {
|
|
||||||
optionSet.insert(.muting)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isBlockingBy {
|
|
||||||
optionSet.insert(.blockingBy)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isBlocking {
|
|
||||||
optionSet.insert(.blocking)
|
|
||||||
}
|
|
||||||
|
|
||||||
if user.suspended {
|
|
||||||
optionSet.insert(.suspended)
|
|
||||||
}
|
|
||||||
|
|
||||||
if isShowingReblogs {
|
|
||||||
optionSet.insert(.showReblogs)
|
|
||||||
}
|
|
||||||
|
|
||||||
return optionSet
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue