mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 10:33:45 +00:00
Update UserIndicators with newer implementation from Element (modified to work here)
This commit is contained in:
committed by
Stefan Ceriu
parent
32d40eec47
commit
4b728f3d09
@@ -3,7 +3,7 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 51;
|
objectVersion = 52;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
@@ -14,13 +14,16 @@
|
|||||||
03B8FEA668A5B76A93113BB1 /* MemberDetailProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */; };
|
03B8FEA668A5B76A93113BB1 /* MemberDetailProviderManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */; };
|
||||||
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */; };
|
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */; };
|
||||||
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
059173B3C77056C406906B6D /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = D4DA544B2520BFA65D6DB4BB /* target.yml */; };
|
||||||
|
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */; };
|
||||||
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
066A1E9B94723EE9F3038044 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EBB5D698CE9A25BB553A2D /* Strings.swift */; };
|
||||||
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE6C10032A77AE7DC5AA4C50 /* MessageComposerTextField.swift */; };
|
||||||
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; };
|
||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; };
|
||||||
|
10866439ABA58CCDB5D1459D /* UserIndicatorQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C91A6BC1A54CDB598EE2A81B /* UserIndicatorQueue.swift */; };
|
||||||
|
1151DCC5EC2C6585826545EC /* UserIndicatorPresenterSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B695D0D12086158BAD1D9859 /* UserIndicatorPresenterSpy.swift */; };
|
||||||
1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */; };
|
1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */; };
|
||||||
12F70C493FB69F4D7E9A37EA /* NavigationRouterStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */; };
|
12F70C493FB69F4D7E9A37EA /* NavigationRouterStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29EBCBFEC6FD0941749404D /* NavigationRouterStore.swift */; };
|
||||||
15FEC447B7FEA62F418732AC /* ToastActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E09C9DFFE9A897E439D770C5 /* ToastActivityPresenter.swift */; };
|
15D1F9C415D9C921643BA82E /* UserIndicatorRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B73D5E21F524A9BE44448D /* UserIndicatorRequest.swift */; };
|
||||||
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */; };
|
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCA431E6EDD71F7067B5F9E7 /* UITestsRootView.swift */; };
|
||||||
1999ECC6777752A2616775CF /* MemberDetailsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */; };
|
1999ECC6777752A2616775CF /* MemberDetailsProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */; };
|
||||||
1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; };
|
1A70A2199394B5EC660934A5 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = A678E40E917620059695F067 /* MatrixRustSDK */; };
|
||||||
@@ -37,6 +40,7 @@
|
|||||||
2E59008365E01F0AFB3A6B24 /* ImageRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */; };
|
2E59008365E01F0AFB3A6B24 /* ImageRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BF686BA36D0C2FA3C63DFDF /* ImageRoomMessage.swift */; };
|
||||||
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; };
|
2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 086B997409328F091EBA43CE /* RoomScreenUITests.swift */; };
|
||||||
2FE4EEF780553B25A446BBFB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */; };
|
2FE4EEF780553B25A446BBFB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */; };
|
||||||
|
30122AB3484AC6C3A7F6A717 /* ActivityIndicatorView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B64F3A3D0DF86ED5A241AB05 /* ActivityIndicatorView.xib */; };
|
||||||
306CC09DF101E7E9CDE79AA5 /* LoginScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C8F70ADAFB63907B862E5D /* LoginScreenCoordinator.swift */; };
|
306CC09DF101E7E9CDE79AA5 /* LoginScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61C8F70ADAFB63907B862E5D /* LoginScreenCoordinator.swift */; };
|
||||||
33912D1B9264D897033E0681 /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0779B2CC9A687CBB82A5B920 /* LoginScreenViewModelProtocol.swift */; };
|
33912D1B9264D897033E0681 /* LoginScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0779B2CC9A687CBB82A5B920 /* LoginScreenViewModelProtocol.swift */; };
|
||||||
33B4E59D408AE6E02323EE41 /* NoticeRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDA364DFFC3AC71C4771251 /* NoticeRoomMessage.swift */; };
|
33B4E59D408AE6E02323EE41 /* NoticeRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDA364DFFC3AC71C4771251 /* NoticeRoomMessage.swift */; };
|
||||||
@@ -46,23 +50,23 @@
|
|||||||
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; };
|
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; };
|
||||||
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; };
|
||||||
39AE84C8E5F2FE9D2DC7775C /* EventBasedTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56008790A9C4479A6B31FDF4 /* EventBasedTimelineView.swift */; };
|
39AE84C8E5F2FE9D2DC7775C /* EventBasedTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56008790A9C4479A6B31FDF4 /* EventBasedTimelineView.swift */; };
|
||||||
3C7009EB92E77136FF7BD9D7 /* FullscreenLoadingActivityPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7D1C4699CE71F08DC5B016 /* FullscreenLoadingActivityPresenter.swift */; };
|
|
||||||
3C732330B5A3D0A64142B280 /* ActivityPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC54146B646F161762B54BBF /* ActivityPresentable.swift */; };
|
|
||||||
3D325A1147F6281C57BFCDF6 /* EventBrief.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4411C0DA0087A1CB143E96FA /* EventBrief.swift */; };
|
3D325A1147F6281C57BFCDF6 /* EventBrief.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4411C0DA0087A1CB143E96FA /* EventBrief.swift */; };
|
||||||
3ED2725734568F6B8CC87544 /* AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */; };
|
3ED2725734568F6B8CC87544 /* AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */; };
|
||||||
417E2190C02B96F498592559 /* ActivityDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34FB01A9AC30E2FA59678BC5 /* ActivityDismissal.swift */; };
|
|
||||||
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */; };
|
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */; };
|
||||||
|
462813B93C39DF93B1249403 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */; };
|
||||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */; };
|
||||||
|
4669804D0369FBED4E8625D1 /* ToastViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */; };
|
||||||
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */; };
|
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */; };
|
||||||
|
4B8A2C45FF906ADBB1F5C3B4 /* UserIndicatorQueueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04E1273CC3BC3E471AF87BE5 /* UserIndicatorQueueTests.swift */; };
|
||||||
|
4D23C56053013437C35E511E /* ActivityIndicatorPresenterType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C2318DF4C0E601EEE31F84 /* ActivityIndicatorPresenterType.swift */; };
|
||||||
4D970CB606276717B43E2332 /* TimelineItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 804F9B0FABE093C7284CD09B /* TimelineItemList.swift */; };
|
4D970CB606276717B43E2332 /* TimelineItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 804F9B0FABE093C7284CD09B /* TimelineItemList.swift */; };
|
||||||
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; };
|
4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; };
|
||||||
4ED453A61AF45EBE18D8BC69 /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */; };
|
4ED453A61AF45EBE18D8BC69 /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */; };
|
||||||
4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */; };
|
4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */; };
|
||||||
500CB65ED116B81DA52FDAEE /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874A1842477895F199567BD7 /* TimelineView.swift */; };
|
500CB65ED116B81DA52FDAEE /* TimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 874A1842477895F199567BD7 /* TimelineView.swift */; };
|
||||||
50391038BC50C8ED9A4D88A0 /* WeakDictionaryReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B23371BC8BF6164D9F6A05 /* WeakDictionaryReference.swift */; };
|
50391038BC50C8ED9A4D88A0 /* WeakDictionaryReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64B23371BC8BF6164D9F6A05 /* WeakDictionaryReference.swift */; };
|
||||||
51910CB919287139F2DF6261 /* RectangleToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D867D38F60E364DA470C131D /* RectangleToastView.swift */; };
|
|
||||||
51DB67C5B5BC68B0A6FF54D4 /* MockRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACBDC1D28EFB7789EB467E0 /* MockRoomProxy.swift */; };
|
51DB67C5B5BC68B0A6FF54D4 /* MockRoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ACBDC1D28EFB7789EB467E0 /* MockRoomProxy.swift */; };
|
||||||
539F448EC0250880703775DE /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B3947F320B9F5748C736AD3 /* LabelledActivityIndicatorView.swift */; };
|
53B9C2240C2F5533246EE230 /* RectangleToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6235E1CE00A6D989D7DB6D47 /* RectangleToastView.swift */; };
|
||||||
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; };
|
56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */; };
|
||||||
59C41313AED7566C3AC51163 /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */; };
|
59C41313AED7566C3AC51163 /* RoomSummary.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A953B6C0C431DBF4DD00B4 /* RoomSummary.swift */; };
|
||||||
5B2C4C17888FC095ED6880B2 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48971F1FFD7FC5C466889FC7 /* SplashViewController.xib */; };
|
5B2C4C17888FC095ED6880B2 /* SplashViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 48971F1FFD7FC5C466889FC7 /* SplashViewController.xib */; };
|
||||||
@@ -75,23 +79,26 @@
|
|||||||
6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; };
|
6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; };
|
||||||
67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; };
|
67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; };
|
||||||
68AC3C84E2B438036B174E30 /* EmoteRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */; };
|
68AC3C84E2B438036B174E30 /* EmoteRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 471EB7D96AFEA8D787659686 /* EmoteRoomTimelineView.swift */; };
|
||||||
|
6A367F3D7A437A79B7D9A31C /* FullscreenLoadingViewPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4112D04077F6709C5CA0A13E /* FullscreenLoadingViewPresenter.swift */; };
|
||||||
6F2AB43A1EFAD8A97AF41A15 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 5986E300FC849DEAB2EE7AEB /* Introspect */; };
|
6F2AB43A1EFAD8A97AF41A15 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 5986E300FC849DEAB2EE7AEB /* Introspect */; };
|
||||||
7002C55A4C917F3715765127 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */; };
|
7002C55A4C917F3715765127 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */; };
|
||||||
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; };
|
||||||
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */; };
|
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */; };
|
||||||
7684092532FBC71B73916441 /* RoundedToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B4238D6EB22C0F9D7A2EEC9 /* RoundedToastView.swift */; };
|
|
||||||
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; };
|
||||||
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FFCC48E7F701B6C24484593 /* WeakDictionaryKeyReference.swift */; };
|
||||||
78B71D53C1FC55FB7A9B75F0 /* RoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B0C97D2F560BCB72BE73B1 /* RoomTimelineController.swift */; };
|
78B71D53C1FC55FB7A9B75F0 /* RoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 24B0C97D2F560BCB72BE73B1 /* RoomTimelineController.swift */; };
|
||||||
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */; };
|
7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */; };
|
||||||
|
7A54700193DC1F264368746A /* UserIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */; };
|
||||||
7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; };
|
7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; };
|
||||||
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; };
|
7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; };
|
||||||
7C72B61B30B41D76953237A8 /* ActivityRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9525FEE63EBF02C97161BF7D /* ActivityRequest.swift */; };
|
|
||||||
7C9121245B11CA48307CB462 /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8FD25EB4DF66625B74E4505 /* LoginScreenViewModel.swift */; };
|
7C9121245B11CA48307CB462 /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8FD25EB4DF66625B74E4505 /* LoginScreenViewModel.swift */; };
|
||||||
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */; };
|
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */; };
|
||||||
7DE5EB4CB2401C672257283C /* WeakKeyDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */; };
|
7DE5EB4CB2401C672257283C /* WeakKeyDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */; };
|
||||||
7E1EDBA3934E6C29E5BD045B /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77DD2DA5DC8654F2A80FF1D /* Bundle.swift */; };
|
7E1EDBA3934E6C29E5BD045B /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77DD2DA5DC8654F2A80FF1D /* Bundle.swift */; };
|
||||||
7F19E97E7985F518C9018B83 /* RootRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF47564C584F614B7287F3EB /* RootRouter.swift */; };
|
7F19E97E7985F518C9018B83 /* RootRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF47564C584F614B7287F3EB /* RootRouter.swift */; };
|
||||||
|
7FA4227B2BAAA71560252866 /* UserIndicatorDismissal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D1532B5D9FB0C8461A1453 /* UserIndicatorDismissal.swift */; };
|
||||||
|
80E04BE80A89A78FBB4863BB /* UserIndicatorViewPresentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 193FB285430D3956B6E61E4D /* UserIndicatorViewPresentable.swift */; };
|
||||||
|
8775F46AE3234A5A5688C19D /* UserIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD73FAAA4A76CE4A1F3014D9 /* UserIndicator.swift */; };
|
||||||
8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */; };
|
8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */; };
|
||||||
8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F49CDE349C490D617332770 /* NoticeRoomTimelineItem.swift */; };
|
8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F49CDE349C490D617332770 /* NoticeRoomTimelineItem.swift */; };
|
||||||
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */; };
|
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */; };
|
||||||
@@ -103,6 +110,8 @@
|
|||||||
9B8DE1D424E37581C7D99CCC /* RoomTimelineControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC7CCC6DE5FA623E31BA8546 /* RoomTimelineControllerProtocol.swift */; };
|
9B8DE1D424E37581C7D99CCC /* RoomTimelineControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC7CCC6DE5FA623E31BA8546 /* RoomTimelineControllerProtocol.swift */; };
|
||||||
9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */; };
|
9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66F2402D738694F98729A441 /* RoomTimelineProvider.swift */; };
|
||||||
9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */; };
|
9C45CE85325CD591DADBC4CA /* ElementXTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */; };
|
||||||
|
9C9E48A627C7C166084E3F5B /* LabelledActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56F01DD1BBD4450E18115916 /* LabelledActivityIndicatorView.swift */; };
|
||||||
|
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */; };
|
||||||
9D2E03DB175A6AB14589076D /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 0DD568A494247444A4B56031 /* Kingfisher */; };
|
9D2E03DB175A6AB14589076D /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 0DD568A494247444A4B56031 /* Kingfisher */; };
|
||||||
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */; };
|
9DC5FB22B8F86C3B51E907C1 /* HomeScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */; };
|
||||||
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */; };
|
||||||
@@ -116,11 +125,12 @@
|
|||||||
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9760103CF316DF68698BCFE6 /* LaunchScreen.storyboard */; };
|
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9760103CF316DF68698BCFE6 /* LaunchScreen.storyboard */; };
|
||||||
B0887A7B5AFEC88981626389 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64839516BD56D1C81D84C5E0 /* MXLog.swift */; };
|
B0887A7B5AFEC88981626389 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64839516BD56D1C81D84C5E0 /* MXLog.swift */; };
|
||||||
B4AAB3257A83B73F53FB2689 /* StateStoreViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F3DFE5B444F131648066F05 /* StateStoreViewModel.swift */; };
|
B4AAB3257A83B73F53FB2689 /* StateStoreViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F3DFE5B444F131648066F05 /* StateStoreViewModel.swift */; };
|
||||||
B4EF927F0C14F2F3F8D63DE8 /* ActivityCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED659E775C4FCEBC977C6A08 /* ActivityCenter.swift */; };
|
|
||||||
B6DF6B6FA8734B70F9BF261E /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */; };
|
B6DF6B6FA8734B70F9BF261E /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5272BC4A60B6AD7553BACA1 /* BlurHashDecode.swift */; };
|
||||||
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 16DC8C5B2991724903F1FA6A /* AppIcon.pdf */; };
|
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 16DC8C5B2991724903F1FA6A /* AppIcon.pdf */; };
|
||||||
BE3237142FA6E1A13C0E7D11 /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */; };
|
BE3237142FA6E1A13C0E7D11 /* RoomSummaryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C21ECC295F4DE8DAA86D62AC /* RoomSummaryProtocol.swift */; };
|
||||||
|
BEEC06EFD30BFCA02F0FD559 /* UserIndicatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D8EA85D4F10D7445BB6368A /* UserIndicatorTests.swift */; };
|
||||||
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB7F9D6FC121204D59E18DF /* Presentable.swift */; };
|
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CB7F9D6FC121204D59E18DF /* Presentable.swift */; };
|
||||||
|
C052A8CDC7A8E7A2D906674F /* UserIndicatorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FAA6438B00FDB130F404E31 /* UserIndicatorStore.swift */; };
|
||||||
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; };
|
||||||
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; };
|
||||||
CB326BAB54E9B68658909E36 /* Benchmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */; };
|
CB326BAB54E9B68658909E36 /* Benchmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */; };
|
||||||
@@ -129,8 +139,8 @@
|
|||||||
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */; };
|
D013E70C8E28E43497820444 /* TextRoomMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */; };
|
||||||
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */; };
|
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */; };
|
||||||
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
|
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; };
|
||||||
D735AF72894A273F53D941B8 /* Activity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B33C10BC91ABFF09605DB6 /* Activity.swift */; };
|
|
||||||
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */; };
|
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */; };
|
||||||
|
D94F664677C380A3CAB8D7F6 /* ActivityIndicatorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 68706A66BBA04268F7747A2F /* ActivityIndicatorPresenter.swift */; };
|
||||||
DCB781BD227CA958809AFADF /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CC95CD75B688E946438165 /* Coordinator.swift */; };
|
DCB781BD227CA958809AFADF /* Coordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95CC95CD75B688E946438165 /* Coordinator.swift */; };
|
||||||
DD4ADDB73E0935B74D2D18D6 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E3FE65EE63CBA65592863C2 /* UserSession.swift */; };
|
DD4ADDB73E0935B74D2D18D6 /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E3FE65EE63CBA65592863C2 /* UserSession.swift */; };
|
||||||
DDB80FD2753FEAAE43CC2AAE /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */; };
|
DDB80FD2753FEAAE43CC2AAE /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */; };
|
||||||
@@ -146,6 +156,7 @@
|
|||||||
F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */; };
|
F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */; };
|
||||||
F78C57B197DA74735FEBB42C /* EventBriefFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B61C243325DC76D3086494 /* EventBriefFactoryProtocol.swift */; };
|
F78C57B197DA74735FEBB42C /* EventBriefFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92B61C243325DC76D3086494 /* EventBriefFactoryProtocol.swift */; };
|
||||||
FA9C427FFB11B1AA2DCC5602 /* RoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */; };
|
FA9C427FFB11B1AA2DCC5602 /* RoomProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47111410B6E659A697D472B5 /* RoomProxyProtocol.swift */; };
|
||||||
|
FC6B7436C3A5B3D0565227D5 /* ActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF05352F28D4E7336228E9F4 /* ActivityIndicatorView.swift */; };
|
||||||
FCB640C576292BEAF7FA3B2E /* SplashViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F395A2E917115C7AAF7F34 /* SplashViewController.swift */; };
|
FCB640C576292BEAF7FA3B2E /* SplashViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9F395A2E917115C7AAF7F34 /* SplashViewController.swift */; };
|
||||||
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA154570F693D93513E584C1 /* RoomMessageFactory.swift */; };
|
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA154570F693D93513E584C1 /* RoomMessageFactory.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
@@ -171,6 +182,7 @@
|
|||||||
01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
02A07FF019724B6ACEA73076 /* szl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = szl; path = szl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
02A07FF019724B6ACEA73076 /* szl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = szl; path = szl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
04BBC9E08250EF92ADE89CFD /* sr-Latn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sr-Latn"; path = "sr-Latn.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
04BBC9E08250EF92ADE89CFD /* sr-Latn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sr-Latn"; path = "sr-Latn.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
|
04E1273CC3BC3E471AF87BE5 /* UserIndicatorQueueTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorQueueTests.swift; sourceTree = "<group>"; };
|
||||||
057B747CF045D3C6C30EAB2C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
057B747CF045D3C6C30EAB2C /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
0779B2CC9A687CBB82A5B920 /* LoginScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
0779B2CC9A687CBB82A5B920 /* LoginScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||||
086B997409328F091EBA43CE /* RoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = "<group>"; };
|
086B997409328F091EBA43CE /* RoomScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
@@ -194,6 +206,7 @@
|
|||||||
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
13802897C7AFA360EA74C0B0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
16DC8C5B2991724903F1FA6A /* AppIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = AppIcon.pdf; sourceTree = "<group>"; };
|
16DC8C5B2991724903F1FA6A /* AppIcon.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = AppIcon.pdf; sourceTree = "<group>"; };
|
||||||
184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecorationTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
184CF8C196BE143AE226628D /* DecorationTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecorationTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
193FB285430D3956B6E61E4D /* UserIndicatorViewPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorViewPresentable.swift; sourceTree = "<group>"; };
|
||||||
1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = "<group>"; };
|
1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = "<group>"; };
|
||||||
1A2082B5226B2A3A4D0798B6 /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
1A2082B5226B2A3A4D0798B6 /* LoginScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenModels.swift; sourceTree = "<group>"; };
|
||||||
1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = "<group>"; };
|
||||||
@@ -216,7 +229,6 @@
|
|||||||
2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
2CF9FE7E0CF9F40D1509E63A /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = bg; path = bg.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = "<group>"; };
|
||||||
33E49C5C6F802B4D94CA78D1 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
33E49C5C6F802B4D94CA78D1 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
34FB01A9AC30E2FA59678BC5 /* ActivityDismissal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityDismissal.swift; sourceTree = "<group>"; };
|
|
||||||
35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
35AFCF4C05DEED04E3DB1A16 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactory.swift; sourceTree = "<group>"; };
|
36322DD0D4E29D31B0945ADC /* EventBriefFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactory.swift; sourceTree = "<group>"; };
|
||||||
3747C96188856006F784BF49 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
3747C96188856006F784BF49 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ko; path = ko.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
@@ -228,11 +240,13 @@
|
|||||||
3CDF9E55650D6035D6536538 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "nb-NO"; path = "nb-NO.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
3CDF9E55650D6035D6536538 /* nb-NO */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "nb-NO"; path = "nb-NO.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
3D4DD336905C72F95EAF34B7 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; };
|
3D4DD336905C72F95EAF34B7 /* ElementX-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ElementX-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
3DD6E7C1D8B53F47789778CD /* fr-CA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-CA"; path = "fr-CA.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
3DD6E7C1D8B53F47789778CD /* fr-CA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-CA"; path = "fr-CA.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
|
3FAA6438B00FDB130F404E31 /* UserIndicatorStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorStore.swift; sourceTree = "<group>"; };
|
||||||
3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactory.swift; sourceTree = "<group>"; };
|
3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactory.swift; sourceTree = "<group>"; };
|
||||||
4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = "<group>"; };
|
4110685D9CA159F3FD2D6BA1 /* TextRoomMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomMessage.swift; sourceTree = "<group>"; };
|
||||||
|
4112D04077F6709C5CA0A13E /* FullscreenLoadingViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingViewPresenter.swift; sourceTree = "<group>"; };
|
||||||
434522ED2BDED08759048077 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
434522ED2BDED08759048077 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
43B33C10BC91ABFF09605DB6 /* Activity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Activity.swift; sourceTree = "<group>"; };
|
|
||||||
4411C0DA0087A1CB143E96FA /* EventBrief.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBrief.swift; sourceTree = "<group>"; };
|
4411C0DA0087A1CB143E96FA /* EventBrief.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBrief.swift; sourceTree = "<group>"; };
|
||||||
|
4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewPresenter.swift; sourceTree = "<group>"; };
|
||||||
4488F5F92A64A137665C96CD /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4488F5F92A64A137665C96CD /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = pa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
44AEEE13AC1BF303AE48CBF8 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
44AEEE13AC1BF303AE48CBF8 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = "<group>"; };
|
453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
@@ -246,8 +260,9 @@
|
|||||||
49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
49D2C8E66E83EA578A7F318A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
||||||
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Benchmark.swift; sourceTree = "<group>"; };
|
49EAD710A2C16EFF7C3EA16F /* Benchmark.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Benchmark.swift; sourceTree = "<group>"; };
|
||||||
4B40B7F6FCCE2D8C242492D9 /* ga */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ga; path = ga.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4B40B7F6FCCE2D8C242492D9 /* ga */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ga; path = ga.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastViewState.swift; sourceTree = "<group>"; };
|
||||||
4C8D988E82A8DFA13BE46F7C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
4C8D988E82A8DFA13BE46F7C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = "<group>"; };
|
4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = "<group>"; };
|
||||||
4DF56C3239EA3C16951E1E66 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Localizable.strings; sourceTree = "<group>"; };
|
4DF56C3239EA3C16951E1E66 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTableViewAdapter.swift; sourceTree = "<group>"; };
|
4E854E7CF531DAC5CBEBDC75 /* ListTableViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTableViewAdapter.swift; sourceTree = "<group>"; };
|
||||||
@@ -261,19 +276,22 @@
|
|||||||
55BC11560C8A2598964FFA4C /* bs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bs; path = bs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
55BC11560C8A2598964FFA4C /* bs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bs; path = bs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
55D7187F6B0C0A651AC3DFFA /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = in; path = in.lproj/Localizable.strings; sourceTree = "<group>"; };
|
55D7187F6B0C0A651AC3DFFA /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = in; path = in.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
56008790A9C4479A6B31FDF4 /* EventBasedTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBasedTimelineView.swift; sourceTree = "<group>"; };
|
56008790A9C4479A6B31FDF4 /* EventBasedTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBasedTimelineView.swift; sourceTree = "<group>"; };
|
||||||
|
56F01DD1BBD4450E18115916 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||||
5773C86AF04AEF26515AD00C /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
5773C86AF04AEF26515AD00C /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelTests.swift; sourceTree = "<group>"; };
|
5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
5B4238D6EB22C0F9D7A2EEC9 /* RoundedToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedToastView.swift; sourceTree = "<group>"; };
|
|
||||||
5B9D5F812E5AD6DC786DBC9B /* NavigationRouterStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStoreProtocol.swift; sourceTree = "<group>"; };
|
5B9D5F812E5AD6DC786DBC9B /* NavigationRouterStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouterStoreProtocol.swift; sourceTree = "<group>"; };
|
||||||
5CB7F9D6FC121204D59E18DF /* Presentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Presentable.swift; sourceTree = "<group>"; };
|
5CB7F9D6FC121204D59E18DF /* Presentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Presentable.swift; sourceTree = "<group>"; };
|
||||||
5D26A086A8278D39B5756D6F /* project.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = project.yml; sourceTree = "<group>"; };
|
5D26A086A8278D39B5756D6F /* project.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = project.yml; sourceTree = "<group>"; };
|
||||||
|
5D8EA85D4F10D7445BB6368A /* UserIndicatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorTests.swift; sourceTree = "<group>"; };
|
||||||
5F12E996BFBEB43815189ABF /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
5F12E996BFBEB43815189ABF /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
5F77E8010D41AA3F5F9A1FCA /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = "<group>"; };
|
||||||
5FF214969B25BFCBF87B908B /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-BD"; path = "bn-BD.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
5FF214969B25BFCBF87B908B /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-BD"; path = "bn-BD.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageProtocol.swift; sourceTree = "<group>"; };
|
607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageProtocol.swift; sourceTree = "<group>"; };
|
||||||
616197D81103330BF2ADD559 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
616197D81103330BF2ADD559 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gl; path = gl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
61ADFB893DEF81E58DF3FAB9 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = "<group>"; };
|
61ADFB893DEF81E58DF3FAB9 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = "<group>"; };
|
||||||
|
61B73D5E21F524A9BE44448D /* UserIndicatorRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorRequest.swift; sourceTree = "<group>"; };
|
||||||
61C8F70ADAFB63907B862E5D /* LoginScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenCoordinator.swift; sourceTree = "<group>"; };
|
61C8F70ADAFB63907B862E5D /* LoginScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||||
|
6235E1CE00A6D989D7DB6D47 /* RectangleToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RectangleToastView.swift; sourceTree = "<group>"; };
|
||||||
624244C398804ADC885239AA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
624244C398804ADC885239AA /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineView.swift; sourceTree = "<group>"; };
|
6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
64839516BD56D1C81D84C5E0 /* MXLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
|
64839516BD56D1C81D84C5E0 /* MXLog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXLog.swift; sourceTree = "<group>"; };
|
||||||
@@ -282,12 +300,13 @@
|
|||||||
6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
6654859746B0BE9611459391 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
667DD3A9D932D7D9EB380CAA /* sk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sk; path = sk.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
|
66F2402D738694F98729A441 /* RoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineProvider.swift; sourceTree = "<group>"; };
|
||||||
|
68706A66BBA04268F7747A2F /* ActivityIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorPresenter.swift; sourceTree = "<group>"; };
|
||||||
6920A4869821BF72FFC58842 /* MockMediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProvider.swift; sourceTree = "<group>"; };
|
6920A4869821BF72FFC58842 /* MockMediaProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProvider.swift; sourceTree = "<group>"; };
|
||||||
6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailsProvider.swift; sourceTree = "<group>"; };
|
6A152791A2F56BD193BFE986 /* MemberDetailsProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailsProvider.swift; sourceTree = "<group>"; };
|
||||||
6B3947F320B9F5748C736AD3 /* LabelledActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledActivityIndicatorView.swift; sourceTree = "<group>"; };
|
|
||||||
6DB53055CB130F0651C70763 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
6DB53055CB130F0651C70763 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindableState.swift; sourceTree = "<group>"; };
|
6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindableState.swift; sourceTree = "<group>"; };
|
||||||
6F3DFE5B444F131648066F05 /* StateStoreViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateStoreViewModel.swift; sourceTree = "<group>"; };
|
6F3DFE5B444F131648066F05 /* StateStoreViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateStoreViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresentationContext.swift; sourceTree = "<group>"; };
|
||||||
6FC5015B9634698BDB8701AF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
6FC5015B9634698BDB8701AF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenModels.swift; sourceTree = "<group>"; };
|
||||||
71D52BAA5BADB06E5E8C295D /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
|
71D52BAA5BADB06E5E8C295D /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = "<group>"; };
|
||||||
@@ -309,6 +328,7 @@
|
|||||||
8210612D17A39369480FC183 /* MediaSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSource.swift; sourceTree = "<group>"; };
|
8210612D17A39369480FC183 /* MediaSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaSource.swift; sourceTree = "<group>"; };
|
||||||
84E92FF38EBC12EC2452C79C /* zh-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-TW"; path = "zh-TW.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
84E92FF38EBC12EC2452C79C /* zh-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-TW"; path = "zh-TW.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
858F8D0B0D51CC41BAA18E24 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
858F8D0B0D51CC41BAA18E24 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
85C2318DF4C0E601EEE31F84 /* ActivityIndicatorPresenterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorPresenterType.swift; sourceTree = "<group>"; };
|
||||||
85CB1DDCEE53B946D09DF4F6 /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "bn-BD"; path = "bn-BD.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
85CB1DDCEE53B946D09DF4F6 /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "bn-BD"; path = "bn-BD.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
873718F8BD17B778C5141C45 /* ta */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ta; path = ta.lproj/Localizable.strings; sourceTree = "<group>"; };
|
873718F8BD17B778C5141C45 /* ta */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ta; path = ta.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
874A1842477895F199567BD7 /* TimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineView.swift; sourceTree = "<group>"; };
|
874A1842477895F199567BD7 /* TimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineView.swift; sourceTree = "<group>"; };
|
||||||
@@ -321,13 +341,11 @@
|
|||||||
8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailProviderManager.swift; sourceTree = "<group>"; };
|
8C2ABC1A9B62BDB3D216E7FD /* MemberDetailProviderManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemberDetailProviderManager.swift; sourceTree = "<group>"; };
|
||||||
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
8E3FE65EE63CBA65592863C2 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
8E3FE65EE63CBA65592863C2 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = "<group>"; };
|
||||||
8F7D1C4699CE71F08DC5B016 /* FullscreenLoadingActivityPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FullscreenLoadingActivityPresenter.swift; sourceTree = "<group>"; };
|
|
||||||
90733775209F4D4D366A268F /* RootRouterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootRouterType.swift; sourceTree = "<group>"; };
|
90733775209F4D4D366A268F /* RootRouterType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootRouterType.swift; sourceTree = "<group>"; };
|
||||||
92B61C243325DC76D3086494 /* EventBriefFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactoryProtocol.swift; sourceTree = "<group>"; };
|
92B61C243325DC76D3086494 /* EventBriefFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBriefFactoryProtocol.swift; sourceTree = "<group>"; };
|
||||||
938BD1FCD9E6FF3FCFA7AB4C /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-CN"; path = "zh-CN.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
938BD1FCD9E6FF3FCFA7AB4C /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-CN"; path = "zh-CN.lproj/Localizable.stringsdict"; sourceTree = "<group>"; };
|
||||||
93B21E72926FACB13A186689 /* ml */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ml; path = ml.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
93B21E72926FACB13A186689 /* ml */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ml; path = ml.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelTests.swift; sourceTree = "<group>"; };
|
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelTests.swift; sourceTree = "<group>"; };
|
||||||
9525FEE63EBF02C97161BF7D /* ActivityRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityRequest.swift; sourceTree = "<group>"; };
|
|
||||||
956BDA4AE16429AD015661A8 /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
|
956BDA4AE16429AD015661A8 /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = "<group>"; };
|
||||||
95CC95CD75B688E946438165 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
95CC95CD75B688E946438165 /* Coordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coordinator.swift; sourceTree = "<group>"; };
|
||||||
967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
967873B9E11828B67F64C89A /* UITestsAppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsAppCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@@ -355,14 +373,19 @@
|
|||||||
ADCB8A232D3A8FB3E16A7303 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
ADCB8A232D3A8FB3E16A7303 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
AE225C66978648AA4AF37B45 /* te */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = te; path = te.lproj/Localizable.strings; sourceTree = "<group>"; };
|
AE225C66978648AA4AF37B45 /* te */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = te; path = te.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
AE5DDBEBBA17973ED4638823 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = de; path = de.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
AE5DDBEBBA17973ED4638823 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = de; path = de.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
|
AF05352F28D4E7336228E9F4 /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||||
AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderTests.swift; sourceTree = "<group>"; };
|
AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderTests.swift; sourceTree = "<group>"; };
|
||||||
|
AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedToastView.swift; sourceTree = "<group>"; };
|
||||||
B08CBE1E670690ECF11C2C6A /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eu; path = eu.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
B08CBE1E670690ECF11C2C6A /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eu; path = eu.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
B0C5E5931A668B18D8C09028 /* cy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cy; path = cy.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B0C5E5931A668B18D8C09028 /* cy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cy; path = cy.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B1183B55FF4B01022DA721CB /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
B1183B55FF4B01022DA721CB /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||||
B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
B12969CEC0051BC750DA5068 /* WeakKeyDictionary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakKeyDictionary.swift; sourceTree = "<group>"; };
|
||||||
|
B1D1532B5D9FB0C8461A1453 /* UserIndicatorDismissal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorDismissal.swift; sourceTree = "<group>"; };
|
||||||
B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
B4173A48FD8542CD4AD3645C /* NavigationRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRouter.swift; sourceTree = "<group>"; };
|
||||||
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = "<group>"; };
|
B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = "<group>"; };
|
||||||
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
|
B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineView.swift; sourceTree = "<group>"; };
|
||||||
|
B64F3A3D0DF86ED5A241AB05 /* ActivityIndicatorView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ActivityIndicatorView.xib; sourceTree = "<group>"; };
|
||||||
|
B695D0D12086158BAD1D9859 /* UserIndicatorPresenterSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenterSpy.swift; sourceTree = "<group>"; };
|
||||||
B6BDAC8895AB2B77B47703AE /* MockRoomSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummary.swift; sourceTree = "<group>"; };
|
B6BDAC8895AB2B77B47703AE /* MockRoomSummary.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummary.swift; sourceTree = "<group>"; };
|
||||||
B7E035C6AC137C9392D98814 /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B7E035C6AC137C9392D98814 /* lv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lv; path = lv.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
B80D1901BA0B095E27793EDE /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
|
B80D1901BA0B095E27793EDE /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
@@ -381,6 +404,7 @@
|
|||||||
C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = "<group>"; };
|
C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenModels.swift; sourceTree = "<group>"; };
|
||||||
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = "<group>"; };
|
||||||
|
C91A6BC1A54CDB598EE2A81B /* UserIndicatorQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorQueue.swift; sourceTree = "<group>"; };
|
||||||
C95ADE8D9527523572532219 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hu; path = hu.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
C95ADE8D9527523572532219 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hu; path = hu.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
C9F395A2E917115C7AAF7F34 /* SplashViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashViewController.swift; sourceTree = "<group>"; };
|
C9F395A2E917115C7AAF7F34 /* SplashViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SplashViewController.swift; sourceTree = "<group>"; };
|
||||||
CAAE4A709C0A2144C103AA0F /* ang */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ang; path = ang.lproj/Localizable.strings; sourceTree = "<group>"; };
|
CAAE4A709C0A2144C103AA0F /* ang */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ang; path = ang.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
@@ -402,10 +426,9 @@
|
|||||||
D67CBAFA48ED0B6FCE74F88F /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Localizable.strings; sourceTree = "<group>"; };
|
D67CBAFA48ED0B6FCE74F88F /* lt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = lt; path = lt.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
D6D094C15E8DB424F1C6FC94 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
D6D094C15E8DB424F1C6FC94 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hr; path = hr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
D77DD2DA5DC8654F2A80FF1D /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
|
D77DD2DA5DC8654F2A80FF1D /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = "<group>"; };
|
||||||
D867D38F60E364DA470C131D /* RectangleToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RectangleToastView.swift; sourceTree = "<group>"; };
|
|
||||||
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = "<group>"; };
|
||||||
DC54146B646F161762B54BBF /* ActivityPresentable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityPresentable.swift; sourceTree = "<group>"; };
|
DD73FAAA4A76CE4A1F3014D9 /* UserIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicator.swift; sourceTree = "<group>"; };
|
||||||
E09C9DFFE9A897E439D770C5 /* ToastActivityPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToastActivityPresenter.swift; sourceTree = "<group>"; };
|
E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserIndicatorPresenter.swift; sourceTree = "<group>"; };
|
||||||
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = "<group>"; };
|
||||||
E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = "<group>"; };
|
||||||
@@ -419,7 +442,6 @@
|
|||||||
E9D059BFE329BE09B6D96A9F /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
E9D059BFE329BE09B6D96A9F /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
|
||||||
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = "<group>"; };
|
||||||
ED659E775C4FCEBC977C6A08 /* ActivityCenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityCenter.swift; sourceTree = "<group>"; };
|
|
||||||
EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
EFFA5FD06AAAC4AF544B594E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
F012CB5EE3F2B67359F6CC52 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
F012CB5EE3F2B67359F6CC52 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = "<group>"; };
|
||||||
@@ -593,15 +615,6 @@
|
|||||||
path = View;
|
path = View;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
52C7F31749CD188294292122 /* Toasts */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
D867D38F60E364DA470C131D /* RectangleToastView.swift */,
|
|
||||||
5B4238D6EB22C0F9D7A2EEC9 /* RoundedToastView.swift */,
|
|
||||||
);
|
|
||||||
path = Toasts;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
5958CAF6E56422496E0063AF /* LoginScreen */ = {
|
5958CAF6E56422496E0063AF /* LoginScreen */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -658,6 +671,7 @@
|
|||||||
C070FD43DC6BF4E50217965A /* LocalizationTests.swift */,
|
C070FD43DC6BF4E50217965A /* LocalizationTests.swift */,
|
||||||
5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */,
|
5A43964330459965AF048A8C /* LoginScreenViewModelTests.swift */,
|
||||||
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */,
|
||||||
|
AF552BB969DC98A4BB8CF8D5 /* UserIndicators */,
|
||||||
);
|
);
|
||||||
path = Sources;
|
path = Sources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -709,21 +723,6 @@
|
|||||||
path = Media;
|
path = Media;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
8EDC2B4DFB37263DDCE0E8D1 /* Activity */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
43B33C10BC91ABFF09605DB6 /* Activity.swift */,
|
|
||||||
ED659E775C4FCEBC977C6A08 /* ActivityCenter.swift */,
|
|
||||||
34FB01A9AC30E2FA59678BC5 /* ActivityDismissal.swift */,
|
|
||||||
DC54146B646F161762B54BBF /* ActivityPresentable.swift */,
|
|
||||||
9525FEE63EBF02C97161BF7D /* ActivityRequest.swift */,
|
|
||||||
6B3947F320B9F5748C736AD3 /* LabelledActivityIndicatorView.swift */,
|
|
||||||
A04A0AFBCA9BCC4B44334981 /* ActivityPresenters */,
|
|
||||||
52C7F31749CD188294292122 /* Toasts */,
|
|
||||||
);
|
|
||||||
path = Activity;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
8F9A844EB44B6AD7CA18FD96 /* HTMLParsing */ = {
|
8F9A844EB44B6AD7CA18FD96 /* HTMLParsing */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -783,15 +782,6 @@
|
|||||||
path = WeakDictionary;
|
path = WeakDictionary;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
A04A0AFBCA9BCC4B44334981 /* ActivityPresenters */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
8F7D1C4699CE71F08DC5B016 /* FullscreenLoadingActivityPresenter.swift */,
|
|
||||||
E09C9DFFE9A897E439D770C5 /* ToastActivityPresenter.swift */,
|
|
||||||
);
|
|
||||||
path = ActivityPresenters;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
A0C06C0F6A8621B22BFAEB56 /* Localizations */ = {
|
A0C06C0F6A8621B22BFAEB56 /* Localizations */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -823,6 +813,16 @@
|
|||||||
path = Authentication;
|
path = Authentication;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
AF552BB969DC98A4BB8CF8D5 /* UserIndicators */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B695D0D12086158BAD1D9859 /* UserIndicatorPresenterSpy.swift */,
|
||||||
|
04E1273CC3BC3E471AF87BE5 /* UserIndicatorQueueTests.swift */,
|
||||||
|
5D8EA85D4F10D7445BB6368A /* UserIndicatorTests.swift */,
|
||||||
|
);
|
||||||
|
path = UserIndicators;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B53CA9BECD3F97805E1432D0 /* HomeScreen */ = {
|
B53CA9BECD3F97805E1432D0 /* HomeScreen */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -859,10 +859,10 @@
|
|||||||
95CC95CD75B688E946438165 /* Coordinator.swift */,
|
95CC95CD75B688E946438165 /* Coordinator.swift */,
|
||||||
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */,
|
F7B81C8227BBEA95CCE86037 /* MatrixEntitityRegex.swift */,
|
||||||
64839516BD56D1C81D84C5E0 /* MXLog.swift */,
|
64839516BD56D1C81D84C5E0 /* MXLog.swift */,
|
||||||
8EDC2B4DFB37263DDCE0E8D1 /* Activity */,
|
|
||||||
8F9A844EB44B6AD7CA18FD96 /* HTMLParsing */,
|
8F9A844EB44B6AD7CA18FD96 /* HTMLParsing */,
|
||||||
FE50232944F9E67ADD7A2D21 /* Routers */,
|
FE50232944F9E67ADD7A2D21 /* Routers */,
|
||||||
052CC920F473C10B509F9FC1 /* SwiftUI */,
|
052CC920F473C10B509F9FC1 /* SwiftUI */,
|
||||||
|
F8474EB69289112888B65518 /* UserIndicators */,
|
||||||
9D1AFFAEB84C76D1B4FFBB3A /* WeakDictionary */,
|
9D1AFFAEB84C76D1B4FFBB3A /* WeakDictionary */,
|
||||||
);
|
);
|
||||||
path = Other;
|
path = Other;
|
||||||
@@ -903,6 +903,31 @@
|
|||||||
path = Sources;
|
path = Sources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
F8474EB69289112888B65518 /* UserIndicators */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
68706A66BBA04268F7747A2F /* ActivityIndicatorPresenter.swift */,
|
||||||
|
85C2318DF4C0E601EEE31F84 /* ActivityIndicatorPresenterType.swift */,
|
||||||
|
AF05352F28D4E7336228E9F4 /* ActivityIndicatorView.swift */,
|
||||||
|
B64F3A3D0DF86ED5A241AB05 /* ActivityIndicatorView.xib */,
|
||||||
|
4112D04077F6709C5CA0A13E /* FullscreenLoadingViewPresenter.swift */,
|
||||||
|
56F01DD1BBD4450E18115916 /* LabelledActivityIndicatorView.swift */,
|
||||||
|
6235E1CE00A6D989D7DB6D47 /* RectangleToastView.swift */,
|
||||||
|
AFABDF2E19D349DAAAC18C65 /* RoundedToastView.swift */,
|
||||||
|
4470B8CB654B097D807AA713 /* ToastViewPresenter.swift */,
|
||||||
|
4C82DAE0B8EB28234E84E6CF /* ToastViewState.swift */,
|
||||||
|
DD73FAAA4A76CE4A1F3014D9 /* UserIndicator.swift */,
|
||||||
|
B1D1532B5D9FB0C8461A1453 /* UserIndicatorDismissal.swift */,
|
||||||
|
6FA072E995316CD18BC29313 /* UserIndicatorPresentationContext.swift */,
|
||||||
|
E077F76026C85ED96FEBB810 /* UserIndicatorPresenter.swift */,
|
||||||
|
C91A6BC1A54CDB598EE2A81B /* UserIndicatorQueue.swift */,
|
||||||
|
61B73D5E21F524A9BE44448D /* UserIndicatorRequest.swift */,
|
||||||
|
3FAA6438B00FDB130F404E31 /* UserIndicatorStore.swift */,
|
||||||
|
193FB285430D3956B6E61E4D /* UserIndicatorViewPresentable.swift */,
|
||||||
|
);
|
||||||
|
path = UserIndicators;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
FCDF06BDB123505F0334B4F9 /* Timeline */ = {
|
FCDF06BDB123505F0334B4F9 /* Timeline */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1115,6 +1140,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
30122AB3484AC6C3A7F6A717 /* ActivityIndicatorView.xib in Resources */,
|
||||||
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */,
|
B80C4FABB5529DF12436FFDA /* AppIcon.pdf in Resources */,
|
||||||
992F5E750F5030C4BA2D0D03 /* Assets.xcassets in Resources */,
|
992F5E750F5030C4BA2D0D03 /* Assets.xcassets in Resources */,
|
||||||
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */,
|
AB34401E4E1CAD5D2EC3072B /* LaunchScreen.storyboard in Resources */,
|
||||||
@@ -1195,6 +1221,9 @@
|
|||||||
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */,
|
0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */,
|
||||||
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */,
|
7434A7F02D587A920B376A9A /* LoginScreenViewModelTests.swift in Sources */,
|
||||||
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */,
|
||||||
|
1151DCC5EC2C6585826545EC /* UserIndicatorPresenterSpy.swift in Sources */,
|
||||||
|
4B8A2C45FF906ADBB1F5C3B4 /* UserIndicatorQueueTests.swift in Sources */,
|
||||||
|
BEEC06EFD30BFCA02F0FD559 /* UserIndicatorTests.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -1202,11 +1231,9 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
D735AF72894A273F53D941B8 /* Activity.swift in Sources */,
|
D94F664677C380A3CAB8D7F6 /* ActivityIndicatorPresenter.swift in Sources */,
|
||||||
B4EF927F0C14F2F3F8D63DE8 /* ActivityCenter.swift in Sources */,
|
4D23C56053013437C35E511E /* ActivityIndicatorPresenterType.swift in Sources */,
|
||||||
417E2190C02B96F498592559 /* ActivityDismissal.swift in Sources */,
|
FC6B7436C3A5B3D0565227D5 /* ActivityIndicatorView.swift in Sources */,
|
||||||
3C732330B5A3D0A64142B280 /* ActivityPresentable.swift in Sources */,
|
|
||||||
7C72B61B30B41D76953237A8 /* ActivityRequest.swift in Sources */,
|
|
||||||
A636D4900E0D98ED91536482 /* AppCoordinator.swift in Sources */,
|
A636D4900E0D98ED91536482 /* AppCoordinator.swift in Sources */,
|
||||||
2FE4EEF780553B25A446BBFB /* AppDelegate.swift in Sources */,
|
2FE4EEF780553B25A446BBFB /* AppDelegate.swift in Sources */,
|
||||||
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */,
|
90EB25D13AE6EEF034BDE9D2 /* Assets.swift in Sources */,
|
||||||
@@ -1230,7 +1257,7 @@
|
|||||||
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */,
|
418B4AEFD03DC7A6D2C9D5C8 /* EventBriefFactory.swift in Sources */,
|
||||||
F78C57B197DA74735FEBB42C /* EventBriefFactoryProtocol.swift in Sources */,
|
F78C57B197DA74735FEBB42C /* EventBriefFactoryProtocol.swift in Sources */,
|
||||||
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */,
|
A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */,
|
||||||
3C7009EB92E77136FF7BD9D7 /* FullscreenLoadingActivityPresenter.swift in Sources */,
|
6A367F3D7A437A79B7D9A31C /* FullscreenLoadingViewPresenter.swift in Sources */,
|
||||||
964B9D2EC38C488C360CE0C9 /* HomeScreen.swift in Sources */,
|
964B9D2EC38C488C360CE0C9 /* HomeScreen.swift in Sources */,
|
||||||
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */,
|
8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */,
|
||||||
8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */,
|
8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */,
|
||||||
@@ -1241,7 +1268,7 @@
|
|||||||
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */,
|
D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */,
|
||||||
2D8A687149E46B8C8B989561 /* KeychainController.swift in Sources */,
|
2D8A687149E46B8C8B989561 /* KeychainController.swift in Sources */,
|
||||||
277D2531C70F207A2F9F5906 /* KeychainControllerProtocol.swift in Sources */,
|
277D2531C70F207A2F9F5906 /* KeychainControllerProtocol.swift in Sources */,
|
||||||
539F448EC0250880703775DE /* LabelledActivityIndicatorView.swift in Sources */,
|
9C9E48A627C7C166084E3F5B /* LabelledActivityIndicatorView.swift in Sources */,
|
||||||
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */,
|
D826154612415D2A3BB6EBF3 /* ListTableViewAdapter.swift in Sources */,
|
||||||
A941EAD7F407F2ED6DA54A31 /* LoginScreen.swift in Sources */,
|
A941EAD7F407F2ED6DA54A31 /* LoginScreen.swift in Sources */,
|
||||||
306CC09DF101E7E9CDE79AA5 /* LoginScreenCoordinator.swift in Sources */,
|
306CC09DF101E7E9CDE79AA5 /* LoginScreenCoordinator.swift in Sources */,
|
||||||
@@ -1272,7 +1299,7 @@
|
|||||||
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */,
|
368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */,
|
||||||
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */,
|
7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */,
|
||||||
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */,
|
BF35062D06888FA80BD139FF /* Presentable.swift in Sources */,
|
||||||
51910CB919287139F2DF6261 /* RectangleToastView.swift in Sources */,
|
53B9C2240C2F5533246EE230 /* RectangleToastView.swift in Sources */,
|
||||||
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */,
|
FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */,
|
||||||
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */,
|
D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */,
|
||||||
4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */,
|
4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */,
|
||||||
@@ -1294,7 +1321,7 @@
|
|||||||
CF82143AA4A4F7BD11D22946 /* RoomTimelineViewProvider.swift in Sources */,
|
CF82143AA4A4F7BD11D22946 /* RoomTimelineViewProvider.swift in Sources */,
|
||||||
7F19E97E7985F518C9018B83 /* RootRouter.swift in Sources */,
|
7F19E97E7985F518C9018B83 /* RootRouter.swift in Sources */,
|
||||||
2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */,
|
2C0CE61E5DC177938618E0B1 /* RootRouterType.swift in Sources */,
|
||||||
7684092532FBC71B73916441 /* RoundedToastView.swift in Sources */,
|
462813B93C39DF93B1249403 /* RoundedToastView.swift in Sources */,
|
||||||
1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */,
|
1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */,
|
||||||
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */,
|
49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */,
|
||||||
FCB640C576292BEAF7FA3B2E /* SplashViewController.swift in Sources */,
|
FCB640C576292BEAF7FA3B2E /* SplashViewController.swift in Sources */,
|
||||||
@@ -1307,10 +1334,19 @@
|
|||||||
01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */,
|
01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */,
|
||||||
4D970CB606276717B43E2332 /* TimelineItemList.swift in Sources */,
|
4D970CB606276717B43E2332 /* TimelineItemList.swift in Sources */,
|
||||||
500CB65ED116B81DA52FDAEE /* TimelineView.swift in Sources */,
|
500CB65ED116B81DA52FDAEE /* TimelineView.swift in Sources */,
|
||||||
15FEC447B7FEA62F418732AC /* ToastActivityPresenter.swift in Sources */,
|
4669804D0369FBED4E8625D1 /* ToastViewPresenter.swift in Sources */,
|
||||||
|
9CB5129C83F75921E5E28028 /* ToastViewState.swift in Sources */,
|
||||||
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */,
|
||||||
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */,
|
03CB204C52F18E24A5C3D219 /* UITestsAppCoordinator.swift in Sources */,
|
||||||
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */,
|
17CC4FB64F3A670F43ECBE5F /* UITestsRootView.swift in Sources */,
|
||||||
|
8775F46AE3234A5A5688C19D /* UserIndicator.swift in Sources */,
|
||||||
|
7FA4227B2BAAA71560252866 /* UserIndicatorDismissal.swift in Sources */,
|
||||||
|
0602FA07557F580086782A9E /* UserIndicatorPresentationContext.swift in Sources */,
|
||||||
|
7A54700193DC1F264368746A /* UserIndicatorPresenter.swift in Sources */,
|
||||||
|
10866439ABA58CCDB5D1459D /* UserIndicatorQueue.swift in Sources */,
|
||||||
|
15D1F9C415D9C921643BA82E /* UserIndicatorRequest.swift in Sources */,
|
||||||
|
C052A8CDC7A8E7A2D906674F /* UserIndicatorStore.swift in Sources */,
|
||||||
|
80E04BE80A89A78FBB4863BB /* UserIndicatorViewPresentable.swift in Sources */,
|
||||||
DD4ADDB73E0935B74D2D18D6 /* UserSession.swift in Sources */,
|
DD4ADDB73E0935B74D2D18D6 /* UserSession.swift in Sources */,
|
||||||
01F4A40C1EDCEC8DC4EC9CFA /* WeakDictionary.swift in Sources */,
|
01F4A40C1EDCEC8DC4EC9CFA /* WeakDictionary.swift in Sources */,
|
||||||
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */,
|
77E192BA943B90F9F310CA23 /* WeakDictionaryKeyReference.swift in Sources */,
|
||||||
@@ -1528,7 +1564,7 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
|
||||||
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES;
|
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
@@ -1552,7 +1588,7 @@
|
|||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SUPPORTS_MACCATALYST = YES;
|
SUPPORTS_MACCATALYST = YES;
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "ElementX/SupportingFiles/ElementX-Bridging-Header.h";
|
||||||
SWIFT_TREAT_WARNINGS_AS_ERRORS = YES;
|
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
|
|
||||||
private let memberDetailProviderManager: MemberDetailProviderManager
|
private let memberDetailProviderManager: MemberDetailProviderManager
|
||||||
|
|
||||||
private var loadingActivity: Activity?
|
private var indicatorPresenter: UserIndicatorTypePresenterProtocol
|
||||||
private var errorActivity: Activity?
|
private var loadingIndicator: UserIndicator?
|
||||||
|
private var errorIndicator: UserIndicator?
|
||||||
|
|
||||||
var childCoordinators: [Coordinator] = []
|
var childCoordinators: [Coordinator] = []
|
||||||
|
|
||||||
@@ -35,6 +36,8 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
|
|
||||||
memberDetailProviderManager = MemberDetailProviderManager()
|
memberDetailProviderManager = MemberDetailProviderManager()
|
||||||
|
|
||||||
|
indicatorPresenter = UserIndicatorTypePresenter(presentingViewController: mainNavigationController)
|
||||||
|
|
||||||
guard let bundleIdentifier = Bundle.main.bundleIdentifier else {
|
guard let bundleIdentifier = Bundle.main.bundleIdentifier else {
|
||||||
fatalError("Should have a valid bundle identifier at this point")
|
fatalError("Should have a valid bundle identifier at this point")
|
||||||
}
|
}
|
||||||
@@ -143,30 +146,14 @@ class AppCoordinator: AuthenticationCoordinatorDelegate, Coordinator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func showLoadingIndicator() {
|
private func showLoadingIndicator() {
|
||||||
let presenter = FullscreenLoadingActivityPresenter(label: "Loading",
|
loadingIndicator = indicatorPresenter.present(.loading(label: "Loading", isInteractionBlocking: true))
|
||||||
on: mainNavigationController)
|
|
||||||
|
|
||||||
let request = ActivityRequest(
|
|
||||||
presenter: presenter,
|
|
||||||
dismissal: .manual
|
|
||||||
)
|
|
||||||
|
|
||||||
loadingActivity = ActivityCenter.shared.add(request)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func hideLoadingIndicator() {
|
private func hideLoadingIndicator() {
|
||||||
loadingActivity = nil
|
loadingIndicator = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showLoginErrorToast() {
|
private func showLoginErrorToast() {
|
||||||
let presenter = ToastActivityPresenter(viewState: .init(style: .success, label: "Failed logging in"),
|
errorIndicator = indicatorPresenter.present(.success(label: "Failed logging in"))
|
||||||
navigationController: mainNavigationController)
|
|
||||||
|
|
||||||
let request = ActivityRequest(
|
|
||||||
presenter: presenter,
|
|
||||||
dismissal: .timeout(3.0)
|
|
||||||
)
|
|
||||||
|
|
||||||
errorActivity = ActivityCenter.shared.add(request)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-67
@@ -1,67 +0,0 @@
|
|||||||
//
|
|
||||||
// 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
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
/// An `ActivityPresenter` responsible for showing / hiding a full-screen loading view that obscures (and thus disables) all other controls.
|
|
||||||
/// It is managed by an `Activity`, meaning the `present` and `dismiss` methods will be called when the parent `Activity` starts or completes.
|
|
||||||
class FullscreenLoadingActivityPresenter: ActivityPresentable {
|
|
||||||
private let label: String
|
|
||||||
private weak var viewController: UIViewController?
|
|
||||||
private weak var view: UIView?
|
|
||||||
|
|
||||||
init(label: String, on viewController: UIViewController) {
|
|
||||||
self.label = label
|
|
||||||
self.viewController = viewController
|
|
||||||
}
|
|
||||||
|
|
||||||
func present() {
|
|
||||||
let view = LabelledActivityIndicatorView(text: label)
|
|
||||||
self.view = view
|
|
||||||
|
|
||||||
guard let window = viewController?.view.window else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
window.addSubview(view)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
view.topAnchor.constraint(equalTo: window.topAnchor),
|
|
||||||
view.bottomAnchor.constraint(equalTo: window.bottomAnchor),
|
|
||||||
view.leadingAnchor.constraint(equalTo: window.leadingAnchor),
|
|
||||||
view.trailingAnchor.constraint(equalTo: window.trailingAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
view.alpha = 0
|
|
||||||
CATransaction.commit()
|
|
||||||
UIView.animate(withDuration: 0.2) {
|
|
||||||
view.alpha = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dismiss() {
|
|
||||||
guard let view = view, view.superview != nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
UIView.animate(withDuration: 0.2, delay: 0, options: .beginFromCurrentState) {
|
|
||||||
view.alpha = 0
|
|
||||||
} completion: { _ in
|
|
||||||
view.removeFromSuperview()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// 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
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
/// An `ActivityPresenter` responsible for showing / hiding a toast view for activity indicators or success messages.
|
|
||||||
/// It is managed by an `Activity`, meaning the `present` and `dismiss` methods will be called when the parent `Activity` starts or completes.
|
|
||||||
class ToastActivityPresenter: ActivityPresentable {
|
|
||||||
private let viewState: RoundedToastView.ViewState
|
|
||||||
private weak var navigationController: UINavigationController?
|
|
||||||
private weak var view: UIView?
|
|
||||||
|
|
||||||
init(viewState: RoundedToastView.ViewState, navigationController: UINavigationController) {
|
|
||||||
self.viewState = viewState
|
|
||||||
self.navigationController = navigationController
|
|
||||||
}
|
|
||||||
|
|
||||||
func present() {
|
|
||||||
guard let navigationController = navigationController,
|
|
||||||
let window = navigationController.view.window else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let view = RoundedToastView(viewState: viewState)
|
|
||||||
self.view = view
|
|
||||||
|
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
window.addSubview(view)
|
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
view.centerXAnchor.constraint(equalTo: navigationController.navigationBar.centerXAnchor),
|
|
||||||
view.topAnchor.constraint(equalTo: navigationController.navigationBar.bottomAnchor)
|
|
||||||
])
|
|
||||||
|
|
||||||
view.alpha = 0
|
|
||||||
CATransaction.flush()
|
|
||||||
view.transform = .init(translationX: 0, y: 5)
|
|
||||||
|
|
||||||
UIView.animate(withDuration: 0.2) {
|
|
||||||
view.alpha = 1
|
|
||||||
view.transform = .identity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dismiss() {
|
|
||||||
guard let view = view, view.superview != nil else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
UIView.animate(withDuration: 0.2, delay: 0, options: .beginFromCurrentState) {
|
|
||||||
view.alpha = 0
|
|
||||||
view.transform = .init(translationX: 0, y: -5)
|
|
||||||
} completion: { _ in
|
|
||||||
view.removeFromSuperview()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// Used to present activity indicator on a view
|
||||||
|
final class ActivityIndicatorPresenter: ActivityIndicatorPresenterType {
|
||||||
|
|
||||||
|
// MARK: - Constants
|
||||||
|
|
||||||
|
private enum Constants {
|
||||||
|
static let animationDuration: TimeInterval = 0.3
|
||||||
|
static let backgroundOverlayColor = UIColor.clear
|
||||||
|
static let backgroundOverlayAlpha: CGFloat = 1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
private weak var backgroundOverlayView: UIView?
|
||||||
|
private weak var activityIndicatorView: ActivityIndicatorView?
|
||||||
|
private weak var presentingView: UIView?
|
||||||
|
|
||||||
|
var isPresenting: Bool {
|
||||||
|
return self.activityIndicatorView != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func presentActivityIndicator(on view: UIView, animated: Bool, completion: (() -> Void)? = nil) {
|
||||||
|
if self.presentingView != nil {
|
||||||
|
if let completion = completion {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.presentingView = view
|
||||||
|
|
||||||
|
view.isUserInteractionEnabled = false
|
||||||
|
|
||||||
|
let backgroundOverlayView = self.createBackgroundOverlayView(with: view.frame)
|
||||||
|
|
||||||
|
let activityIndicatorView = ActivityIndicatorView()
|
||||||
|
|
||||||
|
// Add activityIndicatorView on backgroundOverlayView centered
|
||||||
|
backgroundOverlayView.addSubview(activityIndicatorView)
|
||||||
|
activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
activityIndicatorView.centerXAnchor.constraint(equalTo: backgroundOverlayView.centerXAnchor).isActive = true
|
||||||
|
activityIndicatorView.centerYAnchor.constraint(equalTo: backgroundOverlayView.centerYAnchor).isActive = true
|
||||||
|
|
||||||
|
activityIndicatorView.startAnimating()
|
||||||
|
|
||||||
|
backgroundOverlayView.alpha = 0
|
||||||
|
backgroundOverlayView.isHidden = false
|
||||||
|
|
||||||
|
view.vc_addSubViewMatchingParent(backgroundOverlayView)
|
||||||
|
|
||||||
|
self.backgroundOverlayView = backgroundOverlayView
|
||||||
|
self.activityIndicatorView = activityIndicatorView
|
||||||
|
|
||||||
|
let animationInstructions = {
|
||||||
|
backgroundOverlayView.alpha = Constants.backgroundOverlayAlpha
|
||||||
|
}
|
||||||
|
|
||||||
|
if animated {
|
||||||
|
UIView.animate(withDuration: Constants.animationDuration, animations: {
|
||||||
|
animationInstructions()
|
||||||
|
}, completion: { _ in
|
||||||
|
completion?()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
animationInstructions()
|
||||||
|
completion?()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCurrentActivityIndicator(animated: Bool, completion: (() -> Void)? = nil) {
|
||||||
|
guard let presentingView = self.presentingView,
|
||||||
|
let backgroundOverlayView = self.backgroundOverlayView,
|
||||||
|
let activityIndicatorView = self.activityIndicatorView else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
presentingView.isUserInteractionEnabled = true
|
||||||
|
self.presentingView = nil
|
||||||
|
|
||||||
|
let animationInstructions = {
|
||||||
|
activityIndicatorView.alpha = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
let animationCompletionInstructions = {
|
||||||
|
activityIndicatorView.stopAnimating()
|
||||||
|
backgroundOverlayView.isHidden = true
|
||||||
|
backgroundOverlayView.removeFromSuperview()
|
||||||
|
}
|
||||||
|
|
||||||
|
if animated {
|
||||||
|
UIView.animate(withDuration: Constants.animationDuration, animations: {
|
||||||
|
animationInstructions()
|
||||||
|
}, completion: { _ in
|
||||||
|
animationCompletionInstructions()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
animationInstructions()
|
||||||
|
animationCompletionInstructions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func createBackgroundOverlayView(with frame: CGRect = CGRect.zero) -> UIView {
|
||||||
|
let backgroundOverlayView = UIView(frame: frame)
|
||||||
|
backgroundOverlayView.backgroundColor = Constants.backgroundOverlayColor
|
||||||
|
backgroundOverlayView.alpha = Constants.backgroundOverlayAlpha
|
||||||
|
return backgroundOverlayView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UIView {
|
||||||
|
|
||||||
|
/// Add a subview matching parent view using autolayout
|
||||||
|
@objc func vc_addSubViewMatchingParent(_ subView: UIView) {
|
||||||
|
self.addSubview(subView)
|
||||||
|
subView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
let views = ["view": subView]
|
||||||
|
["H:|[view]|", "V:|[view]|"].forEach { vfl in
|
||||||
|
let constraints = NSLayoutConstraint.constraints(withVisualFormat: vfl,
|
||||||
|
options: [],
|
||||||
|
metrics: nil,
|
||||||
|
views: views)
|
||||||
|
constraints.forEach { $0.isActive = true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 UIKit
|
||||||
|
|
||||||
|
/// Protocol used to present activity indicator on a view
|
||||||
|
protocol ActivityIndicatorPresenterType {
|
||||||
|
func presentActivityIndicator(on view: UIView, animated: Bool, completion: (() -> Void)?)
|
||||||
|
func removeCurrentActivityIndicator(animated: Bool, completion: (() -> Void)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
// `ActivityIndicatorPresenterType` default implementation
|
||||||
|
extension ActivityIndicatorPresenterType {
|
||||||
|
func presentActivityIndicator(on view: UIView, animated: Bool) {
|
||||||
|
self.presentActivityIndicator(on: view, animated: animated, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCurrentActivityIndicator(animated: Bool) {
|
||||||
|
self.removeCurrentActivityIndicator(animated: animated, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 UIKit
|
||||||
|
|
||||||
|
final class ActivityIndicatorView: UIView {
|
||||||
|
|
||||||
|
// MARK: - Constants
|
||||||
|
|
||||||
|
private enum Constants {
|
||||||
|
static let cornerRadius: CGFloat = 5.0
|
||||||
|
static let activityIndicatorMargin = CGSize(width: 30.0, height: 30.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
// MARK: Outlets
|
||||||
|
|
||||||
|
@IBOutlet private weak var activityIndicatorView: UIActivityIndicatorView!
|
||||||
|
@IBOutlet private weak var activityIndicatorBackgroundView: UIView!
|
||||||
|
|
||||||
|
// MARK: Public
|
||||||
|
|
||||||
|
var color: UIColor? {
|
||||||
|
get {
|
||||||
|
return activityIndicatorView.color
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
activityIndicatorView.color = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Setup
|
||||||
|
|
||||||
|
private func commonInit() {
|
||||||
|
self.activityIndicatorBackgroundView.layer.masksToBounds = true
|
||||||
|
}
|
||||||
|
|
||||||
|
convenience init() {
|
||||||
|
self.init(frame: CGRect.zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder aDecoder: NSCoder) {
|
||||||
|
super.init(coder: aDecoder)
|
||||||
|
self.loadNibContent()
|
||||||
|
self.commonInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
self.loadNibContent()
|
||||||
|
self.commonInit()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Overrides
|
||||||
|
|
||||||
|
override var intrinsicContentSize: CGSize {
|
||||||
|
return CGSize(width: self.activityIndicatorView.intrinsicContentSize.width + Constants.activityIndicatorMargin.width,
|
||||||
|
height: self.activityIndicatorView.intrinsicContentSize.height + Constants.activityIndicatorMargin.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
self.activityIndicatorBackgroundView.layer.cornerRadius = Constants.cornerRadius
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Public
|
||||||
|
|
||||||
|
func startAnimating() {
|
||||||
|
self.activityIndicatorView.startAnimating()
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopAnimating() {
|
||||||
|
self.activityIndicatorView.stopAnimating()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UIView {
|
||||||
|
static var nib: UINib {
|
||||||
|
return UINib(nibName: String(describing: self), bundle: Bundle(for: self))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadNibContent() {
|
||||||
|
let layoutAttributes: [NSLayoutConstraint.Attribute] = [.top, .leading, .bottom, .trailing]
|
||||||
|
for case let view as UIView in type(of: self).nib.instantiate(withOwner: self, options: nil) {
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
self.addSubview(view)
|
||||||
|
NSLayoutConstraint.activate(layoutAttributes.map { attribute in
|
||||||
|
NSLayoutConstraint(
|
||||||
|
item: view, attribute: attribute,
|
||||||
|
relatedBy: .equal,
|
||||||
|
toItem: self, attribute: attribute,
|
||||||
|
multiplier: 1, constant: 0.0
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
|
<dependencies>
|
||||||
|
<deployment identifier="iOS"/>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<objects>
|
||||||
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="ActivityIndicatorView" customModule="Riot" customModuleProvider="target">
|
||||||
|
<connections>
|
||||||
|
<outlet property="activityIndicatorBackgroundView" destination="2qY-Ui-WjQ" id="obw-ml-Ppb"/>
|
||||||
|
<outlet property="activityIndicatorView" destination="32q-cl-Ru4" id="38r-gn-BJg"/>
|
||||||
|
</connections>
|
||||||
|
</placeholder>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||||
|
<view contentMode="scaleToFill" id="DuQ-Nt-i8B">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="204"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<subviews>
|
||||||
|
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2qY-Ui-WjQ">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="204"/>
|
||||||
|
<subviews>
|
||||||
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="white" translatesAutoresizingMaskIntoConstraints="NO" id="32q-cl-Ru4">
|
||||||
|
<rect key="frame" x="15" y="15" width="345" height="174"/>
|
||||||
|
</activityIndicatorView>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" red="0.80000000000000004" green="0.80000000000000004" blue="0.80000000000000004" alpha="0.89787029109589045" colorSpace="calibratedRGB"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="32q-cl-Ru4" firstAttribute="top" secondItem="2qY-Ui-WjQ" secondAttribute="top" constant="15" id="hLL-Ao-h6a"/>
|
||||||
|
<constraint firstItem="32q-cl-Ru4" firstAttribute="centerX" secondItem="2qY-Ui-WjQ" secondAttribute="centerX" id="n1z-Rb-ce3"/>
|
||||||
|
<constraint firstItem="32q-cl-Ru4" firstAttribute="leading" secondItem="2qY-Ui-WjQ" secondAttribute="leading" constant="15" id="tTB-ZQ-Xrm"/>
|
||||||
|
<constraint firstItem="32q-cl-Ru4" firstAttribute="centerY" secondItem="2qY-Ui-WjQ" secondAttribute="centerY" id="ty6-5W-zen"/>
|
||||||
|
</constraints>
|
||||||
|
</view>
|
||||||
|
</subviews>
|
||||||
|
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||||
|
<constraints>
|
||||||
|
<constraint firstItem="Zud-2y-G9d" firstAttribute="bottom" secondItem="2qY-Ui-WjQ" secondAttribute="bottom" id="F2N-Wt-CCH"/>
|
||||||
|
<constraint firstItem="2qY-Ui-WjQ" firstAttribute="top" secondItem="Zud-2y-G9d" secondAttribute="top" id="V7A-HL-11f"/>
|
||||||
|
<constraint firstItem="2qY-Ui-WjQ" firstAttribute="leading" secondItem="Zud-2y-G9d" secondAttribute="leading" id="jbB-4Q-tNb"/>
|
||||||
|
<constraint firstItem="Zud-2y-G9d" firstAttribute="trailing" secondItem="2qY-Ui-WjQ" secondAttribute="trailing" id="psU-2p-PBH"/>
|
||||||
|
</constraints>
|
||||||
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
|
<nil key="simulatedBottomBarMetrics"/>
|
||||||
|
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="Zud-2y-G9d"/>
|
||||||
|
<point key="canvasLocation" x="55" y="-605"/>
|
||||||
|
</view>
|
||||||
|
</objects>
|
||||||
|
</document>
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// 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 UIKit
|
||||||
|
|
||||||
|
/// A presenter responsible for showing / hiding a full-screen loading view that obscures (and thus disables) all other controls.
|
||||||
|
/// It is managed by a `UserIndicator`, meaning the `present` and `dismiss` methods will be called when the parent `UserIndicator` starts or completes.
|
||||||
|
class FullscreenLoadingViewPresenter: UserIndicatorViewPresentable {
|
||||||
|
private let label: String
|
||||||
|
private let presentationContext: UserIndicatorPresentationContext
|
||||||
|
private weak var view: UIView?
|
||||||
|
private var animator: UIViewPropertyAnimator?
|
||||||
|
|
||||||
|
init(label: String, presentationContext: UserIndicatorPresentationContext) {
|
||||||
|
self.label = label
|
||||||
|
self.presentationContext = presentationContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func present() {
|
||||||
|
// Find the current top navigation controller
|
||||||
|
var presentingController: UIViewController? = presentationContext.indicatorPresentingViewController
|
||||||
|
while presentingController?.navigationController != nil {
|
||||||
|
presentingController = presentingController?.navigationController
|
||||||
|
}
|
||||||
|
guard let presentingController = presentingController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let view = LabelledActivityIndicatorView(text: label)
|
||||||
|
self.view = view
|
||||||
|
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
presentingController.view.addSubview(view)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
view.topAnchor.constraint(equalTo: presentingController.view.topAnchor),
|
||||||
|
view.bottomAnchor.constraint(equalTo: presentingController.view.bottomAnchor),
|
||||||
|
view.leadingAnchor.constraint(equalTo: presentingController.view.leadingAnchor),
|
||||||
|
view.trailingAnchor.constraint(equalTo: presentingController.view.trailingAnchor)
|
||||||
|
])
|
||||||
|
|
||||||
|
view.alpha = 0
|
||||||
|
animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeOut) {
|
||||||
|
view.alpha = 1
|
||||||
|
}
|
||||||
|
animator?.startAnimation()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dismiss() {
|
||||||
|
guard let view = view, view.superview != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
animator?.stopAnimation(true)
|
||||||
|
animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeIn) {
|
||||||
|
view.alpha = 0
|
||||||
|
}
|
||||||
|
animator?.addCompletion { _ in
|
||||||
|
view.removeFromSuperview()
|
||||||
|
}
|
||||||
|
animator?.startAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
-29
@@ -14,17 +14,21 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class RoundedToastView: UIView {
|
class RoundedToastView: UIView {
|
||||||
|
private struct ShadowStyle {
|
||||||
|
let offset: CGSize
|
||||||
|
let radius: CGFloat
|
||||||
|
let opacity: Float
|
||||||
|
}
|
||||||
|
|
||||||
private struct Constants {
|
private struct Constants {
|
||||||
static let padding = UIEdgeInsets(top: 10, left: 12, bottom: 10, right: 12)
|
static let padding = UIEdgeInsets(top: 10, left: 12, bottom: 10, right: 12)
|
||||||
static let activityIndicatorScale = CGFloat(0.75)
|
static let activityIndicatorScale = CGFloat(0.75)
|
||||||
static let imageViewSize = CGFloat(15)
|
static let imageViewSize = CGFloat(15)
|
||||||
static let shadowOffset = CGSize(width: 0, height: 4)
|
static let lightShadow = ShadowStyle(offset: .init(width: 0, height: 4), radius: 12, opacity: 0.1)
|
||||||
static let shadowRadius = CGFloat(12)
|
static let darkShadow = ShadowStyle(offset: .init(width: 0, height: 4), radius: 4, opacity: 0.2)
|
||||||
static let shadowOpacity = Float(0.1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private lazy var activityIndicator: UIActivityIndicatorView = {
|
private lazy var activityIndicator: UIActivityIndicatorView = {
|
||||||
@@ -34,7 +38,7 @@ class RoundedToastView: UIView {
|
|||||||
return indicator
|
return indicator
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var imagView: UIImageView = {
|
private lazy var imageView: UIImageView = {
|
||||||
let imageView = UIImageView()
|
let imageView = UIImageView()
|
||||||
imageView.contentMode = .scaleAspectFit
|
imageView.contentMode = .scaleAspectFit
|
||||||
imageView.translatesAutoresizingMaskIntoConstraints = false
|
imageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
@@ -57,7 +61,7 @@ class RoundedToastView: UIView {
|
|||||||
return UILabel()
|
return UILabel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
init(viewState: ViewState) {
|
init(viewState: ToastViewState) {
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
setup(viewState: viewState)
|
setup(viewState: viewState)
|
||||||
}
|
}
|
||||||
@@ -66,11 +70,10 @@ class RoundedToastView: UIView {
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setup(viewState: ViewState) {
|
private func setup(viewState: ToastViewState) {
|
||||||
|
|
||||||
backgroundColor = .gray.withAlphaComponent(0.75)
|
backgroundColor = .gray.withAlphaComponent(0.75)
|
||||||
|
|
||||||
setupLayer()
|
|
||||||
setupStackView()
|
setupStackView()
|
||||||
stackView.addArrangedSubview(toastView(for: viewState.style))
|
stackView.addArrangedSubview(toastView(for: viewState.style))
|
||||||
stackView.addArrangedSubview(label)
|
stackView.addArrangedSubview(label)
|
||||||
@@ -88,36 +91,18 @@ class RoundedToastView: UIView {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
private func setupLayer() {
|
|
||||||
layer.shadowColor = UIColor.black.cgColor
|
|
||||||
layer.shadowOffset = Constants.shadowOffset
|
|
||||||
layer.shadowRadius = Constants.shadowRadius
|
|
||||||
layer.shadowOpacity = Constants.shadowOpacity
|
|
||||||
}
|
|
||||||
|
|
||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
layer.cornerRadius = layer.frame.height / 2
|
layer.cornerRadius = layer.frame.height / 2
|
||||||
}
|
}
|
||||||
|
|
||||||
private func toastView(for style: Style) -> UIView {
|
private func toastView(for style: ToastViewState.Style) -> UIView {
|
||||||
switch style {
|
switch style {
|
||||||
case .loading:
|
case .loading:
|
||||||
return activityIndicator
|
return activityIndicator
|
||||||
case .success:
|
case .success:
|
||||||
imagView.image = UIImage(systemName: "checkmark.circle")
|
imageView.image = UIImage(systemName: "checkmark.circle")
|
||||||
return imagView
|
return imageView
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension RoundedToastView {
|
|
||||||
enum Style {
|
|
||||||
case loading
|
|
||||||
case success
|
|
||||||
}
|
|
||||||
struct ViewState {
|
|
||||||
let style: Style
|
|
||||||
let label: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
//
|
||||||
|
// 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 UIKit
|
||||||
|
|
||||||
|
/// A presenter responsible for showing / hiding a toast view for loading spinners or success messages.
|
||||||
|
/// It is managed by an `UserIndicator`, meaning the `present` and `dismiss` methods will be called when the parent `UserIndicator` starts or completes.
|
||||||
|
class ToastViewPresenter: UserIndicatorViewPresentable {
|
||||||
|
struct Constants {
|
||||||
|
static let navigationBarPatting = CGFloat(10)
|
||||||
|
}
|
||||||
|
|
||||||
|
private let viewState: ToastViewState
|
||||||
|
private let presentationContext: UserIndicatorPresentationContext
|
||||||
|
private weak var view: UIView?
|
||||||
|
private var animator: UIViewPropertyAnimator?
|
||||||
|
|
||||||
|
init(viewState: ToastViewState, presentationContext: UserIndicatorPresentationContext) {
|
||||||
|
self.viewState = viewState
|
||||||
|
self.presentationContext = presentationContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func present() {
|
||||||
|
guard let viewController = presentationContext.indicatorPresentingViewController else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let view = RoundedToastView(viewState: viewState)
|
||||||
|
self.view = view
|
||||||
|
|
||||||
|
view.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
if let navigation = viewController.topNavigationController {
|
||||||
|
navigation.view.addSubview(view)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
view.centerXAnchor.constraint(equalTo: navigation.view.centerXAnchor),
|
||||||
|
view.topAnchor.constraint(equalTo: navigation.navigationBar.safeAreaLayoutGuide.bottomAnchor, constant: -Constants.navigationBarPatting)
|
||||||
|
])
|
||||||
|
} else {
|
||||||
|
viewController.view.addSubview(view)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
view.centerXAnchor.constraint(equalTo: viewController.view.centerXAnchor),
|
||||||
|
view.topAnchor.constraint(equalTo: viewController.view.topAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
view.alpha = 0
|
||||||
|
view.transform = .init(translationX: 0, y: 5)
|
||||||
|
animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeOut) {
|
||||||
|
view.alpha = 1
|
||||||
|
view.transform = .identity
|
||||||
|
}
|
||||||
|
animator?.startAnimation()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dismiss() {
|
||||||
|
guard let view = view, view.superview != nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
animator?.stopAnimation(true)
|
||||||
|
animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeIn) {
|
||||||
|
view.alpha = 0
|
||||||
|
view.transform = .init(translationX: 0, y: -5)
|
||||||
|
}
|
||||||
|
animator?.addCompletion { _ in
|
||||||
|
view.removeFromSuperview()
|
||||||
|
}
|
||||||
|
animator?.startAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension UIViewController {
|
||||||
|
var topNavigationController: UINavigationController? {
|
||||||
|
var controller: UINavigationController? = self as? UINavigationController ?? navigationController
|
||||||
|
while controller?.navigationController != nil {
|
||||||
|
controller = controller?.navigationController
|
||||||
|
}
|
||||||
|
return controller
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
|
||||||
|
struct ToastViewState {
|
||||||
|
enum Style {
|
||||||
|
case loading
|
||||||
|
case success
|
||||||
|
}
|
||||||
|
|
||||||
|
let style: Style
|
||||||
|
let label: String
|
||||||
|
}
|
||||||
+14
-13
@@ -17,27 +17,27 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
/// An `Activity` represents the state of a temporary visual indicator, such as activity indicator, success notification or an error message. It does not directly manage the UI, instead it delegates to a `presenter`
|
/// A `UserIndicator` represents the state of a temporary visual indicator, such as loading spinner, success notification or an error message. It does not directly manage the UI, instead it delegates to a `presenter`
|
||||||
/// whenever the UI should be shown or hidden.
|
/// whenever the UI should be shown or hidden.
|
||||||
///
|
///
|
||||||
/// More than one `Activity` may be requested by the system at the same time (e.g. global syncing vs local refresh),
|
/// More than one `UserIndicator` may be requested by the system at the same time (e.g. global syncing vs local refresh),
|
||||||
/// and the `ActivityCenter` will ensure that only one activity is shown at a given time, putting the other in a pending queue.
|
/// and the `UserIndicatorQueue` will ensure that only one indicator is shown at a given time, putting the other in a pending queue.
|
||||||
///
|
///
|
||||||
/// A client that requests an activity can specify a default timeout after which the activity is dismissed, or it has to be manually
|
/// A client that requests an indicator can specify a default timeout after which the indicator is dismissed, or it has to be manually
|
||||||
/// responsible for dismissing it via `cancel` method, or by deallocating itself.
|
/// responsible for dismissing it via `cancel` method, or by deallocating itself.
|
||||||
public class Activity {
|
public class UserIndicator {
|
||||||
public enum State {
|
public enum State {
|
||||||
case pending
|
case pending
|
||||||
case executing
|
case executing
|
||||||
case completed
|
case completed
|
||||||
}
|
}
|
||||||
|
|
||||||
private let request: ActivityRequest
|
private let request: UserIndicatorRequest
|
||||||
private let completion: () -> Void
|
private let completion: () -> Void
|
||||||
|
|
||||||
public private(set) var state: State
|
public private(set) var state: State
|
||||||
|
|
||||||
public init(request: ActivityRequest, completion: @escaping () -> Void) {
|
public init(request: UserIndicatorRequest, completion: @escaping () -> Void) {
|
||||||
self.request = request
|
self.request = request
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
|
|
||||||
@@ -66,10 +66,11 @@ public class Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel the activity, triggering any dismissal action / animation
|
/// Cancel the indicator, triggering any dismissal action / animation
|
||||||
///
|
///
|
||||||
/// Note: clients can call this method directly, if they have access to the `Activity`.
|
/// Note: clients can call this method directly, if they have access to the `UserIndicator`. Alternatively
|
||||||
/// Once cancelled, `ActivityCenter` will automatically start the next `Activity` in the queue.
|
/// deallocating the `UserIndicator` will call `cancel` automatically.
|
||||||
|
/// Once cancelled, `UserIndicatorQueue` will automatically start the next `UserIndicator` in the queue.
|
||||||
public func cancel() {
|
public func cancel() {
|
||||||
complete()
|
complete()
|
||||||
}
|
}
|
||||||
@@ -87,13 +88,13 @@ public class Activity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension Activity {
|
public extension UserIndicator {
|
||||||
func store<C>(in collection: inout C) where C: RangeReplaceableCollection, C.Element == Activity {
|
func store<C>(in collection: inout C) where C: RangeReplaceableCollection, C.Element == UserIndicator {
|
||||||
collection.append(self)
|
collection.append(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension Collection where Element == Activity {
|
public extension Collection where Element == UserIndicator {
|
||||||
func cancelAll() {
|
func cancelAll() {
|
||||||
forEach {
|
forEach {
|
||||||
$0.cancel()
|
$0.cancel()
|
||||||
+4
-4
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// Different ways in which an `Activity` can be dismissed
|
/// Different ways in which a `UserIndicator` can be dismissed
|
||||||
public enum ActivityDismissal {
|
public enum UserIndicatorDismissal {
|
||||||
/// The `Activity` will not manage the dismissal, but will expect the calling client to do so manually
|
/// The `UserIndicator` will not manage the dismissal, but will expect the calling client to do so manually
|
||||||
case manual
|
case manual
|
||||||
/// The `Activity` will be automatically dismissed after `TimeInterval`
|
/// The `UserIndicator` will be automatically dismissed after `TimeInterval`
|
||||||
case timeout(TimeInterval)
|
case timeout(TimeInterval)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 New Vector Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
/// The presentation context is used by `UserIndicatorViewPresentable`s to display content
|
||||||
|
/// on the screen and it serves two primary purposes:
|
||||||
|
///
|
||||||
|
/// - abstraction on top of UIKit (passing context instead of view controllers)
|
||||||
|
/// - immutable context passed at init with variable presenting view controller
|
||||||
|
/// (e.g. depending on collapsed / uncollapsed iPad presentation that changes
|
||||||
|
/// at runtime)
|
||||||
|
public protocol UserIndicatorPresentationContext {
|
||||||
|
var indicatorPresentingViewController: UIViewController? { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A simple implementation of `UserIndicatorPresentationContext` that uses a weak reference
|
||||||
|
/// to the passed-in view controller as the presentation context.
|
||||||
|
public class StaticUserIndicatorPresentationContext: UserIndicatorPresentationContext {
|
||||||
|
// The presenting view controller will be the parent of the user indicator,
|
||||||
|
// and the indicator holds a strong reference to the context, so the view controller
|
||||||
|
// must be decleared `weak` to avoid a retain cycle
|
||||||
|
public private(set) weak var indicatorPresentingViewController: UIViewController?
|
||||||
|
|
||||||
|
public init(viewController: UIViewController) {
|
||||||
|
self.indicatorPresentingViewController = viewController
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
//
|
||||||
|
// 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 UIKit
|
||||||
|
|
||||||
|
/// A set of user interactors commonly used across the app
|
||||||
|
enum UserIndicatorType {
|
||||||
|
case loading(label: String, isInteractionBlocking: Bool)
|
||||||
|
case success(label: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A presenter which can handle `UserIndicatorType` by creating the underlying `UserIndicator`
|
||||||
|
/// and adding it to its `UserIndicatorQueue`
|
||||||
|
protocol UserIndicatorTypePresenterProtocol {
|
||||||
|
/// Present a new type of user indicator, such as loading spinner or success message.
|
||||||
|
///
|
||||||
|
/// The presenter will internally convert the type into a `UserIndicator` and add it to its internal queue
|
||||||
|
/// of other indicators.
|
||||||
|
///
|
||||||
|
/// If the queue is empty, the indicator will be displayed immediately, otherwise it will be pending
|
||||||
|
/// until the previously added indicators have completed / been cancelled.
|
||||||
|
///
|
||||||
|
/// To remove an indicator, `cancel` or deallocate the returned `UserIndicator`
|
||||||
|
func present(_ type: UserIndicatorType) -> UserIndicator
|
||||||
|
|
||||||
|
/// The queue of user indicators owned by the presenter
|
||||||
|
///
|
||||||
|
/// Clients can access the queue to add custom `UserIndicatorRequest`s
|
||||||
|
/// above and beyond those defined by `UserIndicatorType`
|
||||||
|
var queue: UserIndicatorQueue { get }
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserIndicatorTypePresenter: UserIndicatorTypePresenterProtocol {
|
||||||
|
private let presentationContext: UserIndicatorPresentationContext
|
||||||
|
let queue: UserIndicatorQueue
|
||||||
|
|
||||||
|
init(presentationContext: UserIndicatorPresentationContext) {
|
||||||
|
self.presentationContext = presentationContext
|
||||||
|
self.queue = UserIndicatorQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
convenience init(presentingViewController: UIViewController) {
|
||||||
|
let context = StaticUserIndicatorPresentationContext(viewController: presentingViewController)
|
||||||
|
self.init(presentationContext: context)
|
||||||
|
}
|
||||||
|
|
||||||
|
func present(_ type: UserIndicatorType) -> UserIndicator {
|
||||||
|
let request = userIndicatorRequest(for: type)
|
||||||
|
return queue.add(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func userIndicatorRequest(for type: UserIndicatorType) -> UserIndicatorRequest {
|
||||||
|
switch type {
|
||||||
|
case .loading(let label, let isInteractionBlocking):
|
||||||
|
if isInteractionBlocking {
|
||||||
|
return fullScreenLoadingRequest(label: label)
|
||||||
|
} else {
|
||||||
|
return loadingRequest(label: label)
|
||||||
|
}
|
||||||
|
case .success(let label):
|
||||||
|
return successRequest(label: label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func loadingRequest(label: String) -> UserIndicatorRequest {
|
||||||
|
let presenter = ToastViewPresenter(
|
||||||
|
viewState: .init(
|
||||||
|
style: .loading,
|
||||||
|
label: label
|
||||||
|
),
|
||||||
|
presentationContext: presentationContext
|
||||||
|
)
|
||||||
|
return UserIndicatorRequest(
|
||||||
|
presenter: presenter,
|
||||||
|
dismissal: .manual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func fullScreenLoadingRequest(label: String) -> UserIndicatorRequest {
|
||||||
|
let presenter = FullscreenLoadingViewPresenter(
|
||||||
|
label: label,
|
||||||
|
presentationContext: presentationContext
|
||||||
|
)
|
||||||
|
return UserIndicatorRequest(
|
||||||
|
presenter: presenter,
|
||||||
|
dismissal: .manual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func successRequest(label: String) -> UserIndicatorRequest {
|
||||||
|
let presenter = ToastViewPresenter(
|
||||||
|
viewState: .init(
|
||||||
|
style: .success,
|
||||||
|
label: label
|
||||||
|
),
|
||||||
|
presentationContext: presentationContext
|
||||||
|
)
|
||||||
|
return UserIndicatorRequest(
|
||||||
|
presenter: presenter,
|
||||||
|
dismissal: .timeout(1.5)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
-15
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A shared activity center with a single FIFO queue which will ensure only one activity is shown at a given time.
|
/// A FIFO queue which will ensure only one user indicator is shown at a given time.
|
||||||
///
|
///
|
||||||
/// `ActivityCenter` offers a `shared` center that can be used by any clients, but clients are also allowed
|
/// `UserIndicatorQueue` offers a `shared` queue that can be used by any clients app-wide, but clients are also allowed
|
||||||
/// to create local `ActivityCenter` if the context requres multiple simultaneous activities.
|
/// to create local `UserIndicatorQueue` if the context requres multiple simultaneous indicators.
|
||||||
public class ActivityCenter {
|
public class UserIndicatorQueue {
|
||||||
private class Weak<T: AnyObject> {
|
private class Weak<T: AnyObject> {
|
||||||
weak var element: T?
|
weak var element: T?
|
||||||
init(_ element: T) {
|
init(_ element: T) {
|
||||||
@@ -28,27 +28,30 @@ public class ActivityCenter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static let shared = ActivityCenter()
|
private var queue: [Weak<UserIndicator>]
|
||||||
private var queue = [Weak<Activity>]()
|
|
||||||
|
|
||||||
/// Add a new activity to the queue by providing a request.
|
public init() {
|
||||||
|
queue = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a new indicator to the queue by providing a request.
|
||||||
///
|
///
|
||||||
/// The queue will start the activity right away, if there are no currently running activities,
|
/// The queue will start the indicator right away, if there are no currently running indicators,
|
||||||
/// otherwise the activity will be put on hold.
|
/// otherwise the indicator will be put on hold.
|
||||||
public func add(_ request: ActivityRequest) -> Activity {
|
public func add(_ request: UserIndicatorRequest) -> UserIndicator {
|
||||||
let activity = Activity(request: request) { [weak self] in
|
let indicator = UserIndicator(request: request) { [weak self] in
|
||||||
self?.startNextIfIdle()
|
self?.startNextIfIdle()
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.append(Weak(activity))
|
queue.append(Weak(indicator))
|
||||||
startNextIfIdle()
|
startNextIfIdle()
|
||||||
return activity
|
return indicator
|
||||||
}
|
}
|
||||||
|
|
||||||
private func startNextIfIdle() {
|
private func startNextIfIdle() {
|
||||||
cleanup()
|
cleanup()
|
||||||
if let activity = queue.first?.element, activity.state == .pending {
|
if let indicator = queue.first?.element, indicator.state == .pending {
|
||||||
activity.start()
|
indicator.start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+5
-5
@@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A request used to create an underlying `Activity`, allowing clients to only specify the visual aspects of an activity.
|
/// A request used to create an underlying `UserIndicator`, allowing clients to only specify the visual aspects of an indicator.
|
||||||
public struct ActivityRequest {
|
public struct UserIndicatorRequest {
|
||||||
internal let presenter: ActivityPresentable
|
internal let presenter: UserIndicatorViewPresentable
|
||||||
internal let dismissal: ActivityDismissal
|
internal let dismissal: UserIndicatorDismissal
|
||||||
|
|
||||||
public init(presenter: ActivityPresentable, dismissal: ActivityDismissal) {
|
public init(presenter: UserIndicatorViewPresentable, dismissal: UserIndicatorDismissal) {
|
||||||
self.presenter = presenter
|
self.presenter = presenter
|
||||||
self.dismissal = dismissal
|
self.dismissal = dismissal
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
//
|
||||||
|
// Copyright 2022 New Vector Ltd
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
typealias UserIndicatorCancel = () -> Void
|
||||||
|
|
||||||
|
/// An abstraction on top of `UserIndicatorTypePresenterProtocol` which manages and stores the individual user indicators.
|
||||||
|
/// When used to present an indicator the `UserIndicatorStore` will instead returns a simple callback function to the clients
|
||||||
|
/// letting them cancel the indicators without worrying about memory.
|
||||||
|
@objc final class UserIndicatorStore: NSObject {
|
||||||
|
private let presenter: UserIndicatorTypePresenterProtocol
|
||||||
|
private var indicators: [UserIndicator]
|
||||||
|
|
||||||
|
init(presenter: UserIndicatorTypePresenterProtocol) {
|
||||||
|
self.presenter = presenter
|
||||||
|
self.indicators = []
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Present a new type of user indicator, such as loading spinner or success message.
|
||||||
|
/// To remove an indicator, call the returned `UserIndicatorCancel` function
|
||||||
|
func present(type: UserIndicatorType) -> UserIndicatorCancel {
|
||||||
|
let indicator = presenter.present(type)
|
||||||
|
indicators.append(indicator)
|
||||||
|
return {
|
||||||
|
indicator.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Present a loading indicator.
|
||||||
|
/// To remove the indicator call the returned `UserIndicatorCancel` function
|
||||||
|
///
|
||||||
|
/// Note: This is a convenience function callable by objective-c code
|
||||||
|
@objc func presentLoading(label: String, isInteractionBlocking: Bool) -> UserIndicatorCancel {
|
||||||
|
present(
|
||||||
|
type: .loading(
|
||||||
|
label: label,
|
||||||
|
isInteractionBlocking: isInteractionBlocking
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Present a success message that will be automatically dismissed after a few seconds.
|
||||||
|
///
|
||||||
|
/// Note: This is a convenience function callable by objective-c code
|
||||||
|
@objc func presentSuccess(label: String) {
|
||||||
|
let indicator = presenter.present(.success(label: label))
|
||||||
|
indicators.append(indicator)
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-4
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
/// A presenter associated with and called by an `Activity`, and responsible for the underlying view shown on the screen.
|
/// A presenter associated with and called by a `UserIndicator`, and responsible for the underlying view shown on the screen.
|
||||||
public protocol ActivityPresentable {
|
public protocol UserIndicatorViewPresentable {
|
||||||
/// Called when the `Activity` is started (manually or by the `ActivityCenter`)
|
/// Called when the `UserIndicator` is started (manually or by the `UserIndicatorQueue`)
|
||||||
func present()
|
func present()
|
||||||
/// Called when the `Activity` is manually cancelled or completed
|
/// Called when the `UserIndicator` is manually cancelled or completed
|
||||||
func dismiss()
|
func dismiss()
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
class UserIndicatorPresenterSpy: UserIndicatorViewPresentable {
|
||||||
|
var intel = [String]()
|
||||||
|
|
||||||
|
func present() {
|
||||||
|
intel.append(#function)
|
||||||
|
}
|
||||||
|
|
||||||
|
func dismiss() {
|
||||||
|
intel.append(#function)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
import XCTest
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
class UserIndicatorQueueTests: XCTestCase {
|
||||||
|
var indicators: [UserIndicator]!
|
||||||
|
var queue: UserIndicatorQueue!
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
indicators = []
|
||||||
|
queue = UserIndicatorQueue()
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeRequest() -> UserIndicatorRequest {
|
||||||
|
return UserIndicatorRequest(
|
||||||
|
presenter: UserIndicatorPresenterSpy(),
|
||||||
|
dismissal: .manual
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testStartsIndicatorWhenAdded() {
|
||||||
|
let indicator = queue.add(makeRequest())
|
||||||
|
XCTAssertEqual(indicator.state, .executing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSecondIndicatorIsPending() {
|
||||||
|
queue.add(makeRequest()).store(in: &indicators)
|
||||||
|
let indicator = queue.add(makeRequest())
|
||||||
|
XCTAssertEqual(indicator.state, .pending)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSecondIndicatorIsExecutingWhenFirstCompleted() {
|
||||||
|
let first = queue.add(makeRequest())
|
||||||
|
let second = queue.add(makeRequest())
|
||||||
|
|
||||||
|
first.cancel()
|
||||||
|
|
||||||
|
XCTAssertEqual(second.state, .executing)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
//
|
||||||
|
// 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
|
||||||
|
import XCTest
|
||||||
|
@testable import ElementX
|
||||||
|
|
||||||
|
class UserIndicatorTests: XCTestCase {
|
||||||
|
var presenter: UserIndicatorPresenterSpy!
|
||||||
|
|
||||||
|
override func setUp() {
|
||||||
|
super.setUp()
|
||||||
|
presenter = UserIndicatorPresenterSpy()
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeIndicator(dismissal: UserIndicatorDismissal = .manual, callback: @escaping () -> Void = {}) -> UserIndicator {
|
||||||
|
let request = UserIndicatorRequest(
|
||||||
|
presenter: presenter,
|
||||||
|
dismissal: dismissal
|
||||||
|
)
|
||||||
|
return UserIndicator(
|
||||||
|
request: request,
|
||||||
|
completion: callback
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - State
|
||||||
|
|
||||||
|
func testNewIndicatorIsPending() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
XCTAssertEqual(indicator.state, .pending)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testStartedIndicatorIsExecuting() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.start()
|
||||||
|
XCTAssertEqual(indicator.state, .executing)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCancelledIndicatorIsCompleted() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.cancel()
|
||||||
|
XCTAssertEqual(indicator.state, .completed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Presenter
|
||||||
|
|
||||||
|
func testStartingIndicatorPresentsUI() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.start()
|
||||||
|
XCTAssertEqual(presenter.intel, ["present()"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAllowStartingOnlyOnce() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.start()
|
||||||
|
presenter.intel = []
|
||||||
|
|
||||||
|
indicator.start()
|
||||||
|
|
||||||
|
XCTAssertEqual(presenter.intel, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCancellingIndicatorDismissesUI() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.start()
|
||||||
|
presenter.intel = []
|
||||||
|
|
||||||
|
indicator.cancel()
|
||||||
|
|
||||||
|
XCTAssertEqual(presenter.intel, ["dismiss()"])
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAllowCancellingOnlyOnce() {
|
||||||
|
let indicator = makeIndicator()
|
||||||
|
indicator.start()
|
||||||
|
indicator.cancel()
|
||||||
|
presenter.intel = []
|
||||||
|
|
||||||
|
indicator.cancel()
|
||||||
|
|
||||||
|
XCTAssertEqual(presenter.intel, [])
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Dismissal
|
||||||
|
|
||||||
|
func testDismissAfterTimeout() {
|
||||||
|
let interval: TimeInterval = 0.01
|
||||||
|
let indicator = makeIndicator(dismissal: .timeout(interval))
|
||||||
|
|
||||||
|
indicator.start()
|
||||||
|
|
||||||
|
let exp = expectation(description: "")
|
||||||
|
DispatchQueue.main.asyncAfter(deadline: .now() + interval) {
|
||||||
|
exp.fulfill()
|
||||||
|
}
|
||||||
|
waitForExpectations(timeout: 1)
|
||||||
|
|
||||||
|
XCTAssertEqual(indicator.state, .completed)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Completion callback
|
||||||
|
|
||||||
|
func testTriggersCallbackWhenCompleted() {
|
||||||
|
var didComplete = false
|
||||||
|
let indicator = makeIndicator {
|
||||||
|
didComplete = true
|
||||||
|
}
|
||||||
|
indicator.start()
|
||||||
|
|
||||||
|
indicator.cancel()
|
||||||
|
|
||||||
|
XCTAssertTrue(didComplete)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user