Add support for UIAccessibilityCustomAction in MastodonMenu

This commit is contained in:
Jed Fox 2022-10-31 11:32:31 -04:00
parent 869e44737a
commit 87e05ecdab
No known key found for this signature in database
GPG Key ID: 0B61D18EA54B47E1
1 changed files with 71 additions and 36 deletions

View File

@ -20,10 +20,22 @@ public enum MastodonMenu {
var children: [UIMenuElement] = [] var children: [UIMenuElement] = []
for action in actions { for action in actions {
let element = action.build(delegate: delegate) let element = action.build(delegate: delegate)
children.append(element) children.append(element.menuElement)
} }
return UIMenu(title: "", options: [], children: children) return UIMenu(title: "", options: [], children: children)
} }
public static func setupAccessibilityActions(
actions: [Action],
delegate: MastodonMenuDelegate
) -> [UIAccessibilityCustomAction] {
var accessibilityActions: [UIAccessibilityCustomAction] = []
for action in actions {
let element = action.build(delegate: delegate)
accessibilityActions.append(element.accessibilityCustomAction)
}
return accessibilityActions
}
} }
extension MastodonMenu { extension MastodonMenu {
@ -34,69 +46,50 @@ extension MastodonMenu {
case shareUser(ShareUserActionContext) case shareUser(ShareUserActionContext)
case deleteStatus case deleteStatus
func build(delegate: MastodonMenuDelegate) -> UIMenuElement { func build(delegate: MastodonMenuDelegate) -> BuiltAction {
switch self { switch self {
case .muteUser(let context): case .muteUser(let context):
let muteAction = UIAction( let muteAction = BuiltAction(
title: context.isMuting ? L10n.Common.Controls.Friendship.unmuteUser(context.name) : L10n.Common.Controls.Friendship.muteUser(context.name), title: context.isMuting ? L10n.Common.Controls.Friendship.unmuteUser(context.name) : L10n.Common.Controls.Friendship.muteUser(context.name),
image: context.isMuting ? UIImage(systemName: "speaker.wave.2") : UIImage(systemName: "speaker.slash"), image: context.isMuting ? UIImage(systemName: "speaker.wave.2") : UIImage(systemName: "speaker.slash")
identifier: nil, ) { [weak delegate] in
discoverabilityTitle: nil,
attributes: [],
state: .off
) { [weak delegate] _ in
guard let delegate = delegate else { return } guard let delegate = delegate else { return }
delegate.menuAction(self) delegate.menuAction(self)
} }
return muteAction return muteAction
case .blockUser(let context): case .blockUser(let context):
let blockAction = UIAction( let blockAction = BuiltAction(
title: context.isBlocking ? L10n.Common.Controls.Friendship.unblockUser(context.name) : L10n.Common.Controls.Friendship.blockUser(context.name), title: context.isBlocking ? L10n.Common.Controls.Friendship.unblockUser(context.name) : L10n.Common.Controls.Friendship.blockUser(context.name),
image: context.isBlocking ? UIImage(systemName: "hand.raised") : UIImage(systemName: "hand.raised"), image: context.isBlocking ? UIImage(systemName: "hand.raised") : UIImage(systemName: "hand.raised")
identifier: nil, ) { [weak delegate] in
discoverabilityTitle: nil,
attributes: [],
state: .off
) { [weak delegate] _ in
guard let delegate = delegate else { return } guard let delegate = delegate else { return }
delegate.menuAction(self) delegate.menuAction(self)
} }
return blockAction return blockAction
case .reportUser(let context): case .reportUser(let context):
let reportAction = UIAction( let reportAction = BuiltAction(
title: L10n.Common.Controls.Actions.reportUser(context.name), title: L10n.Common.Controls.Actions.reportUser(context.name),
image: UIImage(systemName: "flag"), image: UIImage(systemName: "flag")
identifier: nil, ) { [weak delegate] in
discoverabilityTitle: nil,
attributes: [],
state: .off
) { [weak delegate] _ in
guard let delegate = delegate else { return } guard let delegate = delegate else { return }
delegate.menuAction(self) delegate.menuAction(self)
} }
return reportAction return reportAction
case .shareUser(let context): case .shareUser(let context):
let shareAction = UIAction( let shareAction = BuiltAction(
title: L10n.Common.Controls.Actions.shareUser(context.name), title: L10n.Common.Controls.Actions.shareUser(context.name),
image: UIImage(systemName: "square.and.arrow.up"), image: UIImage(systemName: "square.and.arrow.up")
identifier: nil, ) { [weak delegate] in
discoverabilityTitle: nil,
attributes: [],
state: .off
) { [weak delegate] _ in
guard let delegate = delegate else { return } guard let delegate = delegate else { return }
delegate.menuAction(self) delegate.menuAction(self)
} }
return shareAction return shareAction
case .deleteStatus: case .deleteStatus:
let deleteAction = UIAction( let deleteAction = BuiltAction(
title: L10n.Common.Controls.Actions.delete, title: L10n.Common.Controls.Actions.delete,
image: UIImage(systemName: "minus.circle"), image: UIImage(systemName: "minus.circle"),
identifier: nil, attributes: .destructive
discoverabilityTitle: nil, ) { [weak delegate] in
attributes: .destructive,
state: .off
) { [weak delegate] _ in
guard let delegate = delegate else { return } guard let delegate = delegate else { return }
delegate.menuAction(self) delegate.menuAction(self)
} }
@ -104,6 +97,48 @@ extension MastodonMenu {
} // end switch } // end switch
} // end func build } // end func build
} // end enum Action } // end enum Action
struct BuiltAction {
init(
title: String,
image: UIImage? = nil,
attributes: UIMenuElement.Attributes = [],
state: UIMenuElement.State = .off,
handler: @escaping () -> Void
) {
self.title = title
self.image = image
self.attributes = attributes
self.state = state
self.handler = handler
}
let title: String
let image: UIImage?
let attributes: UIMenuElement.Attributes
let state: UIMenuElement.State
let handler: () -> Void
var menuElement: UIMenuElement {
UIAction(
title: title,
image: image,
identifier: nil,
discoverabilityTitle: nil,
attributes: attributes,
state: .off
) { _ in
handler()
}
}
var accessibilityCustomAction: UIAccessibilityCustomAction {
UIAccessibilityCustomAction(name: title, image: image) { _ in
handler()
return true
}
}
}
} }
extension MastodonMenu { extension MastodonMenu {