mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 13:37:11 +00:00
Welcome Screen (#1259)
* the screen renders and changed the analytics checkmark to be more generic * welcome screen * transition * tests... TODO * changelog * changed assets and added multilineTextAlignment * better naming * fix for missing after migration but has a weird presentaiton bug * fix * icon color
This commit is contained in:
parent
9ebc57e1cf
commit
00636d98da
@ -43,7 +43,7 @@
|
||||
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
||||
0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */; };
|
||||
10516CF20E8B5852F4C444FD /* AnalyticsPromptScreenCheckmarkItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1253D3E9395A0493DB944B9 /* AnalyticsPromptScreenCheckmarkItem.swift */; };
|
||||
10516CF20E8B5852F4C444FD /* RoundedLabelItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1253D3E9395A0493DB944B9 /* RoundedLabelItem.swift */; };
|
||||
1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; };
|
||||
126EE01D8BEAEF26105D83C5 /* RoomDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */; };
|
||||
12C867E85E6D12EEDFD0B127 /* CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */; };
|
||||
@ -56,6 +56,7 @@
|
||||
152AE2B8650FB23AFD2E28B9 /* MockAuthenticationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C2B80DD0BF6F10BB5FA922 /* MockAuthenticationServiceProxy.swift */; };
|
||||
155063E980E763D4910EA3CF /* Analytics+SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CFE236419E830E8946639C /* Analytics+SwiftUI.swift */; };
|
||||
1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4549FCB53F43DB0B278374BC /* TemplateScreen.swift */; };
|
||||
15705159D584B189BC48CE50 /* WelcomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9AC2812E6AB8C477A199E565 /* WelcomeScreen.swift */; };
|
||||
157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; };
|
||||
158A2D528CC78C4E7A8ED608 /* MockRoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71556206CD5E8B1F53F07178 /* MockRoomTimelineControllerFactory.swift */; };
|
||||
15D867E638BFD0E5E71DB1EF /* List.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AFEF3AC64B1358083F76B8B /* List.swift */; };
|
||||
@ -85,6 +86,7 @@
|
||||
1FEC0A4EC6E6DF693C16B32A /* StringTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CEBCB9676FCD1D0F13188DD /* StringTests.swift */; };
|
||||
206F0DBAB6AF042CA1FF2C0D /* SettingsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D487C1185D658F8B15B8F55 /* SettingsViewModelTests.swift */; };
|
||||
208C19811613F9A10F8A7B75 /* MediaLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */; };
|
||||
2185C1F6724C78FFF355D6FA /* WelcomeScreenScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AB10FA6570DD08B3966C159 /* WelcomeScreenScreenUITests.swift */; };
|
||||
2198B4458AFF69102BBCC370 /* RoomTimelineItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA7D3C686C214470F4911618 /* RoomTimelineItemViewModel.swift */; };
|
||||
21BF2B7CEDFE3CA67C5355AD /* test_image.png in Resources */ = {isa = PBXBuildFile; fileRef = C733D11B421CFE3A657EF230 /* test_image.png */; };
|
||||
22882C710BC99EC34A5024A0 /* UITestsScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEBE5EA91E8691EDF364EC2 /* UITestsScreenIdentifier.swift */; };
|
||||
@ -149,6 +151,7 @@
|
||||
36AD4DD4C798E22584ED3200 /* Version in Frameworks */ = {isa = PBXBuildFile; productRef = A05AF81DDD14AD58CB0E1B9B /* Version */; };
|
||||
36CD6E11B37396E14F032CB6 /* Flow in Frameworks */ = {isa = PBXBuildFile; productRef = 4D7E6BFC89715FC3CF0349D0 /* Flow */; };
|
||||
37D789F24199B32E3FD1AA7B /* FileRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 216F0DDC98F2A2C162D09C28 /* FileRoomTimelineItemContent.swift */; };
|
||||
383055C6ABE5BE058CEE1DDB /* WelcomeScreenScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57FE5EF0AFFE360C66420AAE /* WelcomeScreenScreenCoordinator.swift */; };
|
||||
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
||||
38896D54D6D675534E606195 /* RoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6FCC416A3BFE73DF7B3E6BF /* RoomTimelineControllerFactory.swift */; };
|
||||
3910D3A2EF98587C0E7B9CCB /* EmojiMartEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */; };
|
||||
@ -333,6 +336,7 @@
|
||||
7E3C34BC10936AD4F77975F4 /* EmojiMartJSONLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */; };
|
||||
7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */; };
|
||||
7ECF12D5DCD69F67BD3E3842 /* RoomTimelineControllerFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */; };
|
||||
7F02063FB3D1C3E5601471A1 /* WelcomeScreenScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 851EF6258DF8B7EF129DC3AC /* WelcomeScreenScreenViewModelTests.swift */; };
|
||||
7F08F4BC1312075E2B5EAEFA /* AuthenticationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF48AF076424DBC1615C74AD /* AuthenticationServiceProxy.swift */; };
|
||||
7F61F9ACD5EC9E845EF3EFBF /* BugReportServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFD3200F9960D4996159F10 /* BugReportServiceTests.swift */; };
|
||||
7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */; };
|
||||
@ -401,6 +405,7 @@
|
||||
9408CE8B8865C0C8DD4C9869 /* NoticeRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD51B4D5173F7FC886F5360 /* NoticeRoomTimelineItemContent.swift */; };
|
||||
9462C62798F47E39DCC182D2 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA89A2DD51B6BBE1DA55E263 /* Application.swift */; };
|
||||
94A65DD8A353DF112EBEF67A /* SessionVerificationControllerProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */; };
|
||||
94CEF587A3994A36A46D8334 /* WelcomeScreenScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7101698791B321A76F552804 /* WelcomeScreenScreenViewModelProtocol.swift */; };
|
||||
94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
||||
95690DDD9D547D3D842ACBE3 /* AnalyticsSettingsScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD371B60E07A5324B9507EF /* AnalyticsSettingsScreenCoordinator.swift */; };
|
||||
9586E90A447C4896C0CA3A8E /* TimelineItemReplyDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE89A8BD65CCE3FCC925CA14 /* TimelineItemReplyDetails.swift */; };
|
||||
@ -536,6 +541,7 @@
|
||||
BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; };
|
||||
BCC864190651B3A3CF51E4DF /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
|
||||
BD203FC6A7AE7637EA003643 /* RoomProxyMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ABDE6F66532CBEB0E016F94 /* RoomProxyMock.swift */; };
|
||||
BD2BF1EC73FFB0C01552ECDA /* WelcomeScreenScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB782CE6176A5D2C082EC5D /* WelcomeScreenScreenModels.swift */; };
|
||||
BD6D98676111DA8FC2BE4908 /* InvitesScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 86873A768B13069BB5CAECF6 /* InvitesScreenViewModelProtocol.swift */; };
|
||||
BD782053BE4C3D2F0BDE5699 /* ServiceLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */; };
|
||||
BDA68E8D95B2B24B28825B8B /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C368CAB3063EF275357ECD4 /* LoginScreenViewModel.swift */; };
|
||||
@ -618,6 +624,7 @@
|
||||
D9F80CE61BF8FF627FDB0543 /* LoadableImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C352359663A0E52BA20761EE /* LoadableImage.swift */; };
|
||||
DB079D1929B5A5F52D207C83 /* RoomDetailsScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466C71A0FED9BFF287613C82 /* RoomDetailsScreenModels.swift */; };
|
||||
DC08ADC41E792086A340A8B3 /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */; };
|
||||
DC1BB5EE5F4D9B6A1F98A77A /* WelcomeScreenScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = FEC2E8E1B20BB2EA07B0B61E /* WelcomeScreenScreenViewModel.swift */; };
|
||||
DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */; };
|
||||
DE0BBA736557B42BC0DA6CBF /* TimelineEventProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00B62EE933FC3D5651AF4607 /* TimelineEventProxy.swift */; };
|
||||
DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */; };
|
||||
@ -814,6 +821,7 @@
|
||||
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>"; };
|
||||
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>"; };
|
||||
1059E2AE7878CF7820592637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||
105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactory.swift; sourceTree = "<group>"; };
|
||||
10CC626F97AD70FF0420C115 /* RoomSummaryProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomSummaryProviderProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1009,6 +1017,7 @@
|
||||
57B6B383F1FD04CC0E7B60C6 /* AnalyticsConsentState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsConsentState.swift; sourceTree = "<group>"; };
|
||||
57EAAF82432B0B53881CF826 /* AudioRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceLocator.swift; sourceTree = "<group>"; };
|
||||
57FE5EF0AFFE360C66420AAE /* WelcomeScreenScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
584A61D9C459FAFEF038A7C0 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
|
||||
58C2527813FDAE23E72A9063 /* AnalyticsSettingsScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettingsScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
592A35163B0749C66BFD6186 /* MapLibreStaticMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreStaticMapView.swift; sourceTree = "<group>"; };
|
||||
@ -1075,6 +1084,7 @@
|
||||
6FC5015B9634698BDB8701AF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||
7023EB4F3B7C7D1FBA68638B /* TimelineItemDebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemDebugView.swift; sourceTree = "<group>"; };
|
||||
70C86696AC9521F8ED88FBEB /* MediaUploadPreviewScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaUploadPreviewScreen.swift; sourceTree = "<group>"; };
|
||||
7101698791B321A76F552804 /* WelcomeScreenScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
713B48DBF65DE4B0DD445D66 /* ReportContentScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportContentScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
71556206CD5E8B1F53F07178 /* MockRoomTimelineControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineControllerFactory.swift; sourceTree = "<group>"; };
|
||||
71A7D4DDEEE5D2CA0C8D63CD /* SoftLogoutScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutScreen.swift; sourceTree = "<group>"; };
|
||||
@ -1115,6 +1125,7 @@
|
||||
84816E0D2F34E368BF64FA60 /* SessionVerificationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreen.swift; sourceTree = "<group>"; };
|
||||
84A87D0471D438A233C2CF4A /* RoomMemberDetailsScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
84B7A28A6606D58D1E38C55A /* ExpiringTaskRunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExpiringTaskRunnerTests.swift; sourceTree = "<group>"; };
|
||||
851EF6258DF8B7EF129DC3AC /* WelcomeScreenScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
854BCEAF2A832176FAACD2CB /* SplashScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
85EB16E7FE59A947CA441531 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
||||
86873A768B13069BB5CAECF6 /* InvitesScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InvitesScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1125,6 +1136,7 @@
|
||||
893777A4997BBDB68079D4F5 /* ArrayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArrayTests.swift; sourceTree = "<group>"; };
|
||||
8977176AB534AA41630395BC /* LegalInformationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LegalInformationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
897DF5E9A70CE05A632FC8AF /* UTType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UTType.swift; sourceTree = "<group>"; };
|
||||
8AB10FA6570DD08B3966C159 /* WelcomeScreenScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenUITests.swift; sourceTree = "<group>"; };
|
||||
8AFCE895ECFFA53FEE64D62B /* MediaLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaLoader.swift; sourceTree = "<group>"; };
|
||||
8BEBF0E59F25E842EDB6FD11 /* LocationSharingScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationSharingScreenModels.swift; sourceTree = "<group>"; };
|
||||
8C8616254EE40CA8BA5E9BC2 /* VideoRoomTimelineItemContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItemContent.swift; sourceTree = "<group>"; };
|
||||
@ -1165,6 +1177,7 @@
|
||||
9A008E57D52B07B78DFAD1BB /* RoomFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomFlowCoordinator.swift; sourceTree = "<group>"; };
|
||||
9A22A05E472533ED3C5A31B3 /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
||||
9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
9AC2812E6AB8C477A199E565 /* WelcomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreen.swift; sourceTree = "<group>"; };
|
||||
9B06663F7858E45882E63471 /* StaticLocationScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreen.swift; sourceTree = "<group>"; };
|
||||
9B65A314DF40B6BBF775C2BC /* AnalyticsPromptScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
9B663BE498BB39EADC24025D /* SettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreenModels.swift; sourceTree = "<group>"; };
|
||||
@ -1352,7 +1365,7 @@
|
||||
DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
E062C1750EFC8627DE4CAB8E /* MapTilerAuthorization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapTilerAuthorization.swift; sourceTree = "<group>"; };
|
||||
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
||||
E1253D3E9395A0493DB944B9 /* AnalyticsPromptScreenCheckmarkItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptScreenCheckmarkItem.swift; sourceTree = "<group>"; };
|
||||
E1253D3E9395A0493DB944B9 /* RoundedLabelItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedLabelItem.swift; sourceTree = "<group>"; };
|
||||
E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
||||
E1A5FEF17ED7E6176D922D4F /* RoomDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsScreen.swift; sourceTree = "<group>"; };
|
||||
E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarSize.swift; sourceTree = "<group>"; };
|
||||
@ -1427,6 +1440,7 @@
|
||||
FC2D505742FDA21FCDC4C18A /* AudioRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||
FD1275D9CE0FFBA6E8E85426 /* UserIndicatorController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorController.swift; sourceTree = "<group>"; };
|
||||
FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerTests.swift; sourceTree = "<group>"; };
|
||||
FEC2E8E1B20BB2EA07B0B61E /* WelcomeScreenScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeScreenScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
FEFEEE93B82937B2E86F92EB /* AnalyticsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsScreen.swift; sourceTree = "<group>"; };
|
||||
FFECCE59967018204876D0A5 /* LocationMarkerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationMarkerView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
@ -1554,7 +1568,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5F8002D0392A476D2758B291 /* AnalyticsPromptScreen.swift */,
|
||||
E1253D3E9395A0493DB944B9 /* AnalyticsPromptScreenCheckmarkItem.swift */,
|
||||
E1253D3E9395A0493DB944B9 /* RoundedLabelItem.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -2427,6 +2441,7 @@
|
||||
2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */,
|
||||
BA241DEEF7C8A7181C0AEDC9 /* UserPreferenceTests.swift */,
|
||||
C796FC1DFDBCDD5573D0360F /* WaitlistScreenViewModelTests.swift */,
|
||||
851EF6258DF8B7EF129DC3AC /* WelcomeScreenScreenViewModelTests.swift */,
|
||||
53280D2292E6C9C7821773FD /* UserSession */,
|
||||
70C5B842301AC281DF374E41 /* Extensions */,
|
||||
7583EAC171059A86B767209F /* MediaProvider */,
|
||||
@ -2712,6 +2727,18 @@
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
93F4D089C78719B688D576ED /* WelcomeScreenScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
57FE5EF0AFFE360C66420AAE /* WelcomeScreenScreenCoordinator.swift */,
|
||||
0FB782CE6176A5D2C082EC5D /* WelcomeScreenScreenModels.swift */,
|
||||
FEC2E8E1B20BB2EA07B0B61E /* WelcomeScreenScreenViewModel.swift */,
|
||||
7101698791B321A76F552804 /* WelcomeScreenScreenViewModelProtocol.swift */,
|
||||
C5B85A56479F1382EA5A9913 /* View */,
|
||||
);
|
||||
path = WelcomeScreenScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9413F680ECDFB2B0DDB0DEF2 /* Packages */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2774,6 +2801,7 @@
|
||||
DA2AEC1AB349A341FE13DEC1 /* StartChatScreenUITests.swift */,
|
||||
F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */,
|
||||
ECB08484CD5D77C9BF97AA78 /* WaitlistScreenUITests.swift */,
|
||||
8AB10FA6570DD08B3966C159 /* WelcomeScreenScreenUITests.swift */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@ -3154,6 +3182,14 @@
|
||||
path = CreateRoom;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
C5B85A56479F1382EA5A9913 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9AC2812E6AB8C477A199E565 /* WelcomeScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CA15BB3F6C62B35AE2C281A9 /* Provider */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -3321,6 +3357,7 @@
|
||||
3153FCA3F4B0E88B16D99D12 /* SessionVerificationScreen */,
|
||||
70B74A432C241E56A7ACE610 /* Settings */,
|
||||
EC4545C7E37E8294D3FE6800 /* StartChatScreen */,
|
||||
93F4D089C78719B688D576ED /* WelcomeScreenScreen */,
|
||||
);
|
||||
path = Screens;
|
||||
sourceTree = "<group>";
|
||||
@ -4010,6 +4047,7 @@
|
||||
81A7C020CB5F6232242A8414 /* UserSessionTests.swift in Sources */,
|
||||
99F8DA4CCC6772EE5FE68E24 /* ViewModelContext.swift in Sources */,
|
||||
FB9A1DD83EF641A75ABBCE69 /* WaitlistScreenViewModelTests.swift in Sources */,
|
||||
7F02063FB3D1C3E5601471A1 /* WelcomeScreenScreenViewModelTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -4037,7 +4075,7 @@
|
||||
8DDC6F28C797D8685F2F8E32 /* AnalyticsConsentState.swift in Sources */,
|
||||
EDC1031A7CFB3406A9DA3175 /* AnalyticsLocationType.swift in Sources */,
|
||||
9DF3F6318A4402305F5EB869 /* AnalyticsPromptScreen.swift in Sources */,
|
||||
10516CF20E8B5852F4C444FD /* AnalyticsPromptScreenCheckmarkItem.swift in Sources */,
|
||||
10516CF20E8B5852F4C444FD /* RoundedLabelItem.swift in Sources */,
|
||||
5F28C9146694B381BB82E18C /* AnalyticsPromptScreenCoordinator.swift in Sources */,
|
||||
496CC9D59ACFAB84FD9B3B5F /* AnalyticsPromptScreenModels.swift in Sources */,
|
||||
0AA0477E063E72B786A983CF /* AnalyticsPromptScreenViewModel.swift in Sources */,
|
||||
@ -4507,6 +4545,11 @@
|
||||
2F66701B15657A87B4AC3A0A /* WaitlistScreenModels.swift in Sources */,
|
||||
CF3827071B0BC9638BD44F5D /* WaitlistScreenViewModel.swift in Sources */,
|
||||
B717A820BE02C6FE2CB53F6E /* WaitlistScreenViewModelProtocol.swift in Sources */,
|
||||
15705159D584B189BC48CE50 /* WelcomeScreen.swift in Sources */,
|
||||
383055C6ABE5BE058CEE1DDB /* WelcomeScreenScreenCoordinator.swift in Sources */,
|
||||
BD2BF1EC73FFB0C01552ECDA /* WelcomeScreenScreenModels.swift in Sources */,
|
||||
DC1BB5EE5F4D9B6A1F98A77A /* WelcomeScreenScreenViewModel.swift in Sources */,
|
||||
94CEF587A3994A36A46D8334 /* WelcomeScreenScreenViewModelProtocol.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -4549,6 +4592,7 @@
|
||||
84EFCB95F9DA2979C8042B26 /* UITestsSignalling.swift in Sources */,
|
||||
B22D857D1E8FCA6DD74A58E3 /* UserSessionScreenTests.swift in Sources */,
|
||||
2DA90E38FF4E696825810C1A /* WaitlistScreenUITests.swift in Sources */,
|
||||
2185C1F6724C78FFF355D6FA /* WelcomeScreenScreenUITests.swift in Sources */,
|
||||
588411C8FD72B2A2DFE5F7DE /* XCUIElement.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -279,7 +279,7 @@
|
||||
"screen_room_details_encryption_enabled_subtitle" = "Messages are secured with locks. Only you and the recipients have the unique keys to unlock them.";
|
||||
"screen_room_details_encryption_enabled_title" = "Message encryption enabled";
|
||||
"screen_room_details_invite_people_title" = "Invite people";
|
||||
"screen_room_details_notification_title" = "Notification";
|
||||
"screen_room_details_notification_title" = "Notifications";
|
||||
"screen_room_details_room_name_label" = "Room name";
|
||||
"screen_room_details_share_room_title" = "Share room";
|
||||
"screen_room_details_updating_room" = "Updating room…";
|
||||
@ -336,6 +336,12 @@
|
||||
"screen_waitlist_message_success" = "Welcome to %1$@!";
|
||||
"screen_waitlist_title" = "You’re almost there.";
|
||||
"screen_waitlist_title_success" = "You're in.";
|
||||
"screen_welcome_bullet_1" = "Calls, location sharing, search and more will be added later this year.";
|
||||
"screen_welcome_bullet_2" = "Message history for encrypted rooms won’t be available in this update.";
|
||||
"screen_welcome_bullet_3" = "We’d love to hear from you, let us know what you think via the settings page.";
|
||||
"screen_welcome_button" = "Let's go!";
|
||||
"screen_welcome_subtitle" = "Here’s what you need to know:";
|
||||
"screen_welcome_title" = "Welcome to %1$@!";
|
||||
"session_verification_banner_message" = "Looks like you’re using a new device. Verify with another device to access your encrypted messages moving forwards.";
|
||||
"session_verification_banner_title" = "Verify it’s you";
|
||||
"settings_rageshake" = "Rageshake";
|
||||
|
@ -33,6 +33,7 @@ final class AppSettings {
|
||||
case readReceiptsEnabled
|
||||
case locationEventsEnabled
|
||||
case shareLocationEnabled
|
||||
case hasShownWelcomeScreen
|
||||
}
|
||||
|
||||
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
|
||||
@ -89,6 +90,9 @@ final class AppSettings {
|
||||
|
||||
/// The task identifier used for background app refresh. Also used in main target's the Info.plist
|
||||
let backgroundAppRefreshTaskIdentifier = "io.element.elementx.background.refresh"
|
||||
|
||||
@UserPreference(key: UserDefaultsKeys.hasShownWelcomeScreen, defaultValue: false, storageType: .userDefaults(store))
|
||||
var hasShownWelcomeScreen: Bool
|
||||
|
||||
// MARK: - Authentication
|
||||
|
||||
@ -119,7 +123,7 @@ final class AppSettings {
|
||||
/// proxy that it is the first sync (or that an upgrade on the backend will involve a slower sync).
|
||||
@UserPreference(key: UserDefaultsKeys.migratedAccounts, defaultValue: [:], storageType: .userDefaults(store))
|
||||
var migratedAccounts: [String: Bool]
|
||||
|
||||
|
||||
// MARK: - Notifications
|
||||
|
||||
var pusherAppId: String {
|
||||
|
@ -37,7 +37,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private let sidebarNavigationStackCoordinator: NavigationStackCoordinator
|
||||
private let detailNavigationStackCoordinator: NavigationStackCoordinator
|
||||
|
||||
|
||||
private let selectedRoomSubject = CurrentValueSubject<String?, Never>(nil)
|
||||
|
||||
var callback: ((UserSessionFlowCoordinatorAction) -> Void)?
|
||||
@ -85,6 +85,8 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
if appSettings.migratedAccounts[userSession.userID] != true {
|
||||
// Show the migration screen for a new account.
|
||||
stateMachine.processEvent(.startWithMigration)
|
||||
} else if !appSettings.hasShownWelcomeScreen {
|
||||
stateMachine.processEvent(.startWithWelcomeScreen)
|
||||
} else {
|
||||
// Otherwise go straight to the home screen.
|
||||
stateMachine.processEvent(.start)
|
||||
@ -106,7 +108,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
return // Not ready to handle a route.
|
||||
case .roomList:
|
||||
break // Nothing to tidy up on the home screen.
|
||||
case .feedbackScreen, .sessionVerificationScreen, .settingsScreen, .startChatScreen, .invitesScreen:
|
||||
case .feedbackScreen, .sessionVerificationScreen, .settingsScreen, .startChatScreen, .invitesScreen, .welcomeScreen:
|
||||
navigationSplitCoordinator.setSheetCoordinator(nil, animated: animated)
|
||||
}
|
||||
|
||||
@ -135,13 +137,21 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
let animated = (context.userInfo as? UserSessionFlowCoordinatorStateMachine.EventUserInfo)?.animated ?? true
|
||||
switch (context.fromState, context.event, context.toState) {
|
||||
case (.initial, .start, .roomList):
|
||||
self.presentHomeScreen()
|
||||
presentHomeScreen()
|
||||
|
||||
case (.initial, .startWithMigration, .migration):
|
||||
self.presentMigrationScreen() // Full screen cover
|
||||
self.presentHomeScreen() // Have the home screen ready to show underneath
|
||||
presentMigrationScreen() // Full screen cover
|
||||
presentHomeScreen() // Have the home screen ready to show underneath
|
||||
case (.migration, .completeMigration, .roomList):
|
||||
self.dismissMigrationScreen()
|
||||
dismissMigrationScreen()
|
||||
|
||||
case (.initial, .startWithWelcomeScreen, .welcomeScreen):
|
||||
presentHomeScreen()
|
||||
presentWelcomeScreen()
|
||||
case (.roomList, .presentWelcomeScreen, .welcomeScreen):
|
||||
presentWelcomeScreen()
|
||||
case (.welcomeScreen, .dismissedWelcomeScreen, .roomList):
|
||||
break
|
||||
|
||||
case(.roomList, .selectRoom, .roomList):
|
||||
break
|
||||
@ -154,27 +164,27 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
break
|
||||
|
||||
case (.roomList, .showSessionVerificationScreen, .sessionVerificationScreen):
|
||||
self.presentSessionVerification(animated: animated)
|
||||
presentSessionVerification(animated: animated)
|
||||
case (.sessionVerificationScreen, .dismissedSessionVerificationScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList, .showSettingsScreen, .settingsScreen):
|
||||
self.presentSettingsScreen(animated: animated)
|
||||
presentSettingsScreen(animated: animated)
|
||||
case (.settingsScreen, .dismissedSettingsScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList, .feedbackScreen, .feedbackScreen):
|
||||
self.presentFeedbackScreen(animated: animated)
|
||||
presentFeedbackScreen(animated: animated)
|
||||
case (.feedbackScreen, .dismissedFeedbackScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList, .showStartChatScreen, .startChatScreen):
|
||||
self.presentStartChat(animated: animated)
|
||||
presentStartChat(animated: animated)
|
||||
case (.startChatScreen, .dismissedStartChatScreen, .roomList):
|
||||
break
|
||||
|
||||
case (.roomList, .showInvitesScreen, .invitesScreen):
|
||||
self.presentInvitesList(animated: animated)
|
||||
presentInvitesList(animated: animated)
|
||||
case (.invitesScreen, .showInvitesScreen, .invitesScreen):
|
||||
break
|
||||
case (.invitesScreen, .closedInvitesScreen, .roomList):
|
||||
@ -216,6 +226,14 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private func dismissMigrationScreen() {
|
||||
navigationSplitCoordinator.setFullScreenCoverCoordinator(nil)
|
||||
|
||||
// Not sure why but the full screen closure dismissal closure doesn't seem to work properly
|
||||
// And not using the DispatchQueue.main results in the the screen getting presented as full screen too.
|
||||
if !appSettings.hasShownWelcomeScreen {
|
||||
DispatchQueue.main.async {
|
||||
self.stateMachine.processEvent(.presentWelcomeScreen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// swiftlint:disable:next cyclomatic_complexity
|
||||
@ -257,6 +275,21 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
sidebarNavigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
}
|
||||
|
||||
private func presentWelcomeScreen() {
|
||||
let welcomeScreenCoordinator = WelcomeScreenScreenCoordinator()
|
||||
welcomeScreenCoordinator.actions.sink { [weak self] action in
|
||||
switch action {
|
||||
case .dismiss:
|
||||
self?.navigationSplitCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
navigationSplitCoordinator.setSheetCoordinator(welcomeScreenCoordinator) { [weak self] in
|
||||
self?.stateMachine.processEvent(.dismissedWelcomeScreen)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Settings
|
||||
|
||||
|
@ -25,6 +25,9 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
|
||||
/// Showing the migration screen whilst the proxy performs an initial sync.
|
||||
case migration
|
||||
|
||||
/// Showing the welcome screen.
|
||||
case welcomeScreen
|
||||
|
||||
/// Showing the home screen. The `selectedRoomId` represents the timeline shown on the detail panel (if any)
|
||||
case roomList(selectedRoomId: String?)
|
||||
@ -53,11 +56,15 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
enum Event: EventType {
|
||||
/// Start the user session flows
|
||||
case start
|
||||
|
||||
/// Starts the user session flows with the welcome screen
|
||||
case startWithWelcomeScreen
|
||||
/// Start the user session flows with a migration screen.
|
||||
case startWithMigration
|
||||
/// Request to transition from the migration state to the home screen.
|
||||
case completeMigration
|
||||
|
||||
case presentWelcomeScreen
|
||||
case dismissedWelcomeScreen
|
||||
|
||||
/// Request presentation for a particular room
|
||||
/// - Parameter roomId:the room identifier
|
||||
@ -106,8 +113,10 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
private func configure() {
|
||||
stateMachine.addRoutes(event: .start, transitions: [.initial => .roomList(selectedRoomId: nil)])
|
||||
stateMachine.addRoutes(event: .startWithMigration, transitions: [.initial => .migration])
|
||||
stateMachine.addRoutes(event: .startWithWelcomeScreen, transitions: [.initial => .welcomeScreen])
|
||||
stateMachine.addRoutes(event: .completeMigration, transitions: [.migration => .roomList(selectedRoomId: nil)])
|
||||
|
||||
stateMachine.addRoutes(event: .dismissedWelcomeScreen, transitions: [.welcomeScreen => .roomList(selectedRoomId: nil)])
|
||||
|
||||
stateMachine.addRouteMapping { event, fromState, _ in
|
||||
switch (event, fromState) {
|
||||
case (.selectRoom(let roomId), .roomList):
|
||||
@ -146,6 +155,9 @@ class UserSessionFlowCoordinatorStateMachine {
|
||||
|
||||
case (.closedInvitesScreen, .invitesScreen(let selectedRoomId)):
|
||||
return .roomList(selectedRoomId: selectedRoomId)
|
||||
|
||||
case (.presentWelcomeScreen, .roomList):
|
||||
return .welcomeScreen
|
||||
|
||||
default:
|
||||
return nil
|
||||
|
@ -704,7 +704,7 @@ public enum L10n {
|
||||
public static var screenRoomDetailsInvitePeopleTitle: String { return L10n.tr("Localizable", "screen_room_details_invite_people_title") }
|
||||
/// Leave room
|
||||
public static var screenRoomDetailsLeaveRoomTitle: String { return L10n.tr("Localizable", "screen_room_details_leave_room_title") }
|
||||
/// Notification
|
||||
/// Notifications
|
||||
public static var screenRoomDetailsNotificationTitle: String { return L10n.tr("Localizable", "screen_room_details_notification_title") }
|
||||
/// People
|
||||
public static var screenRoomDetailsPeopleTitle: String { return L10n.tr("Localizable", "screen_room_details_people_title") }
|
||||
@ -850,6 +850,20 @@ public enum L10n {
|
||||
public static var screenWaitlistTitle: String { return L10n.tr("Localizable", "screen_waitlist_title") }
|
||||
/// You're in.
|
||||
public static var screenWaitlistTitleSuccess: String { return L10n.tr("Localizable", "screen_waitlist_title_success") }
|
||||
/// Calls, location sharing, search and more will be added later this year.
|
||||
public static var screenWelcomeBullet1: String { return L10n.tr("Localizable", "screen_welcome_bullet_1") }
|
||||
/// Message history for encrypted rooms won’t be available in this update.
|
||||
public static var screenWelcomeBullet2: String { return L10n.tr("Localizable", "screen_welcome_bullet_2") }
|
||||
/// We’d love to hear from you, let us know what you think via the settings page.
|
||||
public static var screenWelcomeBullet3: String { return L10n.tr("Localizable", "screen_welcome_bullet_3") }
|
||||
/// Let's go!
|
||||
public static var screenWelcomeButton: String { return L10n.tr("Localizable", "screen_welcome_button") }
|
||||
/// Here’s what you need to know:
|
||||
public static var screenWelcomeSubtitle: String { return L10n.tr("Localizable", "screen_welcome_subtitle") }
|
||||
/// Welcome to %1$@!
|
||||
public static func screenWelcomeTitle(_ p1: Any) -> String {
|
||||
return L10n.tr("Localizable", "screen_welcome_title", String(describing: p1))
|
||||
}
|
||||
/// Looks like you’re using a new device. Verify with another device to access your encrypted messages moving forwards.
|
||||
public static var sessionVerificationBannerMessage: String { return L10n.tr("Localizable", "session_verification_banner_message") }
|
||||
/// Verify it’s you
|
||||
|
@ -58,17 +58,32 @@ struct AnalyticsPromptScreen: View {
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var checkMark: some View {
|
||||
Image(systemName: "checkmark.circle")
|
||||
.symbolVariant(.fill)
|
||||
.symbolRenderingMode(.palette)
|
||||
.foregroundStyle(Color.compound.iconAccentTertiary, Color.compound.textOnSolidPrimary)
|
||||
}
|
||||
|
||||
/// The list of re-assurances about analytics.
|
||||
private var checkmarkList: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
AnalyticsPromptScreenCheckmarkItem(title: context.viewState.strings.point1, listPosition: .top)
|
||||
AnalyticsPromptScreenCheckmarkItem(title: context.viewState.strings.point2, listPosition: .middle)
|
||||
AnalyticsPromptScreenCheckmarkItem(title: context.viewState.strings.point3, listPosition: .bottom)
|
||||
checkMarkItem(title: context.viewState.strings.point1, position: .top)
|
||||
checkMarkItem(title: context.viewState.strings.point2, position: .middle)
|
||||
checkMarkItem(title: context.viewState.strings.point3, position: .bottom)
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private func checkMarkItem(title: String, position: ListPosition) -> some View {
|
||||
RoundedLabelItem(title: title, listPosition: position) {
|
||||
checkMark
|
||||
}
|
||||
}
|
||||
|
||||
/// The stack of enable/disable buttons.
|
||||
private var buttons: some View {
|
||||
|
@ -16,33 +16,31 @@
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct AnalyticsPromptScreenCheckmarkItem: View {
|
||||
/// Represents the position of a checkmark item in a list.
|
||||
enum ListPosition {
|
||||
case top, middle, bottom
|
||||
|
||||
/// The corners that should be rounded for this position.
|
||||
var roundedCorners: UIRectCorner {
|
||||
switch self {
|
||||
case .top:
|
||||
return [.topLeft, .topRight]
|
||||
case .middle:
|
||||
return []
|
||||
case .bottom:
|
||||
return [.bottomLeft, .bottomRight]
|
||||
}
|
||||
/// Represents the position of a checkmark item in a list.
|
||||
enum ListPosition {
|
||||
case top, middle, bottom
|
||||
|
||||
/// The corners that should be rounded for this position.
|
||||
var roundedCorners: UIRectCorner {
|
||||
switch self {
|
||||
case .top:
|
||||
return [.topLeft, .topRight]
|
||||
case .middle:
|
||||
return []
|
||||
case .bottom:
|
||||
return [.bottomLeft, .bottomRight]
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct RoundedLabelItem<Icon: View>: View {
|
||||
let title: String
|
||||
let listPosition: ListPosition
|
||||
let iconContent: () -> Icon
|
||||
|
||||
var body: some View {
|
||||
Label { Text(title) } icon: {
|
||||
Image(systemName: "checkmark.circle")
|
||||
.symbolVariant(.fill)
|
||||
.symbolRenderingMode(.palette)
|
||||
.foregroundStyle(Color.compound.iconAccentTertiary, Color.compound.textOnSolidPrimary)
|
||||
iconContent()
|
||||
}
|
||||
.labelStyle(CheckmarkLabelStyle())
|
||||
.padding(.horizontal, 20)
|
||||
@ -68,14 +66,32 @@ private struct CheckmarkLabelStyle: LabelStyle {
|
||||
|
||||
struct AnalyticsPromptScreenCheckmarkItem_Previews: PreviewProvider {
|
||||
static let strings = AnalyticsPromptScreenStrings(termsURL: ServiceLocator.shared.settings.analyticsConfiguration.termsURL)
|
||||
|
||||
@ViewBuilder
|
||||
static var testImage1: some View {
|
||||
Image(systemName: "circle")
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
static var testImage2: some View {
|
||||
Image(systemName: "square")
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
AnalyticsPromptScreenCheckmarkItem(title: strings.point1, listPosition: .top)
|
||||
AnalyticsPromptScreenCheckmarkItem(title: strings.point2, listPosition: .middle)
|
||||
AnalyticsPromptScreenCheckmarkItem(title: "This is a short string.", listPosition: .middle)
|
||||
AnalyticsPromptScreenCheckmarkItem(title: "This is a very long string that will be used to test the layout over multiple lines of text to ensure everything is correct.",
|
||||
listPosition: .bottom)
|
||||
RoundedLabelItem(title: strings.point1, listPosition: .top) {
|
||||
testImage1
|
||||
}
|
||||
RoundedLabelItem(title: strings.point2, listPosition: .middle) {
|
||||
testImage2
|
||||
}
|
||||
RoundedLabelItem(title: "This is a short string.", listPosition: .middle) {
|
||||
testImage1
|
||||
}
|
||||
RoundedLabelItem(title: "This is a very long string that will be used to test the layout over multiple lines of text to ensure everything is correct.",
|
||||
listPosition: .bottom) {
|
||||
testImage2
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
}
|
@ -29,7 +29,9 @@ struct UIConstants {
|
||||
|
||||
/// The padding used to the top of the view for breaker screens that don't have a navigation bar.
|
||||
static let onboardingBreakerScreenTopPadding: CGFloat = 80
|
||||
|
||||
|
||||
static let welcomeScreenTopPadding: CGFloat = 122
|
||||
|
||||
/// The height to use for top/bottom spacers to pad the views to fit the `maxContentHeight`.
|
||||
static func spacerHeight(in geometry: GeometryProxy) -> CGFloat {
|
||||
max(0, (geometry.size.height - maxContentHeight) / 2)
|
||||
|
@ -0,0 +1,108 @@
|
||||
//
|
||||
// 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 WelcomeScreen: View {
|
||||
@ScaledMetric var iconSize = 20
|
||||
@ObservedObject var context: WelcomeScreenScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
FullscreenDialog(topPadding: UIConstants.welcomeScreenTopPadding) {
|
||||
mainContent
|
||||
} bottomContent: {
|
||||
button
|
||||
}
|
||||
.background(OnboardingBackgroundImage())
|
||||
.environment(\.backgroundStyle, AnyShapeStyle(Color.clear))
|
||||
.onAppear {
|
||||
context.send(viewAction: .appeared)
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var mainContent: some View {
|
||||
VStack(spacing: 42) {
|
||||
header
|
||||
list
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var header: some View {
|
||||
VStack(spacing: 32) {
|
||||
Image(asset: Asset.Images.launchLogo)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(width: 118, height: 118)
|
||||
.accessibilityHidden(true)
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var title: some View {
|
||||
VStack(spacing: 12) {
|
||||
Text(context.viewState.title)
|
||||
.font(Font.compound.headingLGBold)
|
||||
.foregroundColor(Color.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
Text(context.viewState.subtitle)
|
||||
.font(Font.compound.bodyMD)
|
||||
.foregroundColor(Color.compound.textPrimary)
|
||||
.multilineTextAlignment(.center)
|
||||
}
|
||||
}
|
||||
|
||||
private var list: some View {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
RoundedLabelItem(title: context.viewState.bullet1, listPosition: .top) {
|
||||
Image(systemName: "exclamationmark.transmission")
|
||||
.foregroundColor(.compound.iconSecondary)
|
||||
}
|
||||
RoundedLabelItem(title: context.viewState.bullet2, listPosition: .middle) {
|
||||
Image(systemName: "lock")
|
||||
.foregroundColor(.compound.iconSecondary)
|
||||
}
|
||||
RoundedLabelItem(title: context.viewState.bullet3, listPosition: .bottom) {
|
||||
Image(systemName: "plus.bubble")
|
||||
.foregroundColor(.compound.iconSecondary)
|
||||
}
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
|
||||
@ViewBuilder
|
||||
private var button: some View {
|
||||
Button {
|
||||
context.send(viewAction: .doneTapped)
|
||||
} label: {
|
||||
Text(context.viewState.buttonTitle)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct WelcomeScreen_Previews: PreviewProvider {
|
||||
static let viewModel = WelcomeScreenScreenViewModel()
|
||||
|
||||
static var previews: some View {
|
||||
WelcomeScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
//
|
||||
// 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
|
||||
|
||||
enum WelcomeScreenScreenCoordinatorAction {
|
||||
case dismiss
|
||||
}
|
||||
|
||||
final class WelcomeScreenScreenCoordinator: CoordinatorProtocol {
|
||||
private var viewModel: WelcomeScreenScreenViewModelProtocol
|
||||
private let actionsSubject: PassthroughSubject<WelcomeScreenScreenCoordinatorAction, Never> = .init()
|
||||
private var cancellables: Set<AnyCancellable> = .init()
|
||||
|
||||
var actions: AnyPublisher<WelcomeScreenScreenCoordinatorAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init() {
|
||||
viewModel = WelcomeScreenScreenViewModel()
|
||||
}
|
||||
|
||||
func start() {
|
||||
viewModel.actions.sink { [weak self] action in
|
||||
guard let self else { return }
|
||||
switch action {
|
||||
case .dismiss:
|
||||
actionsSubject.send(.dismiss)
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func toPresentable() -> AnyView {
|
||||
AnyView(WelcomeScreen(context: viewModel.context))
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright 2022 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum WelcomeScreenScreenViewModelAction {
|
||||
case dismiss
|
||||
}
|
||||
|
||||
struct WelcomeScreenScreenViewState: BindableState {
|
||||
let title = L10n.screenWelcomeTitle(InfoPlistReader.main.bundleDisplayName)
|
||||
let subtitle = L10n.screenWelcomeSubtitle
|
||||
let bullet1 = L10n.screenWelcomeBullet1
|
||||
let bullet2 = L10n.screenWelcomeBullet2
|
||||
let bullet3 = L10n.screenWelcomeBullet3
|
||||
let buttonTitle = L10n.screenWelcomeButton
|
||||
}
|
||||
|
||||
enum WelcomeScreenScreenViewAction {
|
||||
case doneTapped
|
||||
case appeared
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//
|
||||
// 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 WelcomeScreenScreenViewModelType = StateStoreViewModel<WelcomeScreenScreenViewState, WelcomeScreenScreenViewAction>
|
||||
|
||||
class WelcomeScreenScreenViewModel: WelcomeScreenScreenViewModelType, WelcomeScreenScreenViewModelProtocol {
|
||||
let appSettings: AppSettings
|
||||
private var actionsSubject: PassthroughSubject<WelcomeScreenScreenViewModelAction, Never> = .init()
|
||||
|
||||
var actions: AnyPublisher<WelcomeScreenScreenViewModelAction, Never> {
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
init(appSettings: AppSettings = ServiceLocator.shared.settings) {
|
||||
self.appSettings = appSettings
|
||||
super.init(initialViewState: WelcomeScreenScreenViewState())
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: WelcomeScreenScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .doneTapped:
|
||||
actionsSubject.send(.dismiss)
|
||||
case .appeared:
|
||||
appSettings.hasShownWelcomeScreen = true
|
||||
}
|
||||
}
|
||||
}
|
@ -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 WelcomeScreenScreenViewModelProtocol {
|
||||
var actions: AnyPublisher<WelcomeScreenScreenViewModelAction, Never> { get }
|
||||
var context: WelcomeScreenScreenViewModelType.Context { get }
|
||||
}
|
21
UITests/Sources/WelcomeScreenScreenUITests.swift
Normal file
21
UITests/Sources/WelcomeScreenScreenUITests.swift
Normal file
@ -0,0 +1,21 @@
|
||||
//
|
||||
// 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 ElementX
|
||||
import XCTest
|
||||
|
||||
@MainActor
|
||||
class WelcomeScreenScreenUITests: XCTestCase { }
|
22
UnitTests/Sources/WelcomeScreenScreenViewModelTests.swift
Normal file
22
UnitTests/Sources/WelcomeScreenScreenViewModelTests.swift
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// 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 XCTest
|
||||
|
||||
@testable import ElementX
|
||||
|
||||
@MainActor
|
||||
class WelcomeScreenScreenViewModelTests: XCTestCase { }
|
1
changelog.d/pr-1259.feature
Normal file
1
changelog.d/pr-1259.feature
Normal file
@ -0,0 +1 @@
|
||||
Added a welcome screen that will appear only once.
|
Loading…
x
Reference in New Issue
Block a user