From 9ac1c43511eefe72b20af1edf3258b8f13deefa4 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 13 May 2023 13:48:49 -0400 Subject: [PATCH] Update favorite/reblog button appearance immediately on tap Fixes #381 --- Tusker.xcodeproj/project.pbxproj | 4 +++ ...ersationMainStatusCollectionViewCell.swift | 4 +-- .../Status/StatusCollectionViewCell.swift | 18 ++++++----- .../TimelineStatusCollectionViewCell.swift | 4 +-- Tusker/Views/ToggleableButton.swift | 31 +++++++++++++++++++ 5 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 Tusker/Views/ToggleableButton.swift diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 49c6c8f8..3d4d89e1 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -301,6 +301,7 @@ D6D79F2B2A0D5D5C00AB2315 /* StatusEditCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D79F2A2A0D5D5C00AB2315 /* StatusEditCollectionViewCell.swift */; }; D6D79F2D2A0D61B400AB2315 /* StatusEditContentTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D79F2C2A0D61B400AB2315 /* StatusEditContentTextView.swift */; }; D6D79F2F2A0D6A7F00AB2315 /* StatusEditPollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D79F2E2A0D6A7F00AB2315 /* StatusEditPollView.swift */; }; + D6D79F532A0FFE3200AB2315 /* ToggleableButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D79F522A0FFE3200AB2315 /* ToggleableButton.swift */; }; D6D94955298963A900C59229 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D94954298963A900C59229 /* Colors.swift */; }; D6D9498D298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D9498C298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift */; }; D6D9498F298EB79400C59229 /* CopyableLable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D9498E298EB79400C59229 /* CopyableLable.swift */; }; @@ -700,6 +701,7 @@ D6D79F2A2A0D5D5C00AB2315 /* StatusEditCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditCollectionViewCell.swift; sourceTree = ""; }; D6D79F2C2A0D61B400AB2315 /* StatusEditContentTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditContentTextView.swift; sourceTree = ""; }; D6D79F2E2A0D6A7F00AB2315 /* StatusEditPollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditPollView.swift; sourceTree = ""; }; + D6D79F522A0FFE3200AB2315 /* ToggleableButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleableButton.swift; sourceTree = ""; }; D6D94954298963A900C59229 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; D6D9498C298CBB4000C59229 /* TrendingStatusCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrendingStatusCollectionViewCell.swift; sourceTree = ""; }; D6D9498E298EB79400C59229 /* CopyableLable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLable.swift; sourceTree = ""; }; @@ -1371,6 +1373,7 @@ D65B4B69297777D900DABDFB /* StatusNotFoundView.swift */, 04ED00B021481ED800567C53 /* SteppedProgressView.swift */, D6093FB625BE0CF3004811E6 /* TrendHistoryView.swift */, + D6D79F522A0FFE3200AB2315 /* ToggleableButton.swift */, D686BBE224FBF8110068E6AA /* WrappedProgressView.swift */, D627944623A6AC9300D38C68 /* BasicTableViewCell.xib */, D6A3BC872321F78000FD64D5 /* Account Cell */, @@ -1945,6 +1948,7 @@ D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */, D6ADB6EC28EA73CB009924AB /* StatusContentContainer.swift in Sources */, D6969E9E240C81B9002843CE /* NSTextAttachment+Emoji.swift in Sources */, + D6D79F532A0FFE3200AB2315 /* ToggleableButton.swift in Sources */, D6BC9DB3232D4C07002CA326 /* WellnessPrefsView.swift in Sources */, D6ADB6F028ED1F25009924AB /* CachedImageView.swift in Sources */, D693DE5923FE24310061E07D /* InteractivePushTransition.swift in Sources */, diff --git a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift index 29f277cd..f996370b 100644 --- a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift @@ -191,13 +191,13 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status $0.addInteraction(UIPointerInteraction(delegate: self)) } - private(set) lazy var favoriteButton = UIButton().configure { + private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { $0.setImage(UIImage(systemName: "star.fill"), for: .normal) $0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside) $0.addInteraction(UIPointerInteraction(delegate: self)) } - private(set) lazy var reblogButton = UIButton().configure { + private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { $0.setImage(UIImage(systemName: "repeat"), for: .normal) $0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside) $0.addInteraction(UIPointerInteraction(delegate: self)) diff --git a/Tusker/Views/Status/StatusCollectionViewCell.swift b/Tusker/Views/Status/StatusCollectionViewCell.swift index 4072224e..e448c939 100644 --- a/Tusker/Views/Status/StatusCollectionViewCell.swift +++ b/Tusker/Views/Status/StatusCollectionViewCell.swift @@ -26,8 +26,8 @@ protocol StatusCollectionViewCell: UICollectionViewCell, AttachmentViewDelegate var collapseButton: StatusCollapseButton { get } var contentContainer: StatusContentContainer { get } var replyButton: UIButton { get } - var favoriteButton: UIButton { get } - var reblogButton: UIButton { get } + var favoriteButton: ToggleableButton { get } + var reblogButton: ToggleableButton { get } var moreButton: UIButton { get } var prevThreadLinkView: UIView? { get set } var nextThreadLinkView: UIView? { get set } @@ -59,7 +59,13 @@ extension StatusCollectionViewCell { .receive(on: DispatchQueue.main) .filter { [unowned self] in $0 == self.statusID } .sink { [unowned self] _ in - self.delegate?.statusCellNeedsReconfigure(self, animated: true, completion: nil) + if let status = self.mastodonController.persistentContainer.status(for: self.statusID) { + // update immediately w/o animation + self.favoriteButton.active = status.favourited + self.reblogButton.active = status.reblogged + + self.delegate?.statusCellNeedsReconfigure(self, animated: true, completion: nil) + } } .store(in: &cancellables) @@ -195,18 +201,16 @@ extension StatusCollectionViewCell { } func baseUpdateStatusState(status: StatusMO) { + favoriteButton.active = status.favourited if status.favourited { - favoriteButton.tintColor = UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) favoriteButton.accessibilityLabel = NSLocalizedString("Undo Favorite", comment: "undo favorite button accessibility label") } else { - favoriteButton.tintColor = nil favoriteButton.accessibilityLabel = NSLocalizedString("Favorite", comment: "favorite button accessibility label") } + reblogButton.active = status.reblogged if status.reblogged { - reblogButton.tintColor = UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) reblogButton.accessibilityLabel = NSLocalizedString("Undo Reblog", comment: "undo reblog button accessibility label") } else { - reblogButton.tintColor = nil reblogButton.accessibilityLabel = NSLocalizedString("Reblog", comment: "reblog button accessibility label") } diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index 2c988958..8852f668 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -238,13 +238,13 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti $0.addInteraction(UIPointerInteraction(delegate: self)) } - private(set) lazy var favoriteButton = UIButton().configure { + private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { $0.setImage(UIImage(systemName: "star.fill"), for: .normal) $0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside) $0.addInteraction(UIPointerInteraction(delegate: self)) } - private(set) lazy var reblogButton = UIButton().configure { + private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { $0.setImage(UIImage(systemName: "repeat"), for: .normal) $0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside) $0.addInteraction(UIPointerInteraction(delegate: self)) diff --git a/Tusker/Views/ToggleableButton.swift b/Tusker/Views/ToggleableButton.swift new file mode 100644 index 00000000..e380b8f9 --- /dev/null +++ b/Tusker/Views/ToggleableButton.swift @@ -0,0 +1,31 @@ +// +// ToggleableButton.swift +// Tusker +// +// Created by Shadowfacts on 5/13/23. +// Copyright © 2023 Shadowfacts. All rights reserved. +// + +import UIKit + +class ToggleableButton: UIButton { + + let activeColor: UIColor + + var active: Bool { + didSet { + tintColor = active ? activeColor : nil + } + } + + init(activeColor: UIColor) { + self.activeColor = activeColor + self.active = false + super.init(frame: .zero) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +}