From bd466deb74fe98134637e7a253eb47505f28c8ed Mon Sep 17 00:00:00 2001 From: Daniele Date: Sun, 20 Nov 2022 16:38:15 -0800 Subject: [PATCH] display favorites as likes --- Localizations/en.lproj/Localizable.strings | 3 + .../Utilities/AppPreferences.swift | 20 ++++++ Views/SwiftUI/PreferencesView.swift | 17 +++++ .../Content Views/NotificationView.swift | 19 +++-- Views/UIKit/Content Views/StatusView.swift | 71 +++++++++++++++---- 5 files changed, 113 insertions(+), 17 deletions(-) diff --git a/Localizations/en.lproj/Localizable.strings b/Localizations/en.lproj/Localizable.strings index f7f6054..bf32305 100644 --- a/Localizations/en.lproj/Localizable.strings +++ b/Localizations/en.lproj/Localizable.strings @@ -253,6 +253,7 @@ "preferences.require-double-tap-to-favorite" = "Require double tap to favorite"; "preferences.show-reblog-and-favorite-counts" = "Show boost and favorite counts"; "preferences.status-word" = "Status word"; +"preferences.display-favorites-as" = "Display favorites as"; "filters.active" = "Active"; "filters.expired" = "Expired"; "filter.add-new" = "Add New Filter"; @@ -279,6 +280,7 @@ "notifications" = "Notifications"; "notifications.reblogged-your-status-%@" = "%@ boosted your status"; "notifications.favourited-your-status-%@" = "%@ favorited your status"; +"notifications.liked-your-status-%@" = "%@ liked your status"; "notifications.followed-you-%@" = "%@ followed you"; "notifications.poll-ended" = "A poll you have voted in has ended"; "notifications.your-poll-ended" = "Your poll has ended"; @@ -356,3 +358,4 @@ "timelines.local" = "Local"; "timelines.federated" = "Federated"; "toot" = "Toot"; +"likes" = "Likes"; diff --git a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift index 828fa03..c77b6b4 100644 --- a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift +++ b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift @@ -32,6 +32,13 @@ public extension AppPreferences { public var id: String { rawValue } } + enum DisplayFavoritesAs: String, CaseIterable, Identifiable { + case favorites + case likes + + public var id: String { rawValue } + } + enum AnimateAvatars: String, CaseIterable, Identifiable { case everywhere case profiles @@ -79,6 +86,18 @@ public extension AppPreferences { set { self[.statusWord] = newValue.rawValue } } + var displayFavoritesAs: DisplayFavoritesAs { + get { + if let rawValue = self[.displayFavoritesAs] as String?, + let value = DisplayFavoritesAs(rawValue: rawValue) { + return value + } + + return .favorites + } + set { self[.displayFavoritesAs] = newValue.rawValue } + } + var animateAvatars: AnimateAvatars { get { if let rawValue = self[.animateAvatars] as String?, @@ -207,6 +226,7 @@ private extension AppPreferences { enum Item: String { case colorScheme case statusWord + case displayFavoritesAs case requireDoubleTapToReblog case requireDoubleTapToFavorite case animateAvatars diff --git a/Views/SwiftUI/PreferencesView.swift b/Views/SwiftUI/PreferencesView.swift index 296e58d..24b1dfd 100644 --- a/Views/SwiftUI/PreferencesView.swift +++ b/Views/SwiftUI/PreferencesView.swift @@ -101,6 +101,12 @@ struct PreferencesView: View { Text(option.localizedStringKey).tag(option) } } + Picker("preferences.display-favorites-as", + selection: $identityContext.appPreferences.displayFavoritesAs) { + ForEach(AppPreferences.DisplayFavoritesAs.allCases) { option in + Text(option.localizedStringKey).tag(option) + } + } Toggle("preferences.show-reblog-and-favorite-counts", isOn: $identityContext.appPreferences.showReblogAndFavoriteCounts) Toggle("preferences.require-double-tap-to-reblog", @@ -182,6 +188,17 @@ extension AppPreferences.StatusWord { } } +extension AppPreferences.DisplayFavoritesAs { + var localizedStringKey: LocalizedStringKey { + switch self { + case .favorites: + return "favorites" + case .likes: + return "likes" + } + } +} + extension AppPreferences.AnimateAvatars { var localizedStringKey: LocalizedStringKey { switch self { diff --git a/Views/UIKit/Content Views/NotificationView.swift b/Views/UIKit/Content Views/NotificationView.swift index 0e29641..7127a26 100644 --- a/Views/UIKit/Content Views/NotificationView.swift +++ b/Views/UIKit/Content Views/NotificationView.swift @@ -165,7 +165,7 @@ private extension NotificationView { func applyNotificationConfiguration() { let viewModel = notificationConfiguration.viewModel - + var imageName = viewModel.type.systemImageName avatarImageView.sd_setImage(with: viewModel.accountViewModel.avatarURL()) switch viewModel.type { @@ -184,12 +184,23 @@ private extension NotificationView { identityContext: viewModel.identityContext) iconImageView.tintColor = .systemGreen case .favourite: - typeLabel.attributedText = "notifications.favourited-your-status-%@".localizedBolding( + let label: String + let color: UIColor + switch viewModel.identityContext.appPreferences.displayFavoritesAs { + case .favorites: + label = "notifications.favourited-your-status-%@" + color = .systemYellow + case .likes: + label = "notifications.liked-your-status-%@" + color = .systemRed + imageName = "heart.fill" + } + typeLabel.attributedText = label.localizedBolding( displayName: viewModel.accountViewModel.displayName, emojis: viewModel.accountViewModel.emojis, label: typeLabel, identityContext: viewModel.identityContext) - iconImageView.tintColor = .systemYellow + iconImageView.tintColor = color case .poll: typeLabel.text = NSLocalizedString( viewModel.accountViewModel.isSelf @@ -229,7 +240,7 @@ private extension NotificationView { timeLabel.accessibilityLabel = viewModel.accessibilityTime iconImageView.image = UIImage( - systemName: viewModel.type.systemImageName, + systemName: imageName, withConfiguration: UIImage.SymbolConfiguration(scale: .medium)) let accessibilityAttributedLabel = NSMutableAttributedString(string: "") diff --git a/Views/UIKit/Content Views/StatusView.swift b/Views/UIKit/Content Views/StatusView.swift index 89a103e..ce10687 100644 --- a/Views/UIKit/Content Views/StatusView.swift +++ b/Views/UIKit/Content Views/StatusView.swift @@ -835,10 +835,24 @@ private extension StatusView { return accessibilityAttributedLabel } + var favoriteIcon: String { + switch statusConfiguration.viewModel.identityContext.appPreferences.displayFavoritesAs { + case .favorites: return "star" + case .likes: return "heart" + } + } + + var favoritedIcon: String { + switch statusConfiguration.viewModel.identityContext.appPreferences.displayFavoritesAs { + case .favorites: return "star.fill" + case .likes: return "heart.fill" + } + } + func setButtonImages(font: UIFont) { let visibility = statusConfiguration.viewModel.visibility let reblogSystemImageName: String - + let isFavorited = statusConfiguration.viewModel.favorited if statusConfiguration.viewModel.configuration.isContextParent { reblogSystemImageName = "arrow.2.squarepath" } else { @@ -858,7 +872,7 @@ private extension StatusView { pointSize: font.pointSize, weight: statusConfiguration.viewModel.reblogged ? .bold : .regular)), for: .normal) - favoriteButton.setImage(UIImage(systemName: statusConfiguration.viewModel.favorited ? "star.fill" : "star", + favoriteButton.setImage(UIImage(systemName: isFavorited ? favoritedIcon : favoriteIcon, withConfiguration: UIImage.SymbolConfiguration(pointSize: font.pointSize)), for: .normal) shareButton.setImage(UIImage(systemName: "square.and.arrow.up", @@ -905,7 +919,11 @@ private extension StatusView { } func setFavoriteButtonColor(favorited: Bool) { - let favoriteColor: UIColor = favorited ? .systemYellow : .secondaryLabel + var favoriteColor: UIColor + switch statusConfiguration.viewModel.identityContext.appPreferences.displayFavoritesAs { + case .favorites: favoriteColor = favorited ? .systemYellow : .secondaryLabel + case .likes: favoriteColor = favorited ? .systemRed : .secondaryLabel + } favoriteButton.tintColor = favoriteColor favoriteButton.setTitleColor(favoriteColor, for: .normal) @@ -938,20 +956,47 @@ private extension StatusView { statusConfiguration.viewModel.toggleReblogged() } + func animateFavorite() { + switch statusConfiguration.viewModel.identityContext.appPreferences.displayFavoritesAs { + + case .favorites: + self.animateAsFavorite() + case .likes: + self.animateAsLike() + } + } + + func animateAsFavorite() { + UIViewPropertyAnimator.runningPropertyAnimator( + withDuration: .defaultAnimationDuration, + delay: 0, + options: .curveLinear) { + self.setFavoriteButtonColor(favorited: !self.statusConfiguration.viewModel.favorited) + self.favoriteButton.imageView?.transform = + self.favoriteButton.imageView?.transform.rotated(by: .pi) ?? .identity + } completion: { _ in + self.favoriteButton.imageView?.transform = .identity + } + } + + func animateAsLike() { + UIViewPropertyAnimator.runningPropertyAnimator( + withDuration: .defaultAnimationDuration, + delay: 0, + options: .curveEaseInOut) { + self.setFavoriteButtonColor(favorited: !self.statusConfiguration.viewModel.favorited) + self.favoriteButton.imageView?.transform = + self.favoriteButton.imageView?.transform.scaledBy(x: 0.7, y: 0.7) ?? .identity + } completion: { _ in + self.favoriteButton.imageView?.transform = .identity + } + } + func favorite() { UIImpactFeedbackGenerator(style: .medium).impactOccurred() if !UIAccessibility.isReduceMotionEnabled { - UIViewPropertyAnimator.runningPropertyAnimator( - withDuration: .defaultAnimationDuration, - delay: 0, - options: .curveLinear) { - self.setFavoriteButtonColor(favorited: !self.statusConfiguration.viewModel.favorited) - self.favoriteButton.imageView?.transform = - self.favoriteButton.imageView?.transform.rotated(by: .pi) ?? .identity - } completion: { _ in - self.favoriteButton.imageView?.transform = .identity - } + self.animateFavorite() } statusConfiguration.viewModel.toggleFavorited()