diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index b08660ef..7ef5203b 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -9,10 +9,16 @@ /* 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 */; }; 04496BD721625361001F1B23 /* ContentLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04496BD621625361001F1B23 /* ContentLabel.swift */; }; 0450531F22B0097E00100BA2 /* Timline+UI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0450531E22B0097E00100BA2 /* Timline+UI.swift */; }; 0454DDAF22B462EF00B8BB8E /* GalleryExpandAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0454DDAE22B462EF00B8BB8E /* GalleryExpandAnimationController.swift */; }; 0454DDB122B467AA00B8BB8E /* GalleryShrinkAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0454DDB022B467AA00B8BB8E /* GalleryShrinkAnimationController.swift */; }; + 04586B4122B2FFB10021BD04 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04586B4022B2FFB10021BD04 /* PreferencesView.swift */; }; + 04586B4322B301470021BD04 /* AppearancePrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04586B4222B301470021BD04 /* AppearancePrefsView.swift */; }; 0461A3902163CBAE00C0A807 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0461A38F2163CBAE00C0A807 /* Cache.framework */; }; 0461A3912163CBAE00C0A807 /* Cache.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0461A38F2163CBAE00C0A807 /* Cache.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 04D14BB022B34A2800642648 /* GalleryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D14BAE22B34A2800642648 /* GalleryViewController.swift */; }; @@ -69,9 +75,7 @@ D627FF7B217E951500CC0648 /* DraftsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */; }; D627FF7D217E958900CC0648 /* DraftTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D627FF7C217E958900CC0648 /* DraftTableViewCell.xib */; }; D627FF7F217E95E000CC0648 /* DraftTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF7E217E95E000CC0648 /* DraftTableViewCell.swift */; }; - D627FF81217FE8F400CC0648 /* BehaviorTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */; }; D6285B4F21EA695800FE4B39 /* StatusContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6285B4E21EA695800FE4B39 /* StatusContentType.swift */; }; - D6285B5121EA6E6E00FE4B39 /* AdvancedTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6285B5021EA6E6E00FE4B39 /* AdvancedTableViewController.swift */; }; D6285B5321EA708700FE4B39 /* StatusFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6285B5221EA708700FE4B39 /* StatusFormat.swift */; }; D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6289E83217B795D0003D1D7 /* LargeImageViewController.xib */; }; D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62D2421217AA7E1005076CC /* UserActivityManager.swift */; }; @@ -100,8 +104,6 @@ D663625F2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */; }; D663626221360B1900C9CBA2 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626121360B1900C9CBA2 /* Preferences.swift */; }; D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626321360D2300C9CBA2 /* AvatarStyle.swift */; }; - D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626521360DD700C9CBA2 /* Preferences.storyboard */; }; - D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */; }; D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */; }; D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; }; D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; }; @@ -121,7 +123,6 @@ D67C57AF21E28EAD00C3118B /* Array+Uniques.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67C57AE21E28EAD00C3118B /* Array+Uniques.swift */; }; D67C57B221E28FAD00C3118B /* ComposeStatusReplyView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D67C57B121E28FAD00C3118B /* ComposeStatusReplyView.xib */; }; D67C57B421E2910700C3118B /* ComposeStatusReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67C57B321E2910700C3118B /* ComposeStatusReplyView.swift */; }; - D67E0513216438A7000E0927 /* AppearanceTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */; }; D686329521ED8319008C716E /* GMImagePicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = D686326E21ED8312008C716E /* GMImagePicker.strings */; }; D686329621ED8319008C716E /* GMImagePicker.strings in Resources */ = {isa = PBXBuildFile; fileRef = D686327121ED8312008C716E /* GMImagePicker.strings */; }; D686329721ED8319008C716E /* GMGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = D686327321ED8312008C716E /* GMGridViewCell.m */; }; @@ -154,9 +155,6 @@ D6BC8748219738E1006163F1 /* EnhancedTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */; }; D6BED170212663DA00F02DA0 /* SwiftSoup.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */; }; - D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */; }; - D6C693CD2161257B007D6A6D /* SilentActionPermissionCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6C693CC2161257B007D6A6D /* SilentActionPermissionCell.xib */; }; - D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */; }; D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; }; D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */; }; D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; }; @@ -244,10 +242,16 @@ /* 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 = ""; }; 04496BD621625361001F1B23 /* ContentLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentLabel.swift; sourceTree = ""; }; 0450531E22B0097E00100BA2 /* Timline+UI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Timline+UI.swift"; sourceTree = ""; }; 0454DDAE22B462EF00B8BB8E /* GalleryExpandAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryExpandAnimationController.swift; sourceTree = ""; }; 0454DDB022B467AA00B8BB8E /* GalleryShrinkAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryShrinkAnimationController.swift; sourceTree = ""; }; + 04586B4022B2FFB10021BD04 /* PreferencesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; + 04586B4222B301470021BD04 /* AppearancePrefsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearancePrefsView.swift; sourceTree = ""; }; 0461A38F2163CBAE00C0A807 /* Cache.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Cache.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 04D14BAE22B34A2800642648 /* GalleryViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryViewController.swift; sourceTree = ""; }; 04DACE8B212CB14B009840C4 /* MainTabBarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainTabBarViewController.swift; sourceTree = ""; }; @@ -304,9 +308,7 @@ D627FF7A217E951500CC0648 /* DraftsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftsTableViewController.swift; sourceTree = ""; }; D627FF7C217E958900CC0648 /* DraftTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraftTableViewCell.xib; sourceTree = ""; }; D627FF7E217E95E000CC0648 /* DraftTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraftTableViewCell.swift; sourceTree = ""; }; - D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BehaviorTableViewController.swift; sourceTree = ""; }; D6285B4E21EA695800FE4B39 /* StatusContentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentType.swift; sourceTree = ""; }; - D6285B5021EA6E6E00FE4B39 /* AdvancedTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedTableViewController.swift; sourceTree = ""; }; D6285B5221EA708700FE4B39 /* StatusFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusFormat.swift; sourceTree = ""; }; D6289E83217B795D0003D1D7 /* LargeImageViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LargeImageViewController.xib; sourceTree = ""; }; D62D2421217AA7E1005076CC /* UserActivityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserActivityManager.swift; sourceTree = ""; }; @@ -334,8 +336,6 @@ D663625E2135C75500C9CBA2 /* ConversationMainStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationMainStatusTableViewCell.swift; 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 = ""; }; - D663626521360DD700C9CBA2 /* Preferences.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Preferences.storyboard; sourceTree = ""; }; - D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesTableViewController.swift; sourceTree = ""; }; D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesAdaptive.swift; sourceTree = ""; }; D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = ""; }; D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = ""; }; @@ -355,7 +355,6 @@ D67C57AE21E28EAD00C3118B /* Array+Uniques.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+Uniques.swift"; sourceTree = ""; }; D67C57B121E28FAD00C3118B /* ComposeStatusReplyView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ComposeStatusReplyView.xib; sourceTree = ""; }; D67C57B321E2910700C3118B /* ComposeStatusReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusReplyView.swift; sourceTree = ""; }; - D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceTableViewController.swift; sourceTree = ""; }; D686326F21ED8312008C716E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = GMImagePicker.strings; sourceTree = ""; }; D686327221ED8312008C716E /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = GMImagePicker.strings; sourceTree = ""; }; D686327321ED8312008C716E /* GMGridViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GMGridViewCell.m; sourceTree = ""; }; @@ -387,9 +386,6 @@ D6BC8747219738E1006163F1 /* EnhancedTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnhancedTableViewController.swift; sourceTree = ""; }; D6BED16E212663DA00F02DA0 /* SwiftSoup.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftSoup.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D6BED173212667E900F02DA0 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = ""; }; - D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionsTableViewController.swift; sourceTree = ""; }; - D6C693CC2161257B007D6A6D /* SilentActionPermissionCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SilentActionPermissionCell.xib; sourceTree = ""; }; - D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SilentActionPermissionTableViewCell.swift; sourceTree = ""; }; D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerNavigationDelegate.swift; sourceTree = ""; }; D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentLabel.swift; sourceTree = ""; }; D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingViewController.swift; sourceTree = ""; }; @@ -739,12 +735,11 @@ D641C789213DD87E004B4513 /* Preferences */ = { isa = PBXGroup; children = ( - D663626521360DD700C9CBA2 /* Preferences.storyboard */, - D663626721360E2C00C9CBA2 /* PreferencesTableViewController.swift */, - D6285B5021EA6E6E00FE4B39 /* AdvancedTableViewController.swift */, - D67E0512216438A7000E0927 /* AppearanceTableViewController.swift */, - D627FF80217FE8F400CC0648 /* BehaviorTableViewController.swift */, - D6C693C92161253F007D6A6D /* SilentActionPermissionsTableViewController.swift */, + 04586B4022B2FFB10021BD04 /* PreferencesView.swift */, + 04586B4222B301470021BD04 /* AppearancePrefsView.swift */, + 0427033722B30F5F000D31B6 /* BehaviorPrefsView.swift */, + 0427033922B31269000D31B6 /* AdvancedPrefsView.swift */, + 0427037B22B316B9000D31B6 /* SilentActionPrefs.swift */, ); path = Preferences; sourceTree = ""; @@ -803,6 +798,7 @@ D663626121360B1900C9CBA2 /* Preferences.swift */, D663626321360D2300C9CBA2 /* AvatarStyle.swift */, D66362692136163000C9CBA2 /* PreferencesAdaptive.swift */, + 0427033522B30B3D000D31B6 /* Preference.swift */, ); path = Preferences; sourceTree = ""; @@ -936,15 +932,6 @@ path = Views; sourceTree = ""; }; - D6C693CB2161256B007D6A6D /* Silent Action Permissions */ = { - isa = PBXGroup; - children = ( - D6C693CC2161257B007D6A6D /* SilentActionPermissionCell.xib */, - D6C693CE216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift */, - ); - path = "Silent Action Permissions"; - sourceTree = ""; - }; D6C693FA2162FE5D007D6A6D /* Utilities */ = { isa = PBXGroup; children = ( @@ -1304,7 +1291,6 @@ D641C779213CAC56004B4513 /* ActionNotificationTableViewCell.xib in Resources */, D627FF7D217E958900CC0648 /* DraftTableViewCell.xib in Resources */, D667E5E921349EE50057A976 /* ProfileHeaderTableViewCell.xib in Resources */, - D6C693CD2161257B007D6A6D /* SilentActionPermissionCell.xib in Resources */, D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */, D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */, D663625D2135C74800C9CBA2 /* ConversationMainStatusTableViewCell.xib in Resources */, @@ -1312,7 +1298,6 @@ D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */, D641C77B213CB017004B4513 /* FollowNotificationTableViewCell.xib in Resources */, D6289E84217B795D0003D1D7 /* LargeImageViewController.xib in Resources */, - D663626621360DD700C9CBA2 /* Preferences.storyboard in Resources */, D627FF79217E950100CC0648 /* DraftsTableViewController.xib in Resources */, D67C57B221E28FAD00C3118B /* ComposeStatusReplyView.xib in Resources */, 0411610122B442870030A9B7 /* AttachmentViewController.xib in Resources */, @@ -1408,12 +1393,12 @@ buildActionMask = 2147483647; files = ( D6285B5321EA708700FE4B39 /* StatusFormat.swift in Sources */, + 0427033A22B31269000D31B6 /* AdvancedPrefsView.swift in Sources */, D6757A822157E8FA00721E32 /* XCBSession.swift in Sources */, 04DACE8C212CB14B009840C4 /* MainTabBarViewController.swift in Sources */, D6C693F92162E4DB007D6A6D /* StatusContentLabel.swift in Sources */, D6D58DF922074B74009C8DD9 /* LinkLabel.swift in Sources */, 0454DDAF22B462EF00B8BB8E /* GalleryExpandAnimationController.swift in Sources */, - D6285B5121EA6E6E00FE4B39 /* AdvancedTableViewController.swift in Sources */, 0450531F22B0097E00100BA2 /* Timline+UI.swift in Sources */, D667E5F52135BCD50057A976 /* ConversationTableViewController.swift in Sources */, D6C7D27D22B6EBF800071952 /* AttachmentsContainerView.swift in Sources */, @@ -1421,7 +1406,6 @@ 0411610022B442870030A9B7 /* AttachmentViewController.swift in Sources */, D62D2426217ABF63005076CC /* UserActivityType.swift in Sources */, D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */, - D627FF81217FE8F400CC0648 /* BehaviorTableViewController.swift in Sources */, D6028B9B2150811100F223B9 /* MastodonCache.swift in Sources */, D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */, D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */, @@ -1440,17 +1424,18 @@ D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */, D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */, D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */, + 0427033822B30F5F000D31B6 /* BehaviorPrefsView.swift in Sources */, D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */, 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 */, 04496BD721625361001F1B23 /* ContentLabel.swift in Sources */, D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */, - D6C693CA2161253F007D6A6D /* SilentActionPermissionsTableViewController.swift in Sources */, D6333B372137838300CE884A /* AttributedString+Helpers.swift in Sources */, D6B8DB342182A59300424AF7 /* UIAlertController+Visibility.swift in Sources */, D67C57AD21E265FC00C3118B /* LargeAccountDetailView.swift in Sources */, @@ -1458,22 +1443,22 @@ D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, D627FF76217E923E00CC0648 /* DraftsManager.swift in Sources */, - D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */, D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */, + 04586B4322B301470021BD04 /* AppearancePrefsView.swift in Sources */, D67C57AF21E28EAD00C3118B /* Array+Uniques.swift in Sources */, D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */, - D67E0513216438A7000E0927 /* AppearanceTableViewController.swift in Sources */, D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */, D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */, D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */, + 04586B4122B2FFB10021BD04 /* PreferencesView.swift in Sources */, D663626A2136163000C9CBA2 /* PreferencesAdaptive.swift in Sources */, D667E5EB21349EF80057A976 /* ProfileHeaderTableViewCell.swift in Sources */, 04D14BB022B34A2800642648 /* GalleryViewController.swift in Sources */, D641C77D213CB024004B4513 /* FollowNotificationTableViewCell.swift in Sources */, D641C773213CAA25004B4513 /* NotificationsTableViewController.swift in Sources */, D6757A7C2157E01900721E32 /* XCBManager.swift in Sources */, - D6C693CF216125FC007D6A6D /* SilentActionPermissionTableViewCell.swift in Sources */, D6F1F84D2193B56E00F5FE67 /* Cache.swift in Sources */, + 0427037C22B316B9000D31B6 /* SilentActionPrefs.swift in Sources */, D6757A7E2157E02600721E32 /* XCBRequestSpec.swift in Sources */, D667E5F12134D5050057A976 /* UIViewController+Delegates.swift in Sources */, D6BC8748219738E1006163F1 /* EnhancedTableViewController.swift in Sources */, @@ -1891,7 +1876,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = D9LRWNKC29; + DEVELOPMENT_TEAM = HGYVAQA9FW; INFOPLIST_FILE = Tusker/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( @@ -1913,7 +1898,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = D9LRWNKC29; + DEVELOPMENT_TEAM = HGYVAQA9FW; INFOPLIST_FILE = Tusker/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( diff --git a/Tusker/Extensions/Visibility+Helpers.swift b/Tusker/Extensions/Visibility+Helpers.swift index b69dbad3..2d2f2495 100644 --- a/Tusker/Extensions/Visibility+Helpers.swift +++ b/Tusker/Extensions/Visibility+Helpers.swift @@ -24,19 +24,17 @@ extension Status.Visibility { } } - var image: UIImage { - let name: String + var imageName: String { switch self { case .public: - name = "globe" + return "globe" case .unlisted: - name = "lock.open.fill" + return "lock.open.fill" case .private: - name = "lock.fill" + return "lock.fill" case .direct: - name = "envelope.fill" + return "envelope.fill" } - return UIImage(systemName: name)! } } diff --git a/Tusker/Preferences/Preference.swift b/Tusker/Preferences/Preference.swift new file mode 100644 index 00000000..b08fe5d5 --- /dev/null +++ b/Tusker/Preferences/Preference.swift @@ -0,0 +1,60 @@ +// Preference.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import SwiftUI + +@propertyWrapper +struct Preference: BindingConvertible { + let path: WritableKeyPath + let binding: Binding + + init(_ path: WritableKeyPath) { + self.path = path + self.binding = Binding(getValue: { + return Preferences.shared[keyPath: path] + }, setValue: { (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: BindingConvertible { + 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(getValue: { + return fromPref(Preferences.shared[keyPath: path]) + }, setValue: { (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 f29bcc91..877a5c96 100644 --- a/Tusker/Preferences/Preferences.swift +++ b/Tusker/Preferences/Preferences.swift @@ -8,10 +8,12 @@ import Foundation import Pachyderm +import SwiftUI +import Combine -class Preferences: Codable { - - private(set) static var shared: Preferences = load() +class Preferences: Codable, BindableObject { + + 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") @@ -33,22 +35,35 @@ class Preferences: Codable { private init() {} + typealias PublisherType = PassthroughSubject + let willChange = PassthroughSubject() + // MARK: - Appearance - var showRepliesInProfiles = false - var avatarStyle = AvatarStyle.roundRect - var hideCustomEmojiInUsernames = false + var showRepliesInProfiles = false { willSet { willChange.send(self) } } + var avatarStyle = AvatarStyle.roundRect { willSet { willChange.send(self) } } + var hideCustomEmojiInUsernames = false { willSet { willChange.send(self) } } // MARK: - Behavior - var defaultPostVisibility = Status.Visibility.public - var automaticallySaveDrafts = true - var openLinksInApps = true + var defaultPostVisibility = Status.Visibility.public { willSet { willChange.send(self) } } + var automaticallySaveDrafts = true { willSet { willChange.send(self) } } + var openLinksInApps = true { willSet { willChange.send(self) } } // MARK: - Advanced - var silentActions: [String: Permission] = [:] - var statusContentType: StatusContentType = .plain + var silentActions: [String: Permission] = [:] { willSet { willChange.send(self) } } + var statusContentType: StatusContentType = .plain { willSet { willChange.send(self) } } } +extension PassthroughSubject: Codable { + public convenience init(from decoder: Decoder) throws { + self.init() + } + + public func encode(to encoder: Encoder) throws { + + } +} + extension Preferences { enum Permission: String, Codable { case undecided, accepted, rejected diff --git a/Tusker/Screens/Compose/ComposeViewController.swift b/Tusker/Screens/Compose/ComposeViewController.swift index df9d6038..980b4c3a 100644 --- a/Tusker/Screens/Compose/ComposeViewController.swift +++ b/Tusker/Screens/Compose/ComposeViewController.swift @@ -103,7 +103,7 @@ class ComposeViewController: UIViewController { let toolbar = UIToolbar() contentWarningBarButtonItem = UIBarButtonItem(title: "CW", style: .plain, target: self, action: #selector(contentWarningButtonPressed)) - visibilityBarButtonItem = UIBarButtonItem(image: nil, style: .plain, target: self, action: #selector(visibilityButtonPressed)) + visibilityBarButtonItem = UIBarButtonItem(image: UIImage(systemName: Preferences.shared.defaultPostVisibility.imageName), style: .plain, target: self, action: #selector(visibilityButtonPressed)) toolbar.items = [ contentWarningBarButtonItem, visibilityBarButtonItem, @@ -159,6 +159,8 @@ class ComposeViewController: UIViewController { stackView.insertArrangedSubview(replyLabelContainer, at: 1) } + // we have to set the font here, because the monospaced digit font is not available in IB + charactersRemainingLabel.font = .monospacedDigitSystemFont(ofSize: 17, weight: .regular) updateCharactersRemaining() updatePlaceholder() @@ -294,7 +296,7 @@ class ComposeViewController: UIViewController { } func visibilityChanged() { - visibilityBarButtonItem.image = visibility.image + visibilityBarButtonItem.image = UIImage(systemName: visibility.imageName) } func saveDraft() { diff --git a/Tusker/Screens/Onboarding/OnboardingViewController.swift b/Tusker/Screens/Onboarding/OnboardingViewController.swift index 1b51f1f8..b2c7762c 100644 --- a/Tusker/Screens/Onboarding/OnboardingViewController.swift +++ b/Tusker/Screens/Onboarding/OnboardingViewController.swift @@ -83,8 +83,10 @@ class OnboardingViewController: UIViewController { } } } - self.authenticationSession!.presentationContextProvider = self - self.authenticationSession!.start() + DispatchQueue.main.async { + self.authenticationSession!.presentationContextProvider = self + self.authenticationSession!.start() + } } } diff --git a/Tusker/Screens/Preferences/AdvancedPrefsView.swift b/Tusker/Screens/Preferences/AdvancedPrefsView.swift new file mode 100644 index 00000000..cfff61c2 --- /dev/null +++ b/Tusker/Screens/Preferences/AdvancedPrefsView.swift @@ -0,0 +1,65 @@ +// AdvancedPrefsView.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import SwiftUI +import Pachyderm + +struct AdvancedPrefsView : View { + @Preference(\.statusContentType) var statusContentType: StatusContentType + + var body: some View { + List { + formattingSection + automationSection + }.listStyle(.grouped) + .navigationBarTitle(Text("Advanced")) + } + + var formattingFooter: some View { + Text("This option is only supported for Pleroma and Mastodon instances with formatting enabled. On all other instances, formatting symbols will remain in the unformatted plain text.").lineLimit(nil) + } + + var formattingSection: some View { + Section(footer: formattingFooter) { + Picker(selection: _statusContentType.binding, label: Text("Post Content Type")) { + ForEach(StatusContentType.allCases, id: \.self) { type in + Text(type.displayName).tag(type) + }//.navigationBarTitle("Post Content Type") + // see FB6838291 + } + } + } + + var automationSection: some View { + Section(header: Text("AUTOMATION")) { + NavigationLink(destination: SilentActionPrefs()) { + Text("Silent Action Permissions") + } + } + } +} + +extension StatusContentType { + var displayName: String { + switch self { + case .plain: + return "Plain" + case .markdown: + return "Markdown" + case .html: + return "HTML" + } + } +} + +#if DEBUG +struct AdvancedPrefsView_Previews : PreviewProvider { + static var previews: some View { + AdvancedPrefsView() + } +} +#endif diff --git a/Tusker/Screens/Preferences/AdvancedTableViewController.swift b/Tusker/Screens/Preferences/AdvancedTableViewController.swift deleted file mode 100644 index a8ebdd94..00000000 --- a/Tusker/Screens/Preferences/AdvancedTableViewController.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// AdvancedTableViewController.swift -// Tusker -// -// Created by Shadowfacts on 1/12/19. -// Copyright © 2019 Shadowfacts. All rights reserved. -// - -import UIKit -import Pachyderm - -class AdvancedTableViewController: UITableViewController { - - @IBOutlet weak var postContentTypeLabel: UILabel! - - override func viewDidLoad() { - super.viewDidLoad() - - postContentTypeLabel.text = Preferences.shared.statusContentType.displayName - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - guard indexPath.section == 1 && indexPath.row == 0 else { - return - } - tableView.deselectRow(at: indexPath, animated: true) - - let alertController = UIAlertController(title: "Post Content Type", message: nil, preferredStyle: .actionSheet) - for contentType in StatusContentType.allCases { - let action = UIAlertAction(title: contentType.displayName, style: .default) { (_) in - Preferences.shared.statusContentType = contentType - self.postContentTypeLabel.text = contentType.displayName - } - if contentType == Preferences.shared.statusContentType { - action.setValue(true, forKey: "checked") - } - alertController.addAction(action) - } - alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) - present(alertController, animated: true) - } - -} - -extension StatusContentType { - var displayName: String { - switch self { - case .plain: - return "Plain" - case .markdown: - return "Markdown" - case .html: - return "HTML" - } - } -} diff --git a/Tusker/Screens/Preferences/AppearancePrefsView.swift b/Tusker/Screens/Preferences/AppearancePrefsView.swift new file mode 100644 index 00000000..48eb8060 --- /dev/null +++ b/Tusker/Screens/Preferences/AppearancePrefsView.swift @@ -0,0 +1,40 @@ +// AppearancePrefsView.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +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 + + var body: some View { + List { + Toggle(isOn: _showRepliesInProfiles.binding) { + Text("Show Replies in Profiles") + } + Toggle(isOn: _useCircularAvatars.binding) { + Text("Use Circular Avatars") + } + Toggle(isOn: _hideCustomEmojiInUsernames.binding) { + Text("Hide Custom Emoji in Usernames") + } + } + .listStyle(.grouped) + .navigationBarTitle(Text("Appearance")) + } +} + +#if DEBUG +struct AppearancePrefsView_Previews : PreviewProvider { + static var previews: some View { + AppearancePrefsView() + } +} +#endif diff --git a/Tusker/Screens/Preferences/AppearanceTableViewController.swift b/Tusker/Screens/Preferences/AppearanceTableViewController.swift deleted file mode 100644 index 1e9d8ce0..00000000 --- a/Tusker/Screens/Preferences/AppearanceTableViewController.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// AppearanceTableViewController.swift -// Tusker -// -// Created by Shadowfacts on 10/2/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit - -class AppearanceTableViewController: UITableViewController { - - @IBOutlet weak var showRepliesInProfilesSwitch: UISwitch! - @IBOutlet weak var circularAvatarsSwitch: UISwitch! - @IBOutlet weak var hideCustomEmojiInUsernamesSwitch: UISwitch! - - override func viewDidLoad() { - super.viewDidLoad() - - showRepliesInProfilesSwitch.setOn(Preferences.shared.showRepliesInProfiles, animated: false) - circularAvatarsSwitch.setOn(Preferences.shared.avatarStyle == .circle, animated: false) - hideCustomEmojiInUsernamesSwitch.setOn(Preferences.shared.hideCustomEmojiInUsernames, animated: false) - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - - // MARK: - Interaction - - @IBAction func showRepliesInProfilesChanged(_ sender: Any) { - Preferences.shared.showRepliesInProfiles = showRepliesInProfilesSwitch.isOn - } - - @IBAction func circularAvatarsChanged(_ sender: Any) { - Preferences.shared.avatarStyle = circularAvatarsSwitch.isOn ? .circle : .roundRect - } - - @IBAction func hideCustomEmojiInUsernamesChanged(_ sender: Any) { - Preferences.shared.hideCustomEmojiInUsernames = hideCustomEmojiInUsernamesSwitch.isOn - } - -} diff --git a/Tusker/Screens/Preferences/BehaviorPrefsView.swift b/Tusker/Screens/Preferences/BehaviorPrefsView.swift new file mode 100644 index 00000000..a7b971d0 --- /dev/null +++ b/Tusker/Screens/Preferences/BehaviorPrefsView.swift @@ -0,0 +1,57 @@ +// BehaviorPrefsView.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import SwiftUI +import Pachyderm + +struct BehaviorPrefsView : View { + @Preference(\.defaultPostVisibility) var defaultPostVisibility: Status.Visibility + @Preference(\.automaticallySaveDrafts) var automaticallySaveDrafts: Bool + @Preference(\.openLinksInApps) var openLinksInApps: Bool + + var body: some View { + List { + section1 + section2 + }.listStyle(.grouped) + .navigationBarTitle(Text("Behavior")) + } + + var section1: some View { + Section { + Picker(selection: _defaultPostVisibility.binding, label: Text("Default Post Visibility")) { + ForEach(Status.Visibility.allCases, id: \.self) { visibility in + HStack { + Image(systemName: visibility.imageName) + Text(visibility.displayName) + } + .tag(visibility) + }//.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) { + Text("Automatically Save Drafts") + } + } + } + + var section2: some View { + Section { + Toggle(isOn: _openLinksInApps.binding) { + Text("Open Links in Apps") + } + } + } +} + +#if DEBUG +struct BehaviorPrefsView_Previews : PreviewProvider { + static var previews: some View { + BehaviorPrefsView() + } +} +#endif diff --git a/Tusker/Screens/Preferences/BehaviorTableViewController.swift b/Tusker/Screens/Preferences/BehaviorTableViewController.swift deleted file mode 100644 index c72ba06a..00000000 --- a/Tusker/Screens/Preferences/BehaviorTableViewController.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// BehaviorTableViewController.swift -// Tusker -// -// Created by Shadowfacts on 10/23/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit - -class BehaviorTableViewController: UITableViewController { - - @IBOutlet weak var defaultPostVisibilityLabel: UILabel! - @IBOutlet weak var automaticallySaveDraftsSwitch: UISwitch! - @IBOutlet weak var openLinksInAppsSwitch: UISwitch! - - override func viewDidLoad() { - super.viewDidLoad() - - defaultPostVisibilityLabel.text = Preferences.shared.defaultPostVisibility.displayName - automaticallySaveDraftsSwitch.setOn(Preferences.shared.automaticallySaveDrafts, animated: false) - openLinksInAppsSwitch.setOn(Preferences.shared.openLinksInApps, animated: false) - } - - override func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { - if indexPath.row == 0 { - return indexPath - } else { - return nil - } - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - tableView.deselectRow(at: indexPath, animated: true) - - let alertController = UIAlertController(currentVisibility: Preferences.shared.defaultPostVisibility) { (visibility) in - guard let visibility = visibility else { return } - Preferences.shared.defaultPostVisibility = visibility - self.defaultPostVisibilityLabel.text = visibility.displayName - } - present(alertController, animated: true) - } - - @IBAction func automaticallySaveDraftsChanged(_ sender: Any) { - Preferences.shared.automaticallySaveDrafts = automaticallySaveDraftsSwitch.isOn - } - - @IBAction func openLinksInAppsChanged(_ sender: Any) { - Preferences.shared.openLinksInApps = openLinksInAppsSwitch.isOn - } - - -} diff --git a/Tusker/Screens/Preferences/Preferences.storyboard b/Tusker/Screens/Preferences/Preferences.storyboard deleted file mode 100644 index ac24a88f..00000000 --- a/Tusker/Screens/Preferences/Preferences.storyboard +++ /dev/null @@ -1,464 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - This option is only supported for Pleroma instances with formatting enabled. On all other instances, formatting symbols will remain in the plain, unformatted text. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tusker/Screens/Preferences/PreferencesTableViewController.swift b/Tusker/Screens/Preferences/PreferencesTableViewController.swift deleted file mode 100644 index 26607b9e..00000000 --- a/Tusker/Screens/Preferences/PreferencesTableViewController.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// PreferencesTableViewController.swift -// Tusker -// -// Created by Shadowfacts on 8/28/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit - -class PreferencesTableViewController: UITableViewController { - - static func create() -> UINavigationController { - guard let navigationController = UIStoryboard(name: "Preferences", bundle: nil).instantiateInitialViewController() as? UINavigationController else { fatalError() } - return navigationController - } - - @IBAction func donePressed(_ sender: Any) { - dismiss(animated: true) - } - -} diff --git a/Tusker/Screens/Preferences/PreferencesView.swift b/Tusker/Screens/Preferences/PreferencesView.swift new file mode 100644 index 00000000..3b69e7ea --- /dev/null +++ b/Tusker/Screens/Preferences/PreferencesView.swift @@ -0,0 +1,37 @@ +// PreferencesView.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import SwiftUI + +struct PreferencesView : View { + var body: some View { + // workaround: the navigation view is provided by MyProfileTableViewController so that it can inject the Done button +// NavigationView { + List { + NavigationLink(destination: AppearancePrefsView()) { + Text("Appearance") + } + NavigationLink(destination: BehaviorPrefsView()) { + Text("Behavior") + } + NavigationLink(destination: AdvancedPrefsView()) { + Text("Advanced") + } + } + .listStyle(.grouped) + .navigationBarTitle(Text("Preferences"), displayMode: .inline) +// } + } +} + +#if DEBUG +struct PreferencesView_Previews : PreviewProvider { + static var previews: some View { + PreferencesView() + } +} +#endif diff --git a/Tusker/Screens/Preferences/SilentActionPermissionsTableViewController.swift b/Tusker/Screens/Preferences/SilentActionPermissionsTableViewController.swift deleted file mode 100644 index 047bfcb5..00000000 --- a/Tusker/Screens/Preferences/SilentActionPermissionsTableViewController.swift +++ /dev/null @@ -1,49 +0,0 @@ -// -// SilentActionPermissionsTableViewController.swift -// Tusker -// -// Created by Shadowfacts on 9/30/18. -// Copyright © 2018 Shadowfacts. All rights reserved. -// - -import UIKit - -class SilentActionPermissionsTableViewController: UITableViewController { - - override func viewDidLoad() { - super.viewDidLoad() - - tableView.register(UINib(nibName: "SilentActionPermissionCell", bundle: nil), forCellReuseIdentifier: "permissionCell") - } - - // MARK: - Table view data source - - override func numberOfSections(in tableView: UITableView) -> Int { - return 1 - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return Preferences.shared.silentActions.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - guard let cell = tableView.dequeueReusableCell(withIdentifier: "permissionCell", for: indexPath) as? SilentActionPermissionTableViewCell else { fatalError() } - - let index = Preferences.shared.silentActions.index(Preferences.shared.silentActions.startIndex, offsetBy: indexPath.row) - let (source, permission) = Preferences.shared.silentActions[index] - cell.updateUI(source: source, permission: permission) - - return cell - } - - /* - // MARK: - Navigation - - // In a storyboard-based application, you will often want to do a little preparation before navigation - override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - // Get the new view controller using segue.destination. - // Pass the selected object to the new view controller. - } - */ - -} diff --git a/Tusker/Screens/Preferences/SilentActionPrefs.swift b/Tusker/Screens/Preferences/SilentActionPrefs.swift new file mode 100644 index 00000000..ccda62a4 --- /dev/null +++ b/Tusker/Screens/Preferences/SilentActionPrefs.swift @@ -0,0 +1,77 @@ +// SilentActionPrefs.swift +// Tusker +// +// Created by Shadowfacts on 6/13/19. +// Copyright © 2019 Shadowfacts. All rights reserved. +// + +import SwiftUI + +//struct SilentActionPermission: Identifiable { +// let application: String +// let permission: Preferences.Permission +// +// var id: String { +// return application +// } +// +// init(_ application: String, _ permission: Preferences.Permission) { +// self.application = application +// self.permission = permission +// } +//} + +struct SilentActionPrefs : View { +// @MappedPreference(\.silentActions, fromPref: { +// var array = [SilentActionPermission]() +// for (application, permission) in $0 { +// array.append(SilentActionPermission(application, permission)) +// } +// return array +// }) +// var silentActionPermissions: [SilentActionPermission] +// @Preference(\.silentActions) var silentActions: [String: Preferences.Permission] + @EnvironmentObject var preferences: Preferences + + var body: some View { + List(Array(preferences.silentActions.keys), id: \.self) { source in + SilentActionPermissionCell(source: source) + } + .listStyle(.grouped) +// .navigationBarTitle("Silent Action Permissions") + // see FB6838291 +// List(Array(silentActions.keys).identified(by: \.self)) { application in +// Text(application) +//// Toggle(isOn: Binding(getValue: { self.silentActions[application] == .accepted }, setValue: { self.silentActions[application] = $0 ? .accepted : .rejected }), label: Text(application)) +// }.listStyle(.grouped) + } +} + +struct SilentActionPermissionCell: View { + @EnvironmentObject var preferences: Preferences + let source: String +// var binding: Binding + + init(source: String) { + self.source = source +// self.binding = Binding(getValue: { self.preferences.silentActions[source] == .accepted }, setValue: { self.preferences.silentActions[source] = $0 ? .accepted : .rejected }) + } + + var body: some View { + Toggle(isOn: Binding(getValue: { + self.preferences.silentActions[self.source] == .accepted + }, setValue: { + self.preferences.silentActions[self.source] = $0 ? .accepted : .rejected + })) { + Text(verbatim: source) + } + } +} + +#if DEBUG +struct SilentActionPrefs_Previews : PreviewProvider { + static var previews: some View { + SilentActionPrefs().environmentObject(Preferences.shared) + } +} +#endif diff --git a/Tusker/Screens/Profile/MyProfileTableViewController.swift b/Tusker/Screens/Profile/MyProfileTableViewController.swift index 170a6d61..4f284de8 100644 --- a/Tusker/Screens/Profile/MyProfileTableViewController.swift +++ b/Tusker/Screens/Profile/MyProfileTableViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import SwiftUI class MyProfileTableViewController: ProfileTableViewController { @@ -50,7 +51,15 @@ class MyProfileTableViewController: ProfileTableViewController { } @objc func preferencesPressed() { - present(PreferencesTableViewController.create(), animated: true) + let view = PreferencesView().environmentObject(Preferences.shared) + let hostingController = UIHostingController(rootView: view) + let navigationController = UINavigationController(rootViewController: hostingController) + hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(closePreferences)) + present(navigationController, animated: true) + } + + @objc func closePreferences() { + dismiss(animated: true) } } diff --git a/Tusker/Screens/Utilities/EnhancedTableViewController.swift b/Tusker/Screens/Utilities/EnhancedTableViewController.swift index 61a2a6e2..200a7577 100644 --- a/Tusker/Screens/Utilities/EnhancedTableViewController.swift +++ b/Tusker/Screens/Utilities/EnhancedTableViewController.swift @@ -47,8 +47,7 @@ extension EnhancedTableViewController { return nil } let actionProvider: UIContextMenuActionProvider = { (elements) in -// return UIMenu.create(title: "test", children: elements + actionsProvider()) - return nil + return UIMenu(title: "", image: nil, identifier: nil, options: [], children: elements + actionsProvider()) } return UIContextMenuConfiguration(identifier: nil, previewProvider: previewProvider, actionProvider: actionProvider) } else { diff --git a/Tusker/Screens/Utilities/Previewing.swift b/Tusker/Screens/Utilities/Previewing.swift index b68c3671..1bd95e2e 100644 --- a/Tusker/Screens/Utilities/Previewing.swift +++ b/Tusker/Screens/Utilities/Previewing.swift @@ -27,26 +27,26 @@ extension MenuPreviewProvider { func actionsForProfile(accountID: String) -> [UIAction] { guard let account = MastodonCache.account(for: accountID) else { return [] } return [ - UIAction(__title: "Open in Safari", image: UIImage(systemName: "safari")) { (_) in + createAction(identifier: "openinsafari", title: "Open in Safari", systemImageName: "safari", handler: { (_) in self.present(SFSafariViewController(url: account.url)) - }, - UIAction(__title: "Send Message", image: UIImage(systemName: "envelope")) { (_) in + }), + createAction(identifier: "sendmessage", title: "Send Message", systemImageName: "envelope", handler: { (_) in self.present(UINavigationController(rootViewController: ComposeViewController(mentioningAcct: account.acct))) - }, - UIAction(__title: "Share...", image: UIImage(systemName: "square.and.arrow.up")) { (_) in + }), + createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in self.present(UIActivityViewController(activityItems: [account.url], applicationActivities: nil)) - } + }) ] } func actionsForURL(_ url: URL) -> [UIAction] { return [ - UIAction(__title: "Open in Safari", image: UIImage(systemName: "safari")) { (_) in + createAction(identifier: "openinsafari", title: "Open in Safari", systemImageName: "safari", handler: { (_) in self.present(SFSafariViewController(url: url)) - }, - UIAction(__title: "Share...", image: UIImage(systemName: "square.and.arrow.up")) { (_) in + }), + createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in self.present(UIActivityViewController(activityItems: [url], applicationActivities: nil)) - } + }) ] } @@ -57,16 +57,20 @@ extension MenuPreviewProvider { func actionsForStatus(statusID: String) -> [UIAction] { guard let status = MastodonCache.status(for: statusID) else { return [] } return [ - UIAction(__title: "Reply", image: UIImage(systemName: "arrowshape.turn.up.left")) { (_) in + createAction(identifier: "reply", title: "Reply", systemImageName: "arrowshape.turn.up.left", handler: { (_) in self.present(UINavigationController(rootViewController: ComposeViewController(inReplyTo: statusID))) - }, - UIAction(__title: "Open in Safari", image: UIImage(systemName: "safari")) { (_) in + }), + createAction(identifier: "openinsafari", title: "Open in Safari", systemImageName: "safari", handler: { (_) in self.present(SFSafariViewController(url: status.url!)) - }, - UIAction(__title: "Share...", image: UIImage(systemName: "square.and.arrow.up")) { (_) in + }), + createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in self.present(UIActivityViewController(activityItems: [status.url!], applicationActivities: nil)) - } + }) ] } + private func createAction(identifier: String, title: String, systemImageName: String, handler: @escaping UIActionHandler) -> UIAction { + return UIAction(title: title, image: UIImage(systemName: systemImageName), identifier: UIAction.Identifier(identifier), discoverabilityTitle: nil, attributes: [], state: .off, handler: handler) + } + } diff --git a/Tusker/Screens/Utilities/UIAlertController+Visibility.swift b/Tusker/Screens/Utilities/UIAlertController+Visibility.swift index 41f5bc92..6f4d8040 100644 --- a/Tusker/Screens/Utilities/UIAlertController+Visibility.swift +++ b/Tusker/Screens/Utilities/UIAlertController+Visibility.swift @@ -21,7 +21,7 @@ extension UIAlertController { if visibility == currentVisibility { action.setValue(true, forKey: "checked") } - action.setValue(visibility.image, forKey: "image") + action.setValue(UIImage(systemName: visibility.imageName), forKey: "image") addAction(action) }