From 5076aec54e3834bd7b3746f057868e0e2bf48048 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 14 Nov 2019 19:53:00 -0500 Subject: [PATCH] Use ObservedObject for binding to prefs in SwiftUI instead of custom property wrappers --- Tusker.xcodeproj/project.pbxproj | 4 -- Tusker/Preferences/Preference.swift | 60 ------------------- Tusker/Preferences/Preferences.swift | 3 - .../Preferences/AdvancedPrefsView.swift | 6 +- .../Preferences/AppearancePrefsView.swift | 20 ++++--- .../Preferences/BehaviorPrefsView.swift | 17 +++--- .../Preferences/WellnessPrefsView.swift | 9 ++- 7 files changed, 25 insertions(+), 94 deletions(-) delete mode 100644 Tusker/Preferences/Preference.swift diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 7f6da374..399ecf4f 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -9,7 +9,6 @@ /* Begin PBXBuildFile section */ 0411610022B442870030A9B7 /* AttachmentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 041160FE22B442870030A9B7 /* AttachmentViewController.swift */; }; 0411610122B442870030A9B7 /* AttachmentViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 041160FF22B442870030A9B7 /* AttachmentViewController.xib */; }; - 0427033622B30B3D000D31B6 /* Preference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0427033522B30B3D000D31B6 /* Preference.swift */; }; 0427033822B30F5F000D31B6 /* BehaviorPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0427033722B30F5F000D31B6 /* BehaviorPrefsView.swift */; }; 0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0427033922B31269000D31B6 /* AdvancedPrefsView.swift */; }; 0427037C22B316B9000D31B6 /* SilentActionPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0427037B22B316B9000D31B6 /* SilentActionPrefs.swift */; }; @@ -269,7 +268,6 @@ /* Begin PBXFileReference section */ 041160FE22B442870030A9B7 /* AttachmentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentViewController.swift; sourceTree = ""; }; 041160FF22B442870030A9B7 /* AttachmentViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AttachmentViewController.xib; sourceTree = ""; }; - 0427033522B30B3D000D31B6 /* Preference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preference.swift; sourceTree = ""; }; 0427033722B30F5F000D31B6 /* BehaviorPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BehaviorPrefsView.swift; sourceTree = ""; }; 0427033922B31269000D31B6 /* AdvancedPrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedPrefsView.swift; sourceTree = ""; }; 0427037B22B316B9000D31B6 /* SilentActionPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPrefs.swift; sourceTree = ""; }; @@ -876,7 +874,6 @@ children = ( D663626121360B1900C9CBA2 /* Preferences.swift */, D663626321360D2300C9CBA2 /* AvatarStyle.swift */, - 0427033522B30B3D000D31B6 /* Preference.swift */, D6DD353C22F28CD000A9563A /* ContentWarningCopyMode.swift */, D6DD353E22F502EC00A9563A /* Preferences+Notification.swift */, D6BC9DB4232D4CE3002CA326 /* NotificationsMode.swift */, @@ -1606,7 +1603,6 @@ D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */, D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */, D6434EB3215B1856001A919A /* XCBRequest.swift in Sources */, - 0427033622B30B3D000D31B6 /* Preference.swift in Sources */, D663626221360B1900C9CBA2 /* Preferences.swift in Sources */, D6333B792139AEFD00CE884A /* Date+TimeAgo.swift in Sources */, D641C77F213DC78A004B4513 /* InlineTextAttachment.swift in Sources */, diff --git a/Tusker/Preferences/Preference.swift b/Tusker/Preferences/Preference.swift deleted file mode 100644 index 5b05da76..00000000 --- a/Tusker/Preferences/Preference.swift +++ /dev/null @@ -1,60 +0,0 @@ -// Preference.swift -// Tusker -// -// Created by Shadowfacts on 6/13/19. -// Copyright © 2019 Shadowfacts. All rights reserved. -// - -import SwiftUI - -@propertyWrapper -struct Preference { - let path: WritableKeyPath - let binding: Binding - - init(_ path: WritableKeyPath) { - self.path = path - self.binding = Binding(get: { - return Preferences.shared[keyPath: path] - }, set: { (newValue) in - Preferences.shared[keyPath: path] = newValue - }) - } - - var wrappedValue: Value { - get { - return Preferences.shared[keyPath: path] - } - set { - Preferences.shared[keyPath: path] = newValue - } - } -} - -@propertyWrapper -struct MappedPreference { - let path: WritableKeyPath - let fromPref: (PrefValue) -> Value - let toPref: (Value) -> PrefValue - let binding: Binding - - init(_ path: WritableKeyPath, fromPref: @escaping (PrefValue) -> Value, toPref: @escaping (Value) -> PrefValue) { - self.path = path - self.fromPref = fromPref - self.toPref = toPref - self.binding = Binding(get: { - return fromPref(Preferences.shared[keyPath: path]) - }, set: { (newValue) in - Preferences.shared[keyPath: path] = toPref(newValue) - }) - } - - var wrappedValue: Value { - get { - return fromPref(Preferences.shared[keyPath: path]) - } - set { - Preferences.shared[keyPath: path] = toPref(newValue) - } - } -} diff --git a/Tusker/Preferences/Preferences.swift b/Tusker/Preferences/Preferences.swift index 86dfd0ea..e3673cfc 100644 --- a/Tusker/Preferences/Preferences.swift +++ b/Tusker/Preferences/Preferences.swift @@ -73,9 +73,6 @@ class Preferences: Codable, ObservableObject { try container.encode(statusContentType, forKey: .statusContentType) } - typealias ObjectWillChangePublisher = PassthroughSubject - let objectWillChange = PassthroughSubject() - // MARK: - Appearance @Published var showRepliesInProfiles = false @Published var avatarStyle = AvatarStyle.roundRect diff --git a/Tusker/Screens/Preferences/AdvancedPrefsView.swift b/Tusker/Screens/Preferences/AdvancedPrefsView.swift index 9c30fe04..fc82c27b 100644 --- a/Tusker/Screens/Preferences/AdvancedPrefsView.swift +++ b/Tusker/Screens/Preferences/AdvancedPrefsView.swift @@ -9,8 +9,8 @@ import SwiftUI import Pachyderm struct AdvancedPrefsView : View { - @Preference(\.statusContentType) var statusContentType: StatusContentType - + @ObservedObject var preferences = Preferences.shared + var body: some View { List { formattingSection @@ -25,7 +25,7 @@ struct AdvancedPrefsView : View { var formattingSection: some View { Section(footer: formattingFooter) { - Picker(selection: _statusContentType.binding, label: Text("Post Content Type")) { + Picker(selection: $preferences.statusContentType, label: Text("Post Content Type")) { ForEach(StatusContentType.allCases, id: \.self) { type in Text(type.displayName).tag(type) }//.navigationBarTitle("Post Content Type") diff --git a/Tusker/Screens/Preferences/AppearancePrefsView.swift b/Tusker/Screens/Preferences/AppearancePrefsView.swift index ffc57462..e05afe3c 100644 --- a/Tusker/Screens/Preferences/AppearancePrefsView.swift +++ b/Tusker/Screens/Preferences/AppearancePrefsView.swift @@ -8,21 +8,23 @@ import SwiftUI struct AppearancePrefsView : View { - @Preference(\.showRepliesInProfiles) var showRepliesInProfiles: Bool - @Preference(\.hideCustomEmojiInUsernames) var hideCustomEmojiInUsernames: Bool - - @MappedPreference(\.avatarStyle, fromPref: { $0 == .circle }, toPref: { $0 ? .circle : .roundRect }) - var useCircularAvatars: Bool - + @ObservedObject var preferences = Preferences.shared + + var useCircularAvatars: Binding = Binding(get: { + Preferences.shared.avatarStyle == .circle + }) { + Preferences.shared.avatarStyle = $0 ? .circle : .roundRect + } + var body: some View { List { - Toggle(isOn: _showRepliesInProfiles.binding) { + Toggle(isOn: $preferences.showRepliesInProfiles) { Text("Show Replies in Profiles") } - Toggle(isOn: _useCircularAvatars.binding) { + Toggle(isOn: useCircularAvatars) { Text("Use Circular Avatars") } - Toggle(isOn: _hideCustomEmojiInUsernames.binding) { + Toggle(isOn: $preferences.hideCustomEmojiInUsernames) { Text("Hide Custom Emoji in Usernames") } } diff --git a/Tusker/Screens/Preferences/BehaviorPrefsView.swift b/Tusker/Screens/Preferences/BehaviorPrefsView.swift index e34765c8..486377ce 100644 --- a/Tusker/Screens/Preferences/BehaviorPrefsView.swift +++ b/Tusker/Screens/Preferences/BehaviorPrefsView.swift @@ -8,12 +8,9 @@ import SwiftUI import Pachyderm -struct BehaviorPrefsView : View { - @Preference(\.defaultPostVisibility) var defaultPostVisibility: Status.Visibility - @Preference(\.automaticallySaveDrafts) var automaticallySaveDrafts: Bool - @Preference(\.contentWarningCopyMode) var contentWarningCopyMode: ContentWarningCopyMode - @Preference(\.openLinksInApps) var openLinksInApps: Bool - +struct BehaviorPrefsView: View { + @ObservedObject var preferences = Preferences.shared + var body: some View { List { section1 @@ -24,7 +21,7 @@ struct BehaviorPrefsView : View { var section1: some View { Section(header: Text("COMPOSING")) { - Picker(selection: _defaultPostVisibility.binding, label: Text("Default Post Visibility")) { + Picker(selection: $preferences.defaultPostVisibility, label: Text("Default Post Visibility")) { ForEach(Status.Visibility.allCases, id: \.self) { visibility in HStack { Image(systemName: visibility.imageName) @@ -34,10 +31,10 @@ struct BehaviorPrefsView : View { }//.navigationBarTitle("Default Post Visibility") // navbar title on the ForEach is currently incorrectly applied when the picker is not expanded, see FB6838291 } - Toggle(isOn: _automaticallySaveDrafts.binding) { + Toggle(isOn: $preferences.automaticallySaveDrafts) { Text("Automatically Save Drafts") } - Picker(selection: _contentWarningCopyMode.binding, label: Text("Content Warning Copy Style")) { + Picker(selection: $preferences.contentWarningCopyMode, label: Text("Content Warning Copy Style")) { Text("As-is").tag(ContentWarningCopyMode.asIs) Text("Prepend 're: '").tag(ContentWarningCopyMode.prependRe) Text("Don't copy").tag(ContentWarningCopyMode.doNotCopy) @@ -47,7 +44,7 @@ struct BehaviorPrefsView : View { var section2: some View { Section(header: Text("READING")) { - Toggle(isOn: _openLinksInApps.binding) { + Toggle(isOn: $preferences.openLinksInApps) { Text("Open Links in Apps") } } diff --git a/Tusker/Screens/Preferences/WellnessPrefsView.swift b/Tusker/Screens/Preferences/WellnessPrefsView.swift index b127a488..72eca695 100644 --- a/Tusker/Screens/Preferences/WellnessPrefsView.swift +++ b/Tusker/Screens/Preferences/WellnessPrefsView.swift @@ -9,9 +9,8 @@ import SwiftUI struct WellnessPrefsView: View { - @Preference(\.showFavoriteAndReblogCounts) var showFavoriteAndReblogCounts: Bool - @Preference(\.defaultNotificationsMode) var defaultNotificationsMode: NotificationsMode - + @ObservedObject var preferences = Preferences.shared + var body: some View { List { showFavAndReblogCountSection @@ -22,7 +21,7 @@ struct WellnessPrefsView: View { var showFavAndReblogCountSection: some View { Section(footer: showFavAndReblogCountFooter) { - Toggle(isOn: _showFavoriteAndReblogCounts.binding) { + Toggle(isOn: $preferences.showFavoriteAndReblogCounts) { Text("Show Favorite and Reblog Counts") } } @@ -34,7 +33,7 @@ struct WellnessPrefsView: View { var notificationsModeSection: some View { Section(footer: notificationsModeFooter) { - Picker(selection: _defaultNotificationsMode.binding, label: Text("Default Notifications Mode")) { + Picker(selection: $preferences.defaultNotificationsMode, label: Text("Default Notifications Mode")) { ForEach(NotificationsMode.allCases, id: \.self) { type in Text(type.displayName).tag(type) }