chore: cherry pick 00eddc2aae
from feature-post-edit branch
This commit is contained in:
parent
060aec6bcb
commit
0b0d7fcd48
|
@ -12,7 +12,7 @@ import MastodonCore
|
||||||
|
|
||||||
extension DataSourceFacade {
|
extension DataSourceFacade {
|
||||||
public static func responseToStatusBookmarkAction(
|
public static func responseToStatusBookmarkAction(
|
||||||
provider: DataSourceProvider & AuthContextProvider,
|
provider: UIViewController & NeedsDependency & AuthContextProvider,
|
||||||
status: ManagedObjectRecord<Status>
|
status: ManagedObjectRecord<Status>
|
||||||
) async throws {
|
) async throws {
|
||||||
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
|
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
|
||||||
|
|
|
@ -36,7 +36,7 @@ extension DataSourceFacade {
|
||||||
button: UIButton
|
button: UIButton
|
||||||
) async throws {
|
) async throws {
|
||||||
let activityViewController = try await createActivityViewController(
|
let activityViewController = try await createActivityViewController(
|
||||||
provider: provider,
|
dependency: provider,
|
||||||
status: status
|
status: status
|
||||||
)
|
)
|
||||||
provider.coordinator.present(
|
provider.coordinator.present(
|
||||||
|
@ -51,19 +51,19 @@ extension DataSourceFacade {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func createActivityViewController(
|
private static func createActivityViewController(
|
||||||
provider: DataSourceProvider,
|
dependency: NeedsDependency,
|
||||||
status: ManagedObjectRecord<Status>
|
status: ManagedObjectRecord<Status>
|
||||||
) async throws -> UIActivityViewController {
|
) async throws -> UIActivityViewController {
|
||||||
var activityItems: [Any] = try await provider.context.managedObjectContext.perform {
|
var activityItems: [Any] = try await dependency.context.managedObjectContext.perform {
|
||||||
guard let status = status.object(in: provider.context.managedObjectContext) else { return [] }
|
guard let status = status.object(in: dependency.context.managedObjectContext) else { return [] }
|
||||||
let url = status.url ?? status.uri
|
let url = status.url ?? status.uri
|
||||||
return [URL(string: url)].compactMap { $0 } as [Any]
|
return [URL(string: url)].compactMap { $0 } as [Any]
|
||||||
}
|
}
|
||||||
var applicationActivities: [UIActivity] = [
|
var applicationActivities: [UIActivity] = [
|
||||||
SafariActivity(sceneCoordinator: provider.coordinator), // open URL
|
SafariActivity(sceneCoordinator: dependency.coordinator), // open URL
|
||||||
]
|
]
|
||||||
|
|
||||||
if let provider = provider as? ShareActivityProvider {
|
if let provider = dependency as? ShareActivityProvider {
|
||||||
activityItems.append(contentsOf: provider.activities)
|
activityItems.append(contentsOf: provider.activities)
|
||||||
applicationActivities.append(contentsOf: provider.applicationActivities)
|
applicationActivities.append(contentsOf: provider.applicationActivities)
|
||||||
}
|
}
|
||||||
|
@ -247,6 +247,37 @@ extension DataSourceFacade {
|
||||||
from: dependency,
|
from: dependency,
|
||||||
transition: .activityViewControllerPresent(animated: true, completion: nil)
|
transition: .activityViewControllerPresent(animated: true, completion: nil)
|
||||||
)
|
)
|
||||||
|
case .bookmarkStatus:
|
||||||
|
Task {
|
||||||
|
guard let status = menuContext.status else {
|
||||||
|
assertionFailure()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try await DataSourceFacade.responseToStatusBookmarkAction(
|
||||||
|
provider: dependency,
|
||||||
|
status: status
|
||||||
|
)
|
||||||
|
} // end Task
|
||||||
|
case .shareStatus:
|
||||||
|
Task {
|
||||||
|
guard let status = menuContext.status else {
|
||||||
|
assertionFailure()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let activityViewController = try await DataSourceFacade.createActivityViewController(
|
||||||
|
dependency: dependency,
|
||||||
|
status: status
|
||||||
|
)
|
||||||
|
await dependency.coordinator.present(
|
||||||
|
scene: .activityViewController(
|
||||||
|
activityViewController: activityViewController,
|
||||||
|
sourceView: menuContext.button,
|
||||||
|
barButtonItem: menuContext.barButtonItem
|
||||||
|
),
|
||||||
|
from: dependency,
|
||||||
|
transition: .activityViewControllerPresent(animated: true, completion: nil)
|
||||||
|
)
|
||||||
|
} // end Task
|
||||||
case .deleteStatus:
|
case .deleteStatus:
|
||||||
let alertController = UIAlertController(
|
let alertController = UIAlertController(
|
||||||
title: "Delete Post",
|
title: "Delete Post",
|
||||||
|
|
|
@ -144,7 +144,8 @@ extension NotificationView.ViewModel {
|
||||||
name: name,
|
name: name,
|
||||||
isMuting: isMuting,
|
isMuting: isMuting,
|
||||||
isBlocking: isBlocking,
|
isBlocking: isBlocking,
|
||||||
isMyself: isMyself
|
isMyself: isMyself,
|
||||||
|
isBookmarking: false // no bookmark action display for notification item
|
||||||
)
|
)
|
||||||
notificationView.menuButton.menu = notificationView.setupAuthorMenu(menuContext: menuContext)
|
notificationView.menuButton.menu = notificationView.setupAuthorMenu(menuContext: menuContext)
|
||||||
notificationView.menuButton.showsMenuAsPrimaryAction = true
|
notificationView.menuButton.showsMenuAsPrimaryAction = true
|
||||||
|
|
|
@ -514,13 +514,6 @@ extension StatusView.ViewModel {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
$isBookmark
|
|
||||||
.sink { isHighlighted in
|
|
||||||
statusView.actionToolbarContainer.configureBookmark(
|
|
||||||
isHighlighted: isHighlighted
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.store(in: &disposeBag)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func bindMetric(statusView: StatusView) {
|
private func bindMetric(statusView: StatusView) {
|
||||||
|
@ -577,13 +570,24 @@ extension StatusView.ViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func bindMenu(statusView: StatusView) {
|
private func bindMenu(statusView: StatusView) {
|
||||||
Publishers.CombineLatest4(
|
let publisherOne = Publishers.CombineLatest(
|
||||||
$authorName,
|
$authorName,
|
||||||
$isMuting,
|
|
||||||
$isBlocking,
|
|
||||||
$isMyself
|
$isMyself
|
||||||
)
|
)
|
||||||
.sink { authorName, isMuting, isBlocking, isMyself in
|
let publishersTwo = Publishers.CombineLatest3(
|
||||||
|
$isMuting,
|
||||||
|
$isBlocking,
|
||||||
|
$isBookmark
|
||||||
|
)
|
||||||
|
|
||||||
|
Publishers.CombineLatest(
|
||||||
|
publisherOne.eraseToAnyPublisher(),
|
||||||
|
publishersTwo.eraseToAnyPublisher()
|
||||||
|
).eraseToAnyPublisher()
|
||||||
|
.sink { tupleOne, tupleTwo in
|
||||||
|
let (authorName, isMyself) = tupleOne
|
||||||
|
let (isMuting, isBlocking, isBookmark) = tupleTwo
|
||||||
|
|
||||||
guard let name = authorName?.string else {
|
guard let name = authorName?.string else {
|
||||||
statusView.menuButton.menu = nil
|
statusView.menuButton.menu = nil
|
||||||
return
|
return
|
||||||
|
@ -593,7 +597,8 @@ extension StatusView.ViewModel {
|
||||||
name: name,
|
name: name,
|
||||||
isMuting: isMuting,
|
isMuting: isMuting,
|
||||||
isBlocking: isBlocking,
|
isBlocking: isBlocking,
|
||||||
isMyself: isMyself
|
isMyself: isMyself,
|
||||||
|
isBookmarking: isBookmark
|
||||||
)
|
)
|
||||||
statusView.menuButton.menu = statusView.setupAuthorMenu(menuContext: menuContext)
|
statusView.menuButton.menu = statusView.setupAuthorMenu(menuContext: menuContext)
|
||||||
statusView.menuButton.showsMenuAsPrimaryAction = true
|
statusView.menuButton.showsMenuAsPrimaryAction = true
|
||||||
|
|
|
@ -705,6 +705,7 @@ extension StatusView {
|
||||||
public let isMuting: Bool
|
public let isMuting: Bool
|
||||||
public let isBlocking: Bool
|
public let isBlocking: Bool
|
||||||
public let isMyself: Bool
|
public let isMyself: Bool
|
||||||
|
public let isBookmarking: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
public func setupAuthorMenu(menuContext: AuthorMenuContext) -> UIMenu {
|
public func setupAuthorMenu(menuContext: AuthorMenuContext) -> UIMenu {
|
||||||
|
@ -722,6 +723,10 @@ extension StatusView {
|
||||||
.reportUser(
|
.reportUser(
|
||||||
.init(name: menuContext.name)
|
.init(name: menuContext.name)
|
||||||
),
|
),
|
||||||
|
.bookmarkStatus(
|
||||||
|
.init(isBookmarking: menuContext.isBookmarking)
|
||||||
|
),
|
||||||
|
.shareStatus
|
||||||
]
|
]
|
||||||
|
|
||||||
if menuContext.isMyself {
|
if menuContext.isMyself {
|
||||||
|
|
|
@ -22,14 +22,11 @@ public final class ActionToolbarContainer: UIView {
|
||||||
static let reblogImage = Asset.Arrow.repeat.image.withRenderingMode(.alwaysTemplate)
|
static let reblogImage = Asset.Arrow.repeat.image.withRenderingMode(.alwaysTemplate)
|
||||||
static let starImage = Asset.ObjectsAndTools.star.image.withRenderingMode(.alwaysTemplate)
|
static let starImage = Asset.ObjectsAndTools.star.image.withRenderingMode(.alwaysTemplate)
|
||||||
static let starFillImage = Asset.ObjectsAndTools.starFill.image.withRenderingMode(.alwaysTemplate)
|
static let starFillImage = Asset.ObjectsAndTools.starFill.image.withRenderingMode(.alwaysTemplate)
|
||||||
static let bookmarkImage = Asset.ObjectsAndTools.bookmark.image.withRenderingMode(.alwaysTemplate)
|
static let shareImage = Asset.Arrow.squareAndArrowUp.image.withRenderingMode(.alwaysTemplate)
|
||||||
static let bookmarkFillImage = Asset.ObjectsAndTools.bookmarkFill.image.withRenderingMode(.alwaysTemplate)
|
|
||||||
static let shareImage = Asset.Communication.share.image.withRenderingMode(.alwaysTemplate)
|
|
||||||
|
|
||||||
public let replyButton = HighlightDimmableButton()
|
public let replyButton = HighlightDimmableButton()
|
||||||
public let reblogButton = HighlightDimmableButton()
|
public let reblogButton = HighlightDimmableButton()
|
||||||
public let favoriteButton = HighlightDimmableButton()
|
public let favoriteButton = HighlightDimmableButton()
|
||||||
public let bookmarkButton = HighlightDimmableButton()
|
|
||||||
public let shareButton = HighlightDimmableButton()
|
public let shareButton = HighlightDimmableButton()
|
||||||
|
|
||||||
public weak var delegate: ActionToolbarContainerDelegate?
|
public weak var delegate: ActionToolbarContainerDelegate?
|
||||||
|
@ -64,7 +61,6 @@ extension ActionToolbarContainer {
|
||||||
replyButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
replyButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
||||||
reblogButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
reblogButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
||||||
favoriteButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
favoriteButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
||||||
bookmarkButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
|
||||||
shareButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
shareButton.addTarget(self, action: #selector(ActionToolbarContainer.buttonDidPressed(_:)), for: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +75,7 @@ extension ActionToolbarContainer {
|
||||||
subview.removeFromSuperview()
|
subview.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttons = [replyButton, reblogButton, favoriteButton, bookmarkButton, shareButton]
|
let buttons = [replyButton, reblogButton, favoriteButton, shareButton]
|
||||||
buttons.forEach { button in
|
buttons.forEach { button in
|
||||||
button.tintColor = Asset.Colors.Button.actionToolbar.color
|
button.tintColor = Asset.Colors.Button.actionToolbar.color
|
||||||
button.titleLabel?.font = .monospacedDigitSystemFont(ofSize: 12, weight: .regular)
|
button.titleLabel?.font = .monospacedDigitSystemFont(ofSize: 12, weight: .regular)
|
||||||
|
@ -94,7 +90,6 @@ extension ActionToolbarContainer {
|
||||||
replyButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.reply
|
replyButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.reply
|
||||||
reblogButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.reblog // needs update to follow state
|
reblogButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.reblog // needs update to follow state
|
||||||
favoriteButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.favorite // needs update to follow state
|
favoriteButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.favorite // needs update to follow state
|
||||||
bookmarkButton.accessibilityLabel = L10n.Common.Controls.Status.Actions.bookmark // needs update to follow state
|
|
||||||
shareButton.accessibilityLabel = L10n.Common.Controls.Actions.share
|
shareButton.accessibilityLabel = L10n.Common.Controls.Actions.share
|
||||||
|
|
||||||
switch style {
|
switch style {
|
||||||
|
@ -105,7 +100,6 @@ extension ActionToolbarContainer {
|
||||||
replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal)
|
replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal)
|
||||||
reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal)
|
reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal)
|
||||||
favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal)
|
favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal)
|
||||||
bookmarkButton.setImage(ActionToolbarContainer.bookmarkImage, for: .normal)
|
|
||||||
shareButton.setImage(ActionToolbarContainer.shareImage, for: .normal)
|
shareButton.setImage(ActionToolbarContainer.shareImage, for: .normal)
|
||||||
|
|
||||||
container.axis = .horizontal
|
container.axis = .horizontal
|
||||||
|
@ -114,22 +108,18 @@ extension ActionToolbarContainer {
|
||||||
replyButton.translatesAutoresizingMaskIntoConstraints = false
|
replyButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
reblogButton.translatesAutoresizingMaskIntoConstraints = false
|
reblogButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
favoriteButton.translatesAutoresizingMaskIntoConstraints = false
|
favoriteButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
bookmarkButton.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
shareButton.translatesAutoresizingMaskIntoConstraints = false
|
shareButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
container.addArrangedSubview(replyButton)
|
container.addArrangedSubview(replyButton)
|
||||||
container.addArrangedSubview(reblogButton)
|
container.addArrangedSubview(reblogButton)
|
||||||
container.addArrangedSubview(favoriteButton)
|
container.addArrangedSubview(favoriteButton)
|
||||||
container.addArrangedSubview(bookmarkButton)
|
|
||||||
container.addArrangedSubview(shareButton)
|
container.addArrangedSubview(shareButton)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
replyButton.heightAnchor.constraint(equalToConstant: 36).priority(.defaultHigh),
|
replyButton.heightAnchor.constraint(equalToConstant: 36).priority(.defaultHigh),
|
||||||
replyButton.heightAnchor.constraint(equalTo: reblogButton.heightAnchor).priority(.defaultHigh),
|
replyButton.heightAnchor.constraint(equalTo: reblogButton.heightAnchor).priority(.defaultHigh),
|
||||||
replyButton.heightAnchor.constraint(equalTo: favoriteButton.heightAnchor).priority(.defaultHigh),
|
replyButton.heightAnchor.constraint(equalTo: favoriteButton.heightAnchor).priority(.defaultHigh),
|
||||||
replyButton.heightAnchor.constraint(equalTo: bookmarkButton.heightAnchor).priority(.defaultHigh),
|
|
||||||
replyButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).priority(.defaultHigh),
|
replyButton.heightAnchor.constraint(equalTo: shareButton.heightAnchor).priority(.defaultHigh),
|
||||||
replyButton.widthAnchor.constraint(equalTo: reblogButton.widthAnchor).priority(.defaultHigh),
|
replyButton.widthAnchor.constraint(equalTo: reblogButton.widthAnchor).priority(.defaultHigh),
|
||||||
replyButton.widthAnchor.constraint(equalTo: favoriteButton.widthAnchor).priority(.defaultHigh),
|
replyButton.widthAnchor.constraint(equalTo: favoriteButton.widthAnchor).priority(.defaultHigh),
|
||||||
replyButton.widthAnchor.constraint(equalTo: bookmarkButton.widthAnchor).priority(.defaultHigh),
|
|
||||||
])
|
])
|
||||||
shareButton.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
shareButton.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||||
shareButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
shareButton.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
|
||||||
|
@ -141,7 +131,6 @@ extension ActionToolbarContainer {
|
||||||
replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal)
|
replyButton.setImage(ActionToolbarContainer.replyImage, for: .normal)
|
||||||
reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal)
|
reblogButton.setImage(ActionToolbarContainer.reblogImage, for: .normal)
|
||||||
favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal)
|
favoriteButton.setImage(ActionToolbarContainer.starImage, for: .normal)
|
||||||
bookmarkButton.setImage(ActionToolbarContainer.bookmarkImage, for: .normal)
|
|
||||||
|
|
||||||
container.axis = .horizontal
|
container.axis = .horizontal
|
||||||
container.spacing = 8
|
container.spacing = 8
|
||||||
|
@ -150,7 +139,6 @@ extension ActionToolbarContainer {
|
||||||
container.addArrangedSubview(replyButton)
|
container.addArrangedSubview(replyButton)
|
||||||
container.addArrangedSubview(reblogButton)
|
container.addArrangedSubview(reblogButton)
|
||||||
container.addArrangedSubview(favoriteButton)
|
container.addArrangedSubview(favoriteButton)
|
||||||
container.addArrangedSubview(bookmarkButton)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,11 +185,6 @@ extension ActionToolbarContainer {
|
||||||
favoriteButton.setTitleColor(tintColor, for: .highlighted)
|
favoriteButton.setTitleColor(tintColor, for: .highlighted)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func isBookmarkButtonHighlightStateDidChange(to isHighlight: Bool) {
|
|
||||||
let tintColor = isHighlight ? Asset.Colors.brand.color : Asset.Colors.Button.actionToolbar.color
|
|
||||||
bookmarkButton.tintColor = tintColor
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ActionToolbarContainer {
|
extension ActionToolbarContainer {
|
||||||
|
@ -214,7 +197,6 @@ extension ActionToolbarContainer {
|
||||||
case replyButton: _action = .reply
|
case replyButton: _action = .reply
|
||||||
case reblogButton: _action = .reblog
|
case reblogButton: _action = .reblog
|
||||||
case favoriteButton: _action = .like
|
case favoriteButton: _action = .like
|
||||||
case bookmarkButton: _action = .bookmark
|
|
||||||
case shareButton: _action = .share
|
case shareButton: _action = .share
|
||||||
default: _action = nil
|
default: _action = nil
|
||||||
}
|
}
|
||||||
|
@ -275,20 +257,6 @@ extension ActionToolbarContainer {
|
||||||
favoriteButton.accessibilityLabel = L10n.Plural.Count.favorite(count)
|
favoriteButton.accessibilityLabel = L10n.Plural.Count.favorite(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func configureBookmark(isHighlighted: Bool) {
|
|
||||||
let image = isHighlighted ? ActionToolbarContainer.bookmarkFillImage : ActionToolbarContainer.bookmarkImage
|
|
||||||
bookmarkButton.setImage(image, for: .normal)
|
|
||||||
let tintColor = isHighlighted ? Asset.Colors.brand.color : Asset.Colors.Button.actionToolbar.color
|
|
||||||
bookmarkButton.tintColor = tintColor
|
|
||||||
|
|
||||||
if isHighlighted {
|
|
||||||
bookmarkButton.accessibilityTraits.insert(.selected)
|
|
||||||
} else {
|
|
||||||
bookmarkButton.accessibilityTraits.remove(.selected)
|
|
||||||
}
|
|
||||||
bookmarkButton.accessibilityLabel = isHighlighted ? L10n.Common.Controls.Status.Actions.unbookmark : L10n.Common.Controls.Status.Actions.bookmark
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension ActionToolbarContainer {
|
extension ActionToolbarContainer {
|
||||||
|
@ -300,7 +268,7 @@ extension ActionToolbarContainer {
|
||||||
|
|
||||||
extension ActionToolbarContainer {
|
extension ActionToolbarContainer {
|
||||||
public override var accessibilityElements: [Any]? {
|
public override var accessibilityElements: [Any]? {
|
||||||
get { [replyButton, reblogButton, favoriteButton, bookmarkButton, shareButton] }
|
get { [replyButton, reblogButton, favoriteButton, shareButton] }
|
||||||
set { }
|
set { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ extension MastodonMenu {
|
||||||
case blockUser(BlockUserActionContext)
|
case blockUser(BlockUserActionContext)
|
||||||
case reportUser(ReportUserActionContext)
|
case reportUser(ReportUserActionContext)
|
||||||
case shareUser(ShareUserActionContext)
|
case shareUser(ShareUserActionContext)
|
||||||
|
case bookmarkStatus(BookmarkStatusActionContext)
|
||||||
|
case shareStatus
|
||||||
case deleteStatus
|
case deleteStatus
|
||||||
|
|
||||||
func build(delegate: MastodonMenuDelegate) -> UIMenuElement {
|
func build(delegate: MastodonMenuDelegate) -> UIMenuElement {
|
||||||
|
@ -88,6 +90,32 @@ extension MastodonMenu {
|
||||||
delegate.menuAction(self)
|
delegate.menuAction(self)
|
||||||
}
|
}
|
||||||
return shareAction
|
return shareAction
|
||||||
|
case .bookmarkStatus(let context):
|
||||||
|
let action = UIAction(
|
||||||
|
title: context.isBookmarking ? "Remove Bookmark" : "Bookmark", // TODO: i18n
|
||||||
|
image: context.isBookmarking ? UIImage(systemName: "bookmark.slash.fill") : UIImage(systemName: "bookmark"),
|
||||||
|
identifier: nil,
|
||||||
|
discoverabilityTitle: nil,
|
||||||
|
attributes: [],
|
||||||
|
state: .off
|
||||||
|
) { [weak delegate] _ in
|
||||||
|
guard let delegate = delegate else { return }
|
||||||
|
delegate.menuAction(self)
|
||||||
|
}
|
||||||
|
return action
|
||||||
|
case .shareStatus:
|
||||||
|
let action = UIAction(
|
||||||
|
title: "Share", // TODO: i18n
|
||||||
|
image: UIImage(systemName: "square.and.arrow.up"),
|
||||||
|
identifier: nil,
|
||||||
|
discoverabilityTitle: nil,
|
||||||
|
attributes: [],
|
||||||
|
state: .off
|
||||||
|
) { [weak delegate] _ in
|
||||||
|
guard let delegate = delegate else { return }
|
||||||
|
delegate.menuAction(self)
|
||||||
|
}
|
||||||
|
return action
|
||||||
case .deleteStatus:
|
case .deleteStatus:
|
||||||
let deleteAction = UIAction(
|
let deleteAction = UIAction(
|
||||||
title: L10n.Common.Controls.Actions.delete,
|
title: L10n.Common.Controls.Actions.delete,
|
||||||
|
@ -100,7 +128,7 @@ extension MastodonMenu {
|
||||||
guard let delegate = delegate else { return }
|
guard let delegate = delegate else { return }
|
||||||
delegate.menuAction(self)
|
delegate.menuAction(self)
|
||||||
}
|
}
|
||||||
return deleteAction
|
return UIMenu(options: .displayInline, children: [deleteAction])
|
||||||
} // end switch
|
} // end switch
|
||||||
} // end func build
|
} // end func build
|
||||||
} // end enum Action
|
} // end enum Action
|
||||||
|
@ -127,6 +155,14 @@ extension MastodonMenu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct BookmarkStatusActionContext {
|
||||||
|
public let isBookmarking: Bool
|
||||||
|
|
||||||
|
public init(isBookmarking: Bool) {
|
||||||
|
self.isBookmarking = isBookmarking
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct ReportUserActionContext {
|
public struct ReportUserActionContext {
|
||||||
public let name: String
|
public let name: String
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue