diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 3aae24f37..31bbeca10 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -41,6 +41,7 @@ 03CDCA6243F89B194E3FAD17 /* EncryptionAuthenticity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 955336CBD5ED73C792D1F580 /* EncryptionAuthenticity.swift */; }; 0437765FF480249486893CC7 /* ScreenTrackerViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 196004E7695FBA292A7944AF /* ScreenTrackerViewModifier.swift */; }; 044DD8F80231BC30570F7965 /* UserDiscoveryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65AAD845E53B0C8B5E0812C2 /* UserDiscoveryService.swift */; }; + 0499C34D0F8BF41D90CD9017 /* ConfigurableSettingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D1CF5F8B1A4842F384A4E0 /* ConfigurableSettingTests.swift */; }; 04F17DE71A50206336749BAC /* UserPreferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BA241DEEF7C8A7181C0AEDC9 /* UserPreferenceTests.swift */; }; 053B8BD2496207838878C6C9 /* PinnedItemsBannerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60C9BAE9F9436B14E4E22E8F /* PinnedItemsBannerView.swift */; }; 059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; }; @@ -77,6 +78,7 @@ 0AE0AB1952F186EB86719B4F /* HomeScreenRoomCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */; }; 0B05A35FF5D1ED9E8A0B41A7 /* AuthenticationStartScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65DDCF8E41759890355ACBC /* AuthenticationStartScreenViewModelProtocol.swift */; }; 0BAF83521871E69D222EE8E4 /* ClientBuilderHook.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AC0CD1CAFD3F8B057F9AEA5 /* ClientBuilderHook.swift */; }; + 0BC39401827AD84F617AD476 /* ConfigurableSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DAF51E93886BAFAE08CB565 /* ConfigurableSetting.swift */; }; 0BDA19079FD6E17C5AC62E22 /* RoomDetailsEditScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06F22CFA34885B40976061 /* RoomDetailsEditScreen.swift */; }; 0BE4D5CBF86956410F071F91 /* CreateRoomViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15A657D96779D1DEB8EF1327 /* CreateRoomViewModel.swift */; }; 0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */; }; @@ -112,7 +114,6 @@ 128FFD8A3D85845F9A927F47 /* PollRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF8548D48512127CCC17C520 /* PollRoomTimelineView.swift */; }; 12AF926E783E40BFB32A2D84 /* UserIdentityProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8536B40F578BA7FDB23D97B1 /* UserIdentityProxyMock.swift */; }; 12C867E85E6D12EEDFD0B127 /* CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */; }; - 12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; }; 12CD8B5CC30A05061228BF9E /* TimelineItemMenuActionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9E6065FC6BC4A1B4C629E08 /* TimelineItemMenuActionProvider.swift */; }; 12E6D052D055531A6783E21B /* portrait_test_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = BC51BF90469412ABDE658CDD /* portrait_test_image.jpg */; }; 12EC6BC99F373FE5C6EB9B64 /* TimelineMediaPreviewDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 467498BEA681758BE2F80826 /* TimelineMediaPreviewDetailsView.swift */; }; @@ -225,6 +226,7 @@ 28AB1614E749D1147A2AC6C2 /* CreateRoomScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2214C32EA81FA9168D923D4C /* CreateRoomScreenTests.swift */; }; 28E8C44DD6E39BEB2A1599C8 /* AccessibilityTestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CABD320DE5566D133890B24 /* AccessibilityTestsAppCoordinator.swift */; }; 292827744227DF61C930BDDB /* CreateRoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB0D6CB491777E7FC6B5BA12 /* CreateRoomScreen.swift */; }; + 2932570AA418974979D16DED /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E6DE144D887A254F4CAF203 /* UserPreference.swift */; }; 29491EE7AE37E239E839C5A3 /* LocationSharingScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BEBF0E59F25E842EDB6FD11 /* LocationSharingScreenModels.swift */; }; 2955F4C160CFD7794D819C64 /* EffectsScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 024F7398C5FC12586FB10E9D /* EffectsScene.swift */; }; 298F9EC30E918F12AB7F1EE8 /* TypingIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81F0325E252B057FAEEE1B2D /* TypingIndicatorView.swift */; }; @@ -248,6 +250,7 @@ 2C5E832434EE94E21AB3B238 /* EmojiPickerScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3EAE3E9D5EF4A6D5D9C6CFD /* EmojiPickerScreenViewModel.swift */; }; 2CA61BB208CD82EBDB58CD13 /* VideoRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED0CBEAB5F796BEFBAF7BB6A /* VideoRoomTimelineView.swift */; }; 2CA6ABBC9A88EB89EA52FCCB /* ConfettiScene.scn in Resources */ = {isa = PBXBuildFile; fileRef = B61C339A2FDDBD067FF6635C /* ConfettiScene.scn */; }; + 2CC3F27CD76DB00A747BEA6C /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; }; 2D0E3983288E2D35613AD681 /* SecureBackupControllerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AB29A2D95D3469B5F016655 /* SecureBackupControllerMock.swift */; }; 2D2D8A53B35BE8D8A01449C6 /* PinnedEventsBannerStateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA38E813BE14149F173F461 /* PinnedEventsBannerStateTests.swift */; }; 2D38D39B1789B91AE69F477F /* PhotoLibraryManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD955A0380C287C418F1A74D /* PhotoLibraryManagerMock.swift */; }; @@ -314,7 +317,6 @@ 3AA9E878FDCFF85664AC071F /* ComposerDraftService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D70253004A5AEC9C73D6A4F /* ComposerDraftService.swift */; }; 3B0F9B57D25B07E66F15762A /* MediaUploadPreviewScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E7C987AE5DC9087BB19F7D /* MediaUploadPreviewScreenModels.swift */; }; 3B277D9538090766DA6C4566 /* StateRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2AF1828A5B76B7C371240FE /* StateRoomTimelineView.swift */; }; - 3B28408450BCAED911283AA2 /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; }; 3B5AB5CF8D8163599C5BF19B /* PillViewOnBubblePreviews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2005B4AD70A792340E2694F1 /* PillViewOnBubblePreviews.swift */; }; 3B98049F56025726FB646ABD /* SwipeToReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B0E0B55E2EE75AF67029924 /* SwipeToReplyView.swift */; }; 3BEBDCB42BABFA3B456FECA7 /* MapTilerURLBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D262A26713C18BB70C82CA5 /* MapTilerURLBuilderTests.swift */; }; @@ -338,7 +340,6 @@ 3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; }; 401BB28CD6B7DD6B4E7863E7 /* ServerConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */; }; 407DCE030E0F9B7C9861D38A /* LoremSwiftum in Frameworks */ = {isa = PBXBuildFile; productRef = 1A6B622CCFDEFB92D9CF1CA5 /* LoremSwiftum */; }; - 40B79D20A873620F7F128A2C /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; }; 414F50CFCFEEE2611127DCFB /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; }; 41C5DA0C06F30311A221E85B /* ClientSDKMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EAF4A49F3ACD8BB8B0D2371 /* ClientSDKMock.swift */; }; 41CE5E1289C8768FC5B6490C /* RoomTimelineItemViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C2D52E36AD614B3C003EF6 /* RoomTimelineItemViewState.swift */; }; @@ -353,7 +354,6 @@ 42B084FDE621FBEE433AF444 /* LegalInformationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4176C3E20C772DE8D182863C /* LegalInformationScreen.swift */; }; 42F1C8731166633E35A6D7E6 /* RoomEventStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0A307A44F952CD73E63AE31 /* RoomEventStringBuilder.swift */; }; 432EA37BDC97CEDBAB7B23A6 /* RoomInfoProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14517E5597594956FCE1950D /* RoomInfoProxyProtocol.swift */; }; - 43F06DF42EC00B3CE2B020A4 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; }; 43F35A7E5703D64DB0519C59 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD469F7513574341181F7EAA /* ServerSelectionScreen.swift */; }; 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */; }; 441857143FC100E0A7DE42A8 /* RoomPowerLevelProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D635709C1D6D37C225AD40E /* RoomPowerLevelProxyProtocol.swift */; }; @@ -411,10 +411,10 @@ 4D2B54233C7B2C04B4ABE55A /* EncryptionSettingsFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB836DD8BE31931F51B8AC9 /* EncryptionSettingsFlowCoordinator.swift */; }; 4D4D236F0BBCDC4D2CBCCBB5 /* RoomChangePermissionsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = C729D95CB4588D4D9AAC3DFA /* RoomChangePermissionsScreenModels.swift */; }; 4D66CEBE490B2F118F4CEC8A /* EditRoomAddressScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBD21AF0131AA38FF9534FAD /* EditRoomAddressScreenModels.swift */; }; + 4D98B16B7FAECD465E8D7AB1 /* ConfigurableSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DAF51E93886BAFAE08CB565 /* ConfigurableSetting.swift */; }; 4DAEE2468669848B6C9F55B4 /* TimelineReadReceiptsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33035418BB35754232985871 /* TimelineReadReceiptsView.swift */; }; 4DEEFB73181C3B023DB42686 /* NetworkMonitorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1575947B7A6FE08C57FE5EE4 /* NetworkMonitorProtocol.swift */; }; 4E0D9E09B52CEC4C0E6211A8 /* MediaPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64F49FB9EE2913234F06CE68 /* MediaPickerScreenCoordinator.swift */; }; - 4E22086585CB3B35FEEFBBB9 /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35FA991289149D31F4286747 /* UserPreference.swift */; }; 4E36A66E0EDA74BF3A036FD0 /* RoomChangeRolesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */; }; 4E4EF97B9F9CEFAC726BA72F /* TimelineProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62EACAFB3F3E017060F9F1C5 /* TimelineProviderMock.swift */; }; 4E8A2A2CFEB212F14E49E1A1 /* AppLockSetupSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5484457C81B325660901B161 /* AppLockSetupSettingsScreen.swift */; }; @@ -546,6 +546,7 @@ 67EFF46180B939CBF389AECD /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93C713D124FE915ABF47A6B7 /* TimelineView.swift */; }; 6817EAD73DC1FFD8B943B5B9 /* HomeScreenRoomTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B73587C2E3CF5998361AE516 /* HomeScreenRoomTests.swift */; }; 68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; }; + 683154AD739245E56F37921E /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E6DE144D887A254F4CAF203 /* UserPreference.swift */; }; 6832733838C57A7D3FE8FEB5 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; }; 6851B077B4C913CC12DB6E77 /* AppLockFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FCE93F0CBF0D96B77111C413 /* AppLockFlowCoordinator.swift */; }; 68B2DD307C57ECFABBB05323 /* DeclineAndBlockScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127D1947BA9C6CA62E3D03EC /* DeclineAndBlockScreen.swift */; }; @@ -969,7 +970,6 @@ B855AF29D7D8FC8DAAA73D4A /* test_voice_message.m4a in Resources */ = {isa = PBXBuildFile; fileRef = DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */; }; B89990DD875B0B603D4D4332 /* NotificationItemProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B927CF5EF7FCCDA5EDC474B /* NotificationItemProxyProtocol.swift */; }; B8D9960F77B213FD1B0B0FD3 /* JoinRoomByAddressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A13364350970987B93F6018 /* JoinRoomByAddressView.swift */; }; - B8EC8A544162B0A41B9AB339 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; }; B93D7CE520088AD53FA6D53C /* SettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B663BE498BB39EADC24025D /* SettingsScreenModels.swift */; }; B93FA0DA1504B301CAEE141B /* NotificationSettingsProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6F5D66F158A6662F953733E /* NotificationSettingsProxy.swift */; }; B94368839BDB69172E28E245 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; }; @@ -1075,6 +1075,7 @@ CE3B7FC34FB2C279AAA5EA01 /* AVMetadataMachineReadableCodeObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3339B1DDB1341E833D2555BC /* AVMetadataMachineReadableCodeObject.swift */; }; CE4B342F9DD747CF4BEDB5AB /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43F773904F87FF5ADFE4DD1 /* TestablePreview.swift */; }; CE6F237360875D3D573FD0B2 /* RoomNotificationSettingsProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD6B522BD637845AB9570B10 /* RoomNotificationSettingsProxy.swift */; }; + CE86DC78D390F0C137BB9D18 /* ConfigurableSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DAF51E93886BAFAE08CB565 /* ConfigurableSetting.swift */; }; CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; }; CEAEA57B7665C8E790599A78 /* BlockedUsersScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 240610DF32F3213BEC5611D7 /* BlockedUsersScreenViewModelTests.swift */; }; CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; }; @@ -1086,6 +1087,7 @@ D02DEB36D32A72A1B365E452 /* SessionVerificationScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796CBD0C56FA0D3AEDAB255B /* SessionVerificationScreenCoordinator.swift */; }; D050D7756E92CA061ED0ABF0 /* SecureBackupLogoutConfirmationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74E08B8A66948E9690F38B94 /* SecureBackupLogoutConfirmationScreenViewModelProtocol.swift */; }; D0A965852D6C04138FA55181 /* SecureBackupLogoutConfirmationScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF239C619971FDE48132550 /* SecureBackupLogoutConfirmationScreenModels.swift */; }; + D104B27C5DA0626B41CE78D3 /* CurrentValuePublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 127C8472672A5BA09EF1ACF8 /* CurrentValuePublisher.swift */; }; D10BA4F041DC58580A440A32 /* RoomRolesAndPermissionsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B1DC3B3FB40A7F4AE9B7BF /* RoomRolesAndPermissionsScreen.swift */; }; D12F440F7973F1489F61389D /* NotificationSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */; }; D18B70975644C24F60656C0D /* KnockRequestProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07851F4EA81AA3339806A7B /* KnockRequestProxyProtocol.swift */; }; @@ -1096,6 +1098,7 @@ D26093BB80B69092B0E9AC7C /* PinnedItemsIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E66763BD54A3A1D9C6E6F2F1 /* PinnedItemsIndicatorView.swift */; }; D2825E013A8ECFB66D9A1DE6 /* RoomChangeRolesScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F841F219ACDFC1D3F42FEFB /* RoomChangeRolesScreenViewModelTests.swift */; }; D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; }; + D304343515CE0464C5089537 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; }; D31B34B3902BC597593F3ABB /* preview_image.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 200626E8353AB2729444F991 /* preview_image.jpg */; }; D33AC79A50DFC26D2498DD28 /* FileRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */; }; D34E328E9E65904358248FDD /* GlobalSearchScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 436A0D98D372B17EAE9AA999 /* GlobalSearchScreenModels.swift */; }; @@ -1152,6 +1155,7 @@ E184FFAD32342D3D6E2F89AA /* PinnedEventsTimelineScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D53754227CEBD06358956D7 /* PinnedEventsTimelineScreenCoordinator.swift */; }; E1A0752244567A25E376A2F4 /* AdvancedSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7A1B80FE6E3BA72F9C748AD /* AdvancedSettingsScreenViewModel.swift */; }; E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */; }; + E1DE8A5422643F759385290F /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD5523BDEDB247E29228476 /* AppSettings.swift */; }; E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; }; E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */; }; E26E702F325F0AA49B8A5CFD /* RoomPowerLevelsProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E944F717FC10A428D027074D /* RoomPowerLevelsProxyMock.swift */; }; @@ -1227,6 +1231,7 @@ EF0D0155DD104C7A41A2EB0E /* PlainMentionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AE78FA0011E07920AE83135 /* PlainMentionBuilder.swift */; }; EF47D802A404A53F15D5D4B6 /* JoinRoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CD7C0A2750998C2D77AD00F /* JoinRoomScreenViewModel.swift */; }; EF5009AC03212227131C8AF2 /* RoomNotificationSettingsProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E55B5EA766E89FF1F87C3ACB /* RoomNotificationSettingsProxyProtocol.swift */; }; + EF79B9EFD094C17FBB4942C2 /* UserPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5E6DE144D887A254F4CAF203 /* UserPreference.swift */; }; EF890DEF0479E66548F2BA23 /* AppLockTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 490BEADEFB2D6B7C9F618AE8 /* AppLockTimer.swift */; }; EFBBD44C0A16F017C32D2099 /* TimelineItemStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72614BFF35B8394C6E13F55A /* TimelineItemStatusView.swift */; }; F0570F1ECD70C4C851FB2052 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E7304F5ECB4CB11CB10E60 /* SecureBackupRecoveryKeyScreenViewModelProtocol.swift */; }; @@ -1428,6 +1433,7 @@ 046C0D3F53B0B5EF0A1F5BEA /* RoomSummaryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryTests.swift; sourceTree = ""; }; 048A21188AB19349D026BECD /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityIdentifiers.swift; sourceTree = ""; }; + 04D1CF5F8B1A4842F384A4E0 /* ConfigurableSettingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurableSettingTests.swift; sourceTree = ""; }; 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager.swift; sourceTree = ""; }; 0516C69708D5CBDE1A8E77EC /* RoomDirectorySearchProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDirectorySearchProxyProtocol.swift; sourceTree = ""; }; 052B2F924572AFD70B5F500E /* StartChatScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartChatScreenViewModel.swift; sourceTree = ""; }; @@ -1685,7 +1691,6 @@ 3558A15CFB934F9229301527 /* RestorationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RestorationToken.swift; sourceTree = ""; }; 35A057BA9BE0F079784CD061 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; - 35FA991289149D31F4286747 /* UserPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreference.swift; sourceTree = ""; }; 36DA824791172B9821EACBED /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; path = PrivacyInfo.xcprivacy; sourceTree = ""; }; 36FD673E24FBFCFDF398716A /* RoomMemberProxyMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberProxyMock.swift; sourceTree = ""; }; 37A63A59BFDDC494B1C20119 /* CallScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallScreenViewModel.swift; sourceTree = ""; }; @@ -1876,6 +1881,7 @@ 5D53754227CEBD06358956D7 /* PinnedEventsTimelineScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinnedEventsTimelineScreenCoordinator.swift; sourceTree = ""; }; 5DE8D25D6A91030175D52A20 /* RoomTimelineItemProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProperties.swift; sourceTree = ""; }; 5E33FD32BBC44D703C7AE4F9 /* TextBasedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextBasedRoomTimelineItem.swift; sourceTree = ""; }; + 5E6DE144D887A254F4CAF203 /* UserPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserPreference.swift; sourceTree = ""; }; 5E75948AA1FE1D1A7809931F /* AuthenticationServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProtocol.swift; sourceTree = ""; }; 5E9CBF577B9711CFBB4FA40D /* VoiceMessageRecordingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageRecordingView.swift; sourceTree = ""; }; 5EB2CAA266B921D128C35710 /* LegalInformationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenCoordinator.swift; sourceTree = ""; }; @@ -2008,6 +2014,7 @@ 7B849D2FF2CC12BA411A1651 /* CreateRoomModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomModels.swift; sourceTree = ""; }; 7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowCoordinatorProtocol.swift; sourceTree = ""; }; 7BBADF8010C813D905C172CE /* SecurityAndPrivacyScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityAndPrivacyScreenModels.swift; sourceTree = ""; }; + 7BD5523BDEDB247E29228476 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; 7C1AF829F12FDC99717082D9 /* RoomRolesAndPermissionsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsScreenViewModel.swift; sourceTree = ""; }; 7C28B70BEFD3676F11D5D51F /* RoomRolesAndPermissionsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomRolesAndPermissionsScreenCoordinator.swift; sourceTree = ""; }; 7C71B9802433F1B4252291BB /* IdentityConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenViewModelProtocol.swift; sourceTree = ""; }; @@ -2015,6 +2022,7 @@ 7D0CBC76C80E04345E11F2DB /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactoryProtocol.swift; sourceTree = ""; }; 7D39AF1F659923D77778511E /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sk; path = sk.lproj/InfoPlist.strings; sourceTree = ""; }; + 7DAF51E93886BAFAE08CB565 /* ConfigurableSetting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurableSetting.swift; sourceTree = ""; }; 7DC017C3CB6B0F7C63F460F2 /* SecureBackupLogoutConfirmationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureBackupLogoutConfirmationScreenViewModel.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 = ""; }; @@ -2248,7 +2256,6 @@ ABA4CF2F5B4F68D02E412004 /* ServerConfirmationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenViewModelProtocol.swift; sourceTree = ""; }; AC0275CEE9CA078B34028BDF /* AppLockScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLockScreenViewModelTests.swift; sourceTree = ""; }; AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = ""; }; - AC3F82523D6F48B926D6AF68 /* AppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppSettings.swift; sourceTree = ""; }; AC43313F21511C853D34544E /* SoftLogoutScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreenViewModelTests.swift; sourceTree = ""; }; AC4F10BDD56FA77FEC742333 /* VoiceMessageMediaManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VoiceMessageMediaManagerTests.swift; sourceTree = ""; }; AC5F5209279A752D98AAC4B2 /* CollapsibleFlowLayoutTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollapsibleFlowLayoutTests.swift; sourceTree = ""; }; @@ -4374,6 +4381,7 @@ CAD9547E47C58930E2CE8306 /* CallScreenViewModelTests.swift */, D5EA0312A6262484AA393AC9 /* CompletionSuggestionServiceTests.swift */, CA29952595B804DA221A0C1D /* ComposerToolbarViewModelTests.swift */, + 04D1CF5F8B1A4842F384A4E0 /* ConfigurableSettingTests.swift */, 69D42EE0102D2857933625DD /* CreateRoomViewModelTests.swift */, 3B5E97E9615A158C76B2AB77 /* DateTests.swift */, D77F75B3E9F99864048A422A /* DeactivateAccountScreenViewModelTests.swift */, @@ -5268,12 +5276,12 @@ CA89A2DD51B6BBE1DA55E263 /* Application.swift */, B53AC78E49A297AC1D72A7CF /* AppMediator.swift */, 05AF58372CA884A789EB9C5A /* AppMediatorProtocol.swift */, - AC3F82523D6F48B926D6AF68 /* AppSettings.swift */, B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */, 7B9FCA1CFD07B8CF9BD21266 /* FlowCoordinatorProtocol.swift */, 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */, B5D829FD8958376614504B18 /* TargetConfiguration.swift */, 780F74C73E826685A9DB289B /* Navigation */, + D64E20C9E4C486D5C764D7F3 /* Settings */, 703929219780FFABAC6380AA /* Windowing */, ); path = Application; @@ -5496,7 +5504,6 @@ FE5CD2993048222B64C45006 /* SDKListener.swift */, 4481799F455B3DA243BDA2AC /* ShareToMapsAppActivity.swift */, 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */, - 35FA991289149D31F4286747 /* UserPreference.swift */, 7431C962E314ADAE38B6D708 /* Analytics */, 9F7C2D63C42828D8931D5286 /* CollapsibleFlowLayout */, 349FE0C25B41C7AC9B7C623F /* EffectsScene */, @@ -5754,6 +5761,16 @@ path = RoomPollsHistoryScreen; sourceTree = ""; }; + D64E20C9E4C486D5C764D7F3 /* Settings */ = { + isa = PBXGroup; + children = ( + 7BD5523BDEDB247E29228476 /* AppSettings.swift */, + 7DAF51E93886BAFAE08CB565 /* ConfigurableSetting.swift */, + 5E6DE144D887A254F4CAF203 /* UserPreference.swift */, + ); + path = Settings; + sourceTree = ""; + }; D7117C32909844BCF5AF30BA /* AccessibilityTests */ = { isa = PBXGroup; children = ( @@ -6878,7 +6895,7 @@ buildActionMask = 2147483647; files = ( A2172B5A26976F9174228B8A /* AppHooks.swift in Sources */, - 43F06DF42EC00B3CE2B020A4 /* AppSettings.swift in Sources */, + E1DE8A5422643F759385290F /* AppSettings.swift in Sources */, F253AAB4C8F06208173C9C4A /* Assets.swift in Sources */, 484202C5D50983442D24D061 /* AttributedString.swift in Sources */, CDCA8A559E098503DDE29477 /* AttributedStringBuilder.swift in Sources */, @@ -6888,6 +6905,7 @@ 9295F1F5E04484E10780BCE8 /* CharacterSet.swift in Sources */, 238D561CA231339C6D4D06F3 /* ClientBuilder.swift in Sources */, 0BAF83521871E69D222EE8E4 /* ClientBuilderHook.swift in Sources */, + 0BC39401827AD84F617AD476 /* ConfigurableSetting.swift in Sources */, 211B5F524E851178EE549417 /* CurrentValuePublisher.swift in Sources */, B5618E3C948584E5C1F67033 /* DTHTMLElement+AttributedStringBuilder.swift in Sources */, 7CD05B18A432060E4770FBD8 /* DataProtectionManager.swift in Sources */, @@ -6943,7 +6961,7 @@ 06B55882911B4BF5B14E9851 /* URL.swift in Sources */, D98B5EE8C4F5A2CE84687AE8 /* UTType.swift in Sources */, 34357B287357BC0B9715DD51 /* UserAgentBuilder.swift in Sources */, - 3B28408450BCAED911283AA2 /* UserPreference.swift in Sources */, + 683154AD739245E56F37921E /* UserPreference.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6976,6 +6994,7 @@ B5321A1F5B26A0F3EC54909E /* CollapsibleFlowLayoutTests.swift in Sources */, 3A164187907DA43B7858F9EC /* CompletionSuggestionServiceTests.swift in Sources */, 0C932A5158C1D0604DFC5750 /* ComposerToolbarViewModelTests.swift in Sources */, + 0499C34D0F8BF41D90CD9017 /* ConfigurableSettingTests.swift in Sources */, D3FD96913D2B1AAA3149DAC7 /* CreateRoomViewModelTests.swift in Sources */, CD0088B763CD970CF1CBF8CB /* DateTests.swift in Sources */, 80F6C8EFCA4564B67F0D34B0 /* DeactivateAccountScreenViewModelTests.swift in Sources */, @@ -7097,8 +7116,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B8EC8A544162B0A41B9AB339 /* AppSettings.swift in Sources */, + 2CC3F27CD76DB00A747BEA6C /* AppSettings.swift in Sources */, 2F2906AE9BC3D0E79A6F98F8 /* Bundle.swift in Sources */, + CE86DC78D390F0C137BB9D18 /* ConfigurableSetting.swift in Sources */, + D104B27C5DA0626B41CE78D3 /* CurrentValuePublisher.swift in Sources */, F38D32C1B0232AAFE6A0822C /* ExtensionLogger.swift in Sources */, C022284E2774A5E1EF683B4D /* FileManager.swift in Sources */, 05FF0CD80EDAB3A7C0D4700A /* InfoPlistReader.swift in Sources */, @@ -7115,7 +7136,7 @@ 03BD83E8BDD23AE059802E0D /* UITestsScreenIdentifier.swift in Sources */, 26252AA9AED64010788F4C26 /* UIView.swift in Sources */, 66E9202BED03B5BB00E812A1 /* URL.swift in Sources */, - 4E22086585CB3B35FEEFBBB9 /* UserPreference.swift in Sources */, + EF79B9EFD094C17FBB4942C2 /* UserPreference.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -7202,7 +7223,7 @@ A36AD251013402EDBD666C75 /* AppMediatorMock.swift in Sources */, 4BBF6C8E3EFC944B55231B19 /* AppMediatorProtocol.swift in Sources */, 355B11D08CE0CEF97A813236 /* AppRoutes.swift in Sources */, - 12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */, + D304343515CE0464C5089537 /* AppSettings.swift in Sources */, 4EAC427267424192964B16B3 /* AppSettingsHook.swift in Sources */, 9462C62798F47E39DCC182D2 /* Application.swift in Sources */, 61A36B9BB2ADE36CEFF5E98C /* Array.swift in Sources */, @@ -7304,6 +7325,7 @@ 4A4110369DBB79E4A314F415 /* ComposerToolbarViewModelProtocol.swift in Sources */, 311868F5E65BA61AFA6CCC2C /* CompoundHook.swift in Sources */, A6B83EB78F025D21B6EBA90C /* CompoundIcon.swift in Sources */, + 4D98B16B7FAECD465E8D7AB1 /* ConfigurableSetting.swift in Sources */, EA6613B29BA671F39CE1B1D2 /* ConfirmationDialog.swift in Sources */, AC7AA215D60FBC307F984028 /* Consumable.swift in Sources */, C3522917C0C367C403429EEC /* CoordinatorProtocol.swift in Sources */, @@ -8016,7 +8038,7 @@ 9E838A62918E47BC72D6640D /* UserIndicatorPresenter.swift in Sources */, F7BC744FFA7FE248FAE7F570 /* UserIndicatorToastView.swift in Sources */, E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */, - 40B79D20A873620F7F128A2C /* UserPreference.swift in Sources */, + 2932570AA418974979D16DED /* UserPreference.swift in Sources */, 80DEA2A4B20F9E279EAE6B2B /* UserProfile+Mock.swift in Sources */, ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */, E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */, diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index f515eb12f..c1cdea1bb 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -18,6 +18,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg private let stateMachine: AppCoordinatorStateMachine private let navigationRootCoordinator: NavigationRootCoordinator private let userSessionStore: UserSessionStoreProtocol + private let targetConfiguration: Target.Configuration private let appMediator: AppMediator private let appSettings: AppSettings private let appDelegate: AppDelegate @@ -74,9 +75,9 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg let appSettings = appHooks.appSettingsHook.configure(AppSettings()) - Target.mainApp.configure(logLevel: appSettings.logLevel, - traceLogPacks: appSettings.traceLogPacks, - sentryURL: appSettings.bugReportSentryRustURL) + targetConfiguration = Target.mainApp.configure(logLevel: appSettings.logLevel, + traceLogPacks: appSettings.traceLogPacks, + sentryURL: appSettings.bugReportSentryRustURL) let appName = InfoPlistReader.main.bundleDisplayName let appVersion = InfoPlistReader.main.bundleShortVersionString @@ -372,7 +373,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg private static func setupServiceLocator(appSettings: AppSettings, appHooks: AppHooks) { ServiceLocator.shared.register(userIndicatorController: UserIndicatorController()) ServiceLocator.shared.register(appSettings: appSettings) - ServiceLocator.shared.register(bugReportService: BugReportService(rageshakeURL: appSettings.bugReportRageshakeURL, + ServiceLocator.shared.register(bugReportService: BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher, applicationID: appSettings.bugReportApplicationID, sdkGitSHA: sdkGitSha(), maxUploadSize: appSettings.bugReportMaxUploadSize, @@ -403,7 +404,7 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationFlowCoordinatorDeleg } } - // This could be removed once the adotpion of 25.06.x is widespread. + // This could be removed once the adoption of 25.06.x is widespread. private func performSettingsToAccountDataMigration(userSession: UserSessionProtocol) { guard let userDefaults = UserDefaults(suiteName: InfoPlistReader.main.appGroupIdentifier) else { return diff --git a/ElementX/Sources/Application/AppSettings.swift b/ElementX/Sources/Application/Settings/AppSettings.swift similarity index 98% rename from ElementX/Sources/Application/AppSettings.swift rename to ElementX/Sources/Application/Settings/AppSettings.swift index 1cc615ea2..c460163f7 100644 --- a/ElementX/Sources/Application/AppSettings.swift +++ b/ElementX/Sources/Application/Settings/AppSettings.swift @@ -65,7 +65,6 @@ final class AppSettings { } private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier - private static var remoteSuiteName = "\(InfoPlistReader.main.appGroupIdentifier).remote" /// UserDefaults to be used on reads and writes. private static var store: UserDefaults! = UserDefaults(suiteName: suiteName) @@ -252,8 +251,8 @@ final class AppSettings { var pusherProfileTag: String? // MARK: - Bug report - - let bugReportRageshakeURL: URL? = Secrets.rageshakeURL.map { URL(string: $0)! } // swiftlint:disable:this force_unwrapping + + let bugReportRageshakeURL: ConfigurableSetting = .init(Secrets.rageshakeURL.map { .url(URL(string: $0)!) } ?? .disabled) // swiftlint:disable:this force_unwrapping let bugReportSentryURL: URL? = Secrets.sentryDSN.map { URL(string: $0)! } // swiftlint:disable:this force_unwrapping let bugReportSentryRustURL: URL? = Secrets.sentryRustDSN.map { URL(string: $0)! } // swiftlint:disable:this force_unwrapping /// The name allocated by the bug report server diff --git a/ElementX/Sources/Application/Settings/ConfigurableSetting.swift b/ElementX/Sources/Application/Settings/ConfigurableSetting.swift new file mode 100644 index 000000000..fcd874cb2 --- /dev/null +++ b/ElementX/Sources/Application/Settings/ConfigurableSetting.swift @@ -0,0 +1,35 @@ +// +// Copyright 2025 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import Combine + +/// A setting that can be instantiated with an initial value, overridden and reset back again, +/// automatically publishing the changes for downstream subscribers to react to. +/// +/// Unlike ``UserPreference``, this type of setting isn't settable by the user, nor is the +/// override persisted between app launches. +struct ConfigurableSetting { + private let initialValue: T + private let subject: CurrentValueSubject + var publisher: CurrentValuePublisher { subject.asCurrentValuePublisher() } + var isOverridden: Bool { subject.value != initialValue } + + init(_ initialValue: T) { + self.initialValue = initialValue + subject = .init(initialValue) + } + + func override(_ value: T) { + subject.send(value) + } + + func reset() { + if isOverridden { + subject.send(initialValue) + } + } +} diff --git a/ElementX/Sources/Other/UserPreference.swift b/ElementX/Sources/Application/Settings/UserPreference.swift similarity index 100% rename from ElementX/Sources/Other/UserPreference.swift rename to ElementX/Sources/Application/Settings/UserPreference.swift diff --git a/ElementX/Sources/Application/TargetConfiguration.swift b/ElementX/Sources/Application/TargetConfiguration.swift index e1a5498dc..b1f338069 100644 --- a/ElementX/Sources/Application/TargetConfiguration.swift +++ b/ElementX/Sources/Application/TargetConfiguration.swift @@ -8,51 +8,42 @@ import Foundation import MatrixRustSDK -@MainActor enum Target: String { case mainApp = "elementx" case nse case shareExtension = "shareextension" case tests - private static var isConfigured = false - - func configure(logLevel: LogLevel, traceLogPacks: Set, sentryURL: URL?) { - guard !Self.isConfigured else { - return + var useLightweightTokioRuntime: Bool { + switch self { + case .mainApp: false + case .nse: true + case .shareExtension: true + case .tests: false } + } + + var logFilePrefix: String? { + switch self { + case .mainApp: nil + default: rawValue + } + } + + /// Configures the target with logging and an appropriate runtime. + /// + /// Returns a `Configuration` which should be stored to + /// a) detect whether the platform is already configured. + /// b) reconfigure the platform if necessary. + func configure(logLevel: LogLevel, traceLogPacks: Set, sentryURL: URL?) -> Configuration { + let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, + traceLogPacks: traceLogPacks, + currentTarget: rawValue, + filePrefix: logFilePrefix, + sentryURL: sentryURL) do { - switch self { - case .mainApp: - let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, - traceLogPacks: traceLogPacks, - currentTarget: rawValue, - filePrefix: nil, - sentryURL: sentryURL) - try initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: false) - case .nse: - let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, - traceLogPacks: traceLogPacks, - currentTarget: rawValue, - filePrefix: rawValue, - sentryURL: sentryURL) - try initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: true) - case .shareExtension: - let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, - traceLogPacks: traceLogPacks, - currentTarget: rawValue, - filePrefix: rawValue, - sentryURL: sentryURL) - try initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: true) - case .tests: - let tracingConfiguration = Tracing.buildConfiguration(logLevel: logLevel, - traceLogPacks: traceLogPacks, - currentTarget: rawValue, - filePrefix: rawValue, - sentryURL: sentryURL) - try initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: false) - } + try initPlatform(config: tracingConfiguration, useLightweightTokioRuntime: useLightweightTokioRuntime) } catch { fatalError("Failed configuring target \(self) with error: \(error)") } @@ -63,6 +54,14 @@ enum Target: String { MXLog.configure(currentTarget: rawValue) - Self.isConfigured = true + return Configuration(tracingConfiguration: tracingConfiguration) + } + + /// Represents the configuration that was applied by ``configure(logLevel:traceLogPacks:sentryURL:)``. + struct Configuration { + /// The configuration applied when calling ``configure(logLevel:traceLogPacks:sentryURL:)``. + /// + /// **Note:** This is immutable and won't be updated to reflect further changes. + let tracingConfiguration: TracingConfiguration } } diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 6ce4431e8..7b8a9819d 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -1995,47 +1995,6 @@ class BugReportServiceMock: BugReportServiceProtocol, @unchecked Sendable { var underlyingCrashedLastRun: Bool! var lastCrashEventID: String? - //MARK: - applyConfiguration - - var applyConfigurationUnderlyingCallsCount = 0 - var applyConfigurationCallsCount: Int { - get { - if Thread.isMainThread { - return applyConfigurationUnderlyingCallsCount - } else { - var returnValue: Int? = nil - DispatchQueue.main.sync { - returnValue = applyConfigurationUnderlyingCallsCount - } - - return returnValue! - } - } - set { - if Thread.isMainThread { - applyConfigurationUnderlyingCallsCount = newValue - } else { - DispatchQueue.main.sync { - applyConfigurationUnderlyingCallsCount = newValue - } - } - } - } - var applyConfigurationCalled: Bool { - return applyConfigurationCallsCount > 0 - } - var applyConfigurationReceivedConfiguration: RageshakeConfiguration? - var applyConfigurationReceivedInvocations: [RageshakeConfiguration] = [] - var applyConfigurationClosure: ((RageshakeConfiguration) -> Void)? - - func applyConfiguration(_ configuration: RageshakeConfiguration) { - applyConfigurationCallsCount += 1 - applyConfigurationReceivedConfiguration = configuration - DispatchQueue.main.async { - self.applyConfigurationReceivedInvocations.append(configuration) - } - applyConfigurationClosure?(configuration) - } //MARK: - submitBugReport var submitBugReportProgressListenerUnderlyingCallsCount = 0 diff --git a/ElementX/Sources/Screens/CallScreen/CallScreenViewModel.swift b/ElementX/Sources/Screens/CallScreen/CallScreenViewModel.swift index 166cafba3..184c6a964 100644 --- a/ElementX/Sources/Screens/CallScreen/CallScreenViewModel.swift +++ b/ElementX/Sources/Screens/CallScreen/CallScreenViewModel.swift @@ -185,13 +185,23 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol } // We only set the analytics configuration if analytics are enabled - let analyticsConfiguration = analyticsService.isEnabled ? ElementCallAnalyticsConfiguration(posthogAPIHost: appSettings.elementCallPosthogAPIHost, - posthogAPIKey: appSettings.elementCallPosthogAPIKey, - sentryDSN: appSettings.elementCallPosthogSentryDSN) : nil + let analyticsConfiguration: ElementCallAnalyticsConfiguration? = if analyticsService.isEnabled { + .init(posthogAPIHost: appSettings.elementCallPosthogAPIHost, + posthogAPIKey: appSettings.elementCallPosthogAPIKey, + sentryDSN: appSettings.elementCallPosthogSentryDSN) + } else { + nil + } + let rageshakeURL: String? = if case let .url(baseURL) = appSettings.bugReportRageshakeURL.publisher.value { + baseURL.absoluteString + } else { + nil + } + switch await widgetDriver.start(baseURL: baseURL, clientID: clientID, colorScheme: colorScheme, - rageshakeURL: appSettings.bugReportRageshakeURL?.absoluteString, + rageshakeURL: rageshakeURL, analyticsConfiguration: analyticsConfiguration) { case .success(let url): state.url = url diff --git a/ElementX/Sources/Services/BugReport/BugReportService.swift b/ElementX/Sources/Services/BugReport/BugReportService.swift index 83d333159..781a43d26 100644 --- a/ElementX/Sources/Services/BugReport/BugReportService.swift +++ b/ElementX/Sources/Services/BugReport/BugReportService.swift @@ -12,10 +12,7 @@ import Sentry import UIKit class BugReportService: NSObject, BugReportServiceProtocol { - /// The rageshake URL as provided in the init. - private let defaultRageshakeURL: URL? - /// The rageshake URL currently being used by the service. - private var rageshakeURL: URL? + private var rageshakeURL: RageshakeConfiguration private let applicationID: String private let sdkGitSHA: String private let maxUploadSize: Int @@ -25,23 +22,27 @@ class BugReportService: NSObject, BugReportServiceProtocol { private let progressSubject = PassthroughSubject() private var cancellables = Set() - var isEnabled: Bool { rageshakeURL != nil } + var isEnabled: Bool { rageshakeURL != .disabled } var lastCrashEventID: String? - init(rageshakeURL: URL?, + init(rageshakeURLPublisher: CurrentValuePublisher, applicationID: String, sdkGitSHA: String, maxUploadSize: Int, session: URLSession = .shared, appHooks: AppHooks) { - defaultRageshakeURL = rageshakeURL - self.rageshakeURL = rageshakeURL + rageshakeURL = rageshakeURLPublisher.value self.applicationID = applicationID self.sdkGitSHA = sdkGitSHA self.maxUploadSize = maxUploadSize self.session = session self.appHooks = appHooks + super.init() + + rageshakeURLPublisher + .weakAssign(to: \.rageshakeURL, on: self) + .store(in: &cancellables) } // MARK: - BugReportServiceProtocol @@ -50,21 +51,10 @@ class BugReportService: NSObject, BugReportServiceProtocol { SentrySDK.crashedLastRun } - func applyConfiguration(_ configuration: RageshakeConfiguration) { - switch configuration { - case .url(let url): - rageshakeURL = url - case .disabled: - rageshakeURL = nil - case .default: - rageshakeURL = defaultRageshakeURL - } - } - // swiftlint:disable:next cyclomatic_complexity func submitBugReport(_ bugReport: BugReport, progressListener: CurrentValueSubject) async -> Result { - guard let rageshakeURL else { + guard case let .url(rageshakeURL) = rageshakeURL else { fatalError("No bug report URL set, the screen should not be shown in this case.") } diff --git a/ElementX/Sources/Services/BugReport/BugReportServiceProtocol.swift b/ElementX/Sources/Services/BugReport/BugReportServiceProtocol.swift index cb05d2a56..b9a9dadd5 100644 --- a/ElementX/Sources/Services/BugReport/BugReportServiceProtocol.swift +++ b/ElementX/Sources/Services/BugReport/BugReportServiceProtocol.swift @@ -46,13 +46,11 @@ enum BugReportServiceError: LocalizedError { } } -enum RageshakeConfiguration { +enum RageshakeConfiguration: Equatable { /// Rageshakes should be sent to the provided URL case url(URL) /// Rageshakes are disabled. case disabled - /// No customisations are made, use the default configuration. - case `default` } // sourcery: AutoMockable @@ -62,8 +60,6 @@ protocol BugReportServiceProtocol: AnyObject { var lastCrashEventID: String? { get set } - func applyConfiguration(_ configuration: RageshakeConfiguration) - func submitBugReport(_ bugReport: BugReport, progressListener: CurrentValueSubject) async -> Result } diff --git a/NSE/Sources/NotificationServiceExtension.swift b/NSE/Sources/NotificationServiceExtension.swift index c92d3d5f6..cd9643401 100644 --- a/NSE/Sources/NotificationServiceExtension.swift +++ b/NSE/Sources/NotificationServiceExtension.swift @@ -28,12 +28,13 @@ import UserNotifications // notification. class NotificationServiceExtension: UNNotificationServiceExtension { + private static var targetConfiguration: Target.Configuration? private var notificationHandler: NotificationHandler? private let appHooks = AppHooks() private let settings: CommonSettingsProtocol = AppSettings() - + private let keychainController = KeychainController(service: .sessions, accessGroup: InfoPlistReader.main.keychainAccessGroupIdentifier) @@ -44,6 +45,14 @@ class NotificationServiceExtension: UNNotificationServiceExtension { MXLog.info("\(tag) deinit") } + override init() { + if Self.targetConfiguration == nil { + Self.targetConfiguration = Target.nse.configure(logLevel: settings.logLevel, + traceLogPacks: settings.traceLogPacks, + sentryURL: nil) + } + } + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { guard !DataProtectionManager.isDeviceLockedAfterReboot(containerURL: URL.appGroupContainerDirectory), @@ -63,17 +72,13 @@ class NotificationServiceExtension: UNNotificationServiceExtension { return contentHandler(request.content) } + MXLog.info("\(tag) #########################################") + + ExtensionLogger.logMemory(with: tag) + + MXLog.info("\(tag) Received payload: \(request.content.userInfo)") + Task { - await Target.nse.configure(logLevel: settings.logLevel, - traceLogPacks: settings.traceLogPacks, - sentryURL: nil) - - MXLog.info("\(tag) #########################################") - - ExtensionLogger.logMemory(with: tag) - - MXLog.info("\(tag) Received payload: \(request.content.userInfo)") - do { let userSession = try await NSEUserSession(credentials: credentials, roomID: roomID, diff --git a/NSE/SupportingFiles/target.yml b/NSE/SupportingFiles/target.yml index 97f4c2e2d..607768201 100644 --- a/NSE/SupportingFiles/target.yml +++ b/NSE/SupportingFiles/target.yml @@ -82,7 +82,7 @@ targets: - path: ../SupportingFiles - path: ../../ElementX/Sources/AppHooks/AppHooks.swift - path: ../../ElementX/Sources/AppHooks/Hooks/ClientBuilderHook.swift - - path: ../../ElementX/Sources/Application/AppSettings.swift + - path: ../../ElementX/Sources/Application/Settings - path: ../../ElementX/Sources/Application/TargetConfiguration.swift - path: ../../ElementX/Sources/Generated/Assets.swift - path: ../../ElementX/Sources/Generated/Strings.swift @@ -115,7 +115,6 @@ targets: - path: ../../ElementX/Sources/Other/SwiftUI/Views/PlaceholderAvatarImage.swift - path: ../../ElementX/Sources/Other/TestablePreview/TestablePreview.swift - path: ../../ElementX/Sources/Other/UserAgentBuilder.swift - - path: ../../ElementX/Sources/Other/UserPreference.swift - path: ../../ElementX/Sources/Services/ElementCall/ElementCallServiceConstants.swift - path: ../../ElementX/Sources/Services/Keychain/KeychainController.swift - path: ../../ElementX/Sources/Services/Keychain/KeychainControllerProtocol.swift diff --git a/ShareExtension/Sources/ShareExtensionViewController.swift b/ShareExtension/Sources/ShareExtensionViewController.swift index 39d5b3890..88461bc51 100644 --- a/ShareExtension/Sources/ShareExtensionViewController.swift +++ b/ShareExtension/Sources/ShareExtensionViewController.swift @@ -9,15 +9,18 @@ import IntentsUI import SwiftUI class ShareExtensionViewController: UIViewController { + private static var targetConfiguration: Target.Configuration? private let appSettings: CommonSettingsProtocol = AppSettings() private let hostingController = UIHostingController(rootView: ShareExtensionView()) override func viewDidLoad() { super.viewDidLoad() - Target.shareExtension.configure(logLevel: appSettings.logLevel, - traceLogPacks: appSettings.traceLogPacks, - sentryURL: nil) + if Self.targetConfiguration == nil { + Self.targetConfiguration = Target.shareExtension.configure(logLevel: appSettings.logLevel, + traceLogPacks: appSettings.traceLogPacks, + sentryURL: nil) + } addChild(hostingController) view.addMatchedSubview(hostingController.view) diff --git a/ShareExtension/SupportingFiles/target.yml b/ShareExtension/SupportingFiles/target.yml index e30f067bd..5a02cb125 100644 --- a/ShareExtension/SupportingFiles/target.yml +++ b/ShareExtension/SupportingFiles/target.yml @@ -79,7 +79,7 @@ targets: - path: ../Sources - path: ../SupportingFiles - path: ../../ElementX/Sources/ShareExtension - - path: ../../ElementX/Sources/Application/AppSettings.swift + - path: ../../ElementX/Sources/Application/Settings - path: ../../ElementX/Sources/Application/TargetConfiguration.swift - path: ../../ElementX/Sources/Other/Extensions/Bundle.swift - path: ../../ElementX/Sources/Other/Extensions/FileManager.swift @@ -88,6 +88,6 @@ targets: - path: ../../ElementX/Sources/Other/Extensions/UIView.swift - path: ../../ElementX/Sources/Other/Extensions/URL.swift - path: ../../ElementX/Sources/Other/InfoPlistReader.swift + - path: ../../ElementX/Sources/Other/CurrentValuePublisher.swift - path: ../../ElementX/Sources/Other/Logging - - path: ../../ElementX/Sources/Other/UserPreference.swift - path: ../../ElementX/Sources/UITests/UITestsScreenIdentifier.swift diff --git a/UnitTests/Sources/BugReportServiceTests.swift b/UnitTests/Sources/BugReportServiceTests.swift index a5a8b88fd..90d6daae7 100644 --- a/UnitTests/Sources/BugReportServiceTests.swift +++ b/UnitTests/Sources/BugReportServiceTests.swift @@ -12,14 +12,23 @@ import Foundation import XCTest class BugReportServiceTests: XCTestCase { + var appSettings: AppSettings! var bugReportService: BugReportServiceProtocol! override func setUpWithError() throws { + AppSettings.resetAllSettings() + appSettings = AppSettings() + appSettings.bugReportRageshakeURL.reset() + let bugReportServiceMock = BugReportServiceMock() bugReportServiceMock.underlyingCrashedLastRun = false bugReportServiceMock.submitBugReportProgressListenerReturnValue = .success(SubmitBugReportResponse(reportURL: "https://www.example.com/123")) bugReportService = bugReportServiceMock } + + override func tearDown() { + appSettings.bugReportRageshakeURL.reset() + } func testInitialStateWithMockService() { XCTAssertFalse(bugReportService.crashedLastRun) @@ -42,7 +51,8 @@ class BugReportServiceTests: XCTestCase { } func testInitialStateWithRealService() throws { - let service = BugReportService(rageshakeURL: "https://example.com/submit", + let urlPublisher: CurrentValueSubject = .init(.url("https://example.com/submit")) + let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), applicationID: "mock_app_id", sdkGitSHA: "1234", maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize, @@ -52,8 +62,9 @@ class BugReportServiceTests: XCTestCase { XCTAssertFalse(service.crashedLastRun) } - func testInitialStateWithRealServiceAndNoURL() throws { - let service = BugReportService(rageshakeURL: nil, + func testInitialStateWithRealServiceAndDisabled() throws { + let urlPublisher: CurrentValueSubject = .init(.disabled) + let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), applicationID: "mock_app_id", sdkGitSHA: "1234", maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize, @@ -64,7 +75,8 @@ class BugReportServiceTests: XCTestCase { } @MainActor func testSubmitBugReportWithRealService() async throws { - let service = BugReportService(rageshakeURL: "https://example.com/submit", + let urlPublisher: CurrentValueSubject = .init(.url("https://example.com/submit")) + let service = BugReportService(rageshakeURLPublisher: urlPublisher.asCurrentValuePublisher(), applicationID: "mock_app_id", sdkGitSHA: "1234", maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize, @@ -87,7 +99,12 @@ class BugReportServiceTests: XCTestCase { } @MainActor func testConfigurations() async throws { - let service = BugReportService(rageshakeURL: "https://example.com/submit", + guard case let .url(initialURL) = appSettings.bugReportRageshakeURL.publisher.value else { + XCTFail("Unexpected initial configuration.") + return + } + + let service = BugReportService(rageshakeURLPublisher: appSettings.bugReportRageshakeURL.publisher, applicationID: "mock_app_id", sdkGitSHA: "1234", maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize, @@ -95,10 +112,10 @@ class BugReportServiceTests: XCTestCase { appHooks: AppHooks()) XCTAssertTrue(service.isEnabled) - service.applyConfiguration(.disabled) + appSettings.bugReportRageshakeURL.override(.disabled) XCTAssertFalse(service.isEnabled) - service.applyConfiguration(.url("https://bugs.server.net/submit")) + appSettings.bugReportRageshakeURL.override(.url("https://bugs.server.net/submit")) XCTAssertTrue(service.isEnabled) let bugReport = BugReport(userID: "@mock:client.com", @@ -115,31 +132,12 @@ class BugReportServiceTests: XCTestCase { XCTAssertEqual(customConfigurationResponse.reportURL, "https://bugs.server.net/123") - service.applyConfiguration(.default) + appSettings.bugReportRageshakeURL.reset() XCTAssertTrue(service.isEnabled) let defaultConfigurationResponse = try await service.submitBugReport(bugReport, progressListener: progressSubject).get() - XCTAssertEqual(defaultConfigurationResponse.reportURL, "https://example.com/123") - } - - func testDisabledConfigurations() { - let service = BugReportService(rageshakeURL: nil, - applicationID: "mock_app_id", - sdkGitSHA: "1234", - maxUploadSize: ServiceLocator.shared.settings.bugReportMaxUploadSize, - session: .mock, - appHooks: AppHooks()) - XCTAssertFalse(service.isEnabled) - - service.applyConfiguration(.disabled) - XCTAssertFalse(service.isEnabled) - - service.applyConfiguration(.url("https://bugs.server.net/submit")) - XCTAssertTrue(service.isEnabled) - - service.applyConfiguration(.default) - XCTAssertFalse(service.isEnabled) + XCTAssertEqual(defaultConfigurationResponse.reportURL, initialURL.absoluteString.replacingOccurrences(of: "submit", with: "123")) } func testLogsMaxSize() { diff --git a/UnitTests/Sources/ConfigurableSettingTests.swift b/UnitTests/Sources/ConfigurableSettingTests.swift new file mode 100644 index 000000000..767622c8a --- /dev/null +++ b/UnitTests/Sources/ConfigurableSettingTests.swift @@ -0,0 +1,40 @@ +// +// Copyright 2023, 2024 New Vector Ltd. +// +// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial +// Please see LICENSE files in the repository root for full details. +// + +import XCTest + +@testable import ElementX + +class ConfigurableSettingTests: XCTestCase { + func testOverrideAndReset() { + let setting = ConfigurableSetting(0) + XCTAssertEqual(setting.publisher.value, 0) + + setting.override(1) + XCTAssertEqual(setting.publisher.value, 1) + + setting.override(2) + XCTAssertEqual(setting.publisher.value, 2) + + setting.reset() + XCTAssertEqual(setting.publisher.value, 0) + } + + func testOptionalOverride() { + let setting: ConfigurableSetting = .init("Hello") + XCTAssertEqual(setting.publisher.value, "Hello") + + setting.override("World") + XCTAssertEqual(setting.publisher.value, "World") + + setting.override(nil) + XCTAssertEqual(setting.publisher.value, nil) + + setting.reset() + XCTAssertEqual(setting.publisher.value, "Hello") + } +} diff --git a/UnitTests/Sources/LoggingTests.swift b/UnitTests/Sources/LoggingTests.swift index a4137a5dc..703cae36b 100644 --- a/UnitTests/Sources/LoggingTests.swift +++ b/UnitTests/Sources/LoggingTests.swift @@ -10,6 +10,8 @@ import XCTest class LoggingTests: XCTestCase { + static var targetConfiguration: Target.Configuration? + private enum Constants { static let genericFailure = "Test failed" } @@ -22,7 +24,9 @@ class LoggingTests: XCTestCase { let target = "tests" XCTAssertTrue(Tracing.logFiles.isEmpty) - await Target.tests.configure(logLevel: .info, traceLogPacks: [], sentryURL: nil) + if Self.targetConfiguration == nil { + Self.targetConfiguration = Target.tests.configure(logLevel: .info, traceLogPacks: [], sentryURL: nil) + } // There is something weird with Rust logging where the file writing handle doesn't // notice that the file it is writing to was deleted, so we can't run these checks @@ -175,7 +179,9 @@ class LoggingTests: XCTestCase { contentType: nil)) // When logging that value - await Target.tests.configure(logLevel: .info, traceLogPacks: [], sentryURL: nil) + if Self.targetConfiguration == nil { + Self.targetConfiguration = Target.tests.configure(logLevel: .info, traceLogPacks: [], sentryURL: nil) + } MXLog.info(textMessage) MXLog.info(noticeMessage)