diff --git a/ElementX.xcodeproj/project.pbxproj b/ElementX.xcodeproj/project.pbxproj index 636e464a07..6c019fc54e 100644 --- a/ElementX.xcodeproj/project.pbxproj +++ b/ElementX.xcodeproj/project.pbxproj @@ -3,12 +3,11 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 51; objects = { /* Begin PBXBuildFile section */ 0033481EE363E4914295F188 /* LocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C070FD43DC6BF4E50217965A /* LocalizationTests.swift */; }; - 00EA14F62DCEF62CDE4808D6 /* RedactedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B577F829C693B8DFB7014FD /* RedactedRoomTimelineItem.swift */; }; 00F3059B1E0CFCA019710C3E /* BugReportModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B516212D9FE785DDD5E490D1 /* BugReportModels.swift */; }; 01CB8ACFA5E143E89C168CA8 /* TimelineItemContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */; }; 02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 218AB05B4E3889731959C5F1 /* EventBasedTimelineItemProtocol.swift */; }; @@ -33,20 +32,22 @@ 0BEFE400B4802FE8C9DB39B3 /* FilePreviewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62BDF0FF4F59AF6EA858B70B /* FilePreviewViewModel.swift */; }; 0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */; }; 0C38C3E771B472E27295339D /* SessionVerificationModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4BB9A17AC512A7EF4B106E5 /* SessionVerificationModels.swift */; }; + 0C58A846F61949B1D545D661 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */; }; + 0DB01C67B68CB26E5B3A21AF /* RoomMemberDetailsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53C4265ED404027938012B35 /* RoomMemberDetailsViewModelProtocol.swift */; }; 0E8C480700870BB34A2A360F /* AppAuth in Frameworks */ = {isa = PBXBuildFile; productRef = 4346F63D53A346271577FD9C /* AppAuth */; }; 0EA6537A07E2DC882AEA5962 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = 187853A7E643995EE49FAD43 /* Localizable.stringsdict */; }; 0EE5EBA18BA1FE10254BB489 /* UIFont+AttributedStringBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */; }; 0F3F2FDD4021A25A0D57F801 /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 885D8C42DD17625B5261BEFF /* MediaProvider.swift */; }; 0F9E38A75337D0146652ACAB /* BackgroundTaskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DFCAA239095A116976E32C4 /* BackgroundTaskTests.swift */; }; 1146E9EDCF8344F7D6E0D553 /* MockCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0376C429FAB1687C3D905F3E /* MockCoder.swift */; }; - 1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */; }; + 12C867E85E6D12EEDFD0B127 /* CustomStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */; }; 12CCA59536EDD99A3272CF77 /* AppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC3F82523D6F48B926D6AF68 /* AppSettings.swift */; }; 132D241B09F9044711FD70A5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 91DE43B8815918E590912DDA /* InfoPlist.strings */; }; - 1368EBBF25858519477FF8A7 /* ReadMarkerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02351B2D9CD9B2B914352908 /* ReadMarkerRoomTimelineItem.swift */; }; 13853973A5E24374FCEDE8A3 /* RedactedRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8F2A7A4E3F5060F52ACFFB0 /* RedactedRoomTimelineView.swift */; }; 13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D25A35764C7B3DB78954AB5 /* RoomTimelineItemFactoryProtocol.swift */; }; 14132418A748C988B85B025E /* OnboardingPageIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09199C43BAB209C0BD89A836 /* OnboardingPageIndicator.swift */; }; 149D1942DC005D0485FB8D93 /* LoggingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DC1943ADE6A62ED5129D7C8 /* LoggingTests.swift */; }; + 14E99D27628B1A6F0CB46FEA /* SeparatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */; }; 152AE2B8650FB23AFD2E28B9 /* MockAuthenticationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C2B80DD0BF6F10BB5FA922 /* MockAuthenticationServiceProxy.swift */; }; 1555A7643D85187D4851040C /* TemplateScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4549FCB53F43DB0B278374BC /* TemplateScreen.swift */; }; 157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A2932515EA11D3DD8A3506 /* TimelineItemBubbledStylerView.swift */; }; @@ -78,7 +79,6 @@ 214CDBF0C783155242FFE4A0 /* NotificationItemProxy+NSE.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B1FBF8CA40199B8058B1F08 /* NotificationItemProxy+NSE.swift */; }; 2276870A19F34B3FFFDA690F /* SoftLogoutCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AEA20A6B4883E60469ACF8F /* SoftLogoutCoordinator.swift */; }; 2352C541AF857241489756FF /* MockRoomSummaryProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */; }; - 235819701B166DFBA21994F1 /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33AECDFE83A880328CCFD0B1 /* RoomMemberDetailsViewModelTests.swift */; }; 237FC70AA257B935F53316BA /* SessionVerificationControllerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */; }; 23B2CD5A06B16055BDDD0994 /* ApplicationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44D8C8431416EB8DFEC7E235 /* ApplicationTests.swift */; }; 24906A1E82D0046655958536 /* MessageComposer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E18CF12478983A5EB390FB26 /* MessageComposer.swift */; }; @@ -88,11 +88,11 @@ 27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */; }; 282A5F3375DDC774AE09B0C3 /* TracingConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1734A445A58ED855B977A0A8 /* TracingConfigurationTests.swift */; }; 28410F3DE89C2C44E4F75C92 /* MockBugReportService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0E7BF8F7BB1021F889C6483 /* MockBugReportService.swift */; }; - 28934460A497CD002249ED71 /* TimelineStartRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF73D6149F4755E9C530303 /* TimelineStartRoomTimelineItem.swift */; }; 290FDB0FFDC2F1DDF660343E /* TestMeasurementParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */; }; 297CD0A27C87B0C50FF192EE /* RoomTimelineViewFactoryProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */; }; 29EE1791E0AFA1ABB7F23D2F /* SwiftyBeaver in Frameworks */ = {isa = PBXBuildFile; productRef = A981A4CA233FB5C13B9CA690 /* SwiftyBeaver */; }; 2ABF11717C64054CEF2819A3 /* RoomTimelineController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F85164F9475FF2867F71AAA /* RoomTimelineController.swift */; }; + 2AD668FAF5C6BFE252A965F2 /* RoomMemberDetailsMemberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B07B937B036247F1962BBCC7 /* RoomMemberDetailsMemberCell.swift */; }; 2B9AEEC12B1BBE5BD61D0F5E /* UserSessionFlowCoordinatorStateMachine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3429142FE11930422E7CC1A0 /* UserSessionFlowCoordinatorStateMachine.swift */; }; 2BA59D0AEFB4B82A2EC2A326 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 78A5A8DE1E2B09C978C7F3B0 /* KeychainAccess */; }; 2BAA5B222856068158D0B3C6 /* MatrixRustSDK in Frameworks */ = {isa = PBXBuildFile; productRef = B1E8B697DF78FE7F61FC6CA4 /* MatrixRustSDK */; }; @@ -112,18 +112,17 @@ 33D630461FC4562CC767EE9F /* FileCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5B0B1226DA8DB55918B34CD /* FileCache.swift */; }; 340D39DB87F3800D53A6A621 /* EmojiPickerScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00245D40CD90FD71D6A05239 /* EmojiPickerScreen.swift */; }; 34966D4C1C2C6D37FE3F7F50 /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DD2D50A7EAA4FC78417730E /* SettingsCoordinator.swift */; }; + 34C752A73717C691582DC6C7 /* UnsupportedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */; }; 352C439BE0F75E101EF11FB1 /* RoomScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2886615BEBAE33A0AA4D5F8 /* RoomScreenModels.swift */; }; 3588F34D05B4D731A73214C6 /* BugReportScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = DED59F9EFF273BFA2055FFDF /* BugReportScreen.swift */; }; 35E975CFDA60E05362A7CF79 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 1222DB76B917EB8A55365BA5 /* target.yml */; }; 368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5B243E7818E5E9F6A4EDC7A /* NoticeRoomTimelineView.swift */; }; 36AC963F2F04069B7FF1AA0C /* UIConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E6D88E8AFFBF2C1D589C0FA /* UIConstants.swift */; }; - 36C10EDEDC0466E3A9D63132 /* VideoRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4B5B19A10D3F7C2BC5315DF /* VideoRoomTimelineItem.swift */; }; 38546A6010A2CF240EC9AF73 /* BindableState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */; }; 38896D54D6D675534E606195 /* RoomTimelineControllerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6FCC416A3BFE73DF7B3E6BF /* RoomTimelineControllerFactory.swift */; }; 388FD50AC66E9E684DDFA9D8 /* ServerSelectionScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5D2C0950F8196232D88045C /* ServerSelectionScreen.swift */; }; 38C76D586404C1FDED095F3A /* LoginModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B01468022EC826CB2FD2C0 /* LoginModels.swift */; }; 3910D3A2EF98587C0E7B9CCB /* EmojiMartEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11F7F3CF7E70518BD7D25E04 /* EmojiMartEmoji.swift */; }; - 392D0519E5597A538BFB2CAB /* UnsupportedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7EDBCE09CCF06B5BB522502 /* UnsupportedRoomTimelineItem.swift */; }; 39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8872E9C5E91E9F2BFC4EBCCA /* AlignedScrollView.swift */; }; 3A08584ECDD4A4541DBF21F8 /* EmojiLoaderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 201305507D7DFD16E544563A /* EmojiLoaderProtocol.swift */; }; 3A64A93A651A3CB8774ADE8E /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 21C83087604B154AA30E9A8F /* SnapshotTesting */; }; @@ -137,6 +136,7 @@ 407DCE030E0F9B7C9861D38A /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 997C7385E1A07E061D7E2100 /* GZIP */; }; 414F50CFCFEEE2611127DCFB /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; }; 41DFDD212D1BE57CA50D783B /* SwiftyBeaver in Frameworks */ = {isa = PBXBuildFile; productRef = FD43A50D9B75C9D6D30F006B /* SwiftyBeaver */; }; + 4219391CD2351E410554B3E8 /* AggregratedReaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */; }; 438FB9BC535BC95948AA5F34 /* SettingsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B2F9D5C39A4494D19F33E38 /* SettingsViewModelProtocol.swift */; }; 43BD17BC8794BB9B04F2A26B /* MediaSourceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 179423E34EE846E048E49CBF /* MediaSourceProxy.swift */; }; 43FD77998F33C32718C51450 /* TemplateCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */; }; @@ -149,9 +149,9 @@ 49E9B99CB6A275C7744351F0 /* LoginViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F2D58333B377888012740101 /* LoginViewModel.swift */; }; 49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6390A6DC140CA3D6865A66FF /* SeparatorRoomTimelineView.swift */; }; 4A2E0DBB63919AC8309B6D40 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A191D3FDB995309C7E2DE7D /* SettingsViewModel.swift */; }; - 4A67D2EAB564B34EE5C03E11 /* StickerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C84013BB71998CDD90C634C /* StickerRoomTimelineItem.swift */; }; 4BB282209EA82015D0DF8F89 /* NavigationStackCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C698E30698EC59302A8EEBD /* NavigationStackCoordinatorTests.swift */; }; 4C3365818DE1CEAEDF590FD3 /* MediaProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */; }; + 4C5A638DAA8AF64565BA4866 /* EncryptedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */; }; 4E8F17EBA24FBBA6ABB62ECB /* MockBackgroundTaskService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3948D16F021DFDB2CD26EAA8 /* MockBackgroundTaskService.swift */; }; 4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */; }; 4FC1EFE4968A259CBBACFAFB /* RoomProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */; }; @@ -173,6 +173,7 @@ 5B8B51CEC4717AF487794685 /* NotificationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B490675B8E31423AF116BDA /* NotificationServiceProxy.swift */; }; 5C02841B2A86327B2C377682 /* NotificationConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C830A64609CBD152F06E0457 /* NotificationConstants.swift */; }; 5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */; }; + 5D27B6537591471A42C89027 /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 450E04B2A976CC4C8CC1807C /* EmoteRoomTimelineItem.swift */; }; 5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AC06FC11B6638F7BF1670E /* TimelineDeliveryStatusView.swift */; }; 5D430CDE11EAC3E8E6B80A66 /* RoomTimelineViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */; }; 5D70FAE4D2BF4553AFFFFE41 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; }; @@ -183,19 +184,16 @@ 5F06AD3C66884CE793AE6119 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; }; 5F1FDE49DFD0C680386E48F9 /* TemplateViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B80895CE021B49847BD7D74 /* TemplateViewModelProtocol.swift */; }; 5F5488FBC9CFEB6F433D74A4 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; }; - 60E838D870A4969D9BADF1BC /* RoomMemberDetailsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD38C315F6576DB898EA9529 /* RoomMemberDetailsViewModelProtocol.swift */; }; 60ED66E63A169E47489348A8 /* GZIP in Frameworks */ = {isa = PBXBuildFile; productRef = 2B788C81F6369D164ADEB917 /* GZIP */; }; 6126CC51654E159804999E6A /* UNMutableNotificationContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5741CD0691019B32FE74CE9E /* UNMutableNotificationContent.swift */; }; 617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; }; - 626367FC2416CA4E25E15383 /* RoomMemberDetailsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F910035944E5F38F4F801E /* RoomMemberDetailsScreenUITests.swift */; }; 6298AB0906DDD3525CD78C6B /* SwiftState in Frameworks */ = {isa = PBXBuildFile; productRef = 9573B94B1C86C6DF751AF3FD /* SwiftState */; }; - 630E89EBB0F791208EEE6D11 /* FileRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C00A7110B937C6AE2EF5D7D6 /* FileRoomTimelineItem.swift */; }; 63C9AF0FB8278AF1C0388A0C /* TemplateModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAB10E673916D2B8D21FD197 /* TemplateModels.swift */; }; 64F43D7390DA2A0AFD6BA911 /* VideoRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1941C8817E6B6971BA4415F5 /* VideoRoomTimelineView.swift */; }; 64FF5CB4E35971255872E1BB /* AuthenticationServiceProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F0CB536D1C3CC15AA740CC6 /* AuthenticationServiceProxyProtocol.swift */; }; 652ACCF104A8CEF30788963C /* NotificationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1423AB065857FA546444DB15 /* NotificationManager.swift */; }; 663E198678778F7426A9B27D /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A9FAFE1C2149E6AC8156ED2B /* Collection.swift */; }; - 6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */; }; + 67523160A392C40492BB8DC8 /* MessageTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 755DC0F79EF8181CC175A193 /* MessageTimelineItem.swift */; }; 67C05C50AD734283374605E3 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; }; 67D6E0700A9C1E676F6231F8 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 940C605265DD82DA0C655E23 /* Kingfisher */; }; 67E391A2E00709FB41903B36 /* MockMediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6920A4869821BF72FFC58842 /* MockMediaProvider.swift */; }; @@ -206,6 +204,7 @@ 6A0E7551E0D1793245F34CDD /* ClientError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09A267106B9585D3D0CFC0D /* ClientError.swift */; }; 6AC1DC1EAD9F7568360DA1BA /* ServerSelectionModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = A30A1758E2B73EF38E7C42F8 /* ServerSelectionModels.swift */; }; 6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C88046D6A070D9827181C4D /* OnboardingUITests.swift */; }; + 6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */; }; 6C67774E8387D44426718BD9 /* FilePreviewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADB3A7BCE745626EC61EF3C3 /* FilePreviewCoordinator.swift */; }; 6C9F6C7F2B35288C4230EF3F /* FilePreviewModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55EA4B03F92F31EAA83B3F7B /* FilePreviewModels.swift */; }; 6CA81428F0970785CDCC5E86 /* UserNotificationToastView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F31A4E5941ACBA4BB9FEF94C /* UserNotificationToastView.swift */; }; @@ -219,15 +218,16 @@ 70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = E96ED747FF90332EA1333C22 /* RoomTimelineItemFixtures.swift */; }; 706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7F0192CE2F891141A25B49F /* UITestsSignalling.swift */; }; 706F79A39BDB32F592B8C2C7 /* UIKitBackgroundTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */; }; - 7096FA3AC218D914E88BFB70 /* AggregratedReaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = F15BE37BE2FB86E00C8D150A /* AggregratedReaction.swift */; }; 719E7AAD1F8E68F68F30FECD /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = A40C19719687984FD9478FBE /* Task.swift */; }; 71C1347F23868324A4F43940 /* NavigationModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A22A05E472533ED3C5A31B3 /* NavigationModule.swift */; }; 7354D094A4C59B555F407FA1 /* RustTracing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 542D4F49FABA056DEEEB3400 /* RustTracing.swift */; }; 7361B011A79BF723D8C9782B /* EmojiCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C1A3D524D63815B28FA4D62 /* EmojiCategory.swift */; }; 7405B4824D45BA7C3D943E76 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D0CBC76C80E04345E11F2DB /* Application.swift */; }; + 743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */; }; 744C029EB6C43429926A0499 /* AnalyticsPromptViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C9A86C95340248A8B7BA9A43 /* AnalyticsPromptViewModelProtocol.swift */; }; 74604ACFDBE7F54260E7B617 /* ApplicationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8903A9F615BBD0E6D7CD133 /* ApplicationProtocol.swift */; }; 748F482FEF4E04D61C39AAD7 /* EmojiPickerScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */; }; + 7501442D52A65F73DF79FFD4 /* PaginationIndicatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */; }; 755727E0B756430DFFEC4732 /* SessionVerificationViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */; }; 758BF44CA565AB0AB84F2185 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 7109E709A7738E6BCC4553E6 /* Localizable.strings */; }; 75EA4ABBFAA810AFF289D6F4 /* TemplateViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */; }; @@ -238,11 +238,11 @@ 77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 095AED4CF56DFF3EB7BB84C8 /* RoomTimelineProviderProtocol.swift */; }; 77FACC29F98FE2E65BBB6A5F /* ServerSelectionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */; }; 78BF60C696FFED63AAF58D10 /* SoftLogoutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22D46DB0CC6C55EBA7AE67A3 /* SoftLogoutViewModel.swift */; }; - 7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */; }; 7A71AEF419904209BB8C2833 /* UserAgentBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F2529D434C750ED78ADF1ED /* UserAgentBuilder.swift */; }; 7AE1FFB132F2B84EB8A2AEBC /* TemplateViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3340ABAE3A4647E80163AE18 /* TemplateViewModelTests.swift */; }; 7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; }; 7C1A7B594B2F8143F0DD0005 /* ElementXAttributeScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */; }; + 7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */; }; 7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0950733DD4BA83EEE752E259 /* PlaceholderAvatarImage.swift */; }; 7E3B1F8D72573ED2FCB2D94B /* NotificationServiceProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCD5FEE195446A9E458DDDAF /* NotificationServiceProxyProtocol.swift */; }; 7E3C34BC10936AD4F77975F4 /* EmojiMartJSONLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39001365B76B89983FDB7AD8 /* EmojiMartJSONLoader.swift */; }; @@ -254,6 +254,7 @@ 7F64FA937B95924B3A44EC12 /* OnboardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */; }; 7FED310F6AB7A70CBFB7C8A3 /* SettingsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = C483956FA3D665E3842E319A /* SettingsScreen.swift */; }; 8024BE37156FF0A95A7A3465 /* AnalyticsPromptUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */; }; + 806241864ED47055DC76CB60 /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = AB5F75EDB6A9D0779AD01902 /* RoomMemberDetailsScreen.swift */; }; 80D00A7C62AAB44F54725C43 /* PermalinkBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */; }; 8196A2E71ACC902DD69F24EE /* UserNotificationControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DE6C5C756E1393202BA95CD /* UserNotificationControllerTests.swift */; }; 81A7C020CB5F6232242A8414 /* UserSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F36C0A6D59717193F49EA986 /* UserSessionTests.swift */; }; @@ -267,12 +268,12 @@ 872A6457DF573AF8CEAE927A /* LoginHomeserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9349F590E35CE514A71E6764 /* LoginHomeserver.swift */; }; 87315D70BABB38CFBC8CFF61 /* test_image.png in Resources */ = {isa = PBXBuildFile; fileRef = 7EF42E492B7599EBCB4A4174 /* test_image.png */; }; 87756CA950ED55870A1AAE8F /* ServerSelectionCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D7D706FFF438CAF16F44D8C /* ServerSelectionCoordinator.swift */; }; + 878070573C7BF19E735707B4 /* RoomTimelineItemProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DE8D25D6A91030175D52A20 /* RoomTimelineItemProperties.swift */; }; 87BD4F95F9D603C309837378 /* UserNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6B262D7584C65BC5B79A0E /* UserNotification.swift */; }; 8810A2A30A68252EBB54EE05 /* HomeScreenModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71BC7CA1BC1041E93077BBA1 /* HomeScreenModels.swift */; }; 890F0D453FE388756479AC97 /* AnalyticsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C687844F60BFF532D49A994C /* AnalyticsTests.swift */; }; 8AB8ED1051216546CB35FA0E /* UserSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */; }; 8B807DC963D1D4155A241BCC /* UserSessionFlowCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3F9E67AAB66638C69626866C /* UserSessionFlowCoordinator.swift */; }; - 8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F49CDE349C490D617332770 /* NoticeRoomTimelineItem.swift */; }; 8C454500B8073E1201F801A9 /* MXLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = A34A814CBD56230BC74FFCF4 /* MXLogger.swift */; }; 8CC12086CBF91A7E10CDC205 /* HomeScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D653265D006E708E4E51AD64 /* HomeScreenCoordinator.swift */; }; 8D3E1FADD78E72504DE0E402 /* UserAgentBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */; }; @@ -293,6 +294,7 @@ 94D0F36A87E596A93C0C178A /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; }; 964B9D2EC38C488C360CE0C9 /* HomeScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = B902EA6CD3296B0E10EE432B /* HomeScreen.swift */; }; 968A5B890004526AB58A217C /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; }; + 96FE26ABD4E5B8B6EF0EF596 /* RoomMemberDetailsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1CEFB5144EF8F50C77CF6E14 /* RoomMemberDetailsCoordinator.swift */; }; 97189E495F0E47805D1868DB /* DTCoreText in Frameworks */ = {isa = PBXBuildFile; productRef = 527578916BD388A09F5A8036 /* DTCoreText */; }; 978BB24F2A5D31EE59EEC249 /* UserSessionProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */; }; 981853650217B6C8ECDD998C /* NavigationRootCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */; }; @@ -321,19 +323,17 @@ A33784831AD880A670CAA9F9 /* FileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04DF593C3F7AF4B2FBAEB05D /* FileManager.swift */; }; A371629728E597C5FCA3C2B2 /* Analytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73FC861755C6388F62B9280A /* Analytics.swift */; }; A37EED79941AD3B7140B3822 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287FC98AF2664EAD79C0D902 /* UIDevice.swift */; }; - A382B0EA99888F74B6952019 /* RoomMemberDetailsMemberCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22FECA5919BE59C4BB5AEB22 /* RoomMemberDetailsMemberCell.swift */; }; - A3CE203A923A4DD0E9371FB9 /* RoomMemberDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = E254EA67FB16AB33F9F9B18D /* RoomMemberDetailsScreen.swift */; }; A440D4BC02088482EC633A88 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; }; A494741843F087881299ACF0 /* RestorationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3558A15CFB934F9229301527 /* RestorationToken.swift */; }; A4E885358D7DD5A072A06824 /* PostHog in Frameworks */ = {isa = PBXBuildFile; productRef = CCE5BF78B125320CBF3BB834 /* PostHog */; }; A50849766F056FD1DB942DEA /* AlertInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EEB64CC6F3DF5B68736A6B4 /* AlertInfo.swift */; }; - A57A62859AE46AE07281B4AE /* RoomMemberDetailsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F5734DF8967F3595F8C784D /* RoomMemberDetailsModels.swift */; }; A663FE6704CB500EBE782AE1 /* AnalyticsPromptCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DE1CF8F5EFD353B1A5E36F /* AnalyticsPromptCoordinator.swift */; }; A69A54FF11A3F9EA0660E6BF /* NSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0D8F620C8B314840D8602E3F /* NSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; A6DEC1ADEC8FEEC206A0FA37 /* AttributedStringBuilderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */; }; A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; A7FD7B992E6EE6E5A8429197 /* RoomSummaryDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = 142808B69851451AC32A2CEA /* RoomSummaryDetails.swift */; }; A851635B3255C6DC07034A12 /* RoomScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */; }; + A8771F5975A82759FA5138AE /* RoomMemberDetailsScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */; }; A8EC7C9D886244DAE9433E37 /* SessionVerificationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4C18FAAD59AE7F1462D817E /* SessionVerificationViewModel.swift */; }; A9D23B78F42BCDD896531436 /* UserNotificationPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 649759084B0C9FE1F8DF8D17 /* UserNotificationPresenter.swift */; }; AA050DF4AEE54A641BA7CA22 /* RoomSummaryProviderProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10CC626F97AD70FF0420C115 /* RoomSummaryProviderProtocol.swift */; }; @@ -345,6 +345,8 @@ ACF094CF3BF02DBFA6DFDE60 /* AuthenticationCoordinatorUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D2D0A6F1ABC99D29462FB84 /* AuthenticationCoordinatorUITests.swift */; }; AD2A81B65A9F6163012086F1 /* MXLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 111B698739E3410E2CDB7144 /* MXLog.swift */; }; AEE3981A0F090208E4445808 /* MockNotificationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2B37DCC9025452F46F91340E /* MockNotificationServiceProxy.swift */; }; + AF19D65A9C60C6B2646F3210 /* RedactedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */; }; + AF2095134EED8FD8FC4C3091 /* RoomMemberDetailsModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA78F8D91974DFFEDC05485A /* RoomMemberDetailsModels.swift */; }; AF33B9044498211C3D82F1E1 /* UNTextInputNotificationResponse+Creator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 130ED565A078F7E0B59D9D25 /* UNTextInputNotificationResponse+Creator.swift */; }; B037C365CF8A58A0D149A2DB /* AuthenticationIconImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */; }; B064D42BA087649ACAE462E8 /* SoftLogoutUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55F30E764BED111C81739844 /* SoftLogoutUITests.swift */; }; @@ -370,34 +372,33 @@ BA31448FBD9697F8CB9A83CD /* ImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E2245243369B99216C7D84E /* ImageCache.swift */; }; BB01CC19C3D3322308D1B2CF /* ServerSelectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167521635A1CC27624FCEB7F /* ServerSelectionViewModel.swift */; }; BB6B0B91CE11E06330017000 /* SessionVerificationScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AC1A01C3A745BDF1D3697D3 /* SessionVerificationScreen.swift */; }; + BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */; }; BCEC41FB1F2BB663183863E4 /* LoginServerInfoSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D379E13DD9D987470A3C70C /* LoginServerInfoSection.swift */; }; BD782053BE4C3D2F0BDE5699 /* ServiceLocator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */; }; BEEEB659A0BA510D7BE6345C /* RoomMemberProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D1790942BE4FE0D8273191B /* RoomMemberProxy.swift */; }; BFB534E338A3D949944FB2F5 /* NotificationServiceProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B490675B8E31423AF116BDA /* NotificationServiceProxy.swift */; }; C1910A16BDF131FECA77BE22 /* EmojiPickerScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */; }; C3522917C0C367C403429EEC /* CoordinatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */; }; - C35CF4DAB1467FE1BBDC204B /* MessageTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAF1C75771D9DC75877F4B4 /* MessageTimelineItem.swift */; }; C4180F418235DAD9DD173951 /* TemplateScreenUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9873076F224E4CE09D8BD47D /* TemplateScreenUITests.swift */; }; C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E508AB0EDEE017FF4F6F8D1 /* DTHTMLElement+AttributedStringBuilder.swift */; }; C4F784AABFF44E4716E7A8BC /* RoomDetailsViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 87B3A76EA6AB67910C11330F /* RoomDetailsViewModelProtocol.swift */; }; + C4FE0E11A907C8999F92D5A8 /* TimelineStartRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8F5F9E02B1AB5350B1815E7 /* TimelineStartRoomTimelineItem.swift */; }; C55A44C99F64A479ABA85B46 /* RoomScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */; }; + C58E305C380D3ADDF7912180 /* StickerRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 818695BED971753243FEF897 /* StickerRoomTimelineItem.swift */; }; C6136E848E55D2C86BF760F5 /* NetworkMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C789E7BFC066CF39B8AE0974 /* NetworkMonitor.swift */; }; C74EE50257ED925C2B8EFCE6 /* MockSoftLogoutScreenState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B869438A1B52836F912A702 /* MockSoftLogoutScreenState.swift */; }; C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 398817652FA8ABAE0A31AC6D /* ReadableFrameModifier.swift */; }; C7B251DC896C0867C51B616D /* AnalyticsPrompt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 541542F5AC323709D8563458 /* AnalyticsPrompt.swift */; }; C7CFDB4929DDD9A3B5BA085D /* BugReportViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB7ED3A898B07976F3AA90F /* BugReportViewModelTests.swift */; }; - C8E82786DE1B6A400DA9BA25 /* RoomTimelineItemProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 289FA233E896FBC5956C67E0 /* RoomTimelineItemProperties.swift */; }; CA45758F08DF42D41D8A4B29 /* FilePreviewViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF38B69D2C331A499276F400 /* FilePreviewViewModelTests.swift */; }; CB137BFB3E083C33E398A6CB /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = 0DD568A494247444A4B56031 /* Kingfisher */; }; CB498F4E27AA0545DCEF0F6F /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4003BC24B24C9E63D3304177 /* DeviceKit */; }; CB99B0FA38A4AC596F38CC13 /* KeychainControllerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */; }; - CC2A6B71E12DDF1EE6ECD299 /* RoomMemberDetailsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = F118CF7C5548099AACF7E90C /* RoomMemberDetailsCoordinator.swift */; }; CC736DA1AA8F8B9FD8785009 /* ScreenshotDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5C4AF6E3885730CD560311C /* ScreenshotDetector.swift */; }; CCAA0671B46EAFD0BB528E2C /* apple_emojis_data.json in Resources */ = {isa = PBXBuildFile; fileRef = 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */; }; CD6A72B65D3B6076F4045C30 /* PHGPostHogConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6B891A6DA826E2461DBB40F /* PHGPostHogConfiguration.swift */; }; CE1694C7BB93C3311524EF28 /* Untranslated.strings in Resources */ = {isa = PBXBuildFile; fileRef = D2F7194F440375338F8E2487 /* Untranslated.strings */; }; CE7148E80F09B7305E026AC6 /* OnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1198B925F4A88DA74083662 /* OnboardingViewModel.swift */; }; - CE79753EA0C433641F0449C0 /* PaginationIndicatorRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756288D339AFC15D2C3F4A0D /* PaginationIndicatorRoomTimelineItem.swift */; }; CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25F7FE40EF7490A7E09D7BE6 /* NotificationItemProxy.swift */; }; CEB8FB1269DE20536608B957 /* LoginMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41FABA2B0AEF4389986495 /* LoginMode.swift */; }; CF6319CC05F964B4D05BF614 /* MockFileCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEC96B3DC55090BBF8876CC2 /* MockFileCache.swift */; }; @@ -406,6 +407,7 @@ D05A193AE63030F2CFCE2E9C /* UITestScreenIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC6FE34A0A47D010BBB4D4D4 /* UITestScreenIdentifier.swift */; }; D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607974D08BD2AF83725D817A /* RoomMessageProtocol.swift */; }; D2D70B5DB1A5E4AF0CD88330 /* target.yml in Resources */ = {isa = PBXBuildFile; fileRef = 033DB41C51865A2E83174E87 /* target.yml */; }; + D33AC79A50DFC26D2498DD28 /* FileRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */; }; D59F046B15AA8E971053C1A6 /* RoomDetailsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 813B198AE8833FD12E5A9C78 /* RoomDetailsCoordinator.swift */; }; D5C805F49B2C75DC3793E780 /* EmojiItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A243E04B58DC6E41FDCD82 /* EmojiItem.swift */; }; D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */; }; @@ -415,11 +417,10 @@ D85D4FA590305180B4A41795 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3073CCD77D906B330BC1D6 /* Tests.swift */; }; D876EC0FED3B6D46C806912A /* AvatarSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */; }; D8CFF02C2730EE5BC4F17ABF /* ElementToggleStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0960A7F5C1B0B6679BDF26F9 /* ElementToggleStyle.swift */; }; - DC2D20609B9B612F6946C3F6 /* RoomMemberDetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4CF2FC815D26B337E78DA45 /* RoomMemberDetailsViewModel.swift */; }; DC68E866D6E664B0D2B06E74 /* MockImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */; }; DD9B70DE54B24E0694A35D8A /* Strings+Untranslated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */; }; - DDB80FD2753FEAAE43CC2AAE /* ImageRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */; }; DE4F8C4E0F1DB4832F09DE97 /* HomeScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */; }; + DEC6778FB8CFB829D3E012AC /* RoomMemberDetailsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57CF0E6DD78FB3F6CBF5AC38 /* RoomMemberDetailsViewModel.swift */; }; DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 854BCEAF2A832176FAACD2CB /* SplashScreenCoordinator.swift */; }; DF504B10A4918F971A57BEF2 /* PostHogAnalyticsClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1715E3D7F53C0748AA50C91C /* PostHogAnalyticsClient.swift */; }; DFCA89C4EC2A5332ED6B441F /* DataProtectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4959CECEC984B3995616F427 /* DataProtectionManager.swift */; }; @@ -453,6 +454,7 @@ EF7924005216B8189898F370 /* BackgroundTaskProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CA028DCD4157F9A1F999827 /* BackgroundTaskProtocol.swift */; }; F040ABFEB0A2B142D948BA12 /* Untranslated.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = F75DF9500D69A3AAF8339E69 /* Untranslated.stringsdict */; }; F06CE9132855E81EBB6DDC32 /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = 800631D7250B7F93195035F1 /* KeychainAccess */; }; + F07D88421A9BC4D03D4A5055 /* VideoRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */; }; F0F82C3C848C865C3098AA52 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 67E7A6F388D3BF85767609D9 /* Sentry */; }; F257F964493A9CD02A6F720C /* OnboardingPageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DF2717AB91060260E5F4781 /* OnboardingPageView.swift */; }; F32B271F60531BE92C6E62A1 /* StickerRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612EF972F2A1800682D32C5E /* StickerRoomTimelineView.swift */; }; @@ -460,7 +462,6 @@ F508683B76EF7B23BB2CBD6D /* TimelineItemPlainStylerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94BCC8A9C73C1F838122C645 /* TimelineItemPlainStylerView.swift */; }; F61AFA8BF2E739FBC30472F5 /* NotificationServiceProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCD5FEE195446A9E458DDDAF /* NotificationServiceProxyProtocol.swift */; }; F656F92A63D3DC1978D79427 /* AnalyticsEvents in Frameworks */ = {isa = PBXBuildFile; productRef = 2A3F7BCCB18C15B30CCA39A9 /* AnalyticsEvents */; }; - F6E860FF7B18B81DF43B30B8 /* EncryptedRoomTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3FA7C8D4EF2B1873C180ED7 /* EncryptedRoomTimelineItem.swift */; }; F6F49E37272AD7397CD29A01 /* HomeScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */; }; F7567DD6635434E8C563BF85 /* AnalyticsClientProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3B97591B2D3D4D67553506D /* AnalyticsClientProtocol.swift */; }; F9981191DC408AED537C1749 /* MediaProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = E12C9E0B61A77C7F0EE7918C /* MediaProxy.swift */; }; @@ -526,7 +527,6 @@ 00245D40CD90FD71D6A05239 /* EmojiPickerScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreen.swift; sourceTree = ""; }; 00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModelTests.swift; sourceTree = ""; }; 01C4C7DB37597D7D8379511A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 02351B2D9CD9B2B914352908 /* ReadMarkerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineItem.swift; sourceTree = ""; }; 02A07FF019724B6ACEA73076 /* szl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = szl; path = szl.lproj/Localizable.strings; sourceTree = ""; }; 033DB41C51865A2E83174E87 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = ""; }; 0376C429FAB1687C3D905F3E /* MockCoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCoder.swift; sourceTree = ""; }; @@ -546,6 +546,7 @@ 0AB7A0C06CB527A1095DEB33 /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = da; path = da.lproj/Localizable.stringsdict; sourceTree = ""; }; 0B490675B8E31423AF116BDA /* NotificationServiceProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceProxy.swift; sourceTree = ""; }; 0B869438A1B52836F912A702 /* MockSoftLogoutScreenState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSoftLogoutScreenState.swift; sourceTree = ""; }; + 0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineItem.swift; sourceTree = ""; }; 0BC588051E6572A1AF51D738 /* TimelineSenderAvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineSenderAvatarView.swift; sourceTree = ""; }; 0C13A92C1E9C79F055B8133D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ar; path = ar.lproj/Localizable.stringsdict; sourceTree = ""; }; 0C88046D6A070D9827181C4D /* OnboardingUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingUITests.swift; sourceTree = ""; }; @@ -556,6 +557,7 @@ 0E7062F88E9D5F79C8A80524 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = th; path = th.lproj/Localizable.stringsdict; sourceTree = ""; }; 0E8BDC092D817B68CD9040C5 /* UserSessionStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStore.swift; sourceTree = ""; }; 0EE9EAF0309A2A1D67D8FAF5 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Localizable.stringsdict; sourceTree = ""; }; + 0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenUITests.swift; sourceTree = ""; }; 0F52BF30D12BA3BD3D3DBB8F /* ServerSelectionViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelProtocol.swift; sourceTree = ""; }; 1059E2AE7878CF7820592637 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 105B2A8426404EF66F00CFDB /* RoomTimelineItemFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemFactory.swift; sourceTree = ""; }; @@ -583,9 +585,9 @@ 18FE0CDF1FFA92EA7EE17B0B /* RoomTimelineControllerFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerFactoryProtocol.swift; sourceTree = ""; }; 1941C8817E6B6971BA4415F5 /* VideoRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineView.swift; sourceTree = ""; }; 1A18F6CE4D694D21E4EA9B25 /* Strings+Untranslated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Strings+Untranslated.swift"; sourceTree = ""; }; - 1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = ""; }; 1BC4437C107D52ED19357DFC /* OnboardingViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewModelProtocol.swift; sourceTree = ""; }; 1C429043E986008B97736636 /* ab */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ab; path = ab.lproj/Localizable.strings; sourceTree = ""; }; + 1CEFB5144EF8F50C77CF6E14 /* RoomMemberDetailsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsCoordinator.swift; sourceTree = ""; }; 1D56469A9EE0CFA2B7BA9760 /* SessionVerificationControllerProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxyProtocol.swift; sourceTree = ""; }; 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenUITests.swift; sourceTree = ""; }; 1DF2717AB91060260E5F4781 /* OnboardingPageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPageView.swift; sourceTree = ""; }; @@ -601,7 +603,6 @@ 227AC5D71A4CE43512062243 /* URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URL.swift; sourceTree = ""; }; 22B384D54464FA39C6C7F6E7 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ca; path = ca.lproj/Localizable.stringsdict; sourceTree = ""; }; 22D46DB0CC6C55EBA7AE67A3 /* SoftLogoutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutViewModel.swift; sourceTree = ""; }; - 22FECA5919BE59C4BB5AEB22 /* RoomMemberDetailsMemberCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsMemberCell.swift; sourceTree = ""; }; 233D5F7E5E9F49ABF3413291 /* hr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hr; path = hr.lproj/Localizable.stringsdict; sourceTree = ""; }; 24F5530B2212862FA4BEFF2D /* HomeScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelProtocol.swift; sourceTree = ""; }; 2583416C8974272ADBADDBE1 /* zh-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-TW"; path = "zh-TW.lproj/Localizable.stringsdict"; sourceTree = ""; }; @@ -610,7 +611,6 @@ 27A1AD6389A4659AF0CEAE62 /* NotificationServiceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtension.swift; sourceTree = ""; }; 287FC98AF2664EAD79C0D902 /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = ""; }; 28959C7DB36C7688A01D4045 /* BugReportViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportViewModelProtocol.swift; sourceTree = ""; }; - 289FA233E896FBC5956C67E0 /* RoomTimelineItemProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProperties.swift; sourceTree = ""; }; 28EA8BE9EEDBD17555141C7E /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = el; path = el.lproj/Localizable.stringsdict; sourceTree = ""; }; 2A5C6FBF97B6EED3D4FA5EFF /* AttributedStringBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilder.swift; sourceTree = ""; }; 2AE83A3DD63BCFBB956FE5CB /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nl; path = nl.lproj/Localizable.stringsdict; sourceTree = ""; }; @@ -634,7 +634,6 @@ 31D6764D6976D235926FE5FC /* HomeScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModel.swift; sourceTree = ""; }; 32C5DAA1773F57653BF1C4F9 /* SoftLogoutViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoftLogoutViewModelTests.swift; sourceTree = ""; }; 3340ABAE3A4647E80163AE18 /* TemplateViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModelTests.swift; sourceTree = ""; }; - 33AECDFE83A880328CCFD0B1 /* RoomMemberDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelTests.swift; sourceTree = ""; }; 33E49C5C6F802B4D94CA78D1 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Localizable.strings; sourceTree = ""; }; 3429142FE11930422E7CC1A0 /* UserSessionFlowCoordinatorStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionFlowCoordinatorStateMachine.swift; sourceTree = ""; }; 351E89CE2ED9B73C5CC47955 /* TimelineReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineReactionsView.swift; sourceTree = ""; }; @@ -660,17 +659,20 @@ 3DD2D50A7EAA4FC78417730E /* SettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = ""; }; 3DD6E7C1D8B53F47789778CD /* fr-CA */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "fr-CA"; path = "fr-CA.lproj/Localizable.strings"; sourceTree = ""; }; 3DF1FFC3336EB23374BBBFCC /* UIKitBackgroundTaskService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTaskService.swift; sourceTree = ""; }; + 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineItem.swift; sourceTree = ""; }; 3F40F48279322E504153AB0D /* MockClientProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockClientProxy.swift; sourceTree = ""; }; 3F9E67AAB66638C69626866C /* UserSessionFlowCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionFlowCoordinator.swift; sourceTree = ""; }; 3FEE631F3A4AFDC6652DD9DA /* RoomTimelineViewFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactory.swift; sourceTree = ""; }; 40B21E611DADDEF00307E7AC /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = ""; }; 41F3B445BD6EF1C751806B22 /* SlidingSyncViewProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SlidingSyncViewProxy.swift; sourceTree = ""; }; + 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItem.swift; sourceTree = ""; }; 422724361B6555364C43281E /* RoomHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomHeaderView.swift; sourceTree = ""; }; 42EEA67A6796BDC2761619C5 /* PaginationIndicatorRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineView.swift; sourceTree = ""; }; 434522ED2BDED08759048077 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Localizable.strings; sourceTree = ""; }; 4488F5F92A64A137665C96CD /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = pa.lproj/Localizable.strings; sourceTree = ""; }; 44AEEE13AC1BF303AE48CBF8 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Localizable.strings; sourceTree = ""; }; 44D8C8431416EB8DFEC7E235 /* ApplicationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationTests.swift; sourceTree = ""; }; + 450E04B2A976CC4C8CC1807C /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = ""; }; 453E722A43D092C06FB8E3FA /* tzm */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tzm; path = tzm.lproj/Localizable.strings; sourceTree = ""; }; 4549FCB53F43DB0B278374BC /* TemplateScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateScreen.swift; sourceTree = ""; }; 45D8149FDDA0315CDC553B4B /* UserNotificationCenterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationCenterProtocol.swift; sourceTree = ""; }; @@ -690,29 +692,28 @@ 4B362E695A7103C11F64B185 /* AnalyticsSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsSettings.swift; sourceTree = ""; }; 4B40B7F6FCCE2D8C242492D9 /* ga */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ga; path = ga.lproj/Localizable.strings; sourceTree = ""; }; 4B41FABA2B0AEF4389986495 /* LoginMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginMode.swift; sourceTree = ""; }; - 4C84013BB71998CDD90C634C /* StickerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineItem.swift; sourceTree = ""; }; 4C8D988E82A8DFA13BE46F7C /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pl; path = pl.lproj/Localizable.stringsdict; sourceTree = ""; }; 4CD6AC7546E8D7E5C73CEA48 /* ElementX.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = ElementX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 4CDDDDD9FE1A699D23A5E096 /* LoginScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreen.swift; sourceTree = ""; }; 4D6E4C37E9F0E53D3DF951AC /* HomeScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenUITests.swift; sourceTree = ""; }; 4DF56C3239EA3C16951E1E66 /* is */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = is; path = is.lproj/Localizable.strings; sourceTree = ""; }; - 4DF73D6149F4755E9C530303 /* TimelineStartRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStartRoomTimelineItem.swift; sourceTree = ""; }; 4E2245243369B99216C7D84E /* ImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCache.swift; sourceTree = ""; }; 4F0CB536D1C3CC15AA740CC6 /* AuthenticationServiceProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationServiceProxyProtocol.swift; sourceTree = ""; }; - 4F49CDE349C490D617332770 /* NoticeRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoticeRoomTimelineItem.swift; sourceTree = ""; }; 4F5F0662483ED69791D63B16 /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = et; path = et.lproj/Localizable.stringsdict; sourceTree = ""; }; 505208F28007C0FEC14E1FF0 /* HomeScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenViewModelTests.swift; sourceTree = ""; }; + 5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItem.swift; sourceTree = ""; }; 51DF91C374901E94D93276F1 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-MX"; path = "es-MX.lproj/Localizable.stringsdict"; sourceTree = ""; }; 5221DFDF809142A2D6AC82B9 /* RoomScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreen.swift; sourceTree = ""; }; 529513218340CC8419273165 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Localizable.strings; sourceTree = ""; }; 52D7074991B3267B26D89B22 /* MockRoomTimelineController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineController.swift; sourceTree = ""; }; 53482ECA4B6633961EC224F5 /* ScrollViewAdapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewAdapter.swift; sourceTree = ""; }; 534A5C8FCDE2CBC50266B9F2 /* gl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gl; path = gl.lproj/Localizable.stringsdict; sourceTree = ""; }; + 5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineItem.swift; sourceTree = ""; }; 536E72DCBEEC4A1FE66CFDCE /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = ""; }; + 53C4265ED404027938012B35 /* RoomMemberDetailsViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelProtocol.swift; sourceTree = ""; }; 541542F5AC323709D8563458 /* AnalyticsPrompt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPrompt.swift; sourceTree = ""; }; 542D4F49FABA056DEEEB3400 /* RustTracing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RustTracing.swift; sourceTree = ""; }; 5445FCE0CE15E634FDC1A2E2 /* AnalyticsService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsService.swift; sourceTree = ""; }; - 551DAED7F623AA5366E79927 /* repository */ = {isa = PBXFileReference; lastKnownFileType = folder; name = repository; path = .; sourceTree = SOURCE_ROOT; }; 55BC11560C8A2598964FFA4C /* bs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bs; path = bs.lproj/Localizable.strings; sourceTree = ""; }; 55D7187F6B0C0A651AC3DFFA /* in */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = in; path = in.lproj/Localizable.strings; sourceTree = ""; }; 55EA4B03F92F31EAA83B3F7B /* FilePreviewModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewModels.swift; sourceTree = ""; }; @@ -720,10 +721,12 @@ 56C1BCB9E83B09A45387FCA2 /* EncryptedRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineView.swift; sourceTree = ""; }; 5741CD0691019B32FE74CE9E /* UNMutableNotificationContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UNMutableNotificationContent.swift; sourceTree = ""; }; 5773C86AF04AEF26515AD00C /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = sl.lproj/Localizable.strings; sourceTree = ""; }; + 57CF0E6DD78FB3F6CBF5AC38 /* RoomMemberDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModel.swift; sourceTree = ""; }; 57F95CADD0A5DBD76B990FCB /* ServiceLocator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceLocator.swift; sourceTree = ""; }; 5B2F9D5C39A4494D19F33E38 /* SettingsViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewModelProtocol.swift; sourceTree = ""; }; 5D26A086A8278D39B5756D6F /* project.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = project.yml; sourceTree = ""; }; 5D2D0A6F1ABC99D29462FB84 /* AuthenticationCoordinatorUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationCoordinatorUITests.swift; sourceTree = ""; }; + 5DE8D25D6A91030175D52A20 /* RoomTimelineItemProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProperties.swift; sourceTree = ""; }; 5F12E996BFBEB43815189ABF /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = uk; path = uk.lproj/Localizable.stringsdict; sourceTree = ""; }; 5F4134FEFE4EB55759017408 /* UserSessionProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionProtocol.swift; sourceTree = ""; }; 5FF214969B25BFCBF87B908B /* bn-BD */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-BD"; path = "bn-BD.lproj/Localizable.stringsdict"; sourceTree = ""; }; @@ -755,7 +758,6 @@ 6E5E9C044BEB7C70B1378E91 /* UserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSession.swift; sourceTree = ""; }; 6EA1D2CBAEA5D0BD00B90D1B /* BindableState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BindableState.swift; sourceTree = ""; }; 6F3DFE5B444F131648066F05 /* StateStoreViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateStoreViewModel.swift; sourceTree = ""; }; - 6F5734DF8967F3595F8C784D /* RoomMemberDetailsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsModels.swift; sourceTree = ""; }; 6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermalinkBuilderTests.swift; sourceTree = ""; }; 6FC5015B9634698BDB8701AF /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = it; path = it.lproj/Localizable.stringsdict; sourceTree = ""; }; 71556206CD5E8B1F53F07178 /* MockRoomTimelineControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineControllerFactory.swift; sourceTree = ""; }; @@ -763,10 +765,9 @@ 71D52BAA5BADB06E5E8C295D /* Assets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assets.swift; sourceTree = ""; }; 72D03D36422177EF01905D20 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = ca.lproj/Localizable.strings; sourceTree = ""; }; 72F37B5DA798C9AE436F2C2C /* AttributedStringBuilderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderProtocol.swift; sourceTree = ""; }; - 72F910035944E5F38F4F801E /* RoomMemberDetailsScreenUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreenUITests.swift; sourceTree = ""; }; 73FC861755C6388F62B9280A /* Analytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Analytics.swift; sourceTree = ""; }; 748AE77AC3B0A01223033B87 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - 756288D339AFC15D2C3F4A0D /* PaginationIndicatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaginationIndicatorRoomTimelineItem.swift; sourceTree = ""; }; + 755DC0F79EF8181CC175A193 /* MessageTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageTimelineItem.swift; sourceTree = ""; }; 78913D6E120D46138E97C107 /* NavigationSplitCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationSplitCoordinatorTests.swift; sourceTree = ""; }; 799A3A11C434296ED28F87C8 /* iw */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = iw; path = iw.lproj/Localizable.strings; sourceTree = ""; }; 7AB7ED3A898B07976F3AA90F /* BugReportViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportViewModelTests.swift; sourceTree = ""; }; @@ -784,6 +785,7 @@ 813B198AE8833FD12E5A9C78 /* RoomDetailsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsCoordinator.swift; sourceTree = ""; }; 8140010A796DB2C7977B6643 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; 8166F121C79C7B62BF01D508 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = pt; path = pt.lproj/Localizable.stringsdict; sourceTree = ""; }; + 818695BED971753243FEF897 /* StickerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerRoomTimelineItem.swift; sourceTree = ""; }; 81B17DB1BC3B0C62AF84D230 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedCornerShape.swift; sourceTree = ""; }; 84E92FF38EBC12EC2452C79C /* zh-TW */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-TW"; path = "zh-TW.lproj/Localizable.strings"; sourceTree = ""; }; @@ -804,13 +806,14 @@ 8D6094DEAAEB388E1AE118C6 /* MockRoomTimelineProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomTimelineProvider.swift; sourceTree = ""; }; 8D8169443E5AC5FF71BFB3DB /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = ""; }; 8DC2C9E0E15C79BBDA80F0A2 /* TimelineStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStyle.swift; sourceTree = ""; }; - 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = UITests.xctestplan; sourceTree = ""; }; + 8E088F2A1B9EC529D3221931 /* UITests.xctestplan */ = {isa = PBXFileReference; path = UITests.xctestplan; sourceTree = ""; }; 8ED2D2F6A137A95EA50413BE /* UserNotificationControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationControllerProtocol.swift; sourceTree = ""; }; 8F7D42E66E939B709C1EC390 /* MockRoomSummaryProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockRoomSummaryProvider.swift; sourceTree = ""; }; 8FC26871038FB0E4AAE22605 /* apple_emojis_data.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = apple_emojis_data.json; sourceTree = ""; }; 8FC803282F9268D49F4ABF14 /* AppCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinator.swift; sourceTree = ""; }; 9010EE0CC913D095887EF36E /* OIDCService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCService.swift; sourceTree = ""; }; 9080CDD3881D0D1B2F280A7C /* MockUserNotificationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserNotificationController.swift; sourceTree = ""; }; + 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = ""; }; 91FB6F5ECCF51ECE98ACFEEC /* RoomDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomDetailsViewModel.swift; sourceTree = ""; }; 9238D3A3A00F45E841FE4EFF /* DebugScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugScreen.swift; sourceTree = ""; }; 92FCD9116ADDE820E4E30F92 /* UIKitBackgroundTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIKitBackgroundTask.swift; sourceTree = ""; }; @@ -820,6 +823,7 @@ 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenViewModelTests.swift; sourceTree = ""; }; 94BCC8A9C73C1F838122C645 /* TimelineItemPlainStylerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemPlainStylerView.swift; sourceTree = ""; }; 96561CC53F7C1E24D4C292E4 /* MockNotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockNotificationManager.swift; sourceTree = ""; }; + 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomStringConvertible.swift; sourceTree = ""; }; 96F37AB24AF5A006521D38D1 /* RoomMessageFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMessageFactoryProtocol.swift; sourceTree = ""; }; 9772C1D2223108EB3131AEE4 /* zh-CN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-CN"; path = "zh-CN.lproj/Localizable.strings"; sourceTree = ""; }; 97755C01C3971474EFAD5367 /* AuthenticationIconImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationIconImage.swift; sourceTree = ""; }; @@ -832,7 +836,6 @@ 9A22A05E472533ED3C5A31B3 /* NavigationModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModule.swift; sourceTree = ""; }; 9A68BCE6438873D2661D93D0 /* BugReportServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportServiceProtocol.swift; sourceTree = ""; }; 9B1FBF8CA40199B8058B1F08 /* NotificationItemProxy+NSE.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationItemProxy+NSE.swift"; sourceTree = ""; }; - 9B577F829C693B8DFB7014FD /* RedactedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactedRoomTimelineItem.swift; sourceTree = ""; }; 9BF9E3E6A23180EC05F06460 /* EmojiMartJSONLoaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiMartJSONLoaderTests.swift; sourceTree = ""; }; 9C4048041C1A6B20CB97FD18 /* TestMeasurementParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestMeasurementParser.swift; sourceTree = ""; }; 9C5E81214D27A6B898FC397D /* ElementX.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ElementX.entitlements; sourceTree = ""; }; @@ -849,7 +852,6 @@ A0A20AE75FF4FF35B1FF6CA7 /* MockServerSelectionScreenState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockServerSelectionScreenState.swift; sourceTree = ""; }; A11B74ACE8D71747E1044A9C /* AnalyticsPromptViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptViewModel.swift; sourceTree = ""; }; A1C22B1B5FA3A765EADB2CC9 /* SessionVerificationStateMachineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachineTests.swift; sourceTree = ""; }; - A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = ""; }; A2AC3C656E960E15B5905E05 /* UnsupportedRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineView.swift; sourceTree = ""; }; A2B6433F516F1E6DFA0E2D89 /* vls */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vls; path = vls.lproj/Localizable.strings; sourceTree = ""; }; A30A1758E2B73EF38E7C42F8 /* ServerSelectionModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionModels.swift; sourceTree = ""; }; @@ -858,8 +860,6 @@ A436057DBEA1A23CA8CB1FD7 /* UIFont+AttributedStringBuilder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIFont+AttributedStringBuilder.h"; sourceTree = ""; }; A443FAE2EE820A5790C35C8D /* et */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = et; path = et.lproj/Localizable.strings; sourceTree = ""; }; A4756C5A8C8649AD6C10C615 /* MockUserSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockUserSession.swift; sourceTree = ""; }; - A4B5B19A10D3F7C2BC5315DF /* VideoRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItem.swift; sourceTree = ""; }; - A4CF2FC815D26B337E78DA45 /* RoomMemberDetailsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModel.swift; sourceTree = ""; }; A5B0B1226DA8DB55918B34CD /* FileCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCache.swift; sourceTree = ""; }; A64F0DB78E0AC23C91AD89EF /* mk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = mk; path = mk.lproj/Localizable.strings; sourceTree = ""; }; A65F140F9FE5E8D4DAEFF354 /* RoomProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomProxy.swift; sourceTree = ""; }; @@ -875,6 +875,7 @@ AAC9344689121887B74877AF /* UnitTests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; AACE9B8E1A4AE79A7E2914F6 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Localizable.stringsdict; sourceTree = ""; }; AAE73D571D4F9C36DD45255A /* BackgroundTaskServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundTaskServiceProtocol.swift; sourceTree = ""; }; + AB5F75EDB6A9D0779AD01902 /* RoomMemberDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreen.swift; sourceTree = ""; }; AB785716B9212C093704E767 /* EmojiPickerHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerHeaderView.swift; sourceTree = ""; }; AB8E75B9CB6C78BE8D09B1AF /* OnboardingScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingScreen.swift; sourceTree = ""; }; AC1DA29A5A041CC0BACA7CB0 /* MockImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockImageCache.swift; sourceTree = ""; }; @@ -890,12 +891,12 @@ AEC96B3DC55090BBF8876CC2 /* MockFileCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockFileCache.swift; sourceTree = ""; }; AF11DD57D9FACF2A757AB024 /* AnalyticsPromptUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptUITests.swift; sourceTree = ""; }; AF25E364AE85090A70AE4644 /* AttributedStringBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringBuilderTests.swift; sourceTree = ""; }; + B07B937B036247F1962BBCC7 /* RoomMemberDetailsMemberCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsMemberCell.swift; sourceTree = ""; }; B08CBE1E670690ECF11C2C6A /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eu; path = eu.lproj/Localizable.stringsdict; sourceTree = ""; }; B0C5E5931A668B18D8C09028 /* cy */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cy; path = cy.lproj/Localizable.strings; sourceTree = ""; }; B1183B55FF4B01022DA721CB /* en-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-GB"; path = "en-GB.lproj/Localizable.strings"; sourceTree = ""; }; B251F5B4511D1CA0BA8361FE /* CoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinatorProtocol.swift; sourceTree = ""; }; B3069ADED46D063202FE7698 /* SessionVerificationViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModelProtocol.swift; sourceTree = ""; }; - B3FA7C8D4EF2B1873C180ED7 /* EncryptedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptedRoomTimelineItem.swift; sourceTree = ""; }; B43AF03660F5FD4FFFA7F1CE /* TimelineItemContextMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineItemContextMenu.swift; sourceTree = ""; }; B4C18FAAD59AE7F1462D817E /* SessionVerificationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModel.swift; sourceTree = ""; }; B4DE1CF8F5EFD353B1A5E36F /* AnalyticsPromptCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptCoordinator.swift; sourceTree = ""; }; @@ -909,6 +910,7 @@ B8108C8F0ACF6A7EB72D0117 /* RoomScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomScreenCoordinator.swift; sourceTree = ""; }; B8347789959986B374DB25DD /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sq; path = sq.lproj/Localizable.stringsdict; sourceTree = ""; }; B83CB897B183BF3C33715F55 /* bn-IN */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "bn-IN"; path = "bn-IN.lproj/Localizable.stringsdict"; sourceTree = ""; }; + B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = ""; }; B8A56EA2A5AE726F445CB2E3 /* eo */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eo; path = eo.lproj/Localizable.stringsdict; sourceTree = ""; }; B8F28602AC7AC881AED37EBA /* NavigationCoordinators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationCoordinators.swift; sourceTree = ""; }; B902EA6CD3296B0E10EE432B /* HomeScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreen.swift; sourceTree = ""; }; @@ -920,7 +922,6 @@ BEA38B9851CFCC4D67F5587D /* EmojiPickerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenCoordinator.swift; sourceTree = ""; }; BEBA759D1347CFFB3D84ED1F /* UserSessionStoreProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionStoreProtocol.swift; sourceTree = ""; }; BEE6BF9BA63FF42F8AF6EEEA /* sr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sr; path = sr.lproj/Localizable.stringsdict; sourceTree = ""; }; - C00A7110B937C6AE2EF5D7D6 /* FileRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRoomTimelineItem.swift; sourceTree = ""; }; C024C151639C4E1B91FCC68B /* ElementXAttributeScope.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXAttributeScope.swift; sourceTree = ""; }; C06FCD42EEFEFC220F14EAC5 /* SessionVerificationStateMachine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationStateMachine.swift; sourceTree = ""; }; C070FD43DC6BF4E50217965A /* LocalizationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationTests.swift; sourceTree = ""; }; @@ -931,10 +932,10 @@ C483956FA3D665E3842E319A /* SettingsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsScreen.swift; sourceTree = ""; }; C55D7E514F9DE4E3D72FDCAD /* SessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationControllerProxy.swift; sourceTree = ""; }; C687844F60BFF532D49A994C /* AnalyticsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsTests.swift; sourceTree = ""; }; + C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorRoomTimelineItem.swift; sourceTree = ""; }; C6FEA87EA3752203065ECE27 /* BugReportUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportUITests.swift; sourceTree = ""; }; C75EF87651B00A176AB08E97 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; C789E7BFC066CF39B8AE0974 /* NetworkMonitor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkMonitor.swift; sourceTree = ""; }; - C7EDBCE09CCF06B5BB522502 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = ""; }; C830A64609CBD152F06E0457 /* NotificationConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationConstants.swift; sourceTree = ""; }; C88508B6F7974CFABEC4B261 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; }; C888BCD78E2A55DCE364F160 /* MediaProviderProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProviderProtocol.swift; sourceTree = ""; }; @@ -942,6 +943,7 @@ C95ADE8D9527523572532219 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = hu; path = hu.lproj/Localizable.stringsdict; sourceTree = ""; }; C9A86C95340248A8B7BA9A43 /* AnalyticsPromptViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsPromptViewModelProtocol.swift; sourceTree = ""; }; CA28F29C9F93E93CC3C2C715 /* NavigationRootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinator.swift; sourceTree = ""; }; + CA78F8D91974DFFEDC05485A /* RoomMemberDetailsModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsModels.swift; sourceTree = ""; }; CA89A2DD51B6BBE1DA55E263 /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; CA9D14D6F914324865C7DB9F /* ActivityCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityCoordinator.swift; sourceTree = ""; }; CAAE4A709C0A2144C103AA0F /* ang */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ang; path = ang.lproj/Localizable.strings; sourceTree = ""; }; @@ -962,6 +964,7 @@ D0A45283CF1DB96E583BECA6 /* ImageRoomTimelineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageRoomTimelineView.swift; sourceTree = ""; }; D1A9CCCF53495CF3D7B19FCE /* MockSessionVerificationControllerProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSessionVerificationControllerProxy.swift; sourceTree = ""; }; D263254AFE5B7993FFBBF324 /* NSE.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NSE.entitlements; sourceTree = ""; }; + D31DC8105C6233E5FFD9B84C /* element-x-ios */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "element-x-ios"; path = .; sourceTree = SOURCE_ROOT; }; D33116993D54FADC0C721C1F /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; D3D455BC2423D911A62ACFB2 /* NSELogger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSELogger.swift; sourceTree = ""; }; D4DA544B2520BFA65D6DB4BB /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = ""; }; @@ -973,6 +976,7 @@ D6DC38E64A5ED3FDB201029A /* BugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportService.swift; sourceTree = ""; }; D751BB69BB7C38FD247517B4 /* UITestsRootCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestsRootCoordinator.swift; sourceTree = ""; }; D77B3D4950F1707E66E4A45A /* AnalyticsConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnalyticsConfiguration.swift; sourceTree = ""; }; + D8F5F9E02B1AB5350B1815E7 /* TimelineStartRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineStartRoomTimelineItem.swift; sourceTree = ""; }; DA6B262D7584C65BC5B79A0E /* UserNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotification.swift; sourceTree = ""; }; DBD460ED7ED1E03B85DEA25C /* TemplateCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateCoordinator.swift; sourceTree = ""; }; DBFEAC3AC691CBB84983E275 /* ElementXTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementXTests.swift; sourceTree = ""; }; @@ -984,12 +988,12 @@ DED59F9EFF273BFA2055FFDF /* BugReportScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BugReportScreen.swift; sourceTree = ""; }; DF05DA24F71B455E8EFEBC3B /* SessionVerificationViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationViewModelTests.swift; sourceTree = ""; }; DF38B69D2C331A499276F400 /* FilePreviewViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewViewModelTests.swift; sourceTree = ""; }; + DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReadMarkerRoomTimelineItem.swift; sourceTree = ""; }; E0FCA0957FAA0E15A9F5579D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Untranslated.stringsdict; sourceTree = ""; }; E12C9E0B61A77C7F0EE7918C /* MediaProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProxy.swift; sourceTree = ""; }; E157152B11E347F735C3FD6E /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Localizable.stringsdict; sourceTree = ""; }; E18CF12478983A5EB390FB26 /* MessageComposer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageComposer.swift; sourceTree = ""; }; E24B88AD3D1599E8CB1376E0 /* AvatarSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarSize.swift; sourceTree = ""; }; - E254EA67FB16AB33F9F9B18D /* RoomMemberDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsScreen.swift; sourceTree = ""; }; E26747B3154A5DBC3A7E24A5 /* Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = ""; }; E36CB905A2B9EC2C92A2DA7C /* KeychainController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainController.swift; sourceTree = ""; }; E36CFF3E430B27B7C3AD0A28 /* MockMediaProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockMediaProxy.swift; sourceTree = ""; }; @@ -1005,6 +1009,7 @@ E5E94DCFEE803E5ABAE8ACCE /* KeychainControllerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerProtocol.swift; sourceTree = ""; }; E5F2B6443D1ED8602F328539 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Localizable.stringsdict; sourceTree = ""; }; E6281B199D8A8F0892490C2E /* OnboardingCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingCoordinator.swift; sourceTree = ""; }; + E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RedactedRoomTimelineItem.swift; sourceTree = ""; }; E6FCC416A3BFE73DF7B3E6BF /* RoomTimelineControllerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineControllerFactory.swift; sourceTree = ""; }; E8294DB9E95C0C0630418466 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; }; E8CA187FE656EE5A3F6C7DE5 /* UIFont+AttributedStringBuilder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIFont+AttributedStringBuilder.m"; sourceTree = ""; }; @@ -1013,13 +1018,13 @@ E9D059BFE329BE09B6D96A9F /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ro; path = ro.lproj/Localizable.stringsdict; sourceTree = ""; }; EB3B237387B8288A5A938F1B /* UserAgentBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserAgentBuilderTests.swift; sourceTree = ""; }; EBE5502760CF6CA2D7201883 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ja; path = ja.lproj/Localizable.stringsdict; sourceTree = ""; }; + EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelTests.swift; sourceTree = ""; }; ED044D00F2176681CC02CD54 /* HomeScreenRoomCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeScreenRoomCell.swift; sourceTree = ""; }; ED1D792EB82506A19A72C8DE /* RoomTimelineItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineItemProtocol.swift; sourceTree = ""; }; - ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = message.caf; sourceTree = ""; }; + ED482057AE39D5C6D9C5F3D8 /* message.caf */ = {isa = PBXFileReference; path = message.caf; sourceTree = ""; }; EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSelectionViewModelTests.swift; sourceTree = ""; }; EDB6E40BAD4504D899FAAC9A /* TemplateViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateViewModel.swift; sourceTree = ""; }; EE8BCD14EFED23459A43FDFF /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; - EEAF1C75771D9DC75877F4B4 /* MessageTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageTimelineItem.swift; sourceTree = ""; }; EEE384418EB1FEDFA62C9CD0 /* RoomTimelineViewFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomTimelineViewFactoryProtocol.swift; sourceTree = ""; }; EF1593DD87F974F8509BB619 /* ElementAnimations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElementAnimations.swift; sourceTree = ""; }; EFF7BF82A950B91BC5469E91 /* ViewFrameReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewFrameReader.swift; sourceTree = ""; }; @@ -1027,22 +1032,20 @@ F012CB5EE3F2B67359F6CC52 /* target.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = target.yml; sourceTree = ""; }; F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotDetectorTests.swift; sourceTree = ""; }; F0E7BF8F7BB1021F889C6483 /* MockBugReportService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockBugReportService.swift; sourceTree = ""; }; - F118CF7C5548099AACF7E90C /* RoomMemberDetailsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsCoordinator.swift; sourceTree = ""; }; - F15BE37BE2FB86E00C8D150A /* AggregratedReaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AggregratedReaction.swift; sourceTree = ""; }; F174A5627CDB3CAF280D1880 /* EmojiPickerScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenModels.swift; sourceTree = ""; }; + F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnsupportedRoomTimelineItem.swift; sourceTree = ""; }; F23BA6D4842D53C5AC9B7584 /* nn */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = nn; path = nn.lproj/Localizable.stringsdict; sourceTree = ""; }; F2D58333B377888012740101 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; F31A4E5941ACBA4BB9FEF94C /* UserNotificationToastView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNotificationToastView.swift; sourceTree = ""; }; F31F59030205A6F65B057E1A /* MatrixEntityRegexTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MatrixEntityRegexTests.swift; sourceTree = ""; }; + F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoRoomTimelineItem.swift; sourceTree = ""; }; F3648F2FADEF2672D6A0D489 /* FileCacheTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCacheTests.swift; sourceTree = ""; }; F36C0A6D59717193F49EA986 /* UserSessionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionTests.swift; sourceTree = ""; }; F3EAE3E9D5EF4A6D5D9C6CFD /* EmojiPickerScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiPickerScreenViewModel.swift; sourceTree = ""; }; F506C6ADB1E1DA6638078E11 /* UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; F5C4AF6E3885730CD560311C /* ScreenshotDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotDetector.swift; sourceTree = ""; }; - F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRoomTimelineItem.swift; sourceTree = ""; }; F73FF1A33198F5FAE9D34B1F /* FormattedBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormattedBodyText.swift; sourceTree = ""; }; F754E66A8970963B15B2A41E /* PermalinkBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermalinkBuilder.swift; sourceTree = ""; }; - F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmoteRoomTimelineItem.swift; sourceTree = ""; }; F875D71347DC81EAE7687446 /* NavigationRootCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRootCoordinatorTests.swift; sourceTree = ""; }; F899D02CF26EA7675EEBE74C /* UserSessionScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionScreenTests.swift; sourceTree = ""; }; F9212AE02CBDD692C56A879F /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = ""; }; @@ -1052,7 +1055,6 @@ FAB10E673916D2B8D21FD197 /* TemplateModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemplateModels.swift; sourceTree = ""; }; FBC776F301D374A3298C69DA /* AppCoordinatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCoordinatorProtocol.swift; sourceTree = ""; }; FC3D31C2DA6910AA0079678A /* MediaProxyProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaProxyProtocol.swift; sourceTree = ""; }; - FD38C315F6576DB898EA9529 /* RoomMemberDetailsViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomMemberDetailsViewModelProtocol.swift; sourceTree = ""; }; FDB9C37196A4C79F24CE80C6 /* KeychainControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainControllerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -1240,6 +1242,13 @@ path = Resources; sourceTree = ""; }; + 285079C24A5189C48284CC47 /* VideoPlayer */ = { + isa = PBXGroup; + children = ( + ); + path = VideoPlayer; + sourceTree = ""; + }; 2D6DC9871FD7173E51D67C73 /* Cache */ = { isa = PBXGroup; children = ( @@ -1556,15 +1565,6 @@ path = ErrorHandling; sourceTree = ""; }; - 5A7A7D6D373D411C8C48B881 /* TimeLineItemContent */ = { - isa = PBXGroup; - children = ( - F15BE37BE2FB86E00C8D150A /* AggregratedReaction.swift */, - EEAF1C75771D9DC75877F4B4 /* MessageTimelineItem.swift */, - ); - path = TimeLineItemContent; - sourceTree = ""; - }; 5BACB442D02C878293C04837 /* EmojiMart */ = { isa = PBXGroup; children = ( @@ -1619,6 +1619,17 @@ name = Products; sourceTree = ""; }; + 6B0910BCE4F1B02F124E1A09 /* TimelineItemContent */ = { + isa = PBXGroup; + children = ( + B858A61F2A570DFB8DE570A7 /* AggregratedReaction.swift */, + 96C4762F8D6112E43117DB2F /* CustomStringConvertible.swift */, + 755DC0F79EF8181CC175A193 /* MessageTimelineItem.swift */, + 5DE8D25D6A91030175D52A20 /* RoomTimelineItemProperties.swift */, + ); + path = TimelineItemContent; + sourceTree = ""; + }; 6DE13A7AE6587B079F4049D7 /* Notification */ = { isa = PBXGroup; children = ( @@ -1696,7 +1707,7 @@ 00A941F289F6AB876BA3361A /* OnboardingViewModelTests.swift */, 6FB31A32C93D94930B253FBF /* PermalinkBuilderTests.swift */, 2EFE1922F39398ABFB36DF3F /* RoomDetailsViewModelTests.swift */, - 33AECDFE83A880328CCFD0B1 /* RoomMemberDetailsViewModelTests.swift */, + EC589E641AE46EFB2962534D /* RoomMemberDetailsViewModelTests.swift */, 93CF7B19FFCF8EFBE0A8696A /* RoomScreenViewModelTests.swift */, F03C9D319676F3C0DC6B0203 /* ScreenshotDetectorTests.swift */, EDAA4472821985BF868CC21C /* ServerSelectionViewModelTests.swift */, @@ -1730,21 +1741,9 @@ 75D1D02F7F3AC1122FCFB4F3 /* Items */ = { isa = PBXGroup; children = ( - F77C060C2ACC4CB7336A29E7 /* EmoteRoomTimelineItem.swift */, - B3FA7C8D4EF2B1873C180ED7 /* EncryptedRoomTimelineItem.swift */, - C00A7110B937C6AE2EF5D7D6 /* FileRoomTimelineItem.swift */, - 1A63815AD6A5C306453342F2 /* ImageRoomTimelineItem.swift */, - 4F49CDE349C490D617332770 /* NoticeRoomTimelineItem.swift */, - 756288D339AFC15D2C3F4A0D /* PaginationIndicatorRoomTimelineItem.swift */, - 02351B2D9CD9B2B914352908 /* ReadMarkerRoomTimelineItem.swift */, - 9B577F829C693B8DFB7014FD /* RedactedRoomTimelineItem.swift */, - 289FA233E896FBC5956C67E0 /* RoomTimelineItemProperties.swift */, - A1ED7E89865201EE7D53E6DA /* SeparatorRoomTimelineItem.swift */, - 4C84013BB71998CDD90C634C /* StickerRoomTimelineItem.swift */, - F6A8C632CEF4600107792899 /* TextRoomTimelineItem.swift */, - 4DF73D6149F4755E9C530303 /* TimelineStartRoomTimelineItem.swift */, - C7EDBCE09CCF06B5BB522502 /* UnsupportedRoomTimelineItem.swift */, - A4B5B19A10D3F7C2BC5315DF /* VideoRoomTimelineItem.swift */, + 8428BD1821586CEE0B9C9ECA /* Messages */, + B1FC81662045E2369B0C4A0E /* Other */, + D977D4E565C06D3F41C8F8FC /* Virtual */, ); path = Items; sourceTree = ""; @@ -1891,12 +1890,25 @@ 83CA952B8D738B8E810F569D /* View */ = { isa = PBXGroup; children = ( - 22FECA5919BE59C4BB5AEB22 /* RoomMemberDetailsMemberCell.swift */, - E254EA67FB16AB33F9F9B18D /* RoomMemberDetailsScreen.swift */, + B07B937B036247F1962BBCC7 /* RoomMemberDetailsMemberCell.swift */, + AB5F75EDB6A9D0779AD01902 /* RoomMemberDetailsScreen.swift */, ); path = View; sourceTree = ""; }; + 8428BD1821586CEE0B9C9ECA /* Messages */ = { + isa = PBXGroup; + children = ( + 450E04B2A976CC4C8CC1807C /* EmoteRoomTimelineItem.swift */, + 5098DA7799946A61E34A2373 /* FileRoomTimelineItem.swift */, + 3DFE4453AB0B34C203447162 /* ImageRoomTimelineItem.swift */, + 421E716C521F96D24ECE69B3 /* NoticeRoomTimelineItem.swift */, + 90A55430639712CFACA34F43 /* TextRoomTimelineItem.swift */, + F348B5F2C12F9D4F4B4D3884 /* VideoRoomTimelineItem.swift */, + ); + path = Messages; + sourceTree = ""; + }; 864330656491EBAADA4901D3 /* Sources */ = { isa = PBXGroup; children = ( @@ -1953,7 +1965,7 @@ 9413F680ECDFB2B0DDB0DEF2 /* Packages */ = { isa = PBXGroup; children = ( - 551DAED7F623AA5366E79927 /* repository */, + D31DC8105C6233E5FFD9B84C /* element-x-ios */, ); name = Packages; sourceTree = SOURCE_ROOT; @@ -1969,7 +1981,7 @@ 1DB34B0C74CD242FED9DD069 /* LoginScreenUITests.swift */, 0C88046D6A070D9827181C4D /* OnboardingUITests.swift */, 3BFDAF6918BB096C44788FC9 /* RoomDetailsScreenUITests.swift */, - 72F910035944E5F38F4F801E /* RoomMemberDetailsScreenUITests.swift */, + 0F19DBE940499D3E3DD405D8 /* RoomMemberDetailsScreenUITests.swift */, 086B997409328F091EBA43CE /* RoomScreenUITests.swift */, 054F469E433864CC6FE6EE8E /* ServerSelectionUITests.swift */, 6D4777F0142E330A75C46FE4 /* SessionVerificationUITests.swift */, @@ -2118,6 +2130,17 @@ path = NSE; sourceTree = ""; }; + B1FC81662045E2369B0C4A0E /* Other */ = { + isa = PBXGroup; + children = ( + 5351EBD7A0B9610548E4B7B2 /* EncryptedRoomTimelineItem.swift */, + E6E6BDF9D26DB05C88901416 /* RedactedRoomTimelineItem.swift */, + 818695BED971753243FEF897 /* StickerRoomTimelineItem.swift */, + F1B8500C152BC59445647DA8 /* UnsupportedRoomTimelineItem.swift */, + ); + path = Other; + sourceTree = ""; + }; B442FCF47E0A6F28D7D50A4D /* FilePreview */ = { isa = PBXGroup; children = ( @@ -2270,6 +2293,17 @@ path = SessionVerification; sourceTree = ""; }; + D977D4E565C06D3F41C8F8FC /* Virtual */ = { + isa = PBXGroup; + children = ( + 0B987FC3FDBAA0E1C5AA235C /* PaginationIndicatorRoomTimelineItem.swift */, + DF3D25B3EDB283B5807EADCF /* ReadMarkerRoomTimelineItem.swift */, + C6A9F49B3EE59147AF2F70BB /* SeparatorRoomTimelineItem.swift */, + D8F5F9E02B1AB5350B1815E7 /* TimelineStartRoomTimelineItem.swift */, + ); + path = Virtual; + sourceTree = ""; + }; DA5F79E290EB586FC98AAC63 /* UserNotifications */ = { isa = PBXGroup; children = ( @@ -2328,6 +2362,7 @@ 679E9837ECA8D6776079D16E /* RoomScreen */, D958761758AA1110476DE6A3 /* SessionVerification */, 70B74A432C241E56A7ACE610 /* Settings */, + 285079C24A5189C48284CC47 /* VideoPlayer */, ); path = Screens; sourceTree = ""; @@ -2381,10 +2416,10 @@ F363C3EEA04EE9F4584B060C /* RoomMembers */ = { isa = PBXGroup; children = ( - F118CF7C5548099AACF7E90C /* RoomMemberDetailsCoordinator.swift */, - 6F5734DF8967F3595F8C784D /* RoomMemberDetailsModels.swift */, - A4CF2FC815D26B337E78DA45 /* RoomMemberDetailsViewModel.swift */, - FD38C315F6576DB898EA9529 /* RoomMemberDetailsViewModelProtocol.swift */, + 1CEFB5144EF8F50C77CF6E14 /* RoomMemberDetailsCoordinator.swift */, + CA78F8D91974DFFEDC05485A /* RoomMemberDetailsModels.swift */, + 57CF0E6DD78FB3F6CBF5AC38 /* RoomMemberDetailsViewModel.swift */, + 53C4265ED404027938012B35 /* RoomMemberDetailsViewModelProtocol.swift */, 83CA952B8D738B8E810F569D /* View */, ); path = RoomMembers; @@ -2411,7 +2446,7 @@ 2D505843AB66822EB91F0DF0 /* TimelineItemProxy.swift */, 3EA31CC7012EA2A5653DAFC9 /* Fixtures */, 2F2FED77226A43559F009463 /* TimelineController */, - 5A7A7D6D373D411C8C48B881 /* TimeLineItemContent */, + 6B0910BCE4F1B02F124E1A09 /* TimelineItemContent */, 95BE1C7CB2C80344FF0BE724 /* TimelineItems */, ); path = Timeline; @@ -2895,7 +2930,7 @@ F9F6D2883BBEBB9A3789A137 /* OnboardingViewModelTests.swift in Sources */, 27E9263DA75E266690A37EB1 /* PermalinkBuilderTests.swift in Sources */, EA974337FA7D040E7C74FE6E /* RoomDetailsViewModelTests.swift in Sources */, - 235819701B166DFBA21994F1 /* RoomMemberDetailsViewModelTests.swift in Sources */, + 6B31508C6334C617360C2EAB /* RoomMemberDetailsViewModelTests.swift in Sources */, 46562110EE202E580A5FFD9C /* RoomScreenViewModelTests.swift in Sources */, EA31DD9043B91ECB8E45A9A6 /* ScreenshotDetectorTests.swift in Sources */, 93875ADD456142D20823ED24 /* ServerSelectionViewModelTests.swift in Sources */, @@ -2920,7 +2955,7 @@ buildActionMask = 2147483647; files = ( 098CE03C6CC71A31F263FA33 /* ActivityCoordinator.swift in Sources */, - 7096FA3AC218D914E88BFB70 /* AggregratedReaction.swift in Sources */, + 4219391CD2351E410554B3E8 /* AggregratedReaction.swift in Sources */, A50849766F056FD1DB942DEA /* AlertInfo.swift in Sources */, 39929D29B265C3F6606047DE /* AlignedScrollView.swift in Sources */, A371629728E597C5FCA3C2B2 /* Analytics.swift in Sources */, @@ -2966,6 +3001,7 @@ 24BDDD09A90B8BFE3793F3AA /* ClientProxyProtocol.swift in Sources */, 663E198678778F7426A9B27D /* Collection.swift in Sources */, C3522917C0C367C403429EEC /* CoordinatorProtocol.swift in Sources */, + 12C867E85E6D12EEDFD0B127 /* CustomStringConvertible.swift in Sources */, C4F69156C31A447FEFF2A47C /* DTHTMLElement+AttributedStringBuilder.swift in Sources */, 1CF18DE71D5D23C61BD88852 /* DebugScreen.swift in Sources */, EE8491AD81F47DF3C192497B /* DecorationTimelineItemProtocol.swift in Sources */, @@ -2986,9 +3022,9 @@ 2C5E832434EE94E21AB3B238 /* EmojiPickerScreenViewModel.swift in Sources */, 1D69E31913DF66426985909B /* EmojiPickerScreenViewModelProtocol.swift in Sources */, FBF09B6C900415800DDF2A21 /* EmojiProvider.swift in Sources */, - 6647430A45B4A8E692909A8F /* EmoteRoomTimelineItem.swift in Sources */, + 5D27B6537591471A42C89027 /* EmoteRoomTimelineItem.swift in Sources */, 68AC3C84E2B438036B174E30 /* EmoteRoomTimelineView.swift in Sources */, - F6E860FF7B18B81DF43B30B8 /* EncryptedRoomTimelineItem.swift in Sources */, + 4C5A638DAA8AF64565BA4866 /* EncryptedRoomTimelineItem.swift in Sources */, B5903E48CF43259836BF2DBF /* EncryptedRoomTimelineView.swift in Sources */, 02D8DF8EB7537EB4E9019DDB /* EventBasedTimelineItemProtocol.swift in Sources */, 33D630461FC4562CC767EE9F /* FileCache.swift in Sources */, @@ -2998,7 +3034,7 @@ 91DFCB641FBA03EE2DA0189E /* FilePreviewScreen.swift in Sources */, 0BEFE400B4802FE8C9DB39B3 /* FilePreviewViewModel.swift in Sources */, 3274219F7F26A5C6C2C55630 /* FilePreviewViewModelProtocol.swift in Sources */, - 630E89EBB0F791208EEE6D11 /* FileRoomTimelineItem.swift in Sources */, + D33AC79A50DFC26D2498DD28 /* FileRoomTimelineItem.swift in Sources */, 1F04C63D4FA95948E3F52147 /* FileRoomTimelineView.swift in Sources */, A0A0D2A9564BDA3FDE2E360F /* FormattedBodyText.swift in Sources */, 85AFBB433AD56704A880F8A0 /* FramePreferenceKey.swift in Sources */, @@ -3010,7 +3046,7 @@ 56F0A22972A3BB519DA2261C /* HomeScreenViewModelProtocol.swift in Sources */, 03D684A3AE85A23B3DA3B43F /* Image.swift in Sources */, BA31448FBD9697F8CB9A83CD /* ImageCache.swift in Sources */, - DDB80FD2753FEAAE43CC2AAE /* ImageRoomTimelineItem.swift in Sources */, + 7CD16990BA843BE9ED639129 /* ImageRoomTimelineItem.swift in Sources */, D5EA4C6C80579279770D5804 /* ImageRoomTimelineView.swift in Sources */, B6048166B4AA4CEFEA9B77A6 /* InfoPlistReader.swift in Sources */, 9F41FF9C53F7A6EAEA6259C9 /* InviteFriendsCoordinator.swift in Sources */, @@ -3036,7 +3072,7 @@ 43BD17BC8794BB9B04F2A26B /* MediaSourceProxy.swift in Sources */, 24906A1E82D0046655958536 /* MessageComposer.swift in Sources */, 072BA9DBA932374CCA300125 /* MessageComposerTextField.swift in Sources */, - C35CF4DAB1467FE1BBDC204B /* MessageTimelineItem.swift in Sources */, + 67523160A392C40492BB8DC8 /* MessageTimelineItem.swift in Sources */, 152AE2B8650FB23AFD2E28B9 /* MockAuthenticationServiceProxy.swift in Sources */, 28410F3DE89C2C44E4F75C92 /* MockBugReportService.swift in Sources */, EE4F5601356228FF72FC56B6 /* MockClientProxy.swift in Sources */, @@ -3057,7 +3093,7 @@ 71C1347F23868324A4F43940 /* NavigationModule.swift in Sources */, B5E455C9689EA600EDB3E9E0 /* NavigationRootCoordinator.swift in Sources */, C6136E848E55D2C86BF760F5 /* NetworkMonitor.swift in Sources */, - 8BBD3AA589DEE02A1B0923B2 /* NoticeRoomTimelineItem.swift in Sources */, + 0C58A846F61949B1D545D661 /* NoticeRoomTimelineItem.swift in Sources */, 368C8758FCD079E6AAA18C2C /* NoticeRoomTimelineView.swift in Sources */, 3F70E237CE4C3FAB02FC227F /* NotificationConstants.swift in Sources */, CE9530A4CA661E090635C2F2 /* NotificationItemProxy.swift in Sources */, @@ -3074,15 +3110,15 @@ CE7148E80F09B7305E026AC6 /* OnboardingViewModel.swift in Sources */, 992477AB8E3F3C36D627D32E /* OnboardingViewModelProtocol.swift in Sources */, CD6A72B65D3B6076F4045C30 /* PHGPostHogConfiguration.swift in Sources */, - CE79753EA0C433641F0449C0 /* PaginationIndicatorRoomTimelineItem.swift in Sources */, + 7501442D52A65F73DF79FFD4 /* PaginationIndicatorRoomTimelineItem.swift in Sources */, 764AFCC225B044CF5F9B41E5 /* PaginationIndicatorRoomTimelineView.swift in Sources */, 80D00A7C62AAB44F54725C43 /* PermalinkBuilder.swift in Sources */, 7D1DAAA364A9A29D554BD24E /* PlaceholderAvatarImage.swift in Sources */, DF504B10A4918F971A57BEF2 /* PostHogAnalyticsClient.swift in Sources */, - 1368EBBF25858519477FF8A7 /* ReadMarkerRoomTimelineItem.swift in Sources */, + 743790BF6A5B0577EA74AF14 /* ReadMarkerRoomTimelineItem.swift in Sources */, 8EF63DDDC1B54F122070B04D /* ReadMarkerRoomTimelineView.swift in Sources */, C76892321558E75101E68ED6 /* ReadableFrameModifier.swift in Sources */, - 00EA14F62DCEF62CDE4808D6 /* RedactedRoomTimelineItem.swift in Sources */, + AF19D65A9C60C6B2646F3210 /* RedactedRoomTimelineItem.swift in Sources */, 13853973A5E24374FCEDE8A3 /* RedactedRoomTimelineView.swift in Sources */, A494741843F087881299ACF0 /* RestorationToken.swift in Sources */, D59F046B15AA8E971053C1A6 /* RoomDetailsCoordinator.swift in Sources */, @@ -3091,13 +3127,13 @@ 930556A6E30010A551A9DB50 /* RoomDetailsViewModel.swift in Sources */, C4F784AABFF44E4716E7A8BC /* RoomDetailsViewModelProtocol.swift in Sources */, 04A16B45228F7678A027C079 /* RoomHeaderView.swift in Sources */, + 96FE26ABD4E5B8B6EF0EF596 /* RoomMemberDetailsCoordinator.swift in Sources */, + 2AD668FAF5C6BFE252A965F2 /* RoomMemberDetailsMemberCell.swift in Sources */, + AF2095134EED8FD8FC4C3091 /* RoomMemberDetailsModels.swift in Sources */, + 806241864ED47055DC76CB60 /* RoomMemberDetailsScreen.swift in Sources */, + DEC6778FB8CFB829D3E012AC /* RoomMemberDetailsViewModel.swift in Sources */, + 0DB01C67B68CB26E5B3A21AF /* RoomMemberDetailsViewModelProtocol.swift in Sources */, BEEEB659A0BA510D7BE6345C /* RoomMemberProxy.swift in Sources */, - CC2A6B71E12DDF1EE6ECD299 /* RoomMemberDetailsCoordinator.swift in Sources */, - A382B0EA99888F74B6952019 /* RoomMemberDetailsMemberCell.swift in Sources */, - A57A62859AE46AE07281B4AE /* RoomMemberDetailsModels.swift in Sources */, - A3CE203A923A4DD0E9371FB9 /* RoomMemberDetailsScreen.swift in Sources */, - DC2D20609B9B612F6946C3F6 /* RoomMemberDetailsViewModel.swift in Sources */, - 60E838D870A4969D9BADF1BC /* RoomMemberDetailsViewModelProtocol.swift in Sources */, FE79E2BCCF69E8BF4D21E15A /* RoomMessageFactory.swift in Sources */, 8D9F646387DF656EF91EE4CB /* RoomMessageFactoryProtocol.swift in Sources */, D0619D2E6B9C511190FBEB95 /* RoomMessageProtocol.swift in Sources */, @@ -3118,7 +3154,7 @@ 4E945AD6862C403F74E57755 /* RoomTimelineItemFactory.swift in Sources */, 13C77FDF17C4C6627CFFC205 /* RoomTimelineItemFactoryProtocol.swift in Sources */, 70558528EF68CAAEF09972D5 /* RoomTimelineItemFixtures.swift in Sources */, - C8E82786DE1B6A400DA9BA25 /* RoomTimelineItemProperties.swift in Sources */, + 878070573C7BF19E735707B4 /* RoomTimelineItemProperties.swift in Sources */, 1AE4AEA0FA8DEF52671832E0 /* RoomTimelineItemProtocol.swift in Sources */, 9BD3A773186291560DF92B62 /* RoomTimelineProvider.swift in Sources */, 77D7DAA41AAB36800C1F2E2D /* RoomTimelineProviderProtocol.swift in Sources */, @@ -3129,7 +3165,7 @@ 50C90117FE25390BFBD40173 /* RustTracing.swift in Sources */, CC736DA1AA8F8B9FD8785009 /* ScreenshotDetector.swift in Sources */, 0BFA67AFD757EE2BA569836A /* ScrollViewAdapter.swift in Sources */, - 1281625B25371BE53D36CB3A /* SeparatorRoomTimelineItem.swift in Sources */, + 14E99D27628B1A6F0CB46FEA /* SeparatorRoomTimelineItem.swift in Sources */, 49F2E7DD8CAACE09CEECE3E6 /* SeparatorRoomTimelineView.swift in Sources */, 87756CA950ED55870A1AAE8F /* ServerSelectionCoordinator.swift in Sources */, 6AC1DC1EAD9F7568360DA1BA /* ServerSelectionModels.swift in Sources */, @@ -3158,7 +3194,7 @@ 165A883C29998EC779465068 /* SoftLogoutViewModelProtocol.swift in Sources */, DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */, B4AAB3257A83B73F53FB2689 /* StateStoreViewModel.swift in Sources */, - 4A67D2EAB564B34EE5C03E11 /* StickerRoomTimelineItem.swift in Sources */, + C58E305C380D3ADDF7912180 /* StickerRoomTimelineItem.swift in Sources */, F32B271F60531BE92C6E62A1 /* StickerRoomTimelineView.swift in Sources */, 2F94054F50E312AF30BE07F3 /* String.swift in Sources */, A7D48E44D485B143AADDB77D /* Strings+Untranslated.swift in Sources */, @@ -3171,7 +3207,7 @@ 75EA4ABBFAA810AFF289D6F4 /* TemplateViewModel.swift in Sources */, 5F1FDE49DFD0C680386E48F9 /* TemplateViewModelProtocol.swift in Sources */, D85D4FA590305180B4A41795 /* Tests.swift in Sources */, - 7963F98CDFDEAC75E072BD81 /* TextRoomTimelineItem.swift in Sources */, + BB784A02BADB03C820617A46 /* TextRoomTimelineItem.swift in Sources */, 5E0F2E612718BB4397A6D40A /* TextRoomTimelineView.swift in Sources */, 5D2AF8C0DF872E7985F8FE54 /* TimelineDeliveryStatusView.swift in Sources */, 157E5FDDF419C0B2CA7E2C28 /* TimelineItemBubbledStylerView.swift in Sources */, @@ -3180,7 +3216,7 @@ 440123E29E2F9B001A775BBE /* TimelineItemProxy.swift in Sources */, 9B582B3EEFEA615D4A6FBF1A /* TimelineReactionsView.swift in Sources */, ABF3FAB234AD3565B214309B /* TimelineSenderAvatarView.swift in Sources */, - 28934460A497CD002249ED71 /* TimelineStartRoomTimelineItem.swift in Sources */, + C4FE0E11A907C8999F92D5A8 /* TimelineStartRoomTimelineItem.swift in Sources */, 6FF51EB400DBA0668FC38B97 /* TimelineStartRoomTimelineView.swift in Sources */, 69BCBB4FB2DC3D61A28D3FD8 /* TimelineStyle.swift in Sources */, FFD3E4FF948E06C7585317FC /* TimelineStyler.swift in Sources */, @@ -3197,7 +3233,7 @@ 086C2FA7750378EB2BFD0BEE /* UITestsRootCoordinator.swift in Sources */, 706289B086B0A6B0C211763F /* UITestsSignalling.swift in Sources */, 071A017E415AD378F2961B11 /* URL.swift in Sources */, - 392D0519E5597A538BFB2CAB /* UnsupportedRoomTimelineItem.swift in Sources */, + 34C752A73717C691582DC6C7 /* UnsupportedRoomTimelineItem.swift in Sources */, E1F446C6B78A3A0FEA15079C /* UnsupportedRoomTimelineView.swift in Sources */, 7A71AEF419904209BB8C2833 /* UserAgentBuilder.swift in Sources */, 87BD4F95F9D603C309837378 /* UserNotification.swift in Sources */, @@ -3214,7 +3250,7 @@ 978BB24F2A5D31EE59EEC249 /* UserSessionProtocol.swift in Sources */, 7E91BAC17963ED41208F489B /* UserSessionStore.swift in Sources */, AC69B6DF15FC451AB2945036 /* UserSessionStoreProtocol.swift in Sources */, - 36C10EDEDC0466E3A9D63132 /* VideoRoomTimelineItem.swift in Sources */, + F07D88421A9BC4D03D4A5055 /* VideoRoomTimelineItem.swift in Sources */, 64F43D7390DA2A0AFD6BA911 /* VideoRoomTimelineView.swift in Sources */, 6FC10A00D268FCD48B631E37 /* ViewFrameReader.swift in Sources */, ); @@ -3233,7 +3269,7 @@ 5C8AFBF168A41E20835F3B86 /* LoginScreenUITests.swift in Sources */, 6B15FF984906AAFCF9DC4F58 /* OnboardingUITests.swift in Sources */, 829062DD3C3F7016FE1A6476 /* RoomDetailsScreenUITests.swift in Sources */, - 626367FC2416CA4E25E15383 /* RoomMemberDetailsScreenUITests.swift in Sources */, + A8771F5975A82759FA5138AE /* RoomMemberDetailsScreenUITests.swift in Sources */, 2F1CF90A3460C153154427F0 /* RoomScreenUITests.swift in Sources */, 77FACC29F98FE2E65BBB6A5F /* ServerSelectionUITests.swift in Sources */, 05EC896A4B9AF4A56670C0BB /* SessionVerificationUITests.swift in Sources */, diff --git a/ElementX/Sources/Application/AppCoordinator.swift b/ElementX/Sources/Application/AppCoordinator.swift index b9da6e44c9..adb8b1175a 100644 --- a/ElementX/Sources/Application/AppCoordinator.swift +++ b/ElementX/Sources/Application/AppCoordinator.swift @@ -27,7 +27,7 @@ class AppCoordinator: AppCoordinatorProtocol { private var backgroundTask: BackgroundTaskProtocol? private var isSuspended = false { didSet { - MXLog.debug("didSet to: \(isSuspended)") + MXLog.info("didSet to: \(isSuspended)") } } @@ -320,7 +320,7 @@ class AppCoordinator: AppCoordinatorProtocol { } .store(in: &cancellables) } else { - MXLog.debug("Couldn't register to AppDelegate callbacks") + MXLog.error("Couldn't register to AppDelegate callbacks") } } } @@ -457,7 +457,7 @@ extension AppCoordinator: NotificationManagerDelegate { } func notificationTapped(_ service: NotificationManagerProtocol, content: UNNotificationContent) async { - MXLog.debug("[AppCoordinator] tappedNotification") + MXLog.info("[AppCoordinator] tappedNotification") guard let roomId = content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String else { return @@ -467,7 +467,7 @@ extension AppCoordinator: NotificationManagerDelegate { } func handleInlineReply(_ service: NotificationManagerProtocol, content: UNNotificationContent, replyText: String) async { - MXLog.debug("[AppCoordinator] handle notification reply") + MXLog.info("[AppCoordinator] handle notification reply") guard let roomId = content.userInfo[NotificationConstants.UserInfoKey.roomIdentifier] as? String else { return diff --git a/ElementX/Sources/Other/Logging/MXLog.swift b/ElementX/Sources/Other/Logging/MXLog.swift index 35474b8b1d..9a7445b599 100644 --- a/ElementX/Sources/Other/Logging/MXLog.swift +++ b/ElementX/Sources/Other/Logging/MXLog.swift @@ -18,25 +18,25 @@ import Foundation import SwiftyBeaver /// Various MXLog configuration options. Used in conjunction with `MXLog.configure()` -@objc public class MXLogConfiguration: NSObject { +public class MXLogConfiguration: NSObject { /// the desired log level. `.verbose` by default. - @objc public var logLevel = MXLogLevel.verbose + public var logLevel = MXLogLevel.verbose /// whether logs should be written directly to files. `false` by default. - @objc public var redirectLogsToFiles = false + public var redirectLogsToFiles = false /// the maximum total space to use for log files in bytes. `100MB` by default. - @objc public var logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB + public var logFilesSizeLimit: UInt = 100 * 1024 * 1024 // 100MB /// the maximum number of log files to use before rolling. `50` by default. - @objc public var maxLogFilesCount: UInt = 50 + public var maxLogFilesCount: UInt = 50 /// the subname for log files. Files will be named as 'console-[subLogName].log'. `nil` by default - @objc public var subLogName: String? + public var subLogName: String? } /// MXLog logging levels. Use .none to disable logging entirely. -@objc public enum MXLogLevel: UInt { +public enum MXLogLevel: UInt { case none case verbose case debug @@ -56,13 +56,13 @@ private var logger: SwiftyBeaver.Type = { Its purpose is to provide a common entry for customizing logging and should be used throughout the code. Please see `MXLog.h` for Objective-C options. */ -@objc public class MXLog: NSObject { +public class MXLog: NSObject { /// Method used to customize MXLog's behavior. /// Called automatically when first accessing the logger with the default values. /// Please see `MXLogConfiguration` for all available options. /// - Parameters: /// - configuration: the `MXLogConfiguration` instance to use - @objc public static func configure(_ configuration: MXLogConfiguration) { + public static func configure(_ configuration: MXLogConfiguration) { configureLogger(logger, withConfiguration: configuration) } @@ -74,11 +74,6 @@ private var logger: SwiftyBeaver.Type = { logger.verbose(message(), file, function, line: line, context: context) } - @available(swift, obsoleted: 5.4) - @objc public static func logVerbose(_ message: String, file: String, function: String, line: Int) { - logger.verbose(message, file, function, line: line) - } - public static func debug(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, @@ -87,11 +82,6 @@ private var logger: SwiftyBeaver.Type = { logger.debug(message(), file, function, line: line, context: context) } - @available(swift, obsoleted: 5.4) - @objc public static func logDebug(_ message: String, file: String, function: String, line: Int) { - logger.debug(message, file, function, line: line) - } - public static func info(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, @@ -100,11 +90,6 @@ private var logger: SwiftyBeaver.Type = { logger.info(message(), file, function, line: line, context: context) } - @available(swift, obsoleted: 5.4) - @objc public static func logInfo(_ message: String, file: String, function: String, line: Int) { - logger.info(message, file, function, line: line) - } - public static func warning(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, @@ -113,31 +98,17 @@ private var logger: SwiftyBeaver.Type = { logger.warning(message(), file, function, line: line, context: context) } - @available(swift, obsoleted: 5.4) - @objc public static func logWarning(_ message: String, file: String, function: String, line: Int) { - logger.warning(message, file, function, line: line) - } - /// Log error with additional details /// /// - Parameters: /// - message: Description of the error without any variables (this is to improve error aggregations by type) /// - context: Additional context-dependent details about the issue - public static func error(_ message: String, + public static func error(_ message: @autoclosure () -> Any, file: String = #file, function: String = #function, line: Int = #line, context: Any? = nil) { - logger.error(message, file, function, line: line, context: context) - } - - @available(swift, obsoleted: 5.4) - @objc public static func logError(_ message: String, - file: String, - function: String, - line: Int, - context: Any? = nil) { - logger.error(message, file, function, line: line, context: context) + logger.error(message(), file, function, line: line, context: context) } /// Log failure with additional details @@ -159,18 +130,6 @@ private var logger: SwiftyBeaver.Type = { #endif } - @available(swift, obsoleted: 5.4) - @objc public static func logFailure(_ message: String, - file: String, - function: String, - line: Int, - context: Any? = nil) { - logger.error(message, file, function, line: line, context: context) - #if DEBUG - assertionFailure("\(message)") - #endif - } - // MARK: - Private fileprivate static func configureLogger(_ logger: SwiftyBeaver.Type, withConfiguration configuration: MXLogConfiguration) { diff --git a/ElementX/Sources/Other/Logging/MXLogger.swift b/ElementX/Sources/Other/Logging/MXLogger.swift index 07d244253f..f3405d1edb 100644 --- a/ElementX/Sources/Other/Logging/MXLogger.swift +++ b/ElementX/Sources/Other/Logging/MXLogger.swift @@ -54,10 +54,10 @@ class MXLogger { let nsLogURL = logURL(for: "console\(subLogName).log") freopen((nsLogURL as NSURL).fileSystemRepresentation, "w+", stderr) - MXLog.debug("redirectNSLogToFiles: true") + MXLog.info("redirectNSLogToFiles: true") if !tempLog.isEmpty { // We can now log into files - MXLog.debug(tempLog) + MXLog.info(tempLog) } removeExtraFiles(from: numberOfFiles) @@ -138,7 +138,7 @@ class MXLogger { } } - MXLog.debug("logFiles: \(logFiles)") + MXLog.info("logFiles: \(logFiles)") return logFiles } @@ -282,7 +282,7 @@ class MXLogger { if fileManager.fileExists(atPath: logFile.path()) { try? fileManager.removeItem(at: logFile) - MXLog.debug("removeExtraFilesFromCount: \(count). removeItemAt: \(logFile)\n") + MXLog.info("removeExtraFilesFromCount: \(count). removeItemAt: \(logFile)\n") } else { break } @@ -318,10 +318,10 @@ class MXLogger { let sizeLimitString = sizeLimit.formatted(.byteCount(style: .binary)) if let indexExceedingSizeLimit { - MXLog.debug("removeFilesAfterSizeLimit: Remove files from index \(indexExceedingSizeLimit) because logs are too large (\(logSizeString) for a limit of \(sizeLimitString)\n") + MXLog.info("removeFilesAfterSizeLimit: Remove files from index \(indexExceedingSizeLimit) because logs are too large (\(logSizeString) for a limit of \(sizeLimitString)\n") removeExtraFiles(from: UInt(indexExceedingSizeLimit)) } else { - MXLog.debug("removeFilesAfterSizeLimit: No need: \(logSizeString) for a limit of \(sizeLimitString)\n") + MXLog.info("removeFilesAfterSizeLimit: No need: \(logSizeString) for a limit of \(sizeLimitString)\n") } } } diff --git a/ElementX/Sources/Other/Logging/RustTracing.swift b/ElementX/Sources/Other/Logging/RustTracing.swift index 36ba7167d9..ad0a198a97 100644 --- a/ElementX/Sources/Other/Logging/RustTracing.swift +++ b/ElementX/Sources/Other/Logging/RustTracing.swift @@ -36,13 +36,11 @@ struct TracingConfiguration { ]) enum Target: String { - case hyper, sled, matrix_sdk_sled, matrix_sdk_ffi + case hyper, sled, matrix_sdk_sled, matrix_sdk_ffi, matrix_sdk_crypto case matrix_sdk_http_client = "matrix_sdk::http_client" case matrix_sdk_ffi_uniffi_api = "matrix_sdk_ffi::uniffi_api" case matrix_sdk_sliding_sync = "matrix_sdk::sliding_sync" case matrix_sdk_base_sliding_sync = "matrix_sdk_base::sliding_sync" - case matrix_sdk_crypto - case matrix_sdk_crypto_sync = "matrix_sdk_crypto::machine[receive_sync_changes]" } enum LogLevel: String { case error, warn, info, debug, trace } @@ -52,8 +50,7 @@ struct TracingConfiguration { .hyper: .warn, .sled: .warn, .matrix_sdk_sled: .warn, - .matrix_sdk_crypto: .debug, - .matrix_sdk_crypto_sync: .trace + .matrix_sdk_crypto: .debug ] var filter: String { diff --git a/ElementX/Sources/Screens/AnalyticsPrompt/AnalyticsPromptCoordinator.swift b/ElementX/Sources/Screens/AnalyticsPrompt/AnalyticsPromptCoordinator.swift index 4f5db8103a..9c75624689 100644 --- a/ElementX/Sources/Screens/AnalyticsPrompt/AnalyticsPromptCoordinator.swift +++ b/ElementX/Sources/Screens/AnalyticsPrompt/AnalyticsPromptCoordinator.swift @@ -37,15 +37,15 @@ final class AnalyticsPromptCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] result in - MXLog.debug("AnalyticsPromptViewModel did complete with result: \(result).") - guard let self else { return } switch result { case .enable: + MXLog.info("Enable Analytics") Analytics.shared.optIn(with: self.parameters.userSession) self.callback?() case .disable: + MXLog.info("Disable Analytics") Analytics.shared.optOut() self.callback?() } diff --git a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift index 734f7aa8ec..9209d7f073 100644 --- a/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/LoginScreen/LoginCoordinator.swift @@ -63,7 +63,6 @@ final class LoginCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("LoginViewModel did callback with result: \(action).") switch action { case .selectServer: @@ -118,6 +117,8 @@ final class LoginCoordinator: CoordinatorProtocol { /// Processes an error to either update the flow or display it to the user. private func handleError(_ error: AuthenticationServiceError) { + MXLog.info("Error occurred: \(error)") + switch error { case .invalidCredentials: viewModel.displayError(.alert(ElementL10n.authInvalidLoginParam)) @@ -150,6 +151,7 @@ final class LoginCoordinator: CoordinatorProtocol { /// Requests the authentication coordinator to log in using the specified credentials. private func login(username: String, password: String) { + MXLog.info("Starting login with password.") startLoading(isInteractionBlocking: true) Task { diff --git a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift b/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift index 2efc964977..edf5e46d61 100644 --- a/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/ServerSelection/ServerSelectionCoordinator.swift @@ -49,7 +49,6 @@ final class ServerSelectionCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("ServerSelectionViewModel did callback with action: \(action).") switch action { case .confirm(let homeserverAddress): @@ -87,9 +86,11 @@ final class ServerSelectionCoordinator: CoordinatorProtocol { Task { switch await authenticationService.configure(for: homeserverAddress) { case .success: + MXLog.info("Selected homeserver: \(homeserverAddress)") callback?(.updated) stopLoading() case .failure(let error): + MXLog.info("Invalid homeserver: \(homeserverAddress)") stopLoading() handleError(error) } diff --git a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift b/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift index 889cae7a34..86e491e9e5 100644 --- a/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift +++ b/ElementX/Sources/Screens/Authentication/SoftLogout/SoftLogoutCoordinator.swift @@ -70,7 +70,7 @@ final class SoftLogoutCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] result in guard let self else { return } - MXLog.debug("[SoftLogoutCoordinator] SoftLogoutViewModel did complete with result: \(result).") + MXLog.info("[SoftLogoutCoordinator] SoftLogoutViewModel did complete with result: \(result).") switch result { case .login(let password): @@ -112,8 +112,6 @@ final class SoftLogoutCoordinator: CoordinatorProtocol { /// Shows the forgot password screen. @MainActor private func showForgotPasswordScreen() { - MXLog.debug("[SoftLogoutCoordinator] showForgotPasswordScreen") - viewModel.displayError(.alert("Not implemented.")) } diff --git a/ElementX/Sources/Screens/BugReport/BugReportCoordinator.swift b/ElementX/Sources/Screens/BugReport/BugReportCoordinator.swift index fa2e2bff66..c497b5fd71 100644 --- a/ElementX/Sources/Screens/BugReport/BugReportCoordinator.swift +++ b/ElementX/Sources/Screens/BugReport/BugReportCoordinator.swift @@ -47,7 +47,7 @@ final class BugReportCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] result in guard let self else { return } - MXLog.debug("BugReportViewModel did complete with result: \(result).") + MXLog.info("BugReportViewModel did complete with result: \(result).") switch result { case .cancel: self.completion?(.cancel) diff --git a/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenCoordinator.swift b/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenCoordinator.swift index e985d4f0d1..4c1043ce63 100644 --- a/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenCoordinator.swift +++ b/ElementX/Sources/Screens/EmojiPickerScreen/EmojiPickerScreenCoordinator.swift @@ -41,7 +41,7 @@ final class EmojiPickerScreenCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("EmojiPickerScreenViewModel did complete with result: \(action).") + switch action { case let .emojiSelected(emoji: emoji): self.callback?(.emojiSelected(emoji: emoji, itemId: self.parameters.itemId)) diff --git a/ElementX/Sources/Screens/FilePreview/FilePreviewCoordinator.swift b/ElementX/Sources/Screens/FilePreview/FilePreviewCoordinator.swift index f7f621a7b6..721e05c0be 100644 --- a/ElementX/Sources/Screens/FilePreview/FilePreviewCoordinator.swift +++ b/ElementX/Sources/Screens/FilePreview/FilePreviewCoordinator.swift @@ -42,7 +42,7 @@ final class FilePreviewCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("FilePreviewViewModel did complete with result: \(action).") + switch action { case .cancel: self.callback?(.cancel) diff --git a/ElementX/Sources/Screens/OnboardingScreen/OnboardingCoordinator.swift b/ElementX/Sources/Screens/OnboardingScreen/OnboardingCoordinator.swift index 8af7dddfa5..64f0f8d71b 100644 --- a/ElementX/Sources/Screens/OnboardingScreen/OnboardingCoordinator.swift +++ b/ElementX/Sources/Screens/OnboardingScreen/OnboardingCoordinator.swift @@ -29,8 +29,8 @@ final class OnboardingCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in - MXLog.debug("OnboardingViewModel did complete with result: \(action).") guard let self else { return } + switch action { case .login: self.callback?(.login) diff --git a/ElementX/Sources/Screens/RoomDetails/RoomDetailsCoordinator.swift b/ElementX/Sources/Screens/RoomDetails/RoomDetailsCoordinator.swift index 07c5715d27..6561980c50 100644 --- a/ElementX/Sources/Screens/RoomDetails/RoomDetailsCoordinator.swift +++ b/ElementX/Sources/Screens/RoomDetails/RoomDetailsCoordinator.swift @@ -45,6 +45,7 @@ final class RoomDetailsCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } + switch action { case .requestMemberDetailsPresentation(let members): self.presentRoomMemberDetails(members) diff --git a/ElementX/Sources/Screens/RoomDetails/RoomDetailsViewModel.swift b/ElementX/Sources/Screens/RoomDetails/RoomDetailsViewModel.swift index 2834c8acbf..0b1face925 100644 --- a/ElementX/Sources/Screens/RoomDetails/RoomDetailsViewModel.swift +++ b/ElementX/Sources/Screens/RoomDetails/RoomDetailsViewModel.swift @@ -47,7 +47,7 @@ class RoomDetailsViewModel: RoomDetailsViewModelType, RoomDetailsViewModelProtoc case .success(let members): self.members = members case .failure(let error): - MXLog.debug("Failed to retrieve room members: \(error)") + MXLog.error("Failed retrieving room members: \(error)") state.bindings.alertInfo = AlertInfo(id: .alert(ElementL10n.unknownError)) } } diff --git a/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsCoordinator.swift b/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsCoordinator.swift index 5e11fb12dc..452ae75307 100644 --- a/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsCoordinator.swift +++ b/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsCoordinator.swift @@ -38,7 +38,7 @@ final class RoomMemberDetailsCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("RoomMemberDetailsViewModel did complete with result: \(action).") + switch action { case .cancel: self.callback?(.cancel) diff --git a/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsViewModel.swift b/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsViewModel.swift index fe5f40251a..d25b59c4c8 100644 --- a/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsViewModel.swift +++ b/ElementX/Sources/Screens/RoomMembers/RoomMemberDetailsViewModel.swift @@ -60,7 +60,7 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta state.members[index].avatar = image } case .failure(let error): - MXLog.debug("Failed to retrieve room member avatar: \(error)") + MXLog.error("Failed to retrieve room member avatar: \(error)") } } } diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index 9b5071095e..d4b5a30d36 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -49,10 +49,10 @@ final class RoomScreenCoordinator: CoordinatorProtocol { // MARK: - Public func start() { - viewModel?.callback = { [weak self] result in + viewModel?.callback = { [weak self] action in guard let self else { return } - MXLog.debug("RoomScreenViewModel did complete with result: \(result).") - switch result { + + switch action { case .displayRoomDetails: self.displayRoomDetails() case .displayVideo(let fileURL, let title), .displayFile(let fileURL, let title): @@ -103,8 +103,8 @@ final class RoomScreenCoordinator: CoordinatorProtocol { coordinator.callback = { [weak self] action in switch action { case let .emojiSelected(emoji: emoji, itemId: itemId): + MXLog.debug("Selected \(emoji) for \(itemId)") self?.navigationStackCoordinator.setSheetCoordinator(nil) - MXLog.debug("Save \(emoji) for \(itemId)") Task { await timelineController.sendReaction(emoji, for: itemId) } diff --git a/ElementX/Sources/Screens/RoomScreen/View/TimelineTableViewController.swift b/ElementX/Sources/Screens/RoomScreen/View/TimelineTableViewController.swift index 03ce8c0d45..abbcbf5309 100644 --- a/ElementX/Sources/Screens/RoomScreen/View/TimelineTableViewController.swift +++ b/ElementX/Sources/Screens/RoomScreen/View/TimelineTableViewController.swift @@ -242,8 +242,6 @@ class TimelineTableViewController: UIViewController { updateTopPadding() - guard snapshot.numberOfItems != previousLayout.numberOfItems else { return } - if previousLayout.isBottomVisible { scrollToBottom(animated: false) } else if let pinnedItem = previousLayout.pinnedItem { @@ -357,15 +355,19 @@ class TimelineTableViewController: UIViewController { extension TimelineTableViewController: UITableViewDelegate { func scrollViewDidScroll(_ scrollView: UIScrollView) { - let isAtBottom = isAtBottom() + paginateBackwardsPublisher.send(()) - // Only update the binding on changes to avoid needlessly recomputing the hierarchy when scrolling. - if scrollToBottomButtonVisible != isAtBottom { - // Dispatch to fix runtime warning about making changes during a view update. - DispatchQueue.main.async { self.scrollToBottomButtonVisible = isAtBottom } + // Dispatch to fix runtime warning about making changes during a view update. + DispatchQueue.main.async { [weak self] in + guard let self else { return } + + let isAtBottom = self.isAtBottom() + + // Only update the binding on changes to avoid needlessly recomputing the hierarchy when scrolling. + if self.scrollToBottomButtonVisible != isAtBottom { + self.scrollToBottomButtonVisible = isAtBottom + } } - - paginateBackwardsPublisher.send(()) } // MARK: ScrollViewAdapter Methods diff --git a/ElementX/Sources/Screens/Settings/SettingsCoordinator.swift b/ElementX/Sources/Screens/Settings/SettingsCoordinator.swift index 4a1d4791ea..df37151bc5 100644 --- a/ElementX/Sources/Screens/Settings/SettingsCoordinator.swift +++ b/ElementX/Sources/Screens/Settings/SettingsCoordinator.swift @@ -40,10 +40,10 @@ final class SettingsCoordinator: CoordinatorProtocol { self.parameters = parameters viewModel = SettingsViewModel(withUserSession: parameters.userSession) - viewModel.callback = { [weak self] result in + viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("SettingsViewModel did complete with result: \(result).") - switch result { + + switch action { case .close: self.callback?(.dismiss) case .toggleAnalytics: diff --git a/ElementX/Sources/Services/Analytics/Analytics.swift b/ElementX/Sources/Services/Analytics/Analytics.swift index fc25107968..16789b7616 100644 --- a/ElementX/Sources/Services/Analytics/Analytics.swift +++ b/ElementX/Sources/Services/Analytics/Analytics.swift @@ -71,7 +71,7 @@ class Analytics { client.stop() // monitoringClient.stop() - MXLog.debug("Stopped.") + MXLog.info("Stopped.") } /// Starts the analytics client if the user has opted in, otherwise does nothing. @@ -84,7 +84,7 @@ class Analytics { // Sanity check in case something went wrong. guard client.isRunning else { return } - MXLog.debug("Started.") + MXLog.info("Started.") // Catch and log crashes // MXLogger.logCrashes(true) @@ -121,7 +121,7 @@ class Analytics { client.reset() // monitoringClient.reset() - MXLog.debug("Reset.") + MXLog.info("Reset.") ServiceLocator.shared.settings.isIdentifiedForAnalytics = false // Stop collecting crash logs @@ -146,7 +146,7 @@ class Analytics { } client.identify(id: id) - MXLog.debug("Identified.") + MXLog.info("Identified.") ServiceLocator.shared.settings.isIdentifiedForAnalytics = true } diff --git a/ElementX/Sources/Services/Analytics/AnalyticsService.swift b/ElementX/Sources/Services/Analytics/AnalyticsService.swift index fafe68c824..ce1e9b8263 100644 --- a/ElementX/Sources/Services/Analytics/AnalyticsService.swift +++ b/ElementX/Sources/Services/Analytics/AnalyticsService.swift @@ -59,7 +59,7 @@ class AnalyticsService { let newSettings = AnalyticsSettings.new(currentEvent: settings) switch await userSession.clientProxy.setAccountData(content: newSettings, type: AnalyticsSettings.eventType) { case .failure: - MXLog.warning("Failed to update analytics settings.") + MXLog.error("Failed to update analytics settings.") return .failure(.accountDataFailure) case .success: MXLog.debug("Successfully updated analytics settings in account data.") diff --git a/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift b/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift index 85d9e99177..5e8079f2f0 100644 --- a/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift +++ b/ElementX/Sources/Services/Authentication/AuthenticationServiceProxy.swift @@ -88,7 +88,7 @@ class AuthenticationServiceProxy: AuthenticationServiceProxyProtocol { let client = try authenticationService.restoreWithAccessToken(token: token, deviceId: deviceID) return await userSession(for: client) } catch { - MXLog.debug(error) + MXLog.error(error) return .failure(.failedLoggingIn) } } diff --git a/ElementX/Sources/Services/Background/UIKitBackgroundTask.swift b/ElementX/Sources/Services/Background/UIKitBackgroundTask.swift index 8ef3cb2938..d90a1fb4ab 100644 --- a/ElementX/Sources/Services/Background/UIKitBackgroundTask.swift +++ b/ElementX/Sources/Services/Background/UIKitBackgroundTask.swift @@ -58,7 +58,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol { } if identifier == .invalid { - MXLog.verbose("Do not start background task: \(name), as OS declined") + MXLog.info("Do not start background task: \(name), as OS declined") // call expiration handler immediately expirationHandler?(self) return nil @@ -69,7 +69,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol { reuse() } - MXLog.verbose("Start background task #\(identifier.rawValue) - \(name)") + MXLog.info("Start background task #\(identifier.rawValue) - \(name)") } func reuse() { @@ -92,7 +92,7 @@ class UIKitBackgroundTask: BackgroundTaskProtocol { private func endTask() { if identifier != .invalid { - MXLog.verbose("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)") + MXLog.info("End background task #\(identifier.rawValue) - \(name) after \(readableElapsedTime)") application.endBackgroundTask(identifier) identifier = .invalid diff --git a/ElementX/Sources/Services/Background/UIKitBackgroundTaskService.swift b/ElementX/Sources/Services/Background/UIKitBackgroundTaskService.swift index d65a5f540d..2d7d183075 100644 --- a/ElementX/Sources/Services/Background/UIKitBackgroundTaskService.swift +++ b/ElementX/Sources/Services/Background/UIKitBackgroundTaskService.swift @@ -36,12 +36,12 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol { isReusable: Bool, expirationHandler: (() -> Void)?) -> BackgroundTaskProtocol? { guard let application else { - MXLog.verbose("Do not start background task: \(name). Application is nil") + MXLog.error("Do not start background task: \(name). Application is nil") return nil } if avoidStartingNewTasks(for: application) { - MXLog.verbose("Do not start background task: \(name), as not enough time exists") + MXLog.info("Do not start background task: \(name), as not enough time exists") // call expiration handler immediately expirationHandler?() return nil @@ -82,7 +82,7 @@ class UIKitBackgroundTaskService: BackgroundTaskServiceProtocol { let appState = application.applicationState let remainingTime = readableBackgroundTimeRemaining(application.backgroundTimeRemaining) - MXLog.verbose("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)") + MXLog.info("Background task \(name) \(created ? "started" : "reused") with app state: \(appState) and estimated background time remaining: \(remainingTime)") return result } diff --git a/ElementX/Sources/Services/BugReport/BugReportService.swift b/ElementX/Sources/Services/BugReport/BugReportService.swift index ac721b7771..72c7813846 100644 --- a/ElementX/Sources/Services/BugReport/BugReportService.swift +++ b/ElementX/Sources/Services/BugReport/BugReportService.swift @@ -53,7 +53,7 @@ class BugReportService: BugReportServiceProtocol { } options.onCrashedLastRun = { [weak self] event in - MXLog.debug("Sentry detected application was crashed: \(event)") + MXLog.error("Sentry detected application was crashed: \(event)") self?.lastCrashEventId = event.eventId.sentryIdString } } @@ -79,11 +79,7 @@ class BugReportService: BugReportServiceProtocol { includeCrashLog: Bool, githubLabels: [String], files: [URL]) async throws -> SubmitBugReportResponse { - MXLog.debug("submitBugReport") - - var params = [ - MultipartFormData(key: "text", type: .text(value: text)) - ] + var params = [MultipartFormData(key: "text", type: .text(value: text))] params.append(contentsOf: defaultParams) for label in githubLabels { params.append(MultipartFormData(key: "label", type: .text(value: label))) @@ -140,6 +136,8 @@ class BugReportService: BugReportServiceProtocol { lastCrashEventId = nil } + MXLog.info("Feedback submitted.") + return result } @@ -176,7 +174,7 @@ class BugReportService: BugReportServiceProtocol { private func zipFiles(includeLogs: Bool, includeCrashLog: Bool) async throws -> [URL] { - MXLog.debug("zipFiles: includeLogs: \(includeLogs), includeCrashLog: \(includeCrashLog)") + MXLog.info("zipFiles: includeLogs: \(includeLogs), includeCrashLog: \(includeCrashLog)") var filesToCompress: [URL] = [] if includeLogs { @@ -213,7 +211,7 @@ class BugReportService: BugReportServiceProtocol { zippedFiles.append(zippedFileURL) } - MXLog.debug("zipFiles: totalSize: \(totalSize), totalZippedSize: \(totalZippedSize)") + MXLog.info("zipFiles: totalSize: \(totalSize), totalZippedSize: \(totalZippedSize)") return zippedFiles } diff --git a/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift b/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift index 839ab6785a..21c437c5ae 100644 --- a/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift +++ b/ElementX/Sources/Services/Client/SlidingSyncViewProxy.swift @@ -31,21 +31,21 @@ private class SlidingSyncViewObserver: SlidingSyncViewRoomListObserver, SlidingS // MARK: - SlidingSyncViewRoomListObserver func didReceiveUpdate(diff: SlidingSyncViewRoomsListDiff) { - MXLog.verbose("Received room diff") + MXLog.info("Received room diff") roomListDiffPublisher.send(diff) } // MARK: - SlidingSyncViewStateObserver func didReceiveUpdate(newState: SlidingSyncState) { - MXLog.verbose("Updated state: \(newState)") + MXLog.info("Updated state: \(newState)") stateUpdatePublisher.send(newState) } // MARK: - SlidingSyncViewRoomsCountObserver func didReceiveUpdate(count: UInt32) { - MXLog.verbose("Updated room count: \(count)") + MXLog.info("Updated room count: \(count)") countUpdatePublisher.send(UInt(count)) } } diff --git a/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift b/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift index 9348b636c5..6940f1ca9e 100644 --- a/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift +++ b/ElementX/Sources/Services/Notification/Manager/NotificationManager.swift @@ -49,12 +49,12 @@ class NotificationManager: NSObject, NotificationManagerProtocol { Task { do { let granted = try await notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) - MXLog.debug("[NotificationManager] permission granted: \(granted)") + MXLog.info("[NotificationManager] permission granted: \(granted)") await MainActor.run { self.delegate?.authorizationStatusUpdated(self, granted: granted) } } catch { - MXLog.debug("[NotificationManager] request authorization failed: \(error)") + MXLog.error("[NotificationManager] request authorization failed: \(error)") } } } @@ -76,9 +76,9 @@ class NotificationManager: NSObject, NotificationManagerProtocol { trigger: nil) do { try await notificationCenter.add(request) - MXLog.debug("[NotificationManager] show local notification succeeded") + MXLog.info("[NotificationManager] show local notification succeeded") } catch { - MXLog.debug("[NotificationManager] show local notification failed: \(error)") + MXLog.error("[NotificationManager] show local notification failed: \(error)") } } @@ -102,10 +102,10 @@ class NotificationManager: NSObject, NotificationManagerProtocol { ] ] ]) - MXLog.debug("[NotificationManager] set pusher succeeded") + MXLog.info("[NotificationManager] set pusher succeeded") return true } catch { - MXLog.debug("[NotificationManager] set pusher failed: \(error)") + MXLog.error("[NotificationManager] set pusher failed: \(error)") return false } } diff --git a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift index 372bb4646c..33e350589d 100644 --- a/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift +++ b/ElementX/Sources/Services/Room/RoomSummary/RoomSummaryProvider.swift @@ -83,7 +83,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol { MXLog.verbose("Updating \(identifiers.count) rooms") guard statePublisher.value == .live else { - MXLog.verbose("Sliding sync not live yet, ignoring.") + MXLog.warning("Sliding sync not live yet, ignoring update.") return } diff --git a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift index 39de063ca6..545ce2cd54 100644 --- a/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift +++ b/ElementX/Sources/Services/Timeline/RoomTimelineProvider.swift @@ -53,7 +53,8 @@ class RoomTimelineProvider: RoomTimelineProviderProtocol { switch await roomProxy.addTimelineListener(listener: roomTimelineListener) { case .failure: - MXLog.error("Failed adding timeline listener on room with identifier: \(await roomProxy.id)") + let roomID = await roomProxy.id + MXLog.error("Failed adding timeline listener on room with identifier: \(roomID)") default: break } diff --git a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift index 057fb429c2..6434d874c0 100644 --- a/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift +++ b/ElementX/Sources/Services/Timeline/TimelineController/RoomTimelineController.swift @@ -146,6 +146,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } func sendMessage(_ message: String) async { + MXLog.info("Send message in \(roomId)") switch await timelineProvider.sendMessage(message) { default: break @@ -153,6 +154,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } func sendReply(_ message: String, to itemId: String) async { + MXLog.info("Send reply in \(roomId)") switch await timelineProvider.sendMessage(message, inReplyToItemId: itemId) { default: break @@ -160,6 +162,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } func sendReaction(_ reaction: String, for itemId: String) async { + MXLog.info("Send reaction in \(roomId)") switch await timelineProvider.sendReaction(reaction, for: itemId) { default: break @@ -167,6 +170,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } func editMessage(_ newMessage: String, of itemId: String) async { + MXLog.info("Edit message in \(roomId)") switch await timelineProvider.editMessage(newMessage, originalItemId: itemId) { default: break @@ -174,6 +178,7 @@ class RoomTimelineController: RoomTimelineControllerProtocol { } func redact(_ eventID: String) async { + MXLog.info("Send redaction in \(roomId)") switch await timelineProvider.redact(eventID) { default: break diff --git a/ElementX/Sources/Services/Timeline/TimeLineItemContent/AggregratedReaction.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/AggregratedReaction.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimeLineItemContent/AggregratedReaction.swift rename to ElementX/Sources/Services/Timeline/TimelineItemContent/AggregratedReaction.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift new file mode 100644 index 0000000000..9d6f5d6762 --- /dev/null +++ b/ElementX/Sources/Services/Timeline/TimelineItemContent/CustomStringConvertible.swift @@ -0,0 +1,55 @@ +// +// Copyright 2023 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import MatrixRustSDK + +// MARK: Redact message content from logs + +extension EmoteMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} + +extension FileMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} + +extension ImageMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} + +extension NoticeMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} + +extension TextMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} + +extension VideoMessageContent: CustomStringConvertible { + public var description: String { + String(describing: Self.self) + } +} diff --git a/ElementX/Sources/Services/Timeline/TimeLineItemContent/MessageTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift similarity index 97% rename from ElementX/Sources/Services/Timeline/TimeLineItemContent/MessageTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift index f678048a35..470cb872e0 100644 --- a/ElementX/Sources/Services/Timeline/TimeLineItemContent/MessageTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItemContent/MessageTimelineItem.swift @@ -19,7 +19,8 @@ import Foundation import MatrixRustSDK /// A protocol that contains the base `m.room.message` event content properties. -protocol MessageContentProtocol: RoomMessageEventContentProtocol { +/// The `CustomStringConvertible` conformance is to redact specific properties from the logs. +protocol MessageContentProtocol: RoomMessageEventContentProtocol, CustomStringConvertible { var body: String { get } } diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/RoomTimelineItemProperties.swift b/ElementX/Sources/Services/Timeline/TimelineItemContent/RoomTimelineItemProperties.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/RoomTimelineItemProperties.swift rename to ElementX/Sources/Services/Timeline/TimelineItemContent/RoomTimelineItemProperties.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/EmoteRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift similarity index 80% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/EmoteRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift index 03beb80d23..abdfd446e1 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/EmoteRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/EmoteRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct EmoteRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -32,3 +31,11 @@ struct EmoteRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hash var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension EmoteRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/FileRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift similarity index 80% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/FileRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift index e8874f0421..f44be63736 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/FileRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/FileRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct FileRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -35,3 +34,11 @@ struct FileRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hasha var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension FileRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/ImageRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift similarity index 81% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/ImageRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift index 5af081a8d3..3ffc106b78 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/ImageRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/ImageRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct ImageRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -40,3 +39,11 @@ struct ImageRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hash var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension ImageRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/NoticeRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift similarity index 79% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/NoticeRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift index ad206d02fe..8db5586fcc 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/NoticeRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/NoticeRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct NoticeRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -32,3 +31,11 @@ struct NoticeRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Has var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension NoticeRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/TextRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift similarity index 80% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/TextRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift index 2f2f7fc60f..eb2363bc44 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/TextRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/TextRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct TextRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -32,3 +31,11 @@ struct TextRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hasha var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension TextRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/VideoRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift similarity index 82% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/VideoRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift index 921006dacf..86d86eacf1 100644 --- a/ElementX/Sources/Services/Timeline/TimelineItems/Items/VideoRoomTimelineItem.swift +++ b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Messages/VideoRoomTimelineItem.swift @@ -14,7 +14,6 @@ // limitations under the License. // -import Foundation import UIKit struct VideoRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hashable { @@ -42,3 +41,11 @@ struct VideoRoomTimelineItem: EventBasedTimelineItemProtocol, Identifiable, Hash var properties = RoomTimelineItemProperties() } + +// MARK: - Redact content from logs + +extension VideoRoomTimelineItem: CustomStringConvertible { + var description: String { + "\(String(describing: Self.self)): id: \(id), timestamp: \(timestamp), isOutgoing: \(isOutgoing), properties: \(properties)" + } +} diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/EncryptedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/EncryptedRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/EncryptedRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/RedactedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/RedactedRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/RedactedRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/StickerRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/StickerRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/StickerRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/UnsupportedRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/UnsupportedRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Other/UnsupportedRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/PaginationIndicatorRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/PaginationIndicatorRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/PaginationIndicatorRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/ReadMarkerRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/ReadMarkerRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/ReadMarkerRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/ReadMarkerRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/SeparatorRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/SeparatorRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/SeparatorRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/SeparatorRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/Timeline/TimelineItems/Items/TimelineStartRoomTimelineItem.swift b/ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift similarity index 100% rename from ElementX/Sources/Services/Timeline/TimelineItems/Items/TimelineStartRoomTimelineItem.swift rename to ElementX/Sources/Services/Timeline/TimelineItems/Items/Virtual/TimelineStartRoomTimelineItem.swift diff --git a/ElementX/Sources/Services/UserSession/UserSessionStore.swift b/ElementX/Sources/Services/UserSession/UserSessionStore.swift index ffef872dae..37a3274497 100644 --- a/ElementX/Sources/Services/UserSession/UserSessionStore.swift +++ b/ElementX/Sources/Services/UserSession/UserSessionStore.swift @@ -33,7 +33,7 @@ class UserSessionStore: UserSessionStoreProtocol { accessGroup: InfoPlistReader.target.keychainAccessGroupIdentifier) self.backgroundTaskService = backgroundTaskService baseDirectory = .sessionsBaseDirectory - MXLog.debug("Setup base directory at: \(baseDirectory)") + MXLog.info("Setup base directory at: \(baseDirectory)") } /// Deletes all data stored in the shared container and keychain diff --git a/NSE/Sources/NotificationServiceExtension.swift b/NSE/Sources/NotificationServiceExtension.swift index abaf0c6712..90b67b9170 100644 --- a/NSE/Sources/NotificationServiceExtension.swift +++ b/NSE/Sources/NotificationServiceExtension.swift @@ -51,8 +51,8 @@ class NotificationServiceExtension: UNNotificationServiceExtension { NSELogger.logMemory(with: tag) - MXLog.debug("\(tag) #########################################") - MXLog.debug("\(tag) Payload came: \(request.content.userInfo)") + MXLog.info("\(tag) #########################################") + MXLog.info("\(tag) Payload came: \(request.content.userInfo)") Task { try await run(with: credentials, @@ -64,21 +64,21 @@ class NotificationServiceExtension: UNNotificationServiceExtension { override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. - MXLog.debug("\(tag) serviceExtensionTimeWillExpire") + MXLog.warning("\(tag) serviceExtensionTimeWillExpire") notify() } private func run(with credentials: KeychainCredentials, roomId: String, eventId: String) async throws { - MXLog.debug("\(tag) run with roomId: \(roomId), eventId: \(eventId)") + MXLog.info("\(tag) run with roomId: \(roomId), eventId: \(eventId)") let service = NotificationServiceProxy(basePath: URL.sessionsBaseDirectory.path, userId: credentials.userID) guard let itemProxy = try await service.notificationItem(roomId: roomId, eventId: eventId) else { - MXLog.debug("\(tag) got no notification item") + MXLog.error("\(tag) got no notification item") // Notification should be discarded return discard() @@ -88,7 +88,7 @@ class NotificationServiceExtension: UNNotificationServiceExtension { // After this some properties of the notification should be set, like title, subtitle, sound etc. guard let firstContent = try await itemProxy.process(with: roomId, mediaProvider: nil) else { - MXLog.debug("\(tag) not even first content") + MXLog.error("\(tag) not even first content") // Notification should be discarded return discard() @@ -98,13 +98,13 @@ class NotificationServiceExtension: UNNotificationServiceExtension { modifiedContent = firstContent guard itemProxy.requiresMediaProvider else { - MXLog.debug("\(tag) no media needed") + MXLog.info("\(tag) no media needed") // We've processed the item and no media operations needed, so no need to go further return notify() } - MXLog.debug("\(tag) process with media") + MXLog.info("\(tag) process with media") // There is some media to load, process it again if let latestContent = try await itemProxy.process(with: roomId, @@ -126,7 +126,7 @@ class NotificationServiceExtension: UNNotificationServiceExtension { let client = try builder.build() try client.restoreSession(session: credentials.restorationToken.session) - MXLog.debug("\(tag) creating media provider") + MXLog.info("\(tag) creating media provider") return MediaProvider(mediaProxy: MediaProxy(client: client), imageCache: .onlyOnDisk, @@ -135,10 +135,10 @@ class NotificationServiceExtension: UNNotificationServiceExtension { } private func notify() { - MXLog.debug("\(tag) notify") + MXLog.info("\(tag) notify") guard let modifiedContent else { - MXLog.debug("\(tag) notify: no modified content") + MXLog.info("\(tag) notify: no modified content") return } handler?(modifiedContent) @@ -147,7 +147,7 @@ class NotificationServiceExtension: UNNotificationServiceExtension { } private func discard() { - MXLog.debug("\(tag) discard") + MXLog.info("\(tag) discard") handler?(UNMutableNotificationContent()) handler = nil @@ -160,6 +160,6 @@ class NotificationServiceExtension: UNNotificationServiceExtension { deinit { NSELogger.logMemory(with: tag) - MXLog.debug("\(tag) deinit") + MXLog.info("\(tag) deinit") } } diff --git a/NSE/Sources/Other/NSELogger.swift b/NSE/Sources/Other/NSELogger.swift index 5a475b05d5..3a76696534 100644 --- a/NSE/Sources/Other/NSELogger.swift +++ b/NSE/Sources/Other/NSELogger.swift @@ -102,6 +102,6 @@ class NSELogger { } static func logMemory(with tag: String) { - MXLog.debug("\(tag) Memory: footprint: \(formattedMemoryFootprint) - available: \(formattedMemoryAvailable)") + MXLog.info("\(tag) Memory: footprint: \(formattedMemoryFootprint) - available: \(formattedMemoryAvailable)") } } diff --git a/NSE/Sources/Other/UNMutableNotificationContent.swift b/NSE/Sources/Other/UNMutableNotificationContent.swift index d28842da96..3df418843a 100644 --- a/NSE/Sources/Other/UNMutableNotificationContent.swift +++ b/NSE/Sources/Other/UNMutableNotificationContent.swift @@ -32,7 +32,7 @@ extension UNMutableNotificationContent { options: nil) attachments.append(attachment) case .failure(let error): - MXLog.debug("Couldn't add media attachment: \(error)") + MXLog.error("Couldn't add media attachment: \(error)") } return self @@ -81,10 +81,11 @@ extension UNMutableNotificationContent { // Update notification content before displaying the // communication notification. let updatedContent = try updating(from: intent) - + + // swiftlint:disable:next force_cast return updatedContent.mutableCopy() as! UNMutableNotificationContent case .failure(let error): - MXLog.debug("Couldn't add sender icon: \(error)") + MXLog.error("Couldn't add sender icon: \(error)") return self } } diff --git a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateCoordinator.swift b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateCoordinator.swift index 7c27867c54..2b404659cc 100644 --- a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateCoordinator.swift +++ b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateCoordinator.swift @@ -23,6 +23,8 @@ struct TemplateCoordinatorParameters { enum TemplateCoordinatorAction { case accept case cancel + + // Consider adding CustomStringConvertible conformance if the actions contain PII } final class TemplateCoordinator: CoordinatorProtocol { @@ -40,9 +42,9 @@ final class TemplateCoordinator: CoordinatorProtocol { func start() { viewModel.callback = { [weak self] action in guard let self else { return } - MXLog.debug("TemplateViewModel did complete with result: \(action).") switch action { case .accept: + MXLog.info("User accepted the prompt.") self.callback?(.accept) case .cancel: self.callback?(.cancel) diff --git a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateModels.swift b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateModels.swift index 2840c78ae0..ac95e5cb99 100644 --- a/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateModels.swift +++ b/Tools/Scripts/Templates/SimpleScreenExample/ElementX/TemplateModels.swift @@ -46,6 +46,8 @@ extension TemplatePromptType: Identifiable, CaseIterable { enum TemplateViewModelAction { case accept case cancel + + // Consider adding CustomStringConvertible conformance if the actions contain PII } struct TemplateViewState: BindableState { @@ -58,4 +60,6 @@ enum TemplateViewAction { case decrementCount case accept case cancel + + // Consider adding CustomStringConvertible conformance if the actions contain PII } diff --git a/UnitTests/Sources/LoggingTests.swift b/UnitTests/Sources/LoggingTests.swift index d415e72984..ed5e990bd2 100644 --- a/UnitTests/Sources/LoggingTests.swift +++ b/UnitTests/Sources/LoggingTests.swift @@ -15,6 +15,7 @@ // @testable import ElementX +@testable import MatrixRustSDK import XCTest class LoggingTests: XCTestCase { @@ -38,7 +39,7 @@ class LoggingTests: XCTestCase { let configuration = MXLogConfiguration() configuration.redirectLogsToFiles = true MXLog.configure(configuration) - MXLog.debug(log) + MXLog.info(log) guard let logFile = MXLogger.logFiles.first else { XCTFail(Constants.genericFailure) return @@ -58,7 +59,7 @@ class LoggingTests: XCTestCase { let configuration = MXLogConfiguration() configuration.redirectLogsToFiles = true MXLog.configure(configuration) // This call is only made at app launch. - MXLog.debug("Launch \(index + 1)") + MXLog.info("Launch \(index + 1)") } // Then 5 log files should be created each with the correct contents. @@ -80,7 +81,7 @@ class LoggingTests: XCTestCase { configuration.maxLogFilesCount = UInt(logFileCount) configuration.redirectLogsToFiles = true MXLog.configure(configuration) // This call is only made at app launch. - MXLog.debug("Launch \(index + 1)") + MXLog.info("Launch \(index + 1)") } // Then only 5 log files should be stored on disk, with the contents of launches 6 to 10. @@ -102,12 +103,12 @@ class LoggingTests: XCTestCase { configuration.logFilesSizeLimit = UInt(logFileSizeLimit) configuration.redirectLogsToFiles = true MXLog.configure(configuration) // This call is only made at app launch. - MXLog.debug("Launch \(index + 1)") + MXLog.info("Launch \(index + 1)") // Add ~5KB of logs for _ in 0..<5 { let string = [String](repeating: "a", count: 1024).joined() - MXLog.debug(string) + MXLog.info(string) } } @@ -145,7 +146,7 @@ class LoggingTests: XCTestCase { configuration.logLevel = .error configuration.redirectLogsToFiles = true MXLog.configure(configuration) - MXLog.debug(log) + MXLog.info(log) guard let logFile = MXLogger.logFiles.first else { XCTFail(Constants.genericFailure) return @@ -164,7 +165,7 @@ class LoggingTests: XCTestCase { configuration.subLogName = subLogName configuration.redirectLogsToFiles = true MXLog.configure(configuration) - MXLog.debug(UUID().uuidString) + MXLog.info(UUID().uuidString) guard let logFile = MXLogger.logFiles.first else { XCTFail(Constants.genericFailure) return @@ -172,4 +173,164 @@ class LoggingTests: XCTestCase { XCTAssertTrue(logFile.lastPathComponent.contains(subLogName)) } + + func testRoomSummaryContentIsRedacted() throws { + // Given a room summary that contains sensitive information + let roomName = "Private Conversation" + let lastMessage = "Secret information" + let roomSummary = RoomSummaryDetails(id: "myroomid", + name: roomName, + isDirect: true, + avatarURLString: nil, + lastMessage: AttributedString(lastMessage), + lastMessageTimestamp: .now, + unreadNotificationCount: 0) + + // When logging that value + XCTAssert(MXLogger.logFiles.isEmpty) + let configuration = MXLogConfiguration() + configuration.logLevel = .info + configuration.redirectLogsToFiles = true + MXLog.configure(configuration) + MXLog.info(roomSummary) + + // Then the log file should not include the sensitive information + guard let logFile = MXLogger.logFiles.first else { + XCTFail(Constants.genericFailure) + return + } + + let content = try String(contentsOf: logFile) + XCTAssertTrue(content.contains(roomSummary.id)) + XCTAssertFalse(content.contains(roomName)) + XCTAssertFalse(content.contains(lastMessage)) + } + + // swiftlint:disable function_body_length + func testTimelineContentIsRedacted() throws { + // Given timeline items that contain text + let textAttributedString = "TextAttributed" + let textMessage = TextRoomTimelineItem(id: "mytextmessage", text: "TextString", + attributedComponents: [.init(attributedString: AttributedString(textAttributedString), + isBlockquote: false)], + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, senderId: "sender") + let noticeAttributedString = "NoticeAttributed" + let noticeMessage = NoticeRoomTimelineItem(id: "mynoticemessage", text: "NoticeString", + attributedComponents: [.init(attributedString: AttributedString(noticeAttributedString), + isBlockquote: false)], + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, senderId: "sender") + let emoteAttributedString = "EmoteAttributed" + let emoteMessage = EmoteRoomTimelineItem(id: "myemotemessage", text: "EmoteString", + attributedComponents: [.init(attributedString: AttributedString(emoteAttributedString), + isBlockquote: false)], + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, senderId: "sender") + let imageMessage = ImageRoomTimelineItem(id: "myimagemessage", text: "ImageString", + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, + senderId: "sender", source: nil) + let videoMessage = VideoRoomTimelineItem(id: "myvideomessage", text: "VideoString", + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, + senderId: "sender", duration: 0, source: nil, thumbnailSource: nil) + let fileMessage = FileRoomTimelineItem(id: "myfilemessage", text: "FileString", + timestamp: "", groupState: .single, isOutgoing: false, isEditable: false, + senderId: "sender", source: nil, thumbnailSource: nil) + + // When logging that value + XCTAssert(MXLogger.logFiles.isEmpty) + let configuration = MXLogConfiguration() + configuration.logLevel = .info + configuration.redirectLogsToFiles = true + MXLog.configure(configuration) + MXLog.info(textMessage) + MXLog.info(noticeMessage) + MXLog.info(emoteMessage) + MXLog.info(imageMessage) + MXLog.info(videoMessage) + MXLog.info(fileMessage) + + // Then the log file should not include the text content + guard let logFile = MXLogger.logFiles.first else { + XCTFail(Constants.genericFailure) + return + } + + let content = try String(contentsOf: logFile) + XCTAssertTrue(content.contains(textMessage.id)) + XCTAssertFalse(content.contains(textMessage.text)) + XCTAssertFalse(content.contains(textAttributedString)) + + XCTAssertTrue(content.contains(noticeMessage.id)) + XCTAssertFalse(content.contains(noticeMessage.text)) + XCTAssertFalse(content.contains(noticeAttributedString)) + + XCTAssertTrue(content.contains(emoteMessage.id)) + XCTAssertFalse(content.contains(emoteMessage.text)) + XCTAssertFalse(content.contains(emoteAttributedString)) + + XCTAssertTrue(content.contains(imageMessage.id)) + XCTAssertFalse(content.contains(imageMessage.text)) + + XCTAssertTrue(content.contains(videoMessage.id)) + XCTAssertFalse(content.contains(videoMessage.text)) + + XCTAssertTrue(content.contains(fileMessage.id)) + XCTAssertFalse(content.contains(fileMessage.text)) + } + + // swiftlint:enable function_body_length + + func testRustMessageContentIsRedacted() throws { + // Given message content that contain text + let textString = "TextString" + let textMessage = TextMessageContent(body: "", + formatted: FormattedBody(format: .html, body: "\(textString)")) + let noticeString = "NoticeString" + let noticeMessage = NoticeMessageContent(body: noticeString, + formatted: FormattedBody(format: .html, body: "\(noticeString)")) + let emoteString = "EmoteString" + let emoteMessage = EmoteMessageContent(body: emoteString, + formatted: FormattedBody(format: .html, body: "\(emoteString)")) + + let pointer = Unmanaged.passRetained(NSURL(fileURLWithPath: "/tmp/file")).toOpaque() + let imageMessage = ImageMessageContent(body: "ImageString", source: MediaSource(unsafeFromRawPointer: pointer), info: nil) + let videoMessage = VideoMessageContent(body: "VideoString", source: MediaSource(unsafeFromRawPointer: pointer), info: nil) + let fileMessage = FileMessageContent(body: "FileString", source: MediaSource(unsafeFromRawPointer: pointer), info: nil) + + // When logging that value + XCTAssert(MXLogger.logFiles.isEmpty) + let configuration = MXLogConfiguration() + configuration.logLevel = .info + configuration.redirectLogsToFiles = true + MXLog.configure(configuration) + MXLog.info(textMessage) + MXLog.info(noticeMessage) + MXLog.info(emoteMessage) + MXLog.info(imageMessage) + MXLog.info(videoMessage) + MXLog.info(fileMessage) + + // Then the log file should not include the text content + guard let logFile = MXLogger.logFiles.first else { + XCTFail(Constants.genericFailure) + return + } + + let content = try String(contentsOf: logFile) + XCTAssertTrue(content.contains(String(describing: TextMessageContent.self))) + XCTAssertFalse(content.contains(textString)) + + XCTAssertTrue(content.contains(String(describing: NoticeMessageContent.self))) + XCTAssertFalse(content.contains(noticeString)) + + XCTAssertTrue(content.contains(String(describing: EmoteMessageContent.self))) + XCTAssertFalse(content.contains(emoteString)) + + XCTAssertTrue(content.contains(String(describing: ImageMessageContent.self))) + XCTAssertFalse(content.contains(imageMessage.body)) + + XCTAssertTrue(content.contains(String(describing: VideoMessageContent.self))) + XCTAssertFalse(content.contains(videoMessage.body)) + + XCTAssertTrue(content.contains(String(describing: FileMessageContent.self))) + XCTAssertFalse(content.contains(fileMessage.body)) + } } diff --git a/changelog.d/pr-457.change b/changelog.d/pr-457.change new file mode 100644 index 0000000000..e0951db038 --- /dev/null +++ b/changelog.d/pr-457.change @@ -0,0 +1 @@ +Logging: Redact Room/Message content and use MXLog.info in more places. \ No newline at end of file