mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-06 04:18:31 +00:00
New notifications section in settings (#1273)
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
167D00CAA13FAFB822298021 /* MediaProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */; };
|
167D00CAA13FAFB822298021 /* MediaProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62A81CCC2516D9CF9322DF01 /* MediaProviderTests.swift */; };
|
||||||
1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; };
|
1702981A8085BE4FB0EC001B /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = D33116993D54FADC0C721C1F /* Application.swift */; };
|
||||||
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
172E6E9A612ADCF10A62CF13 /* BugReportServiceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */; };
|
||||||
|
17780569FB41E9BAC60D4710 /* UNUserNotificationCenter+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E685274772980BDEFF6691E /* UNUserNotificationCenter+Settings.swift */; };
|
||||||
18867F4F1C8991EEC56EA932 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
|
18867F4F1C8991EEC56EA932 /* UTType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 897DF5E9A70CE05A632FC8AF /* UTType.swift */; };
|
||||||
1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; };
|
1950A80CD198BED283DFC2CE /* ClientProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2958E6D247AE2516BEEE8 /* ClientProxy.swift */; };
|
||||||
19FE025AE9BA2959B6589B0D /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */; };
|
19FE025AE9BA2959B6589B0D /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CC575D1895FA62591451A93 /* RoomMemberDetailsScreen.swift */; };
|
||||||
@@ -269,6 +270,7 @@
|
|||||||
664F77F02A57617A00FB9B24 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664F77EF2A57617A00FB9B24 /* XCTestCase.swift */; };
|
664F77F02A57617A00FB9B24 /* XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 664F77EF2A57617A00FB9B24 /* XCTestCase.swift */; };
|
||||||
6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */; };
|
6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */; };
|
||||||
67160204A8D362BB7D4AD259 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E16574C6F7F9FA1015A8C /* Search.swift */; };
|
67160204A8D362BB7D4AD259 /* Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 693E16574C6F7F9FA1015A8C /* Search.swift */; };
|
||||||
|
6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */; };
|
||||||
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
|
67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
|
||||||
67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = AD544C0FA48DFFB080920061 /* Collections */; };
|
67D6E0700A9C1E676F6231F8 /* Collections in Frameworks */ = {isa = PBXBuildFile; productRef = AD544C0FA48DFFB080920061 /* Collections */; };
|
||||||
68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
68184EF36396424FE19A727D /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
||||||
@@ -337,6 +339,7 @@
|
|||||||
7F08F4BC1312075E2B5EAEFA /* AuthenticationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */; };
|
7F08F4BC1312075E2B5EAEFA /* AuthenticationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */; };
|
||||||
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */; };
|
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */; };
|
||||||
7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */; };
|
7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */; };
|
||||||
|
7F7EA51A9A43125A8CB6AC90 /* NotificationSettingsScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46D560DDA3B20C82766ACFAD /* NotificationSettingsScreenViewModel.swift */; };
|
||||||
7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */; };
|
7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */; };
|
||||||
8024BE37156FF0A95A7A3465 /* AnalyticsPromptUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */; };
|
8024BE37156FF0A95A7A3465 /* AnalyticsPromptUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */; };
|
||||||
804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */; };
|
804C15D8ADE0EA7A5268F58A /* OverridableAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 648DD1C10E4957CB791FE0B8 /* OverridableAvatarImage.swift */; };
|
||||||
@@ -492,6 +495,7 @@
|
|||||||
AF19D65A9C60C6B2646F3210 /* RedactedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */; };
|
AF19D65A9C60C6B2646F3210 /* RedactedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */; };
|
||||||
AF2ABA2794E376B64104C964 /* MockSoftLogoutScreenState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5644919DB2022397D9D5825A /* MockSoftLogoutScreenState.swift */; };
|
AF2ABA2794E376B64104C964 /* MockSoftLogoutScreenState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5644919DB2022397D9D5825A /* MockSoftLogoutScreenState.swift */; };
|
||||||
AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */; };
|
AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */; };
|
||||||
|
AF4232E6F08C3DB86FFA9BBD /* NotificationSettingsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83BC0DC9A2DF2DD60F9B6E9 /* NotificationSettingsScreenUITests.swift */; };
|
||||||
AF8BFA37791E1756EE243E08 /* SettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8F0ED874DF8C9A51B0AB6F /* SettingsScreenCoordinator.swift */; };
|
AF8BFA37791E1756EE243E08 /* SettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B8F0ED874DF8C9A51B0AB6F /* SettingsScreenCoordinator.swift */; };
|
||||||
B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; };
|
B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; };
|
||||||
B064D42BA087649ACAE462E8 /* SoftLogoutUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55F30E764BED111C81739844 /* SoftLogoutUITests.swift */; };
|
B064D42BA087649ACAE462E8 /* SoftLogoutUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55F30E764BED111C81739844 /* SoftLogoutUITests.swift */; };
|
||||||
@@ -584,6 +588,7 @@
|
|||||||
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
|
CB6BCBF28E4B76EA08C2926D /* StateRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16048D30F0438731C41F775 /* StateRoomTimelineItem.swift */; };
|
||||||
CB99B0FA38A4AC596F38CC13 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; };
|
CB99B0FA38A4AC596F38CC13 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; };
|
||||||
CBA9EDF305036039166E76FF /* StartChatScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2AEC1AB349A341FE13DEC1 /* StartChatScreenUITests.swift */; };
|
CBA9EDF305036039166E76FF /* StartChatScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2AEC1AB349A341FE13DEC1 /* StartChatScreenUITests.swift */; };
|
||||||
|
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */; };
|
||||||
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */; };
|
CC0D088F505F33A20DC5590F /* RoomStateEventStringBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEEAFB646E583655652C3D04 /* RoomStateEventStringBuilderTests.swift */; };
|
||||||
CC961529F9F1854BEC3272C9 /* LayoutMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */; };
|
CC961529F9F1854BEC3272C9 /* LayoutMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC8AA23D4F37CC26564F63C5 /* LayoutMocks.swift */; };
|
||||||
CCAA0671B46EAFD0BB528E2C /* apple_emojis_data.json in Resources */ = {isa = PBXBuildFile; fileRef = 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */; };
|
CCAA0671B46EAFD0BB528E2C /* apple_emojis_data.json in Resources */ = {isa = PBXBuildFile; fileRef = 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */; };
|
||||||
@@ -598,6 +603,7 @@
|
|||||||
CF3827071B0BC9638BD44F5D /* WaitlistScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB58EF0176D4CFB1040DA22 /* WaitlistScreenViewModel.swift */; };
|
CF3827071B0BC9638BD44F5D /* WaitlistScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB58EF0176D4CFB1040DA22 /* WaitlistScreenViewModel.swift */; };
|
||||||
CF4044A8EED5C41BC0ED6ABE /* SoftLogoutScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D316BB02636AF2174F2580E6 /* SoftLogoutScreenViewModelProtocol.swift */; };
|
CF4044A8EED5C41BC0ED6ABE /* SoftLogoutScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D316BB02636AF2174F2580E6 /* SoftLogoutScreenViewModelProtocol.swift */; };
|
||||||
D02AA6208C7ACB9BE6332394 /* UNNotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */; };
|
D02AA6208C7ACB9BE6332394 /* UNNotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE148A4FFEE853C5A281500C /* UNNotificationContent.swift */; };
|
||||||
|
D12F440F7973F1489F61389D /* NotificationSettingsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */; };
|
||||||
D181AC8FF236B7F91C0A8C28 /* MapTiler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23AA3F4B285570805CB0CCDD /* MapTiler.swift */; };
|
D181AC8FF236B7F91C0A8C28 /* MapTiler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23AA3F4B285570805CB0CCDD /* MapTiler.swift */; };
|
||||||
D2A15D03F81342A09340BD56 /* AnalyticsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFEEE93B82937B2E86F92EB /* AnalyticsScreen.swift */; };
|
D2A15D03F81342A09340BD56 /* AnalyticsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEFEEE93B82937B2E86F92EB /* AnalyticsScreen.swift */; };
|
||||||
D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; };
|
D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; };
|
||||||
@@ -648,6 +654,7 @@
|
|||||||
E2DDA49BD62F03F180A42E30 /* MapLibreStaticMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 592A35163B0749C66BFD6186 /* MapLibreStaticMapView.swift */; };
|
E2DDA49BD62F03F180A42E30 /* MapLibreStaticMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 592A35163B0749C66BFD6186 /* MapLibreStaticMapView.swift */; };
|
||||||
E313BDD2B8813144139B2E00 /* UserDiscoveryServiceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0287793F11C480E242B03DF5 /* UserDiscoveryServiceTest.swift */; };
|
E313BDD2B8813144139B2E00 /* UserDiscoveryServiceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0287793F11C480E242B03DF5 /* UserDiscoveryServiceTest.swift */; };
|
||||||
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */; };
|
E3291AD16D7A5CB14781819C /* UserNotificationCenterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */; };
|
||||||
|
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */; };
|
||||||
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
|
E3CA565A4B9704F191B191F0 /* JoinedRoomSize+MemberCount.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBF9AEA706926DD0DA2B954C /* JoinedRoomSize+MemberCount.swift */; };
|
||||||
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
|
E3E1E255DC8CB34BD8573E0D /* UserIndicatorControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A12D3B1BCF920880CA8BBB6B /* UserIndicatorControllerProtocol.swift */; };
|
||||||
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
|
E45C9FA22BC13B477FD3B4AC /* EmojiDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D99730313BEBF08CDE81EE3 /* EmojiDetection.swift */; };
|
||||||
@@ -705,6 +712,7 @@
|
|||||||
F656F92A63D3DC1978D79427 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = 07FEEEDB11543A7DED420F04 /* Compound */; };
|
F656F92A63D3DC1978D79427 /* Compound in Frameworks */ = {isa = PBXBuildFile; productRef = 07FEEEDB11543A7DED420F04 /* Compound */; };
|
||||||
F692D4AF571333C0D785725A /* MigrationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBC5E7C0F8337D2A46EB2DD /* MigrationScreenViewModelProtocol.swift */; };
|
F692D4AF571333C0D785725A /* MigrationScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBBC5E7C0F8337D2A46EB2DD /* MigrationScreenViewModelProtocol.swift */; };
|
||||||
F697284B9B5F2C00CFEA3B12 /* EmojiDetectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E93D91DE3288010390DEE /* EmojiDetectionTests.swift */; };
|
F697284B9B5F2C00CFEA3B12 /* EmojiDetectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58E93D91DE3288010390DEE /* EmojiDetectionTests.swift */; };
|
||||||
|
F6DFA23885980118AD7359C5 /* NotificationSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2389732B0E115A999A069083 /* NotificationSettingsScreenCoordinator.swift */; };
|
||||||
F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */; };
|
F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */; };
|
||||||
F7567DD6635434E8C563BF85 /* AnalyticsClientProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */; };
|
F7567DD6635434E8C563BF85 /* AnalyticsClientProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */; };
|
||||||
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6E6EDC4BBF962B2ED595A4 /* MessageForwardingScreenViewModelTests.swift */; };
|
F777C6FEE7D106136E2ED2B2 /* MessageForwardingScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F6E6EDC4BBF962B2ED595A4 /* MessageForwardingScreenViewModelTests.swift */; };
|
||||||
@@ -822,6 +830,7 @@
|
|||||||
0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = "<group>"; };
|
0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = "<group>"; };
|
||||||
0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenUITests.swift; sourceTree = "<group>"; };
|
0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = "<group>"; };
|
0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DocumentPicker.swift; sourceTree = "<group>"; };
|
||||||
|
0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenCoordinator.swift; sourceTree = "<group>"; };
|
0FA60F848D1C14F873F9621A /* RoomMemberDetailsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
0FB782CE6176A5D2C082EC5D /* WelcomeScreenScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenModels.swift; sourceTree = "<group>"; };
|
0FB782CE6176A5D2C082EC5D /* WelcomeScreenScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenModels.swift; sourceTree = "<group>"; };
|
||||||
1059E2AE7878CF7820592637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
1059E2AE7878CF7820592637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
@@ -885,6 +894,7 @@
|
|||||||
225EFCA26877E75CDFE7F48D /* MapTilerStyleBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyleBuilderProtocol.swift; sourceTree = "<group>"; };
|
225EFCA26877E75CDFE7F48D /* MapTilerStyleBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerStyleBuilderProtocol.swift; sourceTree = "<group>"; };
|
||||||
22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
|
227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = "<group>"; };
|
||||||
|
2389732B0E115A999A069083 /* NotificationSettingsScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
23AA3F4B285570805CB0CCDD /* MapTiler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTiler.swift; sourceTree = "<group>"; };
|
23AA3F4B285570805CB0CCDD /* MapTiler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTiler.swift; sourceTree = "<group>"; };
|
||||||
24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenInvitesButton.swift; sourceTree = "<group>"; };
|
24227FF9A2797F6EA7F69CDD /* HomeScreenInvitesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenInvitesButton.swift; sourceTree = "<group>"; };
|
||||||
2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerTests.swift; sourceTree = "<group>"; };
|
2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorControllerTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -956,6 +966,7 @@
|
|||||||
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreenUITests.swift; sourceTree = "<group>"; };
|
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
4176C3E20C772DE8D182863C /* LegalInformationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreen.swift; sourceTree = "<group>"; };
|
4176C3E20C772DE8D182863C /* LegalInformationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreen.swift; sourceTree = "<group>"; };
|
||||||
421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItem.swift; sourceTree = "<group>"; };
|
421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
|
421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
422724361B6555364C43281E /* RoomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHeaderView.swift; sourceTree = "<group>"; };
|
422724361B6555364C43281E /* RoomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHeaderView.swift; sourceTree = "<group>"; };
|
||||||
42ADEA322D2089391E049535 /* InvitesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreen.swift; sourceTree = "<group>"; };
|
42ADEA322D2089391E049535 /* InvitesScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreen.swift; sourceTree = "<group>"; };
|
||||||
42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenModels.swift; sourceTree = "<group>"; };
|
42C64A14EE89928207E3B42B /* AnalyticsSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
@@ -970,6 +981,7 @@
|
|||||||
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreenModels.swift; sourceTree = "<group>"; };
|
||||||
46B59EC4B0C93254089EAACB /* MigrationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
46B59EC4B0C93254089EAACB /* MigrationScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MigrationScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
46C208DA43CE25D13E670F40 /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
46D560DDA3B20C82766ACFAD /* NotificationSettingsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
|
471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = "<group>"; };
|
47873756E45B46683D97DC32 /* LegalInformationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenModels.swift; sourceTree = "<group>"; };
|
||||||
@@ -998,6 +1010,7 @@
|
|||||||
505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelTests.swift; sourceTree = "<group>"; };
|
505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItem.swift; sourceTree = "<group>"; };
|
5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
50E31AB0E77BB70E2BC77463 /* MatrixUserShareLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixUserShareLink.swift; sourceTree = "<group>"; };
|
50E31AB0E77BB70E2BC77463 /* MatrixUserShareLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixUserShareLink.swift; sourceTree = "<group>"; };
|
||||||
|
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
51C2BCE0BC1FC69C1B36E688 /* BugReportScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenModels.swift; sourceTree = "<group>"; };
|
51C2BCE0BC1FC69C1B36E688 /* BugReportScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreenModels.swift; sourceTree = "<group>"; };
|
||||||
51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileProxy.swift; sourceTree = "<group>"; };
|
51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfileProxy.swift; sourceTree = "<group>"; };
|
||||||
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
52135BD9E0E7A091688F627A /* MessageForwardingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageForwardingScreenModels.swift; sourceTree = "<group>"; };
|
||||||
@@ -1189,6 +1202,7 @@
|
|||||||
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackCoordinatorTests.swift; sourceTree = "<group>"; };
|
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackCoordinatorTests.swift; sourceTree = "<group>"; };
|
||||||
9C7F7DE62D33C6A26CBFCD72 /* IntegrationTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
9C7F7DE62D33C6A26CBFCD72 /* IntegrationTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModel.swift; sourceTree = "<group>"; };
|
9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
9E685274772980BDEFF6691E /* UNUserNotificationCenter+Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UNUserNotificationCenter+Settings.swift"; sourceTree = "<group>"; };
|
||||||
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIConstants.swift; sourceTree = "<group>"; };
|
9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIConstants.swift; sourceTree = "<group>"; };
|
||||||
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
||||||
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
@@ -1262,6 +1276,7 @@
|
|||||||
B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsSignalling.swift; sourceTree = "<group>"; };
|
B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsSignalling.swift; sourceTree = "<group>"; };
|
||||||
B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = "<group>"; };
|
B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
B81B6170DB690013CEB646F4 /* MapLibreModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreModels.swift; sourceTree = "<group>"; };
|
B81B6170DB690013CEB646F4 /* MapLibreModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreModels.swift; sourceTree = "<group>"; };
|
||||||
|
B83BC0DC9A2DF2DD60F9B6E9 /* NotificationSettingsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = "<group>"; };
|
B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = "<group>"; };
|
||||||
B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = "<group>"; };
|
B8A3B7637DDBD6AA97AC2545 /* CameraPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraPicker.swift; sourceTree = "<group>"; };
|
||||||
B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = "<group>"; };
|
B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = "<group>"; };
|
||||||
@@ -1301,6 +1316,7 @@
|
|||||||
C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
|
C54464351F170D570110AFCA /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
|
||||||
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = "<group>"; };
|
||||||
C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenUITests.swift; sourceTree = "<group>"; };
|
C5B7A755E985FA14469E86B2 /* RoomMembersListScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMembersListScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
|
C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSettingsScreen.swift; sourceTree = "<group>"; };
|
||||||
C616D90B1E2F033CAA325439 /* StaticLocationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
C616D90B1E2F033CAA325439 /* StaticLocationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
C618CA2B6C8758B06C88013C /* CreateRoomCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomCoordinator.swift; sourceTree = "<group>"; };
|
C618CA2B6C8758B06C88013C /* CreateRoomCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateRoomCoordinator.swift; sourceTree = "<group>"; };
|
||||||
C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = "<group>"; };
|
C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -2326,6 +2342,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C830A64609CBD152F06E0457 /* NotificationConstants.swift */,
|
C830A64609CBD152F06E0457 /* NotificationConstants.swift */,
|
||||||
|
A9E072BD31B744FC34F4D368 /* Helper */,
|
||||||
6EE5E2BBFBC7947CFE789B4D /* Manager */,
|
6EE5E2BBFBC7947CFE789B4D /* Manager */,
|
||||||
832FC81F760220239E285294 /* Proxy */,
|
832FC81F760220239E285294 /* Proxy */,
|
||||||
);
|
);
|
||||||
@@ -2349,6 +2366,7 @@
|
|||||||
09C599CB430ABF160C1EE55C /* AnalyticsSettingsScreen */,
|
09C599CB430ABF160C1EE55C /* AnalyticsSettingsScreen */,
|
||||||
1CA6CD0DE6F0445156361B6D /* DeveloperOptionsScreen */,
|
1CA6CD0DE6F0445156361B6D /* DeveloperOptionsScreen */,
|
||||||
38A1C74493B816B8753F5BC2 /* LegalInformationScreen */,
|
38A1C74493B816B8753F5BC2 /* LegalInformationScreen */,
|
||||||
|
7B91CB64534AD870924CCFEF /* NotificationSettingsScreen */,
|
||||||
B364E08924AD15820350CDD9 /* SettingsScreen */,
|
B364E08924AD15820350CDD9 /* SettingsScreen */,
|
||||||
);
|
);
|
||||||
path = Settings;
|
path = Settings;
|
||||||
@@ -2420,6 +2438,7 @@
|
|||||||
F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */,
|
F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */,
|
||||||
78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */,
|
78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */,
|
||||||
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */,
|
9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */,
|
||||||
|
514363244AE7D68080D44C6F /* NotificationSettingsScreenViewModelTests.swift */,
|
||||||
00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */,
|
00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */,
|
||||||
6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */,
|
6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */,
|
||||||
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */,
|
086C19086DD16E9B38E25954 /* ReportContentViewModelTests.swift */,
|
||||||
@@ -2568,6 +2587,18 @@
|
|||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7B91CB64534AD870924CCFEF /* NotificationSettingsScreen */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2389732B0E115A999A069083 /* NotificationSettingsScreenCoordinator.swift */,
|
||||||
|
0F64447FF544298A6A3BEF85 /* NotificationSettingsScreenModels.swift */,
|
||||||
|
46D560DDA3B20C82766ACFAD /* NotificationSettingsScreenViewModel.swift */,
|
||||||
|
421FA93BCC2840E66E4F306F /* NotificationSettingsScreenViewModelProtocol.swift */,
|
||||||
|
BE7641A284D3E81DC96943E3 /* View */,
|
||||||
|
);
|
||||||
|
path = NotificationSettingsScreen;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7DBC911559934065993A5FF4 /* NotificationManager */ = {
|
7DBC911559934065993A5FF4 /* NotificationManager */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -2792,6 +2823,7 @@
|
|||||||
39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */,
|
39B6C8690AEA1E49FF1BAF95 /* MediaUploadPreviewScreenUITests.swift */,
|
||||||
59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */,
|
59846FA04E1DBBFDD8829C2A /* MessageForwardingScreenUITests.swift */,
|
||||||
75910F5A36EA8FF9BAD08D18 /* MigrationScreenUITests.swift */,
|
75910F5A36EA8FF9BAD08D18 /* MigrationScreenUITests.swift */,
|
||||||
|
B83BC0DC9A2DF2DD60F9B6E9 /* NotificationSettingsScreenUITests.swift */,
|
||||||
0C88046D6A070D9827181C4D /* OnboardingUITests.swift */,
|
0C88046D6A070D9827181C4D /* OnboardingUITests.swift */,
|
||||||
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */,
|
4132F882A984ED971338EE9D /* ReportContentScreenUITests.swift */,
|
||||||
122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */,
|
122186B7CD1BC46A9C629DD9 /* RoomDetailsEditScreenUITests.swift */,
|
||||||
@@ -2970,6 +3002,14 @@
|
|||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
A9E072BD31B744FC34F4D368 /* Helper */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9E685274772980BDEFF6691E /* UNUserNotificationCenter+Settings.swift */,
|
||||||
|
);
|
||||||
|
path = Helper;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
AAFDD509929A0CCF8BCE51EB /* Authentication */ = {
|
AAFDD509929A0CCF8BCE51EB /* Authentication */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -3131,6 +3171,14 @@
|
|||||||
path = ServerConfirmationScreen;
|
path = ServerConfirmationScreen;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
BE7641A284D3E81DC96943E3 /* View */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
C5F06F2F09B2EDD067DC2174 /* NotificationSettingsScreen.swift */,
|
||||||
|
);
|
||||||
|
path = View;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C0937E3B06A8F0E2DB7C8241 /* Other */ = {
|
C0937E3B06A8F0E2DB7C8241 /* Other */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -4037,6 +4085,7 @@
|
|||||||
69C7B956B74BEC3DB88224EA /* NavigationSplitCoordinatorTests.swift in Sources */,
|
69C7B956B74BEC3DB88224EA /* NavigationSplitCoordinatorTests.swift in Sources */,
|
||||||
4BB282209EA82015D0DF8F89 /* NavigationStackCoordinatorTests.swift in Sources */,
|
4BB282209EA82015D0DF8F89 /* NavigationStackCoordinatorTests.swift in Sources */,
|
||||||
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */,
|
1B2DADC008EE211AF1DA5292 /* NotificationManagerTests.swift in Sources */,
|
||||||
|
E3AC72E3E58F364EF15C1CC7 /* NotificationSettingsScreenViewModelTests.swift in Sources */,
|
||||||
F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */,
|
F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */,
|
||||||
27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */,
|
27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */,
|
||||||
D415764645491F10344FC6AC /* Publisher.swift in Sources */,
|
D415764645491F10344FC6AC /* Publisher.swift in Sources */,
|
||||||
@@ -4341,6 +4390,11 @@
|
|||||||
CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */,
|
CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */,
|
||||||
652ACCF104A8CEF30788963C /* NotificationManager.swift in Sources */,
|
652ACCF104A8CEF30788963C /* NotificationManager.swift in Sources */,
|
||||||
06D3942496E9E0E655F14D21 /* NotificationManagerProtocol.swift in Sources */,
|
06D3942496E9E0E655F14D21 /* NotificationManagerProtocol.swift in Sources */,
|
||||||
|
6786C4B0936AC84D993B20BF /* NotificationSettingsScreen.swift in Sources */,
|
||||||
|
F6DFA23885980118AD7359C5 /* NotificationSettingsScreenCoordinator.swift in Sources */,
|
||||||
|
D12F440F7973F1489F61389D /* NotificationSettingsScreenModels.swift in Sources */,
|
||||||
|
7F7EA51A9A43125A8CB6AC90 /* NotificationSettingsScreenViewModel.swift in Sources */,
|
||||||
|
CBD2ABE4C1A47ECD99E1488E /* NotificationSettingsScreenViewModelProtocol.swift in Sources */,
|
||||||
9A4E3D5AA44B041DAC3A0D81 /* OIDCAuthenticationPresenter.swift in Sources */,
|
9A4E3D5AA44B041DAC3A0D81 /* OIDCAuthenticationPresenter.swift in Sources */,
|
||||||
329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */,
|
329571083B132E4941131835 /* OnboardingBackgroundImage.swift in Sources */,
|
||||||
2CB6787E25B11711518E9588 /* OnboardingCoordinator.swift in Sources */,
|
2CB6787E25B11711518E9588 /* OnboardingCoordinator.swift in Sources */,
|
||||||
@@ -4530,6 +4584,7 @@
|
|||||||
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,
|
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */,
|
||||||
706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */,
|
706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */,
|
||||||
D02AA6208C7ACB9BE6332394 /* UNNotificationContent.swift in Sources */,
|
D02AA6208C7ACB9BE6332394 /* UNNotificationContent.swift in Sources */,
|
||||||
|
17780569FB41E9BAC60D4710 /* UNUserNotificationCenter+Settings.swift in Sources */,
|
||||||
071A017E415AD378F2961B11 /* URL.swift in Sources */,
|
071A017E415AD378F2961B11 /* URL.swift in Sources */,
|
||||||
90733645AE76FB33DAD28C2B /* URLSession.swift in Sources */,
|
90733645AE76FB33DAD28C2B /* URLSession.swift in Sources */,
|
||||||
18867F4F1C8991EEC56EA932 /* UTType.swift in Sources */,
|
18867F4F1C8991EEC56EA932 /* UTType.swift in Sources */,
|
||||||
@@ -4598,6 +4653,7 @@
|
|||||||
7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */,
|
7FB0BDE26838F1A92782D5E1 /* MediaUploadPreviewScreenUITests.swift in Sources */,
|
||||||
6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */,
|
6713835120D94BAA8ED7E3E5 /* MessageForwardingScreenUITests.swift in Sources */,
|
||||||
51C240F4660F7269203A9B3A /* MigrationScreenUITests.swift in Sources */,
|
51C240F4660F7269203A9B3A /* MigrationScreenUITests.swift in Sources */,
|
||||||
|
AF4232E6F08C3DB86FFA9BBD /* NotificationSettingsScreenUITests.swift in Sources */,
|
||||||
6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */,
|
6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */,
|
||||||
BA0D3DDCEDD97502DAC4B6E9 /* ReportContentScreenUITests.swift in Sources */,
|
BA0D3DDCEDD97502DAC4B6E9 /* ReportContentScreenUITests.swift in Sources */,
|
||||||
F16109A6F6DF03DA26D59233 /* RoomDetailsEditScreenUITests.swift in Sources */,
|
F16109A6F6DF03DA26D59233 /* RoomDetailsEditScreenUITests.swift in Sources */,
|
||||||
|
|||||||
@@ -133,12 +133,14 @@ class AppCoordinator: AppCoordinatorProtocol, AuthenticationCoordinatorDelegate,
|
|||||||
|
|
||||||
// MARK: - NotificationManagerDelegate
|
// MARK: - NotificationManagerDelegate
|
||||||
|
|
||||||
func authorizationStatusUpdated(_ service: NotificationManagerProtocol, granted: Bool) {
|
func registerForRemoteNotifications() {
|
||||||
if granted {
|
UIApplication.shared.registerForRemoteNotifications()
|
||||||
UIApplication.shared.registerForRemoteNotifications()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unregisterForRemoteNotifications() {
|
||||||
|
UIApplication.shared.unregisterForRemoteNotifications()
|
||||||
|
}
|
||||||
|
|
||||||
func shouldDisplayInAppNotification(_ service: NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
|
func shouldDisplayInAppNotification(_ service: NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
|
||||||
guard let roomId = content.roomID else {
|
guard let roomId = content.roomID else {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ final class AppSettings {
|
|||||||
case migratedAccounts
|
case migratedAccounts
|
||||||
case timelineStyle
|
case timelineStyle
|
||||||
case analyticsConsentState
|
case analyticsConsentState
|
||||||
|
case enableNotifications
|
||||||
case enableInAppNotifications
|
case enableInAppNotifications
|
||||||
case pusherProfileTag
|
case pusherProfileTag
|
||||||
case shouldCollapseRoomStateEvents
|
case shouldCollapseRoomStateEvents
|
||||||
@@ -34,6 +35,7 @@ final class AppSettings {
|
|||||||
case locationEventsEnabled
|
case locationEventsEnabled
|
||||||
case shareLocationEnabled
|
case shareLocationEnabled
|
||||||
case hasShownWelcomeScreen
|
case hasShownWelcomeScreen
|
||||||
|
case notificationSettingsEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||||
@@ -178,6 +180,9 @@ final class AppSettings {
|
|||||||
|
|
||||||
// MARK: - Notifications
|
// MARK: - Notifications
|
||||||
|
|
||||||
|
@UserPreference(key: UserDefaultsKeys.enableNotifications, defaultValue: true, storageType: .userDefaults(store))
|
||||||
|
var enableNotifications
|
||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.enableInAppNotifications, defaultValue: true, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.enableInAppNotifications, defaultValue: true, storageType: .userDefaults(store))
|
||||||
var enableInAppNotifications
|
var enableInAppNotifications
|
||||||
|
|
||||||
@@ -218,4 +223,7 @@ final class AppSettings {
|
|||||||
|
|
||||||
@UserPreference(key: UserDefaultsKeys.shareLocationEnabled, defaultValue: false, storageType: .userDefaults(store))
|
@UserPreference(key: UserDefaultsKeys.shareLocationEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
var shareLocationEnabled
|
var shareLocationEnabled
|
||||||
|
|
||||||
|
@UserPreference(key: UserDefaultsKeys.notificationSettingsEnabled, defaultValue: false, storageType: .userDefaults(store))
|
||||||
|
var notificationSettingsEnabled
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1317,4 +1317,86 @@ class UserIndicatorControllerMock: UserIndicatorControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
class UserNotificationCenterMock: UserNotificationCenterProtocol {
|
||||||
|
var delegate: UNUserNotificationCenterDelegate?
|
||||||
|
|
||||||
|
//MARK: - add
|
||||||
|
|
||||||
|
var addThrowableError: Error?
|
||||||
|
var addCallsCount = 0
|
||||||
|
var addCalled: Bool {
|
||||||
|
return addCallsCount > 0
|
||||||
|
}
|
||||||
|
var addReceivedRequest: UNNotificationRequest?
|
||||||
|
var addReceivedInvocations: [UNNotificationRequest] = []
|
||||||
|
var addClosure: ((UNNotificationRequest) async throws -> Void)?
|
||||||
|
|
||||||
|
func add(_ request: UNNotificationRequest) async throws {
|
||||||
|
if let error = addThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
addCallsCount += 1
|
||||||
|
addReceivedRequest = request
|
||||||
|
addReceivedInvocations.append(request)
|
||||||
|
try await addClosure?(request)
|
||||||
|
}
|
||||||
|
//MARK: - requestAuthorization
|
||||||
|
|
||||||
|
var requestAuthorizationOptionsThrowableError: Error?
|
||||||
|
var requestAuthorizationOptionsCallsCount = 0
|
||||||
|
var requestAuthorizationOptionsCalled: Bool {
|
||||||
|
return requestAuthorizationOptionsCallsCount > 0
|
||||||
|
}
|
||||||
|
var requestAuthorizationOptionsReceivedOptions: UNAuthorizationOptions?
|
||||||
|
var requestAuthorizationOptionsReceivedInvocations: [UNAuthorizationOptions] = []
|
||||||
|
var requestAuthorizationOptionsReturnValue: Bool!
|
||||||
|
var requestAuthorizationOptionsClosure: ((UNAuthorizationOptions) async throws -> Bool)?
|
||||||
|
|
||||||
|
func requestAuthorization(options: UNAuthorizationOptions) async throws -> Bool {
|
||||||
|
if let error = requestAuthorizationOptionsThrowableError {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
requestAuthorizationOptionsCallsCount += 1
|
||||||
|
requestAuthorizationOptionsReceivedOptions = options
|
||||||
|
requestAuthorizationOptionsReceivedInvocations.append(options)
|
||||||
|
if let requestAuthorizationOptionsClosure = requestAuthorizationOptionsClosure {
|
||||||
|
return try await requestAuthorizationOptionsClosure(options)
|
||||||
|
} else {
|
||||||
|
return requestAuthorizationOptionsReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//MARK: - setNotificationCategories
|
||||||
|
|
||||||
|
var setNotificationCategoriesCallsCount = 0
|
||||||
|
var setNotificationCategoriesCalled: Bool {
|
||||||
|
return setNotificationCategoriesCallsCount > 0
|
||||||
|
}
|
||||||
|
var setNotificationCategoriesReceivedCategories: Set<UNNotificationCategory>?
|
||||||
|
var setNotificationCategoriesReceivedInvocations: [Set<UNNotificationCategory>] = []
|
||||||
|
var setNotificationCategoriesClosure: ((Set<UNNotificationCategory>) -> Void)?
|
||||||
|
|
||||||
|
func setNotificationCategories(_ categories: Set<UNNotificationCategory>) {
|
||||||
|
setNotificationCategoriesCallsCount += 1
|
||||||
|
setNotificationCategoriesReceivedCategories = categories
|
||||||
|
setNotificationCategoriesReceivedInvocations.append(categories)
|
||||||
|
setNotificationCategoriesClosure?(categories)
|
||||||
|
}
|
||||||
|
//MARK: - authorizationStatus
|
||||||
|
|
||||||
|
var authorizationStatusCallsCount = 0
|
||||||
|
var authorizationStatusCalled: Bool {
|
||||||
|
return authorizationStatusCallsCount > 0
|
||||||
|
}
|
||||||
|
var authorizationStatusReturnValue: UNAuthorizationStatus!
|
||||||
|
var authorizationStatusClosure: (() async -> UNAuthorizationStatus)?
|
||||||
|
|
||||||
|
func authorizationStatus() async -> UNAuthorizationStatus {
|
||||||
|
authorizationStatusCallsCount += 1
|
||||||
|
if let authorizationStatusClosure = authorizationStatusClosure {
|
||||||
|
return await authorizationStatusClosure()
|
||||||
|
} else {
|
||||||
|
return authorizationStatusReturnValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// swiftlint:enable all
|
// swiftlint:enable all
|
||||||
|
|||||||
+2
@@ -31,6 +31,7 @@ struct DeveloperOptionsScreenViewStateBindings {
|
|||||||
var isEncryptionSyncEnabled: Bool
|
var isEncryptionSyncEnabled: Bool
|
||||||
var locationEventsEnabled: Bool
|
var locationEventsEnabled: Bool
|
||||||
var shareLocationEnabled: Bool
|
var shareLocationEnabled: Bool
|
||||||
|
var notificationSettingsEnabled: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DeveloperOptionsScreenViewAction {
|
enum DeveloperOptionsScreenViewAction {
|
||||||
@@ -40,5 +41,6 @@ enum DeveloperOptionsScreenViewAction {
|
|||||||
case changedIsEncryptionSyncEnabled
|
case changedIsEncryptionSyncEnabled
|
||||||
case changedLocationEventsEnabled
|
case changedLocationEventsEnabled
|
||||||
case changedShareLocationEnabled
|
case changedShareLocationEnabled
|
||||||
|
case changedNotificationSettingsEnabled
|
||||||
case clearCache
|
case clearCache
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -31,7 +31,8 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
|||||||
readReceiptsEnabled: appSettings.readReceiptsEnabled,
|
readReceiptsEnabled: appSettings.readReceiptsEnabled,
|
||||||
isEncryptionSyncEnabled: appSettings.isEncryptionSyncEnabled,
|
isEncryptionSyncEnabled: appSettings.isEncryptionSyncEnabled,
|
||||||
locationEventsEnabled: appSettings.locationEventsEnabled,
|
locationEventsEnabled: appSettings.locationEventsEnabled,
|
||||||
shareLocationEnabled: appSettings.shareLocationEnabled)
|
shareLocationEnabled: appSettings.shareLocationEnabled,
|
||||||
|
notificationSettingsEnabled: appSettings.notificationSettingsEnabled)
|
||||||
let state = DeveloperOptionsScreenViewState(bindings: bindings)
|
let state = DeveloperOptionsScreenViewState(bindings: bindings)
|
||||||
|
|
||||||
super.init(initialViewState: state)
|
super.init(initialViewState: state)
|
||||||
@@ -55,6 +56,8 @@ class DeveloperOptionsScreenViewModel: DeveloperOptionsScreenViewModelType, Deve
|
|||||||
appSettings.locationEventsEnabled = state.bindings.locationEventsEnabled
|
appSettings.locationEventsEnabled = state.bindings.locationEventsEnabled
|
||||||
case .changedShareLocationEnabled:
|
case .changedShareLocationEnabled:
|
||||||
appSettings.shareLocationEnabled = state.bindings.shareLocationEnabled
|
appSettings.shareLocationEnabled = state.bindings.shareLocationEnabled
|
||||||
|
case .changedNotificationSettingsEnabled:
|
||||||
|
appSettings.notificationSettingsEnabled = state.bindings.notificationSettingsEnabled
|
||||||
case .clearCache:
|
case .clearCache:
|
||||||
callback?(.clearCache)
|
callback?(.clearCache)
|
||||||
}
|
}
|
||||||
|
|||||||
+7
@@ -66,6 +66,13 @@ struct DeveloperOptionsScreen: View {
|
|||||||
.onChange(of: context.shareLocationEnabled) { _ in
|
.onChange(of: context.shareLocationEnabled) { _ in
|
||||||
context.send(viewAction: .changedShareLocationEnabled)
|
context.send(viewAction: .changedShareLocationEnabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Toggle(isOn: $context.notificationSettingsEnabled) {
|
||||||
|
Text("Show notification settings")
|
||||||
|
}
|
||||||
|
.onChange(of: context.notificationSettingsEnabled) { _ in
|
||||||
|
context.send(viewAction: .changedNotificationSettingsEnabled)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section {
|
Section {
|
||||||
|
|||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
//
|
||||||
|
// 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 Combine
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct NotificationSettingsScreenCoordinatorParameters {
|
||||||
|
let userNotificationCenter: UserNotificationCenterProtocol
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NotificationSettingsScreenCoordinatorAction { }
|
||||||
|
|
||||||
|
final class NotificationSettingsScreenCoordinator: CoordinatorProtocol {
|
||||||
|
private let parameters: NotificationSettingsScreenCoordinatorParameters
|
||||||
|
private var viewModel: NotificationSettingsScreenViewModelProtocol
|
||||||
|
private let actionsSubject: PassthroughSubject<NotificationSettingsScreenCoordinatorAction, Never> = .init()
|
||||||
|
private var cancellables: Set<AnyCancellable> = .init()
|
||||||
|
|
||||||
|
var actions: AnyPublisher<NotificationSettingsScreenCoordinatorAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(parameters: NotificationSettingsScreenCoordinatorParameters) {
|
||||||
|
self.parameters = parameters
|
||||||
|
|
||||||
|
viewModel = NotificationSettingsScreenViewModel(appSettings: ServiceLocator.shared.settings,
|
||||||
|
userNotificationCenter: parameters.userNotificationCenter)
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() { }
|
||||||
|
|
||||||
|
func toPresentable() -> AnyView {
|
||||||
|
AnyView(NotificationSettingsScreen(context: viewModel.context))
|
||||||
|
}
|
||||||
|
}
|
||||||
+53
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
enum NotificationSettingsScreenViewModelAction { }
|
||||||
|
|
||||||
|
struct NotificationSettingsScreenViewState: BindableState {
|
||||||
|
var bindings: NotificationSettingsScreenViewStateBindings
|
||||||
|
var strings = NotificationSettingsScreenStrings()
|
||||||
|
var isUserPermissionGranted: Bool?
|
||||||
|
|
||||||
|
var showSystemNotificationsAlert: Bool {
|
||||||
|
bindings.enableNotifications && isUserPermissionGranted == false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NotificationSettingsScreenViewStateBindings {
|
||||||
|
var enableNotifications = false
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NotificationSettingsScreenStrings {
|
||||||
|
let changeYourSystemSettings: AttributedString = {
|
||||||
|
let linkPlaceholder = "{link}"
|
||||||
|
var text = AttributedString(L10n.screenNotificationSettingsSystemNotificationsActionRequired(linkPlaceholder))
|
||||||
|
var linkString = AttributedString(L10n.screenNotificationSettingsSystemNotificationsActionRequiredContentLink)
|
||||||
|
// Note: On the simulator, `UIApplication.openNotificationSettingsURLString` opens the `Settings` application instead of the application's notification settings screen.
|
||||||
|
linkString.link = URL(string: UIApplication.openNotificationSettingsURLString)
|
||||||
|
linkString.bold()
|
||||||
|
text.replace(linkPlaceholder, with: linkString)
|
||||||
|
|
||||||
|
return text
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
enum NotificationSettingsScreenViewAction {
|
||||||
|
case linkClicked(url: URL)
|
||||||
|
case changedEnableNotifications
|
||||||
|
}
|
||||||
+76
@@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// 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 Combine
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
typealias NotificationSettingsScreenViewModelType = StateStoreViewModel<NotificationSettingsScreenViewState, NotificationSettingsScreenViewAction>
|
||||||
|
|
||||||
|
class NotificationSettingsScreenViewModel: NotificationSettingsScreenViewModelType, NotificationSettingsScreenViewModelProtocol {
|
||||||
|
private var actionsSubject: PassthroughSubject<NotificationSettingsScreenViewModelAction, Never> = .init()
|
||||||
|
private let appSettings: AppSettings
|
||||||
|
private let userNotificationCenter: UserNotificationCenterProtocol
|
||||||
|
|
||||||
|
var actions: AnyPublisher<NotificationSettingsScreenViewModelAction, Never> {
|
||||||
|
actionsSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(appSettings: AppSettings, userNotificationCenter: UserNotificationCenterProtocol) {
|
||||||
|
self.appSettings = appSettings
|
||||||
|
self.userNotificationCenter = userNotificationCenter
|
||||||
|
let bindings = NotificationSettingsScreenViewStateBindings(enableNotifications: appSettings.enableNotifications)
|
||||||
|
super.init(initialViewState: NotificationSettingsScreenViewState(bindings: bindings))
|
||||||
|
|
||||||
|
// Listen for changes to AppSettings.enableNotifications
|
||||||
|
appSettings.$enableNotifications
|
||||||
|
.weakAssign(to: \.state.bindings.enableNotifications, on: self)
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
// Refresh authorization status uppon UIApplication.didBecomeActiveNotification notification
|
||||||
|
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
|
||||||
|
.sink { [weak self] _ in
|
||||||
|
Task {
|
||||||
|
await self?.readSystemAuthorizationStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
Task {
|
||||||
|
await readSystemAuthorizationStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
override func process(viewAction: NotificationSettingsScreenViewAction) {
|
||||||
|
switch viewAction {
|
||||||
|
case .linkClicked(let url):
|
||||||
|
MXLog.warning("Link clicked: \(url)")
|
||||||
|
case .changedEnableNotifications:
|
||||||
|
toggleNotifications()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
func readSystemAuthorizationStatus() async {
|
||||||
|
state.isUserPermissionGranted = await userNotificationCenter.authorizationStatus() == .authorized
|
||||||
|
}
|
||||||
|
|
||||||
|
func toggleNotifications() {
|
||||||
|
appSettings.enableNotifications.toggle()
|
||||||
|
}
|
||||||
|
}
|
||||||
+23
@@ -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 Combine
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
protocol NotificationSettingsScreenViewModelProtocol {
|
||||||
|
var actions: AnyPublisher<NotificationSettingsScreenViewModelAction, Never> { get }
|
||||||
|
var context: NotificationSettingsScreenViewModelType.Context { get }
|
||||||
|
}
|
||||||
+88
@@ -0,0 +1,88 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
struct NotificationSettingsScreen: View {
|
||||||
|
@ObservedObject var context: NotificationSettingsScreenViewModel.Context
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
Form {
|
||||||
|
if context.viewState.showSystemNotificationsAlert {
|
||||||
|
userPermissionSection
|
||||||
|
}
|
||||||
|
enableNotificationSection
|
||||||
|
}
|
||||||
|
.compoundForm()
|
||||||
|
.navigationTitle(L10n.screenNotificationSettingsTitle)
|
||||||
|
.track(screen: .settingsNotifications)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private var userPermissionSection: some View {
|
||||||
|
Section {
|
||||||
|
HStack(alignment: .firstTextBaseline, spacing: 13) {
|
||||||
|
Image(systemName: "exclamationmark.circle.fill")
|
||||||
|
.foregroundColor(.compound.iconTertiaryAlpha)
|
||||||
|
VStack(alignment: .leading, spacing: 2) {
|
||||||
|
Text(L10n.screenNotificationSettingsSystemNotificationsTurnedOff)
|
||||||
|
.font(.compound.bodyLG)
|
||||||
|
.foregroundColor(.compound.textPrimary)
|
||||||
|
Text(context.viewState.strings.changeYourSystemSettings)
|
||||||
|
.font(.compound.bodySM)
|
||||||
|
.foregroundColor(.compound.textSecondary)
|
||||||
|
.tint(.compound.textPrimary)
|
||||||
|
.environment(\.openURL, OpenURLAction { url in
|
||||||
|
context.send(viewAction: .linkClicked(url: url))
|
||||||
|
return .systemAction
|
||||||
|
})
|
||||||
|
}
|
||||||
|
.padding(.vertical, 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.compoundFormSection()
|
||||||
|
}
|
||||||
|
|
||||||
|
private var enableNotificationSection: some View {
|
||||||
|
Section {
|
||||||
|
Toggle(isOn: $context.enableNotifications) {
|
||||||
|
Text(L10n.screenNotificationSettingsEnableNotifications)
|
||||||
|
}
|
||||||
|
.toggleStyle(.compoundForm)
|
||||||
|
.onChange(of: context.enableNotifications) { _ in
|
||||||
|
context.send(viewAction: .changedEnableNotifications)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.compoundFormSection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Previews
|
||||||
|
|
||||||
|
struct NotificationSettingsScreen_Previews: PreviewProvider {
|
||||||
|
static let viewModel: NotificationSettingsScreenViewModel = {
|
||||||
|
let appSettings = AppSettings()
|
||||||
|
let notificationCenter = UserNotificationCenterMock()
|
||||||
|
notificationCenter.authorizationStatusReturnValue = .notDetermined
|
||||||
|
var viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings, userNotificationCenter: notificationCenter)
|
||||||
|
return viewModel
|
||||||
|
}()
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
NotificationSettingsScreen(context: viewModel.context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -59,6 +59,8 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
self.presentDeveloperOptions()
|
self.presentDeveloperOptions()
|
||||||
case .logout:
|
case .logout:
|
||||||
self.callback?(.logout)
|
self.callback?(.logout)
|
||||||
|
case .notifications:
|
||||||
|
self.presentNotificationSettings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,4 +138,12 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
|||||||
private func showSuccess(label: String) {
|
private func showSuccess(label: String) {
|
||||||
parameters.userIndicatorController?.submitIndicator(UserIndicator(title: label))
|
parameters.userIndicatorController?.submitIndicator(UserIndicator(title: label))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func presentNotificationSettings() {
|
||||||
|
let notificationParameters = NotificationSettingsScreenCoordinatorParameters(
|
||||||
|
userNotificationCenter: UNUserNotificationCenter.current()
|
||||||
|
)
|
||||||
|
let coordinator = NotificationSettingsScreenCoordinator(parameters: notificationParameters)
|
||||||
|
parameters.navigationStackCoordinator?.push(coordinator)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ enum SettingsScreenViewModelAction {
|
|||||||
case about
|
case about
|
||||||
case sessionVerification
|
case sessionVerification
|
||||||
case developerOptions
|
case developerOptions
|
||||||
|
case notifications
|
||||||
case logout
|
case logout
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ struct SettingsScreenViewState: BindableState {
|
|||||||
var userAvatarURL: URL?
|
var userAvatarURL: URL?
|
||||||
var userDisplayName: String?
|
var userDisplayName: String?
|
||||||
var showSessionVerificationSection: Bool
|
var showSessionVerificationSection: Bool
|
||||||
|
var showNotificationSettings: Bool
|
||||||
var showDeveloperOptions: Bool
|
var showDeveloperOptions: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,4 +52,5 @@ enum SettingsScreenViewAction {
|
|||||||
case logout
|
case logout
|
||||||
case changedTimelineStyle
|
case changedTimelineStyle
|
||||||
case developerOptions
|
case developerOptions
|
||||||
|
case notifications
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
deviceID: userSession.deviceID,
|
deviceID: userSession.deviceID,
|
||||||
userID: userSession.userID,
|
userID: userSession.userID,
|
||||||
showSessionVerificationSection: showSessionVerificationSection,
|
showSessionVerificationSection: showSessionVerificationSection,
|
||||||
|
showNotificationSettings: appSettings.notificationSettingsEnabled,
|
||||||
showDeveloperOptions: appSettings.canShowDeveloperOptions),
|
showDeveloperOptions: appSettings.canShowDeveloperOptions),
|
||||||
imageProvider: userSession.mediaProvider)
|
imageProvider: userSession.mediaProvider)
|
||||||
|
|
||||||
@@ -51,6 +52,10 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
.weakAssign(to: \.state.userAvatarURL, on: self)
|
.weakAssign(to: \.state.userAvatarURL, on: self)
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
appSettings.$notificationSettingsEnabled
|
||||||
|
.weakAssign(to: \.state.showNotificationSettings, on: self)
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await userSession.clientProxy.loadUserAvatarURL()
|
await userSession.clientProxy.loadUserAvatarURL()
|
||||||
}
|
}
|
||||||
@@ -92,6 +97,8 @@ class SettingsScreenViewModel: SettingsScreenViewModelType, SettingsScreenViewMo
|
|||||||
callback?(.sessionVerification)
|
callback?(.sessionVerification)
|
||||||
case .changedTimelineStyle:
|
case .changedTimelineStyle:
|
||||||
appSettings.timelineStyle = state.bindings.timelineStyle
|
appSettings.timelineStyle = state.bindings.timelineStyle
|
||||||
|
case .notifications:
|
||||||
|
callback?(.notifications)
|
||||||
case .developerOptions:
|
case .developerOptions:
|
||||||
callback?(.developerOptions)
|
callback?(.developerOptions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,6 +113,15 @@ struct SettingsScreen: View {
|
|||||||
context.send(viewAction: .changedTimelineStyle)
|
context.send(viewAction: .changedTimelineStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notifications
|
||||||
|
if context.viewState.showNotificationSettings {
|
||||||
|
Button { context.send(viewAction: .notifications) } label: {
|
||||||
|
Label(L10n.screenNotificationSettingsTitle, systemImage: "bell")
|
||||||
|
}
|
||||||
|
.buttonStyle(.compoundForm(accessory: .navigationLink))
|
||||||
|
.accessibilityIdentifier("notificationsButton")
|
||||||
|
}
|
||||||
|
|
||||||
// Analytics
|
// Analytics
|
||||||
Button { context.send(viewAction: .analytics) } label: {
|
Button { context.send(viewAction: .analytics) } label: {
|
||||||
Label(L10n.commonAnalytics, systemImage: "chart.bar")
|
Label(L10n.commonAnalytics, systemImage: "chart.bar")
|
||||||
@@ -194,6 +203,7 @@ struct SettingsScreen_Previews: PreviewProvider {
|
|||||||
static let viewModel = {
|
static let viewModel = {
|
||||||
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@userid:example.com"),
|
let userSession = MockUserSession(clientProxy: MockClientProxy(userID: "@userid:example.com"),
|
||||||
mediaProvider: MockMediaProvider())
|
mediaProvider: MockMediaProvider())
|
||||||
|
ServiceLocator.shared.settings.notificationSettingsEnabled = true
|
||||||
return SettingsScreenViewModel(userSession: userSession,
|
return SettingsScreenViewModel(userSession: userSession,
|
||||||
appSettings: ServiceLocator.shared.settings)
|
appSettings: ServiceLocator.shared.settings)
|
||||||
}()
|
}()
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 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
|
||||||
|
import UserNotifications
|
||||||
|
|
||||||
|
extension UNUserNotificationCenter {
|
||||||
|
func authorizationStatus() async -> UNAuthorizationStatus {
|
||||||
|
await notificationSettings().authorizationStatus
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,7 +24,9 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
|
|||||||
private let appSettings: AppSettings
|
private let appSettings: AppSettings
|
||||||
|
|
||||||
private var userSession: UserSessionProtocol?
|
private var userSession: UserSessionProtocol?
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
private var notificationsEnabled = false
|
||||||
|
|
||||||
init(notificationCenter: UserNotificationCenterProtocol,
|
init(notificationCenter: UserNotificationCenterProtocol,
|
||||||
appSettings: AppSettings) {
|
appSettings: AppSettings) {
|
||||||
self.notificationCenter = notificationCenter
|
self.notificationCenter = notificationCenter
|
||||||
@@ -50,15 +52,35 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
|
|||||||
options: [])
|
options: [])
|
||||||
notificationCenter.setNotificationCategories([messageCategory, inviteCategory])
|
notificationCenter.setNotificationCategories([messageCategory, inviteCategory])
|
||||||
notificationCenter.delegate = self
|
notificationCenter.delegate = self
|
||||||
|
|
||||||
|
notificationsEnabled = appSettings.enableNotifications
|
||||||
|
MXLog.info("[NotificationManager] app setting 'enableNotifications' is '\(notificationsEnabled)'")
|
||||||
|
|
||||||
|
// Listen for changes to AppSettings.enableNotifications
|
||||||
|
appSettings.$enableNotifications
|
||||||
|
.sink { [weak self] newValue in
|
||||||
|
self?.enableNotifications(newValue)
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
// Request authorization uppon UIApplication.didBecomeActiveNotification notification
|
||||||
|
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
|
||||||
|
.sink { [weak self] _ in
|
||||||
|
self?.requestAuthorization()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
func requestAuthorization() {
|
func requestAuthorization() {
|
||||||
|
guard appSettings.enableNotifications, !userSession.isNil else { return }
|
||||||
Task {
|
Task {
|
||||||
do {
|
do {
|
||||||
let granted = try await notificationCenter.requestAuthorization(options: [.alert, .sound, .badge])
|
let permissionGranted = try await notificationCenter.requestAuthorization(options: [.alert, .sound, .badge])
|
||||||
MXLog.info("[NotificationManager] permission granted: \(granted)")
|
MXLog.info("[NotificationManager] permission granted: \(permissionGranted)")
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
self.delegate?.authorizationStatusUpdated(self, granted: granted)
|
if permissionGranted {
|
||||||
|
self.delegate?.registerForRemoteNotifications()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("[NotificationManager] request authorization failed: \(error)")
|
MXLog.error("[NotificationManager] request authorization failed: \(error)")
|
||||||
@@ -136,6 +158,17 @@ class NotificationManager: NSObject, NotificationManagerProtocol {
|
|||||||
appSettings.pusherProfileTag = newTag
|
appSettings.pusherProfileTag = newTag
|
||||||
return newTag
|
return newTag
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func enableNotifications(_ enable: Bool) {
|
||||||
|
guard notificationsEnabled != enable else { return }
|
||||||
|
notificationsEnabled = enable
|
||||||
|
MXLog.info("[NotificationManager] app setting 'enableNotifications' changed to '\(enable)'")
|
||||||
|
if enable {
|
||||||
|
requestAuthorization()
|
||||||
|
} else {
|
||||||
|
delegate?.unregisterForRemoteNotifications()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UNUserNotificationCenterDelegate
|
// MARK: - UNUserNotificationCenterDelegate
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ import Foundation
|
|||||||
import UserNotifications
|
import UserNotifications
|
||||||
|
|
||||||
protocol NotificationManagerDelegate: AnyObject {
|
protocol NotificationManagerDelegate: AnyObject {
|
||||||
func authorizationStatusUpdated(_ service: NotificationManagerProtocol,
|
|
||||||
granted: Bool)
|
|
||||||
func shouldDisplayInAppNotification(_ service: NotificationManagerProtocol,
|
func shouldDisplayInAppNotification(_ service: NotificationManagerProtocol,
|
||||||
content: UNNotificationContent) -> Bool
|
content: UNNotificationContent) -> Bool
|
||||||
func notificationTapped(_ service: NotificationManagerProtocol,
|
func notificationTapped(_ service: NotificationManagerProtocol,
|
||||||
@@ -27,6 +25,8 @@ protocol NotificationManagerDelegate: AnyObject {
|
|||||||
func handleInlineReply(_ service: NotificationManagerProtocol,
|
func handleInlineReply(_ service: NotificationManagerProtocol,
|
||||||
content: UNNotificationContent,
|
content: UNNotificationContent,
|
||||||
replyText: String) async
|
replyText: String) async
|
||||||
|
func registerForRemoteNotifications()
|
||||||
|
func unregisterForRemoteNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - NotificationManagerProtocol
|
// MARK: - NotificationManagerProtocol
|
||||||
|
|||||||
@@ -22,4 +22,8 @@ protocol UserNotificationCenterProtocol: AnyObject {
|
|||||||
func add(_ request: UNNotificationRequest) async throws
|
func add(_ request: UNNotificationRequest) async throws
|
||||||
func requestAuthorization(options: UNAuthorizationOptions) async throws -> Bool
|
func requestAuthorization(options: UNAuthorizationOptions) async throws -> Bool
|
||||||
func setNotificationCategories(_ categories: Set<UNNotificationCategory>)
|
func setNotificationCategories(_ categories: Set<UNNotificationCategory>)
|
||||||
|
func authorizationStatus() async -> UNAuthorizationStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sourcery: AutoMockable
|
||||||
|
extension UserNotificationCenterProtocol { }
|
||||||
|
|||||||
@@ -191,6 +191,11 @@ class MockScreen: Identifiable {
|
|||||||
isModallyPresented: false))
|
isModallyPresented: false))
|
||||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||||
return navigationStackCoordinator
|
return navigationStackCoordinator
|
||||||
|
case .notificationSettingsScreen:
|
||||||
|
let userNotificationCenter = UserNotificationCenterMock()
|
||||||
|
userNotificationCenter.authorizationStatusReturnValue = .denied
|
||||||
|
let parameters = NotificationSettingsScreenCoordinatorParameters(userNotificationCenter: userNotificationCenter)
|
||||||
|
return NotificationSettingsScreenCoordinator(parameters: parameters)
|
||||||
case .onboarding:
|
case .onboarding:
|
||||||
return OnboardingCoordinator()
|
return OnboardingCoordinator()
|
||||||
case .roomPlainNoAvatar:
|
case .roomPlainNoAvatar:
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ enum UITestsScreenIdentifier: String {
|
|||||||
case settings
|
case settings
|
||||||
case bugReport
|
case bugReport
|
||||||
case bugReportWithScreenshot
|
case bugReportWithScreenshot
|
||||||
|
case notificationSettingsScreen
|
||||||
case onboarding
|
case onboarding
|
||||||
case roomPlainNoAvatar
|
case roomPlainNoAvatar
|
||||||
case roomEncryptedWithAvatar
|
case roomEncryptedWithAvatar
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 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 ElementX
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class NotificationSettingsScreenUITests: XCTestCase { }
|
||||||
@@ -179,8 +179,12 @@ final class NotificationManagerTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension NotificationManagerTests: NotificationManagerDelegate {
|
extension NotificationManagerTests: NotificationManagerDelegate {
|
||||||
func authorizationStatusUpdated(_ service: ElementX.NotificationManagerProtocol, granted: Bool) {
|
func registerForRemoteNotifications() {
|
||||||
authorizationStatusWasGranted = granted
|
authorizationStatusWasGranted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func unregisterForRemoteNotifications() {
|
||||||
|
authorizationStatusWasGranted = false
|
||||||
}
|
}
|
||||||
|
|
||||||
func shouldDisplayInAppNotification(_ service: ElementX.NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
|
func shouldDisplayInAppNotification(_ service: ElementX.NotificationManagerProtocol, content: UNNotificationContent) -> Bool {
|
||||||
|
|||||||
@@ -36,4 +36,9 @@ class UserNotificationCenterSpy: UserNotificationCenterProtocol {
|
|||||||
func setNotificationCategories(_ categories: Set<UNNotificationCategory>) {
|
func setNotificationCategories(_ categories: Set<UNNotificationCategory>) {
|
||||||
notificationCategoriesValue = categories
|
notificationCategoriesValue = categories
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var authorizationStatusValue: UNAuthorizationStatus?
|
||||||
|
func authorizationStatus() async -> UNAuthorizationStatus {
|
||||||
|
authorizationStatusValue ?? UNAuthorizationStatus.denied
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,50 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2023 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 XCTest
|
||||||
|
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class NotificationSettingsScreenViewModelTests: XCTestCase {
|
||||||
|
private var viewModel: NotificationSettingsScreenViewModelProtocol!
|
||||||
|
private var context: NotificationSettingsScreenViewModelType.Context!
|
||||||
|
private var appSettings: AppSettings!
|
||||||
|
private var userNotificationCenter: UserNotificationCenterMock!
|
||||||
|
|
||||||
|
@MainActor override func setUpWithError() throws {
|
||||||
|
AppSettings.reset()
|
||||||
|
|
||||||
|
userNotificationCenter = UserNotificationCenterMock()
|
||||||
|
userNotificationCenter.authorizationStatusReturnValue = .authorized
|
||||||
|
appSettings = AppSettings()
|
||||||
|
viewModel = NotificationSettingsScreenViewModel(appSettings: appSettings,
|
||||||
|
userNotificationCenter: userNotificationCenter)
|
||||||
|
context = viewModel.context
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEnableNotifications() {
|
||||||
|
appSettings.enableNotifications = false
|
||||||
|
context.send(viewAction: .changedEnableNotifications)
|
||||||
|
XCTAssertTrue(appSettings.enableNotifications)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testOptOut() {
|
||||||
|
appSettings.enableNotifications = true
|
||||||
|
context.send(viewAction: .changedEnableNotifications)
|
||||||
|
XCTAssertFalse(appSettings.enableNotifications)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user