From 8fdbfaf01e25d5ad2fb3744d8352df2bbfb8bd10 Mon Sep 17 00:00:00 2001 From: Justin Mazzocchi <2831158+jzzocc@users.noreply.github.com> Date: Wed, 10 Feb 2021 19:52:21 -0800 Subject: [PATCH] Account menu improvements --- Localizations/Localizable.strings | 4 +++ View Controllers/ProfileViewController.swift | 10 +++++-- View Controllers/TableViewController.swift | 30 +++++++++++++++++++ .../Entities/CollectionItemEvent.swift | 3 ++ .../View Models/AccountViewModel.swift | 18 +++++++++++ Views/UIKit/AccountHeaderView.swift | 18 +++-------- 6 files changed, 66 insertions(+), 17 deletions(-) diff --git a/Localizations/Localizable.strings b/Localizations/Localizable.strings index 57e5731..0739814 100644 --- a/Localizations/Localizable.strings +++ b/Localizations/Localizable.strings @@ -23,6 +23,7 @@ "account.follows-you" = "Follows you"; "account.header.accessibility-label-%@" = "Header image: %@"; "account.hide-reblogs" = "Hide boosts"; +"account.hide-reblogs.confirm-%@" = "Hide boosts from %@?"; "account.locked.accessibility-label" = "Locked account"; "account.mute" = "Mute"; "account.mute.indefinite" = "Indefnite"; @@ -41,10 +42,12 @@ "account.statuses-and-replies.toot" = "Toots & Replies"; "account.media" = "Media"; "account.show-reblogs" = "Show boosts"; +"account.show-reblogs.confirm-%@" = "Show boosts from %@?"; "account.unavailable" = "Profile unavailable"; "account.unblock" = "Unblock"; "account.unblock.confirm-%@" = "Unblock %@?"; "account.unfollow" = "Unfollow"; +"account.unfollow.confirm-%@" = "Unfollow %@?"; "account.unmute" = "Unmute"; "account.unmute.confirm-%@" = "Unmute %@?"; "activity.open-in-default-browser" = "Open in default browser"; @@ -251,6 +254,7 @@ "search.scope.statuses.post" = "Posts"; "search.scope.statuses.toot" = "Toots"; "search.scope.tags" = "Hashtags"; +"share" = "Share"; "share-extension-error.no-account-found" = "No account found"; "status.accessibility.view-author-profile" = "View author's profile"; "status.accessibility.view-reblogger-profile" = "View booster's profile"; diff --git a/View Controllers/ProfileViewController.swift b/View Controllers/ProfileViewController.swift index 16ffca5..91478a4 100644 --- a/View Controllers/ProfileViewController.swift +++ b/View Controllers/ProfileViewController.swift @@ -73,20 +73,24 @@ final class ProfileViewController: TableViewController { private extension ProfileViewController { // swiftlint:disable:next function_body_length 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.showingReblogs { actions.append(UIAction( title: NSLocalizedString("account.hide-reblogs", comment: ""), image: UIImage(systemName: "arrow.2.squarepath")) { _ in - accountViewModel.hideReblogs() + accountViewModel.confirmHideReblogs() }) } else { actions.append(UIAction( title: NSLocalizedString("account.show-reblogs", comment: ""), image: UIImage(systemName: "arrow.2.squarepath")) { _ in - accountViewModel.showReblogs() + accountViewModel.confirmShowReblogs() }) } } diff --git a/View Controllers/TableViewController.swift b/View Controllers/TableViewController.swift index 138fb21..86be078 100644 --- a/View Controllers/TableViewController.swift +++ b/View Controllers/TableViewController.swift @@ -443,6 +443,12 @@ private extension TableViewController { compose(inReplyToViewModel: inReplyToViewModel, redraft: redraft) case let .confirmDelete(statusViewModel, 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): confirmMute(muteViewModel: accountViewModel.muteViewModel()) case let .confirmUnmute(accountViewModel): @@ -575,6 +581,30 @@ private extension TableViewController { 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) { let muteViewController = MuteViewController(viewModel: muteViewModel) let navigationController = UINavigationController(rootViewController: muteViewController) diff --git a/ViewModels/Sources/ViewModels/Entities/CollectionItemEvent.swift b/ViewModels/Sources/ViewModels/Entities/CollectionItemEvent.swift index 65ca13c..9341c7a 100644 --- a/ViewModels/Sources/ViewModels/Entities/CollectionItemEvent.swift +++ b/ViewModels/Sources/ViewModels/Entities/CollectionItemEvent.swift @@ -11,6 +11,9 @@ public enum CollectionItemEvent { case attachment(AttachmentViewModel, StatusViewModel) case compose(inReplyTo: StatusViewModel?, redraft: Status?) case confirmDelete(StatusViewModel, redraft: Bool) + case confirmUnfollow(AccountViewModel) + case confirmHideReblogs(AccountViewModel) + case confirmShowReblogs(AccountViewModel) case confirmMute(AccountViewModel) case confirmUnmute(AccountViewModel) case confirmBlock(AccountViewModel) diff --git a/ViewModels/Sources/ViewModels/View Models/AccountViewModel.swift b/ViewModels/Sources/ViewModels/View Models/AccountViewModel.swift index 936feea..73f477a 100644 --- a/ViewModels/Sources/ViewModels/View Models/AccountViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/AccountViewModel.swift @@ -103,14 +103,32 @@ public extension AccountViewModel { ignorableOutputEvent(accountService.follow()) } + func confirmUnfollow() { + eventsSubject.send(Just(.confirmUnfollow(self)).setFailureType(to: Error.self).eraseToAnyPublisher()) + } + func 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() { ignorableOutputEvent(accountService.hideReblogs()) } + func confirmShowReblogs() { + eventsSubject.send(Just(.confirmShowReblogs(self)).setFailureType(to: Error.self).eraseToAnyPublisher()) + } + func showReblogs() { ignorableOutputEvent(accountService.showReblogs()) } diff --git a/Views/UIKit/AccountHeaderView.swift b/Views/UIKit/AccountHeaderView.swift index 79eb8b6..40983b2 100644 --- a/Views/UIKit/AccountHeaderView.swift +++ b/Views/UIKit/AccountHeaderView.swift @@ -272,20 +272,10 @@ private extension AccountHeaderView { systemName: "checkmark", withConfiguration: UIImage.SymbolConfiguration(scale: .small)), for: .normal) - unfollowButton.setTitle(NSLocalizedString("account.following", comment: ""), for: .normal) - unfollowButton.showsMenuAsPrimaryAction = true - unfollowButton.menu = UIMenu(children: [UIDeferredMenuElement { [weak self] completion in - guard let accountViewModel = self?.viewModel.accountViewModel else { return } - - let unfollowAction = UIAction( - title: self?.unfollowButton.title(for: .normal) ?? "", - image: UIImage(systemName: "person.badge.minus"), - attributes: .destructive) { _ in - accountViewModel.unfollow() - } - - completion([unfollowAction]) - }]) + unfollowButton.setTitle(NSLocalizedString("account.unfollow", comment: ""), for: .normal) + unfollowButton.addAction( + UIAction { [weak self] _ in self?.viewModel.accountViewModel?.confirmUnfollow() }, + for: .touchUpInside) addSubview(baseStackView) baseStackView.translatesAutoresizingMaskIntoConstraints = false