From eb0f272c0beeb70ecfeca5de479fd5f36acf7d34 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 8 Sep 2018 21:35:40 -0400 Subject: [PATCH] Favorites and reblogs --- Artwork/Icons/Favorite.svg | 73 +++++++++++ Artwork/Icons/Reblog.svg | 123 ++++++++++++++++++ MyPlayground.playground/Contents.swift | 13 ++ MyPlayground.playground/contents.xcplayground | 4 + Tusker.xcodeproj/project.pbxproj | 4 + Tusker.xcworkspace/contents.xcworkspacedata | 3 + .../Favorite.imageset/Contents.json | 25 ++++ .../Favorite.imageset/Favorite.pdf | Bin 0 -> 1024 bytes .../Reblog.imageset/Contents.json | 25 ++++ .../Reblog.imageset/Reblog.pdf | Bin 0 -> 8328 bytes .../UIViewController+Delegates.swift | 3 + .../TimelineTableViewController.swift | 7 +- .../ConversationMainStatusTableViewCell.swift | 74 ++++++++++- .../ConversationMainStatusTableViewCell.xib | 32 ++++- Tusker/Views/Status/StatusTableViewCell.swift | 73 +++++++++++ Tusker/Views/Status/StatusTableViewCell.xib | 32 ++++- 16 files changed, 482 insertions(+), 9 deletions(-) create mode 100644 Artwork/Icons/Favorite.svg create mode 100644 Artwork/Icons/Reblog.svg create mode 100644 MyPlayground.playground/Contents.swift create mode 100644 MyPlayground.playground/contents.xcplayground create mode 100644 Tusker/Assets.xcassets/Favorite.imageset/Contents.json create mode 100644 Tusker/Assets.xcassets/Favorite.imageset/Favorite.pdf create mode 100644 Tusker/Assets.xcassets/Reblog.imageset/Contents.json create mode 100644 Tusker/Assets.xcassets/Reblog.imageset/Reblog.pdf diff --git a/Artwork/Icons/Favorite.svg b/Artwork/Icons/Favorite.svg new file mode 100644 index 00000000..90bbd0bc --- /dev/null +++ b/Artwork/Icons/Favorite.svg @@ -0,0 +1,73 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/Artwork/Icons/Reblog.svg b/Artwork/Icons/Reblog.svg new file mode 100644 index 00000000..3935d931 --- /dev/null +++ b/Artwork/Icons/Reblog.svg @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/MyPlayground.playground/Contents.swift b/MyPlayground.playground/Contents.swift new file mode 100644 index 00000000..d7b3d126 --- /dev/null +++ b/MyPlayground.playground/Contents.swift @@ -0,0 +1,13 @@ +import UIKit + +func test(_ nillable: String?) { + defer { + print("defer") + } + guard let value = nillable else { return } + print(value) +} + +test("test") +print("------") +test(nil) diff --git a/MyPlayground.playground/contents.xcplayground b/MyPlayground.playground/contents.xcplayground new file mode 100644 index 00000000..9f5f2f40 --- /dev/null +++ b/MyPlayground.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 9b84c491..f3f6a8f2 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -798,6 +798,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = HGYVAQA9FW; INFOPLIST_FILE = Tusker/Info.plist; @@ -807,6 +808,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.Tusker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -816,6 +818,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = HGYVAQA9FW; INFOPLIST_FILE = Tusker/Info.plist; @@ -825,6 +828,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = net.shadowfacts.Tusker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; }; diff --git a/Tusker.xcworkspace/contents.xcworkspacedata b/Tusker.xcworkspace/contents.xcworkspacedata index 9a8e8fd8..043d424d 100644 --- a/Tusker.xcworkspace/contents.xcworkspacedata +++ b/Tusker.xcworkspace/contents.xcworkspacedata @@ -1,6 +1,9 @@ + + diff --git a/Tusker/Assets.xcassets/Favorite.imageset/Contents.json b/Tusker/Assets.xcassets/Favorite.imageset/Contents.json new file mode 100644 index 00000000..b3fe065f --- /dev/null +++ b/Tusker/Assets.xcassets/Favorite.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Favorite.pdf", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Tusker/Assets.xcassets/Favorite.imageset/Favorite.pdf b/Tusker/Assets.xcassets/Favorite.imageset/Favorite.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3f7a12e86e7c8107ae89d77a630710f8383def48 GIT binary patch literal 1024 zcma)5L2DC16xLFe4#DC{@F4GCOba!;o6RPvgkqaCu~cbD6~!t#ZYIf=xD#h5ntBjD zc@P!!QlwP$Ru!Rwpi~6WA0T)TFXG9AAPAxbi^eybCJpVyVRvTdn|bej-+OO^xpZcq z5w=M1*|#Sv!~`Aq*=dqYf_8|xC0T|jLU{rJTE?kJCUC7#$Z1Dx?$^<%aDfOcf2%0SD}67zlLs9>%{vsU&F zvw}lMcpat?(!m_WH?D^Vtw<~uhf}^$in|i6JWzFLCOs>7t=hq>8OBFjR3|aGpsrU{ zA?=wKJO)zKd@@Q;3U8&^1;=Lj?1;M3l%wUD$7{l79;l?`JH#pKtzK9Y=lMj(oq~r# zl>U61drj%>a1iTokis63TtJ^q9l^l}8_{qA`pQyP_iLD61WSTe%Z}}ZxhVDb`(bi| z7iu>4-2a=c6(`;izR5pDC9UvM(=`^#TP@F;Op(e8}G$UtVqjN3hGpt@PE`v=MqE8s>*rJB`D#| b<{5K~98?+nx_Xid=_`yUOcD%^PGrbG238%c literal 0 HcmV?d00001 diff --git a/Tusker/Assets.xcassets/Reblog.imageset/Contents.json b/Tusker/Assets.xcassets/Reblog.imageset/Contents.json new file mode 100644 index 00000000..53d902aa --- /dev/null +++ b/Tusker/Assets.xcassets/Reblog.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Reblog.pdf", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/Tusker/Assets.xcassets/Reblog.imageset/Reblog.pdf b/Tusker/Assets.xcassets/Reblog.imageset/Reblog.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8048630df110751506a5f37ca415a6c54e7a9635 GIT binary patch literal 8328 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 literal 0 HcmV?d00001 diff --git a/Tusker/Extensions/UIViewController+Delegates.swift b/Tusker/Extensions/UIViewController+Delegates.swift index 936fc08b..d9463f4f 100644 --- a/Tusker/Extensions/UIViewController+Delegates.swift +++ b/Tusker/Extensions/UIViewController+Delegates.swift @@ -77,6 +77,9 @@ extension StatusTableViewCellDelegate where Self: UIViewController { present(vc, animated: true) } + func updatedStatus(for cell: StatusTableViewCell, status: Status) { + } + } extension LargeImageViewControllerDelegate where Self: UIViewController { diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 35ecbaef..0e19b485 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -133,5 +133,10 @@ class TimelineTableViewController: UITableViewController { } -extension TimelineTableViewController: StatusTableViewCellDelegate {} +extension TimelineTableViewController: StatusTableViewCellDelegate { + func updatedStatus(for cell: StatusTableViewCell, status: Status) { + let indexPath = tableView.indexPath(for: cell)! + statuses[indexPath.row] = status + } +} extension TimelineTableViewController: LargeImageViewControllerDelegate {} diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift index 9498d574..771e64f9 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.swift @@ -19,12 +19,24 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive @IBOutlet weak var avatarImageView: UIImageView! @IBOutlet weak var timestampLabel: UILabel! @IBOutlet weak var attachmentsView: UIView! + @IBOutlet weak var favoriteButton: UIButton! + @IBOutlet weak var reblogButton: UIButton! var status: Status! var account: Account! - var avatarURL: URL? + var favorited: Bool = false { + didSet { + favoriteButton.tintColor = favorited ? UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) : tintColor + } + } + var reblogged: Bool = false { + didSet { + reblogButton.tintColor = reblogged ? UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) : tintColor + } + } + var avatarURL: URL? var updateTimestampWorkItem: DispatchWorkItem? override func awakeFromNib() { @@ -37,6 +49,7 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive avatarImageView.layer.masksToBounds = true attachmentsView.layer.cornerRadius = 5 attachmentsView.layer.masksToBounds = true + contentLabel.delegate = self } func updateUIForPreferences() { @@ -97,8 +110,11 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive attachmentsView.isHidden = true } + let realStatus = status.reblog ?? status + favorited = realStatus.favourited ?? false + reblogged = realStatus.reblogged ?? false + contentLabel.status = status - contentLabel.delegate = self } func updateTimestamp() { @@ -147,6 +163,60 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive delegate?.reply(to: status) } + @IBAction func favoritePressed(_ sender: Any) { + let oldValue = favorited + favorited = !favorited + + let realStatus: Status = status.reblog ?? status + let req = favorited ? Statuses.favourite(id: realStatus.id) : Statuses.unfavourite(id: realStatus.id) + + MastodonController.shared.client.run(req) { result in + guard case .success = result else { + print("Couldn't favorite status \(realStatus.id)") + // todo: display error message + DispatchQueue.main.async { + self.favorited = oldValue + + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + } + return + } + + DispatchQueue.main.async { + let generator = UIImpactFeedbackGenerator(style: .light) + generator.impactOccurred() + } + } + } + + @IBAction func reblogPressed(_ sender: Any) { + let oldValue = reblogged + reblogged = !reblogged + + let realStatus: Status = status.reblog ?? status + let req = reblogged ? Statuses.reblog(id: realStatus.id) : Statuses.unreblog(id: realStatus.id) + + MastodonController.shared.client.run(req) { result in + guard case .success = result else { + print("Couldn't reblog status \(realStatus.id)") + // todo: display error message + DispatchQueue.main.async { + self.reblogged = oldValue + + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + } + return + } + + DispatchQueue.main.async { + let generator = UIImpactFeedbackGenerator(style: .light) + generator.impactOccurred() + } + } + } + } extension ConversationMainStatusTableViewCell: HTMLContentLabelDelegate { diff --git a/Tusker/Views/Status/ConversationMainStatusTableViewCell.xib b/Tusker/Views/Status/ConversationMainStatusTableViewCell.xib index 1b333c2f..0dfa51d8 100644 --- a/Tusker/Views/Status/ConversationMainStatusTableViewCell.xib +++ b/Tusker/Views/Status/ConversationMainStatusTableViewCell.xib @@ -79,21 +79,43 @@ - - + + + + + + + @@ -116,6 +138,8 @@ + + @@ -123,6 +147,8 @@ + + diff --git a/Tusker/Views/Status/StatusTableViewCell.swift b/Tusker/Views/Status/StatusTableViewCell.swift index 0645a823..357a49d1 100644 --- a/Tusker/Views/Status/StatusTableViewCell.swift +++ b/Tusker/Views/Status/StatusTableViewCell.swift @@ -25,6 +25,8 @@ protocol StatusTableViewCellDelegate { func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) + func updatedStatus(for cell: StatusTableViewCell, status: Status) + } class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { @@ -38,11 +40,24 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { @IBOutlet weak var reblogLabel: UILabel! @IBOutlet weak var timestampLabel: UILabel! @IBOutlet weak var attachmentsView: UIView! + @IBOutlet weak var favoriteButton: UIButton! + @IBOutlet weak var reblogButton: UIButton! var status: Status! var account: Account! var reblogger: Account? + var favorited: Bool = false { + didSet { + favoriteButton.tintColor = favorited ? UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) : tintColor + } + } + var reblogged: Bool = false { + didSet { + reblogButton.tintColor = reblogged ? UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1) : tintColor + } + } + var avatarURL: URL? var updateTimestampWorkItem: DispatchWorkItem? var attachmentDataTasks: [URLSessionDataTask] = [] @@ -129,6 +144,10 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { } + let realStatus = status.reblog ?? status + favorited = realStatus.favourited ?? false + reblogged = realStatus.reblogged ?? false + contentLabel.status = status } @@ -192,6 +211,60 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive { delegate?.selected(account: reblogger) } + @IBAction func favoritePressed(_ sender: Any) { + let oldValue = favorited + favorited = !favorited + + let realStatus: Status = status.reblog ?? status + let req = favorited ? Statuses.favourite(id: realStatus.id) : Statuses.unfavourite(id: realStatus.id) + + MastodonController.shared.client.run(req) { result in + guard case .success = result else { + print("Couldn't favorite status \(realStatus.id)") + // todo: display error message + DispatchQueue.main.async { + self.favorited = oldValue + + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + } + return + } + + DispatchQueue.main.async { + let generator = UIImpactFeedbackGenerator(style: .light) + generator.impactOccurred() + } + } + } + + @IBAction func reblogPressed(_ sender: Any) { + let oldValue = reblogged + reblogged = !reblogged + + let realStatus: Status = status.reblog ?? status + let req = reblogged ? Statuses.reblog(id: realStatus.id) : Statuses.unreblog(id: realStatus.id) + + MastodonController.shared.client.run(req) { result in + guard case .success = result else { + print("Couldn't reblog status \(realStatus.id)") + // todo: display error message + DispatchQueue.main.async { + self.reblogged = oldValue + + let generator = UINotificationFeedbackGenerator() + generator.notificationOccurred(.error) + } + return + } + + DispatchQueue.main.async { + let generator = UIImpactFeedbackGenerator(style: .light) + generator.impactOccurred() + } + } + } + } extension StatusTableViewCell: HTMLContentLabelDelegate { diff --git a/Tusker/Views/Status/StatusTableViewCell.xib b/Tusker/Views/Status/StatusTableViewCell.xib index cc9f1757..704abfa2 100644 --- a/Tusker/Views/Status/StatusTableViewCell.xib +++ b/Tusker/Views/Status/StatusTableViewCell.xib @@ -86,13 +86,12 @@ - - + + + + + + + @@ -123,6 +145,8 @@ + + @@ -131,6 +155,8 @@ + +