From 1a438c176fcdc1286fd7ceba1f73911a0ec1f23a Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 14 Sep 2023 08:37:42 +0300 Subject: [PATCH] Fixes #1699 - Introduce a new advanced settings screen (#1700) --- ElementX.xcodeproj/project.pbxproj | 60 +++++++++++++---- .../en.lproj/Localizable.strings | 2 + .../Sources/Application/AppSettings.swift | 4 ++ ElementX/Sources/Generated/Strings.swift | 4 ++ .../Other/AccessibilityIdentifiers.swift | 1 + .../RoomScreen/RoomScreenViewModel.swift | 5 +- .../AdvancedSettingsScreenCoordinator.swift | 35 ++++++++++ .../AdvancedSettingsScreenModels.swift | 47 ++++++++++++++ .../AdvancedSettingsScreenViewModel.swift | 32 +++++++++ ...ancedSettingsScreenViewModelProtocol.swift | 23 +++++++ .../View/AdvancedSettingsScreen.swift | 65 +++++++++++++++++++ .../DeveloperOptionsScreenModels.swift | 1 - .../View/DeveloperOptionsScreen.swift | 8 +-- .../SettingsScreenCoordinator.swift | 31 +++++---- .../SettingsScreen/SettingsScreenModels.swift | 14 ++-- .../SettingsScreenViewModel.swift | 13 +--- .../SettingsScreen/View/SettingsScreen.swift | 38 +++++------ changelog.d/1699.feature | 1 + 18 files changed, 309 insertions(+), 75 deletions(-) create mode 100644 ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenCoordinator.swift create mode 100644 ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenModels.swift create mode 100644 ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModel.swift create mode 100644 ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModelProtocol.swift create mode 100644 ElementX/Sources/Screens/Settings/AvancedOptionsScreen/View/AdvancedSettingsScreen.swift create mode 100644 changelog.d/1699.feature diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index a7cf6aa3c..afc2b0fdf 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 56; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -32,6 +32,7 @@ 09713669577CDA8D012EE380 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 6647C55D93508C7CE9D954A5 /* MatrixRustSDK */; }; 09AAF04B27732046C755D914 /* SoftLogoutViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */; }; 09C83DDDB07C28364F325209 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */; }; + 0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */; }; 0AA0477E063E72B786A983CF /* AnalyticsPromptScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63E1FF2DA52B1DE7CAEC5422 /* AnalyticsPromptScreenViewModel.swift */; }; 0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */; }; 0B57C2399B9E1CE5CE0D8005 /* ComposerToolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D121B4FCFC38DBCC17BCC6D6 /* ComposerToolbar.swift */; }; @@ -102,6 +103,7 @@ 22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEBE5EA91E8691EDF364EC2 /* UITestsScreenIdentifier.swift */; }; 234E2C782981003971ABE96E /* PermalinkBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */; }; 2352C541AF857241489756FF /* MockRoomSummaryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */; }; + 2355289BB0146231DD8AFFC0 /* AnalyticsMessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2133A5FF0C14986E60326115 /* AnalyticsMessageType.swift */; }; 23701DE32ACD6FD40AA992C3 /* MediaUploadingPreprocessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE203026B9AD3DB412439866 /* MediaUploadingPreprocessorTests.swift */; }; 237FC70AA257B935F53316BA /* SessionVerificationControllerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */; }; 245F7FE5961BD10C145A26E0 /* UITimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA689E792E679F5E3956F21 /* UITimelineView.swift */; }; @@ -157,6 +159,7 @@ 33CAC1226DFB8B5D8447D286 /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 1BCD21310B997A6837B854D6 /* GZIP */; }; 340D39DB87F3800D53A6A621 /* EmojiPickerScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00245D40CD90FD71D6A05239 /* EmojiPickerScreen.swift */; }; 34357B287357BC0B9715DD51 /* UserAgentBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */; }; + 34433A509DFEC93579B3B35B /* AdvancedSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C18CC37B97E77838609CFFE7 /* AdvancedSettingsScreen.swift */; }; 3467FEE8210D301FF1B77001 /* UserIndicatorControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7893780A1FD6E3F38B3E9049 /* UserIndicatorControllerMock.swift */; }; 3471204F2CC05D4821C35F23 /* landscape_test_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 7A5D2323D7B6BF4913EB7EED /* landscape_test_image.jpg */; }; 34C752A73717C691582DC6C7 /* UnsupportedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */; }; @@ -206,6 +209,7 @@ 43F35A7E5703D64DB0519C59 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */; }; 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */; }; 44121202B4A260C98BF615A7 /* RoomMembersListScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */; }; + 4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */; }; 46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; }; 46A261AA898344A1F3C406B1 /* ReportContentScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CCE3636E3D01477C8B2E9D0 /* ReportContentScreenModels.swift */; }; 46BA7F4B4D3A7164DED44B88 /* FullscreenDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565F1B2B300597C616B37888 /* FullscreenDialog.swift */; }; @@ -287,6 +291,7 @@ 6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */; }; 61941DEE5F3834765770BE01 /* InviteUsersScreenSelectedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F32E0B4B83D2A11EE8D011 /* InviteUsersScreenSelectedItem.swift */; }; 61A36B9BB2ADE36CEFF5E98C /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E93A1BE7D8A2EBCAD51EEB4 /* Array.swift */; }; + 62910B515BCB4B455E24D7C1 /* AdvancedSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D086854995173E897F993C26 /* AdvancedSettingsScreenViewModelProtocol.swift */; }; 6298AB0906DDD3525CD78C6B /* KZFileWatchers in Frameworks */ = {isa = PBXBuildFile; productRef = 81DB3AB6CE996AB3954F4F03 /* KZFileWatchers */; }; 63E46D18B91D08E15FC04125 /* ExpiringTaskRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B25F959A434BB9923A3223F /* ExpiringTaskRunner.swift */; }; 6448F8D1D3CA4CD27BB4CADD /* RoomMemberProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F36C5D9B37E50915ECBD3EE /* RoomMemberProxy.swift */; }; @@ -581,6 +586,7 @@ B796A25F282C0A340D1B9C12 /* ImageRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B5EDCD05D50BA9B815C66C /* ImageRoomTimelineItemContent.swift */; }; B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 16DC8C5B2991724903F1FA6A /* AppIcon.pdf */; }; B828C600A54B2EE20871A451 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD700E035C85738EE4B97129 /* PerformanceTests.swift */; }; + B879446FD8E65A711EF8F9F7 /* AdvancedSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */; }; B89990DD875B0B603D4D4332 /* NotificationItemProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */; }; B93D7CE520088AD53FA6D53C /* SettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B663BE498BB39EADC24025D /* SettingsScreenModels.swift */; }; B93FA0DA1504B301CAEE141B /* NotificationSettingsProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6F5D66F158A6662F953733E /* NotificationSettingsProxy.swift */; }; @@ -750,7 +756,6 @@ EC280623A42904341363EAAF /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = A20EA00CCB9DBE0FFB17DD09 /* Collections */; }; EC658A57E715699C52DFBC77 /* CreatePollScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3EB1D0C69FEDD93404DF927E /* CreatePollScreenViewModelTests.swift */; }; ECA636DAF071C611FDC2BB57 /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; - EDC1031A7CFB3406A9DA3175 /* AnalyticsMessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AD6299F4516797E9BBE14C3 /* AnalyticsMessageType.swift */; }; EDF8919F15DE0FF00EF99E70 /* DocumentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */; }; EE4E2C1922BBF5169E213555 /* PillAttachmentViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B53D6C5C0D14B04D3AB3F6E /* PillAttachmentViewProvider.swift */; }; EE4F5601356228FF72FC56B6 /* MockClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F40F48279322E504153AB0D /* MockClientProxy.swift */; }; @@ -919,7 +924,7 @@ 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CurrentValuePublisher.swift; sourceTree = ""; }; 12EDAFB64FA5F6812D54F39A /* MigrationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModel.swift; sourceTree = ""; }; 12F1E7F9C2BE8BB751037826 /* WaitlistScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenCoordinator.swift; sourceTree = ""; }; - 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = IntegrationTests.xctestplan; sourceTree = ""; }; + 1304D9191300873EADA52D6E /* IntegrationTests.xctestplan */ = {isa = PBXFileReference; path = IntegrationTests.xctestplan; sourceTree = ""; }; 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNTextInputNotificationResponse+Creator.swift"; sourceTree = ""; }; 13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = ""; }; 1423AB065857FA546444DB15 /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = ""; }; @@ -964,6 +969,7 @@ 1FD51B4D5173F7FC886F5360 /* NoticeRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItemContent.swift; sourceTree = ""; }; 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiLoaderProtocol.swift; sourceTree = ""; }; 20872C3887F835958CE2F1D0 /* MapTilerStaticMapProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStaticMapProtocol.swift; sourceTree = ""; }; + 2133A5FF0C14986E60326115 /* AnalyticsMessageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsMessageType.swift; sourceTree = ""; }; 2141693488CE5446BB391964 /* Date.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Date.swift; sourceTree = ""; }; 216F0DDC98F2A2C162D09C28 /* FileRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItemContent.swift; sourceTree = ""; }; 218AB05B4E3889731959C5F1 /* EventBasedTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBasedTimelineItemProtocol.swift; sourceTree = ""; }; @@ -1070,17 +1076,17 @@ 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = ""; }; 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = ""; }; 47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = ""; }; - 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DesignKit; sourceTree = SOURCE_ROOT; }; + 478BE8591BD13E908EF70C0C /* DesignKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = DesignKit; path = DesignKit; sourceTree = SOURCE_ROOT; }; 4798B3B7A1E8AE3901CEE8C6 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = ""; }; 47EBB5D698CE9A25BB553A2D /* Strings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Strings.swift; sourceTree = ""; }; 47F29139BC2A804CE5E0757E /* MediaUploadPreviewScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreenViewModel.swift; sourceTree = ""; }; 4959CECEC984B3995616F427 /* DataProtectionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataProtectionManager.swift; sourceTree = ""; }; + 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenModels.swift; sourceTree = ""; }; 49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 49E6066092ED45E36BB306F7 /* zh-Hant-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hant-TW"; path = "zh-Hant-TW.lproj/Localizable.stringsdict"; sourceTree = ""; }; 49E751D7EDB6043238111D90 /* UNNotificationRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNNotificationRequest.swift; sourceTree = ""; }; 4A4AD793D50748F8997E5B15 /* TimelineItemMacContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemMacContextMenu.swift; sourceTree = ""; }; 4AB7D7DAAAF662DED9D02379 /* MockMediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaLoader.swift; sourceTree = ""; }; - 4AD6299F4516797E9BBE14C3 /* AnalyticsMessageType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsMessageType.swift; sourceTree = ""; }; 4ADC55DFF46083BC957E0019 /* CreatePollScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePollScreenModels.swift; sourceTree = ""; }; 4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = ""; }; 4B5046BB295AEAFA6FB81655 /* SessionVerificationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenModels.swift; sourceTree = ""; }; @@ -1223,6 +1229,7 @@ 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactoryProtocol.swift; sourceTree = ""; }; 7DDBF99755A9008CF8C8499E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 7DDF49CEBC0DFC59C308335F /* RoomMemberDetailsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenViewModelProtocol.swift; sourceTree = ""; }; + 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenCoordinator.swift; sourceTree = ""; }; 7F615A00DB223FF3280204D2 /* UserDiscoveryServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoveryServiceProtocol.swift; sourceTree = ""; }; 7FB2253D36E81E045E1CB432 /* Duration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Duration.swift; sourceTree = ""; }; 80C4927D09099497233E9980 /* WaitlistScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreen.swift; sourceTree = ""; }; @@ -1261,7 +1268,7 @@ 8D55702474F279D910D2D162 /* RoomStateEventStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomStateEventStringBuilder.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; 8E1BBA73B611EDEEA6E20E05 /* InvitesScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenModels.swift; sourceTree = ""; }; 8EC57A32ABC80D774CC663DB /* SettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenUITests.swift; sourceTree = ""; }; 8F21ED7205048668BEB44A38 /* AppActivityView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActivityView.swift; sourceTree = ""; }; @@ -1372,8 +1379,9 @@ B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Analytics+SwiftUI.swift"; sourceTree = ""; }; B590BD4507D4F0A377FDE01A /* LoadableAvatarImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadableAvatarImage.swift; sourceTree = ""; }; B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = ""; }; - B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = ConfettiScene.scn; sourceTree = ""; }; + B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */ = {isa = PBXFileReference; path = ConfettiScene.scn; sourceTree = ""; }; B6311F21F911E23BE4DF51B4 /* ReadMarkerRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineView.swift; sourceTree = ""; }; + B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModel.swift; sourceTree = ""; }; B697816AF93DA06EC58C5D70 /* WaitlistScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistScreenViewModelProtocol.swift; sourceTree = ""; }; B6E89E530A8E92EC44301CA1 /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = ""; }; B746EFA112532A7B701FB914 /* RoomNotificationSettingsCustomSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationSettingsCustomSectionView.swift; sourceTree = ""; }; @@ -1413,6 +1421,7 @@ C14D83B2B7CD5501A0089EFC /* LayoutDirection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LayoutDirection.swift; sourceTree = ""; }; C1511766C534367700C8DD75 /* RoomNotificationModeProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomNotificationModeProxy.swift; sourceTree = ""; }; C15E0017717EAE3A1D02D005 /* StaticLocationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenCoordinator.swift; sourceTree = ""; }; + C18CC37B97E77838609CFFE7 /* AdvancedSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreen.swift; sourceTree = ""; }; C1D737F4672021D0A7D218CD /* OIDCAccountSettingsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCAccountSettingsPresenter.swift; sourceTree = ""; }; C23B3FAD8B23C421BC0D1B1E /* MapTilerGeoCodingServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerGeoCodingServiceProtocol.swift; sourceTree = ""; }; C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = ""; }; @@ -1460,10 +1469,11 @@ CD95B3714F806AC9CF9A557B /* ComposerToolbarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerToolbarViewModel.swift; sourceTree = ""; }; CDB3227C7A74B734924942E9 /* RoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProvider.swift; sourceTree = ""; }; CEE0E6043EFCF6FD2A341861 /* TimelineReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReplyView.swift; sourceTree = ""; }; - CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UnitTests.xctestplan; sourceTree = ""; }; + CEE41494C837AA403A06A5D9 /* UnitTests.xctestplan */ = {isa = PBXFileReference; path = UnitTests.xctestplan; sourceTree = ""; }; CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxy.swift; sourceTree = ""; }; D0140615D2232612C813FD6C /* EncryptedHistoryRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedHistoryRoomTimelineItem.swift; sourceTree = ""; }; D071F86CD47582B9196C9D16 /* UserDiscoverySection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDiscoverySection.swift; sourceTree = ""; }; + D086854995173E897F993C26 /* AdvancedSettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenViewModelProtocol.swift; sourceTree = ""; }; D09A267106B9585D3D0CFC0D /* ClientError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientError.swift; sourceTree = ""; }; D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = ""; }; D0C2D52E36AD614B3C003EF6 /* RoomTimelineItemViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemViewState.swift; sourceTree = ""; }; @@ -1544,7 +1554,7 @@ ECF79FB25E2D4BD6F50CE7C9 /* RoomMembersListScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenViewModel.swift; sourceTree = ""; }; ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; ED983D4DCA5AFA6E1ED96099 /* StateRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateRoomTimelineView.swift; sourceTree = ""; }; EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = ""; }; EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItemContent.swift; sourceTree = ""; }; @@ -1558,7 +1568,7 @@ F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = ""; }; F17EFA1D3D09FC2F9C5E1CB2 /* MediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProvider.swift; sourceTree = ""; }; F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = ""; }; - F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; lastKnownFileType = file; path = portrait_test_video.mp4; sourceTree = ""; }; + F2D513D2477B57F90E98EEC0 /* portrait_test_video.mp4 */ = {isa = PBXFileReference; path = portrait_test_video.mp4; sourceTree = ""; }; F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegexTests.swift; sourceTree = ""; }; F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItem.swift; sourceTree = ""; }; F36C0A6D59717193F49EA986 /* UserSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionTests.swift; sourceTree = ""; }; @@ -2307,7 +2317,7 @@ E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */, D77B3D4950F1707E66E4A45A /* AnalyticsConfiguration.swift */, 57B6B383F1FD04CC0E7B60C6 /* AnalyticsConsentState.swift */, - 4AD6299F4516797E9BBE14C3 /* AnalyticsMessageType.swift */, + 2133A5FF0C14986E60326115 /* AnalyticsMessageType.swift */, FEFEEE93B82937B2E86F92EB /* AnalyticsScreen.swift */, 5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */, A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */, @@ -2554,6 +2564,7 @@ children = ( EB5B1119B5AD79297F1D49EB /* AccountSettings */, 09C599CB430ABF160C1EE55C /* AnalyticsSettingsScreen */, + 7563BA5BBB57C5520C067859 /* AvancedOptionsScreen */, 1CA6CD0DE6F0445156361B6D /* DeveloperOptionsScreen */, 38A1C74493B816B8753F5BC2 /* LegalInformationScreen */, 441115752CA2408F26A72D11 /* NotificationSettingsEditScreen */, @@ -2681,6 +2692,18 @@ path = Analytics; sourceTree = ""; }; + 7563BA5BBB57C5520C067859 /* AvancedOptionsScreen */ = { + isa = PBXGroup; + children = ( + 7E492690C8B27A892C194CC4 /* AdvancedSettingsScreenCoordinator.swift */, + 4999B5FD50AED7CB0F590FF8 /* AdvancedSettingsScreenModels.swift */, + B63B69F9A2BC74DD40DC75C8 /* AdvancedSettingsScreenViewModel.swift */, + D086854995173E897F993C26 /* AdvancedSettingsScreenViewModelProtocol.swift */, + B8DF5C80CDA495A1E5ED20D9 /* View */, + ); + path = AvancedOptionsScreen; + sourceTree = ""; + }; 7583EAC171059A86B767209F /* MediaProvider */ = { isa = PBXGroup; children = ( @@ -3386,6 +3409,14 @@ path = RoomMemberDetailsScreen; sourceTree = ""; }; + B8DF5C80CDA495A1E5ED20D9 /* View */ = { + isa = PBXGroup; + children = ( + C18CC37B97E77838609CFFE7 /* AdvancedSettingsScreen.swift */, + ); + path = View; + sourceTree = ""; + }; BA1938A75D8C780F694CEB62 /* ServerConfirmationScreen */ = { isa = PBXGroup; children = ( @@ -4421,6 +4452,11 @@ files = ( 41F553349AF44567184822D8 /* APNSPayload.swift in Sources */, 70394ECD2DCC70741538620D /* AccessibilityIdentifiers.swift in Sources */, + 34433A509DFEC93579B3B35B /* AdvancedSettingsScreen.swift in Sources */, + 4557192F5B15A8D9BB920232 /* AdvancedSettingsScreenCoordinator.swift in Sources */, + 0A194F5E70B5A628C1BF4476 /* AdvancedSettingsScreenModels.swift in Sources */, + B879446FD8E65A711EF8F9F7 /* AdvancedSettingsScreenViewModel.swift in Sources */, + 62910B515BCB4B455E24D7C1 /* AdvancedSettingsScreenViewModelProtocol.swift in Sources */, 53C1E7F6A7D6409D89F36ED7 /* AggregatedReactionMock.swift in Sources */, 4219391CD2351E410554B3E8 /* AggregratedReaction.swift in Sources */, 64D05250CEDE8B604119F6E6 /* Alert.swift in Sources */, @@ -4429,7 +4465,7 @@ F7567DD6635434E8C563BF85 /* AnalyticsClientProtocol.swift in Sources */, 54C774874BED4A8FAD1F22FE /* AnalyticsConfiguration.swift in Sources */, 8DDC6F28C797D8685F2F8E32 /* AnalyticsConsentState.swift in Sources */, - EDC1031A7CFB3406A9DA3175 /* AnalyticsMessageType.swift in Sources */, + 2355289BB0146231DD8AFFC0 /* AnalyticsMessageType.swift in Sources */, 9DF3F6318A4402305F5EB869 /* AnalyticsPromptScreen.swift in Sources */, 5F28C9146694B381BB82E18C /* AnalyticsPromptScreenCoordinator.swift in Sources */, 496CC9D59ACFAB84FD9B3B5F /* AnalyticsPromptScreenModels.swift in Sources */, diff --git a/ElementX/Resources/Localizations/en.lproj/Localizable.strings b/ElementX/Resources/Localizations/en.lproj/Localizable.strings index 3e2e9c26e..ece7f9aa9 100644 --- a/ElementX/Resources/Localizations/en.lproj/Localizable.strings +++ b/ElementX/Resources/Localizations/en.lproj/Localizable.strings @@ -67,6 +67,7 @@ "action_yes" = "Yes"; "common_about" = "About"; "common_acceptable_use_policy" = "Acceptable use policy"; +"common_advanced_settings" = "Advanced settings"; "common_analytics" = "Analytics"; "common_audio" = "Audio"; "common_bubbles" = "Bubbles"; @@ -108,6 +109,7 @@ "common_replying_to" = "Replying to %1$@"; "common_report_a_bug" = "Report a bug"; "common_report_submitted" = "Report submitted"; +"common_rich_text_editor" = "Rich text editor"; "common_room_name" = "Room name"; "common_room_name_placeholder" = "e.g. your project name"; "common_search_for_someone" = "Search for someone"; diff --git a/ElementX/Sources/Application/AppSettings.swift b/ElementX/Sources/Application/AppSettings.swift index 34b5099d2..f35194a34 100644 --- a/ElementX/Sources/Application/AppSettings.swift +++ b/ElementX/Sources/Application/AppSettings.swift @@ -31,6 +31,7 @@ final class AppSettings { case pusherProfileTag case logLevel case otlpTracingEnabled + case viewSourceEnabled // Feature flags case shouldCollapseRoomStateEvents @@ -188,6 +189,9 @@ final class AppSettings { @UserPreference(key: UserDefaultsKeys.shouldCollapseRoomStateEvents, defaultValue: true, storageType: .volatile) var shouldCollapseRoomStateEvents + @UserPreference(key: UserDefaultsKeys.viewSourceEnabled, defaultValue: false, storageType: .userDefaults(store)) + var viewSourceEnabled + // MARK: - Notifications @UserPreference(key: UserDefaultsKeys.enableNotifications, defaultValue: true, storageType: .userDefaults(store)) diff --git a/ElementX/Sources/Generated/Strings.swift b/ElementX/Sources/Generated/Strings.swift index cb8fead33..77937cccf 100644 --- a/ElementX/Sources/Generated/Strings.swift +++ b/ElementX/Sources/Generated/Strings.swift @@ -150,6 +150,8 @@ public enum L10n { public static var commonAbout: String { return L10n.tr("Localizable", "common_about") } /// Acceptable use policy public static var commonAcceptableUsePolicy: String { return L10n.tr("Localizable", "common_acceptable_use_policy") } + /// Advanced settings + public static var commonAdvancedSettings: String { return L10n.tr("Localizable", "common_advanced_settings") } /// Analytics public static var commonAnalytics: String { return L10n.tr("Localizable", "common_analytics") } /// Audio @@ -248,6 +250,8 @@ public enum L10n { public static var commonReportABug: String { return L10n.tr("Localizable", "common_report_a_bug") } /// Report submitted public static var commonReportSubmitted: String { return L10n.tr("Localizable", "common_report_submitted") } + /// Rich text editor + public static var commonRichTextEditor: String { return L10n.tr("Localizable", "common_rich_text_editor") } /// Room name public static var commonRoomName: String { return L10n.tr("Localizable", "common_room_name") } /// e.g. your project name diff --git a/ElementX/Sources/Other/AccessibilityIdentifiers.swift b/ElementX/Sources/Other/AccessibilityIdentifiers.swift index 9fa7e4a58..17ab9e43e 100644 --- a/ElementX/Sources/Other/AccessibilityIdentifiers.swift +++ b/ElementX/Sources/Other/AccessibilityIdentifiers.swift @@ -174,6 +174,7 @@ struct A11yIdentifiers { let analytics = "settings-analytics" let reportBug = "settings-report_bug" let about = "settings_about" + let advancedSettings = "settings_advanced-settings" let developerOptions = "settings_developer-options" let logout = "settings-logout" } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift index 6f9466459..aa98f826a 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenViewModel.swift @@ -501,7 +501,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol return nil } - var debugActions: [TimelineItemMenuAction] = appSettings.canShowDeveloperOptions ? [.viewSource] : [] + var debugActions: [TimelineItemMenuAction] = [] + if appSettings.canShowDeveloperOptions || appSettings.viewSourceEnabled { + debugActions.append(.viewSource) + } if let encryptedItem = timelineItem as? EncryptedRoomTimelineItem { switch encryptedItem.encryptionType { diff --git a/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenCoordinator.swift b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenCoordinator.swift new file mode 100644 index 000000000..dd3492412 --- /dev/null +++ b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenCoordinator.swift @@ -0,0 +1,35 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +enum AdvancedSettingsScreenCoordinatorAction { + case clearCache +} + +final class AdvancedSettingsScreenCoordinator: CoordinatorProtocol { + private var viewModel: AdvancedSettingsScreenViewModelProtocol + + var callback: ((AdvancedSettingsScreenCoordinatorAction) -> Void)? + + init() { + viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings) + } + + func toPresentable() -> AnyView { + AnyView(AdvancedSettingsScreen(context: viewModel.context)) + } +} diff --git a/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenModels.swift b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenModels.swift new file mode 100644 index 000000000..740dd714d --- /dev/null +++ b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenModels.swift @@ -0,0 +1,47 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +enum AdvancedSettingsScreenViewModelAction { } + +struct AdvancedSettingsScreenViewState: BindableState { + var bindings: AdvancedSettingsScreenViewStateBindings +} + +@dynamicMemberLookup +struct AdvancedSettingsScreenViewStateBindings { + private let advancedSettings: AdvancedSettingsProtocol + + init(advancedSettings: AdvancedSettingsProtocol) { + self.advancedSettings = advancedSettings + } + + subscript(dynamicMember keyPath: ReferenceWritableKeyPath) -> Setting { + get { advancedSettings[keyPath: keyPath] } + set { advancedSettings[keyPath: keyPath] = newValue } + } +} + +enum AdvancedSettingsScreenViewAction { } + +protocol AdvancedSettingsProtocol: AnyObject { + var timelineStyle: TimelineStyle { get set } + var viewSourceEnabled: Bool { get set } + var richTextEditorEnabled: Bool { get set } +} + +extension AppSettings: AdvancedSettingsProtocol { } diff --git a/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModel.swift b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModel.swift new file mode 100644 index 000000000..979db8714 --- /dev/null +++ b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModel.swift @@ -0,0 +1,32 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +typealias AdvancedSettingsScreenViewModelType = StateStoreViewModel + +class AdvancedSettingsScreenViewModel: AdvancedSettingsScreenViewModelType, AdvancedSettingsScreenViewModelProtocol { + var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)? + + init(advancedSettings: AdvancedSettingsProtocol) { + let bindings = AdvancedSettingsScreenViewStateBindings(advancedSettings: advancedSettings) + let state = AdvancedSettingsScreenViewState(bindings: bindings) + + super.init(initialViewState: state) + } + + override func process(viewAction: AdvancedSettingsScreenViewAction) { } +} diff --git a/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModelProtocol.swift b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModelProtocol.swift new file mode 100644 index 000000000..5f48e8748 --- /dev/null +++ b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/AdvancedSettingsScreenViewModelProtocol.swift @@ -0,0 +1,23 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +@MainActor +protocol AdvancedSettingsScreenViewModelProtocol { + var callback: ((AdvancedSettingsScreenViewModelAction) -> Void)? { get set } + var context: AdvancedSettingsScreenViewModelType.Context { get } +} diff --git a/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/View/AdvancedSettingsScreen.swift b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/View/AdvancedSettingsScreen.swift new file mode 100644 index 000000000..541534966 --- /dev/null +++ b/ElementX/Sources/Screens/Settings/AvancedOptionsScreen/View/AdvancedSettingsScreen.swift @@ -0,0 +1,65 @@ +// +// Copyright 2022 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Compound +import SwiftUI + +struct AdvancedSettingsScreen: View { + @ObservedObject var context: AdvancedSettingsScreenViewModel.Context + @State private var showConfetti = false + + var body: some View { + Form { + Section { + ListRow(label: .default(title: L10n.commonMessageLayout, + systemIcon: .rectangleGrid1x2), + kind: .picker(selection: $context.timelineStyle, + items: TimelineStyle.allCases.map { (title: $0.name, tag: $0) })) + + ListRow(label: .default(title: L10n.actionViewSource, systemIcon: .mailAndTextMagnifyingglass), + kind: .toggle($context.viewSourceEnabled)) + + ListRow(label: .default(title: L10n.commonRichTextEditor, icon: Image(asset: Asset.Images.textFormat)), + kind: .toggle($context.richTextEditorEnabled)) + } + } + .compoundList() + .navigationTitle(L10n.commonAdvancedSettings) + .navigationBarTitleDisplayMode(.inline) + } +} + +private extension TimelineStyle { + var name: String { + switch self { + case .plain: + return L10n.commonModern + case .bubbles: + return L10n.commonBubbles + } + } +} + +// MARK: - Previews + +struct AdvancedSettingsScreen_Previews: PreviewProvider { + static let viewModel = AdvancedSettingsScreenViewModel(advancedSettings: ServiceLocator.shared.settings) + static var previews: some View { + NavigationStack { + AdvancedSettingsScreen(context: viewModel.context) + } + } +} diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift index f662867a9..187f3f8b5 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/DeveloperOptionsScreenModels.swift @@ -49,7 +49,6 @@ protocol DeveloperOptionsProtocol: AnyObject { var userSuggestionsEnabled: Bool { get set } var readReceiptsEnabled: Bool { get set } var swiftUITimelineEnabled: Bool { get set } - var richTextEditorEnabled: Bool { get set } } extension AppSettings: DeveloperOptionsProtocol { } diff --git a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift index ec309182e..7704d59c2 100644 --- a/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift +++ b/ElementX/Sources/Screens/Settings/DeveloperOptionsScreen/View/DeveloperOptionsScreen.swift @@ -53,12 +53,6 @@ struct DeveloperOptionsScreen: View { } } - Section("Rich Text Editor") { - Toggle(isOn: $context.richTextEditorEnabled) { - Text("Use the Rich Text Editor") - } - } - Section { Button { showConfetti = true @@ -86,7 +80,7 @@ struct DeveloperOptionsScreen: View { } } .overlay(effectsView) - .compoundForm() + .compoundList() .navigationTitle(L10n.commonDeveloperOptions) .navigationBarTitleDisplayMode(.inline) } diff --git a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenCoordinator.swift b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenCoordinator.swift index 1aa5b91bc..70edfc4d8 100644 --- a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenCoordinator.swift +++ b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenCoordinator.swift @@ -61,12 +61,14 @@ final class SettingsScreenCoordinator: CoordinatorProtocol { verifySession() case .accountSessionsList: presentAccountSessionsListURL() + case .notifications: + presentNotificationSettings() + case .advancedSettings: + self.presentAdvancedSettings() case .developerOptions: presentDeveloperOptions() case .logout: callback?(.logout) - case .notifications: - presentNotificationSettings() } } } @@ -159,6 +161,21 @@ final class SettingsScreenCoordinator: CoordinatorProtocol { } } + private func presentNotificationSettings() { + let notificationParameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: parameters.navigationStackCoordinator, + userSession: parameters.userSession, + userNotificationCenter: UNUserNotificationCenter.current(), + notificationSettings: parameters.notificationSettings, + isModallyPresented: false) + let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters) + parameters.navigationStackCoordinator?.push(coordinator) + } + + private func presentAdvancedSettings() { + let coordinator = AdvancedSettingsScreenCoordinator() + parameters.navigationStackCoordinator?.push(coordinator) + } + private func presentDeveloperOptions() { let coordinator = DeveloperOptionsScreenCoordinator() @@ -175,14 +192,4 @@ final class SettingsScreenCoordinator: CoordinatorProtocol { private func showSuccess(label: String) { parameters.userIndicatorController?.submitIndicator(UserIndicator(title: label)) } - - private func presentNotificationSettings() { - let notificationParameters = NotificationSettingsScreenCoordinatorParameters(navigationStackCoordinator: parameters.navigationStackCoordinator, - userSession: parameters.userSession, - userNotificationCenter: UNUserNotificationCenter.current(), - notificationSettings: parameters.notificationSettings, - isModallyPresented: false) - let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters) - parameters.navigationStackCoordinator?.push(coordinator) - } } diff --git a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenModels.swift b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenModels.swift index b3ee7d6e9..5f10f12a9 100644 --- a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenModels.swift +++ b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenModels.swift @@ -25,13 +25,13 @@ enum SettingsScreenViewModelAction { case about case sessionVerification case accountSessionsList - case developerOptions case notifications + case advancedSettings + case developerOptions case logout } struct SettingsScreenViewState: BindableState { - var bindings: SettingsScreenViewStateBindings var deviceID: String? var userID: String var accountProfileURL: URL? @@ -45,10 +45,6 @@ struct SettingsScreenViewState: BindableState { var window: UIWindow? } -struct SettingsScreenViewStateBindings { - var timelineStyle: TimelineStyle -} - enum SettingsScreenViewAction { case close case accountProfile @@ -56,11 +52,11 @@ enum SettingsScreenViewAction { case reportBug case about case sessionVerification - case logout - case changedTimelineStyle case accountSessionsList - case developerOptions case notifications + case developerOptions + case advancedSettings + case logout /// Updates the window used for the OIDC account URL anchor. case updateWindow(UIWindow) diff --git a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenViewModel.swift b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenViewModel.swift index cd39f006b..bb96c14f7 100644 --- a/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenViewModel.swift +++ b/ElementX/Sources/Screens/Settings/SettingsScreen/SettingsScreenViewModel.swift @@ -29,15 +29,12 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo self.userSession = userSession self.appSettings = appSettings - let bindings = SettingsScreenViewStateBindings(timelineStyle: appSettings.timelineStyle) - var showSessionVerificationSection = false if let sessionVerificationController = userSession.sessionVerificationController { showSessionVerificationSection = !sessionVerificationController.isVerified } - super.init(initialViewState: .init(bindings: bindings, - deviceID: userSession.deviceID, + super.init(initialViewState: .init(deviceID: userSession.deviceID, userID: userSession.userID, accountProfileURL: userSession.clientProxy.accountURL(action: .profile), accountSessionsListURL: userSession.clientProxy.accountURL(action: .sessionsList), @@ -45,10 +42,6 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo showDeveloperOptions: appSettings.canShowDeveloperOptions), imageProvider: userSession.mediaProvider) - appSettings.$timelineStyle - .weakAssign(to: \.state.bindings.timelineStyle, on: self) - .store(in: &cancellables) - userSession.clientProxy.avatarURLPublisher .weakAssign(to: \.state.userAvatarURL, on: self) .store(in: &cancellables) @@ -94,12 +87,12 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo callback?(.logout) case .sessionVerification: callback?(.sessionVerification) - case .changedTimelineStyle: - appSettings.timelineStyle = state.bindings.timelineStyle case .notifications: callback?(.notifications) case .accountSessionsList: callback?(.accountSessionsList) + case .advancedSettings: + callback?(.advancedSettings) case .developerOptions: callback?(.developerOptions) diff --git a/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift b/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift index 20ece2b5f..d83ed9bdb 100644 --- a/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift +++ b/ElementX/Sources/Screens/Settings/SettingsScreen/View/SettingsScreen.swift @@ -37,9 +37,7 @@ struct SettingsScreen: View { manageSessionsSection } - if context.viewState.showDeveloperOptions { - developerOptionsSection - } + advancedOptionsSection signOutSection } @@ -89,7 +87,6 @@ struct SettingsScreen: View { private var mainSection: some View { Section { - // Account if context.viewState.accountProfileURL != nil { ListRow(label: .default(title: L10n.actionManageAccount, systemIcon: .person), kind: .button { @@ -98,17 +95,6 @@ struct SettingsScreen: View { .accessibilityIdentifier(A11yIdentifiers.settingsScreen.account) } - // Message layout - ListRow(label: .default(title: L10n.commonMessageLayout, - systemIcon: .rectangleGrid1x2), - kind: .picker(selection: $context.timelineStyle, - items: TimelineStyle.allCases.map { (title: $0.name, tag: $0) })) - .accessibilityIdentifier("timelineStylePicker") - .onChange(of: context.timelineStyle) { _ in - context.send(viewAction: .changedTimelineStyle) - } - - // Notifications ListRow(label: .default(title: L10n.screenNotificationSettingsTitle, systemIcon: .bell), kind: .navigationLink { @@ -116,7 +102,6 @@ struct SettingsScreen: View { }) .accessibilityIdentifier(A11yIdentifiers.settingsScreen.notifications) - // Analytics ListRow(label: .default(title: L10n.commonAnalytics, systemIcon: .chartBar), kind: .navigationLink { @@ -124,7 +109,6 @@ struct SettingsScreen: View { }) .accessibilityIdentifier(A11yIdentifiers.settingsScreen.analytics) - // Report Bug ListRow(label: .default(title: L10n.commonReportABug, systemIcon: .ladybug), kind: .navigationLink { @@ -132,7 +116,6 @@ struct SettingsScreen: View { }) .accessibilityIdentifier(A11yIdentifiers.settingsScreen.reportBug) - // About ListRow(label: .default(title: L10n.commonAbout, systemIcon: .questionmarkCircle), kind: .navigationLink { @@ -161,14 +144,23 @@ struct SettingsScreen: View { } } - private var developerOptionsSection: some View { + private var advancedOptionsSection: some View { Section { - ListRow(label: .default(title: L10n.commonDeveloperOptions, - systemIcon: .hammerCircle), + ListRow(label: .default(title: L10n.commonAdvancedSettings, + systemIcon: .gearshape2), kind: .navigationLink { - context.send(viewAction: .developerOptions) + context.send(viewAction: .advancedSettings) }) - .accessibilityIdentifier(A11yIdentifiers.settingsScreen.developerOptions) + .accessibilityIdentifier(A11yIdentifiers.settingsScreen.advancedSettings) + + if context.viewState.showDeveloperOptions { + ListRow(label: .default(title: L10n.commonDeveloperOptions, + systemIcon: .hammerCircle), + kind: .navigationLink { + context.send(viewAction: .developerOptions) + }) + .accessibilityIdentifier(A11yIdentifiers.settingsScreen.developerOptions) + } } } diff --git a/changelog.d/1699.feature b/changelog.d/1699.feature new file mode 100644 index 000000000..35e190fa9 --- /dev/null +++ b/changelog.d/1699.feature @@ -0,0 +1 @@ +Introduce a new advanced settings screen \ No newline at end of file