From 4c0607af79378adaf2d44480261bd6042e872214 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 14 Dec 2019 12:40:50 -0500 Subject: [PATCH] Add (un)bookmarking to status more options --- Pachyderm/Model/Status.swift | 10 +++++ Tusker.xcodeproj/project.pbxproj | 22 +++++++++- .../BookmarkStatusActivity.swift | 41 +++++++++++++++++++ .../Status Activities/StatusActivity.swift | 34 +++++++++++++++ .../UnbookmarkStatusActivity.swift | 41 +++++++++++++++++++ Tusker/Activities/UIActivity+Types.swift | 2 + Tusker/TuskerNavigationDelegate.swift | 10 ++++- 7 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 Tusker/Activities/Status Activities/BookmarkStatusActivity.swift create mode 100644 Tusker/Activities/Status Activities/StatusActivity.swift create mode 100644 Tusker/Activities/Status Activities/UnbookmarkStatusActivity.swift diff --git a/Pachyderm/Model/Status.swift b/Pachyderm/Model/Status.swift index 6f2b7587..520cc46e 100644 --- a/Pachyderm/Model/Status.swift +++ b/Pachyderm/Model/Status.swift @@ -35,6 +35,7 @@ public class Status: Decodable { public let application: Application? public let language: String? public let pinned: Bool? + public let bookmarked: Bool? public static func getContext(_ status: Status) -> Request { return Request(method: .get, path: "/api/v1/statuses/\(status.id)/context") @@ -84,6 +85,14 @@ public class Status: Decodable { return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unpin") } + public static func bookmark(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/bookmark") + } + + public static func unbookmark(_ status: Status) -> Request { + return Request(method: .post, path: "/api/v1/statuses/\(status.id)/unbookmark") + } + public static func muteConversation(_ status: Status) -> Request { return Request(method: .post, path: "/api/v1/statuses/\(status.id)/mute") } @@ -118,6 +127,7 @@ public class Status: Decodable { case application case language case pinned + case bookmarked } } diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 1de1358a..3fa118b2 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -77,6 +77,9 @@ D61AC1D8232EA42D00C54D2D /* InstanceTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61AC1D6232EA42D00C54D2D /* InstanceTableViewCell.swift */; }; D61AC1D9232EA42D00C54D2D /* InstanceTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D61AC1D7232EA42D00C54D2D /* InstanceTableViewCell.xib */; }; D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943123A5466600D38C68 /* SelectableTableViewCell.swift */; }; + D627943523A5525100D38C68 /* StatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943423A5525100D38C68 /* StatusActivity.swift */; }; + D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */; }; + D627943923A553B600D38C68 /* UnbookmarkStatusActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */; }; D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF75217E923E00CC0648 /* DraftsManager.swift */; }; D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627FF78217E950100CC0648 /* DraftsTableViewController.xib */; }; D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */; }; @@ -341,6 +344,9 @@ D61AC1D6232EA42D00C54D2D /* InstanceTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceTableViewCell.swift; sourceTree = ""; }; D61AC1D7232EA42D00C54D2D /* InstanceTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InstanceTableViewCell.xib; sourceTree = ""; }; D627943123A5466600D38C68 /* SelectableTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectableTableViewCell.swift; sourceTree = ""; }; + D627943423A5525100D38C68 /* StatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusActivity.swift; sourceTree = ""; }; + D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkStatusActivity.swift; sourceTree = ""; }; + D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnbookmarkStatusActivity.swift; sourceTree = ""; }; D627FF75217E923E00CC0648 /* DraftsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsManager.swift; sourceTree = ""; }; D627FF78217E950100CC0648 /* DraftsTableViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraftsTableViewController.xib; sourceTree = ""; }; D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsTableViewController.swift; sourceTree = ""; }; @@ -699,6 +705,16 @@ path = "Instance Cell"; sourceTree = ""; }; + D627943323A5523800D38C68 /* Status Activities */ = { + isa = PBXGroup; + children = ( + D627943423A5525100D38C68 /* StatusActivity.swift */, + D627943623A552C200D38C68 /* BookmarkStatusActivity.swift */, + D627943823A553B600D38C68 /* UnbookmarkStatusActivity.swift */, + ); + path = "Status Activities"; + sourceTree = ""; + }; D627FF77217E94F200CC0648 /* Drafts */ = { isa = PBXGroup; children = ( @@ -1043,8 +1059,9 @@ isa = PBXGroup; children = ( D6AEBB3D2321638100E5038B /* UIActivity+Types.swift */, - D6AEBB4623216B0C00E5038B /* Account Activities */, D6AEBB422321685E00E5038B /* OpenInSafariActivity.swift */, + D6AEBB4623216B0C00E5038B /* Account Activities */, + D627943323A5523800D38C68 /* Status Activities */, ); path = Activities; sourceTree = ""; @@ -1580,6 +1597,7 @@ D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, 0411610022B442870030A9B7 /* AttachmentViewController.swift in Sources */, D611C2CF232DC61100C86A49 /* HashtagTableViewCell.swift in Sources */, + D627943723A552C200D38C68 /* BookmarkStatusActivity.swift in Sources */, D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */, D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */, D6BC9DD7232D7811002CA326 /* TimelinesPageViewController.swift in Sources */, @@ -1614,6 +1632,7 @@ D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */, D6BED174212667E900F02DA0 /* TimelineStatusTableViewCell.swift in Sources */, 0427033822B30F5F000D31B6 /* BehaviorPrefsView.swift in Sources */, + D627943923A553B600D38C68 /* UnbookmarkStatusActivity.swift in Sources */, D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */, D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */, @@ -1622,6 +1641,7 @@ D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */, D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */, + D627943523A5525100D38C68 /* StatusActivity.swift in Sources */, 04496BD721625361001F1B23 /* ContentLabel.swift in Sources */, D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */, D6333B372137838300CE884A /* AttributedString+Helpers.swift in Sources */, diff --git a/Tusker/Activities/Status Activities/BookmarkStatusActivity.swift b/Tusker/Activities/Status Activities/BookmarkStatusActivity.swift new file mode 100644 index 00000000..b553af06 --- /dev/null +++ b/Tusker/Activities/Status Activities/BookmarkStatusActivity.swift @@ -0,0 +1,41 @@ +// +// BookmarkStatusActivity.swift +// Tusker +// +// Created by Shadowfacts on 12/14/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit +import Pachyderm + +class BookmarkStatusActivity: StatusActivity { + + override var activityType: UIActivity.ActivityType? { + return .bookmarkStatus + } + + override var activityTitle: String? { + return NSLocalizedString("Bookmark", comment: "bookmark status activity title") + } + + override var activityImage: UIImage? { + return UIImage(systemName: "bookmark") + } + + override func perform() { + guard let status = status else { return } + + let request = Status.bookmark(status) + MastodonController.client.run(request) { (response) in + if case let .success(status, _) = response { + MastodonCache.add(status: status) + } else { + // todo: display error message + UINotificationFeedbackGenerator().notificationOccurred(.error) + fatalError() + } + } + } + +} diff --git a/Tusker/Activities/Status Activities/StatusActivity.swift b/Tusker/Activities/Status Activities/StatusActivity.swift new file mode 100644 index 00000000..715b0a6e --- /dev/null +++ b/Tusker/Activities/Status Activities/StatusActivity.swift @@ -0,0 +1,34 @@ +// +// StatusActivity.swift +// Tusker +// +// Created by Shadowfacts on 12/14/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit +import Pachyderm + +class StatusActivity: UIActivity { + + override class var activityCategory: UIActivity.Category { + return .action + } + + var status: Status? + + override func canPerform(withActivityItems activityItems: [Any]) -> Bool { + for case is Status in activityItems { + return true + } + return false + } + + override func prepare(withActivityItems activityItems: [Any]) { + for case let status as Status in activityItems { + self.status = status + return + } + } + +} diff --git a/Tusker/Activities/Status Activities/UnbookmarkStatusActivity.swift b/Tusker/Activities/Status Activities/UnbookmarkStatusActivity.swift new file mode 100644 index 00000000..0857348d --- /dev/null +++ b/Tusker/Activities/Status Activities/UnbookmarkStatusActivity.swift @@ -0,0 +1,41 @@ +// +// UnbookmarkStatusActivity.swift +// Tusker +// +// Created by Shadowfacts on 12/14/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import UIKit +import Pachyderm + +class UnbookmarkStatusActivity: StatusActivity { + + override var activityType: UIActivity.ActivityType? { + return .unbookmarkStatus + } + + override var activityTitle: String? { + return NSLocalizedString("Unbookmark", comment: "unbookmark status activity title") + } + + override var activityImage: UIImage? { + return UIImage(systemName: "bookmark.fill") + } + + override func perform() { + guard let status = status else { return } + + let request = Status.unbookmark(status) + MastodonController.client.run(request) { (response) in + if case let .success(status, _) = response { + MastodonCache.add(status: status) + } else { + // todo: display error message + UINotificationFeedbackGenerator().notificationOccurred(.error) + fatalError() + } + } + } + +} diff --git a/Tusker/Activities/UIActivity+Types.swift b/Tusker/Activities/UIActivity+Types.swift index 4fc0de39..86b12d23 100644 --- a/Tusker/Activities/UIActivity+Types.swift +++ b/Tusker/Activities/UIActivity+Types.swift @@ -18,5 +18,7 @@ extension UIActivity.ActivityType { static let unfollowAccount = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unfollow_account") // Status + static let bookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).bookmark_status") + static let unbookmarkStatus = UIActivity.ActivityType("\(Bundle.main.bundleIdentifier!).unbookmark_status") } diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift index df4d96c5..7a7d7426 100644 --- a/Tusker/TuskerNavigationDelegate.swift +++ b/Tusker/TuskerNavigationDelegate.swift @@ -185,7 +185,15 @@ extension TuskerNavigationDelegate where Self: UIViewController { private func moreOptions(forStatus statusID: String) -> UIViewController { guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") } guard let url = status.url else { fatalError("Missing url for status \(statusID)") } - return moreOptions(forURL: url) + var customActivites = [UIActivity]() + + if let bookmarked = status.bookmarked { + customActivites.append(bookmarked ? UnbookmarkStatusActivity() : BookmarkStatusActivity()) + } + + let activityController = UIActivityViewController(activityItems: [url, status], applicationActivities: customActivites) + activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: url) + return activityController } func showMoreOptions(forStatus statusID: String) {