From 06855420da8e99bbaf3f25a5ec620e21f270df0d Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 18 Apr 2023 19:47:49 -0400 Subject: [PATCH] Move preferences to shared package --- Packages/TuskerPreferences/.gitignore | 9 ++ Packages/TuskerPreferences/Package.swift | 28 ++++ .../TuskerPreferences}/AvatarStyle.swift | 8 +- .../ContentWarningCopyMode.swift | 4 +- .../NotificationsMode.swift | 6 +- .../Preferences+Notification.swift | 4 +- .../TuskerPreferences}/Preferences.swift | 136 ++++++++++-------- .../TuskerPreferences/StatusSwipeAction.swift | 53 +++++++ Tusker.xcodeproj/project.pbxproj | 37 ++--- Tusker/AppDelegate.swift | 14 +- ...eAction.swift => StatusSwipeActions.swift} | 46 +----- .../NotificationsPageViewController.swift | 1 + .../Preferences/ComposingPrefsView.swift | 1 + .../Preferences/SwipeActionsPrefsView.swift | 1 + .../Preferences/WellnessPrefsView.swift | 1 + Tusker/Shortcuts/UserActivityManager.swift | 1 + 16 files changed, 208 insertions(+), 142 deletions(-) create mode 100644 Packages/TuskerPreferences/.gitignore create mode 100644 Packages/TuskerPreferences/Package.swift rename {Tusker/Preferences => Packages/TuskerPreferences/Sources/TuskerPreferences}/AvatarStyle.swift (69%) rename {Tusker/Preferences => Packages/TuskerPreferences/Sources/TuskerPreferences}/ContentWarningCopyMode.swift (81%) rename {Tusker/Preferences => Packages/TuskerPreferences/Sources/TuskerPreferences}/NotificationsMode.swift (81%) rename {Tusker/Preferences => Packages/TuskerPreferences/Sources/TuskerPreferences}/Preferences+Notification.swift (51%) rename {Tusker/Preferences => Packages/TuskerPreferences/Sources/TuskerPreferences}/Preferences.swift (77%) create mode 100644 Packages/TuskerPreferences/Sources/TuskerPreferences/StatusSwipeAction.swift rename Tusker/Preferences/{StatusSwipeAction.swift => StatusSwipeActions.swift} (85%) diff --git a/Packages/TuskerPreferences/.gitignore b/Packages/TuskerPreferences/.gitignore new file mode 100644 index 00000000..3b298120 --- /dev/null +++ b/Packages/TuskerPreferences/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ +DerivedData/ +.swiftpm/config/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/Packages/TuskerPreferences/Package.swift b/Packages/TuskerPreferences/Package.swift new file mode 100644 index 00000000..f536c5ae --- /dev/null +++ b/Packages/TuskerPreferences/Package.swift @@ -0,0 +1,28 @@ +// swift-tools-version: 5.8 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "TuskerPreferences", + platforms: [ + .iOS(.v15), + ], + products: [ + // Products define the executables and libraries a package produces, making them visible to other packages. + .library( + name: "TuskerPreferences", + targets: ["TuskerPreferences"]), + ], + dependencies: [ + .package(path: "../Pachyderm"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .target( + name: "TuskerPreferences", + dependencies: ["Pachyderm"] + ), + ] +) diff --git a/Tusker/Preferences/AvatarStyle.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/AvatarStyle.swift similarity index 69% rename from Tusker/Preferences/AvatarStyle.swift rename to Packages/TuskerPreferences/Sources/TuskerPreferences/AvatarStyle.swift index 1cace394..b91683ec 100644 --- a/Tusker/Preferences/AvatarStyle.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/AvatarStyle.swift @@ -1,6 +1,6 @@ // // AvatarStyle.swift -// Tusker +// TuskerPreferences // // Created by Shadowfacts on 8/28/18. // Copyright © 2018 Shadowfacts. All rights reserved. @@ -8,12 +8,12 @@ import UIKit -enum AvatarStyle: String, Codable { +public enum AvatarStyle: String, Codable { case roundRect, circle } extension AvatarStyle { - var cornerRadiusFraction: CGFloat { + public var cornerRadiusFraction: CGFloat { switch self { case .roundRect: return 0.1 @@ -22,7 +22,7 @@ extension AvatarStyle { } } - func cornerRadius(for view: UIView) -> CGFloat { + public func cornerRadius(for view: UIView) -> CGFloat { return cornerRadiusFraction * view.frame.width } } diff --git a/Tusker/Preferences/ContentWarningCopyMode.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/ContentWarningCopyMode.swift similarity index 81% rename from Tusker/Preferences/ContentWarningCopyMode.swift rename to Packages/TuskerPreferences/Sources/TuskerPreferences/ContentWarningCopyMode.swift index 03e08813..28951230 100644 --- a/Tusker/Preferences/ContentWarningCopyMode.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/ContentWarningCopyMode.swift @@ -1,6 +1,6 @@ // // ContentWarningCopyMode.swift -// Tusker +// TuskerPreferences // // Created by Shadowfacts on 7/31/19. // Copyright © 2019 Shadowfacts. All rights reserved. @@ -8,7 +8,7 @@ import Foundation -enum ContentWarningCopyMode: String, Codable { +public enum ContentWarningCopyMode: String, Codable { case asIs // copy CW as-is case prependRe // prepend 're: ' to the beginning of the CW, if it doesn't already have it case doNotCopy // don't copy CW at all diff --git a/Tusker/Preferences/NotificationsMode.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/NotificationsMode.swift similarity index 81% rename from Tusker/Preferences/NotificationsMode.swift rename to Packages/TuskerPreferences/Sources/TuskerPreferences/NotificationsMode.swift index 03d03d1b..a59a6f79 100644 --- a/Tusker/Preferences/NotificationsMode.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/NotificationsMode.swift @@ -1,6 +1,6 @@ // // NotificationsMode.swift -// Tusker +// TuskerPreferences // // Created by Shadowfacts on 9/14/19. // Copyright © 2019 Shadowfacts. All rights reserved. @@ -8,13 +8,13 @@ import Foundation -enum NotificationsMode: String, Codable, CaseIterable { +public enum NotificationsMode: String, Codable, CaseIterable { case allNotifications case mentionsOnly } extension NotificationsMode { - var displayName: String { + public var displayName: String { switch self { case .allNotifications: return NSLocalizedString("All Notifications", comment: "display all notifications mode") diff --git a/Tusker/Preferences/Preferences+Notification.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences+Notification.swift similarity index 51% rename from Tusker/Preferences/Preferences+Notification.swift rename to Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences+Notification.swift index a6ac020c..55d30ba1 100644 --- a/Tusker/Preferences/Preferences+Notification.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences+Notification.swift @@ -9,6 +9,6 @@ import Foundation extension Notification.Name { - static let preferencesChanged = Notification.Name("Tusker.preferencesChanged") - static let themePreferenceChanged = Notification.Name("Tusker.themePreferenceChanged") + public static let preferencesChanged = Notification.Name("Tusker.preferencesChanged") + public static let themePreferenceChanged = Notification.Name("Tusker.themePreferenceChanged") } diff --git a/Tusker/Preferences/Preferences.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift similarity index 77% rename from Tusker/Preferences/Preferences.swift rename to Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift index b5e8654e..0515b1d6 100644 --- a/Tusker/Preferences/Preferences.swift +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/Preferences.swift @@ -1,6 +1,6 @@ // // Preferences.swift -// Tusker +// TuskerPreferences // // Created by Shadowfacts on 8/28/18. // Copyright © 2018 Shadowfacts. All rights reserved. @@ -10,20 +10,21 @@ import UIKit import Pachyderm import Combine -class Preferences: Codable, ObservableObject { +public class Preferences: Codable, ObservableObject { - static var shared: Preferences = load() + public static var shared: Preferences = load() private static var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! - private static var archiveURL = Preferences.documentsDirectory.appendingPathComponent("preferences").appendingPathExtension("plist") + private static var appGroupDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.space.vaccor.Tusker")! + private static var archiveURL = appGroupDirectory.appendingPathComponent("preferences").appendingPathExtension("plist") - static func save() { + public static func save() { let encoder = PropertyListEncoder() let data = try? encoder.encode(shared) try? data?.write(to: archiveURL, options: .noFileProtection) } - static func load() -> Preferences { + public static func load() -> Preferences { let decoder = PropertyListDecoder() if let data = try? Data(contentsOf: archiveURL), let preferences = try? decoder.decode(Preferences.self, from: data) { @@ -32,9 +33,20 @@ class Preferences: Codable, ObservableObject { return Preferences() } + public static func migrate(from url: URL) -> Result { + do { + try? FileManager.default.removeItem(at: archiveURL) + try FileManager.default.moveItem(at: url, to: archiveURL) + } catch { + return .failure(error) + } + shared = load() + return .success(()) + } + private init() {} - required init(from decoder: Decoder) throws { + public required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.theme = try container.decode(UIUserInterfaceStyle.self, forKey: .theme) @@ -91,7 +103,7 @@ class Preferences: Codable, ObservableObject { self.hasShownFederatedTimelineDescription = try container.decodeIfPresent(Bool.self, forKey: .hasShownFederatedTimelineDescription) ?? false } - func encode(to encoder: Encoder) throws { + public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(theme, forKey: .theme) @@ -145,29 +157,29 @@ class Preferences: Codable, ObservableObject { } // MARK: Appearance - @Published var theme = UIUserInterfaceStyle.unspecified - @Published var pureBlackDarkMode = true - @Published var accentColor = AccentColor.default - @Published var avatarStyle = AvatarStyle.roundRect - @Published var hideCustomEmojiInUsernames = false - @Published var showIsStatusReplyIcon = false - @Published var alwaysShowStatusVisibilityIcon = false - @Published var hideActionsInTimeline = false - @Published var showLinkPreviews = true - @Published var leadingStatusSwipeActions: [StatusSwipeAction] = [.favorite, .reblog] - @Published var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share] + @Published public var theme = UIUserInterfaceStyle.unspecified + @Published public var pureBlackDarkMode = true + @Published public var accentColor = AccentColor.default + @Published public var avatarStyle = AvatarStyle.roundRect + @Published public var hideCustomEmojiInUsernames = false + @Published public var showIsStatusReplyIcon = false + @Published public var alwaysShowStatusVisibilityIcon = false + @Published public var hideActionsInTimeline = false + @Published public var showLinkPreviews = true + @Published public var leadingStatusSwipeActions: [StatusSwipeAction] = [.favorite, .reblog] + @Published public var trailingStatusSwipeActions: [StatusSwipeAction] = [.reply, .share] // MARK: Composing - @Published var defaultPostVisibility = Visibility.public - @Published var defaultReplyVisibility = ReplyVisibility.sameAsPost - @Published var automaticallySaveDrafts = true - @Published var requireAttachmentDescriptions = false - @Published var contentWarningCopyMode = ContentWarningCopyMode.asIs - @Published var mentionReblogger = false - @Published var useTwitterKeyboard = false + @Published public var defaultPostVisibility = Visibility.public + @Published public var defaultReplyVisibility = ReplyVisibility.sameAsPost + @Published public var automaticallySaveDrafts = true + @Published public var requireAttachmentDescriptions = false + @Published public var contentWarningCopyMode = ContentWarningCopyMode.asIs + @Published public var mentionReblogger = false + @Published public var useTwitterKeyboard = false // MARK: Media - @Published var attachmentBlurMode = AttachmentBlurMode.useStatusSetting { + @Published public var attachmentBlurMode = AttachmentBlurMode.useStatusSetting { didSet { if attachmentBlurMode == .always { blurMediaBehindContentWarning = true @@ -176,38 +188,38 @@ class Preferences: Codable, ObservableObject { } } } - @Published var blurMediaBehindContentWarning = true - @Published var automaticallyPlayGifs = true - @Published var showUncroppedMediaInline = true - @Published var showAttachmentBadges = true + @Published public var blurMediaBehindContentWarning = true + @Published public var automaticallyPlayGifs = true + @Published public var showUncroppedMediaInline = true + @Published public var showAttachmentBadges = true // MARK: Behavior - @Published var openLinksInApps = true - @Published var useInAppSafari = true - @Published var inAppSafariAutomaticReaderMode = false - @Published var expandAllContentWarnings = false - @Published var collapseLongPosts = true - @Published var oppositeCollapseKeywords: [String] = [] - @Published var confirmBeforeReblog = false - @Published var timelineStateRestoration = true - @Published var timelineSyncMode = TimelineSyncMode.icloud - @Published var hideReblogsInTimelines = false - @Published var hideRepliesInTimelines = false + @Published public var openLinksInApps = true + @Published public var useInAppSafari = true + @Published public var inAppSafariAutomaticReaderMode = false + @Published public var expandAllContentWarnings = false + @Published public var collapseLongPosts = true + @Published public var oppositeCollapseKeywords: [String] = [] + @Published public var confirmBeforeReblog = false + @Published public var timelineStateRestoration = true + @Published public var timelineSyncMode = TimelineSyncMode.icloud + @Published public var hideReblogsInTimelines = false + @Published public var hideRepliesInTimelines = false // MARK: Digital Wellness - @Published var showFavoriteAndReblogCounts = true - @Published var defaultNotificationsMode = NotificationsMode.allNotifications - @Published var grayscaleImages = false - @Published var disableInfiniteScrolling = false - @Published var hideTrends = false + @Published public var showFavoriteAndReblogCounts = true + @Published public var defaultNotificationsMode = NotificationsMode.allNotifications + @Published public var grayscaleImages = false + @Published public var disableInfiniteScrolling = false + @Published public var hideTrends = false // MARK: Advanced - @Published var statusContentType: StatusContentType = .plain - @Published var reportErrorsAutomatically = true + @Published public var statusContentType: StatusContentType = .plain + @Published public var reportErrorsAutomatically = true // MARK: - @Published var hasShownLocalTimelineDescription = false - @Published var hasShownFederatedTimelineDescription = false + @Published public var hasShownLocalTimelineDescription = false + @Published public var hasShownFederatedTimelineDescription = false private enum CodingKeys: String, CodingKey { case theme @@ -264,13 +276,13 @@ class Preferences: Codable, ObservableObject { } extension Preferences { - enum ReplyVisibility: Codable, Hashable, CaseIterable { + public enum ReplyVisibility: Codable, Hashable, CaseIterable { case sameAsPost case visibility(Visibility) - static var allCases: [Preferences.ReplyVisibility] = [.sameAsPost] + Visibility.allCases.map { .visibility($0) } + public static var allCases: [Preferences.ReplyVisibility] = [.sameAsPost] + Visibility.allCases.map { .visibility($0) } - var resolved: Visibility { + public var resolved: Visibility { switch self { case .sameAsPost: return Preferences.shared.defaultPostVisibility @@ -279,7 +291,7 @@ extension Preferences { } } - var displayName: String { + public var displayName: String { switch self { case .sameAsPost: return "Same as Default" @@ -288,7 +300,7 @@ extension Preferences { } } - var imageName: String? { + public var imageName: String? { switch self { case .sameAsPost: return nil @@ -300,12 +312,12 @@ extension Preferences { } extension Preferences { - enum AttachmentBlurMode: Codable, Hashable, CaseIterable { + public enum AttachmentBlurMode: Codable, Hashable, CaseIterable { case useStatusSetting case always case never - var displayName: String { + public var displayName: String { switch self { case .useStatusSetting: return "Default" @@ -321,7 +333,7 @@ extension Preferences { extension UIUserInterfaceStyle: Codable {} extension Preferences { - enum AccentColor: String, Codable, CaseIterable { + public enum AccentColor: String, Codable, CaseIterable { case `default` case purple case indigo @@ -336,7 +348,7 @@ extension Preferences { case pink // case brown - var color: UIColor? { + public var color: UIColor? { switch self { case .default: return nil @@ -367,7 +379,7 @@ extension Preferences { } } - var name: String { + public var name: String { switch self { case .default: return "Default" @@ -401,7 +413,7 @@ extension Preferences { } extension Preferences { - enum TimelineSyncMode: String, Codable { + public enum TimelineSyncMode: String, Codable { case mastodon case icloud } diff --git a/Packages/TuskerPreferences/Sources/TuskerPreferences/StatusSwipeAction.swift b/Packages/TuskerPreferences/Sources/TuskerPreferences/StatusSwipeAction.swift new file mode 100644 index 00000000..ae3aa98b --- /dev/null +++ b/Packages/TuskerPreferences/Sources/TuskerPreferences/StatusSwipeAction.swift @@ -0,0 +1,53 @@ +// +// StatusSwipeAction.swift +// Tusker +// +// Created by Shadowfacts on 11/26/22. +// Copyright © 2022 Shadowfacts. All rights reserved. +// + +import UIKit +import Pachyderm + +public enum StatusSwipeAction: String, Codable, Hashable, CaseIterable { + case reply + case favorite + case reblog + case share + case bookmark + case openInSafari + + public var displayName: String { + switch self { + case .reply: + return "Reply" + case .favorite: + return "Favorite" + case .reblog: + return "Reblog" + case .share: + return "Share" + case .bookmark: + return "Bookmark" + case .openInSafari: + return "Open in Safari" + } + } + + public var systemImageName: String { + switch self { + case .reply: + return "arrowshape.turn.up.left.fill" + case .favorite: + return "star.fill" + case .reblog: + return "repeat" + case .share: + return "square.and.arrow.up" + case .bookmark: + return "bookmark.fill" + case .openInSafari: + return "safari" + } + } +} diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 10d3d469..aab086d6 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -53,7 +53,7 @@ D61DC84628F498F200B82C6E /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61DC84528F498F200B82C6E /* Logging.swift */; }; D61DC84B28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61DC84A28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift */; }; D61DC84D28F500D200B82C6E /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61DC84C28F500D200B82C6E /* ProfileViewController.swift */; }; - D61F75882932DB6000C0B37F /* StatusSwipeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61F75872932DB6000C0B37F /* StatusSwipeAction.swift */; }; + D61F75882932DB6000C0B37F /* StatusSwipeActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61F75872932DB6000C0B37F /* StatusSwipeActions.swift */; }; D61F758A2932E1FC00C0B37F /* SwipeActionsPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61F75892932E1FC00C0B37F /* SwipeActionsPrefsView.swift */; }; D61F758D2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D61F758B2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.swift */; }; D61F758E2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D61F758C2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.xib */; }; @@ -151,8 +151,6 @@ D6620ACE2511A0ED00312CA0 /* StatusStateResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6620ACD2511A0ED00312CA0 /* StatusStateResolver.swift */; }; D662AEEF263A3B880082A153 /* PollFinishedTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D662AEED263A3B880082A153 /* PollFinishedTableViewCell.swift */; }; D662AEF0263A3B880082A153 /* PollFinishedTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D662AEEE263A3B880082A153 /* PollFinishedTableViewCell.xib */; }; - D663626221360B1900C9CBA2 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626121360B1900C9CBA2 /* Preferences.swift */; }; - D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626321360D2300C9CBA2 /* AvatarStyle.swift */; }; D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; }; D6674AEA23341F7600E8DF94 /* AppShortcutItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */; }; D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */ = {isa = PBXBuildFile; productRef = D6676CA427A8D0020052936B /* WebURLFoundationExtras */; }; @@ -256,7 +254,6 @@ D6BC8748219738E1006163F1 /* EnhancedTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */; }; D6BC9DB1232C61BC002CA326 /* NotificationsPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DB0232C61BC002CA326 /* NotificationsPageViewController.swift */; }; D6BC9DB3232D4C07002CA326 /* WellnessPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DB2232D4C07002CA326 /* WellnessPrefsView.swift */; }; - D6BC9DB5232D4CE3002CA326 /* NotificationsMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DB4232D4CE3002CA326 /* NotificationsMode.swift */; }; D6BC9DD7232D7811002CA326 /* TimelinesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DD6232D7811002CA326 /* TimelinesPageViewController.swift */; }; D6BC9DDA232D8BE5002CA326 /* SearchResultsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC9DD9232D8BE5002CA326 /* SearchResultsViewController.swift */; }; D6BD395929B64426005FFD2B /* ComposeUI in Frameworks */ = {isa = PBXBuildFile; productRef = D6BD395829B64426005FFD2B /* ComposeUI */; }; @@ -280,6 +277,7 @@ D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D882139E6EC00CB5196 /* AttachmentView.swift */; }; D6CA6A92249FAD8900AD45C1 /* AudioSessionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */; }; D6CA6A94249FADE700AD45C1 /* GalleryPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA6A93249FADE700AD45C1 /* GalleryPlayerViewController.swift */; }; + D6CA6ED229EF6091003EC5DF /* TuskerPreferences in Frameworks */ = {isa = PBXBuildFile; productRef = D6CA6ED129EF6091003EC5DF /* TuskerPreferences */; }; D6CA8CDA2962231F0050C433 /* ArrayUniqueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA8CD92962231F0050C433 /* ArrayUniqueTests.swift */; }; D6CA8CDE296387310050C433 /* SaveToPhotosActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA8CDD296387310050C433 /* SaveToPhotosActivity.swift */; }; D6D12B2F2925D66500D528E1 /* TimelineGapCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D12B2E2925D66500D528E1 /* TimelineGapCollectionViewCell.swift */; }; @@ -298,8 +296,6 @@ 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 */; }; - D6DD353D22F28CD000A9563A /* ContentWarningCopyMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD353C22F28CD000A9563A /* ContentWarningCopyMode.swift */; }; - D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */; }; D6DD8FFD298495A8002AD3FD /* LogoutService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD8FFC298495A8002AD3FD /* LogoutService.swift */; }; D6DD8FFF2984D327002AD3FD /* BookmarksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD8FFE2984D327002AD3FD /* BookmarksViewController.swift */; }; D6DD996B2998611A0015C962 /* SuggestedProfilesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DD996A2998611A0015C962 /* SuggestedProfilesViewController.swift */; }; @@ -432,7 +428,7 @@ D61DC84528F498F200B82C6E /* Logging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logging.swift; sourceTree = ""; }; D61DC84A28F4FD2000B82C6E /* ProfileHeaderCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileHeaderCollectionViewCell.swift; sourceTree = ""; }; D61DC84C28F500D200B82C6E /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; - D61F75872932DB6000C0B37F /* StatusSwipeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusSwipeAction.swift; sourceTree = ""; }; + D61F75872932DB6000C0B37F /* StatusSwipeActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusSwipeActions.swift; sourceTree = ""; }; D61F75892932E1FC00C0B37F /* SwipeActionsPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeActionsPrefsView.swift; sourceTree = ""; }; D61F758B2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusUpdatedNotificationTableViewCell.swift; sourceTree = ""; }; D61F758C2933C69C00C0B37F /* StatusUpdatedNotificationTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusUpdatedNotificationTableViewCell.xib; sourceTree = ""; }; @@ -531,8 +527,6 @@ D6620ACD2511A0ED00312CA0 /* StatusStateResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusStateResolver.swift; sourceTree = ""; }; D662AEED263A3B880082A153 /* PollFinishedTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollFinishedTableViewCell.swift; sourceTree = ""; }; D662AEEE263A3B880082A153 /* PollFinishedTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PollFinishedTableViewCell.xib; sourceTree = ""; }; - D663626121360B1900C9CBA2 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; - D663626321360D2300C9CBA2 /* AvatarStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarStyle.swift; sourceTree = ""; }; D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = ""; }; D6674AE923341F7600E8DF94 /* AppShortcutItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppShortcutItems.swift; sourceTree = ""; }; D667E5E02134937B0057A976 /* TimelineStatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TimelineStatusTableViewCell.xib; sourceTree = ""; }; @@ -637,7 +631,6 @@ D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedTableViewController.swift; sourceTree = ""; }; D6BC9DB0232C61BC002CA326 /* NotificationsPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsPageViewController.swift; sourceTree = ""; }; D6BC9DB2232D4C07002CA326 /* WellnessPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WellnessPrefsView.swift; sourceTree = ""; }; - D6BC9DB4232D4CE3002CA326 /* NotificationsMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsMode.swift; sourceTree = ""; }; D6BC9DD6232D7811002CA326 /* TimelinesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelinesPageViewController.swift; sourceTree = ""; }; D6BC9DD9232D8BE5002CA326 /* SearchResultsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultsViewController.swift; sourceTree = ""; }; D6BD395729B6441F005FFD2B /* ComposeUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = ComposeUI; path = Packages/ComposeUI; sourceTree = ""; }; @@ -662,6 +655,7 @@ D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = ""; }; D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionHelper.swift; sourceTree = ""; }; D6CA6A93249FADE700AD45C1 /* GalleryPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryPlayerViewController.swift; sourceTree = ""; }; + D6CA6ED029EF6060003EC5DF /* TuskerPreferences */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = TuskerPreferences; path = Packages/TuskerPreferences; sourceTree = ""; }; D6CA8CD92962231F0050C433 /* ArrayUniqueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayUniqueTests.swift; sourceTree = ""; }; D6CA8CDD296387310050C433 /* SaveToPhotosActivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveToPhotosActivity.swift; sourceTree = ""; }; D6D12B2E2925D66500D528E1 /* TimelineGapCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineGapCollectionViewCell.swift; sourceTree = ""; }; @@ -687,8 +681,6 @@ 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 = ""; }; - D6DD353C22F28CD000A9563A /* ContentWarningCopyMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningCopyMode.swift; sourceTree = ""; }; - D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Preferences+Notification.swift"; sourceTree = ""; }; D6DD8FFC298495A8002AD3FD /* LogoutService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogoutService.swift; sourceTree = ""; }; D6DD8FFE2984D327002AD3FD /* BookmarksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksViewController.swift; sourceTree = ""; }; D6DD996A2998611A0015C962 /* SuggestedProfilesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedProfilesViewController.swift; sourceTree = ""; }; @@ -743,6 +735,7 @@ D6B0026E29B5248800C70BE2 /* UserAccounts in Frameworks */, D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */, D60088EF2980D8B5005B4D00 /* StoreKit.framework in Frameworks */, + D6CA6ED229EF6091003EC5DF /* TuskerPreferences in Frameworks */, D6552367289870790048A653 /* ScreenCorners in Frameworks */, D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */, D63CC702290EC0B8000E19DE /* Sentry in Frameworks */, @@ -1181,12 +1174,7 @@ D663626021360A9600C9CBA2 /* Preferences */ = { isa = PBXGroup; children = ( - D663626121360B1900C9CBA2 /* Preferences.swift */, - D663626321360D2300C9CBA2 /* AvatarStyle.swift */, - D6DD353C22F28CD000A9563A /* ContentWarningCopyMode.swift */, - D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */, - D6BC9DB4232D4CE3002CA326 /* NotificationsMode.swift */, - D61F75872932DB6000C0B37F /* StatusSwipeAction.swift */, + D61F75872932DB6000C0B37F /* StatusSwipeActions.swift */, D6D94954298963A900C59229 /* Colors.swift */, ); path = Preferences; @@ -1415,6 +1403,7 @@ D6FA94DF29B52891006AAC51 /* InstanceFeatures */, D6BD395C29B789D5005FFD2B /* TuskerComponents */, D6BD395729B6441F005FFD2B /* ComposeUI */, + D6CA6ED029EF6060003EC5DF /* TuskerPreferences */, D6D4DDCE212518A000E1C4BB /* Tusker */, D6D4DDE3212518A200E1C4BB /* TuskerTests */, D6D4DDEE212518A200E1C4BB /* TuskerUITests */, @@ -1619,6 +1608,7 @@ D6FA94E029B52898006AAC51 /* InstanceFeatures */, D635237029B78A7D009ED5E7 /* TuskerComponents */, D6BD395829B64426005FFD2B /* ComposeUI */, + D6CA6ED129EF6091003EC5DF /* TuskerPreferences */, ); productName = Tusker; productReference = D6D4DDCC212518A000E1C4BB /* Tusker.app */; @@ -1847,7 +1837,6 @@ buildActionMask = 2147483647; files = ( D6531DF0246B867E000F9538 /* GifvAttachmentViewController.swift in Sources */, - D6DD353D22F28CD000A9563A /* ContentWarningCopyMode.swift in Sources */, 0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */, D6C3F4F5298ED0890009FCFF /* LocalPredicateStatusesViewController.swift in Sources */, D662AEEF263A3B880082A153 /* PollFinishedTableViewCell.swift in Sources */, @@ -1961,11 +1950,9 @@ D65C6BF525478A9C00A6E89C /* BackgroundableViewController.swift in Sources */, D61DC84D28F500D200B82C6E /* ProfileViewController.swift in Sources */, D600891F29848DE2005B4D00 /* AddInstancePinnedTimelineView.swift in Sources */, - D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */, D693A72A25CF8C1E003A14E2 /* ProfileDirectoryViewController.swift in Sources */, D693A72F25CF91C6003A14E2 /* FeaturedProfileCollectionViewCell.swift in Sources */, D627943223A5466600D38C68 /* SelectableTableViewCell.swift in Sources */, - D6DD353F22F502EC00A9563A /* Preferences+Notification.swift in Sources */, D6EAE0DB2550CC8A002DB0AC /* FocusableTextField.swift in Sources */, D623A53D2635F5590095BD04 /* StatusPollView.swift in Sources */, D64AAE9726C88DC400FC57FB /* ToastConfiguration.swift in Sources */, @@ -2011,14 +1998,13 @@ D61ABEFE28F1C92600B29151 /* FavoriteService.swift in Sources */, D61F75AB293AF11400C0B37F /* FilterKeywordMO.swift in Sources */, D65B4B5A29720AB000DABDFB /* ReportStatusView.swift in Sources */, - D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, D6D9498F298EB79400C59229 /* CopyableLable.swift in Sources */, D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */, D6D706A029466649000827ED /* ScrollingSegmentedControl.swift in Sources */, D653F411267D1E32004E32B1 /* DiffableTimelineLikeTableViewController.swift in Sources */, D686BBE324FBF8110068E6AA /* WrappedProgressView.swift in Sources */, D620483423D3801D008A63EF /* LinkTextView.swift in Sources */, - D61F75882932DB6000C0B37F /* StatusSwipeAction.swift in Sources */, + D61F75882932DB6000C0B37F /* StatusSwipeActions.swift in Sources */, D68A76EA295285D0001DA1B3 /* AddHashtagPinnedTimelineView.swift in Sources */, D6D12B58292D5B2C00D528E1 /* StatusActionAccountListCollectionViewController.swift in Sources */, D6412B0D24B0D4CF00F5412E /* ProfileHeaderView.swift in Sources */, @@ -2086,7 +2072,6 @@ 04586B4122B2FFB10021BD04 /* PreferencesView.swift in Sources */, D6620ACE2511A0ED00312CA0 /* StatusStateResolver.swift in Sources */, D6B9366B281EE77E00237D0E /* PollVoteButton.swift in Sources */, - D6BC9DB5232D4CE3002CA326 /* NotificationsMode.swift in Sources */, D68A76DA29511CA6001DA1B3 /* AccountPreferences.swift in Sources */, D68015402401A6BA00D6103B /* ComposingPrefsView.swift in Sources */, D6895DC428D65342006341DA /* ConfirmReblogStatusPreviewView.swift in Sources */, @@ -2818,6 +2803,10 @@ isa = XCSwiftPackageProductDependency; productName = Duckable; }; + D6CA6ED129EF6091003EC5DF /* TuskerPreferences */ = { + isa = XCSwiftPackageProductDependency; + productName = TuskerPreferences; + }; D6FA94E029B52898006AAC51 /* InstanceFeatures */ = { isa = XCSwiftPackageProductDependency; productName = InstanceFeatures; diff --git a/Tusker/AppDelegate.swift b/Tusker/AppDelegate.swift index 1be6eff9..890ba40f 100644 --- a/Tusker/AppDelegate.swift +++ b/Tusker/AppDelegate.swift @@ -12,6 +12,9 @@ import OSLog import Sentry import UserAccounts import ComposeUI +import TuskerPreferences + +typealias Preferences = TuskerPreferences.Preferences let stateRestorationLogger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "StateRestoration") private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "AppDelegate") @@ -50,8 +53,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } + let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + let oldPreferencesFile = documentsDirectory.appendingPathComponent("preferences").appendingPathExtension("plist") + if FileManager.default.fileExists(atPath: oldPreferencesFile.path) { + if case .failure(let error) = Preferences.migrate(from: oldPreferencesFile) { + SentrySDK.capture(error: error) + } + } + DispatchQueue.global(qos: .userInitiated).async { - let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! let oldDraftsFile = documentsDirectory.appendingPathComponent("drafts").appendingPathExtension("plist") if FileManager.default.fileExists(atPath: oldDraftsFile.path) { if case .failure(let error) = DraftsManager.migrate(from: oldDraftsFile) { @@ -59,7 +69,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } } } - + return true } diff --git a/Tusker/Preferences/StatusSwipeAction.swift b/Tusker/Preferences/StatusSwipeActions.swift similarity index 85% rename from Tusker/Preferences/StatusSwipeAction.swift rename to Tusker/Preferences/StatusSwipeActions.swift index 8beba5fa..73655145 100644 --- a/Tusker/Preferences/StatusSwipeAction.swift +++ b/Tusker/Preferences/StatusSwipeActions.swift @@ -1,5 +1,5 @@ // -// StatusSwipeAction.swift +// StatusSwipeActions.swift // Tusker // // Created by Shadowfacts on 11/26/22. @@ -8,49 +8,9 @@ import UIKit import Pachyderm +import TuskerPreferences -enum StatusSwipeAction: String, Codable, Hashable, CaseIterable { - case reply - case favorite - case reblog - case share - case bookmark - case openInSafari - - var displayName: String { - switch self { - case .reply: - return "Reply" - case .favorite: - return "Favorite" - case .reblog: - return "Reblog" - case .share: - return "Share" - case .bookmark: - return "Bookmark" - case .openInSafari: - return "Open in Safari" - } - } - - var systemImageName: String { - switch self { - case .reply: - return "arrowshape.turn.up.left.fill" - case .favorite: - return "star.fill" - case .reblog: - return "repeat" - case .share: - return "square.and.arrow.up" - case .bookmark: - return "bookmark.fill" - case .openInSafari: - return "safari" - } - } - +extension StatusSwipeAction { func createAction(status: StatusMO, container: StatusSwipeActionContainer) -> UIContextualAction? { switch self { case .reply: diff --git a/Tusker/Screens/Notifications/NotificationsPageViewController.swift b/Tusker/Screens/Notifications/NotificationsPageViewController.swift index ac2aae5d..b263c4bd 100644 --- a/Tusker/Screens/Notifications/NotificationsPageViewController.swift +++ b/Tusker/Screens/Notifications/NotificationsPageViewController.swift @@ -8,6 +8,7 @@ import UIKit import Pachyderm +import TuskerPreferences class NotificationsPageViewController: SegmentedPageViewController { diff --git a/Tusker/Screens/Preferences/ComposingPrefsView.swift b/Tusker/Screens/Preferences/ComposingPrefsView.swift index 59635f5d..0728bce1 100644 --- a/Tusker/Screens/Preferences/ComposingPrefsView.swift +++ b/Tusker/Screens/Preferences/ComposingPrefsView.swift @@ -8,6 +8,7 @@ import SwiftUI import Pachyderm +import TuskerPreferences struct ComposingPrefsView: View { @ObservedObject var preferences = Preferences.shared diff --git a/Tusker/Screens/Preferences/SwipeActionsPrefsView.swift b/Tusker/Screens/Preferences/SwipeActionsPrefsView.swift index 4d133ebc..9761a594 100644 --- a/Tusker/Screens/Preferences/SwipeActionsPrefsView.swift +++ b/Tusker/Screens/Preferences/SwipeActionsPrefsView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import TuskerPreferences struct SwipeActionsPrefsView: UIViewControllerRepresentable { @Binding var selection: [StatusSwipeAction] diff --git a/Tusker/Screens/Preferences/WellnessPrefsView.swift b/Tusker/Screens/Preferences/WellnessPrefsView.swift index 97879a49..f5df1636 100644 --- a/Tusker/Screens/Preferences/WellnessPrefsView.swift +++ b/Tusker/Screens/Preferences/WellnessPrefsView.swift @@ -7,6 +7,7 @@ // import SwiftUI +import TuskerPreferences struct WellnessPrefsView: View { @ObservedObject private var preferences = Preferences.shared diff --git a/Tusker/Shortcuts/UserActivityManager.swift b/Tusker/Shortcuts/UserActivityManager.swift index d4c82ad5..b7d0e9b9 100644 --- a/Tusker/Shortcuts/UserActivityManager.swift +++ b/Tusker/Shortcuts/UserActivityManager.swift @@ -12,6 +12,7 @@ import Pachyderm import OSLog import UserAccounts import ComposeUI +import TuskerPreferences private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "UserActivityManager")