Added room timeline screen with live events listening and back pagination. Rearranged project files.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
disabled_rules:
|
||||
- trailing_whitespace
|
||||
- unused_setter_value
|
||||
- redundant_discardable_let
|
||||
|
||||
# some rules are only opt-in
|
||||
opt_in_rules:
|
||||
|
||||
@@ -7,18 +7,6 @@
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
182BC42027BE667200A30C33 /* RoomModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC41F27BE667200A30C33 /* RoomModelProtocol.swift */; };
|
||||
182BC42227BE6C6900A30C33 /* MockRoomModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC42127BE6C6900A30C33 /* MockRoomModel.swift */; };
|
||||
182BC46F27C4CD6D00A30C33 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46527C4CD6D00A30C33 /* RoundedToastView.swift */; };
|
||||
182BC47027C4CD6D00A30C33 /* RectangleToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46627C4CD6D00A30C33 /* RectangleToastView.swift */; };
|
||||
182BC47127C4CD6D00A30C33 /* ActivityPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46727C4CD6D00A30C33 /* ActivityPresentable.swift */; };
|
||||
182BC47227C4CD6D00A30C33 /* ActivityCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46827C4CD6D00A30C33 /* ActivityCenter.swift */; };
|
||||
182BC47327C4CD6D00A30C33 /* ToastActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46A27C4CD6D00A30C33 /* ToastActivityPresenter.swift */; };
|
||||
182BC47527C4CD6D00A30C33 /* Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46C27C4CD6D00A30C33 /* Activity.swift */; };
|
||||
182BC47627C4CD6D00A30C33 /* ActivityRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46D27C4CD6D00A30C33 /* ActivityRequest.swift */; };
|
||||
182BC47727C4CD6D00A30C33 /* ActivityDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC46E27C4CD6D00A30C33 /* ActivityDismissal.swift */; };
|
||||
182BC47927C4CE2200A30C33 /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47827C4CE2200A30C33 /* LabelledActivityIndicatorView.swift */; };
|
||||
182BC47B27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 182BC47A27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift */; };
|
||||
182BC48127C4EBBB00A30C33 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 182BC48027C4EBBB00A30C33 /* Kingfisher */; };
|
||||
1850253F27B6918D002E6B18 /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850253E27B6918D002E6B18 /* ElementXTests.swift */; };
|
||||
1850254927B6918D002E6B18 /* ElementXUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1850254827B6918D002E6B18 /* ElementXUITests.swift */; };
|
||||
@@ -30,43 +18,68 @@
|
||||
1850257127B6A135002E6B18 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1850256927B6A135002E6B18 /* LaunchScreen.storyboard */; };
|
||||
1863A3FC27BA5A9100B52E4D /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 1863A3FB27BA5A9100B52E4D /* KeychainAccess */; };
|
||||
1863A40627BA6DFC00B52E4D /* SwiftyBeaver in Frameworks */ = {isa = PBXBuildFile; productRef = 1863A40527BA6DFC00B52E4D /* SwiftyBeaver */; };
|
||||
1863A41427BA716A00B52E4D /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A40E27BA716A00B52E4D /* AuthenticationCoordinator.swift */; };
|
||||
1863A41527BA716A00B52E4D /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A40F27BA716A00B52E4D /* UserSession.swift */; };
|
||||
1863A41627BA716A00B52E4D /* KeychainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A41027BA716A00B52E4D /* KeychainController.swift */; };
|
||||
1863A41727BA716A00B52E4D /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A41127BA716A00B52E4D /* KeychainControllerProtocol.swift */; };
|
||||
1863A41C27BA76B900B52E4D /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A41B27BA76B900B52E4D /* MXLog.swift */; };
|
||||
1863A42C27BA784300B52E4D /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A41F27BA784300B52E4D /* LoginScreenViewModel.swift */; };
|
||||
1863A43027BA784300B52E4D /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A42727BA784300B52E4D /* LoginScreenViewModelProtocol.swift */; };
|
||||
1863A43127BA784300B52E4D /* LoginScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A42827BA784300B52E4D /* LoginScreenModels.swift */; };
|
||||
1863A43227BA784300B52E4D /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A42A27BA784300B52E4D /* LoginScreen.swift */; };
|
||||
1863A43427BA786400B52E4D /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A42627BA784300B52E4D /* LoginScreenViewModelTests.swift */; };
|
||||
1863A43527BA788500B52E4D /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A42427BA784300B52E4D /* LoginScreenUITests.swift */; };
|
||||
1863A43A27BA789800B52E4D /* StateStoreViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A43827BA789800B52E4D /* StateStoreViewModel.swift */; };
|
||||
1863A43B27BA789800B52E4D /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A43927BA789800B52E4D /* BindableState.swift */; };
|
||||
1863A43F27BA790000B52E4D /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A43D27BA790000B52E4D /* Coordinator.swift */; };
|
||||
1863A44927BA79FF00B52E4D /* NavigationRouterStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44127BA79FF00B52E4D /* NavigationRouterStore.swift */; };
|
||||
1863A44A27BA79FF00B52E4D /* NavigationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44227BA79FF00B52E4D /* NavigationRouter.swift */; };
|
||||
1863A44B27BA79FF00B52E4D /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44327BA79FF00B52E4D /* RootRouterType.swift */; };
|
||||
1863A44C27BA79FF00B52E4D /* NavigationRouterStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44427BA79FF00B52E4D /* NavigationRouterStoreProtocol.swift */; };
|
||||
1863A44D27BA79FF00B52E4D /* RootRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44527BA79FF00B52E4D /* RootRouter.swift */; };
|
||||
1863A44E27BA79FF00B52E4D /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44627BA79FF00B52E4D /* Presentable.swift */; };
|
||||
1863A44F27BA79FF00B52E4D /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44727BA79FF00B52E4D /* NavigationModule.swift */; };
|
||||
1863A45027BA79FF00B52E4D /* NavigationRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A44827BA79FF00B52E4D /* NavigationRouterType.swift */; };
|
||||
1863A45627BA7A7800B52E4D /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45227BA7A7800B52E4D /* WeakDictionaryKeyReference.swift */; };
|
||||
1863A45727BA7A7800B52E4D /* WeakDictionaryReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45327BA7A7800B52E4D /* WeakDictionaryReference.swift */; };
|
||||
1863A45827BA7A7800B52E4D /* WeakDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45427BA7A7800B52E4D /* WeakDictionary.swift */; };
|
||||
1863A45927BA7A7800B52E4D /* WeakKeyDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45527BA7A7800B52E4D /* WeakKeyDictionary.swift */; };
|
||||
1863A45B27BA7B4700B52E4D /* LoginScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45A27BA7B4700B52E4D /* LoginScreenCoordinator.swift */; };
|
||||
1863A45F27BAA60300B52E4D /* SplashViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A45D27BAA60300B52E4D /* SplashViewController.swift */; };
|
||||
1863A46027BAA60300B52E4D /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1863A45E27BAA60300B52E4D /* SplashViewController.xib */; };
|
||||
1863A48527BAA8A900B52E4D /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A47927BAA8A900B52E4D /* HomeScreenCoordinator.swift */; };
|
||||
1863A48827BAA8A900B52E4D /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A47F27BAA8A900B52E4D /* HomeScreenViewModelProtocol.swift */; };
|
||||
1863A48927BAA8A900B52E4D /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A48027BAA8A900B52E4D /* HomeScreenModels.swift */; };
|
||||
1863A48A27BAA8A900B52E4D /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A48227BAA8A900B52E4D /* HomeScreen.swift */; };
|
||||
1863A48C27BAA8A900B52E4D /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A48427BAA8A900B52E4D /* HomeScreenViewModel.swift */; };
|
||||
1863A48E27BAA8C800B52E4D /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A47C27BAA8A900B52E4D /* HomeScreenUITests.swift */; };
|
||||
1863A48F27BAA8CC00B52E4D /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A47E27BAA8A900B52E4D /* HomeScreenViewModelTests.swift */; };
|
||||
1863A49427BAAA6700B52E4D /* RoomModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1863A49327BAAA6700B52E4D /* RoomModel.swift */; };
|
||||
18F2BAD727D25B4000DD1988 /* RoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */; };
|
||||
18F2BAD827D25B4000DD1988 /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7427D25B4000DD1988 /* RoomProxy.swift */; };
|
||||
18F2BAD927D25B4000DD1988 /* MockRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */; };
|
||||
18F2BADA27D25B4000DD1988 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */; };
|
||||
18F2BADB27D25B4000DD1988 /* AuthenticationCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */; };
|
||||
18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7A27D25B4000DD1988 /* UserSession.swift */; };
|
||||
18F2BADD27D25B4000DD1988 /* KeychainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7B27D25B4000DD1988 /* KeychainController.swift */; };
|
||||
18F2BADE27D25B4000DD1988 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7C27D25B4000DD1988 /* KeychainControllerProtocol.swift */; };
|
||||
18F2BADF27D25B4000DD1988 /* NavigationRouterStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA7F27D25B4000DD1988 /* NavigationRouterStore.swift */; };
|
||||
18F2BAE027D25B4000DD1988 /* NavigationRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8027D25B4000DD1988 /* NavigationRouter.swift */; };
|
||||
18F2BAE127D25B4000DD1988 /* RootRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8127D25B4000DD1988 /* RootRouterType.swift */; };
|
||||
18F2BAE227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift */; };
|
||||
18F2BAE327D25B4000DD1988 /* RootRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8327D25B4000DD1988 /* RootRouter.swift */; };
|
||||
18F2BAE427D25B4000DD1988 /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8427D25B4000DD1988 /* Presentable.swift */; };
|
||||
18F2BAE527D25B4000DD1988 /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8527D25B4000DD1988 /* NavigationModule.swift */; };
|
||||
18F2BAE627D25B4000DD1988 /* NavigationRouterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8627D25B4000DD1988 /* NavigationRouterType.swift */; };
|
||||
18F2BAE727D25B4000DD1988 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8927D25B4000DD1988 /* RoundedToastView.swift */; };
|
||||
18F2BAE827D25B4000DD1988 /* RectangleToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8A27D25B4000DD1988 /* RectangleToastView.swift */; };
|
||||
18F2BAE927D25B4000DD1988 /* ActivityPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8B27D25B4000DD1988 /* ActivityPresentable.swift */; };
|
||||
18F2BAEA27D25B4000DD1988 /* ActivityCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8C27D25B4000DD1988 /* ActivityCenter.swift */; };
|
||||
18F2BAEB27D25B4000DD1988 /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8D27D25B4000DD1988 /* LabelledActivityIndicatorView.swift */; };
|
||||
18F2BAEC27D25B4000DD1988 /* ToastActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA8F27D25B4000DD1988 /* ToastActivityPresenter.swift */; };
|
||||
18F2BAED27D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9027D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift */; };
|
||||
18F2BAEE27D25B4000DD1988 /* Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9127D25B4000DD1988 /* Activity.swift */; };
|
||||
18F2BAEF27D25B4000DD1988 /* ActivityRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9227D25B4000DD1988 /* ActivityRequest.swift */; };
|
||||
18F2BAF027D25B4000DD1988 /* ActivityDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9327D25B4000DD1988 /* ActivityDismissal.swift */; };
|
||||
18F2BAF127D25B4000DD1988 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9427D25B4000DD1988 /* MXLog.swift */; };
|
||||
18F2BAF227D25B4000DD1988 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9627D25B4000DD1988 /* WeakDictionaryKeyReference.swift */; };
|
||||
18F2BAF327D25B4000DD1988 /* WeakDictionaryReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9727D25B4000DD1988 /* WeakDictionaryReference.swift */; };
|
||||
18F2BAF427D25B4000DD1988 /* WeakDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9827D25B4000DD1988 /* WeakDictionary.swift */; };
|
||||
18F2BAF527D25B4000DD1988 /* WeakKeyDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9927D25B4000DD1988 /* WeakKeyDictionary.swift */; };
|
||||
18F2BAF627D25B4000DD1988 /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9A27D25B4000DD1988 /* Coordinator.swift */; };
|
||||
18F2BAF727D25B4000DD1988 /* StateStoreViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9D27D25B4000DD1988 /* StateStoreViewModel.swift */; };
|
||||
18F2BAF827D25B4000DD1988 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BA9E27D25B4000DD1988 /* BindableState.swift */; };
|
||||
18F2BAF927D25B4000DD1988 /* SplashViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAA127D25B4000DD1988 /* SplashViewController.swift */; };
|
||||
18F2BAFA27D25B4000DD1988 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18F2BAA227D25B4000DD1988 /* SplashViewController.xib */; };
|
||||
18F2BAFB27D25B4000DD1988 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAA427D25B4000DD1988 /* HomeScreenCoordinator.swift */; };
|
||||
18F2BAFE27D25B4000DD1988 /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAAA27D25B4000DD1988 /* HomeScreenViewModelProtocol.swift */; };
|
||||
18F2BAFF27D25B4000DD1988 /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAAB27D25B4000DD1988 /* HomeScreenModels.swift */; };
|
||||
18F2BB0027D25B4000DD1988 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAAD27D25B4000DD1988 /* HomeScreen.swift */; };
|
||||
18F2BB0127D25B4000DD1988 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAAE27D25B4000DD1988 /* HomeScreenViewModel.swift */; };
|
||||
18F2BB0C27D25B4000DD1988 /* RoomScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC427D25B4000DD1988 /* RoomScreenCoordinator.swift */; };
|
||||
18F2BB0D27D25B4000DD1988 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC527D25B4000DD1988 /* RoomScreenViewModel.swift */; };
|
||||
18F2BB0E27D25B4000DD1988 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC627D25B4000DD1988 /* RoomScreenViewModelProtocol.swift */; };
|
||||
18F2BB0F27D25B4000DD1988 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC827D25B4000DD1988 /* RoomScreen.swift */; };
|
||||
18F2BB1127D25B4000DD1988 /* RoomScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BACA27D25B4000DD1988 /* RoomScreenModels.swift */; };
|
||||
18F2BB1227D25B4000DD1988 /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BACC27D25B4000DD1988 /* LoginScreenViewModel.swift */; };
|
||||
18F2BB1527D25B4000DD1988 /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAD227D25B4000DD1988 /* LoginScreenViewModelProtocol.swift */; };
|
||||
18F2BB1627D25B4000DD1988 /* LoginScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAD327D25B4000DD1988 /* LoginScreenModels.swift */; };
|
||||
18F2BB1727D25B4000DD1988 /* LoginScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAD427D25B4000DD1988 /* LoginScreenCoordinator.swift */; };
|
||||
18F2BB1827D25B4000DD1988 /* LoginScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAD627D25B4000DD1988 /* LoginScreen.swift */; };
|
||||
18F2BB1A27D25BE800DD1988 /* RoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BB1927D25BE800DD1988 /* RoomTimelineController.swift */; };
|
||||
18F2BB1D27D25D1C00DD1988 /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAD127D25B4000DD1988 /* LoginScreenViewModelTests.swift */; };
|
||||
18F2BB1E27D25D2200DD1988 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAA927D25B4000DD1988 /* HomeScreenViewModelTests.swift */; };
|
||||
18F2BB1F27D25D3100DD1988 /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC327D25B4000DD1988 /* RoomScreenViewModelTests.swift */; };
|
||||
18F2BB2027D25D3400DD1988 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAC127D25B4000DD1988 /* RoomScreenUITests.swift */; };
|
||||
18F2BB2127D25D3C00DD1988 /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BAA727D25B4000DD1988 /* HomeScreenUITests.swift */; };
|
||||
18F2BB2227D25D4600DD1988 /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BACF27D25B4000DD1988 /* LoginScreenUITests.swift */; };
|
||||
18F2BB2427D262A900DD1988 /* RoomTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BB2327D262A900DD1988 /* RoomTimelineItemProtocol.swift */; };
|
||||
18F2BB2627D262FA00DD1988 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BB2527D262FA00DD1988 /* TextRoomTimelineItem.swift */; };
|
||||
18F2BB2827D2647A00DD1988 /* MockRoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BB2727D2647A00DD1988 /* MockRoomTimelineController.swift */; };
|
||||
18F2BB2A27D2648900DD1988 /* RoomTimelineControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18F2BB2927D2648900DD1988 /* RoomTimelineControllerProtocol.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -87,18 +100,6 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
182BC41F27BE667200A30C33 /* RoomModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomModelProtocol.swift; sourceTree = "<group>"; };
|
||||
182BC42127BE6C6900A30C33 /* MockRoomModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomModel.swift; sourceTree = "<group>"; };
|
||||
182BC46527C4CD6D00A30C33 /* RoundedToastView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedToastView.swift; sourceTree = "<group>"; };
|
||||
182BC46627C4CD6D00A30C33 /* RectangleToastView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RectangleToastView.swift; sourceTree = "<group>"; };
|
||||
182BC46727C4CD6D00A30C33 /* ActivityPresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityPresentable.swift; sourceTree = "<group>"; };
|
||||
182BC46827C4CD6D00A30C33 /* ActivityCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityCenter.swift; sourceTree = "<group>"; };
|
||||
182BC46A27C4CD6D00A30C33 /* ToastActivityPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToastActivityPresenter.swift; sourceTree = "<group>"; };
|
||||
182BC46C27C4CD6D00A30C33 /* Activity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Activity.swift; sourceTree = "<group>"; };
|
||||
182BC46D27C4CD6D00A30C33 /* ActivityRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityRequest.swift; sourceTree = "<group>"; };
|
||||
182BC46E27C4CD6D00A30C33 /* ActivityDismissal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityDismissal.swift; sourceTree = "<group>"; };
|
||||
182BC47827C4CE2200A30C33 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||
182BC47A27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingActivityPresenter.swift; sourceTree = "<group>"; };
|
||||
1850252427B6918C002E6B18 /* ElementX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1850253A27B6918D002E6B18 /* ElementXTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ElementXTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1850253E27B6918D002E6B18 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
||||
@@ -110,43 +111,68 @@
|
||||
1850256727B6A135002E6B18 /* ElementX.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = ElementX.entitlements; sourceTree = "<group>"; };
|
||||
1850256827B6A135002E6B18 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
1850256A27B6A135002E6B18 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
1863A40E27BA716A00B52E4D /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; };
|
||||
1863A40F27BA716A00B52E4D /* UserSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
||||
1863A41027BA716A00B52E4D /* KeychainController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; };
|
||||
1863A41127BA716A00B52E4D /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
|
||||
1863A41B27BA76B900B52E4D /* MXLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
|
||||
1863A41F27BA784300B52E4D /* LoginScreenViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
1863A42427BA784300B52E4D /* LoginScreenUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
||||
1863A42627BA784300B52E4D /* LoginScreenViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
1863A42727BA784300B52E4D /* LoginScreenViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
1863A42827BA784300B52E4D /* LoginScreenModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
||||
1863A42A27BA784300B52E4D /* LoginScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = "<group>"; };
|
||||
1863A43827BA789800B52E4D /* StateStoreViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateStoreViewModel.swift; sourceTree = "<group>"; };
|
||||
1863A43927BA789800B52E4D /* BindableState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BindableState.swift; sourceTree = "<group>"; };
|
||||
1863A43D27BA790000B52E4D /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||
1863A44127BA79FF00B52E4D /* NavigationRouterStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
||||
1863A44227BA79FF00B52E4D /* NavigationRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
||||
1863A44327BA79FF00B52E4D /* RootRouterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootRouterType.swift; sourceTree = "<group>"; };
|
||||
1863A44427BA79FF00B52E4D /* NavigationRouterStoreProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterStoreProtocol.swift; sourceTree = "<group>"; };
|
||||
1863A44527BA79FF00B52E4D /* RootRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootRouter.swift; sourceTree = "<group>"; };
|
||||
1863A44627BA79FF00B52E4D /* Presentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Presentable.swift; sourceTree = "<group>"; };
|
||||
1863A44727BA79FF00B52E4D /* NavigationModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
||||
1863A44827BA79FF00B52E4D /* NavigationRouterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterType.swift; sourceTree = "<group>"; };
|
||||
1863A45227BA7A7800B52E4D /* WeakDictionaryKeyReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionaryKeyReference.swift; sourceTree = "<group>"; };
|
||||
1863A45327BA7A7800B52E4D /* WeakDictionaryReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionaryReference.swift; sourceTree = "<group>"; };
|
||||
1863A45427BA7A7800B52E4D /* WeakDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionary.swift; sourceTree = "<group>"; };
|
||||
1863A45527BA7A7800B52E4D /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
||||
1863A45A27BA7B4700B52E4D /* LoginScreenCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
1863A45D27BAA60300B52E4D /* SplashViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashViewController.swift; sourceTree = "<group>"; };
|
||||
1863A45E27BAA60300B52E4D /* SplashViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SplashViewController.xib; sourceTree = "<group>"; };
|
||||
1863A47927BAA8A900B52E4D /* HomeScreenCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
1863A47C27BAA8A900B52E4D /* HomeScreenUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = "<group>"; };
|
||||
1863A47E27BAA8A900B52E4D /* HomeScreenViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
1863A47F27BAA8A900B52E4D /* HomeScreenViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
1863A48027BAA8A900B52E4D /* HomeScreenModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
||||
1863A48227BAA8A900B52E4D /* HomeScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
|
||||
1863A48427BAA8A900B52E4D /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
1863A49327BAAA6700B52E4D /* RoomModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomModel.swift; sourceTree = "<group>"; };
|
||||
18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxyProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BA7427D25B4000DD1988 /* RoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = "<group>"; };
|
||||
18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockRoomProxy.swift; sourceTree = "<group>"; };
|
||||
18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
|
||||
18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinator.swift; sourceTree = "<group>"; };
|
||||
18F2BA7A27D25B4000DD1988 /* UserSession.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
||||
18F2BA7B27D25B4000DD1988 /* KeychainController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = "<group>"; };
|
||||
18F2BA7C27D25B4000DD1988 /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BA7F27D25B4000DD1988 /* NavigationRouterStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterStore.swift; sourceTree = "<group>"; };
|
||||
18F2BA8027D25B4000DD1988 /* NavigationRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
||||
18F2BA8127D25B4000DD1988 /* RootRouterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootRouterType.swift; sourceTree = "<group>"; };
|
||||
18F2BA8227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterStoreProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BA8327D25B4000DD1988 /* RootRouter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RootRouter.swift; sourceTree = "<group>"; };
|
||||
18F2BA8427D25B4000DD1988 /* Presentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Presentable.swift; sourceTree = "<group>"; };
|
||||
18F2BA8527D25B4000DD1988 /* NavigationModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
||||
18F2BA8627D25B4000DD1988 /* NavigationRouterType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationRouterType.swift; sourceTree = "<group>"; };
|
||||
18F2BA8927D25B4000DD1988 /* RoundedToastView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoundedToastView.swift; sourceTree = "<group>"; };
|
||||
18F2BA8A27D25B4000DD1988 /* RectangleToastView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RectangleToastView.swift; sourceTree = "<group>"; };
|
||||
18F2BA8B27D25B4000DD1988 /* ActivityPresentable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityPresentable.swift; sourceTree = "<group>"; };
|
||||
18F2BA8C27D25B4000DD1988 /* ActivityCenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityCenter.swift; sourceTree = "<group>"; };
|
||||
18F2BA8D27D25B4000DD1988 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||
18F2BA8F27D25B4000DD1988 /* ToastActivityPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ToastActivityPresenter.swift; sourceTree = "<group>"; };
|
||||
18F2BA9027D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingActivityPresenter.swift; sourceTree = "<group>"; };
|
||||
18F2BA9127D25B4000DD1988 /* Activity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Activity.swift; sourceTree = "<group>"; };
|
||||
18F2BA9227D25B4000DD1988 /* ActivityRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityRequest.swift; sourceTree = "<group>"; };
|
||||
18F2BA9327D25B4000DD1988 /* ActivityDismissal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityDismissal.swift; sourceTree = "<group>"; };
|
||||
18F2BA9427D25B4000DD1988 /* MXLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
|
||||
18F2BA9627D25B4000DD1988 /* WeakDictionaryKeyReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionaryKeyReference.swift; sourceTree = "<group>"; };
|
||||
18F2BA9727D25B4000DD1988 /* WeakDictionaryReference.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionaryReference.swift; sourceTree = "<group>"; };
|
||||
18F2BA9827D25B4000DD1988 /* WeakDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakDictionary.swift; sourceTree = "<group>"; };
|
||||
18F2BA9927D25B4000DD1988 /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
||||
18F2BA9A27D25B4000DD1988 /* Coordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||
18F2BA9D27D25B4000DD1988 /* StateStoreViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StateStoreViewModel.swift; sourceTree = "<group>"; };
|
||||
18F2BA9E27D25B4000DD1988 /* BindableState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BindableState.swift; sourceTree = "<group>"; };
|
||||
18F2BAA127D25B4000DD1988 /* SplashViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SplashViewController.swift; sourceTree = "<group>"; };
|
||||
18F2BAA227D25B4000DD1988 /* SplashViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SplashViewController.xib; sourceTree = "<group>"; };
|
||||
18F2BAA427D25B4000DD1988 /* HomeScreenCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
18F2BAA727D25B4000DD1988 /* HomeScreenUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = "<group>"; };
|
||||
18F2BAA927D25B4000DD1988 /* HomeScreenViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
18F2BAAA27D25B4000DD1988 /* HomeScreenViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BAAB27D25B4000DD1988 /* HomeScreenModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
||||
18F2BAAD27D25B4000DD1988 /* HomeScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = "<group>"; };
|
||||
18F2BAAE27D25B4000DD1988 /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
18F2BAC127D25B4000DD1988 /* RoomScreenUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = "<group>"; };
|
||||
18F2BAC327D25B4000DD1988 /* RoomScreenViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
18F2BAC427D25B4000DD1988 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
18F2BAC527D25B4000DD1988 /* RoomScreenViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
18F2BAC627D25B4000DD1988 /* RoomScreenViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BAC827D25B4000DD1988 /* RoomScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = "<group>"; };
|
||||
18F2BACA27D25B4000DD1988 /* RoomScreenModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = "<group>"; };
|
||||
18F2BACC27D25B4000DD1988 /* LoginScreenViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModel.swift; sourceTree = "<group>"; };
|
||||
18F2BACF27D25B4000DD1988 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = "<group>"; };
|
||||
18F2BAD127D25B4000DD1988 /* LoginScreenViewModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||
18F2BAD227D25B4000DD1988 /* LoginScreenViewModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BAD327D25B4000DD1988 /* LoginScreenModels.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
||||
18F2BAD427D25B4000DD1988 /* LoginScreenCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
18F2BAD627D25B4000DD1988 /* LoginScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = "<group>"; };
|
||||
18F2BB1927D25BE800DD1988 /* RoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineController.swift; sourceTree = "<group>"; };
|
||||
18F2BB2327D262A900DD1988 /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||
18F2BB2527D262FA00DD1988 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||
18F2BB2727D2647A00DD1988 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = "<group>"; };
|
||||
18F2BB2927D2648900DD1988 /* RoomTimelineControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerProtocol.swift; sourceTree = "<group>"; };
|
||||
18FE279627C7B85300016375 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -179,39 +205,6 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
182BC46327C4CD6D00A30C33 /* Activity */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
182BC47827C4CE2200A30C33 /* LabelledActivityIndicatorView.swift */,
|
||||
182BC46427C4CD6D00A30C33 /* Toasts */,
|
||||
182BC46727C4CD6D00A30C33 /* ActivityPresentable.swift */,
|
||||
182BC46827C4CD6D00A30C33 /* ActivityCenter.swift */,
|
||||
182BC46927C4CD6D00A30C33 /* ActivityPresenters */,
|
||||
182BC46C27C4CD6D00A30C33 /* Activity.swift */,
|
||||
182BC46D27C4CD6D00A30C33 /* ActivityRequest.swift */,
|
||||
182BC46E27C4CD6D00A30C33 /* ActivityDismissal.swift */,
|
||||
);
|
||||
path = Activity;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
182BC46427C4CD6D00A30C33 /* Toasts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
182BC46527C4CD6D00A30C33 /* RoundedToastView.swift */,
|
||||
182BC46627C4CD6D00A30C33 /* RectangleToastView.swift */,
|
||||
);
|
||||
path = Toasts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
182BC46927C4CD6D00A30C33 /* ActivityPresenters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
182BC47A27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift */,
|
||||
182BC46A27C4CD6D00A30C33 /* ToastActivityPresenter.swift */,
|
||||
);
|
||||
path = ActivityPresenters;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1850251B27B6918C002E6B18 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -263,7 +256,9 @@
|
||||
children = (
|
||||
1850256527B6A135002E6B18 /* AppDelegate.swift */,
|
||||
1850256227B6A135002E6B18 /* AppCoordinator.swift */,
|
||||
1863A40927BA716A00B52E4D /* Modules */,
|
||||
18F2BA7227D25B4000DD1988 /* Services */,
|
||||
18F2BA9F27D25B4000DD1988 /* Screens */,
|
||||
18F2BA7D27D25B4000DD1988 /* Other */,
|
||||
);
|
||||
path = Sources;
|
||||
sourceTree = "<group>";
|
||||
@@ -279,195 +274,287 @@
|
||||
path = "Supporting Files";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A40927BA716A00B52E4D /* Modules */ = {
|
||||
18F2BA7227D25B4000DD1988 /* Services */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A45C27BAA5F100B52E4D /* Splash */,
|
||||
1863A40D27BA716A00B52E4D /* Authentication */,
|
||||
1863A47827BAA8A900B52E4D /* HomeScreen */,
|
||||
1863A49227BAAA6700B52E4D /* Models */,
|
||||
1863A44027BA79FF00B52E4D /* Routers */,
|
||||
1863A41A27BA76B900B52E4D /* Other */,
|
||||
18F2BA7827D25B4000DD1988 /* Authentication */,
|
||||
18F2BA7627D25B4000DD1988 /* Timeline */,
|
||||
18F2BA7327D25B4000DD1988 /* RoomProxyProtocol.swift */,
|
||||
18F2BA7427D25B4000DD1988 /* RoomProxy.swift */,
|
||||
18F2BA7527D25B4000DD1988 /* MockRoomProxy.swift */,
|
||||
);
|
||||
path = Modules;
|
||||
path = Services;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A40D27BA716A00B52E4D /* Authentication */ = {
|
||||
18F2BA7627D25B4000DD1988 /* Timeline */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A40E27BA716A00B52E4D /* AuthenticationCoordinator.swift */,
|
||||
1863A40F27BA716A00B52E4D /* UserSession.swift */,
|
||||
1863A41027BA716A00B52E4D /* KeychainController.swift */,
|
||||
1863A41127BA716A00B52E4D /* KeychainControllerProtocol.swift */,
|
||||
1863A41D27BA784300B52E4D /* LoginScreen */,
|
||||
18F2BB2927D2648900DD1988 /* RoomTimelineControllerProtocol.swift */,
|
||||
18F2BB1927D25BE800DD1988 /* RoomTimelineController.swift */,
|
||||
18F2BB2727D2647A00DD1988 /* MockRoomTimelineController.swift */,
|
||||
18F2BA7727D25B4000DD1988 /* RoomTimelineProvider.swift */,
|
||||
18F2BB2327D262A900DD1988 /* RoomTimelineItemProtocol.swift */,
|
||||
18F2BB2527D262FA00DD1988 /* TextRoomTimelineItem.swift */,
|
||||
);
|
||||
path = Timeline;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA7827D25B4000DD1988 /* Authentication */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BA7927D25B4000DD1988 /* AuthenticationCoordinator.swift */,
|
||||
18F2BA7A27D25B4000DD1988 /* UserSession.swift */,
|
||||
18F2BA7B27D25B4000DD1988 /* KeychainController.swift */,
|
||||
18F2BA7C27D25B4000DD1988 /* KeychainControllerProtocol.swift */,
|
||||
);
|
||||
path = Authentication;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A41A27BA76B900B52E4D /* Other */ = {
|
||||
18F2BA7D27D25B4000DD1988 /* Other */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
182BC46327C4CD6D00A30C33 /* Activity */,
|
||||
1863A43D27BA790000B52E4D /* Coordinator.swift */,
|
||||
1863A41B27BA76B900B52E4D /* MXLog.swift */,
|
||||
1863A43627BA789800B52E4D /* SwiftUI */,
|
||||
1863A45127BA7A7800B52E4D /* WeakDictionary */,
|
||||
18F2BA7E27D25B4000DD1988 /* Routers */,
|
||||
18F2BA8727D25B4000DD1988 /* Activity */,
|
||||
18F2BA9427D25B4000DD1988 /* MXLog.swift */,
|
||||
18F2BA9527D25B4000DD1988 /* WeakDictionary */,
|
||||
18F2BA9A27D25B4000DD1988 /* Coordinator.swift */,
|
||||
18F2BA9B27D25B4000DD1988 /* SwiftUI */,
|
||||
);
|
||||
path = Other;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A41D27BA784300B52E4D /* LoginScreen */ = {
|
||||
18F2BA7E27D25B4000DD1988 /* Routers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A45A27BA7B4700B52E4D /* LoginScreenCoordinator.swift */,
|
||||
1863A42827BA784300B52E4D /* LoginScreenModels.swift */,
|
||||
1863A41F27BA784300B52E4D /* LoginScreenViewModel.swift */,
|
||||
1863A42727BA784300B52E4D /* LoginScreenViewModelProtocol.swift */,
|
||||
1863A42227BA784300B52E4D /* Test */,
|
||||
1863A42927BA784300B52E4D /* View */,
|
||||
);
|
||||
path = LoginScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A42227BA784300B52E4D /* Test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A42327BA784300B52E4D /* UI */,
|
||||
1863A42527BA784300B52E4D /* Unit */,
|
||||
);
|
||||
path = Test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A42327BA784300B52E4D /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A42427BA784300B52E4D /* LoginScreenUITests.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A42527BA784300B52E4D /* Unit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A42627BA784300B52E4D /* LoginScreenViewModelTests.swift */,
|
||||
);
|
||||
path = Unit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A42927BA784300B52E4D /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A42A27BA784300B52E4D /* LoginScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A43627BA789800B52E4D /* SwiftUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A43727BA789800B52E4D /* ViewModel */,
|
||||
);
|
||||
path = SwiftUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A43727BA789800B52E4D /* ViewModel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A43827BA789800B52E4D /* StateStoreViewModel.swift */,
|
||||
1863A43927BA789800B52E4D /* BindableState.swift */,
|
||||
);
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A44027BA79FF00B52E4D /* Routers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A44127BA79FF00B52E4D /* NavigationRouterStore.swift */,
|
||||
1863A44227BA79FF00B52E4D /* NavigationRouter.swift */,
|
||||
1863A44327BA79FF00B52E4D /* RootRouterType.swift */,
|
||||
1863A44427BA79FF00B52E4D /* NavigationRouterStoreProtocol.swift */,
|
||||
1863A44527BA79FF00B52E4D /* RootRouter.swift */,
|
||||
1863A44627BA79FF00B52E4D /* Presentable.swift */,
|
||||
1863A44727BA79FF00B52E4D /* NavigationModule.swift */,
|
||||
1863A44827BA79FF00B52E4D /* NavigationRouterType.swift */,
|
||||
18F2BA7F27D25B4000DD1988 /* NavigationRouterStore.swift */,
|
||||
18F2BA8027D25B4000DD1988 /* NavigationRouter.swift */,
|
||||
18F2BA8127D25B4000DD1988 /* RootRouterType.swift */,
|
||||
18F2BA8227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift */,
|
||||
18F2BA8327D25B4000DD1988 /* RootRouter.swift */,
|
||||
18F2BA8427D25B4000DD1988 /* Presentable.swift */,
|
||||
18F2BA8527D25B4000DD1988 /* NavigationModule.swift */,
|
||||
18F2BA8627D25B4000DD1988 /* NavigationRouterType.swift */,
|
||||
);
|
||||
path = Routers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A45127BA7A7800B52E4D /* WeakDictionary */ = {
|
||||
18F2BA8727D25B4000DD1988 /* Activity */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A45227BA7A7800B52E4D /* WeakDictionaryKeyReference.swift */,
|
||||
1863A45327BA7A7800B52E4D /* WeakDictionaryReference.swift */,
|
||||
1863A45427BA7A7800B52E4D /* WeakDictionary.swift */,
|
||||
1863A45527BA7A7800B52E4D /* WeakKeyDictionary.swift */,
|
||||
18F2BA8827D25B4000DD1988 /* Toasts */,
|
||||
18F2BA8B27D25B4000DD1988 /* ActivityPresentable.swift */,
|
||||
18F2BA8C27D25B4000DD1988 /* ActivityCenter.swift */,
|
||||
18F2BA8D27D25B4000DD1988 /* LabelledActivityIndicatorView.swift */,
|
||||
18F2BA8E27D25B4000DD1988 /* ActivityPresenters */,
|
||||
18F2BA9127D25B4000DD1988 /* Activity.swift */,
|
||||
18F2BA9227D25B4000DD1988 /* ActivityRequest.swift */,
|
||||
18F2BA9327D25B4000DD1988 /* ActivityDismissal.swift */,
|
||||
);
|
||||
path = Activity;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA8827D25B4000DD1988 /* Toasts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BA8927D25B4000DD1988 /* RoundedToastView.swift */,
|
||||
18F2BA8A27D25B4000DD1988 /* RectangleToastView.swift */,
|
||||
);
|
||||
path = Toasts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA8E27D25B4000DD1988 /* ActivityPresenters */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BA8F27D25B4000DD1988 /* ToastActivityPresenter.swift */,
|
||||
18F2BA9027D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift */,
|
||||
);
|
||||
path = ActivityPresenters;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA9527D25B4000DD1988 /* WeakDictionary */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BA9627D25B4000DD1988 /* WeakDictionaryKeyReference.swift */,
|
||||
18F2BA9727D25B4000DD1988 /* WeakDictionaryReference.swift */,
|
||||
18F2BA9827D25B4000DD1988 /* WeakDictionary.swift */,
|
||||
18F2BA9927D25B4000DD1988 /* WeakKeyDictionary.swift */,
|
||||
);
|
||||
path = WeakDictionary;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A45C27BAA5F100B52E4D /* Splash */ = {
|
||||
18F2BA9B27D25B4000DD1988 /* SwiftUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A45D27BAA60300B52E4D /* SplashViewController.swift */,
|
||||
1863A45E27BAA60300B52E4D /* SplashViewController.xib */,
|
||||
18F2BA9C27D25B4000DD1988 /* ViewModel */,
|
||||
);
|
||||
path = SwiftUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA9C27D25B4000DD1988 /* ViewModel */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BA9D27D25B4000DD1988 /* StateStoreViewModel.swift */,
|
||||
18F2BA9E27D25B4000DD1988 /* BindableState.swift */,
|
||||
);
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BA9F27D25B4000DD1988 /* Screens */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAA027D25B4000DD1988 /* Splash */,
|
||||
18F2BACB27D25B4000DD1988 /* LoginScreen */,
|
||||
18F2BAA327D25B4000DD1988 /* HomeScreen */,
|
||||
18F2BABE27D25B4000DD1988 /* RoomScreen */,
|
||||
);
|
||||
path = Screens;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAA027D25B4000DD1988 /* Splash */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAA127D25B4000DD1988 /* SplashViewController.swift */,
|
||||
18F2BAA227D25B4000DD1988 /* SplashViewController.xib */,
|
||||
);
|
||||
path = Splash;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A47827BAA8A900B52E4D /* HomeScreen */ = {
|
||||
18F2BAA327D25B4000DD1988 /* HomeScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A47927BAA8A900B52E4D /* HomeScreenCoordinator.swift */,
|
||||
1863A48027BAA8A900B52E4D /* HomeScreenModels.swift */,
|
||||
1863A48427BAA8A900B52E4D /* HomeScreenViewModel.swift */,
|
||||
1863A47F27BAA8A900B52E4D /* HomeScreenViewModelProtocol.swift */,
|
||||
1863A47A27BAA8A900B52E4D /* Test */,
|
||||
1863A48127BAA8A900B52E4D /* View */,
|
||||
18F2BAAB27D25B4000DD1988 /* HomeScreenModels.swift */,
|
||||
18F2BAA427D25B4000DD1988 /* HomeScreenCoordinator.swift */,
|
||||
18F2BAAA27D25B4000DD1988 /* HomeScreenViewModelProtocol.swift */,
|
||||
18F2BAAE27D25B4000DD1988 /* HomeScreenViewModel.swift */,
|
||||
18F2BAAC27D25B4000DD1988 /* View */,
|
||||
18F2BAA527D25B4000DD1988 /* Test */,
|
||||
);
|
||||
path = HomeScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A47A27BAA8A900B52E4D /* Test */ = {
|
||||
18F2BAA527D25B4000DD1988 /* Test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A47B27BAA8A900B52E4D /* UI */,
|
||||
1863A47D27BAA8A900B52E4D /* Unit */,
|
||||
18F2BAA627D25B4000DD1988 /* UI */,
|
||||
18F2BAA827D25B4000DD1988 /* Unit */,
|
||||
);
|
||||
path = Test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A47B27BAA8A900B52E4D /* UI */ = {
|
||||
18F2BAA627D25B4000DD1988 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A47C27BAA8A900B52E4D /* HomeScreenUITests.swift */,
|
||||
18F2BAA727D25B4000DD1988 /* HomeScreenUITests.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A47D27BAA8A900B52E4D /* Unit */ = {
|
||||
18F2BAA827D25B4000DD1988 /* Unit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A47E27BAA8A900B52E4D /* HomeScreenViewModelTests.swift */,
|
||||
18F2BAA927D25B4000DD1988 /* HomeScreenViewModelTests.swift */,
|
||||
);
|
||||
path = Unit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A48127BAA8A900B52E4D /* View */ = {
|
||||
18F2BAAC27D25B4000DD1988 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A48227BAA8A900B52E4D /* HomeScreen.swift */,
|
||||
18F2BAAD27D25B4000DD1988 /* HomeScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1863A49227BAAA6700B52E4D /* Models */ = {
|
||||
18F2BABE27D25B4000DD1988 /* RoomScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1863A49327BAAA6700B52E4D /* RoomModel.swift */,
|
||||
182BC41F27BE667200A30C33 /* RoomModelProtocol.swift */,
|
||||
182BC42127BE6C6900A30C33 /* MockRoomModel.swift */,
|
||||
18F2BACA27D25B4000DD1988 /* RoomScreenModels.swift */,
|
||||
18F2BAC427D25B4000DD1988 /* RoomScreenCoordinator.swift */,
|
||||
18F2BAC627D25B4000DD1988 /* RoomScreenViewModelProtocol.swift */,
|
||||
18F2BAC527D25B4000DD1988 /* RoomScreenViewModel.swift */,
|
||||
18F2BAC727D25B4000DD1988 /* View */,
|
||||
18F2BABF27D25B4000DD1988 /* Test */,
|
||||
);
|
||||
path = Models;
|
||||
path = RoomScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BABF27D25B4000DD1988 /* Test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAC027D25B4000DD1988 /* UI */,
|
||||
18F2BAC227D25B4000DD1988 /* Unit */,
|
||||
);
|
||||
path = Test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAC027D25B4000DD1988 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAC127D25B4000DD1988 /* RoomScreenUITests.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAC227D25B4000DD1988 /* Unit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAC327D25B4000DD1988 /* RoomScreenViewModelTests.swift */,
|
||||
);
|
||||
path = Unit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAC727D25B4000DD1988 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAC827D25B4000DD1988 /* RoomScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BACB27D25B4000DD1988 /* LoginScreen */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAD327D25B4000DD1988 /* LoginScreenModels.swift */,
|
||||
18F2BAD427D25B4000DD1988 /* LoginScreenCoordinator.swift */,
|
||||
18F2BAD227D25B4000DD1988 /* LoginScreenViewModelProtocol.swift */,
|
||||
18F2BACC27D25B4000DD1988 /* LoginScreenViewModel.swift */,
|
||||
18F2BACD27D25B4000DD1988 /* Test */,
|
||||
18F2BAD527D25B4000DD1988 /* View */,
|
||||
);
|
||||
path = LoginScreen;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BACD27D25B4000DD1988 /* Test */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BACE27D25B4000DD1988 /* UI */,
|
||||
18F2BAD027D25B4000DD1988 /* Unit */,
|
||||
);
|
||||
path = Test;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BACE27D25B4000DD1988 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BACF27D25B4000DD1988 /* LoginScreenUITests.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAD027D25B4000DD1988 /* Unit */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAD127D25B4000DD1988 /* LoginScreenViewModelTests.swift */,
|
||||
);
|
||||
path = Unit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
18F2BAD527D25B4000DD1988 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
18F2BAD627D25B4000DD1988 /* LoginScreen.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
@@ -589,7 +676,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1850257127B6A135002E6B18 /* LaunchScreen.storyboard in Resources */,
|
||||
1863A46027BAA60300B52E4D /* SplashViewController.xib in Resources */,
|
||||
18F2BAFA27D25B4000DD1988 /* SplashViewController.xib in Resources */,
|
||||
1850257027B6A135002E6B18 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -635,52 +722,63 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1863A44B27BA79FF00B52E4D /* RootRouterType.swift in Sources */,
|
||||
182BC47327C4CD6D00A30C33 /* ToastActivityPresenter.swift in Sources */,
|
||||
1863A48C27BAA8A900B52E4D /* HomeScreenViewModel.swift in Sources */,
|
||||
1863A41727BA716A00B52E4D /* KeychainControllerProtocol.swift in Sources */,
|
||||
1863A45B27BA7B4700B52E4D /* LoginScreenCoordinator.swift in Sources */,
|
||||
182BC47127C4CD6D00A30C33 /* ActivityPresentable.swift in Sources */,
|
||||
1863A41427BA716A00B52E4D /* AuthenticationCoordinator.swift in Sources */,
|
||||
1863A43B27BA789800B52E4D /* BindableState.swift in Sources */,
|
||||
182BC47027C4CD6D00A30C33 /* RectangleToastView.swift in Sources */,
|
||||
1863A42C27BA784300B52E4D /* LoginScreenViewModel.swift in Sources */,
|
||||
1863A44F27BA79FF00B52E4D /* NavigationModule.swift in Sources */,
|
||||
1863A43027BA784300B52E4D /* LoginScreenViewModelProtocol.swift in Sources */,
|
||||
1863A48827BAA8A900B52E4D /* HomeScreenViewModelProtocol.swift in Sources */,
|
||||
1863A44D27BA79FF00B52E4D /* RootRouter.swift in Sources */,
|
||||
182BC47627C4CD6D00A30C33 /* ActivityRequest.swift in Sources */,
|
||||
1863A45F27BAA60300B52E4D /* SplashViewController.swift in Sources */,
|
||||
1863A48A27BAA8A900B52E4D /* HomeScreen.swift in Sources */,
|
||||
1863A44927BA79FF00B52E4D /* NavigationRouterStore.swift in Sources */,
|
||||
1863A45727BA7A7800B52E4D /* WeakDictionaryReference.swift in Sources */,
|
||||
1863A48927BAA8A900B52E4D /* HomeScreenModels.swift in Sources */,
|
||||
1863A45027BA79FF00B52E4D /* NavigationRouterType.swift in Sources */,
|
||||
182BC42027BE667200A30C33 /* RoomModelProtocol.swift in Sources */,
|
||||
1863A45627BA7A7800B52E4D /* WeakDictionaryKeyReference.swift in Sources */,
|
||||
182BC47927C4CE2200A30C33 /* LabelledActivityIndicatorView.swift in Sources */,
|
||||
1863A49427BAAA6700B52E4D /* RoomModel.swift in Sources */,
|
||||
18F2BADE27D25B4000DD1988 /* KeychainControllerProtocol.swift in Sources */,
|
||||
18F2BAED27D25B4000DD1988 /* FullscreenLoadingActivityPresenter.swift in Sources */,
|
||||
18F2BB0F27D25B4000DD1988 /* RoomScreen.swift in Sources */,
|
||||
18F2BAFF27D25B4000DD1988 /* HomeScreenModels.swift in Sources */,
|
||||
18F2BB1527D25B4000DD1988 /* LoginScreenViewModelProtocol.swift in Sources */,
|
||||
18F2BAEB27D25B4000DD1988 /* LabelledActivityIndicatorView.swift in Sources */,
|
||||
18F2BAE427D25B4000DD1988 /* Presentable.swift in Sources */,
|
||||
18F2BAF927D25B4000DD1988 /* SplashViewController.swift in Sources */,
|
||||
18F2BAE327D25B4000DD1988 /* RootRouter.swift in Sources */,
|
||||
18F2BAE527D25B4000DD1988 /* NavigationModule.swift in Sources */,
|
||||
18F2BB1227D25B4000DD1988 /* LoginScreenViewModel.swift in Sources */,
|
||||
18F2BAD927D25B4000DD1988 /* MockRoomProxy.swift in Sources */,
|
||||
18F2BAE727D25B4000DD1988 /* RoundedToastView.swift in Sources */,
|
||||
18F2BAF227D25B4000DD1988 /* WeakDictionaryKeyReference.swift in Sources */,
|
||||
18F2BB2427D262A900DD1988 /* RoomTimelineItemProtocol.swift in Sources */,
|
||||
18F2BAE027D25B4000DD1988 /* NavigationRouter.swift in Sources */,
|
||||
18F2BAF627D25B4000DD1988 /* Coordinator.swift in Sources */,
|
||||
18F2BAEA27D25B4000DD1988 /* ActivityCenter.swift in Sources */,
|
||||
18F2BB1A27D25BE800DD1988 /* RoomTimelineController.swift in Sources */,
|
||||
18F2BAF327D25B4000DD1988 /* WeakDictionaryReference.swift in Sources */,
|
||||
18F2BB2A27D2648900DD1988 /* RoomTimelineControllerProtocol.swift in Sources */,
|
||||
18F2BAF127D25B4000DD1988 /* MXLog.swift in Sources */,
|
||||
18F2BAF727D25B4000DD1988 /* StateStoreViewModel.swift in Sources */,
|
||||
18F2BAF427D25B4000DD1988 /* WeakDictionary.swift in Sources */,
|
||||
18F2BB1127D25B4000DD1988 /* RoomScreenModels.swift in Sources */,
|
||||
18F2BADB27D25B4000DD1988 /* AuthenticationCoordinator.swift in Sources */,
|
||||
1850256F27B6A135002E6B18 /* AppDelegate.swift in Sources */,
|
||||
182BC47727C4CD6D00A30C33 /* ActivityDismissal.swift in Sources */,
|
||||
1863A41627BA716A00B52E4D /* KeychainController.swift in Sources */,
|
||||
1863A41527BA716A00B52E4D /* UserSession.swift in Sources */,
|
||||
1863A43A27BA789800B52E4D /* StateStoreViewModel.swift in Sources */,
|
||||
1863A45827BA7A7800B52E4D /* WeakDictionary.swift in Sources */,
|
||||
1863A43227BA784300B52E4D /* LoginScreen.swift in Sources */,
|
||||
1863A48527BAA8A900B52E4D /* HomeScreenCoordinator.swift in Sources */,
|
||||
1863A43F27BA790000B52E4D /* Coordinator.swift in Sources */,
|
||||
1863A41C27BA76B900B52E4D /* MXLog.swift in Sources */,
|
||||
182BC46F27C4CD6D00A30C33 /* RoundedToastView.swift in Sources */,
|
||||
182BC47527C4CD6D00A30C33 /* Activity.swift in Sources */,
|
||||
182BC47B27C4D05200A30C33 /* FullscreenLoadingActivityPresenter.swift in Sources */,
|
||||
1863A44E27BA79FF00B52E4D /* Presentable.swift in Sources */,
|
||||
182BC42227BE6C6900A30C33 /* MockRoomModel.swift in Sources */,
|
||||
18F2BAE627D25B4000DD1988 /* NavigationRouterType.swift in Sources */,
|
||||
18F2BAE927D25B4000DD1988 /* ActivityPresentable.swift in Sources */,
|
||||
18F2BAF827D25B4000DD1988 /* BindableState.swift in Sources */,
|
||||
18F2BAD827D25B4000DD1988 /* RoomProxy.swift in Sources */,
|
||||
18F2BB1827D25B4000DD1988 /* LoginScreen.swift in Sources */,
|
||||
18F2BAE227D25B4000DD1988 /* NavigationRouterStoreProtocol.swift in Sources */,
|
||||
18F2BAD727D25B4000DD1988 /* RoomProxyProtocol.swift in Sources */,
|
||||
18F2BB1727D25B4000DD1988 /* LoginScreenCoordinator.swift in Sources */,
|
||||
18F2BAF527D25B4000DD1988 /* WeakKeyDictionary.swift in Sources */,
|
||||
18F2BADF27D25B4000DD1988 /* NavigationRouterStore.swift in Sources */,
|
||||
18F2BAFE27D25B4000DD1988 /* HomeScreenViewModelProtocol.swift in Sources */,
|
||||
18F2BAE827D25B4000DD1988 /* RectangleToastView.swift in Sources */,
|
||||
18F2BB2627D262FA00DD1988 /* TextRoomTimelineItem.swift in Sources */,
|
||||
18F2BB1627D25B4000DD1988 /* LoginScreenModels.swift in Sources */,
|
||||
18F2BADA27D25B4000DD1988 /* RoomTimelineProvider.swift in Sources */,
|
||||
18F2BB0027D25B4000DD1988 /* HomeScreen.swift in Sources */,
|
||||
18F2BB2827D2647A00DD1988 /* MockRoomTimelineController.swift in Sources */,
|
||||
18F2BB0127D25B4000DD1988 /* HomeScreenViewModel.swift in Sources */,
|
||||
18F2BAF027D25B4000DD1988 /* ActivityDismissal.swift in Sources */,
|
||||
18F2BADD27D25B4000DD1988 /* KeychainController.swift in Sources */,
|
||||
18F2BAFB27D25B4000DD1988 /* HomeScreenCoordinator.swift in Sources */,
|
||||
18F2BB0C27D25B4000DD1988 /* RoomScreenCoordinator.swift in Sources */,
|
||||
18F2BB0E27D25B4000DD1988 /* RoomScreenViewModelProtocol.swift in Sources */,
|
||||
18F2BB0D27D25B4000DD1988 /* RoomScreenViewModel.swift in Sources */,
|
||||
18F2BAE127D25B4000DD1988 /* RootRouterType.swift in Sources */,
|
||||
1850256C27B6A135002E6B18 /* AppCoordinator.swift in Sources */,
|
||||
1863A43127BA784300B52E4D /* LoginScreenModels.swift in Sources */,
|
||||
1863A44A27BA79FF00B52E4D /* NavigationRouter.swift in Sources */,
|
||||
182BC47227C4CD6D00A30C33 /* ActivityCenter.swift in Sources */,
|
||||
1863A45927BA7A7800B52E4D /* WeakKeyDictionary.swift in Sources */,
|
||||
1863A44C27BA79FF00B52E4D /* NavigationRouterStoreProtocol.swift in Sources */,
|
||||
18F2BADC27D25B4000DD1988 /* UserSession.swift in Sources */,
|
||||
18F2BAEF27D25B4000DD1988 /* ActivityRequest.swift in Sources */,
|
||||
18F2BAEE27D25B4000DD1988 /* Activity.swift in Sources */,
|
||||
18F2BAEC27D25B4000DD1988 /* ToastActivityPresenter.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -688,8 +786,9 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
1863A48F27BAA8CC00B52E4D /* HomeScreenViewModelTests.swift in Sources */,
|
||||
1863A43427BA786400B52E4D /* LoginScreenViewModelTests.swift in Sources */,
|
||||
18F2BB2027D25D3400DD1988 /* RoomScreenUITests.swift in Sources */,
|
||||
18F2BB1E27D25D2200DD1988 /* HomeScreenViewModelTests.swift in Sources */,
|
||||
18F2BB1D27D25D1C00DD1988 /* LoginScreenViewModelTests.swift in Sources */,
|
||||
1850253F27B6918D002E6B18 /* ElementXTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -698,10 +797,11 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
18F2BB2127D25D3C00DD1988 /* HomeScreenUITests.swift in Sources */,
|
||||
1850254B27B6918D002E6B18 /* ElementXUITestsLaunchTests.swift in Sources */,
|
||||
1863A48E27BAA8C800B52E4D /* HomeScreenUITests.swift in Sources */,
|
||||
1863A43527BA788500B52E4D /* LoginScreenUITests.swift in Sources */,
|
||||
1850254927B6918D002E6B18 /* ElementXUITests.swift in Sources */,
|
||||
18F2BB2227D25D4600DD1988 /* LoginScreenUITests.swift in Sources */,
|
||||
18F2BB1F27D25D3100DD1988 /* RoomScreenViewModelTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"repositoryURL": "https://github.com/matrix-org/matrix-rust-components-swift.git",
|
||||
"state": {
|
||||
"branch": "main",
|
||||
"revision": "34aa07d11d0e29145b92f42b9d86aa140d598e19",
|
||||
"revision": "497122432c79488e370df2164ae5637f32f82ca3",
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,7 +27,6 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||
init() {
|
||||
splashViewController = SplashViewController()
|
||||
mainNavigationController = UINavigationController(rootViewController: splashViewController)
|
||||
mainNavigationController.navigationBar.isHidden = true
|
||||
window = UIWindow(frame: UIScreen.main.bounds)
|
||||
window.rootViewController = mainNavigationController
|
||||
|
||||
@@ -89,6 +88,8 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||
switch result {
|
||||
case .logout:
|
||||
self?.authenticationCoordinator.logout()
|
||||
case .selectRoom(let roomIdentifier):
|
||||
self?.presentRoomWithIdentifier(roomIdentifier)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +97,35 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
||||
navigationRouter.setRootModule(coordinator)
|
||||
}
|
||||
|
||||
private func presentRoomWithIdentifier(_ roomIdentifier: String) {
|
||||
guard let userSession = authenticationCoordinator.userSession else {
|
||||
fatalError("User session should be already setup at this point")
|
||||
}
|
||||
|
||||
showLoadingIndicator()
|
||||
|
||||
userSession.getRoomList { [weak self] rooms in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.hideLoadingIndicator()
|
||||
|
||||
guard let roomProxy = rooms.filter({ $0.id == roomIdentifier}).first else {
|
||||
MXLog.error("Invalid room identifier: \(roomIdentifier)")
|
||||
return
|
||||
}
|
||||
|
||||
let parameters = RoomScreenCoordinatorParameters(roomProxy: roomProxy)
|
||||
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||
|
||||
coordinator.completion = { [weak self] result in
|
||||
|
||||
}
|
||||
|
||||
self.add(childCoordinator: coordinator)
|
||||
self.navigationRouter.push(coordinator)
|
||||
}
|
||||
}
|
||||
|
||||
private func showLoadingIndicator() {
|
||||
let presenter = FullscreenLoadingActivityPresenter(label: "Loading",
|
||||
on: mainNavigationController)
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
//
|
||||
// RoomModel.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 14.02.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomModelError: Error {
|
||||
case failedRetrievingDisplayName
|
||||
case failedRetrievingAvatar
|
||||
}
|
||||
|
||||
struct RoomModel: RoomModelProtocol {
|
||||
|
||||
private let room: Room
|
||||
|
||||
init(room: Room) {
|
||||
self.room = room
|
||||
}
|
||||
|
||||
var identifier: String {
|
||||
return room.identifier()
|
||||
}
|
||||
|
||||
var isDirect: Bool {
|
||||
return room.isDirect()
|
||||
}
|
||||
|
||||
var isPublic: Bool {
|
||||
return room.isPublic()
|
||||
}
|
||||
|
||||
var isSpace: Bool {
|
||||
return room.isSpace()
|
||||
}
|
||||
|
||||
var isEncrypted: Bool {
|
||||
return room.isEncrypted()
|
||||
}
|
||||
|
||||
var name: String? {
|
||||
return room.name()
|
||||
}
|
||||
|
||||
var displayName: String {
|
||||
do {
|
||||
return try room.displayName()
|
||||
} catch {
|
||||
MXLog.error("Failed retrieving room name with error: \(error)")
|
||||
return "Error"
|
||||
}
|
||||
}
|
||||
|
||||
var topic: String? {
|
||||
return room.topic()
|
||||
}
|
||||
|
||||
var lastMessage: String? {
|
||||
guard let lastMessage = try? room.messages().last else {
|
||||
return "Last message unknown"
|
||||
}
|
||||
|
||||
return "\(lastMessage.sender()): \(lastMessage.content())"
|
||||
}
|
||||
|
||||
var avatarURL: URL? {
|
||||
guard let urlString = room.avatarUrl() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return URL(string: urlString)
|
||||
}
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
let displayName = try room.displayName()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(displayName))
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(RoomModelError.failedRetrievingDisplayName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
let avatarData = try room.avatar()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(UIImage(data: Data(bytes: avatarData, count: avatarData.count))))
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(RoomModelError.failedRetrievingAvatar))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ struct HomeScreenCoordinatorParameters {
|
||||
|
||||
enum HomeScreenCoordinatorResult {
|
||||
case logout
|
||||
case selectRoom(roomIdentifier: String)
|
||||
}
|
||||
|
||||
final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
@@ -70,12 +71,14 @@ final class HomeScreenCoordinator: Coordinator, Presentable {
|
||||
break
|
||||
}
|
||||
})
|
||||
case .selectRoom(let roomIdentifier):
|
||||
self.completion?(.selectRoom(roomIdentifier: roomIdentifier))
|
||||
}
|
||||
}
|
||||
|
||||
parameters.userSession.callbacks.sink { [weak self] result in
|
||||
switch result {
|
||||
case .updatedData:
|
||||
case .updatedRoomsList:
|
||||
self?.updateRoomsList()
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
@@ -20,12 +20,14 @@ import UIKit
|
||||
enum HomeScreenViewModelResult {
|
||||
case logout
|
||||
case loadUserAvatar
|
||||
case selectRoom(roomIdentifier: String)
|
||||
}
|
||||
|
||||
enum HomeScreenViewAction {
|
||||
case logout
|
||||
case loadUserAvatar
|
||||
case loadRoomData(roomId: String)
|
||||
case loadRoomData(roomIdentifier: String)
|
||||
case selectRoom(roomIdentifier: String)
|
||||
}
|
||||
|
||||
struct HomeScreenViewState: BindableState {
|
||||
@@ -65,3 +67,11 @@ struct HomeScreenRoom: Identifiable {
|
||||
let isDirect: Bool
|
||||
let isEncrypted: Bool
|
||||
}
|
||||
|
||||
extension MutableCollection where Element == HomeScreenRoom {
|
||||
mutating func updateEach(_ update: (inout Element) -> Void) {
|
||||
for index in indices {
|
||||
update(&self[index])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Combine
|
||||
import Kingfisher
|
||||
|
||||
@available(iOS 14, *)
|
||||
@@ -24,19 +25,15 @@ typealias HomeScreenViewModelType = StateStoreViewModel<HomeScreenViewState,
|
||||
@available(iOS 14, *)
|
||||
class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var roomList: [RoomModelProtocol]? {
|
||||
private var roomUpdateListeners = Set<AnyCancellable>()
|
||||
private var roomList: [RoomProxyProtocol]? {
|
||||
didSet {
|
||||
self.state.isLoadingRooms = (roomList == nil)
|
||||
}
|
||||
}
|
||||
|
||||
private let imageCache: ImageCache
|
||||
|
||||
// MARK: Public
|
||||
|
||||
var completion: ((HomeScreenViewModelResult) -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
@@ -52,23 +49,38 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
switch viewAction {
|
||||
case .logout:
|
||||
self.completion?(.logout)
|
||||
case .loadRoomData(let roomId):
|
||||
self.loadAvatarForRoomWithIdentifier(roomId)
|
||||
self.loadRoomDisplayNameForRoomWithIdentifier(roomId)
|
||||
case .loadRoomData(let roomIdentifier):
|
||||
self.loadAvatarForRoomWithIdentifier(roomIdentifier)
|
||||
self.loadRoomDisplayNameForRoomWithIdentifier(roomIdentifier)
|
||||
case .loadUserAvatar:
|
||||
self.completion?(.loadUserAvatar)
|
||||
case .selectRoom(let roomIdentifier):
|
||||
self.completion?(.selectRoom(roomIdentifier: roomIdentifier))
|
||||
}
|
||||
}
|
||||
|
||||
func updateWithRoomList(_ roomList: [RoomModelProtocol]) {
|
||||
func updateWithRoomList(_ roomList: [RoomProxyProtocol]) {
|
||||
|
||||
roomUpdateListeners.removeAll()
|
||||
|
||||
self.roomList = roomList
|
||||
state.rooms = roomList.map { roomModel in
|
||||
HomeScreenRoom(id: roomModel.identifier,
|
||||
displayName: roomModel.name,
|
||||
topic: roomModel.topic,
|
||||
lastMessage: roomModel.lastMessage,
|
||||
isDirect: roomModel.isDirect,
|
||||
isEncrypted: roomModel.isEncrypted)
|
||||
|
||||
roomList.forEach({ roomProxy in
|
||||
roomProxy.paginateBackwards(start: 0, finish: 1)
|
||||
roomProxy.startLiveEventListener()
|
||||
roomProxy.callbacks.sink { [weak self] callback in
|
||||
switch callback {
|
||||
case .updatedLastMessage:
|
||||
self?.updateRoomForProxy(roomProxy)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
.store(in: &roomUpdateListeners)
|
||||
})
|
||||
|
||||
state.rooms = roomList.map { roomProxy in
|
||||
roomFromProxy(roomProxy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +91,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
// MARK: - Private
|
||||
|
||||
private func loadAvatarForRoomWithIdentifier(_ roomIdentifier: String) {
|
||||
guard let room = roomList?.filter({ $0.identifier == roomIdentifier }).first,
|
||||
guard let room = roomList?.filter({ $0.id == roomIdentifier }).first,
|
||||
let cacheKey = room.avatarURL?.path else {
|
||||
return
|
||||
}
|
||||
@@ -116,7 +128,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
}
|
||||
|
||||
private func loadRoomDisplayNameForRoomWithIdentifier(_ roomIdentifier: String) {
|
||||
guard let room = roomList?.filter({ $0.identifier == roomIdentifier }).first else {
|
||||
guard let room = roomList?.filter({ $0.id == roomIdentifier }).first else {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -147,4 +159,23 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
self.state.rooms[index].avatar = avatar
|
||||
}
|
||||
|
||||
private func updateRoomForProxy(_ roomProxy: RoomProxyProtocol) {
|
||||
state.rooms.updateEach { room in
|
||||
if room.id != roomProxy.id {
|
||||
return
|
||||
}
|
||||
|
||||
room = roomFromProxy(roomProxy)
|
||||
}
|
||||
}
|
||||
|
||||
private func roomFromProxy(_ roomProxy: RoomProxyProtocol) -> HomeScreenRoom {
|
||||
HomeScreenRoom(id: roomProxy.id,
|
||||
displayName: roomProxy.name,
|
||||
topic: roomProxy.topic,
|
||||
lastMessage: roomProxy.lastMessage,
|
||||
isDirect: roomProxy.isDirect,
|
||||
isEncrypted: roomProxy.isEncrypted)
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ protocol HomeScreenViewModelProtocol {
|
||||
|
||||
var context: HomeScreenViewModelType.Context { get }
|
||||
|
||||
func updateWithRoomList(_ roomList: [RoomModelProtocol])
|
||||
func updateWithRoomList(_ roomList: [RoomProxyProtocol])
|
||||
|
||||
func updateWithUserAvatar(_ avatar: UIImage?)
|
||||
}
|
||||
@@ -106,40 +106,44 @@ struct RoomCell: View {
|
||||
let context: HomeScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 16.0) {
|
||||
if let avatar = room.avatar {
|
||||
Image(uiImage: avatar)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 40, height: 40)
|
||||
.mask(Circle())
|
||||
} else {
|
||||
let _ = context.send(viewAction: .loadRoomData(roomId: room.id))
|
||||
Image(systemName: "person.3")
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
|
||||
VStack(alignment: .leading, spacing: 4.0) {
|
||||
Text(roomName(room))
|
||||
.font(.headline)
|
||||
.fontWeight(.regular)
|
||||
|
||||
if let roomTopic = room.topic, roomTopic.count > 0 {
|
||||
Text(roomTopic)
|
||||
.font(.footnote)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
Button {
|
||||
context.send(viewAction: .selectRoom(roomIdentifier: room.id))
|
||||
} label: {
|
||||
HStack(spacing: 16.0) {
|
||||
if let avatar = room.avatar {
|
||||
Image(uiImage: avatar)
|
||||
.resizable()
|
||||
.scaledToFill()
|
||||
.frame(width: 40, height: 40)
|
||||
.mask(Circle())
|
||||
} else {
|
||||
let _ = context.send(viewAction: .loadRoomData(roomIdentifier: room.id))
|
||||
Image(systemName: "person.3")
|
||||
.frame(width: 40, height: 40)
|
||||
}
|
||||
|
||||
if let lastMessage = room.lastMessage {
|
||||
Text(lastMessage)
|
||||
.font(.footnote)
|
||||
.fontWeight(.medium)
|
||||
.lineLimit(1)
|
||||
VStack(alignment: .leading, spacing: 4.0) {
|
||||
Text(roomName(room))
|
||||
.font(.headline)
|
||||
.fontWeight(.regular)
|
||||
|
||||
if let roomTopic = room.topic, roomTopic.count > 0 {
|
||||
Text(roomTopic)
|
||||
.font(.footnote)
|
||||
.fontWeight(.bold)
|
||||
.lineLimit(1)
|
||||
}
|
||||
|
||||
if let lastMessage = room.lastMessage {
|
||||
Text(lastMessage)
|
||||
.font(.footnote)
|
||||
.fontWeight(.medium)
|
||||
.lineLimit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
.frame(minHeight: 60.0)
|
||||
}
|
||||
.frame(minHeight: 60.0)
|
||||
}
|
||||
|
||||
private func roomName(_ room: HomeScreenRoom) -> String {
|
||||
@@ -153,9 +157,9 @@ struct HomeScreen_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let viewModel = HomeScreenViewModel(userDisplayName: "Johnny Appleseed", imageCache: ImageCache.default)
|
||||
|
||||
let rooms = [MockRoomModel(displayName: "Alfa"),
|
||||
MockRoomModel(displayName: "Beta"),
|
||||
MockRoomModel(displayName: "Omega")]
|
||||
let rooms = [MockRoomProxy(displayName: "Alfa"),
|
||||
MockRoomProxy(displayName: "Beta"),
|
||||
MockRoomProxy(displayName: "Omega")]
|
||||
|
||||
viewModel.updateWithRoomList(rooms)
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// Copyright 2021 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 RoomScreenCoordinatorParameters {
|
||||
let roomProxy: RoomProxyProtocol
|
||||
}
|
||||
|
||||
final class RoomScreenCoordinator: Coordinator, Presentable {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let parameters: RoomScreenCoordinatorParameters
|
||||
private let roomScreenHostingController: UIViewController
|
||||
private var roomScreenViewModel: RoomScreenViewModelProtocol
|
||||
|
||||
// MARK: Public
|
||||
|
||||
// Must be used only internally
|
||||
var childCoordinators: [Coordinator] = []
|
||||
var completion: ((RoomScreenViewModelResult) -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
@available(iOS 14.0, *)
|
||||
init(parameters: RoomScreenCoordinatorParameters) {
|
||||
self.parameters = parameters
|
||||
|
||||
let timelineProvider = RoomTimelineProvider(roomProxy: parameters.roomProxy)
|
||||
let timelineController = RoomTimelineController(timelineProvider: timelineProvider)
|
||||
|
||||
let viewModel = RoomScreenViewModel(roomProxy: parameters.roomProxy, timelineController: timelineController)
|
||||
let view = RoomScreen(context: viewModel.context)
|
||||
roomScreenViewModel = viewModel
|
||||
roomScreenHostingController = UIHostingController(rootView: view)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
func start() {
|
||||
MXLog.debug("[RoomScreenCoordinator] did start.")
|
||||
roomScreenViewModel.completion = { [weak self] result in
|
||||
MXLog.debug("[RoomScreenCoordinator] RoomScreenViewModel did complete with result: \(result).")
|
||||
guard let self = self else { return }
|
||||
self.completion?(result)
|
||||
}
|
||||
}
|
||||
|
||||
func toPresentable() -> UIViewController {
|
||||
return self.roomScreenHostingController
|
||||
}
|
||||
}
|
||||
50
ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift
Normal file
50
ElementX/Sources/Screens/RoomScreen/RoomScreenModels.swift
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// Copyright 2021 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 RoomScreenViewModelResult {
|
||||
|
||||
}
|
||||
|
||||
enum RoomScreenViewAction {
|
||||
case loadPreviousPage
|
||||
}
|
||||
|
||||
private var dateFormatter: DateFormatter = {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateStyle = .short
|
||||
dateFormatter.timeStyle = .short
|
||||
return dateFormatter
|
||||
}()
|
||||
|
||||
struct RoomScreenMessage: Identifiable, Equatable {
|
||||
|
||||
let id: String
|
||||
let sender: String
|
||||
let text: String
|
||||
let originServerTs: Date
|
||||
|
||||
var timestamp: String {
|
||||
dateFormatter.string(from: originServerTs)
|
||||
}
|
||||
}
|
||||
|
||||
struct RoomScreenViewState: BindableState {
|
||||
var roomTitle: String?
|
||||
var isLoading: Bool = false
|
||||
var messages: [RoomScreenMessage] = []
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
@available(iOS 14, *)
|
||||
typealias RoomScreenViewModelType = StateStoreViewModel<RoomScreenViewState,
|
||||
Never,
|
||||
RoomScreenViewAction>
|
||||
@available(iOS 14, *)
|
||||
class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol {
|
||||
|
||||
private struct Constants {
|
||||
static let backPaginationPageSize: UInt = 20
|
||||
}
|
||||
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private let timelineController: RoomTimelineControllerProtocol
|
||||
|
||||
var completion: ((RoomScreenViewModelResult) -> Void)?
|
||||
|
||||
// MARK: - Setup
|
||||
|
||||
init(roomProxy: RoomProxyProtocol, timelineController: RoomTimelineControllerProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
self.timelineController = timelineController
|
||||
|
||||
super.init(initialViewState: RoomScreenViewState())
|
||||
|
||||
state.messages = buildRoomScreenMessages(timelineController.timelineItems)
|
||||
|
||||
timelineController.callbacks.sink { [weak self] callback in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch callback {
|
||||
case .updatedTimelineItems:
|
||||
self.state.messages = self.buildRoomScreenMessages(timelineController.timelineItems)
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
|
||||
timelineController.paginateBackwards(Constants.backPaginationPageSize)
|
||||
}
|
||||
|
||||
// MARK: - Public
|
||||
|
||||
override func process(viewAction: RoomScreenViewAction) {
|
||||
switch viewAction {
|
||||
case .loadPreviousPage:
|
||||
timelineController.paginateBackwards(Constants.backPaginationPageSize)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func buildRoomScreenMessages(_ timelineItems: [RoomTimelineItemProtocol]) -> [RoomScreenMessage] {
|
||||
timelineItems.map { RoomScreenMessage(id: $0.id,
|
||||
sender: $0.senderDisplayName,
|
||||
text: $0.text,
|
||||
originServerTs: $0.originServerTs) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
protocol RoomScreenViewModelProtocol {
|
||||
|
||||
var completion: ((RoomScreenViewModelResult) -> Void)? { get set }
|
||||
@available(iOS 14, *)
|
||||
var context: RoomScreenViewModelType.Context { get }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Copyright 2021 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
|
||||
|
||||
class RoomScreenViewModelTests: XCTestCase {
|
||||
|
||||
}
|
||||
85
ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift
Normal file
85
ElementX/Sources/Screens/RoomScreen/View/RoomScreen.swift
Normal file
@@ -0,0 +1,85 @@
|
||||
//
|
||||
// Copyright 2021 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 RoomScreen: View {
|
||||
|
||||
let timelineBottomDividerIdentifier = "TimelineBottomDividerIdentifier"
|
||||
|
||||
@ObservedObject var context: RoomScreenViewModel.Context
|
||||
@State var backPaginationMessageIdentifier: String?
|
||||
|
||||
var body: some View {
|
||||
ScrollViewReader { reader in
|
||||
List {
|
||||
if backPaginationMessageIdentifier != nil {
|
||||
HStack {
|
||||
Spacer()
|
||||
ProgressView()
|
||||
Spacer()
|
||||
}
|
||||
} else {
|
||||
Rectangle()
|
||||
.onAppear {
|
||||
let _ = MXLog.debug("Request load previous page")
|
||||
backPaginationMessageIdentifier = context.viewState.messages.first?.id
|
||||
context.send(viewAction: .loadPreviousPage)
|
||||
}
|
||||
.frame(height: 0.0)
|
||||
}
|
||||
ForEach(context.viewState.messages) { message in
|
||||
VStack(alignment: .leading) {
|
||||
HStack {
|
||||
Text(message.sender)
|
||||
Spacer()
|
||||
Text(message.timestamp)
|
||||
}
|
||||
.font(.footnote)
|
||||
Text(message.text)
|
||||
}
|
||||
.listRowSeparator(.hidden)
|
||||
}
|
||||
|
||||
Divider()
|
||||
.id(timelineBottomDividerIdentifier)
|
||||
.listRowSeparator(.hidden)
|
||||
}
|
||||
.listStyle(.plain)
|
||||
.onAppear {
|
||||
reader.scrollTo(timelineBottomDividerIdentifier, anchor: .bottom)
|
||||
}
|
||||
.onChange(of: context.viewState.messages) { _ in
|
||||
if backPaginationMessageIdentifier != nil {
|
||||
self.backPaginationMessageIdentifier = nil
|
||||
return
|
||||
}
|
||||
|
||||
reader.scrollTo(timelineBottomDividerIdentifier, anchor: .bottom)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Previews
|
||||
|
||||
struct RoomScreen_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let viewModel = RoomScreenViewModel(roomProxy: MockRoomProxy(displayName: "Test"),
|
||||
timelineController: MockRoomTimelineController())
|
||||
RoomScreen(context: viewModel.context)
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import Combine
|
||||
import UIKit
|
||||
|
||||
enum UserSessionCallback {
|
||||
case updatedData
|
||||
case updatedRoomsList
|
||||
}
|
||||
|
||||
enum UserSessionError: Error {
|
||||
@@ -19,20 +19,27 @@ enum UserSessionError: Error {
|
||||
}
|
||||
|
||||
private class WeakUserSessionWrapper: ClientDelegate {
|
||||
weak var userSession: UserSession?
|
||||
private weak var userSession: UserSession?
|
||||
|
||||
init(userSession: UserSession) {
|
||||
self.userSession = userSession
|
||||
}
|
||||
|
||||
func didReceiveSyncUpdate() {
|
||||
userSession?.didReceiveSyncUpdate()
|
||||
DispatchQueue.main.async {
|
||||
self.userSession?.didReceiveSyncUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UserSession: ClientDelegate {
|
||||
|
||||
private let client: Client
|
||||
private var rooms: [RoomProxy] = [] {
|
||||
didSet {
|
||||
self.callbacks.send(.updatedRoomsList)
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
client.setDelegate(delegate: nil)
|
||||
@@ -81,12 +88,27 @@ class UserSession: ClientDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
func getRoomList(_ completion: @escaping ([RoomModel]) -> Void) {
|
||||
func getRoomList(_ completion: @escaping ([RoomProxyProtocol]) -> Void) {
|
||||
fetchRoomList(completion)
|
||||
}
|
||||
|
||||
// MARK: ClientDelegate
|
||||
|
||||
func didReceiveSyncUpdate() {
|
||||
fetchRoomList { [weak self] rooms in
|
||||
guard let self = self else { return }
|
||||
if self.rooms != rooms {
|
||||
self.rooms = rooms
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
func fetchRoomList(_ completion: @escaping ([RoomProxy]) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
let conversations = self.client.conversations()
|
||||
|
||||
let rooms = conversations.map {
|
||||
return RoomModel(room: $0)
|
||||
let rooms = self.client.conversations().map {
|
||||
return RoomProxy(room: $0)
|
||||
}
|
||||
|
||||
DispatchQueue.main.async {
|
||||
@@ -94,12 +116,4 @@ class UserSession: ClientDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: ClientDelegate
|
||||
|
||||
func didReceiveSyncUpdate() {
|
||||
DispatchQueue.main.async {
|
||||
self.callbacks.send(.updatedData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// MockRoomModel.swift
|
||||
// MockRoomProxy.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 17.02.2022.
|
||||
@@ -7,9 +7,10 @@
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
struct MockRoomModel: RoomModelProtocol {
|
||||
let identifier = UUID().uuidString
|
||||
struct MockRoomProxy: RoomProxyProtocol {
|
||||
let id = UUID().uuidString
|
||||
let name: String? = nil
|
||||
let displayName: String
|
||||
|
||||
@@ -23,6 +24,8 @@ struct MockRoomModel: RoomModelProtocol {
|
||||
let isPublic = Bool.random()
|
||||
let isEncrypted = Bool.random()
|
||||
|
||||
var callbacks = PassthroughSubject<RoomProxyCallback, Never>()
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||
completion(.success(displayName))
|
||||
}
|
||||
@@ -30,4 +33,12 @@ struct MockRoomModel: RoomModelProtocol {
|
||||
func loadAvatar(_ completion: (Result<UIImage?, Error>) -> Void) {
|
||||
completion(.success(UIImage(systemName: "wand.and.stars")))
|
||||
}
|
||||
|
||||
func startLiveEventListener() {
|
||||
|
||||
}
|
||||
|
||||
func paginateBackwards(start: UInt, finish: UInt) {
|
||||
|
||||
}
|
||||
}
|
||||
152
ElementX/Sources/Services/RoomProxy.swift
Normal file
152
ElementX/Sources/Services/RoomProxy.swift
Normal file
@@ -0,0 +1,152 @@
|
||||
//
|
||||
// RoomProxy.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 14.02.2022.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomProxyError: Error {
|
||||
case failedRetrievingDisplayName
|
||||
case failedRetrievingAvatar
|
||||
}
|
||||
|
||||
private class WeakRoomProxyWrapper: RoomDelegate {
|
||||
private weak var roomProxy: RoomProxy?
|
||||
|
||||
init(roomProxy: RoomProxy) {
|
||||
self.roomProxy = roomProxy
|
||||
}
|
||||
|
||||
func didReceiveMessage(message: Message) {
|
||||
DispatchQueue.main.async {
|
||||
self.roomProxy?.appendMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
func didPaginateBackwards(messages: [Message]) {
|
||||
DispatchQueue.main.async {
|
||||
self.roomProxy?.preprendMessages(messages)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RoomProxy: RoomProxyProtocol, Equatable {
|
||||
private let room: Room
|
||||
|
||||
let callbacks = PassthroughSubject<RoomProxyCallback, Never>()
|
||||
|
||||
init(room: Room) {
|
||||
self.room = room
|
||||
self.room.setDelegate(delegate: WeakRoomProxyWrapper(roomProxy: self))
|
||||
}
|
||||
|
||||
var id: String {
|
||||
return room.id()
|
||||
}
|
||||
|
||||
var isDirect: Bool {
|
||||
return room.isDirect()
|
||||
}
|
||||
|
||||
var isPublic: Bool {
|
||||
return room.isPublic()
|
||||
}
|
||||
|
||||
var isSpace: Bool {
|
||||
return room.isSpace()
|
||||
}
|
||||
|
||||
var isEncrypted: Bool {
|
||||
return room.isEncrypted()
|
||||
}
|
||||
|
||||
var name: String? {
|
||||
return room.name()
|
||||
}
|
||||
|
||||
var topic: String? {
|
||||
return room.topic()
|
||||
}
|
||||
|
||||
var lastMessage: String? {
|
||||
didSet {
|
||||
callbacks.send(.updatedLastMessage)
|
||||
}
|
||||
}
|
||||
|
||||
var avatarURL: URL? {
|
||||
guard let urlString = room.avatarUrl() else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return URL(string: urlString)
|
||||
}
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
let displayName = try self.room.displayName()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(displayName))
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(RoomProxyError.failedRetrievingDisplayName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void) {
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
do {
|
||||
let avatarData = try self.room.avatar()
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(.success(UIImage(data: Data(bytes: avatarData, count: avatarData.count))))
|
||||
}
|
||||
} catch {
|
||||
DispatchQueue.main.async {
|
||||
completion(.failure(RoomProxyError.failedRetrievingAvatar))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func startLiveEventListener() {
|
||||
room.startLiveEventListener()
|
||||
}
|
||||
|
||||
func paginateBackwards(start: UInt, finish: UInt) {
|
||||
room.paginateBackwards(from: UInt8(start), to: UInt8(finish))
|
||||
}
|
||||
|
||||
// MARK: - Equatable
|
||||
|
||||
static func == (lhs: RoomProxy, rhs: RoomProxy) -> Bool {
|
||||
lhs.id == rhs.id
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
fileprivate func preprendMessages(_ messages: [Message]) {
|
||||
if lastMessage == nil {
|
||||
lastMessage = messages.last?.content()
|
||||
}
|
||||
|
||||
callbacks.send(.prependedMessages(messages))
|
||||
}
|
||||
|
||||
fileprivate func appendMessage(_ message: Message) {
|
||||
lastMessage = message.content()
|
||||
|
||||
callbacks.send(.addedMessage(message))
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,22 @@
|
||||
//
|
||||
// RoomModelProtocol.swift
|
||||
// RoomProxyProtocol.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 17.02.2022.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
|
||||
protocol RoomModelProtocol {
|
||||
var identifier: String { get }
|
||||
enum RoomProxyCallback {
|
||||
case prependedMessages([Message])
|
||||
case addedMessage(Message)
|
||||
case updatedLastMessage
|
||||
}
|
||||
|
||||
protocol RoomProxyProtocol {
|
||||
var id: String { get }
|
||||
var isDirect: Bool { get }
|
||||
var isPublic: Bool { get }
|
||||
var isSpace: Bool { get }
|
||||
@@ -23,4 +31,9 @@ protocol RoomModelProtocol {
|
||||
|
||||
func loadDisplayName(_ completion: @escaping (Result<String, Error>) -> Void)
|
||||
func loadAvatar(_ completion: @escaping (Result<UIImage?, Error>) -> Void)
|
||||
|
||||
func startLiveEventListener()
|
||||
func paginateBackwards(start: UInt, finish: UInt)
|
||||
|
||||
var callbacks: PassthroughSubject<RoomProxyCallback, Never> { get }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// MockRoomTimelineController.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
||||
let timelineItems: [RoomTimelineItemProtocol] = [TextRoomTimelineItem(id: UUID().uuidString, senderDisplayName: "Anne", text: "You rock!", originServerTs: .now),
|
||||
TextRoomTimelineItem(id: UUID().uuidString, senderDisplayName: "Bob", text: "You rule!", originServerTs: .now)]
|
||||
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
|
||||
|
||||
func paginateBackwards(_ count: UInt) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
//
|
||||
// RoomTimelineController.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomTimelineControllerCallback {
|
||||
case updatedTimelineItems
|
||||
}
|
||||
|
||||
class RoomTimelineController: RoomTimelineControllerProtocol {
|
||||
private let timelineProvider: RoomTimelineProvider
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
let callbacks = PassthroughSubject<RoomTimelineControllerCallback, Never>()
|
||||
|
||||
private(set) var timelineItems = [RoomTimelineItemProtocol]()
|
||||
|
||||
init(timelineProvider: RoomTimelineProvider) {
|
||||
self.timelineProvider = timelineProvider
|
||||
|
||||
self.timelineProvider.callbacks.sink { [weak self] callback in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch callback {
|
||||
case .updatedMessages:
|
||||
self.timelineItems = self.timelineProvider.messages.map { message in
|
||||
let timestamp = Date(timeIntervalSince1970: TimeInterval(message.originServerTs()))
|
||||
return TextRoomTimelineItem(id: message.id(),
|
||||
senderDisplayName: message.sender(),
|
||||
text: message.content(),
|
||||
originServerTs: timestamp)
|
||||
}
|
||||
self.callbacks.send(.updatedTimelineItems)
|
||||
}
|
||||
}.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func paginateBackwards(_ count: UInt) {
|
||||
timelineProvider.paginateBackwards(count)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// RoomTimelineControllerProtocol.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
|
||||
protocol RoomTimelineControllerProtocol {
|
||||
var timelineItems: [RoomTimelineItemProtocol] { get }
|
||||
var callbacks: PassthroughSubject<RoomTimelineControllerCallback, Never> { get }
|
||||
|
||||
func paginateBackwards(_ count: UInt)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// RoomTimelineItemProtocol.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol RoomTimelineItemProtocol {
|
||||
var id: String { get }
|
||||
var senderDisplayName: String { get }
|
||||
var text: String { get }
|
||||
var originServerTs: Date { get }
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
//
|
||||
// RoomTimeline.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import MatrixRustSDK
|
||||
|
||||
enum RoomTimelineCallback {
|
||||
case updatedMessages
|
||||
}
|
||||
|
||||
class RoomTimelineProvider {
|
||||
private let roomProxy: RoomProxyProtocol
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
|
||||
private var paginationCounter: UInt = 0
|
||||
private var isWaitingPaginationResponse = false
|
||||
|
||||
let callbacks = PassthroughSubject<RoomTimelineCallback, Never>()
|
||||
private(set) var messages = [Message]()
|
||||
|
||||
init(roomProxy: RoomProxyProtocol) {
|
||||
self.roomProxy = roomProxy
|
||||
|
||||
self.roomProxy.startLiveEventListener()
|
||||
|
||||
self.roomProxy.callbacks.sink { [weak self] callback in
|
||||
guard let self = self else { return }
|
||||
|
||||
switch callback {
|
||||
case .addedMessage(let message):
|
||||
self.messages.append(message)
|
||||
case .prependedMessages(let messages):
|
||||
self.messages.insert(contentsOf: messages.reversed(), at: 0)
|
||||
self.isWaitingPaginationResponse = false
|
||||
case .updatedLastMessage:
|
||||
break
|
||||
}
|
||||
|
||||
self.callbacks.send(.updatedMessages)
|
||||
|
||||
}.store(in: &cancellables)
|
||||
}
|
||||
|
||||
func paginateBackwards(_ count: UInt) {
|
||||
if isWaitingPaginationResponse {
|
||||
return
|
||||
}
|
||||
|
||||
self.roomProxy.paginateBackwards(start: paginationCounter, finish: count)
|
||||
isWaitingPaginationResponse = true
|
||||
|
||||
// This is not in any way correct but it will do for now.
|
||||
self.paginationCounter += count
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TextRoomTimelineItem.swift
|
||||
// ElementX
|
||||
//
|
||||
// Created by Stefan Ceriu on 04.03.2022.
|
||||
// Copyright © 2022 Element. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
struct TextRoomTimelineItem: RoomTimelineItemProtocol {
|
||||
let id: String
|
||||
let senderDisplayName: String
|
||||
let text: String
|
||||
let originServerTs: Date
|
||||
}
|
||||
@@ -5,7 +5,7 @@ if [ ! $# -eq 2 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MODULE_DIR="../ElementX/Sources/Modules"
|
||||
MODULE_DIR="../ElementX/Sources/Modules/Screens"
|
||||
OUTPUT_DIR=$MODULE_DIR/$1
|
||||
SCREEN_NAME=$2
|
||||
SCREEN_VAR_NAME=`echo $SCREEN_NAME | awk '{ print tolower(substr($0, 1, 1)) substr($0, 2) }'`
|
||||
|
||||
@@ -12,6 +12,7 @@ end
|
||||
lane :ios_adhoc do
|
||||
build_ios_app(
|
||||
scheme: "ElementX",
|
||||
clean: true,
|
||||
export_method: "ad-hoc",
|
||||
output_directory: "build",
|
||||
export_options: {
|
||||
@@ -25,6 +26,7 @@ end
|
||||
lane :mac_adhoc do
|
||||
build_mac_app(
|
||||
scheme: "ElementX",
|
||||
clean: true,
|
||||
export_method: "mac-application",
|
||||
output_directory: "build"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user