mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Room screen header (#86)
* #35 Create `ElementNavigationController` subclass * #35 Add encryption icons * #35 Add avatar and encryption badge image to the room screen view model * #35 Create `RoomHeaderView` class * #35 Replace room title with a RoomHeaderView instance in the toolbar * #35 Add changelog * #35 Introduce `UITestScreenIdentifier` and refactor ui tests * #35 Fix old tests * #35 add some tests for room screen * #35 Use svgs instead of pngs * #35 Fix PR remarks
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C070FD43DC6BF4E50217965A /* LocalizationTests.swift */; };
|
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C070FD43DC6BF4E50217965A /* LocalizationTests.swift */; };
|
||||||
|
004561D297DC8B9786AE136F /* UITestScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */; };
|
||||||
00AC53151BA23A90FAAE9FBF /* BugReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D607F47FDEF16CC63684BE0 /* BugReport.swift */; };
|
00AC53151BA23A90FAAE9FBF /* BugReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D607F47FDEF16CC63684BE0 /* BugReport.swift */; };
|
||||||
00F3059B1E0CFCA019710C3E /* BugReportModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B516212D9FE785DDD5E490D1 /* BugReportModels.swift */; };
|
00F3059B1E0CFCA019710C3E /* BugReportModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B516212D9FE785DDD5E490D1 /* BugReportModels.swift */; };
|
||||||
01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */; };
|
01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */; };
|
||||||
@@ -15,10 +16,12 @@
|
|||||||
02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218AB05B4E3889731959C5F1 /* EventBasedTimelineItemProtocol.swift */; };
|
02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218AB05B4E3889731959C5F1 /* EventBasedTimelineItemProtocol.swift */; };
|
||||||
03B8FEA668A5B76A93113BB1 /* MemberDetailProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */; };
|
03B8FEA668A5B76A93113BB1 /* MemberDetailProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */; };
|
||||||
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */; };
|
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */; };
|
||||||
|
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 422724361B6555364C43281E /* RoomHeaderView.swift */; };
|
||||||
05776B005C57E92582F0CF08 /* BuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F87116470221880017CF522 /* BuildSettings.swift */; };
|
05776B005C57E92582F0CF08 /* BuildSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F87116470221880017CF522 /* BuildSettings.swift */; };
|
||||||
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
||||||
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */; };
|
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */; };
|
||||||
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
||||||
|
06E93B2E3B32740B40F47CC5 /* ElementNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */; };
|
||||||
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
||||||
0B1F80C2BF7D223159FBA82C /* ImageAnonymizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */; };
|
0B1F80C2BF7D223159FBA82C /* ImageAnonymizerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */; };
|
||||||
0E8C480700870BB34A2A360F /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; };
|
0E8C480700870BB34A2A360F /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; };
|
||||||
@@ -121,6 +124,7 @@
|
|||||||
7002C55A4C917F3715765127 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */; };
|
7002C55A4C917F3715765127 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */; };
|
||||||
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
||||||
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */; };
|
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */; };
|
||||||
|
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */; };
|
||||||
7756C4E90CABE6F14F7920A0 /* BugReportUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */; };
|
7756C4E90CABE6F14F7920A0 /* BugReportUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */; };
|
||||||
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
||||||
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
||||||
@@ -336,6 +340,7 @@
|
|||||||
40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
|
||||||
4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = "<group>"; };
|
4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = "<group>"; };
|
||||||
4112D04077F6709C5CA0A13E /* FullscreenLoadingViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingViewPresenter.swift; sourceTree = "<group>"; };
|
4112D04077F6709C5CA0A13E /* FullscreenLoadingViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingViewPresenter.swift; sourceTree = "<group>"; };
|
||||||
|
422724361B6555364C43281E /* RoomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHeaderView.swift; sourceTree = "<group>"; };
|
||||||
434522ED2BDED08759048077 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
434522ED2BDED08759048077 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
4411C0DA0087A1CB143E96FA /* EventBrief.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBrief.swift; sourceTree = "<group>"; };
|
4411C0DA0087A1CB143E96FA /* EventBrief.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBrief.swift; sourceTree = "<group>"; };
|
||||||
4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewPresenter.swift; sourceTree = "<group>"; };
|
4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewPresenter.swift; sourceTree = "<group>"; };
|
||||||
@@ -384,6 +389,7 @@
|
|||||||
5F12E996BFBEB43815189ABF /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
5F12E996BFBEB43815189ABF /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionProtocol.swift; sourceTree = "<group>"; };
|
5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionProtocol.swift; sourceTree = "<group>"; };
|
||||||
5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
||||||
|
5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestScreenIdentifier.swift; sourceTree = "<group>"; };
|
||||||
5FF214969B25BFCBF87B908B /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-BD"; path = "bn-BD.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
5FF214969B25BFCBF87B908B /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-BD"; path = "bn-BD.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxyProtocol.swift; sourceTree = "<group>"; };
|
6033779EB37259F27F938937 /* ClientProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientProxyProtocol.swift; sourceTree = "<group>"; };
|
||||||
6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAnonymizerTests.swift; sourceTree = "<group>"; };
|
6045E825AE900A92D61FEFF0 /* ImageAnonymizerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageAnonymizerTests.swift; sourceTree = "<group>"; };
|
||||||
@@ -539,6 +545,7 @@
|
|||||||
CED34C87277BA3CCC6B6EC7A /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CED34C87277BA3CCC6B6EC7A /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
CF3EDF23226895776553F04A /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
CF3EDF23226895776553F04A /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
CF47564C584F614B7287F3EB /* RootRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootRouter.swift; sourceTree = "<group>"; };
|
CF47564C584F614B7287F3EB /* RootRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootRouter.swift; sourceTree = "<group>"; };
|
||||||
|
CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementNavigationController.swift; sourceTree = "<group>"; };
|
||||||
CF847B3C1873B8E81CEE7FAC /* SplashScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModel.swift; sourceTree = "<group>"; };
|
CF847B3C1873B8E81CEE7FAC /* SplashScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = "<group>"; };
|
D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
||||||
@@ -1016,6 +1023,7 @@
|
|||||||
4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */,
|
4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */,
|
||||||
E18CF12478983A5EB390FB26 /* MessageComposer.swift */,
|
E18CF12478983A5EB390FB26 /* MessageComposer.swift */,
|
||||||
BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */,
|
BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */,
|
||||||
|
422724361B6555364C43281E /* RoomHeaderView.swift */,
|
||||||
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */,
|
5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */,
|
||||||
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */,
|
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */,
|
||||||
804F9B0FABE093C7284CD09B /* TimelineItemList.swift */,
|
804F9B0FABE093C7284CD09B /* TimelineItemList.swift */,
|
||||||
@@ -1248,6 +1256,7 @@
|
|||||||
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */,
|
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */,
|
||||||
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */,
|
E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */,
|
||||||
95CC95CD75B688E946438165 /* Coordinator.swift */,
|
95CC95CD75B688E946438165 /* Coordinator.swift */,
|
||||||
|
CF4B39D52CAE7D21D276ABEE /* ElementNavigationController.swift */,
|
||||||
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */,
|
12A626D74BBE9F4A60763B45 /* ImageAnonymizer.swift */,
|
||||||
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */,
|
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */,
|
||||||
44BBB96FAA2F0D53C507396B /* Extensions */,
|
44BBB96FAA2F0D53C507396B /* Extensions */,
|
||||||
@@ -1301,6 +1310,7 @@
|
|||||||
EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */,
|
EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */,
|
||||||
3F87116470221880017CF522 /* BuildSettings.swift */,
|
3F87116470221880017CF522 /* BuildSettings.swift */,
|
||||||
967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */,
|
967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */,
|
||||||
|
5FD9D66B75292F2CC11AA4D2 /* UITestScreenIdentifier.swift */,
|
||||||
CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */,
|
CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */,
|
||||||
0787F81684E503024BD0C051 /* Services */,
|
0787F81684E503024BD0C051 /* Services */,
|
||||||
E59565F441830B19DBAE567C /* Screens */,
|
E59565F441830B19DBAE567C /* Screens */,
|
||||||
@@ -1705,6 +1715,7 @@
|
|||||||
DCB781BD227CA958809AFADF /* Coordinator.swift in Sources */,
|
DCB781BD227CA958809AFADF /* Coordinator.swift in Sources */,
|
||||||
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
|
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */,
|
||||||
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */,
|
EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */,
|
||||||
|
06E93B2E3B32740B40F47CC5 /* ElementNavigationController.swift in Sources */,
|
||||||
D8CFF02C2730EE5BC4F17ABF /* ElementToggleStyle.swift in Sources */,
|
D8CFF02C2730EE5BC4F17ABF /* ElementToggleStyle.swift in Sources */,
|
||||||
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */,
|
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */,
|
||||||
224A55EEAEECF5336B14A4A5 /* EmoteRoomMessage.swift in Sources */,
|
224A55EEAEECF5336B14A4A5 /* EmoteRoomMessage.swift in Sources */,
|
||||||
@@ -1764,6 +1775,7 @@
|
|||||||
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */,
|
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */,
|
||||||
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */,
|
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */,
|
||||||
53B9C2240C2F5533246EE230 /* RectangleToastView.swift in Sources */,
|
53B9C2240C2F5533246EE230 /* RectangleToastView.swift in Sources */,
|
||||||
|
04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */,
|
||||||
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */,
|
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */,
|
||||||
8D9F646387DF656EF91EE4CB /* RoomMessageFactoryProtocol.swift in Sources */,
|
8D9F646387DF656EF91EE4CB /* RoomMessageFactoryProtocol.swift in Sources */,
|
||||||
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */,
|
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */,
|
||||||
@@ -1824,6 +1836,7 @@
|
|||||||
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */,
|
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */,
|
||||||
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
|
36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */,
|
||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
||||||
|
004561D297DC8B9786AE136F /* UITestScreenIdentifier.swift in Sources */,
|
||||||
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */,
|
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */,
|
||||||
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */,
|
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */,
|
||||||
8775F46AE3234A5A5688C19D /* UserIndicator.swift in Sources */,
|
8775F46AE3234A5A5688C19D /* UserIndicator.swift in Sources */,
|
||||||
@@ -1859,6 +1872,7 @@
|
|||||||
490E606044B18985055FF690 /* SettingsUITests.swift in Sources */,
|
490E606044B18985055FF690 /* SettingsUITests.swift in Sources */,
|
||||||
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */,
|
A00DFC1DD3567B1EDC9F8D16 /* SplashScreenUITests.swift in Sources */,
|
||||||
2E68C57E7D644E94778743D5 /* TemplateSimpleScreenUITests.swift in Sources */,
|
2E68C57E7D644E94778743D5 /* TemplateSimpleScreenUITests.swift in Sources */,
|
||||||
|
75D98001C5AC38B6A5CA897C /* UITestScreenIdentifier.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "encryption_normal.svg",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.09949 11.4627C6.06108 11.4727 6.02775 11.481 6 11.4876C5.97225 11.481 5.93892 11.4727 5.90051 11.4627C5.76801 11.4282 5.57572 11.3731 5.34366 11.2926C4.87791 11.1309 4.2608 10.8694 3.64749 10.4708C2.42721 9.67759 1.25 8.3665 1.25 6.2025V1.91207L6 0.521L10.75 1.91207V6.2025C10.75 8.3665 9.57279 9.67759 8.35251 10.4708C7.7392 10.8694 7.12209 11.1309 6.65634 11.2926C6.42428 11.3731 6.23199 11.4282 6.09949 11.4627Z" fill="#17191C" stroke="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 563 B |
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "encryption_trusted.svg",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.09949 11.4627C6.06108 11.4727 6.02775 11.481 6 11.4876C5.97225 11.481 5.93892 11.4727 5.90051 11.4627C5.76801 11.4282 5.57572 11.3731 5.34366 11.2926C4.87791 11.1309 4.2608 10.8694 3.64749 10.4708C2.42721 9.67759 1.25 8.3665 1.25 6.2025V1.91207L6 0.521L10.75 1.91207V6.2025C10.75 8.3665 9.57279 9.67759 8.35251 10.4708C7.7392 10.8694 7.12209 11.1309 6.65634 11.2926C6.42428 11.3731 6.23199 11.4282 6.09949 11.4627Z" fill="#0DBD8B" stroke="white"/>
|
||||||
|
<path d="M8.70785 3.4047C8.57285 3.2622 8.34785 3.2547 8.20535 3.3897L5.00285 6.3897L3.82535 5.5647C3.66785 5.4597 3.45035 5.4597 3.30035 5.5947C3.12035 5.7447 3.10535 6.0147 3.25535 6.1947L4.61285 7.7547C4.63535 7.7772 4.65785 7.8072 4.68785 7.8222C4.94285 8.0322 5.32535 7.9947 5.53535 7.7397L5.55785 7.7097L8.72285 3.8772C8.82785 3.7422 8.82785 3.5397 8.70785 3.4047Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 950 B |
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "encryption_warning.svg",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.09949 11.4627C6.06108 11.4727 6.02775 11.481 6 11.4876C5.97225 11.481 5.93892 11.4727 5.90051 11.4627C5.76801 11.4282 5.57572 11.3731 5.34366 11.2926C4.87791 11.1309 4.2608 10.8694 3.64749 10.4708C2.42721 9.67759 1.25 8.3665 1.25 6.2025V1.91207L6 0.521L10.75 1.91207V6.2025C10.75 8.3665 9.57279 9.67759 8.35251 10.4708C7.7392 10.8694 7.12209 11.1309 6.65634 11.2926C6.42428 11.3731 6.23199 11.4282 6.09949 11.4627Z" fill="#FF4B55" stroke="white"/>
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.42634 4.03626C5.39822 3.71563 5.63447 3.43438 5.95509 3.41188C6.27009 3.38938 6.55134 3.62563 6.58509 3.94626V4.03626L6.40509 6.28626C6.38822 6.49438 6.21384 6.65188 6.00572 6.65188H5.97197C5.77509 6.63501 5.62322 6.48313 5.60634 6.28626L5.42634 4.03626ZM6.49439 7.75379C6.49439 8.02717 6.27278 8.24879 5.99939 8.24879C5.72601 8.24879 5.50439 8.02717 5.50439 7.75379C5.50439 7.48041 5.72601 7.25879 5.99939 7.25879C6.27278 7.25879 6.49439 7.48041 6.49439 7.75379Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -44,7 +44,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
splashViewController = SplashViewController()
|
splashViewController = SplashViewController()
|
||||||
mainNavigationController = UINavigationController(rootViewController: splashViewController)
|
mainNavigationController = ElementNavigationController(rootViewController: splashViewController)
|
||||||
window = UIWindow(frame: UIScreen.main.bounds)
|
window = UIWindow(frame: UIScreen.main.bounds)
|
||||||
window.rootViewController = mainNavigationController
|
window.rootViewController = mainNavigationController
|
||||||
window.tintColor = .element.accent
|
window.tintColor = .element.accent
|
||||||
@@ -251,7 +251,9 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
memberDetailProvider: memberDetailProvider)
|
memberDetailProvider: memberDetailProvider)
|
||||||
|
|
||||||
let parameters = RoomScreenCoordinatorParameters(timelineController: timelineController,
|
let parameters = RoomScreenCoordinatorParameters(timelineController: timelineController,
|
||||||
roomName: roomProxy.displayName ?? roomProxy.name)
|
roomName: roomProxy.displayName ?? roomProxy.name,
|
||||||
|
roomAvatar: userSession.mediaProvider.imageFromURLString(roomProxy.avatarURL),
|
||||||
|
roomEncryptionBadge: roomProxy.encryptionBadgeImage)
|
||||||
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||||
|
|
||||||
add(childCoordinator: coordinator)
|
add(childCoordinator: coordinator)
|
||||||
@@ -333,7 +335,7 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
|
|
||||||
add(childCoordinator: coordinator)
|
add(childCoordinator: coordinator)
|
||||||
coordinator.start()
|
coordinator.start()
|
||||||
let navController = UINavigationController(rootViewController: coordinator.toPresentable())
|
let navController = ElementNavigationController(rootViewController: coordinator.toPresentable())
|
||||||
navController.navigationBar.topItem?.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel,
|
navController.navigationBar.topItem?.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel,
|
||||||
target: self,
|
target: self,
|
||||||
action: #selector(dismissBugReportScreen))
|
action: #selector(dismissBugReportScreen))
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ internal typealias AssetImageTypeAlias = ImageAsset.Image
|
|||||||
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||||
internal enum Asset {
|
internal enum Asset {
|
||||||
internal enum Images {
|
internal enum Images {
|
||||||
|
internal static let encryptionNormal = ImageAsset(name: "Images/encryption_normal")
|
||||||
|
internal static let encryptionTrusted = ImageAsset(name: "Images/encryption_trusted")
|
||||||
|
internal static let encryptionWarning = ImageAsset(name: "Images/encryption_warning")
|
||||||
internal static let splashScreenPage1 = ImageAsset(name: "Images/Splash Screen Page 1")
|
internal static let splashScreenPage1 = ImageAsset(name: "Images/Splash Screen Page 1")
|
||||||
internal static let splashScreenPage2 = ImageAsset(name: "Images/Splash Screen Page 2")
|
internal static let splashScreenPage2 = ImageAsset(name: "Images/Splash Screen Page 2")
|
||||||
internal static let splashScreenPage3 = ImageAsset(name: "Images/Splash Screen Page 3")
|
internal static let splashScreenPage3 = ImageAsset(name: "Images/Splash Screen Page 3")
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// ElementNavigationController.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Ismail on 20.06.2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class ElementNavigationController: UINavigationController {
|
||||||
|
|
||||||
|
override func viewWillLayoutSubviews() {
|
||||||
|
super.viewWillLayoutSubviews()
|
||||||
|
navigationBar.topItem?.backButtonDisplayMode = .minimal
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -44,7 +44,7 @@ class NavigationRouterStore: NavigationRouterStoreProtocol {
|
|||||||
return existingNavigationRouter
|
return existingNavigationRouter
|
||||||
}
|
}
|
||||||
|
|
||||||
let navigationRouter = NavigationRouter(navigationController: UINavigationController())
|
let navigationRouter = NavigationRouter(navigationController: ElementNavigationController())
|
||||||
return navigationRouter
|
return navigationRouter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import SwiftUI
|
|||||||
struct RoomScreenCoordinatorParameters {
|
struct RoomScreenCoordinatorParameters {
|
||||||
let timelineController: RoomTimelineControllerProtocol
|
let timelineController: RoomTimelineControllerProtocol
|
||||||
let roomName: String?
|
let roomName: String?
|
||||||
|
let roomAvatar: UIImage?
|
||||||
|
let roomEncryptionBadge: UIImage?
|
||||||
}
|
}
|
||||||
|
|
||||||
final class RoomScreenCoordinator: Coordinator, Presentable {
|
final class RoomScreenCoordinator: Coordinator, Presentable {
|
||||||
@@ -43,7 +45,9 @@ final class RoomScreenCoordinator: Coordinator, Presentable {
|
|||||||
|
|
||||||
let viewModel = RoomScreenViewModel(timelineController: parameters.timelineController,
|
let viewModel = RoomScreenViewModel(timelineController: parameters.timelineController,
|
||||||
timelineViewFactory: RoomTimelineViewFactory(),
|
timelineViewFactory: RoomTimelineViewFactory(),
|
||||||
roomName: parameters.roomName)
|
roomName: parameters.roomName,
|
||||||
|
roomAvatar: parameters.roomAvatar,
|
||||||
|
roomEncryptionBadge: parameters.roomEncryptionBadge)
|
||||||
|
|
||||||
let view = RoomScreen(context: viewModel.context)
|
let view = RoomScreen(context: viewModel.context)
|
||||||
roomScreenViewModel = viewModel
|
roomScreenViewModel = viewModel
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
enum RoomScreenViewModelAction {
|
enum RoomScreenViewModelAction {
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ enum RoomScreenViewAction {
|
|||||||
|
|
||||||
struct RoomScreenViewState: BindableState {
|
struct RoomScreenViewState: BindableState {
|
||||||
var roomTitle: String = ""
|
var roomTitle: String = ""
|
||||||
|
var roomAvatar: UIImage?
|
||||||
|
var roomEncryptionBadge: UIImage?
|
||||||
var items: [RoomTimelineViewProvider] = []
|
var items: [RoomTimelineViewProvider] = []
|
||||||
var isBackPaginating = false
|
var isBackPaginating = false
|
||||||
var bindings: RoomScreenViewStateBindings
|
var bindings: RoomScreenViewStateBindings
|
||||||
|
|||||||
@@ -31,11 +31,16 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
|
|
||||||
init(timelineController: RoomTimelineControllerProtocol,
|
init(timelineController: RoomTimelineControllerProtocol,
|
||||||
timelineViewFactory: RoomTimelineViewFactoryProtocol,
|
timelineViewFactory: RoomTimelineViewFactoryProtocol,
|
||||||
roomName: String?) {
|
roomName: String?,
|
||||||
|
roomAvatar: UIImage? = nil,
|
||||||
|
roomEncryptionBadge: UIImage? = nil) {
|
||||||
self.timelineController = timelineController
|
self.timelineController = timelineController
|
||||||
self.timelineViewFactory = timelineViewFactory
|
self.timelineViewFactory = timelineViewFactory
|
||||||
|
|
||||||
super.init(initialViewState: RoomScreenViewState(roomTitle: roomName ?? "Unknown room 💥", bindings: RoomScreenViewStateBindings(composerText: "")))
|
super.init(initialViewState: RoomScreenViewState(roomTitle: roomName ?? "Unknown room 💥",
|
||||||
|
roomAvatar: roomAvatar,
|
||||||
|
roomEncryptionBadge: roomEncryptionBadge,
|
||||||
|
bindings: .init(composerText: "")))
|
||||||
|
|
||||||
timelineController.callbacks
|
timelineController.callbacks
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
//
|
||||||
|
// RoomHeaderView.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Ismail on 21.06.2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
import Introspect
|
||||||
|
|
||||||
|
struct RoomHeaderView: View {
|
||||||
|
|
||||||
|
@ObservedObject var context: RoomScreenViewModel.Context
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack(spacing: 8) {
|
||||||
|
roomAvatar
|
||||||
|
Text(context.viewState.roomTitle)
|
||||||
|
.font(.element.headline)
|
||||||
|
.accessibilityIdentifier("roomNameLabel")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder private var roomAvatar: some View {
|
||||||
|
ZStack(alignment: .bottomTrailing) {
|
||||||
|
roomAvatarImage
|
||||||
|
.clipShape(Circle())
|
||||||
|
|
||||||
|
if let encryptionBadge = context.viewState.roomEncryptionBadge {
|
||||||
|
Image(uiImage: encryptionBadge)
|
||||||
|
.accessibilityIdentifier("encryptionBadgeIcon")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(width: 32.0, height: 32.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder private var roomAvatarImage: some View {
|
||||||
|
if let avatar = context.viewState.roomAvatar {
|
||||||
|
Image(uiImage: avatar)
|
||||||
|
.resizable()
|
||||||
|
.scaledToFill()
|
||||||
|
.accessibilityIdentifier("roomAvatarImage")
|
||||||
|
} else {
|
||||||
|
PlaceholderAvatarImage(firstCharacter: String(context.viewState.roomTitle.first ?? Character("")))
|
||||||
|
.accessibilityIdentifier("roomAvatarPlaceholderImage")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RoomHeaderView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
bodyPlain.preferredColorScheme(.light)
|
||||||
|
bodyPlain.preferredColorScheme(.dark)
|
||||||
|
bodyEncrypted.preferredColorScheme(.light)
|
||||||
|
bodyEncrypted.preferredColorScheme(.dark)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
static var bodyPlain: some View {
|
||||||
|
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||||
|
timelineViewFactory: RoomTimelineViewFactory(),
|
||||||
|
roomName: "Some Room name",
|
||||||
|
roomAvatar: Asset.Images.appLogo.image
|
||||||
|
)
|
||||||
|
|
||||||
|
RoomHeaderView(context: viewModel.context)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ViewBuilder
|
||||||
|
static var bodyEncrypted: some View {
|
||||||
|
let viewModel = RoomScreenViewModel(timelineController: MockRoomTimelineController(),
|
||||||
|
timelineViewFactory: RoomTimelineViewFactory(),
|
||||||
|
roomName: "Some Room name",
|
||||||
|
roomAvatar: Asset.Images.appLogo.image,
|
||||||
|
roomEncryptionBadge: Asset.Images.encryptionTrusted.image
|
||||||
|
)
|
||||||
|
|
||||||
|
RoomHeaderView(context: viewModel.context)
|
||||||
|
.previewLayout(.sizeThatFits)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,8 +28,12 @@ struct RoomScreen: View {
|
|||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
.navigationTitle(context.viewState.roomTitle)
|
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
.navigationBarTitleDisplayMode(.inline)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .navigationBarLeading) {
|
||||||
|
RoomHeaderView(context: context)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func sendMessage() {
|
private func sendMessage() {
|
||||||
|
|||||||
@@ -83,6 +83,15 @@ class RoomProxy: RoomProxyProtocol {
|
|||||||
var avatarURL: String? {
|
var avatarURL: String? {
|
||||||
room.avatarUrl()
|
room.avatarUrl()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encryptionBadgeImage: UIImage? {
|
||||||
|
guard isEncrypted else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// return trusted image for now, should be updated after verification status known
|
||||||
|
return Asset.Images.encryptionTrusted.image
|
||||||
|
}
|
||||||
|
|
||||||
func loadAvatarURLForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
func loadAvatarURLForUserId(_ userId: String) async -> Result<String?, RoomProxyError> {
|
||||||
await Task.detached { () -> Result<String?, RoomProxyError> in
|
await Task.detached { () -> Result<String?, RoomProxyError> in
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// ScreenIdentifier.swift
|
||||||
|
// ElementX
|
||||||
|
//
|
||||||
|
// Created by Ismail on 21.06.2022.
|
||||||
|
// Copyright © 2022 Element. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
enum UITestScreenIdentifier: String {
|
||||||
|
case login
|
||||||
|
case simpleRegular
|
||||||
|
case simpleUpgrade
|
||||||
|
case settings
|
||||||
|
case bugReport
|
||||||
|
case bugReportWithScreenshot
|
||||||
|
case splash
|
||||||
|
case roomPlainNoAvatar
|
||||||
|
case roomEncryptedWithAvatar
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UITestScreenIdentifier: CustomStringConvertible {
|
||||||
|
var description: String {
|
||||||
|
return rawValue.titlecased()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UITestScreenIdentifier: CaseIterable { }
|
||||||
|
|
||||||
|
private extension String {
|
||||||
|
func titlecased() -> String {
|
||||||
|
replacingOccurrences(of: "([A-Z])",
|
||||||
|
with: " $1",
|
||||||
|
options: .regularExpression,
|
||||||
|
range: range(of: self))
|
||||||
|
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
.capitalized
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,19 +40,45 @@ class UITestsAppCoordinator: Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func mockScreens() -> [MockScreen] {
|
private func mockScreens() -> [MockScreen] {
|
||||||
[
|
UITestScreenIdentifier.allCases.map { MockScreen(id: $0) }
|
||||||
MockScreen(id: "Login screen", coordinator: LoginScreenCoordinator(parameters: .init())),
|
|
||||||
MockScreen(id: "Simple Screen - Regular", coordinator: TemplateSimpleScreenCoordinator(parameters: .init(promptType: .regular))),
|
|
||||||
MockScreen(id: "Simple Screen - Upgrade", coordinator: TemplateSimpleScreenCoordinator(parameters: .init(promptType: .upgrade))),
|
|
||||||
MockScreen(id: "Settings screen", coordinator: SettingsCoordinator(parameters: .init(navigationRouter: NavigationRouter(navigationController: UINavigationController()), bugReportService: MockBugReportService()))),
|
|
||||||
MockScreen(id: "Bug report screen", coordinator: BugReportCoordinator(parameters: .init(bugReportService: MockBugReportService(), screenshot: nil))),
|
|
||||||
MockScreen(id: "Bug report screen with screenshot", coordinator: BugReportCoordinator(parameters: .init(bugReportService: MockBugReportService(), screenshot: Asset.Images.appLogo.image))),
|
|
||||||
MockScreen(id: "Splash Screen", coordinator: SplashScreenCoordinator())
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
struct MockScreen: Identifiable {
|
struct MockScreen: Identifiable {
|
||||||
let id: String
|
let id: UITestScreenIdentifier
|
||||||
let coordinator: Coordinator & Presentable
|
var coordinator: Coordinator & Presentable {
|
||||||
|
switch id {
|
||||||
|
case .login:
|
||||||
|
return LoginScreenCoordinator(parameters: .init())
|
||||||
|
case .simpleRegular:
|
||||||
|
return TemplateSimpleScreenCoordinator(parameters: .init(promptType: .regular))
|
||||||
|
case .simpleUpgrade:
|
||||||
|
return TemplateSimpleScreenCoordinator(parameters: .init(promptType: .upgrade))
|
||||||
|
case .settings:
|
||||||
|
let router = NavigationRouter(navigationController: ElementNavigationController())
|
||||||
|
return SettingsCoordinator(parameters: .init(navigationRouter: router,
|
||||||
|
bugReportService: MockBugReportService()))
|
||||||
|
case .bugReport:
|
||||||
|
return BugReportCoordinator(parameters: .init(bugReportService: MockBugReportService(),
|
||||||
|
screenshot: nil))
|
||||||
|
case .bugReportWithScreenshot:
|
||||||
|
return BugReportCoordinator(parameters: .init(bugReportService: MockBugReportService(),
|
||||||
|
screenshot: Asset.Images.appLogo.image))
|
||||||
|
case .splash:
|
||||||
|
return SplashScreenCoordinator()
|
||||||
|
case .roomPlainNoAvatar:
|
||||||
|
let params = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
||||||
|
roomName: "Some room name",
|
||||||
|
roomAvatar: nil,
|
||||||
|
roomEncryptionBadge: nil)
|
||||||
|
return RoomScreenCoordinator(parameters: params)
|
||||||
|
case .roomEncryptedWithAvatar:
|
||||||
|
let params = RoomScreenCoordinatorParameters(timelineController: MockRoomTimelineController(),
|
||||||
|
roomName: "Some room name",
|
||||||
|
roomAvatar: Asset.Images.appLogo.image,
|
||||||
|
roomEncryptionBadge: Asset.Images.encryptionTrusted.image)
|
||||||
|
return RoomScreenCoordinator(parameters: params)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,15 @@ import SwiftUI
|
|||||||
struct UITestsRootView: View {
|
struct UITestsRootView: View {
|
||||||
|
|
||||||
let mockScreens: [MockScreen]
|
let mockScreens: [MockScreen]
|
||||||
var selectionCallback: ((String) -> Void)?
|
var selectionCallback: ((UITestScreenIdentifier) -> Void)?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationView {
|
NavigationView {
|
||||||
List(mockScreens) { coordinator in
|
List(mockScreens) { coordinator in
|
||||||
Button(coordinator.id) {
|
Button(coordinator.id.description) {
|
||||||
selectionCallback?(coordinator.id)
|
selectionCallback?(coordinator.id)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(coordinator.id.rawValue)
|
||||||
}
|
}
|
||||||
.listStyle(.plain)
|
.listStyle(.plain)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -20,7 +20,7 @@ import ElementX
|
|||||||
class TemplateSimpleScreenUITests: XCTestCase {
|
class TemplateSimpleScreenUITests: XCTestCase {
|
||||||
func testRegularScreen() {
|
func testRegularScreen() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Simple Screen - Regular")
|
app.goToScreenWithIdentifier(.simpleRegular)
|
||||||
|
|
||||||
let title = app.staticTexts["title"]
|
let title = app.staticTexts["title"]
|
||||||
XCTAssert(title.exists)
|
XCTAssert(title.exists)
|
||||||
@@ -30,7 +30,7 @@ class TemplateSimpleScreenUITests: XCTestCase {
|
|||||||
|
|
||||||
func testUpgradeScreen() {
|
func testUpgradeScreen() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Simple Screen - Upgrade")
|
app.goToScreenWithIdentifier(.simpleUpgrade)
|
||||||
|
|
||||||
let title = app.staticTexts["title"]
|
let title = app.staticTexts["title"]
|
||||||
XCTAssert(title.exists)
|
XCTAssert(title.exists)
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ struct Application {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension XCUIApplication {
|
extension XCUIApplication {
|
||||||
func goToScreenWithIdentifier(_ identifier: String) {
|
func goToScreenWithIdentifier(_ identifier: UITestScreenIdentifier) {
|
||||||
let button = self.buttons[identifier]
|
let button = self.buttons[identifier.rawValue]
|
||||||
let lastLabel = staticTexts["lastItem"]
|
let lastLabel = staticTexts["lastItem"]
|
||||||
|
|
||||||
while !button.isHittable && !lastLabel.isHittable {
|
while !button.isHittable && !lastLabel.isHittable {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class BugReportUITests: XCTestCase {
|
|||||||
|
|
||||||
func testInitialStateComponents() {
|
func testInitialStateComponents() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Bug report screen")
|
app.goToScreenWithIdentifier(.bugReport)
|
||||||
|
|
||||||
XCTAssert(app.navigationBars["Bug report"].exists)
|
XCTAssert(app.navigationBars["Bug report"].exists)
|
||||||
XCTAssert(app.staticTexts["reportBugDescription"].exists)
|
XCTAssert(app.staticTexts["reportBugDescription"].exists)
|
||||||
@@ -40,7 +40,7 @@ class BugReportUITests: XCTestCase {
|
|||||||
|
|
||||||
func testToggleSendingLogs() {
|
func testToggleSendingLogs() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Bug report screen")
|
app.goToScreenWithIdentifier(.bugReport)
|
||||||
|
|
||||||
app.switches["sendLogsToggle"].tap()
|
app.switches["sendLogsToggle"].tap()
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ class BugReportUITests: XCTestCase {
|
|||||||
|
|
||||||
func testReportText() {
|
func testReportText() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Bug report screen")
|
app.goToScreenWithIdentifier(.bugReport)
|
||||||
|
|
||||||
// type 4 chars
|
// type 4 chars
|
||||||
app.textViews["reportTextView"].tap()
|
app.textViews["reportTextView"].tap()
|
||||||
@@ -66,7 +66,7 @@ class BugReportUITests: XCTestCase {
|
|||||||
|
|
||||||
func testInitialStateComponentsWithScreenshot() {
|
func testInitialStateComponentsWithScreenshot() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Bug report screen with screenshot")
|
app.goToScreenWithIdentifier(.bugReportWithScreenshot)
|
||||||
|
|
||||||
XCTAssert(app.navigationBars["Bug report"].exists)
|
XCTAssert(app.navigationBars["Bug report"].exists)
|
||||||
XCTAssert(app.staticTexts["reportBugDescription"].exists)
|
XCTAssert(app.staticTexts["reportBugDescription"].exists)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import XCTest
|
|||||||
class LoginScreenUITests: XCTestCase {
|
class LoginScreenUITests: XCTestCase {
|
||||||
func testInitialStateComponents() {
|
func testInitialStateComponents() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Login screen")
|
app.goToScreenWithIdentifier(.login)
|
||||||
|
|
||||||
XCTAssert(app.buttons["Login"].exists)
|
XCTAssert(app.buttons["Login"].exists)
|
||||||
XCTAssert(app.textFields["Username"].exists)
|
XCTAssert(app.textFields["Username"].exists)
|
||||||
|
|||||||
@@ -15,3 +15,30 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import XCTest
|
import XCTest
|
||||||
|
import ElementX
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
class RoomScreenUITests: XCTestCase {
|
||||||
|
|
||||||
|
func testPlainNoAvatar() async throws {
|
||||||
|
let app = Application.launch()
|
||||||
|
app.goToScreenWithIdentifier(.roomPlainNoAvatar)
|
||||||
|
|
||||||
|
try await Task.sleep(nanoseconds: 400_000_000)
|
||||||
|
|
||||||
|
XCTAssert(app.staticTexts["roomNameLabel"].exists)
|
||||||
|
XCTAssert(app.staticTexts["roomAvatarPlaceholderImage"].exists)
|
||||||
|
XCTAssertFalse(app.images["encryptionBadgeIcon"].exists)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEncryptedWithAvatar() async throws {
|
||||||
|
let app = Application.launch()
|
||||||
|
app.goToScreenWithIdentifier(.roomEncryptedWithAvatar)
|
||||||
|
|
||||||
|
try await Task.sleep(nanoseconds: 400_000_000)
|
||||||
|
|
||||||
|
XCTAssert(app.staticTexts["roomNameLabel"].exists)
|
||||||
|
XCTAssert(app.images["roomAvatarImage"].exists)
|
||||||
|
XCTAssert(app.images["encryptionBadgeIcon"].exists)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class SettingsUITests: XCTestCase {
|
|||||||
|
|
||||||
func testInitialStateComponents() {
|
func testInitialStateComponents() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Settings screen")
|
app.goToScreenWithIdentifier(.settings)
|
||||||
|
|
||||||
XCTAssert(app.navigationBars["Settings"].exists)
|
XCTAssert(app.navigationBars["Settings"].exists)
|
||||||
XCTAssert(app.buttons["reportBugButton"].exists)
|
XCTAssert(app.buttons["reportBugButton"].exists)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import XCTest
|
|||||||
class SplashScreenUITests: XCTestCase {
|
class SplashScreenUITests: XCTestCase {
|
||||||
func testInitialStateComponents() {
|
func testInitialStateComponents() {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Splash Screen")
|
app.goToScreenWithIdentifier(.splash)
|
||||||
|
|
||||||
let getStartedButton = app.buttons["Get started"]
|
let getStartedButton = app.buttons["Get started"]
|
||||||
XCTAssertTrue(getStartedButton.exists, "The primary action button should be shown.")
|
XCTAssertTrue(getStartedButton.exists, "The primary action button should be shown.")
|
||||||
@@ -28,7 +28,7 @@ class SplashScreenUITests: XCTestCase {
|
|||||||
|
|
||||||
func testSwipingBetweenPages() async throws {
|
func testSwipingBetweenPages() async throws {
|
||||||
let app = Application.launch()
|
let app = Application.launch()
|
||||||
app.goToScreenWithIdentifier("Splash Screen")
|
app.goToScreenWithIdentifier(.splash)
|
||||||
|
|
||||||
// Given the splash screen in its initial state.
|
// Given the splash screen in its initial state.
|
||||||
let page1TitleText = app.staticTexts["Own your conversations."]
|
let page1TitleText = app.staticTexts["Own your conversations."]
|
||||||
|
|||||||
@@ -41,3 +41,4 @@ targets:
|
|||||||
- path: ../SupportingFiles
|
- path: ../SupportingFiles
|
||||||
- path: ../../Tools/Scripts/Templates/SimpleScreenExample/Tests/UI
|
- path: ../../Tools/Scripts/Templates/SimpleScreenExample/Tests/UI
|
||||||
- path: ../../ElementX/Sources/BuildSettings.swift
|
- path: ../../ElementX/Sources/BuildSettings.swift
|
||||||
|
- path: ../../ElementX/Sources/UITestScreenIdentifier.swift
|
||||||
|
|||||||
@@ -28,22 +28,6 @@ class HomeScreenViewModelTests: XCTestCase {
|
|||||||
context = viewModel.context
|
context = viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor func testLogout() async throws {
|
|
||||||
var correctResult = false
|
|
||||||
viewModel.callback = { result in
|
|
||||||
switch result {
|
|
||||||
case .logout:
|
|
||||||
correctResult = true
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context.send(viewAction: .logout)
|
|
||||||
await Task.yield()
|
|
||||||
XCTAssert(correctResult)
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor func testSelectRoom() async throws {
|
@MainActor func testSelectRoom() async throws {
|
||||||
let mockRoomId = "mock_room_id"
|
let mockRoomId = "mock_room_id"
|
||||||
var correctResult = false
|
var correctResult = false
|
||||||
|
|||||||
@@ -29,8 +29,20 @@ class SettingsViewModelTests: XCTestCase {
|
|||||||
context = viewModel.context
|
context = viewModel.context
|
||||||
}
|
}
|
||||||
|
|
||||||
func testInitialState() {
|
@MainActor func testLogout() async throws {
|
||||||
XCTAssert(context.viewState.crashButtonVisible)
|
var correctResult = false
|
||||||
|
viewModel.callback = { result in
|
||||||
|
switch result {
|
||||||
|
case .logout:
|
||||||
|
correctResult = true
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.send(viewAction: .logout)
|
||||||
|
await Task.yield()
|
||||||
|
XCTAssert(correctResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testReportBug() async throws {
|
func testReportBug() async throws {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Room: Add header view containing room avatar and encryption badge.
|
||||||
Reference in New Issue
Block a user