Account menu improvements

This commit is contained in:
Justin Mazzocchi 2021-02-10 19:52:21 -08:00
parent fd09e6ef17
commit 8fdbfaf01e
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
6 changed files with 66 additions and 17 deletions

View file

@ -23,6 +23,7 @@
"account.follows-you" = "Follows you"; "account.follows-you" = "Follows you";
"account.header.accessibility-label-%@" = "Header image: %@"; "account.header.accessibility-label-%@" = "Header image: %@";
"account.hide-reblogs" = "Hide boosts"; "account.hide-reblogs" = "Hide boosts";
"account.hide-reblogs.confirm-%@" = "Hide boosts from %@?";
"account.locked.accessibility-label" = "Locked account"; "account.locked.accessibility-label" = "Locked account";
"account.mute" = "Mute"; "account.mute" = "Mute";
"account.mute.indefinite" = "Indefnite"; "account.mute.indefinite" = "Indefnite";
@ -41,10 +42,12 @@
"account.statuses-and-replies.toot" = "Toots & Replies"; "account.statuses-and-replies.toot" = "Toots & Replies";
"account.media" = "Media"; "account.media" = "Media";
"account.show-reblogs" = "Show boosts"; "account.show-reblogs" = "Show boosts";
"account.show-reblogs.confirm-%@" = "Show boosts from %@?";
"account.unavailable" = "Profile unavailable"; "account.unavailable" = "Profile unavailable";
"account.unblock" = "Unblock"; "account.unblock" = "Unblock";
"account.unblock.confirm-%@" = "Unblock %@?"; "account.unblock.confirm-%@" = "Unblock %@?";
"account.unfollow" = "Unfollow"; "account.unfollow" = "Unfollow";
"account.unfollow.confirm-%@" = "Unfollow %@?";
"account.unmute" = "Unmute"; "account.unmute" = "Unmute";
"account.unmute.confirm-%@" = "Unmute %@?"; "account.unmute.confirm-%@" = "Unmute %@?";
"activity.open-in-default-browser" = "Open in default browser"; "activity.open-in-default-browser" = "Open in default browser";
@ -251,6 +254,7 @@
"search.scope.statuses.post" = "Posts"; "search.scope.statuses.post" = "Posts";
"search.scope.statuses.toot" = "Toots"; "search.scope.statuses.toot" = "Toots";
"search.scope.tags" = "Hashtags"; "search.scope.tags" = "Hashtags";
"share" = "Share";
"share-extension-error.no-account-found" = "No account found"; "share-extension-error.no-account-found" = "No account found";
"status.accessibility.view-author-profile" = "View author's profile"; "status.accessibility.view-author-profile" = "View author's profile";
"status.accessibility.view-reblogger-profile" = "View booster's profile"; "status.accessibility.view-reblogger-profile" = "View booster's profile";

View file

@ -73,20 +73,24 @@ final class ProfileViewController: TableViewController {
private extension ProfileViewController { private extension ProfileViewController {
// swiftlint:disable:next function_body_length // swiftlint:disable:next function_body_length
func menu(accountViewModel: AccountViewModel, relationship: Relationship) -> UIMenu { func menu(accountViewModel: AccountViewModel, relationship: Relationship) -> UIMenu {
var actions = [UIAction]() var actions = [UIAction(
title: NSLocalizedString("share", comment: ""),
image: UIImage(systemName: "square.and.arrow.up")) { _ in
accountViewModel.share()
}]
if relationship.following { if relationship.following {
if relationship.showingReblogs { if relationship.showingReblogs {
actions.append(UIAction( actions.append(UIAction(
title: NSLocalizedString("account.hide-reblogs", comment: ""), title: NSLocalizedString("account.hide-reblogs", comment: ""),
image: UIImage(systemName: "arrow.2.squarepath")) { _ in image: UIImage(systemName: "arrow.2.squarepath")) { _ in
accountViewModel.hideReblogs() accountViewModel.confirmHideReblogs()
}) })
} else { } else {
actions.append(UIAction( actions.append(UIAction(
title: NSLocalizedString("account.show-reblogs", comment: ""), title: NSLocalizedString("account.show-reblogs", comment: ""),
image: UIImage(systemName: "arrow.2.squarepath")) { _ in image: UIImage(systemName: "arrow.2.squarepath")) { _ in
accountViewModel.showReblogs() accountViewModel.confirmShowReblogs()
}) })
} }
} }

View file

@ -443,6 +443,12 @@ private extension TableViewController {
compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft) compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft)
case let .confirmDelete(statusViewModel, redraft): case let .confirmDelete(statusViewModel, redraft):
confirmDelete(statusViewModel: statusViewModel, redraft: redraft) confirmDelete(statusViewModel: statusViewModel, redraft: redraft)
case let .confirmUnfollow(accountViewModel):
confirmUnfollow(accountViewModel: accountViewModel)
case let .confirmHideReblogs(accountViewModel):
confirmHideReblogs(accountViewModel: accountViewModel)
case let .confirmShowReblogs(accountViewModel):
confirmShowReblogs(accountViewModel: accountViewModel)
case let .confirmMute(accountViewModel): case let .confirmMute(accountViewModel):
confirmMute(muteViewModel: accountViewModel.muteViewModel()) confirmMute(muteViewModel: accountViewModel.muteViewModel())
case let .confirmUnmute(accountViewModel): case let .confirmUnmute(accountViewModel):
@ -575,6 +581,30 @@ private extension TableViewController {
present(alertController, animated: true) present(alertController, animated: true)
} }
func confirmUnfollow(accountViewModel: AccountViewModel) {
confirm(message: String.localizedStringWithFormat(
NSLocalizedString("account.unfollow.confirm-%@", comment: ""),
accountViewModel.accountName)) {
accountViewModel.unfollow()
}
}
func confirmHideReblogs(accountViewModel: AccountViewModel) {
confirm(message: String.localizedStringWithFormat(
NSLocalizedString("account.hide-reblogs.confirm-%@", comment: ""),
accountViewModel.accountName)) {
accountViewModel.hideReblogs()
}
}
func confirmShowReblogs(accountViewModel: AccountViewModel) {
confirm(message: String.localizedStringWithFormat(
NSLocalizedString("account.show-reblogs.confirm-%@", comment: ""),
accountViewModel.accountName)) {
accountViewModel.showReblogs()
}
}
func confirmMute(muteViewModel: MuteViewModel) { func confirmMute(muteViewModel: MuteViewModel) {
let muteViewController = MuteViewController(viewModel: muteViewModel) let muteViewController = MuteViewController(viewModel: muteViewModel)
let navigationController = UINavigationController(rootViewController: muteViewController) let navigationController = UINavigationController(rootViewController: muteViewController)

View file

@ -11,6 +11,9 @@ public enum CollectionItemEvent {
case attachment(AttachmentViewModel, StatusViewModel) case attachment(AttachmentViewModel, StatusViewModel)
case compose(inReplyTo: StatusViewModel?, redraft: Status?) case compose(inReplyTo: StatusViewModel?, redraft: Status?)
case confirmDelete(StatusViewModel, redraft: Bool) case confirmDelete(StatusViewModel, redraft: Bool)
case confirmUnfollow(AccountViewModel)
case confirmHideReblogs(AccountViewModel)
case confirmShowReblogs(AccountViewModel)
case confirmMute(AccountViewModel) case confirmMute(AccountViewModel)
case confirmUnmute(AccountViewModel) case confirmUnmute(AccountViewModel)
case confirmBlock(AccountViewModel) case confirmBlock(AccountViewModel)

View file

@ -103,14 +103,32 @@ public extension AccountViewModel {
ignorableOutputEvent(accountService.follow()) ignorableOutputEvent(accountService.follow())
} }
func confirmUnfollow() {
eventsSubject.send(Just(.confirmUnfollow(self)).setFailureType(to: Error.self).eraseToAnyPublisher())
}
func unfollow() { func unfollow() {
ignorableOutputEvent(accountService.unfollow()) ignorableOutputEvent(accountService.unfollow())
} }
func share() {
guard let url = URL(string: accountService.account.url) else { return }
eventsSubject.send(Just(.share(url)).setFailureType(to: Error.self).eraseToAnyPublisher())
}
func confirmHideReblogs() {
eventsSubject.send(Just(.confirmHideReblogs(self)).setFailureType(to: Error.self).eraseToAnyPublisher())
}
func hideReblogs() { func hideReblogs() {
ignorableOutputEvent(accountService.hideReblogs()) ignorableOutputEvent(accountService.hideReblogs())
} }
func confirmShowReblogs() {
eventsSubject.send(Just(.confirmShowReblogs(self)).setFailureType(to: Error.self).eraseToAnyPublisher())
}
func showReblogs() { func showReblogs() {
ignorableOutputEvent(accountService.showReblogs()) ignorableOutputEvent(accountService.showReblogs())
} }

View file

@ -272,20 +272,10 @@ private extension AccountHeaderView {
systemName: "checkmark", systemName: "checkmark",
withConfiguration: UIImage.SymbolConfiguration(scale: .small)), withConfiguration: UIImage.SymbolConfiguration(scale: .small)),
for: .normal) for: .normal)
unfollowButton.setTitle(NSLocalizedString("account.following", comment: ""), for: .normal) unfollowButton.setTitle(NSLocalizedString("account.unfollow", comment: ""), for: .normal)
unfollowButton.showsMenuAsPrimaryAction = true unfollowButton.addAction(
unfollowButton.menu = UIMenu(children: [UIDeferredMenuElement { [weak self] completion in UIAction { [weak self] _ in self?.viewModel.accountViewModel?.confirmUnfollow() },
guard let accountViewModel = self?.viewModel.accountViewModel else { return } for: .touchUpInside)
let unfollowAction = UIAction(
title: self?.unfollowButton.title(for: .normal) ?? "",
image: UIImage(systemName: "person.badge.minus"),
attributes: .destructive) { _ in
accountViewModel.unfollow()
}
completion([unfollowAction])
}])
addSubview(baseStackView) addSubview(baseStackView)
baseStackView.translatesAutoresizingMaskIntoConstraints = false baseStackView.translatesAutoresizingMaskIntoConstraints = false