Add block-action to profile-menu (IOS-5)
This commit is contained in:
parent
30314cdd34
commit
7a67b595a3
@ -394,8 +394,48 @@ extension DataSourceFacade {
|
|||||||
|
|
||||||
try await DataSourceFacade.responseToUserFollowAction(dependency: dependency,
|
try await DataSourceFacade.responseToUserFollowAction(dependency: dependency,
|
||||||
user: author)
|
user: author)
|
||||||
|
case .blockDomain(let context):
|
||||||
|
let title: String
|
||||||
|
let message: String
|
||||||
|
let actionTitle: String
|
||||||
|
|
||||||
|
#warning("Localization")
|
||||||
|
if context.isBlocking {
|
||||||
|
title = "Unblock \(context.domain)"
|
||||||
|
message = "Really unblock \(context.domain)"
|
||||||
|
actionTitle = L10n.Common.Controls.Friendship.unblockUser(context.domain)
|
||||||
|
} else {
|
||||||
|
title = "Block \(context.domain)"
|
||||||
|
message = "Really block \(context.domain)"
|
||||||
|
actionTitle = L10n.Common.Controls.Friendship.blockUser(context.domain)
|
||||||
|
}
|
||||||
|
let alertController = UIAlertController(
|
||||||
|
title: title,
|
||||||
|
message: message,
|
||||||
|
preferredStyle: .alert
|
||||||
|
)
|
||||||
|
|
||||||
|
let confirmAction = UIAlertAction(title: actionTitle, style: .destructive ) { [weak dependency] _ in
|
||||||
|
guard let dependency = dependency else { return }
|
||||||
|
Task {
|
||||||
|
let managedObjectContext = dependency.context.managedObjectContext
|
||||||
|
let _user: ManagedObjectRecord<MastodonUser>? = try? await managedObjectContext.perform {
|
||||||
|
guard let user = menuContext.author?.object(in: managedObjectContext) else { return nil }
|
||||||
|
return ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
|
||||||
|
}
|
||||||
|
guard let user = _user else { return }
|
||||||
|
try await DataSourceFacade.responseToDomainBlockAction(
|
||||||
|
dependency: dependency,
|
||||||
|
user: user
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alertController.addAction(confirmAction)
|
||||||
|
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
dependency.present(alertController, animated: true)
|
||||||
}
|
}
|
||||||
} // end func
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension DataSourceFacade {
|
extension DataSourceFacade {
|
||||||
|
@ -395,16 +395,16 @@ extension ProfileViewController {
|
|||||||
viewModel.relationshipViewModel.$optionSet
|
viewModel.relationshipViewModel.$optionSet
|
||||||
)
|
)
|
||||||
.asyncMap { [weak self] user, relationshipSet -> UIMenu? in
|
.asyncMap { [weak self] user, relationshipSet -> UIMenu? in
|
||||||
guard let self = self else { return nil }
|
guard let self, let user else { return nil }
|
||||||
guard let user = user else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
let name = user.displayNameWithFallback
|
let name = user.displayNameWithFallback
|
||||||
|
let domain = user.domainFromAcct
|
||||||
let _ = ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
|
let _ = ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
|
||||||
|
|
||||||
var menuActions: [MastodonMenu.Action] = [
|
var menuActions: [MastodonMenu.Action] = [
|
||||||
.muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)),
|
.muteUser(.init(name: name, isMuting: self.viewModel.relationshipViewModel.isMuting)),
|
||||||
.blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)),
|
.blockUser(.init(name: name, isBlocking: self.viewModel.relationshipViewModel.isBlocking)),
|
||||||
|
.blockDomain(.init(domain: domain, isBlocking: self.viewModel.relationshipViewModel.isDomainBlocking)),
|
||||||
.reportUser(.init(name: name)),
|
.reportUser(.init(name: name)),
|
||||||
.shareUser(.init(name: name)),
|
.shareUser(.init(name: name)),
|
||||||
]
|
]
|
||||||
@ -829,6 +829,27 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
|
|||||||
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
|
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
|
||||||
alertController.addAction(cancelAction)
|
alertController.addAction(cancelAction)
|
||||||
present(alertController, animated: true, completion: nil)
|
present(alertController, animated: true, completion: nil)
|
||||||
|
case .domainBlocking:
|
||||||
|
guard let user = viewModel.user else { return }
|
||||||
|
let name = user.displayNameWithFallback
|
||||||
|
|
||||||
|
let alertController = UIAlertController(
|
||||||
|
title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.title,
|
||||||
|
message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.message(name),
|
||||||
|
preferredStyle: .alert
|
||||||
|
)
|
||||||
|
let record = ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
|
||||||
|
let unblockAction = UIAlertAction(title: L10n.Common.Controls.Friendship.unblock, style: .default) { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
Task {
|
||||||
|
try await DataSourceFacade.responseToDomainBlockAction(dependency: self, user: record)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alertController.addAction(unblockAction)
|
||||||
|
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
present(alertController, animated: true, completion: nil)
|
||||||
|
|
||||||
case .blocking:
|
case .blocking:
|
||||||
guard let user = viewModel.user else { return }
|
guard let user = viewModel.user else { return }
|
||||||
let name = user.displayNameWithFallback
|
let name = user.displayNameWithFallback
|
||||||
|
@ -59,7 +59,8 @@ extension MastodonMenu {
|
|||||||
case deleteStatus
|
case deleteStatus
|
||||||
case editStatus
|
case editStatus
|
||||||
case followUser(FollowUserActionContext)
|
case followUser(FollowUserActionContext)
|
||||||
|
case blockDomain(BlockDomainActionContext)
|
||||||
|
|
||||||
func build(delegate: MastodonMenuDelegate) -> LabeledAction {
|
func build(delegate: MastodonMenuDelegate) -> LabeledAction {
|
||||||
switch self {
|
switch self {
|
||||||
case .hideReblogs(let context):
|
case .hideReblogs(let context):
|
||||||
@ -194,14 +195,30 @@ extension MastodonMenu {
|
|||||||
image = UIImage(systemName: "person.fill.badge.plus")
|
image = UIImage(systemName: "person.fill.badge.plus")
|
||||||
}
|
}
|
||||||
let action = LabeledAction(title: title, image: image) { [weak delegate] in
|
let action = LabeledAction(title: title, image: image) { [weak delegate] in
|
||||||
guard let delegate = delegate else { return }
|
guard let delegate else { return }
|
||||||
delegate.menuAction(self)
|
delegate.menuAction(self)
|
||||||
}
|
}
|
||||||
return action
|
return action
|
||||||
|
case .blockDomain(let context):
|
||||||
|
let title: String
|
||||||
|
let image: UIImage?
|
||||||
|
//TODO: Add localization
|
||||||
|
if context.isBlocking {
|
||||||
|
title = "Unblock \(context.domain)"
|
||||||
|
image = UIImage(systemName: "hand.raised.slash.fill")
|
||||||
|
} else {
|
||||||
|
title = "Block \(context.domain)"
|
||||||
|
image = UIImage(systemName: "hand.raised.fill")
|
||||||
|
}
|
||||||
|
let action = LabeledAction(title: title, image: image) { [weak delegate] in
|
||||||
|
guard let delegate else { return }
|
||||||
|
|
||||||
} // end switch
|
delegate.menuAction(self)
|
||||||
} // end func build
|
}
|
||||||
} // end enum Action
|
return action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MastodonMenu {
|
extension MastodonMenu {
|
||||||
@ -275,4 +292,14 @@ extension MastodonMenu {
|
|||||||
self.isFollowing = isFollowing
|
self.isFollowing = isFollowing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct BlockDomainActionContext {
|
||||||
|
public let domain: String
|
||||||
|
public let isBlocking: Bool
|
||||||
|
|
||||||
|
public init(domain: String, isBlocking: Bool) {
|
||||||
|
self.domain = domain
|
||||||
|
self.isBlocking = isBlocking
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public enum RelationshipAction: Int, CaseIterable {
|
|||||||
case edit
|
case edit
|
||||||
case editing
|
case editing
|
||||||
case updating
|
case updating
|
||||||
|
case domainBlocking
|
||||||
|
|
||||||
public var option: RelationshipActionOptionSet {
|
public var option: RelationshipActionOptionSet {
|
||||||
return RelationshipActionOptionSet(rawValue: 1 << rawValue)
|
return RelationshipActionOptionSet(rawValue: 1 << rawValue)
|
||||||
@ -60,7 +61,8 @@ public struct RelationshipActionOptionSet: OptionSet {
|
|||||||
public static let updating = RelationshipAction.updating.option
|
public static let updating = RelationshipAction.updating.option
|
||||||
public static let showReblogs = RelationshipAction.showReblogs.option
|
public static let showReblogs = RelationshipAction.showReblogs.option
|
||||||
public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating]
|
public static let editOptions: RelationshipActionOptionSet = [.edit, .editing, .updating]
|
||||||
|
public static let domainBlocking = RelationshipAction.domainBlocking.option
|
||||||
|
|
||||||
public func highPriorityAction(except: RelationshipActionOptionSet) -> RelationshipAction? {
|
public func highPriorityAction(except: RelationshipActionOptionSet) -> RelationshipAction? {
|
||||||
let set = subtracting(except)
|
let set = subtracting(except)
|
||||||
for action in RelationshipAction.allCases.reversed() where set.contains(action.option) {
|
for action in RelationshipAction.allCases.reversed() where set.contains(action.option) {
|
||||||
@ -92,6 +94,7 @@ public struct RelationshipActionOptionSet: OptionSet {
|
|||||||
case .editing: return L10n.Common.Controls.Actions.done
|
case .editing: return L10n.Common.Controls.Actions.done
|
||||||
case .updating: return " "
|
case .updating: return " "
|
||||||
case .showReblogs: return " "
|
case .showReblogs: return " "
|
||||||
|
case .domainBlocking: return " "
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,7 +122,8 @@ public final class RelationshipViewModel {
|
|||||||
@Published public var isBlocking = false
|
@Published public var isBlocking = false
|
||||||
@Published public var isBlockingBy = false
|
@Published public var isBlockingBy = false
|
||||||
@Published public var isSuspended = false
|
@Published public var isSuspended = false
|
||||||
|
@Published public var isDomainBlocking = false
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
Publishers.CombineLatest3(
|
Publishers.CombineLatest3(
|
||||||
$user,
|
$user,
|
||||||
@ -171,9 +175,7 @@ extension RelationshipViewModel {
|
|||||||
|
|
||||||
extension RelationshipViewModel {
|
extension RelationshipViewModel {
|
||||||
private func update(user: MastodonUser?, me: MastodonUser?) {
|
private func update(user: MastodonUser?, me: MastodonUser?) {
|
||||||
guard let user = user,
|
guard let user, let me else {
|
||||||
let me = me
|
|
||||||
else {
|
|
||||||
reset()
|
reset()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -188,6 +190,7 @@ extension RelationshipViewModel {
|
|||||||
self.isBlocking = optionSet.contains(.blocking)
|
self.isBlocking = optionSet.contains(.blocking)
|
||||||
self.isSuspended = optionSet.contains(.suspended)
|
self.isSuspended = optionSet.contains(.suspended)
|
||||||
self.showReblogs = optionSet.contains(.showReblogs)
|
self.showReblogs = optionSet.contains(.showReblogs)
|
||||||
|
self.isDomainBlocking = optionSet.contains(.domainBlocking)
|
||||||
|
|
||||||
self.optionSet = optionSet
|
self.optionSet = optionSet
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user