From efe9041f5c9c97f9d045d6da69585edafd76c40c Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Wed, 20 Oct 2021 02:35:22 +0300 Subject: [PATCH 001/209] Adapt to store api changes --- RiotShareExtension/Shared/ShareDataSource.m | 6 +- SiriIntents/IntentHandler.m | 99 ++++++++++----------- 2 files changed, 50 insertions(+), 55 deletions(-) diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index a06a92e36..19ef37eb8 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -77,7 +77,7 @@ - (void)loadCellData { - [self.fileStore asyncRoomsSummaries:^(NSArray *roomsSummaries) { + [self.fileStore.summariesModule fetchAllSummaries:^(NSArray *roomsSummaries) { NSMutableArray *cellData = [NSMutableArray array]; @@ -111,10 +111,6 @@ }); - } failure:^(NSError * _Nonnull error) { - - MXLogDebug(@"[ShareDataSource failed to get room summaries]"); - }]; } diff --git a/SiriIntents/IntentHandler.m b/SiriIntents/IntentHandler.m index c55a5357e..dead5b239 100644 --- a/SiriIntents/IntentHandler.m +++ b/SiriIntents/IntentHandler.m @@ -217,58 +217,57 @@ { MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject; MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore asyncRoomsSummaries:^(NSArray> * _Nonnull roomsSummaries) { - NSString *roomID = person.customIdentifier; + [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull roomsSummaries) { + NSString *roomID = person.customIdentifier; - BOOL isEncrypted = NO; - for (id roomSummary in roomsSummaries) - { - if ([roomSummary.roomId isEqualToString:roomID]) - { - isEncrypted = roomSummary.isEncrypted; - break; - } - } + BOOL isEncrypted = NO; + for (id roomSummary in roomsSummaries) + { + if ([roomSummary.roomId isEqualToString:roomID]) + { + isEncrypted = roomSummary.isEncrypted; + break; + } + } - if (isEncrypted) - { - [MXFileStore setPreloadOptions:0]; - - MXSession *session = [[MXSession alloc] initWithMatrixRestClient:account.mxRestClient]; - MXWeakify(session); - [session setStore:fileStore success:^{ - MXStrongifyAndReturnIfNil(session); - - MXRoom *room = [MXRoom loadRoomFromStore:fileStore withRoomId:roomID matrixSession:session]; - - // Do not warn for unknown devices. We have cross-signing now - session.crypto.warnOnUnknowDevices = NO; - - [room sendTextMessage:intent.content - success:^(NSString *eventId) { - completeWithCode(INSendMessageIntentResponseCodeSuccess); - } failure:^(NSError *error) { - completeWithCode(INSendMessageIntentResponseCodeFailure); - }]; - - } failure:^(NSError *error) { - completeWithCode(INSendMessageIntentResponseCodeFailure); - }]; - - return; - } + if (isEncrypted) + { + [MXFileStore setPreloadOptions:0]; + + MXSession *session = [[MXSession alloc] initWithMatrixRestClient:account.mxRestClient]; + MXWeakify(session); + [session setStore:fileStore success:^{ + MXStrongifyAndReturnIfNil(session); + + MXRoom *room = [MXRoom loadRoomFromStore:fileStore withRoomId:roomID matrixSession:session]; + + // Do not warn for unknown devices. We have cross-signing now + session.crypto.warnOnUnknowDevices = NO; + + [room sendTextMessage:intent.content + success:^(NSString *eventId) { + completeWithCode(INSendMessageIntentResponseCodeSuccess); + } failure:^(NSError *error) { + completeWithCode(INSendMessageIntentResponseCodeFailure); + }]; + + } failure:^(NSError *error) { + completeWithCode(INSendMessageIntentResponseCodeFailure); + }]; + + return; + } - [account.mxRestClient sendTextMessageToRoom:roomID - text:intent.content - success:^(NSString *eventId) { - completeWithCode(INSendMessageIntentResponseCodeSuccess); - } - failure:^(NSError *error) { - completeWithCode(INSendMessageIntentResponseCodeFailure); - }]; + [account.mxRestClient sendTextMessageToRoom:roomID + text:intent.content + success:^(NSString *eventId) { + completeWithCode(INSendMessageIntentResponseCodeSuccess); + } + failure:^(NSError *error) { + completeWithCode(INSendMessageIntentResponseCodeFailure); + }]; - } - failure:nil]; + }]; } else { @@ -318,7 +317,7 @@ if (account) { MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore asyncRoomsSummaries:^(NSArray> * _Nonnull roomsSummaries) { + [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull roomsSummaries) { // Contains userIds of all users with whom the current user has direct chats // Use set to avoid duplicates @@ -422,7 +421,7 @@ completion(@[[INPersonResolutionResult disambiguationWithPeopleToDisambiguate:persons]]); } } failure:nil]; - } failure:nil]; + }]; } else { From 1e4341ce537f5ff3a967011053dff6af299ad058 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Wed, 20 Oct 2021 18:16:34 +0300 Subject: [PATCH 002/209] Simplify allFetchers array --- .../MatrixSDK/RecentsListService.swift | 43 ++++++------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index cda8f716d..0d9dca602 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -67,35 +67,17 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { ] private var allFetchers: [MXRoomListDataFetcher] { - var result: [MXRoomListDataFetcher] = [] - if let fetcher = invitedRoomListDataFetcher { - result.append(fetcher) - } - if let fetcher = favoritedRoomListDataFetcher { - result.append(fetcher) - } - if let fetcher = directRoomListDataFetcherForHome { - result.append(fetcher) - } - if let fetcher = directRoomListDataFetcherForPeople { - result.append(fetcher) - } - if let fetcher = conversationRoomListDataFetcherForHome { - result.append(fetcher) - } - if let fetcher = conversationRoomListDataFetcherForRooms { - result.append(fetcher) - } - if let fetcher = lowPriorityRoomListDataFetcher { - result.append(fetcher) - } - if let fetcher = serverNoticeRoomListDataFetcher { - result.append(fetcher) - } - if let fetcher = suggestedRoomListDataFetcher { - result.append(fetcher) - } - return result + return [ + invitedRoomListDataFetcher, + favoritedRoomListDataFetcher, + directRoomListDataFetcherForHome, + directRoomListDataFetcherForPeople, + conversationRoomListDataFetcherForHome, + conversationRoomListDataFetcherForRooms, + lowPriorityRoomListDataFetcher, + serverNoticeRoomListDataFetcher, + suggestedRoomListDataFetcher + ].compactMap({ $0 }) } private var visibleFetchers: [MXRoomListDataFetcher] { @@ -127,8 +109,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { if let fetcher = serverNoticeRoomListDataFetcher, fetcherTypes.contains(.serverNotice) { result.append(fetcher) } - if let fetcher = suggestedRoomListDataFetcher, - fetcherTypes.contains(.suggested) { + if let fetcher = suggestedRoomListDataFetcher, fetcherTypes.contains(.suggested) { result.append(fetcher) } return result From 08bb3f263afe766f0f150a1620ea61b7d2643eee Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 2 Nov 2021 16:31:01 +0300 Subject: [PATCH 003/209] Fix async --- .../Common/Recents/Service/MatrixSDK/RecentsListService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 319e4caeb..7d4d7f252 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -350,7 +350,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { let fetchOptions = MXRoomListDataFetchOptions(filterOptions: filterOptions, sortOptions: sortOptions, - async: false) + async: true) let fetcher = session.roomListDataManager.fetcher(withOptions: fetchOptions) if paginate { fetcher.addDelegate(self) From 34b67b46d1f728dc74928e8e34e55098d3ad3e3b Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 2 Nov 2021 16:53:09 +0300 Subject: [PATCH 004/209] Add changelog --- changelog.d/4384.change | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changelog.d/4384.change b/changelog.d/4384.change index 9103529a3..faaccd63e 100644 --- a/changelog.d/4384.change +++ b/changelog.d/4384.change @@ -1 +1,2 @@ -Using mutable room list fetch sort options after chaning them to be a structure. \ No newline at end of file +Using mutable room list fetch sort options after chaning them to be a structure. +Adaptation to MXStore api changes. From 3ad96f4ccb651d3028c7b97b237e2c3fde608564 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 22 Dec 2021 17:25:35 +0100 Subject: [PATCH 005/209] Move timeline cells in dedicated folders. --- .../Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.h | 0 .../Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.m | 0 .../Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.xib | 0 .../Incoming/Clear}/RoomIncomingAttachmentBubbleCell.h | 0 .../Incoming/Clear}/RoomIncomingAttachmentBubbleCell.m | 0 .../Incoming/Clear}/RoomIncomingAttachmentBubbleCell.xib | 0 .../Clear}/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h | 0 .../Clear}/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m | 0 .../RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib | 0 .../Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h | 0 .../Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m | 0 .../Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib | 0 .../Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.h | 0 .../Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.m | 0 .../Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.xib | 0 ...RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h | 0 ...RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m | 0 ...omIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib | 0 .../RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h | 0 .../RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m | 0 ...RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib | 0 .../Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.h | 0 .../Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.m | 0 .../Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.xib | 0 .../Clear}/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h | 0 .../Clear}/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m | 0 .../RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib | 0 .../Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h | 0 .../Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m | 0 .../Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib | 0 .../Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.h | 0 .../Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.m | 0 .../Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.xib | 0 ...RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h | 0 ...RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m | 0 ...omOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib | 0 .../RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h | 0 .../RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m | 0 ...RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib | 0 .../BubbleCells/{ => MessageTyping}/RoomTypingBubbleCell.swift | 0 .../BubbleCells/{ => MessageTyping}/RoomTypingBubbleCell.xib | 0 .../{ => RoomCreation}/RoomCreationCollapsedBubbleCell.h | 0 .../{ => RoomCreation}/RoomCreationCollapsedBubbleCell.m | 0 .../{ => RoomCreation}/RoomCreationCollapsedBubbleCell.xib | 0 .../RoomCreationWithPaginationCollapsedBubbleCell.h | 0 .../RoomCreationWithPaginationCollapsedBubbleCell.m | 0 .../RoomCreationWithPaginationCollapsedBubbleCell.xib | 0 .../BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.h | 0 .../BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.m | 0 .../BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.xib | 0 .../{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.h | 0 .../{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.m | 0 .../{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.xib | 0 .../RoomMembershipCollapsedWithPaginationTitleBubbleCell.h | 0 .../RoomMembershipCollapsedWithPaginationTitleBubbleCell.m | 0 .../RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib | 0 .../{ => RoomMembership}/RoomMembershipExpandedBubbleCell.h | 0 .../{ => RoomMembership}/RoomMembershipExpandedBubbleCell.m | 0 .../{ => RoomMembership}/RoomMembershipExpandedBubbleCell.xib | 0 .../RoomMembershipExpandedWithPaginationTitleBubbleCell.h | 0 .../RoomMembershipExpandedWithPaginationTitleBubbleCell.m | 0 .../RoomMembershipExpandedWithPaginationTitleBubbleCell.xib | 0 .../RoomMembershipWithPaginationTitleBubbleCell.h | 0 .../RoomMembershipWithPaginationTitleBubbleCell.m | 0 .../RoomMembershipWithPaginationTitleBubbleCell.xib | 0 .../BubbleCells/{ => RoomPredecessor}/RoomPredecessorBubbleCell.h | 0 .../BubbleCells/{ => RoomPredecessor}/RoomPredecessorBubbleCell.m | 0 .../{ => RoomPredecessor}/RoomPredecessorBubbleCell.xib | 0 .../BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.h | 0 .../BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.m | 0 .../BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.xib | 0 .../Incoming/Clear}/RoomIncomingTextMsgBubbleCell.h | 0 .../Incoming/Clear}/RoomIncomingTextMsgBubbleCell.m | 0 .../Incoming/Clear}/RoomIncomingTextMsgBubbleCell.xib | 0 .../Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h | 0 .../Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m | 0 .../Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib | 0 ...ncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h | 0 ...ncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m | 0 ...omingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m | 0 .../Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib | 0 .../Incoming/Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.h | 0 .../Incoming/Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.m | 0 .../Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.xib | 0 .../RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h | 0 .../RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m | 0 .../RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib | 0 ...cryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h | 0 ...cryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m | 0 ...yptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m | 0 .../RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib | 0 .../Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.h | 0 .../Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.m | 0 .../Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.xib | 0 .../Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h | 0 .../Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m | 0 .../Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib | 0 ...utgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h | 0 ...utgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m | 0 ...goingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m | 0 .../Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib | 0 .../Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.h | 0 .../Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.m | 0 .../Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.xib | 0 .../RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h | 0 .../RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m | 0 .../RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib | 0 ...cryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h | 0 ...cryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m | 0 ...yptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m | 0 .../RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib | 0 131 files changed, 0 insertions(+), 0 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => EmptyContent}/RoomEmptyBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Incoming/Clear}/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Incoming/Encrypted}/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => FileAttachment/Outgoing/Clear}/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => FileAttachment/Outgoing/Encrypted}/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => MessageTyping}/RoomTypingBubbleCell.swift (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => MessageTyping}/RoomTypingBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationCollapsedBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationCollapsedBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationCollapsedBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationWithPaginationCollapsedBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationWithPaginationCollapsedBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomCreation}/RoomCreationWithPaginationCollapsedBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipExpandedWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomMembership}/RoomMembershipWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomPredecessor}/RoomPredecessorBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomPredecessor}/RoomPredecessorBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => RoomPredecessor}/RoomPredecessorBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => Sticker}/RoomSelectedStickerBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Incoming/Clear}/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Incoming/Encrypted}/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{ => TextMessage/Outgoing/Clear}/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m (100%) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => TextMessage/Outgoing/Encrypted}/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib (100%) diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomEmptyBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/RoomEmptyBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Clear/RoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Encrypted/RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Encrypted/RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTypingBubbleCell.swift b/Riot/Modules/Room/Views/BubbleCells/MessageTyping/RoomTypingBubbleCell.swift similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomTypingBubbleCell.swift rename to Riot/Modules/Room/Views/BubbleCells/MessageTyping/RoomTypingBubbleCell.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTypingBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/MessageTyping/RoomTypingBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomTypingBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/MessageTyping/RoomTypingBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationCollapsedBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationCollapsedBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomCreationWithPaginationCollapsedBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomCreation/RoomCreationWithPaginationCollapsedBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipCollapsedWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipExpandedWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipExpandedWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomMembershipWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomMembership/RoomMembershipWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomPredecessorBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/RoomPredecessor/RoomPredecessorBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomSelectedStickerBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Clear/RoomIncomingTextMsgWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Encrypted/RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Clear/RoomOutgoingTextMsgWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Encrypted/RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.xib From dfb419aba91ba1343750ed445f553acd18e73e2e Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Mon, 27 Dec 2021 16:04:51 +0300 Subject: [PATCH 006/209] Fix store api --- Riot/Modules/MatrixKit/Models/Account/MXKAccount.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index c30867251..0ee38c479 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -1840,7 +1840,7 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; summary.lastMessage.others = [NSMutableDictionary dictionary]; } summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES]; - [self->mxSession.store storeSummaryForRoom:summary.roomId summary:summary]; + [self->mxSession.store.summariesModule storeSummary:summary]; } dispatch_group_leave(dispatchGroup); From 94de6b33e33f0b451e04915952e47dd1495da05e Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 28 Dec 2021 23:18:41 +0300 Subject: [PATCH 007/209] Fix all summaries usage, use summary session if needed in cell data --- .../MatrixKit/Models/RoomList/MXKRecentCellData.m | 9 ++++++++- RiotShareExtension/Shared/ShareDataSource.m | 9 ++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m index b2bfc1885..3bd13a3d2 100644 --- a/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m +++ b/Riot/Modules/MatrixKit/Models/RoomList/MXKRecentCellData.m @@ -46,7 +46,14 @@ - (MXSession *)mxSession { - return dataSource.mxSession; + MXSession *session = dataSource.mxSession; + + if (session == nil) + { + session = roomSummary.mxSession; + } + + return session; } - (NSString*)lastEventDate diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index 29b081683..e63a8d762 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -77,18 +77,21 @@ - (void)loadCellData { - [self.fileStore.summariesModule fetchAllSummaries:^(NSArray *roomsSummaries) { + [self.fileStore.summariesModule fetchAllSummaries:^(NSArray> *roomsSummaries) { NSMutableArray *cellData = [NSMutableArray array]; // Add a fake matrix session to each room summary to provide it a REST client (used to handle correctly the room avatar). MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil]]; - for (MXRoomSummary *roomSummary in roomsSummaries) + for (id roomSummary in roomsSummaries) { if (!roomSummary.hiddenFromUser && roomSummary.roomType == MXRoomTypeRoom) { - [roomSummary setMatrixSession:session]; + if ([roomSummary respondsToSelector:@selector(setMatrixSession:)]) + { + [roomSummary setMatrixSession:session]; + } MXKRecentCellData *recentCellData = [[MXKRecentCellData alloc] initWithRoomSummary:roomSummary dataSource:nil]; From 4f0db984bd672bbe7e273398cac89450263c046c Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Wed, 29 Dec 2021 17:40:09 +0300 Subject: [PATCH 008/209] Adapt from summaries to rooms & little naming fixes --- Riot/Categories/MXSession+Riot.m | 8 ++-- .../OnBoarding/OnBoardingManager.swift | 15 ++++--- .../MatrixKit/Models/Account/MXKAccount.m | 40 ++++++++++--------- .../RoomList/MXKSessionRecentsDataSource.m | 18 +++++---- RiotShareExtension/Shared/ShareDataSource.m | 12 +++--- SiriIntents/IntentHandler.m | 22 +++++----- 6 files changed, 61 insertions(+), 54 deletions(-) diff --git a/Riot/Categories/MXSession+Riot.m b/Riot/Categories/MXSession+Riot.m index faf32bd01..97a74e5b2 100644 --- a/Riot/Categories/MXSession+Riot.m +++ b/Riot/Categories/MXSession+Riot.m @@ -26,15 +26,15 @@ NSUInteger missedDiscussionsCount = 0; // Sum all the rooms with missed notifications. - for (MXRoomSummary *roomSummary in self.roomsSummaries) + for (MXRoom *room in self.rooms) { - NSUInteger notificationCount = roomSummary.notificationCount; + NSUInteger notificationCount = room.summary.notificationCount; // Ignore the regular notification count if the room is in 'mentions only" mode at the Riot level. - if (roomSummary.room.isMentionsOnly) + if (room.isMentionsOnly) { // Only the highlighted missed messages must be considered here. - notificationCount = roomSummary.highlightCount; + notificationCount = room.summary.highlightCount; } if (notificationCount) diff --git a/Riot/Managers/OnBoarding/OnBoardingManager.swift b/Riot/Managers/OnBoarding/OnBoardingManager.swift index c2016019f..dec2287bc 100644 --- a/Riot/Managers/OnBoarding/OnBoardingManager.swift +++ b/Riot/Managers/OnBoarding/OnBoardingManager.swift @@ -81,19 +81,18 @@ final public class OnBoardingManager: NSObject { // MARK: - Private private func isUserJoinedARoom() -> Bool { - guard let roomSummaries = self.session.roomsSummaries() else { - return false - } + var isUserJoinedARoom = false - var isUSerJoinedARoom = false - - for roomSummary in roomSummaries { + for room in session.rooms { + guard let roomSummary = room.summary else { + continue + } if case .join = roomSummary.membership { - isUSerJoinedARoom = true + isUserJoinedARoom = true break } } - return isUSerJoinedARoom + return isUserJoinedARoom } } diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 0ee38c479..26e92d315 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -1826,27 +1826,31 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; dispatch_group_t dispatchGroup = dispatch_group_create(); - for (MXRoomSummary *summary in mxSession.roomsSummaries) + for (MXRoom *room in mxSession.rooms) { - dispatch_group_enter(dispatchGroup); - [summary.mxSession eventWithEventId:summary.lastMessage.eventId - inRoom:summary.roomId - success:^(MXEvent *event) { - - if (event) - { - if (summary.lastMessage.others == nil) + MXRoomSummary *summary = room.summary; + if (summary) + { + dispatch_group_enter(dispatchGroup); + [summary.mxSession eventWithEventId:summary.lastMessage.eventId + inRoom:summary.roomId + success:^(MXEvent *event) { + + if (event) { - summary.lastMessage.others = [NSMutableDictionary dictionary]; + if (summary.lastMessage.others == nil) + { + summary.lastMessage.others = [NSMutableDictionary dictionary]; + } + summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES]; + [self->mxSession.store.summariesModule storeSummary:summary]; } - summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES]; - [self->mxSession.store.summariesModule storeSummary:summary]; - } - - dispatch_group_leave(dispatchGroup); - } failure:^(NSError *error) { - dispatch_group_leave(dispatchGroup); - }]; + + dispatch_group_leave(dispatchGroup); + } failure:^(NSError *error) { + dispatch_group_leave(dispatchGroup); + }]; + } } dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^{ diff --git a/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m b/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m index bf4c600aa..f0f84f5b5 100644 --- a/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m +++ b/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m @@ -311,16 +311,20 @@ static NSTimeInterval const roomSummaryChangeThrottlerDelay = .5; NSDate *startDate = [NSDate date]; - for (MXRoomSummary *roomSummary in self.mxSession.roomsSummaries) + for (MXRoom *room in self.mxSession.rooms) { - // Filter out private rooms with conference users - if (!roomSummary.isConferenceUserRoom // @TODO Abstract this condition with roomSummary.hiddenFromUser - && !roomSummary.hiddenFromUser) + MXRoomSummary *summary = room.summary; + if (summary) { - id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; - if (cellData) + // Filter out private rooms with conference users + if (!summary.isConferenceUserRoom // @TODO Abstract this condition with roomSummary.hiddenFromUser + && !summary.hiddenFromUser) { - [internalCellDataArray addObject:cellData]; + id cellData = [[class alloc] initWithRoomSummary:summary dataSource:self]; + if (cellData) + { + [internalCellDataArray addObject:cellData]; + } } } } diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index e63a8d762..eb993ee05 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -77,23 +77,23 @@ - (void)loadCellData { - [self.fileStore.summariesModule fetchAllSummaries:^(NSArray> *roomsSummaries) { + [self.fileStore.summariesModule fetchAllSummaries:^(NSArray> *summaries) { NSMutableArray *cellData = [NSMutableArray array]; // Add a fake matrix session to each room summary to provide it a REST client (used to handle correctly the room avatar). MXSession *session = [[MXSession alloc] initWithMatrixRestClient:[[MXRestClient alloc] initWithCredentials:self.credentials andOnUnrecognizedCertificateBlock:nil]]; - for (id roomSummary in roomsSummaries) + for (id summary in summaries) { - if (!roomSummary.hiddenFromUser && roomSummary.roomType == MXRoomTypeRoom) + if (!summary.hiddenFromUser && summary.roomType == MXRoomTypeRoom) { - if ([roomSummary respondsToSelector:@selector(setMatrixSession:)]) + if ([summary respondsToSelector:@selector(setMatrixSession:)]) { - [roomSummary setMatrixSession:session]; + [summary setMatrixSession:session]; } - MXKRecentCellData *recentCellData = [[MXKRecentCellData alloc] initWithRoomSummary:roomSummary dataSource:nil]; + MXKRecentCellData *recentCellData = [[MXKRecentCellData alloc] initWithRoomSummary:summary dataSource:nil]; [cellData addObject:recentCellData]; } diff --git a/SiriIntents/IntentHandler.m b/SiriIntents/IntentHandler.m index 99f9910fc..0c93f08aa 100644 --- a/SiriIntents/IntentHandler.m +++ b/SiriIntents/IntentHandler.m @@ -215,15 +215,15 @@ { MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject; MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull roomsSummaries) { + [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull summaries) { NSString *roomID = person.customIdentifier; BOOL isEncrypted = NO; - for (id roomSummary in roomsSummaries) + for (id summary in summaries) { - if ([roomSummary.roomId isEqualToString:roomID]) + if ([summary.roomId isEqualToString:roomID]) { - isEncrypted = roomSummary.isEncrypted; + isEncrypted = summary.isEncrypted; break; } } @@ -315,7 +315,7 @@ if (account) { MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull roomsSummaries) { + [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull summaries) { // Contains userIds of all users with whom the current user has direct chats // Use set to avoid duplicates @@ -324,27 +324,27 @@ // Contains room summaries for all direct rooms connected with particular userId NSMutableDictionary> *> *roomSummaries = [NSMutableDictionary dictionary]; - for (id summary in roomsSummaries) + for (id summary in summaries) { // TODO: We also need to check if joined room members count equals 2 // It is pointlessly to save rooms with 1 joined member or room with more than 2 joined members if (summary.isDirect) { - NSString *diretUserId = summary.directUserId; + NSString *directUserId = summary.directUserId; // Collect room summaries only for specified user - if (selectedUserId && ![diretUserId isEqualToString:selectedUserId]) + if (selectedUserId && ![directUserId isEqualToString:selectedUserId]) continue; // Save userId - [directUserIds addObject:diretUserId]; + [directUserIds addObject:directUserId]; // Save associated with diretUserId room summary - NSMutableArray> *userRoomSummaries = roomSummaries[diretUserId]; + NSMutableArray> *userRoomSummaries = roomSummaries[directUserId]; if (userRoomSummaries) [userRoomSummaries addObject:summary]; else - roomSummaries[diretUserId] = [NSMutableArray arrayWithObject:summary]; + roomSummaries[directUserId] = [NSMutableArray arrayWithObject:summary]; } } From f9f6bc00ae4f4d3b665ac2b0af0268f52a379330 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 3 Jan 2022 18:16:24 +0100 Subject: [PATCH 009/209] Add RoomTimelineStyle enum that represents the room timeline styles available. --- .../Views/BubbleCells/RoomTimelineStyle.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift new file mode 100644 index 000000000..d7c72cea4 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift @@ -0,0 +1,23 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Represents the room timeline styles available +enum RoomTimelineStyle { + case plain + case bubble +} From 31f2698e22378a18c811fdd24e627553f57f60b5 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 3 Jan 2022 18:16:49 +0100 Subject: [PATCH 010/209] Add build settings for timeline style configuration. --- Config/BuildSettings.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index d07f6efb5..5031afdf5 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -297,6 +297,13 @@ final class BuildSettings: NSObject { static let roomScreenAllowMediaLibraryAction: Bool = true static let roomScreenAllowStickerAction: Bool = true static let roomScreenAllowFilesAction: Bool = true + + // Timeline style + static let roomScreenAllowTimelineStyleConfiguration: Bool = false + static let roomScreenTimelineDefaultStyle: RoomTimelineStyle = .plain + static var roomScreenEnableMessageBubblesByDefault: Bool { + return self.roomScreenTimelineDefaultStyle == .bubble + } /// Allow split view detail view stacking static let allowSplitViewDetailsScreenStacking: Bool = true From a76629744c854c503ed9ba28c4122fc2e2bda34f Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 3 Jan 2022 18:18:37 +0100 Subject: [PATCH 011/209] Update targets for new BuildSettings properties. --- RiotNSE/target.yml | 1 + RiotShareExtension/target.yml | 1 + RiotTests/target.yml | 1 + SiriIntents/target.yml | 1 + 4 files changed, 4 insertions(+) diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index f01b619a3..88dde20ff 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -65,3 +65,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index 7f32196f4..d427bd75d 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -72,3 +72,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift diff --git a/RiotTests/target.yml b/RiotTests/target.yml index b07bd2911..fc7443941 100644 --- a/RiotTests/target.yml +++ b/RiotTests/target.yml @@ -64,3 +64,4 @@ targets: - path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift - path: ../Riot/Managers/KeyValueStorage/ - path: ../Riot/PropertyWrappers/UserDefaultsBackedPropertyWrapper.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index 05aea0ea9..cc71dacd7 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -54,3 +54,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift From 0ecdfb106d1ad4084b67f1665b547f6484e30a12 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 3 Jan 2022 18:30:59 +0100 Subject: [PATCH 012/209] Settings: Add enable room message bubbles parameter. --- Riot/Assets/en.lproj/Vector.strings | 2 ++ Riot/Generated/Strings.swift | 4 +++ Riot/Managers/Settings/RiotSettings.swift | 3 ++ .../Modules/Settings/SettingsViewController.m | 30 +++++++++++++++++-- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 119391d9a..461e49618 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -654,6 +654,8 @@ Tap the + to start adding people."; "settings_show_NSFW_public_rooms" = "Show NSFW public rooms"; +"settings_enable_room_message_bubbles" = "Message bubbles"; + // Security settings "security_settings_title" = "Security"; "security_settings_crypto_sessions" = "MY SESSIONS"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index af25f0458..ab91f906b 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -4499,6 +4499,10 @@ public class VectorL10n: NSObject { public static var settingsEnableRageshake: String { return VectorL10n.tr("Vector", "settings_enable_rageshake") } + /// Message bubbles + public static var settingsEnableRoomMessageBubbles: String { + return VectorL10n.tr("Vector", "settings_enable_room_message_bubbles") + } /// Encrypted direct messages public static var settingsEncryptedDirectMessages: String { return VectorL10n.tr("Vector", "settings_encrypted_direct_messages") diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 3aa22a842..dd030c640 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -191,6 +191,9 @@ final class RiotSettings: NSObject { @UserDefault(key: "roomScreenShowsURLPreviews", defaultValue: true, storage: defaults) var roomScreenShowsURLPreviews + @UserDefault(key: "roomScreenEnableMessageBubbles", defaultValue: BuildSettings.roomScreenEnableMessageBubblesByDefault, storage: defaults) + var roomScreenEnableMessageBubbles + // MARK: - Room Contextual Menu @UserDefault(key: "roomContextualMenuShowMoreOptionForMessages", defaultValue: BuildSettings.roomContextualMenuShowMoreOptionForMessages, storage: defaults) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 9aeaa77b7..6c4734514 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -127,7 +127,8 @@ enum { enum { USER_INTERFACE_LANGUAGE_INDEX = 0, - USER_INTERFACE_THEME_INDEX + USER_INTERFACE_THEME_INDEX, + USER_INTERFACE_TIMELINE_STYLE_INDEX }; enum @@ -499,9 +500,16 @@ TableViewSectionsDelegate> } Section *sectionUserInterface = [Section sectionWithTag:SECTION_TAG_USER_INTERFACE]; + sectionUserInterface.headerTitle = [VectorL10n settingsUserInterface]; + [sectionUserInterface addRowWithTag:USER_INTERFACE_LANGUAGE_INDEX]; [sectionUserInterface addRowWithTag:USER_INTERFACE_THEME_INDEX]; - sectionUserInterface.headerTitle = [VectorL10n settingsUserInterface]; + + if (BuildSettings.roomScreenAllowTimelineStyleConfiguration) + { + [sectionUserInterface addRowWithTag:USER_INTERFACE_TIMELINE_STYLE_INDEX]; + } + [tmpSections addObject: sectionUserInterface]; Section *sectionAdvanced = [Section sectionWithTag:SECTION_TAG_ADVANCED]; @@ -2196,6 +2204,19 @@ TableViewSectionsDelegate> [cell vc_setAccessoryDisclosureIndicatorWithCurrentTheme]; cell.selectionStyle = UITableViewCellSelectionStyleDefault; } + else if (row == USER_INTERFACE_TIMELINE_STYLE_INDEX) + { + MXKTableViewCellWithLabelAndSwitch* labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; + + labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsEnableRoomMessageBubbles]; + + labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.roomScreenEnableMessageBubbles; + labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; + labelAndSwitchCell.mxkSwitch.enabled = YES; + [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleEnableRoomMessageBubbles:) forControlEvents:UIControlEventTouchUpInside]; + + cell = labelAndSwitchCell; + } } else if (section == SECTION_TAG_IGNORED_USERS) { @@ -3839,6 +3860,11 @@ TableViewSectionsDelegate> RiotSettings.shared.showNSFWPublicRooms = sender.isOn; } +- (void)toggleEnableRoomMessageBubbles:(UISwitch *)sender +{ + RiotSettings.shared.roomScreenEnableMessageBubbles = sender.isOn; +} + #pragma mark - TextField listener - (IBAction)textFieldDidChange:(id)sender From 4d4cd4ca322603c410008e8858a024d411f8cb6c Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:27:19 +0300 Subject: [PATCH 013/209] Remove all logic in the deprecated data source --- .../RoomList/MXKSessionRecentsDataSource.m | 498 +----------------- 1 file changed, 13 insertions(+), 485 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m b/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m index f0f84f5b5..afee08a82 100644 --- a/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m +++ b/Riot/Modules/MatrixKit/Models/RoomList/MXKSessionRecentsDataSource.m @@ -25,52 +25,6 @@ #pragma mark - Constant definitions NSString *const kMXKRecentCellIdentifier = @"kMXKRecentCellIdentifier"; -static NSTimeInterval const roomSummaryChangeThrottlerDelay = .5; - - -@interface MXKSessionRecentsDataSource () -{ - MXKRoomDataSourceManager *roomDataSourceManager; - - /** - Internal array used to regulate change notifications. - Cell data changes are stored instantly in this array. - These changes are reported to the delegate only if no server sync is in progress. - */ - NSMutableArray *internalCellDataArray; - - /** - Store the current search patterns list. - */ - NSArray* searchPatternsList; - - /** - Do not react on every summary change - */ - MXThrottler *roomSummaryChangeThrottler; - - /** - Last received suggested rooms per space ID - */ - NSMutableDictionary *> *lastSuggestedRooms; - - /** - Event listener of the current space used to update the UI if an event occurs. - */ - id spaceEventsListener; - - /** - Observer used to reload data when the space service is initialised - */ - id spaceServiceDidInitialiseObserver; -} - -/** - Additional suggestedRooms related to the current selected Space - */ -@property (nonatomic, strong) NSArray *suggestedRooms; - -@end @implementation MXKSessionRecentsDataSource @@ -79,478 +33,52 @@ static NSTimeInterval const roomSummaryChangeThrottlerDelay = .5; self = [super initWithMatrixSession:matrixSession]; if (self) { - roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mxSession]; + // Update here data source state + if (state != MXKDataSourceStateReady) + { + state = MXKDataSourceStateReady; + if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)]) + { + [self.delegate dataSource:self didStateChange:state]; + } + } - internalCellDataArray = [NSMutableArray array]; - filteredCellDataArray = nil; - - lastSuggestedRooms = [NSMutableDictionary new]; - - // Set default data and view classes - [self registerCellDataClass:MXKRecentCellData.class forCellIdentifier:kMXKRecentCellIdentifier]; - - roomSummaryChangeThrottler = [[MXThrottler alloc] initWithMinimumDelay:roomSummaryChangeThrottlerDelay]; - - [[MXKAppSettings standardAppSettings] addObserver:self forKeyPath:@"showAllRoomsInHomeSpace" options:0 context:nil]; + // And inform the delegate about the update + [self.delegate dataSource:self didCellChange:nil]; } return self; } -- (void)destroy -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKRoomDataSourceSyncStatusChanged object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionNewRoomNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil]; - - if (spaceServiceDidInitialiseObserver) { - [[NSNotificationCenter defaultCenter] removeObserver:spaceServiceDidInitialiseObserver]; - } - - [roomSummaryChangeThrottler cancelAll]; - roomSummaryChangeThrottler = nil; - - cellDataArray = nil; - internalCellDataArray = nil; - filteredCellDataArray = nil; - lastSuggestedRooms = nil; - - searchPatternsList = nil; - - [[MXKAppSettings standardAppSettings] removeObserver:self forKeyPath:@"showAllRoomsInHomeSpace" context:nil]; - - [super destroy]; -} - -- (void)didMXSessionStateChange -{ - if (MXSessionStateStoreDataReady <= self.mxSession.state) - { - // Check whether some data have been already load - if (0 == internalCellDataArray.count) - { - [self loadData]; - } - else if (!roomDataSourceManager.isServerSyncInProgress) - { - // Sort cell data and notify the delegate - [self sortCellDataAndNotifyChanges]; - } - } -} - -- (void)setCurrentSpace:(MXSpace *)currentSpace -{ - if (_currentSpace == currentSpace) - { - return; - } - - if (_currentSpace && spaceEventsListener) - { - [_currentSpace.room removeListener:spaceEventsListener]; - } - - _currentSpace = currentSpace; - - self.suggestedRooms = _currentSpace ? lastSuggestedRooms[_currentSpace.spaceId] : nil; - [self updateSuggestedRooms]; - - MXWeakify(self); - spaceEventsListener = [self.currentSpace.room listenToEvents:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { - MXStrongifyAndReturnIfNil(self); - [self updateSuggestedRooms]; - }]; -} - --(void)setSuggestedRooms:(NSArray *)suggestedRooms -{ - _suggestedRooms = suggestedRooms; - [self loadData]; -} - --(void)updateSuggestedRooms -{ - if (self.currentSpace) - { - NSString *currentSpaceId = self.currentSpace.spaceId; - MXWeakify(self); - [self.mxSession.spaceService getSpaceChildrenForSpaceWithId:currentSpaceId suggestedOnly:YES limit:5 maxDepth:1 paginationToken:nil success:^(MXSpaceChildrenSummary * _Nonnull childrenSummary) { - MXLogDebug(@"[MXKSessionRecentsDataSource] getSpaceChildrenForSpaceWithId %@: %ld found", self.currentSpace.spaceId, childrenSummary.childInfos.count); - MXStrongifyAndReturnIfNil(self); - self->lastSuggestedRooms[currentSpaceId] = childrenSummary.childInfos; - if ([self.currentSpace.spaceId isEqual:currentSpaceId]) { - self.suggestedRooms = childrenSummary.childInfos; - } - } failure:^(NSError * _Nonnull error) { - MXLogError(@"[MXKSessionRecentsDataSource] getSpaceChildrenForSpaceWithId failed with error: %@", error); - }]; - } -} - #pragma mark - - (NSInteger)numberOfCells { - if (filteredCellDataArray) - { - return filteredCellDataArray.count; - } - return cellDataArray.count; + return 0; } - (BOOL)hasUnread { - // Check all current cells - // Use numberOfRowsInSection methods so that we take benefit of the filtering - for (NSUInteger i = 0; i < self.numberOfCells; i++) - { - id cellData = [self cellDataAtIndex:i]; - if (cellData.hasUnread) - { - return YES; - } - } return NO; } - (void)searchWithPatterns:(NSArray*)patternsList { - if (patternsList.count) - { - searchPatternsList = patternsList; - - if (filteredCellDataArray) - { - [filteredCellDataArray removeAllObjects]; - } - else - { - filteredCellDataArray = [NSMutableArray arrayWithCapacity:cellDataArray.count]; - } - - for (id cellData in cellDataArray) - { - for (NSString* pattern in patternsList) - { - if (cellData.roomDisplayname && [cellData.roomDisplayname rangeOfString:pattern options:NSCaseInsensitiveSearch].location != NSNotFound) - { - [filteredCellDataArray addObject:cellData]; - break; - } - } - } - } - else - { - filteredCellDataArray = nil; - searchPatternsList = nil; - } - - [self.delegate dataSource:self didCellChange:nil]; } - (id)cellDataAtIndex:(NSInteger)index { - if (filteredCellDataArray) - { - if (index < filteredCellDataArray.count) - { - return filteredCellDataArray[index]; - } - } - else if (index < cellDataArray.count) - { - return cellDataArray[index]; - } - return nil; } - (CGFloat)cellHeightAtIndex:(NSInteger)index { - if (self.delegate) - { - id cellData = [self cellDataAtIndex:index]; - - Class class = [self.delegate cellViewClassForCellData:cellData]; - return [class heightForCellData:cellData withMaximumWidth:0]; - } - return 0; } -#pragma mark - Events processing - -/** - Filtering in this method won't have any effect anymore. This class is not maintained. - */ -- (void)loadData -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXRoomSummaryDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXKRoomDataSourceSyncStatusChanged object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionNewRoomNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidLeaveRoomNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDirectRoomsDidChangeNotification object:nil]; - - if (!self.mxSession.spaceService.isInitialised && !spaceServiceDidInitialiseObserver) { - MXWeakify(self); - spaceServiceDidInitialiseObserver = [[NSNotificationCenter defaultCenter] addObserverForName:MXSpaceService.didInitialise object:self.mxSession.spaceService queue:nil usingBlock:^(NSNotification * _Nonnull note) { - MXStrongifyAndReturnIfNil(self); - [self loadData]; - }]; - } - - // Reset the table - [internalCellDataArray removeAllObjects]; - - // Retrieve the MXKCellData class to manage the data - Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier]; - NSAssert([class conformsToProtocol:@protocol(MXKRecentCellDataStoring)], @"MXKSessionRecentsDataSource only manages MXKCellData that conforms to MXKRecentCellDataStoring protocol"); - - NSDate *startDate = [NSDate date]; - - for (MXRoom *room in self.mxSession.rooms) - { - MXRoomSummary *summary = room.summary; - if (summary) - { - // Filter out private rooms with conference users - if (!summary.isConferenceUserRoom // @TODO Abstract this condition with roomSummary.hiddenFromUser - && !summary.hiddenFromUser) - { - id cellData = [[class alloc] initWithRoomSummary:summary dataSource:self]; - if (cellData) - { - [internalCellDataArray addObject:cellData]; - } - } - } - } - - for (MXSpaceChildInfo *childInfo in _suggestedRooms) - { - id summary = [[MXRoomSummary alloc] initWithSpaceChildInfo:childInfo]; - id cellData = [[class alloc] initWithRoomSummary:summary - dataSource:self]; - if (cellData) - { - [internalCellDataArray addObject:cellData]; - } - } - - MXLogDebug(@"[MXKSessionRecentsDataSource] Loaded %tu recents in %.3fms", self.mxSession.rooms.count, [[NSDate date] timeIntervalSinceDate:startDate] * 1000); - - // Make sure all rooms have a last message - [self.mxSession fixRoomsSummariesLastMessage]; - - // Report loaded array except if sync is in progress - if (!roomDataSourceManager.isServerSyncInProgress) - { - [self sortCellDataAndNotifyChanges]; - } - - // Listen to MXSession rooms count changes - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionHaveNewRoom:) name:kMXSessionNewRoomNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionDidLeaveRoom:) name:kMXSessionDidLeaveRoomNotification object:nil]; - - // Listen to the direct rooms list - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didDirectRoomsChange:) name:kMXSessionDirectRoomsDidChangeNotification object:nil]; - - // Listen to MXRoomSummary - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRoomSummaryChanged:) name:kMXRoomSummaryDidChangeNotification object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionStateChange) name:kMXKRoomDataSourceSyncStatusChanged object:nil]; -} - -- (void)didDirectRoomsChange:(NSNotification *)notif -{ - // Inform the delegate about the update - [self.delegate dataSource:self didCellChange:nil]; -} - -- (void)didRoomSummaryChanged:(NSNotification *)notif -{ - [roomSummaryChangeThrottler throttle:^{ - [self didRoomSummaryChanged2:notif]; - }]; -} - -- (void)didRoomSummaryChanged2:(NSNotification *)notif -{ - MXRoomSummary *roomSummary = notif.object; - if (roomSummary.mxSession == self.mxSession && internalCellDataArray.count) - { - // Find the index of the related cell data - NSInteger index = NSNotFound; - for (index = 0; index < internalCellDataArray.count; index++) - { - id theRoomData = [internalCellDataArray objectAtIndex:index]; - if (theRoomData.roomSummary == roomSummary) - { - break; - } - } - - if (index < internalCellDataArray.count) - { - if (roomSummary.hiddenFromUser) - { - [internalCellDataArray removeObjectAtIndex:index]; - } - else - { - // Create a new instance to not modify the content of 'cellDataArray' (the copy is not a deep copy). - Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier]; - id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; - if (cellData) - { - [internalCellDataArray replaceObjectAtIndex:index withObject:cellData]; - } - } - - // Report change except if sync is in progress - if (!roomDataSourceManager.isServerSyncInProgress) - { - [self sortCellDataAndNotifyChanges]; - } - } - else - { - MXLogDebug(@"[MXKSessionRecentsDataSource] didRoomLastMessageChanged: Cannot find the changed room summary for %@ (%@). It is probably not managed by this recents data source", roomSummary.roomId, roomSummary); - } - } - else - { - // Inform the delegate that all the room summaries have been updated. - [self.delegate dataSource:self didCellChange:nil]; - } -} - -- (void)didMXSessionHaveNewRoom:(NSNotification *)notif -{ - MXSession *mxSession = notif.object; - if (mxSession == self.mxSession) - { - NSString *roomId = notif.userInfo[kMXSessionNotificationRoomIdKey]; - - // Add the room if there is not yet a cell for it - id roomData = [self cellDataWithRoomId:roomId]; - if (nil == roomData) - { - MXLogDebug(@"MXKSessionRecentsDataSource] Add newly joined room: %@", roomId); - - // Retrieve the MXKCellData class to manage the data - Class class = [self cellDataClassForCellIdentifier:kMXKRecentCellIdentifier]; - - MXRoomSummary *roomSummary = [mxSession roomSummaryWithRoomId:roomId]; - id cellData = [[class alloc] initWithRoomSummary:roomSummary dataSource:self]; - if (cellData) - { - [internalCellDataArray addObject:cellData]; - - // Report change except if sync is in progress - if (!roomDataSourceManager.isServerSyncInProgress) - { - [self sortCellDataAndNotifyChanges]; - } - } - } - } -} - -- (void)didMXSessionDidLeaveRoom:(NSNotification *)notif -{ - MXSession *mxSession = notif.object; - if (mxSession == self.mxSession) - { - NSString *roomId = notif.userInfo[kMXSessionNotificationRoomIdKey]; - id roomData = [self cellDataWithRoomId:roomId]; - - if (roomData) - { - MXLogDebug(@"MXKSessionRecentsDataSource] Remove left room: %@", roomId); - - [internalCellDataArray removeObject:roomData]; - - // Report change except if sync is in progress - if (!roomDataSourceManager.isServerSyncInProgress) - { - [self sortCellDataAndNotifyChanges]; - } - } - } -} - -// Order cells -- (void)sortCellDataAndNotifyChanges -{ - // Order them by origin_server_ts - [internalCellDataArray sortUsingComparator:^NSComparisonResult(id cellData1, id cellData2) - { - return [cellData1.roomSummary.lastMessage compareOriginServerTs:cellData2.roomSummary.lastMessage]; - }]; - - // Snapshot the cell data array - cellDataArray = [internalCellDataArray copy]; - - // Update search result if any - if (searchPatternsList) - { - [self searchWithPatterns:searchPatternsList]; - } - - // Update here data source state - if (state != MXKDataSourceStateReady) - { - state = MXKDataSourceStateReady; - if (self.delegate && [self.delegate respondsToSelector:@selector(dataSource:didStateChange:)]) - { - [self.delegate dataSource:self didStateChange:state]; - } - } - - // And inform the delegate about the update - [self.delegate dataSource:self didCellChange:nil]; -} - // Find the cell data that stores information about the given room id - (id)cellDataWithRoomId:(NSString*)roomId { - id theRoomData; - - NSMutableArray *dataArray = internalCellDataArray; - if (!roomDataSourceManager.isServerSyncInProgress) - { - dataArray = cellDataArray; - } - - for (id roomData in dataArray) - { - if ([roomData.roomSummary.roomId isEqualToString:roomId]) - { - theRoomData = roomData; - break; - } - } - return theRoomData; -} - -#pragma mark - KVO - -- (void)observeValueForKeyPath:(NSString *)keyPath - ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context -{ - if (object == [MXKAppSettings standardAppSettings] && [keyPath isEqualToString:@"showAllRoomsInHomeSpace"]) - { - if (self.currentSpace == nil) - { - [self loadData]; - } - } + return nil; } @end From 22a41a1f897ad12a9fed8499e8b6bd229047c1d2 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:29:26 +0300 Subject: [PATCH 014/209] Adapt to counts api changes --- .../Recents/DataSources/RecentsDataSource.m | 27 ++++++++++--------- .../MatrixSDK/RecentsListService.swift | 12 ++++----- .../Service/Mock/MockRoomListData.swift | 2 +- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 82b5823b2..1cac2305a 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -606,17 +606,17 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou if (section == favoritesSection) { - count = self.favoriteCellDataArray.count; + count = self.recentsListService.favoritedRoomListData.counts.total.numberOfRooms; title = [VectorL10n roomRecentsFavouritesSection]; } else if (section == peopleSection) { - count = self.peopleCellDataArray.count; + count = self.recentsListService.peopleRoomListData.counts.total.numberOfRooms; title = [VectorL10n roomRecentsPeopleSection]; } else if (section == conversationSection) { - count = self.conversationCellDataArray.count; + count = self.recentsListService.conversationRoomListData.counts.total.numberOfRooms; if (_recentsDataSourceMode == RecentsDataSourceModePeople) { @@ -633,17 +633,17 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou } else if (section == lowPrioritySection) { - count = self.lowPriorityCellDataArray.count; + count = self.recentsListService.lowPriorityRoomListData.counts.total.numberOfRooms; title = [VectorL10n roomRecentsLowPrioritySection]; } else if (section == serverNoticeSection) { - count = self.serverNoticeCellDataArray.count; + count = self.recentsListService.serverNoticeRoomListData.counts.total.numberOfRooms; title = [VectorL10n roomRecentsServerNoticeSection]; } else if (section == invitesSection) { - count = self.invitesCellDataArray.count; + count = self.recentsListService.invitedRoomListData.counts.total.numberOfRooms; if (_recentsDataSourceMode == RecentsDataSourceModePeople) { @@ -656,7 +656,7 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou } else if (section == suggestedRoomsSection) { - count = self.suggestedRoomCellDataArray.count; + count = self.recentsListService.suggestedRoomListData.counts.total.numberOfRooms; title = [VectorL10n roomRecentsSuggestedRoomsSection]; } @@ -714,26 +714,29 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou counts = self.recentsListService.suggestedRoomListData.counts; } - if (counts.numberOfNotifications) + NSUInteger numberOfNotifications = counts.total.numberOfNotifications; + NSUInteger numberOfHighlights = counts.total.numberOfHighlights; + + if (numberOfNotifications) { UILabel *missedNotifAndUnreadBadgeLabel = [[UILabel alloc] init]; missedNotifAndUnreadBadgeLabel.textColor = ThemeService.shared.theme.baseTextPrimaryColor; missedNotifAndUnreadBadgeLabel.font = [UIFont boldSystemFontOfSize:14]; - if (counts.numberOfNotifications > 1000) + if (numberOfNotifications > 1000) { - CGFloat value = counts.numberOfNotifications / 1000.0; + CGFloat value = numberOfNotifications / 1000.0; missedNotifAndUnreadBadgeLabel.text = [VectorL10n largeBadgeValueKFormat:value]; } else { - missedNotifAndUnreadBadgeLabel.text = [NSString stringWithFormat:@"%tu", counts.numberOfNotifications]; + missedNotifAndUnreadBadgeLabel.text = [NSString stringWithFormat:@"%tu", numberOfNotifications]; } [missedNotifAndUnreadBadgeLabel sizeToFit]; CGFloat bgViewWidth = missedNotifAndUnreadBadgeLabel.frame.size.width + 18; - BOOL highlight = counts.numberOfHighlights > 0; + BOOL highlight = numberOfHighlights > 0; missedNotifAndUnreadBadgeBgView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bgViewWidth, 20)]; [missedNotifAndUnreadBadgeBgView.layer setCornerRadius:10]; missedNotifAndUnreadBadgeBgView.backgroundColor = highlight ? ThemeService.shared.theme.noticeColor : ThemeService.shared.theme.noticeSecondaryColor; diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index ae95b12d0..7e40137e8 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -199,24 +199,24 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } public var favoritedMissedDiscussionsCount: DiscussionsCount { - guard let data = favoritedRoomListDataFetcher?.data else { + guard let totalCounts = favoritedRoomListDataFetcher?.data?.counts.total else { return .zero } - return DiscussionsCount(withRoomListDataCounts: data.counts) + return DiscussionsCount(withRoomListDataCounts: totalCounts) } public var peopleMissedDiscussionsCount: DiscussionsCount { - guard let data = directRoomListDataFetcherForPeople?.data else { + guard let totalCounts = directRoomListDataFetcherForPeople?.data?.counts.total else { return .zero } - return DiscussionsCount(withRoomListDataCounts: data.counts) + return DiscussionsCount(withRoomListDataCounts: totalCounts) } public var conversationMissedDiscussionsCount: DiscussionsCount { - guard let data = conversationRoomListDataFetcherForRooms?.data else { + guard let totalCounts = conversationRoomListDataFetcherForRooms?.data?.counts.total else { return .zero } - return DiscussionsCount(withRoomListDataCounts: data.counts) + return DiscussionsCount(withRoomListDataCounts: totalCounts) } public var totalVisibleItemCount: Int { diff --git a/Riot/Modules/Common/Recents/Service/Mock/MockRoomListData.swift b/Riot/Modules/Common/Recents/Service/Mock/MockRoomListData.swift index 90d7efdef..ef0a2742b 100644 --- a/Riot/Modules/Common/Recents/Service/Mock/MockRoomListData.swift +++ b/Riot/Modules/Common/Recents/Service/Mock/MockRoomListData.swift @@ -22,7 +22,7 @@ public class MockRoomListData: MXRoomListData { public init(withRooms rooms: [MXRoomSummaryProtocol]) { super.init(rooms: rooms, counts: MXStoreRoomListDataCounts(withRooms: rooms, - totalRoomsCount: rooms.count), + total: nil), paginationOptions: .none) } From 4c69041e91caacb97dcfc9785ecaa9614d18a2fe Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:30:12 +0300 Subject: [PATCH 015/209] Implement pagination in recents list service --- .../MatrixSDK/RecentsListService.swift | 58 ++++++++++++++++++- .../Service/Mock/MockRecentsListService.swift | 6 +- .../Service/RecentsListServiceDelegate.swift | 8 ++- .../Service/RecentsListServiceProtocol.swift | 5 ++ .../Service/RecentsListServiceSection.swift | 28 +++++++++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 7e40137e8..85f0ba6df 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -223,6 +223,21 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return visibleFetchers.reduce(0, { $0 + ($1.data?.counts.numberOfRooms ?? 0) }) } + public func paginate(inSection section: RecentsListServiceSection) { + guard let fetcher = fetcher(forSection: section) else { + return + } + guard let data = fetcher.data else { + // first page is not fetched yet + return + } + guard data.paginationOptions != .none else { + // pagination is not enabled + return + } + fetcher.paginate() + } + public func updateMode(_ mode: RecentsDataSourceMode) { self.mode = mode if let fetcher = favoritedRoomListDataFetcher { @@ -341,6 +356,44 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { return fetcherTypesForMode[mode]?.contains(.suggested) ?? false } + private func fetcher(forSection section: RecentsListServiceSection) -> MXRoomListDataFetcher? { + switch section { + case .invited: + return invitedRoomListDataFetcher + case .favorited: + return favoritedRoomListDataFetcher + case .people: + return directRoomListDataFetcher + case .conversation: + return conversationRoomListDataFetcher + case .lowPriority: + return lowPriorityRoomListDataFetcher + case .serverNotice: + return serverNoticeRoomListDataFetcher + case .suggested: + return suggestedRoomListDataFetcher + } + } + + private func section(forFetcher fetcher: MXRoomListDataFetcher) -> RecentsListServiceSection? { + if fetcher === invitedRoomListDataFetcher { + return .invited + } else if fetcher === favoritedRoomListDataFetcher { + return .favorited + } else if fetcher === directRoomListDataFetcher { + return .people + } else if fetcher === conversationRoomListDataFetcher { + return .conversation + } else if fetcher === lowPriorityRoomListDataFetcher { + return .lowPriority + } else if fetcher === serverNoticeRoomListDataFetcher { + return .serverNotice + } else if fetcher === suggestedRoomListDataFetcher { + return .suggested + } + return nil + } + private func createCommonRoomListDataFetcher(withDataTypes dataTypes: MXRoomSummaryDataTypes = [], onlySuggested: Bool = false, paginate: Bool = true) -> MXRoomListDataFetcher { @@ -454,7 +507,10 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } private func notifyDataChange(on fetcher: MXRoomListDataFetcher) { - multicastDelegate.invoke({ $0.serviceDidChangeData(self) }) + if let section = section(forFetcher: fetcher) { + multicastDelegate.invoke { $0.recentsListServiceDidChangeData?(self, forSection: section) } + } + multicastDelegate.invoke { $0.recentsListServiceDidChangeData?(self) } } deinit { diff --git a/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift b/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift index 6be38a676..94cc9d835 100644 --- a/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/Mock/MockRecentsListService.swift @@ -170,6 +170,10 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { } } + public func paginate(inSection section: RecentsListServiceSection) { + // no-op + } + public func updateMode(_ mode: RecentsDataSourceMode) { self.mode = mode notifyDataChange() @@ -210,7 +214,7 @@ public class MockRecentsListService: NSObject, RecentsListServiceProtocol { } private func notifyDataChange() { - multicastDelegate.invoke({ $0.serviceDidChangeData(self) }) + multicastDelegate.invoke({ $0.recentsListServiceDidChangeData?(self) }) } } diff --git a/Riot/Modules/Common/Recents/Service/RecentsListServiceDelegate.swift b/Riot/Modules/Common/Recents/Service/RecentsListServiceDelegate.swift index a2afaf599..920bf6120 100644 --- a/Riot/Modules/Common/Recents/Service/RecentsListServiceDelegate.swift +++ b/Riot/Modules/Common/Recents/Service/RecentsListServiceDelegate.swift @@ -21,5 +21,11 @@ public protocol RecentsListServiceDelegate: AnyObject { /// Delegate method to be called when service data updated /// - Parameter service: service object - func serviceDidChangeData(_ service: RecentsListServiceProtocol) + @objc optional func recentsListServiceDidChangeData(_ service: RecentsListServiceProtocol) + + /// Delegate method to be called when a specific section data updated. Called for each updated section before `recentsListServiceDidChangeData` if implemented. + /// - Parameter service: service object + /// - Parameter section: updated section + @objc optional func recentsListServiceDidChangeData(_ service: RecentsListServiceProtocol, + forSection section: RecentsListServiceSection) } diff --git a/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift b/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift index 154cf2e21..72ab08f08 100644 --- a/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift +++ b/Riot/Modules/Common/Recents/Service/RecentsListServiceProtocol.swift @@ -87,6 +87,11 @@ public protocol RecentsListServiceProtocol { /// Stop service. Do not use after stopping. func stop() + // MARK: Pagination + + /// Paginate in the given section. + func paginate(inSection section: RecentsListServiceSection) + // MARK: - Delegate /// Add delegate instance for the service diff --git a/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift b/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift new file mode 100644 index 000000000..99ef11353 --- /dev/null +++ b/Riot/Modules/Common/Recents/Service/RecentsListServiceSection.swift @@ -0,0 +1,28 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +@objc +public enum RecentsListServiceSection: Int { + case invited + case favorited + case people + case conversation + case lowPriority + case serverNotice + case suggested +} From a6a17554e9a0ba205a7ae3e2eab2f1293d05930a Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:30:40 +0300 Subject: [PATCH 016/209] Implement pagination in recents data source --- .../Recents/DataSources/RecentsDataSource.h | 7 ++ .../Recents/DataSources/RecentsDataSource.m | 69 ++++++++++++++++++- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h index 2dbf20bc5..745ab180c 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.h @@ -182,6 +182,13 @@ extern NSString *const kRecentsDataSourceTapOnDirectoryServerChange; */ @property (nonatomic) UIImageView* droppingCellBackGroundView; +/** + Paginate in the given section. Results will be notified from delegate methods. + + @param section section index to be paginated + */ +- (void)paginateInSection:(NSInteger)section; + /** Move a cell from a path to another one. It is based on room Tag. diff --git a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m index 1cac2305a..82336eee5 100644 --- a/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m +++ b/Riot/Modules/Common/Recents/DataSources/RecentsDataSource.m @@ -1339,6 +1339,38 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou return nil; } +- (void)paginateInSection:(NSInteger)section +{ + if (section == invitesSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionInvited]; + } + else if (section == favoritesSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionFavorited]; + } + else if (section == peopleSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionPeople]; + } + else if (section == conversationSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionConversation]; + } + else if (section == lowPrioritySection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionLowPriority]; + } + else if (section == serverNoticeSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionServerNotice]; + } + else if (section == suggestedRoomsSection) + { + [self.recentsListService paginateInSection:RecentsListServiceSectionSuggested]; + } +} + - (void)moveRoomCell:(MXRoom*)room from:(NSIndexPath*)oldPath to:(NSIndexPath*)newPath success:(void (^)(void))moveSuccess failure:(void (^)(NSError *error))moveFailure; { MXLogDebug(@"[RecentsDataSource] moveCellFrom (%tu, %tu) to (%tu, %tu)", oldPath.section, oldPath.row, newPath.section, newPath.row); @@ -1434,10 +1466,41 @@ NSString *const kRecentsDataSourceTapOnDirectoryServerChange = @"kRecentsDataSou #pragma mark - RecentsListServiceDelegate -- (void)serviceDidChangeData:(id)service +- (void)recentsListServiceDidChangeData:(id)service { - // TODO: Update only updated sections - [self.delegate dataSource:self didCellChange:nil]; + // no-op +} + +- (void)recentsListServiceDidChangeData:(id)service + forSection:(RecentsListServiceSection)section +{ + NSInteger sectionIndex = -1; + switch (section) + { + case RecentsListServiceSectionInvited: + sectionIndex = invitesSection; + break; + case RecentsListServiceSectionFavorited: + sectionIndex = favoritesSection; + break; + case RecentsListServiceSectionPeople: + sectionIndex = peopleSection; + break; + case RecentsListServiceSectionConversation: + sectionIndex = conversationSection; + break; + case RecentsListServiceSectionLowPriority: + sectionIndex = lowPrioritySection; + break; + case RecentsListServiceSectionServerNotice: + sectionIndex = serverNoticeSection; + break; + case RecentsListServiceSectionSuggested: + sectionIndex = suggestedRoomsSection; + break; + } + + [self.delegate dataSource:self didCellChange:@(sectionIndex)]; } @end From d36e131b618af57d84359257476e05cecb24b739 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:31:18 +0300 Subject: [PATCH 017/209] Call pagination api from appropriate points --- .../Favorites/FavouritesViewController.m | 21 +++++++++++++++++++ Riot/Modules/Home/HomeViewController.m | 16 ++++++++++++++ Riot/Modules/People/PeopleViewController.m | 20 ++++++++++++++++++ Riot/Modules/Rooms/RoomsViewController.m | 21 +++++++++++++++++++ 4 files changed, 78 insertions(+) diff --git a/Riot/Modules/Favorites/FavouritesViewController.m b/Riot/Modules/Favorites/FavouritesViewController.m index c3c10933b..23b43b856 100644 --- a/Riot/Modules/Favorites/FavouritesViewController.m +++ b/Riot/Modules/Favorites/FavouritesViewController.m @@ -24,6 +24,8 @@ RecentsDataSource *recentsDataSource; } +@property (nonatomic, strong) MXThrottler *tableViewPaginationThrottler; + @end @implementation FavouritesViewController @@ -42,6 +44,7 @@ self.enableDragging = YES; self.screenTimer = [[AnalyticsScreenTimer alloc] initWithScreen:AnalyticsScreenFavourites]; + self.tableViewPaginationThrottler = [[MXThrottler alloc] initWithMinimumDelay:0.1]; } - (void)viewDidLoad @@ -121,6 +124,24 @@ return 0.0f; } +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath +{ + if ([super respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)]) + { + [super tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath]; + } + + [self.tableViewPaginationThrottler throttle:^{ + NSInteger section = indexPath.section; + NSInteger numberOfRowsInSection = [tableView numberOfRowsInSection:section]; + if (tableView.numberOfSections > section + && indexPath.row == numberOfRowsInSection - 1) + { + [self->recentsDataSource paginateInSection:section]; + } + }]; +} + #pragma mark - Empty view management - (void)updateEmptyView diff --git a/Riot/Modules/Home/HomeViewController.m b/Riot/Modules/Home/HomeViewController.m index 2c2f702d7..2c9250112 100644 --- a/Riot/Modules/Home/HomeViewController.m +++ b/Riot/Modules/Home/HomeViewController.m @@ -47,6 +47,7 @@ @property (nonatomic, strong) CrossSigningSetupCoordinatorBridgePresenter *crossSigningSetupCoordinatorBridgePresenter; @property (nonatomic, assign, readwrite) BOOL roomListDataReady; +@property (nonatomic, strong) MXThrottler *collectionViewPaginationThrottler; @property(nonatomic) SpaceMembersCoordinatorBridgePresenter *spaceMembersCoordinatorBridgePresenter; @@ -70,6 +71,7 @@ selectedCollectionViewContentOffset = -1; self.screenTimer = [[AnalyticsScreenTimer alloc] initWithScreen:AnalyticsScreenHome]; + self.collectionViewPaginationThrottler = [[MXThrottler alloc] initWithMinimumDelay:0.1]; } - (void)viewDidLoad @@ -619,6 +621,20 @@ return cell; } +- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath +{ + [self.collectionViewPaginationThrottler throttle:^{ + NSInteger collectionViewSection = indexPath.section; + NSInteger numberOfItemsInSection = [collectionView numberOfItemsInSection:collectionViewSection]; + if (collectionView.numberOfSections > collectionViewSection + && indexPath.item == numberOfItemsInSection - 1) + { + NSInteger tableViewSection = collectionView.tag; + [self->recentsDataSource paginateInSection:tableViewSection]; + } + }]; +} + #pragma mark - UICollectionViewDelegate - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath diff --git a/Riot/Modules/People/PeopleViewController.m b/Riot/Modules/People/PeopleViewController.m index ace78de54..43bb1754c 100644 --- a/Riot/Modules/People/PeopleViewController.m +++ b/Riot/Modules/People/PeopleViewController.m @@ -33,6 +33,7 @@ } @property(nonatomic) SpaceMembersCoordinatorBridgePresenter *spaceMembersCoordinatorBridgePresenter; +@property (nonatomic, strong) MXThrottler *tableViewPaginationThrottler; @end @@ -52,6 +53,7 @@ directRoomsSectionNumber = 0; self.screenTimer = [[AnalyticsScreenTimer alloc] initWithScreen:AnalyticsScreenPeople]; + self.tableViewPaginationThrottler = [[MXThrottler alloc] initWithMinimumDelay:0.1]; } - (void)viewDidLoad @@ -106,6 +108,24 @@ return nil; } +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath +{ + if ([super respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)]) + { + [super tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath]; + } + + [self.tableViewPaginationThrottler throttle:^{ + NSInteger section = indexPath.section; + NSInteger numberOfRowsInSection = [tableView numberOfRowsInSection:section]; + if (tableView.numberOfSections > section + && indexPath.row == numberOfRowsInSection - 1) + { + [self->recentsDataSource paginateInSection:section]; + } + }]; +} + #pragma mark - Override RecentsViewController - (void)refreshCurrentSelectedCell:(BOOL)forceVisible diff --git a/Riot/Modules/Rooms/RoomsViewController.m b/Riot/Modules/Rooms/RoomsViewController.m index 183db0046..71975e939 100644 --- a/Riot/Modules/Rooms/RoomsViewController.m +++ b/Riot/Modules/Rooms/RoomsViewController.m @@ -25,6 +25,8 @@ RecentsDataSource *recentsDataSource; } +@property (nonatomic, strong) MXThrottler *tableViewPaginationThrottler; + @end @implementation RoomsViewController @@ -41,6 +43,7 @@ [super finalizeInit]; self.screenTimer = [[AnalyticsScreenTimer alloc] initWithScreen:AnalyticsScreenRooms]; + self.tableViewPaginationThrottler = [[MXThrottler alloc] initWithMinimumDelay:0.1]; } - (void)viewDidLoad @@ -112,6 +115,24 @@ return [super tableView:tableView heightForHeaderInSection:section]; } +- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath +{ + if ([super respondsToSelector:@selector(tableView:willDisplayCell:forRowAtIndexPath:)]) + { + [super tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath]; + } + + [self.tableViewPaginationThrottler throttle:^{ + NSInteger section = indexPath.section; + NSInteger numberOfRowsInSection = [tableView numberOfRowsInSection:section]; + if (tableView.numberOfSections > section + && indexPath.row == numberOfRowsInSection - 1) + { + [self->recentsDataSource paginateInSection:section]; + } + }]; +} + #pragma mark - - (void)scrollToNextRoomWithMissedNotifications From 913313fc1d2b565182f4849a8db16590d3fe9a22 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 4 Jan 2022 04:31:52 +0300 Subject: [PATCH 018/209] Just reload collection view when paginating --- .../Common/Recents/RecentsViewController.m | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index 0bcceb09a..0b8e9efbb 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -29,6 +29,7 @@ #import "InviteRecentTableViewCell.h" #import "DirectoryRecentTableViewCell.h" #import "RoomIdOrAliasTableViewCell.h" +#import "TableViewCellWithCollectionView.h" #import "GeneratedInterface-Swift.h" @@ -1006,9 +1007,32 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro - (void)dataSource:(MXKDataSource *)dataSource didCellChange:(id)changes { - [super dataSource:dataSource didCellChange:changes]; + BOOL cellReloaded = NO; + if ([changes isKindOfClass:NSNumber.class]) + { + NSInteger section = ((NSNumber *)changes).integerValue; + if (section >= 0) + { + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section]; + UITableViewCell *cell = [self.recentsTableView cellForRowAtIndexPath:indexPath]; + if ([cell isKindOfClass:TableViewCellWithCollectionView.class]) + { + TableViewCellWithCollectionView *collectionViewCell = (TableViewCellWithCollectionView *)cell; + [collectionViewCell.collectionView reloadData]; + cellReloaded = YES; + } + } + } - [self showEmptyViewIfNeeded]; + if (!cellReloaded) + { + [super dataSource:dataSource didCellChange:changes]; + } + + if (changes == nil) + { + [self showEmptyViewIfNeeded]; + } if (dataSource.state == MXKDataSourceStateReady) { From 5b5487857bc799496904e020851d6e7a04164e38 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 4 Jan 2022 10:24:31 +0100 Subject: [PATCH 019/209] Update changes --- changelog.d/5321.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5321.feature diff --git a/changelog.d/5321.feature b/changelog.d/5321.feature new file mode 100644 index 000000000..8fc5d69a2 --- /dev/null +++ b/changelog.d/5321.feature @@ -0,0 +1 @@ +Message bubbles: Add settings and build flag. \ No newline at end of file From be707a0ae979e55dba5700e246dc39a80a8613a4 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 4 Jan 2022 11:11:02 +0100 Subject: [PATCH 020/209] Fix targets configuration. --- RiotNSE/target.yml | 2 +- RiotShareExtension/target.yml | 2 +- RiotTests/target.yml | 2 +- SiriIntents/target.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index 88dde20ff..c7e96ba9a 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -65,4 +65,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index d427bd75d..b5028d6c6 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -72,4 +72,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift diff --git a/RiotTests/target.yml b/RiotTests/target.yml index fc7443941..771ce726e 100644 --- a/RiotTests/target.yml +++ b/RiotTests/target.yml @@ -64,4 +64,4 @@ targets: - path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift - path: ../Riot/Managers/KeyValueStorage/ - path: ../Riot/PropertyWrappers/UserDefaultsBackedPropertyWrapper.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index cc71dacd7..c5da8212f 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -54,4 +54,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift From 608dd0c7a630c8b97ea59f9940758d631637badc Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 4 Jan 2022 17:53:15 +0100 Subject: [PATCH 021/209] Rename RoomTimelineStyle enum to RoomTimelineStyleIdentifier. --- Config/BuildSettings.swift | 4 ++-- .../RoomTimelineStyleIdentifier.swift} | 4 ++-- RiotNSE/target.yml | 2 +- RiotShareExtension/target.yml | 2 +- RiotTests/target.yml | 2 +- SiriIntents/target.yml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/{RoomTimelineStyle.swift => Styles/RoomTimelineStyleIdentifier.swift} (87%) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 5031afdf5..4fc6e3d5b 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -300,9 +300,9 @@ final class BuildSettings: NSObject { // Timeline style static let roomScreenAllowTimelineStyleConfiguration: Bool = false - static let roomScreenTimelineDefaultStyle: RoomTimelineStyle = .plain + static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain static var roomScreenEnableMessageBubblesByDefault: Bool { - return self.roomScreenTimelineDefaultStyle == .bubble + return self.roomScreenTimelineDefaultStyleIdentifier == .bubble } /// Allow split view detail view stacking diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift similarity index 87% rename from Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift rename to Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift index d7c72cea4..e4f9a2316 100644 --- a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift @@ -16,8 +16,8 @@ import Foundation -/// Represents the room timeline styles available -enum RoomTimelineStyle { +/// Represents the room timeline style identifiers available +enum RoomTimelineStyleIdentifier { case plain case bubble } diff --git a/RiotNSE/target.yml b/RiotNSE/target.yml index c7e96ba9a..de0dd69c1 100644 --- a/RiotNSE/target.yml +++ b/RiotNSE/target.yml @@ -65,4 +65,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift diff --git a/RiotShareExtension/target.yml b/RiotShareExtension/target.yml index b5028d6c6..2c8f71d64 100644 --- a/RiotShareExtension/target.yml +++ b/RiotShareExtension/target.yml @@ -72,4 +72,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift diff --git a/RiotTests/target.yml b/RiotTests/target.yml index 771ce726e..36532fecd 100644 --- a/RiotTests/target.yml +++ b/RiotTests/target.yml @@ -64,4 +64,4 @@ targets: - path: ../Riot/Managers/EncryptionKeyManager/EncryptionKeyManager.swift - path: ../Riot/Managers/KeyValueStorage/ - path: ../Riot/PropertyWrappers/UserDefaultsBackedPropertyWrapper.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift diff --git a/SiriIntents/target.yml b/SiriIntents/target.yml index c5da8212f..d184497af 100644 --- a/SiriIntents/target.yml +++ b/SiriIntents/target.yml @@ -54,4 +54,4 @@ targets: excludes: - "**/*.md" # excludes all files with the .md extension - path: ../Riot/Generated/MatrixKitStrings.swift - - path: ../Riot/Modules/Room/Views/BubbleCells/RoomTimelineStyle.swift + - path: ../Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift From cf166006fb320a18f1a9f184ce18300227e4d1f6 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 5 Jan 2022 16:52:05 +0100 Subject: [PATCH 022/209] Reduce grace period to report decryption failure --- Riot/Modules/Analytics/DecryptionFailureTracker.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Analytics/DecryptionFailureTracker.m b/Riot/Modules/Analytics/DecryptionFailureTracker.m index 0f2b2ff81..ea770a375 100644 --- a/Riot/Modules/Analytics/DecryptionFailureTracker.m +++ b/Riot/Modules/Analytics/DecryptionFailureTracker.m @@ -19,11 +19,11 @@ // Call `checkFailures` every `CHECK_INTERVAL` -#define CHECK_INTERVAL 5 +#define CHECK_INTERVAL 2 // Give events a chance to be decrypted by waiting `GRACE_PERIOD` before counting // and reporting them as failures -#define GRACE_PERIOD 60 +#define GRACE_PERIOD 4 // E2E failures analytics category. NSString *const kDecryptionFailureTrackerAnalyticsCategory = @"e2e.failure"; From 0f1c2eaa2cc9a95fd416212087c63b6ac89e5511 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Fri, 7 Jan 2022 16:06:54 +0300 Subject: [PATCH 023/209] Fix initial sync crash --- .../MatrixSDK/RecentsListService.swift | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift index 85f0ba6df..4d8d57259 100644 --- a/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift +++ b/Riot/Modules/Common/Recents/Service/MatrixSDK/RecentsListService.swift @@ -28,6 +28,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { public private(set) var query: String? public private(set) var space: MXSpace? + private var fetchersCreated: Bool = false // MARK: - Fetchers @@ -165,6 +166,7 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { super.init() createFetchers() addRiotSettingsObserver() + addSessionStateObserver() } // MARK: - View Data @@ -262,9 +264,20 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } public func stop() { + removeSessionStateObserver() removeRiotSettingsObserver() removeAllDelegates() allFetchers.forEach({ $0.stop() }) + + invitedRoomListDataFetcher = nil + favoritedRoomListDataFetcher = nil + directRoomListDataFetcherForHome = nil + directRoomListDataFetcherForPeople = nil + conversationRoomListDataFetcherForHome = nil + conversationRoomListDataFetcherForRooms = nil + lowPriorityRoomListDataFetcher = nil + serverNoticeRoomListDataFetcher = nil + suggestedRoomListDataFetcher = nil } // MARK: - Delegate @@ -312,6 +325,32 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } } + // MARK: - Session State Observers + + private func addSessionStateObserver() { + NotificationCenter.default.addObserver(self, + selector: #selector(sessionStateUpdated(_:)), + name: .mxSessionStateDidChange, + object: nil) + } + + private func removeSessionStateObserver() { + NotificationCenter.default.removeObserver(self, + name: .mxSessionStateDidChange, + object: nil) + } + + @objc + private func sessionStateUpdated(_ notification: Notification) { + guard let session = notification.object as? MXSession else { + return + } + guard session == self.session else { + return + } + createFetchers() + } + // MARK: - Private private var shouldShowInvited: Bool { @@ -450,6 +489,16 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { } private func createFetchers() { + guard fetchersCreated == false else { + removeSessionStateObserver() + return + } + guard let session = session else { + return + } + guard session.isEventStreamInitialised else { + return + } if !hideInvitedSection { invitedRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.invited]) } @@ -461,6 +510,9 @@ public class RecentsListService: NSObject, RecentsListServiceProtocol { lowPriorityRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.lowPriority]) serverNoticeRoomListDataFetcher = createCommonRoomListDataFetcher(withDataTypes: [.serverNotice]) suggestedRoomListDataFetcher = createCommonRoomListDataFetcher(onlySuggested: true) + + fetchersCreated = true + removeSessionStateObserver() } private func updateDirectFetcher(_ fetcher: MXRoomListDataFetcher, for mode: RecentsDataSourceMode) { From 4648a5878df3bad7a0090796623dca10aef84eea Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Fri, 7 Jan 2022 18:30:30 +0300 Subject: [PATCH 024/209] Adapt summaries module name change --- Riot/Modules/MatrixKit/Models/Account/MXKAccount.m | 2 +- RiotShareExtension/Shared/ShareDataSource.m | 2 +- SiriIntents/IntentHandler.m | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m index 26e92d315..67697acad 100644 --- a/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m +++ b/Riot/Modules/MatrixKit/Models/Account/MXKAccount.m @@ -1843,7 +1843,7 @@ static NSArray *initialSyncSilentErrorsHTTPStatusCodes; summary.lastMessage.others = [NSMutableDictionary dictionary]; } summary.lastMessage.others[@"lastEventDate"] = [eventFormatter dateStringFromEvent:event withTime:YES]; - [self->mxSession.store.summariesModule storeSummary:summary]; + [self->mxSession.store.roomSummaryStore storeSummary:summary]; } dispatch_group_leave(dispatchGroup); diff --git a/RiotShareExtension/Shared/ShareDataSource.m b/RiotShareExtension/Shared/ShareDataSource.m index eb993ee05..3c3ae631b 100644 --- a/RiotShareExtension/Shared/ShareDataSource.m +++ b/RiotShareExtension/Shared/ShareDataSource.m @@ -77,7 +77,7 @@ - (void)loadCellData { - [self.fileStore.summariesModule fetchAllSummaries:^(NSArray> *summaries) { + [self.fileStore.roomSummaryStore fetchAllSummaries:^(NSArray> *summaries) { NSMutableArray *cellData = [NSMutableArray array]; diff --git a/SiriIntents/IntentHandler.m b/SiriIntents/IntentHandler.m index 0c93f08aa..9c503501d 100644 --- a/SiriIntents/IntentHandler.m +++ b/SiriIntents/IntentHandler.m @@ -215,7 +215,7 @@ { MXKAccount *account = [MXKAccountManager sharedManager].activeAccounts.firstObject; MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull summaries) { + [fileStore.roomSummaryStore fetchAllSummaries:^(NSArray> * _Nonnull summaries) { NSString *roomID = person.customIdentifier; BOOL isEncrypted = NO; @@ -315,7 +315,7 @@ if (account) { MXFileStore *fileStore = [[MXFileStore alloc] initWithCredentials:account.mxCredentials]; - [fileStore.summariesModule fetchAllSummaries:^(NSArray> * _Nonnull summaries) { + [fileStore.roomSummaryStore fetchAllSummaries:^(NSArray> * _Nonnull summaries) { // Contains userIds of all users with whom the current user has direct chats // Use set to avoid duplicates From 7a019d2e5da085c2758401804017582dad4eba41 Mon Sep 17 00:00:00 2001 From: Valere Date: Mon, 10 Jan 2022 09:24:53 +0100 Subject: [PATCH 025/209] Update change log --- changelog.d/5345.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5345.change diff --git a/changelog.d/5345.change b/changelog.d/5345.change new file mode 100644 index 000000000..80ee600a1 --- /dev/null +++ b/changelog.d/5345.change @@ -0,0 +1 @@ +Reduce grace period to report decryption failure From 25dda91aa202833a87fbbdda5e56f428e5b1c63a Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 11 Jan 2022 02:44:36 +0300 Subject: [PATCH 026/209] Make changelog one line --- changelog.d/4384.change | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/changelog.d/4384.change b/changelog.d/4384.change index faaccd63e..13dd82545 100644 --- a/changelog.d/4384.change +++ b/changelog.d/4384.change @@ -1,2 +1 @@ -Using mutable room list fetch sort options after chaning them to be a structure. -Adaptation to MXStore api changes. +Using mutable room list fetch sort options after chaning them to be a structure. Adaptation to MXStore api changes. From 2fd1f94f81c939a24a7cdc5ae63636a0e0c288f2 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 11 Jan 2022 14:27:27 +0000 Subject: [PATCH 027/209] Prepare for new sprint --- Config/AppVersion.xcconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index b213c8623..f0f3b8161 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.6.12 -CURRENT_PROJECT_VERSION = 1.6.12 +MARKETING_VERSION = 1.6.13 +CURRENT_PROJECT_VERSION = 1.6.13 From 9ef7719434e4b39355a257d71924a9fb17c274bf Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 12 Jan 2022 10:59:37 +0000 Subject: [PATCH 028/209] Use new dtmf function signature --- Riot/Modules/Call/CallViewController.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Riot/Modules/Call/CallViewController.m b/Riot/Modules/Call/CallViewController.m index bb702ad15..12cd489b2 100644 --- a/Riot/Modules/Call/CallViewController.m +++ b/Riot/Modules/Call/CallViewController.m @@ -664,9 +664,7 @@ CallAudioRouteMenuViewDelegate> { return; } - BOOL result = [self.mxCall sendDTMF:digit - duration:0 - interToneGap:0]; + BOOL result = [self.mxCall sendDTMF:digit]; MXLogDebug(@"[CallViewController] Sending DTMF tones %@", result ? @"succeeded": @"failed"); } From 57fa1489727ca4b6233ad409c1361fe7da755a87 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 12 Jan 2022 11:34:48 +0000 Subject: [PATCH 029/209] Create 5375.bugfix --- changelog.d/5375.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5375.bugfix diff --git a/changelog.d/5375.bugfix b/changelog.d/5375.bugfix new file mode 100644 index 000000000..b8c851286 --- /dev/null +++ b/changelog.d/5375.bugfix @@ -0,0 +1 @@ +Fixes DTMF(dial tones) during voice calls. From 0b1d0accd4d2aae748c1cb2fe147b0ed3f953146 Mon Sep 17 00:00:00 2001 From: jelv Date: Wed, 12 Jan 2022 09:45:15 +0000 Subject: [PATCH 030/209] Translated using Weblate (Dutch) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/nl/ --- Riot/Assets/nl.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/nl.lproj/InfoPlist.strings b/Riot/Assets/nl.lproj/InfoPlist.strings index c3c846e97..9a4450097 100644 --- a/Riot/Assets/nl.lproj/InfoPlist.strings +++ b/Riot/Assets/nl.lproj/InfoPlist.strings @@ -21,3 +21,4 @@ "NSContactsUsageDescription" = "Element zal uw contacten tonen zodat u ze kunt uitnodigen om te chatten."; "NSCalendarsUsageDescription" = "Bekijk uw geplande afspraken in de app."; "NSFaceIDUsageDescription" = "Face ID wordt gebruikt om toegang te krijgen tot uw app."; +"NSLocationWhenInUseUsageDescription" = "Wanneer u uw locatie deelt met mensen heeft Element toegang nodig om dit op een kaart te tonen."; From 4f40fc2d9edc3a54291bb5ed2a5782b19db859f4 Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Tue, 11 Jan 2022 15:01:04 +0000 Subject: [PATCH 031/209] Translated using Weblate (German) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/de/ --- Riot/Assets/de.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/de.lproj/InfoPlist.strings b/Riot/Assets/de.lproj/InfoPlist.strings index 571d56f44..594fb19a0 100644 --- a/Riot/Assets/de.lproj/InfoPlist.strings +++ b/Riot/Assets/de.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element zeigt deine Kontakte an, damit du sie zum chatten einladen kannst."; "NSCalendarsUsageDescription" = "Sieh dir deine geplanten Meetings in der App an."; "NSFaceIDUsageDescription" = "Face-ID wird zum Zugriff auf deine App verwendet."; +"NSLocationWhenInUseUsageDescription" = "Wenn du deinen Standort mit Personen teilst, braucht Element Zugriff um ihnen eine Karte anzuzeigen."; From bcc325a1395a4708e1656d0e583b9d333743d2df Mon Sep 17 00:00:00 2001 From: jelv Date: Wed, 12 Jan 2022 09:28:40 +0000 Subject: [PATCH 032/209] Translated using Weblate (Dutch) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/nl/ --- Riot/Assets/nl.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/nl.lproj/Localizable.strings b/Riot/Assets/nl.lproj/Localizable.strings index f8c52bb83..7ff69454b 100644 --- a/Riot/Assets/nl.lproj/Localizable.strings +++ b/Riot/Assets/nl.lproj/Localizable.strings @@ -149,3 +149,6 @@ /** General **/ "NOTIFICATION" = "Meldingen"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ deelde hun locatie"; From bb0a92e4655006153acdf216e53777a7c1145e5a Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Tue, 11 Jan 2022 14:57:48 +0000 Subject: [PATCH 033/209] Translated using Weblate (German) Currently translated at 99.7% (441 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/de/ --- .../Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings index 295ea3259..12a8826cc 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings @@ -504,3 +504,4 @@ "attachment_unsupported_preview_message" = "Dieser Dateityp wird nicht unterstützt."; "attachment_unsupported_preview_title" = "Vorschau kann nicht angezeigt werden"; "auth_reset_password_error_unauthorized" = "Nicht Authorisiert"; +"message_reply_to_sender_sent_their_location" = "hat den eigenen Standort geteilt."; From 1f4248714a50c0b845a1488312efabc540e8959a Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 11 Jan 2022 20:11:43 +0000 Subject: [PATCH 034/209] Translated using Weblate (Hungarian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/hu/ --- Riot/Assets/hu.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/hu.lproj/InfoPlist.strings b/Riot/Assets/hu.lproj/InfoPlist.strings index 0edf4d429..75e748c58 100644 --- a/Riot/Assets/hu.lproj/InfoPlist.strings +++ b/Riot/Assets/hu.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element megmutatja a névjegyzéket, hogy beszélgetésbe meghívhasd őket."; "NSCalendarsUsageDescription" = "Nézd meg a találkozóidat az alkalmazásban."; "NSFaceIDUsageDescription" = "Arc felismerés használata az alkalmazás eléréséhez."; +"NSLocationWhenInUseUsageDescription" = "Ha megosztod másokkal a földrajzi helyzetedet, akkor az Elementnek hozzáférésre van szüksége a térképen való megjelenítéshez."; From 36df883344ba9946014359509c5f9ba511d96ed7 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 11 Jan 2022 14:40:30 +0000 Subject: [PATCH 035/209] Translated using Weblate (Albanian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/sq/ --- Riot/Assets/sq.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/sq.lproj/InfoPlist.strings b/Riot/Assets/sq.lproj/InfoPlist.strings index ee2f2697a..bfeef7694 100644 --- a/Riot/Assets/sq.lproj/InfoPlist.strings +++ b/Riot/Assets/sq.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element-i do të shfaqë kontaktet tuaja, që kështu të mund t’i ftoni për të biseduar."; "NSCalendarsUsageDescription" = "Shihini te aplikacioni takimet tuaja të planifikuara."; "NSFaceIDUsageDescription" = "Face ID përdoret që të hyni në aplikacionin tuaj."; +"NSLocationWhenInUseUsageDescription" = "Kur ndani vendndodhjen tuaj me persona, Element-i ka nevojë për hyrje në të, që t’u trgojë atyre një hartë."; From a520da762dc59f2c3e174ef353d7d4c7e3c6533a Mon Sep 17 00:00:00 2001 From: random Date: Tue, 11 Jan 2022 13:15:49 +0000 Subject: [PATCH 036/209] Translated using Weblate (Italian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/it/ --- Riot/Assets/it.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/it.lproj/InfoPlist.strings b/Riot/Assets/it.lproj/InfoPlist.strings index 6382ef48e..989ac76d3 100644 --- a/Riot/Assets/it.lproj/InfoPlist.strings +++ b/Riot/Assets/it.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element mostrerà i tuoi contatti così da poterli invitare in chat."; "NSCalendarsUsageDescription" = "Vedi le tue riunioni programmate nell'app."; "NSFaceIDUsageDescription" = "Face ID viene usato per accedere all'app."; +"NSLocationWhenInUseUsageDescription" = "Quando condividi la tua posizione con altre persone, Element richiede l'accesso per mostrare loro una mappa."; From c5b6a89505faf1eca9948338533c906223aa654d Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Tue, 11 Jan 2022 14:57:12 +0000 Subject: [PATCH 037/209] Translated using Weblate (German) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/de/ --- Riot/Assets/de.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/de.lproj/Localizable.strings b/Riot/Assets/de.lproj/Localizable.strings index 3c7e1f066..a5edb4e62 100644 --- a/Riot/Assets/de.lproj/Localizable.strings +++ b/Riot/Assets/de.lproj/Localizable.strings @@ -116,3 +116,6 @@ /* A user's membership has updated in an unknown way */ "USER_MEMBERSHIP_UPDATED" = "Profil von %@ geupdatet"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ hat den eigenen Standort geteilt"; From 422c5518a8956a77ee9c91bf46d0fb58f306473c Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 11 Jan 2022 12:44:30 +0000 Subject: [PATCH 038/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/pt_BR/ --- Riot/Assets/pt_BR.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/pt_BR.lproj/InfoPlist.strings b/Riot/Assets/pt_BR.lproj/InfoPlist.strings index bb44cdb98..28cf8e2b8 100644 --- a/Riot/Assets/pt_BR.lproj/InfoPlist.strings +++ b/Riot/Assets/pt_BR.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element vai mostrar seus contatos para que você possa convidá-los a conversar."; "NSCalendarsUsageDescription" = "Ver suas reuniões agendadas no app."; "NSFaceIDUsageDescription" = "Face ID é usada para acessar seu app."; +"NSLocationWhenInUseUsageDescription" = "Quando você compartilha sua localização para pessoas, Element precisa de acesso para mostrar-lhes um mapa."; From c2bb2f5b81793641ff6e907d7ab8c93d5001dc30 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 11 Jan 2022 20:12:21 +0000 Subject: [PATCH 039/209] Translated using Weblate (Hungarian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/hu/ --- Riot/Assets/hu.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/hu.lproj/Localizable.strings b/Riot/Assets/hu.lproj/Localizable.strings index caa2f34ad..d0ed4447e 100644 --- a/Riot/Assets/hu.lproj/Localizable.strings +++ b/Riot/Assets/hu.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Értesítés"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ megosztotta a földrajzi helyzetét"; From 6c6402fb48320dc28e9c4ea49f5e71026324ed7e Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 11 Jan 2022 12:48:07 +0000 Subject: [PATCH 040/209] Translated using Weblate (Ukrainian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/uk/ --- Riot/Assets/uk.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/uk.lproj/InfoPlist.strings b/Riot/Assets/uk.lproj/InfoPlist.strings index 1923cbcbc..35a02253f 100644 --- a/Riot/Assets/uk.lproj/InfoPlist.strings +++ b/Riot/Assets/uk.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element покаже ваші контакти, щоб ви могли запросити їх до бесіди."; "NSCalendarsUsageDescription" = "Переглядайте свої заплановані зустрічі в додатку."; "NSFaceIDUsageDescription" = "Face ID використовується для доступу до вашого додатку."; +"NSLocationWhenInUseUsageDescription" = "Коли ви надсилаєте комусь дані про своє місцеперебування, Element потребує дозволу, щоб показати їм карту."; From 383499cf2c24aef534ede5b68de6d1efaf5cddfd Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 11 Jan 2022 14:39:28 +0000 Subject: [PATCH 041/209] Translated using Weblate (Albanian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/sq/ --- Riot/Assets/sq.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/sq.lproj/Localizable.strings b/Riot/Assets/sq.lproj/Localizable.strings index 6bec05eba..ad7a81203 100644 --- a/Riot/Assets/sq.lproj/Localizable.strings +++ b/Riot/Assets/sq.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Njoftim"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ tregoi vendndodhjen e vet"; From 636fd60b4a3257192b8cf9b01535997db0c520c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Jan 2022 07:14:10 +0000 Subject: [PATCH 042/209] Translated using Weblate (Estonian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/et/ --- .../Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings index 997cb7964..310a27da6 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings @@ -478,3 +478,4 @@ "room_displayname_all_other_members_left" = "%@ (lahkus(id))"; "attachment_unsupported_preview_message" = "See failitüüp ei ole toetatud."; "attachment_unsupported_preview_title" = "Eelvaate kuvamine ei õnnestu"; +"message_reply_to_sender_sent_their_location" = "on jaganud oma asukohta."; From e5415236593f5917bcb44a695a6a7a0bf08df51d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Jan 2022 07:15:16 +0000 Subject: [PATCH 043/209] Translated using Weblate (Estonian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/et/ --- Riot/Assets/et.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/et.lproj/InfoPlist.strings b/Riot/Assets/et.lproj/InfoPlist.strings index 25a5d9479..e556d1d6a 100644 --- a/Riot/Assets/et.lproj/InfoPlist.strings +++ b/Riot/Assets/et.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSCalendarsUsageDescription" = "Vaata päevakavasse lisatud koosolekuid vastvast rakendusest."; "NSContactsUsageDescription" = "Element näitab sulle tuttavaid, kellega saad alustada vestlust."; "NSFaceIDUsageDescription" = "Ligipääsuks sinu rakendusele on kasutusel Face ID."; +"NSLocationWhenInUseUsageDescription" = "Kui sa jagad teiste kasutajatega oma asukohta, siis Element vajab õigusi asukoha kuvamiseks kaardil."; From c256c00e67231785eca6c4575bcce837cbaf88f8 Mon Sep 17 00:00:00 2001 From: random Date: Tue, 11 Jan 2022 13:16:08 +0000 Subject: [PATCH 044/209] Translated using Weblate (Italian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/it/ --- Riot/Assets/it.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/it.lproj/Localizable.strings b/Riot/Assets/it.lproj/Localizable.strings index 25a6a0cca..d8ec6e0cd 100644 --- a/Riot/Assets/it.lproj/Localizable.strings +++ b/Riot/Assets/it.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Notifica"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ ha condiviso la sua posizione"; From b791a007582e893175d3618ead75e60e858c76fe Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 11 Jan 2022 20:13:20 +0000 Subject: [PATCH 045/209] Translated using Weblate (Hungarian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/hu/ --- .../Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings index d99934823..d1c2ec520 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/hu.lproj/MatrixKit.strings @@ -283,7 +283,7 @@ "notice_conference_call_started" = "VoIP konferencia indult"; "notice_conference_call_finished" = "VoIP konferencia befejeződött"; // button names -"ok" = "Rendben"; +"ok" = "OK"; "cancel" = "Mégse"; "save" = "Ment"; "send" = "Küld"; @@ -479,3 +479,4 @@ "room_displayname_all_other_members_left" = "%@ (Bal)"; "attachment_unsupported_preview_message" = "Ez a fájl típus nem támogatott."; "attachment_unsupported_preview_title" = "Az előnézetet nem lehet megjeleníteni"; +"message_reply_to_sender_sent_their_location" = "megosztotta a földrajzi helyzetét."; From 34c74a9a3dc381e246f3923b9e604f5282208b2a Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 11 Jan 2022 13:54:54 +0000 Subject: [PATCH 046/209] Translated using Weblate (Indonesian) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/id/ --- Riot/Assets/id.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/id.lproj/InfoPlist.strings b/Riot/Assets/id.lproj/InfoPlist.strings index e74ebc244..3459f17dd 100644 --- a/Riot/Assets/id.lproj/InfoPlist.strings +++ b/Riot/Assets/id.lproj/InfoPlist.strings @@ -7,3 +7,4 @@ "NSCalendarsUsageDescription" = "Lihat pertemuan yang sudah dijadwalkan di aplikasi."; "NSMicrophoneUsageDescription" = "Element membutuhkan akses ke mikrofon Anda untuk melakukan dan menerima panggilan, mengambil video, dan merekam pesan suara."; "NSPhotoLibraryUsageDescription" = "Galeri digunakan untuk mengirim foto dan video."; +"NSLocationWhenInUseUsageDescription" = "Ketika Anda membagikan lokasi Anda ke orang-orang, Element membutuhkan akses untuk menampilkan mereka sebuah peta."; From 6ffb2adee05d31e5438b1b0b15be7bdb0d019c76 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 11 Jan 2022 12:43:37 +0000 Subject: [PATCH 047/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/pt_BR/ --- Riot/Assets/pt_BR.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/pt_BR.lproj/Localizable.strings b/Riot/Assets/pt_BR.lproj/Localizable.strings index 165ee183e..51f9faf5f 100644 --- a/Riot/Assets/pt_BR.lproj/Localizable.strings +++ b/Riot/Assets/pt_BR.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Notificação"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ compartilhou a localização dela(e)"; From 7bf08cfdb77bd41a96d5090f283cb0b5fcdd7d4f Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 11 Jan 2022 12:48:40 +0000 Subject: [PATCH 048/209] Translated using Weblate (Ukrainian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/uk/ --- Riot/Assets/uk.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/uk.lproj/Localizable.strings b/Riot/Assets/uk.lproj/Localizable.strings index 01f01d7ac..0ad0b3aa3 100644 --- a/Riot/Assets/uk.lproj/Localizable.strings +++ b/Riot/Assets/uk.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Сповіщення"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ надсилає дані про своє місцеперебування"; From 96e82b47b53ce69696b7db56373167dd41a76625 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 11 Jan 2022 13:55:18 +0000 Subject: [PATCH 049/209] Translated using Weblate (Indonesian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/id/ --- .../Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings index ef186655b..65682850d 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/id.lproj/MatrixKit.strings @@ -249,7 +249,7 @@ // titles // button names -"ok" = "OK"; +"ok" = "OKE"; "notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "Anda membuat sejarah pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka bergabung."; "notice_room_history_visible_to_members_from_joined_point_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruang, sejak mereka bergabung."; "notice_encryption_enabled_unknown_algorithm_by_you" = "Anda mengaktifkan enkripsi ujung-ke-ujung (algoritma %@ tidak dikenal)."; @@ -557,3 +557,4 @@ "notice_room_power_level_acting_requirement" = "Tingkat daya minimum yang harus dimiliki pengguna sebelum bertindak adalah:"; "attachment_unsupported_preview_title" = "Tidak dapat ditampilkan"; "attachment_unsupported_preview_message" = "Tipe file ini tidak didukung."; +"message_reply_to_sender_sent_their_location" = "telah membagikan lokasinya."; From 14eae7e0f2fc69a1333c1900fdfdbea8f25ba0a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Jan 2022 07:13:34 +0000 Subject: [PATCH 050/209] Translated using Weblate (Estonian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/et/ --- Riot/Assets/et.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/et.lproj/Localizable.strings b/Riot/Assets/et.lproj/Localizable.strings index 6e4824651..844410852 100644 --- a/Riot/Assets/et.lproj/Localizable.strings +++ b/Riot/Assets/et.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Teavitus"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ jagas oma asukohta"; From 414e5e29bb022f2e4788f71d6f6707018ed55155 Mon Sep 17 00:00:00 2001 From: random Date: Tue, 11 Jan 2022 13:16:22 +0000 Subject: [PATCH 051/209] Translated using Weblate (Italian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/it/ --- .../Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings index 6049a7351..fb679dc2b 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/it.lproj/MatrixKit.strings @@ -478,3 +478,4 @@ "rename" = "Rinomina"; "attachment_unsupported_preview_message" = "Questo tipo di file non è supportato."; "attachment_unsupported_preview_title" = "Anteprima non disponibile"; +"message_reply_to_sender_sent_their_location" = "ha condiviso la sua posizione."; From 2376e955c2620890d622264ced30bb8e04c8e982 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 11 Jan 2022 13:55:41 +0000 Subject: [PATCH 052/209] Translated using Weblate (Indonesian) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/id/ --- Riot/Assets/id.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/id.lproj/Localizable.strings b/Riot/Assets/id.lproj/Localizable.strings index 679a5cbb8..dc244763c 100644 --- a/Riot/Assets/id.lproj/Localizable.strings +++ b/Riot/Assets/id.lproj/Localizable.strings @@ -165,3 +165,6 @@ /** General **/ "NOTIFICATION" = "Notifikasi"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ membagikan lokasinya"; From e3fa4cb09abfe353c78264598c9edeab2237b275 Mon Sep 17 00:00:00 2001 From: jelv Date: Wed, 12 Jan 2022 09:45:37 +0000 Subject: [PATCH 053/209] Translated using Weblate (Dutch) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/nl/ --- .../Assets/MatrixKitAssets.bundle/nl.lproj/MatrixKit.strings | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/nl.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/nl.lproj/MatrixKit.strings index 8c6e58224..da52635ac 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/nl.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/nl.lproj/MatrixKit.strings @@ -311,7 +311,7 @@ // titles // button names -"ok" = "Oké"; +"ok" = "OK"; "cancel" = "Annuleren"; "save" = "Opslaan"; "leave" = "Verlaten"; @@ -540,3 +540,4 @@ "room_displayname_all_other_members_left" = "%@ (Vertrok)"; "auth_username_in_use" = "Inlognaam al in gebruik"; "rename" = "Hernoemen"; +"message_reply_to_sender_sent_their_location" = "deelde hun locatie."; From 1c8d3e055ea15c6d9b4e0117ac2479a20510fc5d Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 11 Jan 2022 20:52:32 +0000 Subject: [PATCH 054/209] Translated using Weblate (Slovak) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/sk/ --- Riot/Assets/sk.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/sk.lproj/Localizable.strings b/Riot/Assets/sk.lproj/Localizable.strings index 0ba5126ce..fffb34696 100644 --- a/Riot/Assets/sk.lproj/Localizable.strings +++ b/Riot/Assets/sk.lproj/Localizable.strings @@ -165,3 +165,6 @@ /* New message reply from a specific person in a named room. */ "REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ odpovedal/a v %@"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ zdieľal/a svoju polohu"; From 46d7762c908ccb069b7f47dec81b8142d9fbe22e Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 11 Jan 2022 20:55:25 +0000 Subject: [PATCH 055/209] Translated using Weblate (Slovak) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/sk/ --- Riot/Assets/sk.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/sk.lproj/InfoPlist.strings b/Riot/Assets/sk.lproj/InfoPlist.strings index 9d8892825..704899a7f 100644 --- a/Riot/Assets/sk.lproj/InfoPlist.strings +++ b/Riot/Assets/sk.lproj/InfoPlist.strings @@ -7,3 +7,4 @@ "NSPhotoLibraryUsageDescription" = "Knižnica fotografií sa používa na odosielanie fotografií a videí."; // Permissions usage explanations "NSCameraUsageDescription" = "Fotoaparát sa používa na snímanie fotografií a videí, uskutočňovanie videohovorov."; +"NSLocationWhenInUseUsageDescription" = "Keď zdieľate svoju polohu s ľuďmi, Element potrebuje prístup, aby im mohol zobraziť mapu."; From 69ef824d3204210b07d39ad208913bda863aa9ab Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 11 Jan 2022 13:33:40 +0000 Subject: [PATCH 056/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/pt_BR/ --- .../pt_BR.lproj/MatrixKit.strings | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings index f3dba6590..9ddeb7793 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pt_BR.lproj/MatrixKit.strings @@ -121,7 +121,7 @@ "room_displayname_two_members" = "%@ e %@"; "room_displayname_more_than_two_members" = "%@ e %@ outros"; // Settings -"settings" = "Configurações"; +"settings" = "Ajustes"; "settings_enable_inapp_notifications" = "Habilitar notificações Em-App"; "settings_enable_push_notifications" = "Habilitar notificações push"; "settings_enter_validation_token_for" = "Entrar token de validação para %@:"; @@ -157,7 +157,7 @@ "room_event_encryption_info_block" = "Adicionar à lista negra"; "room_event_encryption_info_unblock" = "Remover da lista negra"; "room_event_encryption_verify_title" = "Verificar sessão\n\n"; -"room_event_encryption_verify_message" = "Para verificar que esta sessão pode ser confiada, por favor contacte a/o dona(o) dela usando alguma outro meio (e.g. em pessoa ou uma chamada de telefone) e pergunte-lhe se a chave que ela/ele vê em suas Configurações de Usuária(o) para esta sessão bate com a chave abaixo:\n\n\tNome de sessão: %@\n\tID de sessão: %@\n\tChave de sessão: %@\n\nSe ela bate, pressione o botão verificar abaixo. Se não bate, então alguma outra pessoa está interceptando esa sessão e você provavelmente quer pressionar o botão adicionar à lista negra em vez disso.\n\nNo futuro este processo de verificação vai ser mais sofisticado."; +"room_event_encryption_verify_message" = "Para verificar que esta sessão pode ser confiada, por favor contacte a/o dona(o) dela usando alguma outro meio (e.g. em pessoa ou uma chamada de telefone) e pergunte-lhe se a chave que ela/ele vê em seus Ajustes de Usuária(o) para esta sessão corresponde com a chave abaixo:\n\n\tNome de sessão: %@\n\tID de sessão: %@\n\tChave de sessão: %@\n\nSe ela corresponde, pressione o botão verificar abaixo. Se não corresponde, então alguma outra pessoa está interceptando esa sessão e você provavelmente quer pressionar o botão adicionar à lista negra em vez disso.\n\nNo futuro este processo de verificação vai ser mais sofisticado."; "room_event_encryption_verify_ok" = "Verificar"; // Account "account_save_changes" = "Salvar mudanças"; @@ -331,9 +331,9 @@ "notification_settings_disable_all" = "Desabilitar todas as notificações"; "notification_settings_enable_notifications" = "Habilitar notificações"; "notification_settings_enable_notifications_warning" = "Todas as notificações estão atualmente desabilitadas para todos os dispositivos."; -"notification_settings_global_info" = "Configurações de notificação são salvas em sua conta de usuária(o) e são compartilhadas entre todos os clientes que as suportam (incluindo notificações de desktop).\n\nRegras são aplicadas em ordem; a primeira regra que corresponde define o resultado da mensagem.\nEntão: Notificações per-palavra são mais importantes que notificações per-sala que são mais importantes que notificações per-enviador(a).\nPara múltiplas regras do mesmo tipo, a primeira na lista que corresponde leva prioridade."; +"notification_settings_global_info" = "Ajustes de notificação são salvas em sua conta de usuária(o) e são compartilhadas entre todos os clientes que as suportam (incluindo notificações de desktop).\n\nRegras são aplicadas em ordem; a primeira regra que corresponde define o resultado da mensagem.\nEntão: Notificações per-palavra são mais importantes que notificações per-sala que são mais importantes que notificações per-enviador(a).\nPara múltiplas regras do mesmo tipo, a primeira na lista que corresponde leva prioridade."; "notification_settings_per_word_notifications" = "Notificações per-palavra"; -"notification_settings_per_word_info" = "Palavras correspondem insensivelmente a maiúsculas e minúsculas, e podem incluir um wildcard *. Então:\nfoo corresponde a string foo rodeado por delimitadores de palavras (e.g., pontuação e whitespace ou início/fim de linha).\nfoo* corresponde a qualquer palavra que começa foo.\n*foo* corresponde a qualquer palavra que inclui as 3 letras foo."; +"notification_settings_per_word_info" = "Palavras correspondem insensivelmente com maiúsculas e minúsculas, e podem incluir um wildcard *. Então:\nfoo corresponde com string foo rodeado por delimitadores de palavras (e.g., pontuação e whitespace ou início/fim de linha).\nfoo* corresponde com qualquer palavra que começa foo.\n*foo* corresponde com qualquer palavra que inclui as 3 letras foo."; "notification_settings_always_notify" = "Sempre notificar"; "notification_settings_never_notify" = "Nunca notificar"; "notification_settings_word_to_match" = "palavra para corresponder"; @@ -372,10 +372,10 @@ "ssl_fingerprint_hash" = "Impressão digital (%@):"; "ssl_could_not_verify" = "Não foi possível verificar identidade de servidor remoto."; "ssl_cert_not_trust" = "Isto pode significar que alguém está interceptando maliciosamente seu tráfico, ou que seu telefone não confia no certificado provido pelo servidor remoto."; -"ssl_cert_new_account_expl" = "Se o/a administrador(a) do servidor tem dito que isto é esperado, assegure-se que a impressão digital abaixo bate com a impressão digital provida por ele(a)."; +"ssl_cert_new_account_expl" = "Se o/a administrador(a) do servidor tem dito que isto é esperado, assegure-se que a impressão digital abaixo corresponde com a impressão digital provida por ele(a)."; "ssl_unexpected_existing_expl" = "O certificado tem mudado de um que esta confiado por seu telefone. Isto é ALTAMENTE INCOMUM. É recomendado que você NÃO ACEITE este novo certificado."; "ssl_expected_existing_expl" = "O certificado tem sido mudado de um previamente confiado para um que não é confiado. O servidor pode ter renovado o certificado dele. Contacte o/a administrador(a) do servidor a impressão digital esperada."; -"ssl_only_accept" = "SOMENTE aceite o certificado se o/a administrador(a) do servidor tem publicado uma impressão digital que corresponde à acima."; +"ssl_only_accept" = "SOMENTE aceite o certificado se o/a administrador(a) do servidor tem publicado uma impressão digital que corresponde com a acima."; "notice_encryption_enabled_ok" = "%@ ativou encriptação ponta-a-ponta."; "notice_encryption_enabled_unknown_algorithm" = "%1$@ ativou encriptação ponta-a-ponta (algoritmo não-reconhecido %2$@)."; "device_details_rename_prompt_title" = "Nome da Sessão"; @@ -468,7 +468,7 @@ "attachment_large_with_resolution" = "Grande %@ (~%@)"; "attachment_medium_with_resolution" = "Médio %@ (~%@)"; "attachment_small_with_resolution" = "Pequeno %@ (~%@)"; -"attachment_size_prompt_message" = "Você pode desligar isto em configurações."; +"attachment_size_prompt_message" = "Você pode desligar isto em ajustes."; "attachment_size_prompt_title" = "Confirmar tamanho para enviar"; "room_displayname_all_other_participants_left" = "%@ (Saiu)"; "auth_reset_password_error_not_found" = "Não encontrado"; @@ -479,3 +479,4 @@ "room_displayname_all_other_members_left" = "%@ (Saiu)"; "attachment_unsupported_preview_message" = "Este tipo de arquivo não é suportado."; "attachment_unsupported_preview_title" = "Incapaz de previsualizar"; +"message_reply_to_sender_sent_their_location" = "tem compartilhado a localização dela(e)."; From 123855fde6fa0c986f4667f3c560198f00454779 Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 11 Jan 2022 15:06:51 +0000 Subject: [PATCH 057/209] Translated using Weblate (Albanian) Currently translated at 99.7% (441 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/sq/ --- .../Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings index 888cbed6b..4e7256707 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sq.lproj/MatrixKit.strings @@ -478,3 +478,4 @@ "attachment_unsupported_preview_message" = "Ky lloj kartele nuk mbulohet."; "attachment_unsupported_preview_title" = "S’arrihet të bëhet paraparje"; "room_displayname_all_other_members_left" = "%@ (Iku)"; +"message_reply_to_sender_sent_their_location" = "ka dhënë vendndodhjen e vet."; From 9afd40a4b808af39a7826e47b67101c4452fd601 Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 11 Jan 2022 12:49:01 +0000 Subject: [PATCH 058/209] Translated using Weblate (Ukrainian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/uk/ --- .../Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings index 955e8fd1a..69eec8107 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/uk.lproj/MatrixKit.strings @@ -558,3 +558,4 @@ "local_contacts_access_not_granted" = "Для пошуку користувачів серед локальних контактів потрібен доступ до ваших контактів, але %@ не має такого дозволу"; "e2e_export_prompt" = "Це дає змогу експортувати в локальний файл ключі до повідомлень, отриманих вами в зашифрованих кімнатах. Тоді ви зможете імпортувати файл до іншого клієнта Matrix у майбутньому, і той клієнт також зможе розшифрувати ці повідомлення.\nЕкспортований файл дасть змогу всім, хто його прочитає, розшифрувати всі видимі вам зашифровані повідомлення."; "e2e_import_prompt" = "Це дає змогу імпортувати ключі шифрування, які ви раніше експортували з іншого клієнта Matrix. Тоді ви зможете розшифрувати всі повідомлення, які міг розшифрувати той клієнт.\nФайл експорту захищений парольною фразою. Введіть парольну фразу сюди, щоб розшифрувати файл."; +"message_reply_to_sender_sent_their_location" = "надсилає дані про своє місцеперебування."; From aafa68987e893afe273878578611b45697c5f6e2 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 11 Jan 2022 20:54:43 +0000 Subject: [PATCH 059/209] Translated using Weblate (Slovak) Currently translated at 97.5% (431 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/sk/ --- .../Assets/MatrixKitAssets.bundle/sk.lproj/MatrixKit.strings | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sk.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sk.lproj/MatrixKit.strings index 1efe28839..fec99d96b 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sk.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sk.lproj/MatrixKit.strings @@ -543,3 +543,7 @@ "notice_feedback" = "Udalosť spätnej väzby (id: %@): %@"; "resume_call" = "Pokračovať"; "answer_call" = "Prijať hovor"; +"message_reply_to_sender_sent_their_location" = "zdieľal/a svoju polohu."; +"account_link_email" = "Prepojený email"; +"account_linked_emails" = "Prepojené e-maily"; +"room_event_encryption_info_event_fingerprint_key" = "Deklarovaný kľúč odtlačkov prstov Ed25519\n"; From e6269edf0cad6dda92ca7dca6acc62c49dc35d4b Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 16:50:17 +0100 Subject: [PATCH 060/209] MXRoomViewController: Remove unused cell classes. --- .../Controllers/MXKRoomViewController.m | 80 +------------------ 1 file changed, 1 insertion(+), 79 deletions(-) diff --git a/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m b/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m index 942eeec58..0028f45f3 100644 --- a/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m +++ b/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m @@ -36,16 +36,6 @@ #import "MXKRoomBubbleCellData.h" -#import "MXKRoomIncomingTextMsgBubbleCell.h" -#import "MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h" -#import "MXKRoomIncomingAttachmentBubbleCell.h" -#import "MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h" - -#import "MXKRoomOutgoingTextMsgBubbleCell.h" -#import "MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h" -#import "MXKRoomOutgoingAttachmentBubbleCell.h" -#import "MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" - #import "MXKEncryptionKeysImportView.h" #import "NSBundle+MatrixKit.h" @@ -616,17 +606,6 @@ _bubblesTableView.delegate = self; _bubblesTableView.dataSource = roomDataSource; // Note: data source may be nil here, it will be set during [displayRoom:] call. - // Set up default classes to use for cells - [_bubblesTableView registerClass:MXKRoomIncomingTextMsgBubbleCell.class forCellReuseIdentifier:MXKRoomIncomingTextMsgBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomIncomingAttachmentBubbleCell.class forCellReuseIdentifier:MXKRoomIncomingAttachmentBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - - [_bubblesTableView registerClass:MXKRoomOutgoingTextMsgBubbleCell.class forCellReuseIdentifier:MXKRoomOutgoingTextMsgBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomOutgoingAttachmentBubbleCell.class forCellReuseIdentifier:MXKRoomOutgoingAttachmentBubbleCell.defaultReuseIdentifier]; - [_bubblesTableView registerClass:MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - // Observe kMXSessionWillLeaveRoomNotification to be notified if the user leaves the current room. MXWeakify(self); _mxSessionWillLeaveRoomNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXSessionWillLeaveRoomNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) { @@ -2477,64 +2456,7 @@ - (Class)cellViewClassForCellData:(MXKCellData*)cellData { - Class cellViewClass = nil; - - // Sanity check - if ([cellData conformsToProtocol:@protocol(MXKRoomBubbleCellDataStoring)]) - { - id bubbleData = (id)cellData; - - // Select the suitable table view cell class - if (bubbleData.isIncoming) - { - if (bubbleData.isAttachmentWithThumbnail) - { - if (bubbleData.shouldHideSenderInformation) - { - cellViewClass = MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.class; - } - else - { - cellViewClass = MXKRoomIncomingAttachmentBubbleCell.class; - } - } - else - { - if (bubbleData.shouldHideSenderInformation) - { - cellViewClass = MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.class; - } - else - { - cellViewClass = MXKRoomIncomingTextMsgBubbleCell.class; - } - } - } - else if (bubbleData.isAttachmentWithThumbnail) - { - if (bubbleData.shouldHideSenderInformation) - { - cellViewClass = MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class; - } - else - { - cellViewClass = MXKRoomOutgoingAttachmentBubbleCell.class; - } - } - else - { - if (bubbleData.shouldHideSenderInformation) - { - cellViewClass = MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class; - } - else - { - cellViewClass = MXKRoomOutgoingTextMsgBubbleCell.class; - } - } - } - - return cellViewClass; + return nil; } - (NSString *)cellReuseIdentifierForCellData:(MXKCellData*)cellData From 0069e77aa83b9912b492ef6698241e595cce8ca2 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 16:51:51 +0100 Subject: [PATCH 061/209] Move MatrixKit text message cells to Riot target. --- .../Common}/MXKRoomIncomingTextMsgBubbleCell.h | 0 .../Common}/MXKRoomIncomingTextMsgBubbleCell.m | 11 +++++++++++ .../Common}/MXKRoomIncomingTextMsgBubbleCell.xib | 0 ...oomIncomingTextMsgWithoutSenderInfoBubbleCell.h | 0 ...oomIncomingTextMsgWithoutSenderInfoBubbleCell.m | 0 ...mIncomingTextMsgWithoutSenderInfoBubbleCell.xib | 0 .../Common}/MXKRoomOutgoingTextMsgBubbleCell.h | 0 .../Common}/MXKRoomOutgoingTextMsgBubbleCell.m | 14 +++++++++++++- .../Common}/MXKRoomOutgoingTextMsgBubbleCell.xib | 0 ...oomOutgoingTextMsgWithoutSenderInfoBubbleCell.h | 0 ...oomOutgoingTextMsgWithoutSenderInfoBubbleCell.m | 0 ...mOutgoingTextMsgWithoutSenderInfoBubbleCell.xib | 0 12 files changed, 24 insertions(+), 1 deletion(-) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgBubbleCell.m (68%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Incoming/Common}/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgBubbleCell.m (67%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/TextMessage/Outgoing/Common}/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib (100%) diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m similarity index 68% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m index 253e7141f..4a66ba815 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m @@ -16,6 +16,17 @@ #import "MXKRoomIncomingTextMsgBubbleCell.h" +#import "GeneratedInterface-Swift.h" + @implementation MXKRoomIncomingTextMsgBubbleCell +- (void)setupViews +{ + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + id currentStyle = timelineConfiguration.currentStyle; + + [currentStyle.cellLayoutUpdater setupLayoutForIncomingMessageCell:self]; +} + @end diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m similarity index 67% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m index 232813182..4f49a219f 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m @@ -16,6 +16,18 @@ #import "MXKRoomOutgoingTextMsgBubbleCell.h" +#import "GeneratedInterface-Swift.h" + @implementation MXKRoomOutgoingTextMsgBubbleCell -@end \ No newline at end of file +- (void)setupViews +{ + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + id currentStyle = timelineConfiguration.currentStyle; + + [currentStyle.cellLayoutUpdater setupLayoutForOutgoingMessageCell:self]; +} + + +@end diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.xib From 541eb1759ad64a9ad785eb3df0641ae5138e8c30 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 16:54:45 +0100 Subject: [PATCH 062/209] MXKRoomBubbleCellData: Add convenient method. --- .../Models/Room/MXKRoomBubbleCellData.h | 7 +++++++ .../Models/Room/MXKRoomBubbleCellData.m | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.h b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.h index 691f092e6..2bd19ed7a 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.h +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.h @@ -163,4 +163,11 @@ */ - (MXKRoomBubbleComponent*)getFirstBubbleComponentWithDisplay; +/** + Get the last visible component. + + @return Last visible component or nil. + */ +- (MXKRoomBubbleComponent*)getLastBubbleComponentWithDisplay; + @end diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m index b20bcb668..cd1fa9b70 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m @@ -327,6 +327,26 @@ return first; } +- (MXKRoomBubbleComponent*)getLastBubbleComponentWithDisplay +{ + // Look for the first component which is actually displayed (some event are ignored in room history display). + MXKRoomBubbleComponent* lastVisibleComponent = nil; + + @synchronized(bubbleComponents) + { + for (NSInteger index = 0; index < bubbleComponents.count; index++) + { + MXKRoomBubbleComponent *component = bubbleComponents[index]; + if (component.attributedTextMessage) + { + lastVisibleComponent = component; + } + } + } + + return lastVisibleComponent; +} + - (NSAttributedString*)attributedTextMessageWithHighlightedEvent:(NSString*)eventId tintColor:(UIColor*)tintColor { NSAttributedString *customAttributedTextMsg; From 86caa7e19ad4a174dfd18437ea249521790ec674 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 16:56:10 +0100 Subject: [PATCH 063/209] RoomTimelineStyleIdentifier: Make it available for ObjC. --- .../Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift index e4f9a2316..a285fe8e0 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyleIdentifier.swift @@ -17,7 +17,8 @@ import Foundation /// Represents the room timeline style identifiers available -enum RoomTimelineStyleIdentifier { +@objc +enum RoomTimelineStyleIdentifier: Int { case plain case bubble } From 830760d2f1bbedce9c4d1c76bc80033511672124 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 17:31:03 +0100 Subject: [PATCH 064/209] Add RoomTimelineCellProviderProtocol that enables to register and provide room timeline cells. --- .../Styles/RoomTimelineCellProviderProtocol.h | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h new file mode 100644 index 000000000..66fc17ee4 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h @@ -0,0 +1,36 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import + +#import "RoomTimelineCellIdentifier.h" +#import "MXKCellRendering.h" + +NS_ASSUME_NONNULL_BEGIN + +/// Enables to register and provide room timeline cells +@protocol RoomTimelineCellProviderProtocol + +/// Register timeline cells for the given table view +- (void)registerCellsForTableView:(UITableView*)tableView; + +/// Get timeline cell class from cell identifier +- (Class)cellViewClassForCellIdentifier:(RoomTimelineCellIdentifier)identifier; + +@end + +NS_ASSUME_NONNULL_END + From cc0a08a28a4d19ec0df6b16be64d5db8063aef35 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 17:31:47 +0100 Subject: [PATCH 065/209] Add PlainRoomTimelineCellProvider. --- .../Plain/PlainRoomTimelineCellProvider.h | 27 ++ .../Plain/PlainRoomTimelineCellProvider.m | 451 ++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h new file mode 100644 index 000000000..7c3d16294 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h @@ -0,0 +1,27 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "RoomTimelineCellProviderProtocol.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface PlainRoomTimelineCellProvider: NSObject + +- (NSDictionary*)outgoingTextMessageCellsMapping; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m new file mode 100644 index 000000000..85f6711c2 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -0,0 +1,451 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "PlainRoomTimelineCellProvider.h" + +#import "MXKRoomBubbleTableViewCell+Riot.h" + +#import "RoomEmptyBubbleCell.h" + +#import "RoomIncomingTextMsgBubbleCell.h" +#import "RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomIncomingTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomIncomingTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#import "RoomIncomingAttachmentBubbleCell.h" +#import "RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomIncomingAttachmentWithPaginationTitleBubbleCell.h" + +#import "RoomIncomingEncryptedTextMsgBubbleCell.h" +#import "RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#import "RoomIncomingEncryptedAttachmentBubbleCell.h" +#import "RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h" + +#import "RoomOutgoingTextMsgBubbleCell.h" +#import "RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingAttachmentBubbleCell.h" +#import "RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" + +#import "RoomOutgoingEncryptedTextMsgBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingEncryptedAttachmentBubbleCell.h" +#import "RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h" + +#import "RoomMembershipBubbleCell.h" +#import "RoomMembershipWithPaginationTitleBubbleCell.h" +#import "RoomMembershipCollapsedBubbleCell.h" +#import "RoomMembershipCollapsedWithPaginationTitleBubbleCell.h" +#import "RoomMembershipExpandedBubbleCell.h" +#import "RoomMembershipExpandedWithPaginationTitleBubbleCell.h" +#import "RoomCreationWithPaginationCollapsedBubbleCell.h" +#import "RoomCreationCollapsedBubbleCell.h" + +#import "RoomSelectedStickerBubbleCell.h" +#import "RoomPredecessorBubbleCell.h" + +#import "GeneratedInterface-Swift.h" + +@interface PlainRoomTimelineCellProvider() + +@property (nonatomic, strong) NSDictionary* cellClasses; + +@end + +@implementation PlainRoomTimelineCellProvider + +#pragma mark - Public + +- (void)registerCellsForTableView:(UITableView*)tableView +{ + // Text message + + [self registerIncomingTextMessageCellsForTableView:tableView]; + + [self registerOutgoingTextMessageCellsForTableView:tableView]; + + // Attachment cells + + [self registerIncomingAttachmentCellsForTableView:tableView]; + + [self registerOutgoingAttachmentCellsForTableView:tableView]; + + // Other cells + + [self registerMembershipCellsForTableView:tableView]; + + [self registerKeyVerificationCellsForTableView:tableView]; + + [self registerRoomCreationCellsForTableView:tableView]; + + [self registerCallCellsForTableView:tableView]; + + [self registerVoiceMessageCellsForTableView:tableView]; + + [self registerPollCellsForTableView:tableView]; + + [self registerLocationCellsForTableView:tableView]; + + [tableView registerClass:RoomEmptyBubbleCell.class forCellReuseIdentifier:RoomEmptyBubbleCell.defaultReuseIdentifier]; + + [tableView registerClass:RoomSelectedStickerBubbleCell.class forCellReuseIdentifier:RoomSelectedStickerBubbleCell.defaultReuseIdentifier]; + + [tableView registerClass:RoomPredecessorBubbleCell.class forCellReuseIdentifier:RoomPredecessorBubbleCell.defaultReuseIdentifier]; + + [tableView registerClass:RoomCreationIntroCell.class forCellReuseIdentifier:RoomCreationIntroCell.defaultReuseIdentifier]; + + [tableView registerNib:RoomTypingBubbleCell.nib forCellReuseIdentifier:RoomTypingBubbleCell.defaultReuseIdentifier]; +} + +- (Class)cellViewClassForCellIdentifier:(RoomTimelineCellIdentifier)identifier +{ + if (self.cellClasses == nil) + { + self.cellClasses = [self buildCellClasses]; + } + + Class cellViewClass = self.cellClasses[@(identifier)]; + + + return cellViewClass; +} + +#pragma mark - Private + +#pragma mark Cell registration + +- (void)registerIncomingTextMessageCellsForTableView:(UITableView*)tableView +{ + // Clear + + [tableView registerClass:RoomIncomingTextMsgBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + + // Encrypted + + [tableView registerClass:RoomIncomingEncryptedTextMsgBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerOutgoingTextMessageCellsForTableView:(UITableView*)tableView +{ + // Clear + + [tableView registerClass:RoomOutgoingTextMsgBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + + // Encrypted + + [tableView registerClass:RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedTextMsgBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerIncomingAttachmentCellsForTableView:(UITableView*)tableView +{ + // Clear + + [tableView registerClass:RoomIncomingAttachmentBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + + // Encrypted + + [tableView registerClass:RoomIncomingEncryptedAttachmentBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerOutgoingAttachmentCellsForTableView:(UITableView*)tableView +{ + // Clear + + [tableView registerClass:RoomOutgoingAttachmentBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + + // Encrypted + + [tableView registerClass:RoomOutgoingEncryptedAttachmentBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerMembershipCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:RoomMembershipBubbleCell.class forCellReuseIdentifier:RoomMembershipBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomMembershipWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomMembershipCollapsedBubbleCell.class forCellReuseIdentifier:RoomMembershipCollapsedBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomMembershipCollapsedWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipCollapsedWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomMembershipExpandedBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomMembershipExpandedWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerKeyVerificationCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:KeyVerificationIncomingRequestApprovalBubbleCell.class forCellReuseIdentifier:KeyVerificationIncomingRequestApprovalBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:KeyVerificationRequestStatusBubbleCell.class forCellReuseIdentifier:KeyVerificationRequestStatusBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:KeyVerificationRequestStatusWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationRequestStatusWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:KeyVerificationConclusionBubbleCell.class forCellReuseIdentifier:KeyVerificationConclusionBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:KeyVerificationConclusionWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationConclusionWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerRoomCreationCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:RoomCreationCollapsedBubbleCell.class forCellReuseIdentifier:RoomCreationCollapsedBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomCreationWithPaginationCollapsedBubbleCell.class forCellReuseIdentifier:RoomCreationWithPaginationCollapsedBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerCallCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:RoomDirectCallStatusBubbleCell.class forCellReuseIdentifier:RoomDirectCallStatusBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomGroupCallStatusBubbleCell.class forCellReuseIdentifier:RoomGroupCallStatusBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerVoiceMessageCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:VoiceMessageBubbleCell.class forCellReuseIdentifier:VoiceMessageBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:VoiceMessageWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:VoiceMessageWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:VoiceMessageWithPaginationTitleBubbleCell.class forCellReuseIdentifier:VoiceMessageWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerPollCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:PollBubbleCell.class forCellReuseIdentifier:PollBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:PollWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:PollWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:PollWithPaginationTitleBubbleCell.class forCellReuseIdentifier:PollWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +- (void)registerLocationCellsForTableView:(UITableView*)tableView +{ + [tableView registerClass:LocationBubbleCell.class forCellReuseIdentifier:LocationBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:LocationWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationWithPaginationTitleBubbleCell.defaultReuseIdentifier]; +} + +#pragma mark Cell class association + +- (NSDictionary*)buildCellClasses +{ + NSMutableDictionary* cellClasses = [NSMutableDictionary dictionary]; + + // Text message + + NSDictionary *incomingTextMessageCellsMapping = [self incomingTextMessageCellsMapping]; + [cellClasses addEntriesFromDictionary:incomingTextMessageCellsMapping]; + + NSDictionary *outgoingTextMessageCellsMapping = [self incomingTextMessageCellsMapping]; + [cellClasses addEntriesFromDictionary:outgoingTextMessageCellsMapping]; + + // Attachment + + NSDictionary *incomingAttachmentCellsMapping = [self incomingAttachmentCellsMapping]; + [cellClasses addEntriesFromDictionary:incomingAttachmentCellsMapping]; + + NSDictionary *outgoingAttachmentCellsMapping = [self outgoingTextMessageCellsMapping]; + [cellClasses addEntriesFromDictionary:outgoingAttachmentCellsMapping]; + + // Other cells + + NSDictionary *roomMembershipCellsMapping = [self membershipCellsMapping]; + [cellClasses addEntriesFromDictionary:roomMembershipCellsMapping]; + + NSDictionary *keyVerificationCellsMapping = [self keyVerificationCellsMapping]; + [cellClasses addEntriesFromDictionary:keyVerificationCellsMapping]; + + NSDictionary *roomCreationCellsMapping = [self roomCreationCellsMapping]; + [cellClasses addEntriesFromDictionary:roomCreationCellsMapping]; + + NSDictionary *callCellsMapping = [self callCellsMapping]; + [cellClasses addEntriesFromDictionary:callCellsMapping]; + + NSDictionary *voiceMessageCellsMapping = [self voiceMessageCellsMapping]; + [cellClasses addEntriesFromDictionary:voiceMessageCellsMapping]; + + NSDictionary *pollCellsMapping = [self pollCellsMapping]; + [cellClasses addEntriesFromDictionary:pollCellsMapping]; + + NSDictionary *locationCellsMapping = [self locationCellsMapping]; + [cellClasses addEntriesFromDictionary:locationCellsMapping]; + + NSDictionary *othersCells = @{ + @(RoomTimelineCellIdentifierEmpty) : RoomEmptyBubbleCell.class, + @(RoomTimelineCellIdentifierSelectedSticker) : RoomSelectedStickerBubbleCell.class, + @(RoomTimelineCellIdentifierRoomPredecessor) : RoomPredecessorBubbleCell.class, + @(RoomTimelineCellIdentifierRoomCreationIntro) : RoomCreationIntroCell.class, + @(RoomTimelineCellIdentifierTyping) : RoomTypingBubbleCell.class, + }; + [cellClasses addEntriesFromDictionary:othersCells]; + + return [cellClasses copy]; +} + +- (NSDictionary*)incomingTextMessageCellsMapping +{ + return @{ + // Clear + @(RoomTimelineCellIdentifierIncomingTextMessage) : RoomIncomingTextMsgBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderInfo) : RoomIncomingTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitle) : RoomIncomingTextMsgWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderName) : RoomIncomingTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitleWithoutSenderName) : RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierIncomingTextMessageEncrypted) : RoomIncomingEncryptedTextMsgBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderInfo) : RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitle) : RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderName) : RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitleWithoutSenderName) : RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + }; +} + +- (NSDictionary*)outgoingTextMessageCellsMapping +{ + return @{ + // Clear + @(RoomTimelineCellIdentifierOutgoingTextMessage) : RoomOutgoingTextMsgBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderInfo) : RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitle) : RoomOutgoingTextMsgWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderName) : RoomOutgoingTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitleWithoutSenderName) : RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierOutgoingTextMessageEncrypted) : RoomOutgoingEncryptedTextMsgBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitle) : RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderName) : RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitleWithoutSenderName) : RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + }; +} + +- (NSDictionary*)incomingAttachmentCellsMapping +{ + return @{ + // Clear + @(RoomTimelineCellIdentifierIncomingAttachment) : RoomIncomingAttachmentBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingAttachmentWithoutSenderInfo) : RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingAttachmentWithPaginationTitle) : RoomIncomingAttachmentWithPaginationTitleBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierIncomingAttachmentEncrypted) : RoomIncomingEncryptedAttachmentBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithoutSenderInfo) : RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithPaginationTitle) : RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class + }; +} + +- (NSDictionary*)outgoingAttachmentCellsMapping +{ + return @{ + // Clear + @(RoomTimelineCellIdentifierOutgoingAttachment) : RoomOutgoingAttachmentBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentWithoutSenderInfo) : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle) : RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierOutgoingAttachmentEncrypted) : RoomOutgoingEncryptedAttachmentBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithPaginationTitle) : RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class + }; +} + +- (NSDictionary*)membershipCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierMembership) : RoomMembershipBubbleCell.class, + @(RoomTimelineCellIdentifierMembershipWithPaginationTitle) : RoomMembershipWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierMembershipCollapsed) : RoomMembershipCollapsedBubbleCell.class, + @(RoomTimelineCellIdentifierMembershipCollapsedWithPaginationTitle) : RoomMembershipCollapsedWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierMembershipExpanded) : RoomMembershipExpandedBubbleCell.class, + @(RoomTimelineCellIdentifierMembershipExpandedWithPaginationTitle) : RoomMembershipExpandedWithPaginationTitleBubbleCell.class, + }; +} + +- (NSDictionary*)keyVerificationCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierKeyVerificationIncomingRequestApproval) : KeyVerificationIncomingRequestApprovalBubbleCell.class, + @(RoomTimelineCellIdentifierKeyVerificationIncomingRequestApprovalWithPaginationTitle) : KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierKeyVerificationRequestStatus) : KeyVerificationRequestStatusBubbleCell.class, + @(RoomTimelineCellIdentifierKeyVerificationRequestStatusWithPaginationTitle) : KeyVerificationRequestStatusWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierKeyVerificationConclusion) : KeyVerificationConclusionBubbleCell.class, + @(RoomTimelineCellIdentifierKeyVerificationConclusionWithPaginationTitle) : KeyVerificationConclusionWithPaginationTitleBubbleCell.class, + }; +} + +- (NSDictionary*)roomCreationCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierRoomCreationCollapsed) : RoomCreationCollapsedBubbleCell.class, + @(RoomTimelineCellIdentifierRoomCreationCollapsedWithPaginationTitle) : RoomCreationWithPaginationCollapsedBubbleCell.class, + }; +} + +- (NSDictionary*)callCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierDirectCallStatus) : RoomDirectCallStatusBubbleCell.class, + @(RoomTimelineCellIdentifierGroupCallStatus) : RoomGroupCallStatusBubbleCell.class, + }; +} + +- (NSDictionary*)voiceMessageCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierVoiceMessage) : VoiceMessageBubbleCell.class, + @(RoomTimelineCellIdentifierVoiceMessageWithoutSenderInfo) : VoiceMessageWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierVoiceMessageWithPaginationTitle) : VoiceMessageWithPaginationTitleBubbleCell.class, + }; +} + +- (NSDictionary*)pollCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierPoll) : PollBubbleCell.class, + @(RoomTimelineCellIdentifierPollWithoutSenderInfo) : PollWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierPollWithPaginationTitle) : PollWithPaginationTitleBubbleCell.class, + }; +} + +- (NSDictionary*)locationCellsMapping +{ + return @{ + @(RoomTimelineCellIdentifierLocation) : LocationBubbleCell.class, + @(RoomTimelineCellIdentifierLocationWithoutSenderInfo) : LocationWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierLocationWithPaginationTitle) : LocationWithPaginationTitleBubbleCell.class + }; +} + + +@end From dc8e5cc8b6ef952e9c8b79d6aa787d08d02b5698 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 17:33:21 +0100 Subject: [PATCH 066/209] Add BubbleRoomTimelineCellProvider. --- .../Bubble/BubbleRoomTimelineCellProvider.h | 25 +++++++++ .../Bubble/BubbleRoomTimelineCellProvider.m | 56 +++++++++++++++++++ 2 files changed, 81 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.h create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.h b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.h new file mode 100644 index 000000000..a389242cc --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.h @@ -0,0 +1,25 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "PlainRoomTimelineCellProvider.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface BubbleRoomTimelineCellProvider : PlainRoomTimelineCellProvider + +@end + +NS_ASSUME_NONNULL_END diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m new file mode 100644 index 000000000..e1329b190 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m @@ -0,0 +1,56 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#import "BubbleRoomTimelineCellProvider.h" + +#import "RoomOutgoingTextMsgBubbleCell.h" +#import "RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" + +#import "RoomOutgoingEncryptedTextMsgBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" + +#import "RoomOutgoingAttachmentBubbleCell.h" +#import "RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" + +@implementation BubbleRoomTimelineCellProvider + +- (NSDictionary*)outgoingTextMessageCellsMapping +{ + // Hide sender info and avatar for bubble outgoing messages + return @{ + // Clear + @(RoomTimelineCellIdentifierOutgoingTextMessage) : RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderInfo) : RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitle) : RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderName) : RoomOutgoingTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitleWithoutSenderName) : RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierOutgoingTextMessageEncrypted) : RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitle) : RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderName) : RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitleWithoutSenderName) : RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class, + }; +} + +@end From 97e51544211763c23e22209e105892d9ced0c9cb Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 17:33:57 +0100 Subject: [PATCH 067/209] Add RoomTimelineCellProviders to bridging header. --- Riot/SupportingFiles/Riot-Bridging-Header.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/SupportingFiles/Riot-Bridging-Header.h b/Riot/SupportingFiles/Riot-Bridging-Header.h index c5a22e8a7..ed95cb775 100644 --- a/Riot/SupportingFiles/Riot-Bridging-Header.h +++ b/Riot/SupportingFiles/Riot-Bridging-Header.h @@ -46,6 +46,9 @@ #import "NSArray+Element.h" #import "ShareItemSender.h" #import "HTMLFormatter.h" +#import "RoomTimelineCellProviderProtocol.h" +#import "PlainRoomTimelineCellProvider.h" +#import "BubbleRoomTimelineCellProvider.h" // MatrixKit common imports, shared with all targets #import "MatrixKit-Bridging-Header.h" From cc3b5d55fa302bf2cf670033c36adadb96bd3a75 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 17:36:13 +0100 Subject: [PATCH 068/209] Add RoomTimelineCellIdentifier that represents room timeline cell identifiers. --- .../BubbleCells/RoomTimelineCellIdentifier.h | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellIdentifier.h diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellIdentifier.h b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellIdentifier.h new file mode 100644 index 000000000..35a3b500a --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineCellIdentifier.h @@ -0,0 +1,115 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/// RoomTimelineCellIdentifier represents room timeline cell identifiers. +typedef NS_ENUM(NSUInteger, RoomTimelineCellIdentifier) { + + RoomTimelineCellIdentifierUnknown, + + // - Text message + // -- Incoming + // --- Clear + RoomTimelineCellIdentifierIncomingTextMessage, + RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderInfo, + RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitle, + RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderName, + RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitleWithoutSenderName, + // --- Encrypted + RoomTimelineCellIdentifierIncomingTextMessageEncrypted, + RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderInfo, + RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitle, + RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderName, + RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitleWithoutSenderName, + // -- Outgoing + // --- Clear + RoomTimelineCellIdentifierOutgoingTextMessage, + RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderInfo, + RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitle, + RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderName, + RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitleWithoutSenderName, + // --- Encrypted + RoomTimelineCellIdentifierOutgoingTextMessageEncrypted, + RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderInfo, + RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitle, + RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderName, + RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitleWithoutSenderName, + + // - Attachment + // -- Incoming + // --- Clear + RoomTimelineCellIdentifierIncomingAttachment, + RoomTimelineCellIdentifierIncomingAttachmentWithoutSenderInfo, + RoomTimelineCellIdentifierIncomingAttachmentWithPaginationTitle, + // --- Encrypted + RoomTimelineCellIdentifierIncomingAttachmentEncrypted, + RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithoutSenderInfo, + RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithPaginationTitle, + // -- Outgoing + // --- Clear + RoomTimelineCellIdentifierOutgoingAttachment, + RoomTimelineCellIdentifierOutgoingAttachmentWithoutSenderInfo, + RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle, + // --- Encrypted + RoomTimelineCellIdentifierOutgoingAttachmentEncrypted, + RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo, + RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithPaginationTitle, + + // - Room membership + RoomTimelineCellIdentifierMembership, + RoomTimelineCellIdentifierMembershipWithPaginationTitle, + RoomTimelineCellIdentifierMembershipCollapsed, + RoomTimelineCellIdentifierMembershipCollapsedWithPaginationTitle, + RoomTimelineCellIdentifierMembershipExpanded, + RoomTimelineCellIdentifierMembershipExpandedWithPaginationTitle, + + // - Key verification + RoomTimelineCellIdentifierKeyVerificationIncomingRequestApproval, + RoomTimelineCellIdentifierKeyVerificationIncomingRequestApprovalWithPaginationTitle, + RoomTimelineCellIdentifierKeyVerificationRequestStatus, + RoomTimelineCellIdentifierKeyVerificationRequestStatusWithPaginationTitle, + RoomTimelineCellIdentifierKeyVerificationConclusion, + RoomTimelineCellIdentifierKeyVerificationConclusionWithPaginationTitle, + + // - Room creation + RoomTimelineCellIdentifierRoomCreationCollapsed, + RoomTimelineCellIdentifierRoomCreationCollapsedWithPaginationTitle, + + // - Call + RoomTimelineCellIdentifierDirectCallStatus, + RoomTimelineCellIdentifierGroupCallStatus, + + // - Voice message + RoomTimelineCellIdentifierVoiceMessage, + RoomTimelineCellIdentifierVoiceMessageWithoutSenderInfo, + RoomTimelineCellIdentifierVoiceMessageWithPaginationTitle, + + // - Poll + RoomTimelineCellIdentifierPoll, + RoomTimelineCellIdentifierPollWithoutSenderInfo, + RoomTimelineCellIdentifierPollWithPaginationTitle, + + // - Location sharing + RoomTimelineCellIdentifierLocation, + RoomTimelineCellIdentifierLocationWithoutSenderInfo, + RoomTimelineCellIdentifierLocationWithPaginationTitle, + + // - Others + RoomTimelineCellIdentifierEmpty, + RoomTimelineCellIdentifierSelectedSticker, + RoomTimelineCellIdentifierRoomPredecessor, + RoomTimelineCellIdentifierRoomCreationIntro, + RoomTimelineCellIdentifierTyping +}; From 29ff465e4ef34588aaa1ff84985810b025a7c25c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 18:19:46 +0100 Subject: [PATCH 069/209] Update MatrixKit bridging header. --- Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h b/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h index 1653472db..3f50b38c7 100644 --- a/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h +++ b/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h @@ -14,3 +14,6 @@ #import "MXKRoomInputToolbarView.h" #import "MXKImageView.h" +#import "MXKRoomBubbleTableViewCell.h" +#import "MXKRoomBubbleCellData.h" +#import "MXKRoomBubbleTableViewCell.h" From 38d10e13c2552b70220541b20d18ee075d3f592f Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 18:20:57 +0100 Subject: [PATCH 070/209] Add RoomCellLayoutUpdaterProtocol that enables to setup or update a room timeline cell view. --- .../RoomCellLayoutUpdaterProtocol.swift | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift new file mode 100644 index 000000000..8b56c19e3 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift @@ -0,0 +1,28 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// Enables to setup or update a room timeline cell view +@objc +protocol RoomCellLayoutUpdaterProtocol: AnyObject { + + func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) + + func setupLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell) + + func setupLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell) +} From 90a50e10e1841eac1224c6e77fa39ea9cbfdede8 Mon Sep 17 00:00:00 2001 From: Doug Date: Thu, 13 Jan 2022 17:23:35 +0000 Subject: [PATCH 071/209] Add instructions for creating analytics events. --- Riot/Modules/Analytics/Analytics.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 535ca7b2a..6a48f5c6c 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -19,6 +19,16 @@ import AnalyticsEvents /// A class responsible for managing an analytics client /// and sending events through this client. +/// +/// ## Creating Analytics Events +/// +/// Events are managed in a shared repo for all Element clients https://github.com/matrix-org/matrix-analytics-events +/// To add a new event create a PR to that repo with the new/updated schema. +/// Once merged into `main`, follow the steps below to integrate the changes into the project: +/// 1. Merge `main` into the `release/swift` branch. +/// 2. Run `bundle exec pod update AnalyticsEvents` to update the pod. +/// 3. Make sure to commit `Podfile.lock` with the new commit hash. +/// @objcMembers class Analytics: NSObject { // MARK: - Properties From 0b8b131272488245d26f2e8e5bc7d7e121dc8e1f Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 13 Jan 2022 18:25:34 +0100 Subject: [PATCH 072/209] Move RoomBubbleCellLayout. --- .../Views/BubbleCells/{Encryption => }/RoomBubbleCellLayout.swift | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/{Encryption => }/RoomBubbleCellLayout.swift (100%) diff --git a/Riot/Modules/Room/Views/BubbleCells/Encryption/RoomBubbleCellLayout.swift b/Riot/Modules/Room/Views/BubbleCells/RoomBubbleCellLayout.swift similarity index 100% rename from Riot/Modules/Room/Views/BubbleCells/Encryption/RoomBubbleCellLayout.swift rename to Riot/Modules/Room/Views/BubbleCells/RoomBubbleCellLayout.swift From 2e5f8cf3d75d119f59cd7ed72b1082ddfc2cc26f Mon Sep 17 00:00:00 2001 From: jelv Date: Wed, 12 Jan 2022 09:49:29 +0000 Subject: [PATCH 073/209] Translated using Weblate (Dutch) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ --- Riot/Assets/nl.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/nl.lproj/Vector.strings b/Riot/Assets/nl.lproj/Vector.strings index 65b0d41c6..c400a6ba9 100644 --- a/Riot/Assets/nl.lproj/Vector.strings +++ b/Riot/Assets/nl.lproj/Vector.strings @@ -1583,7 +1583,7 @@ "space_private_join_rule" = "Privé Space"; "space_participants_action_ban" = "Uit deze Space verbannen"; "space_participants_action_remove" = "Uit deze kamer verwijderen"; -"spaces_coming_soon_detail" = "Deze functies is nog niet klaar, maar er wordt aan gewerkt. Voor nu kan u dit wel doen met Element via uw computer."; +"spaces_coming_soon_detail" = "Deze functies is nog niet klaar, maar er wordt aan gewerkt. Voor nu kan u dit wel doen met %@ via uw computer."; "spaces_invites_coming_soon_title" = "Uitnodigen komt binnenkort"; "spaces_add_rooms_coming_soon_title" = "Kamers toevoegen komt binnenkort"; "spaces_coming_soon_title" = "Komt binnenkort"; @@ -1680,7 +1680,7 @@ "analytics_prompt_terms_new_user" = "U kunt al onze voorwaarden %@ lezen."; "analytics_prompt_terms_link_new_user" = "hier"; "analytics_prompt_message_upgrade" = "U heeft eerder toestemming gegeven om anonieme gebruiksgegevens met ons te delen. Om beter te begrijpen hoe mensen meerdere apparaten gebruiken, genereren we nu een willekeurige identificatiecode die door uw apparaten wordt gedeeld."; -"analytics_prompt_message_new_user" = "Help ons bij het identificeren van problemen en het verbeteren van Element door anonieme gebruiksgegevens te delen. Om te begrijpen hoe mensen meerdere apparaten gebruiken genereren we een willekeurige identificatie die we verspreiden over uw apparaten."; +"analytics_prompt_message_new_user" = "Help ons bij het identificeren van problemen en het verbeteren van %@ door anonieme gebruiksgegevens te delen. Om te begrijpen hoe mensen meerdere apparaten gebruiken genereren we een willekeurige identificatie die we verspreiden over uw apparaten."; // Analytics "analytics_prompt_title" = "Help %@ verbeteren"; @@ -1690,3 +1690,19 @@ "room_event_action_remove_poll" = "Poll verwijderen"; "accessibility_button_label" = "knop"; "enable" = "Inschakelen"; +"location_sharing_settings_toggle_title" = "Locatie delen inschakelen"; +"location_sharing_settings_header" = "Locatie delen"; +"location_sharing_open_google_maps" = "In Google Maps openen"; +"location_sharing_open_apple_maps" = "In Apple Maps openen"; +"location_sharing_invalid_authorization_settings" = "Instellingen"; +"location_sharing_invalid_authorization_not_now" = "Niet nu"; +"location_sharing_invalid_authorization_error_title" = "%@ heeft geen toegang tot uw locatie. U kan dit inschakelen via Instellingen > Locatie"; +"location_sharing_locating_user_error_title" = "%@ heeft geen toegang tot uw locatie. Probeer het later opnieuw."; +"location_sharing_loading_map_error_title" = "%@ kan de kaart niet laden. Probeer het later opnieuw."; +"location_sharing_share_action" = "Delen"; +"location_sharing_close_action" = "Sluiten"; + +// MARK: - Location sharing + +"location_sharing_title" = "Locatie"; +"ok" = "OK"; From c2ca4d5e2bd92ffada7b6b0c7069c5caed85c208 Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Wed, 12 Jan 2022 15:38:25 +0000 Subject: [PATCH 074/209] Translated using Weblate (German) Currently translated at 99.8% (1383 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index f0fb19fc2..5ac4981e8 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -140,8 +140,8 @@ "room_participants_action_ban" = "Aus diesem Raum bannen"; "room_participants_action_ignore" = "Alle Nachrichten von diesem Nutzer verbergen"; "room_participants_action_unignore" = "Zeige alle Nachrichten von diesem Nutzer"; -"room_participants_action_set_moderator" = "Gib Moderationsrechte"; -"room_participants_action_set_admin" = "Mache zum Administrator"; +"room_participants_action_set_moderator" = "Moderationsrechte vergeben"; +"room_participants_action_set_admin" = "Administrationsrechte vergeben"; "room_participants_action_start_new_chat" = "Starte neuen Chat"; "room_participants_action_start_video_call" = "Starte Video-Anruf"; "room_participants_action_mention" = "Erwähnen"; @@ -544,7 +544,7 @@ "room_event_action_view_decrypted_source" = "Zeige entschlüsselten Quelltext"; "room_recents_server_notice_section" = "SYSTEMBENACHRICHTIGUNGEN"; "room_resource_limit_exceeded_message_contact_1" = " Bitte "; -"room_resource_limit_exceeded_message_contact_2_link" = "kontaktiere deinen Dienst-Administrator"; +"room_resource_limit_exceeded_message_contact_2_link" = "kontaktiere deine Dienst-Administration"; "room_resource_limit_exceeded_message_contact_3" = " um diesen Dienst weiter zu nutzen."; "homeserver_connection_lost" = "Konnte keine Verbindung zum Heimserver herstellen."; "room_resource_usage_limit_reached_message_1_default" = "Dieser Heimserver hat eine seiner Ressourcengrenzen überschritten, sodass "; @@ -734,7 +734,7 @@ "close" = "Schließen"; "auth_softlogout_signed_out" = "Du bist abgemeldet"; "auth_softlogout_sign_in" = "Anmelden"; -"auth_softlogout_reason" = "Deine Heimserver-Administrator (%1$@) hat dich von deinem Konto %2$@ (%3$@) abgemeldet."; +"auth_softlogout_reason" = "Die Administration deines Heimservers (%1$@) hat dich von deinem Konto %2$@ (%3$@) abgemeldet."; "auth_softlogout_recover_encryption_keys" = "Melde dich an, um ausschließlich auf diesem Gerät gespeicherte Verschlüsselungsschlüssel wiederherzustellen. Du benötigst sie, um deine verschlüsselten Nachrichten auf jedem Gerät zu lesen."; "auth_softlogout_clear_data" = "Persönliche Daten löschen"; "auth_softlogout_clear_data_message_1" = "Warnung: Deine persönlichen Daten (einschließlich Verschlüsselungsschlüssel) sind noch auf diesem Gerät gespeichert."; @@ -1464,7 +1464,7 @@ "spaces_add_rooms_coming_soon_title" = "Räume hinzufügen ist bald verfügbar"; "spaces_no_result_found_title" = "Keine Ergebnisse gefunden"; "spaces_suggested_room" = "Vorgeschlagen"; -"leave_space_message_admin_warning" = "Du bist Administrator in diesem Space, stelle vor dem Verlassen sicher, dass du die Administrator-Rechte auf ein anderes Mitglied übertragen hast."; +"leave_space_message_admin_warning" = "Du besitzt in diesem Space Administrationsrechte, stelle vor dem Verlassen sicher, dass du die Administrationsrechte auf ein anderes Mitglied übertragen hast."; "leave_space_message" = "Bist du dir sicher, dass du %@ verlassen möchtest? Möchtest du außerdem alle Räume und Spaces in diesem Space verlassen?"; "leave_space_title" = "%@ verlassen"; "space_avatar_view_accessibility_hint" = "Space-Avatar ändern"; @@ -1567,3 +1567,19 @@ "analytics_prompt_point_1" = "Wir erfassen und analysieren keine Accountdaten"; /* Note: The placeholder is for the contents of analytics_prompt_terms_link_upgrade */ "analytics_prompt_terms_upgrade" = "Alle unsere Bedingungen lesen %@. Bist du damit einverstanden?"; +"ok" = "OK"; +"location_sharing_settings_toggle_title" = "Standortfreigabe aktivieren"; +"location_sharing_settings_header" = "Standortfreigabe"; +"location_sharing_open_google_maps" = "In Google Maps öffnen"; +"location_sharing_open_apple_maps" = "In Apple Karten öffnen"; +"location_sharing_invalid_authorization_settings" = "Einstellungen"; +"location_sharing_invalid_authorization_not_now" = "Nicht jetzt"; +"location_sharing_invalid_authorization_error_title" = "%@ besitzt keine Berechtigung um auf deinen Standort zuzugreifen. Du kannst den Zugriff unter Einstellungen > Standort erlauben"; +"location_sharing_locating_user_error_title" = "%@ konnte nicht auf deinen Standort zugreifen. Bitte versuche es später noch einmal."; +"location_sharing_loading_map_error_title" = "%@ konnte die Karte nicht laden. Bitte versuche es später noch einmal."; +"location_sharing_share_action" = "Teilen"; +"location_sharing_close_action" = "Schließen"; + +// MARK: - Location sharing + +"location_sharing_title" = "Standort"; From 4262debdf43318f18e91d0b5931f276f4eb3298d Mon Sep 17 00:00:00 2001 From: Thomas Schmidt Date: Wed, 12 Jan 2022 00:20:15 +0000 Subject: [PATCH 075/209] Translated using Weblate (German) Currently translated at 99.8% (1383 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index 5ac4981e8..bb433b561 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -1459,7 +1459,7 @@ // Mark: Avatar "space_avatar_view_accessibility_label" = "Avatar"; -"spaces_coming_soon_detail" = "Diese Funktion wurde hier noch nicht eingebaut, kommt aber bald. So lange kannst du dafür Element am Computer nutzen."; +"spaces_coming_soon_detail" = "Diese Funktion wurde hier noch nicht eingebaut, kommt aber bald. So lange kannst du dafür %@ am Computer nutzen."; "spaces_invites_coming_soon_title" = "Einladungen sind bald verfügbar"; "spaces_add_rooms_coming_soon_title" = "Räume hinzufügen ist bald verfügbar"; "spaces_no_result_found_title" = "Keine Ergebnisse gefunden"; @@ -1534,7 +1534,7 @@ "settings_about" = "ÜBER"; "enable" = "Aktivieren"; "analytics_prompt_message_upgrade" = "Du hast in der Vergangenheit bereits zugestimmt anonyme Nutzungsdaten mit uns zu teilen. Jetzt werden wir als Hilfe, um zu verstehen, wie Personen mehrere Geräte benutzen, eine zufällige Kennung generieren, die zwischen deinen Geräten geteilt wird."; -"analytics_prompt_message_new_user" = "Hilf uns dabei Probleme zu identifizieren und Element zu verbessern, indem du anonyme Nutzungsdaten teilst. Um zu verstehen, wie Personen mehrere Geräte benutzen, werden wir eine zufällige Kennung generieren, die zwischen deinen Geräten geteilt wird."; +"analytics_prompt_message_new_user" = "Hilf uns dabei Probleme zu identifizieren und %@ zu verbessern, indem du anonyme Nutzungsdaten teilst. Um zu verstehen, wie Personen mehrere Geräte benutzen, werden wir eine zufällige Kennung generieren, die zwischen deinen Geräten geteilt wird."; "find_your_contacts_title" = "Starte mit der Auflistung deiner Kontakte"; /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Du kannst unsere gesamten Bedingungen %@ nachlesen."; From 4bb9b41e1c86911e1ed0d8cd25e12f68b3e9a204 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Tue, 11 Jan 2022 20:20:07 +0000 Subject: [PATCH 076/209] Translated using Weblate (Hungarian) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ --- Riot/Assets/hu.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings index 6060f16c3..dd01bbcac 100644 --- a/Riot/Assets/hu.lproj/Vector.strings +++ b/Riot/Assets/hu.lproj/Vector.strings @@ -1483,7 +1483,7 @@ "space_private_join_rule" = "Privát tér"; "space_participants_action_ban" = "Kitiltás a térről"; "space_participants_action_remove" = "Eltávolítás a térről"; -"spaces_coming_soon_detail" = "Ez a lehetőség még nincs meg, de fejlesztés alatt van. Egyenlőre a számítógépeden Elementtel tudod ezt megtenni."; +"spaces_coming_soon_detail" = "Ez a lehetőség még nincs meg, de fejlesztés alatt van. Egyenlőre a számítógépeden %@ alkalmazással tudod ezt megtenni."; "spaces_invites_coming_soon_title" = "Meghívók küldése hamarosan érkezik"; "spaces_add_rooms_coming_soon_title" = "Szobák hozzáadása hamarosan érkezik"; "spaces_coming_soon_title" = "Hamarosan"; @@ -1579,7 +1579,7 @@ "analytics_prompt_terms_link_new_user" = "itt"; /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Az összes feltételünket elolvashatod itt: %@."; -"analytics_prompt_message_new_user" = "Segíts észrevennünk a hibákat, és jobbá tenni az Element-et a névtelen használati adatok küldése által. Ahhoz, hogy megértsük, hogyan használnak a felhasználók egyszerre több eszközt, egy véletlenszerű azonosítót generálunk, ami az eszközeid között meg lesz osztva."; +"analytics_prompt_message_new_user" = "Segíts észrevennünk a hibákat, és jobbá tenni a(z) %@ alkalmazást a névtelen használati adatok küldése által. Ahhoz, hogy megértsük, hogyan használnak a felhasználók egyszerre több eszközt, egy véletlenszerű azonosítót generálunk, ami az eszközeid között meg lesz osztva."; // Analytics "analytics_prompt_title" = "Segíts jobbá tenni %@"; @@ -1590,3 +1590,19 @@ "accessibility_button_label" = "gomb"; "enable" = "Engedélyezés"; "analytics_prompt_message_upgrade" = "Korábban beleegyeztél, hogy velünk anonimizált adatokat osztasz meg. Most, hogy jobban megértsük, hogyan használnak több eszközt az emberek, véletlenszerű azonosítót állítunk elő amit az eszközeid használni fognak."; +"location_sharing_settings_toggle_title" = "Földrajzi hely megosztás engedélyezése"; +"location_sharing_settings_header" = "Földrajzi hely megosztása"; +"location_sharing_open_google_maps" = "Megnyitás a Google Térképen"; +"location_sharing_open_apple_maps" = "Megnyitás az Apple Térképen"; +"location_sharing_invalid_authorization_settings" = "Beállítások"; +"location_sharing_invalid_authorization_not_now" = "Nem most"; +"location_sharing_invalid_authorization_error_title" = "%@ alkalmazásnak nincs jogosultsága a helyadatod eléréséhez. Engedélyezheted a Beállítások > Helyadatokban"; +"location_sharing_loading_map_error_title" = "%@ nem tudja betölteni a térképet. Próbáld újra később."; +"location_sharing_locating_user_error_title" = "%@ nem fér hozzá a helyadatodhoz. Próbáld újra később."; +"location_sharing_share_action" = "Megoszt"; +"location_sharing_close_action" = "Bezár"; + +// MARK: - Location sharing + +"location_sharing_title" = "Földrajzi helyzet"; +"ok" = "OK"; From ef3876a4b691684487e12de64d2f5f8c8e13bfdc Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Tue, 11 Jan 2022 15:10:07 +0000 Subject: [PATCH 077/209] Translated using Weblate (Albanian) Currently translated at 99.6% (1380 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sq/ --- Riot/Assets/sq.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings index bca45030c..4aacf6cb9 100644 --- a/Riot/Assets/sq.lproj/Vector.strings +++ b/Riot/Assets/sq.lproj/Vector.strings @@ -1471,7 +1471,7 @@ "space_private_join_rule" = "Hapësirë private"; "space_participants_action_ban" = "Dëboje prej kësaj hapësire"; "space_participants_action_remove" = "Hiqe prej kësaj hapësire"; -"spaces_coming_soon_detail" = "Kjo veçori s’është sendërtuar këtu, por po bëhet. Tani për tani, mund ta bëni këtë me Element-in në kompjuterin tuaj."; +"spaces_coming_soon_detail" = "Kjo veçori s’është sendërtuar këtu, por po bëhet. Tani për tani, mund ta bëni këtë me %@-in në kompjuterin tuaj."; "spaces_invites_coming_soon_title" = "Ftesat vijnë së shpejti"; "spaces_add_rooms_coming_soon_title" = "Shtimi i dhomave vjen së shpejti"; "spaces_coming_soon_title" = "S’afërmi"; @@ -1565,7 +1565,7 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Mund të lexoni krejt kushtet tona %@."; "analytics_prompt_message_upgrade" = "Keni pranuar më herët të ndani me ne të dhëna anonime përdorimi. Tani, që të na ndihmoni të kuptojmë se si njerëzit përdorin pajisje të shumta, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja."; -"analytics_prompt_message_new_user" = "Ndihmonani të identifikojmë probleme dhe të përmirësojmë Element-in, duke ndarë me ne të dhëna anonime përdorimi. Për të kuptuar se si i përdorin njerëzit disa pajisje njëherësh, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja."; +"analytics_prompt_message_new_user" = "Ndihmonani të identifikojmë probleme dhe të përmirësojmë %@-in, duke ndarë me ne të dhëna anonime përdorimi. Për të kuptuar se si i përdorin njerëzit disa pajisje njëherësh, do të prodhojmë një identifikues kuturu, të përbashkët për pajisjet tuaja."; // Analytics "analytics_prompt_title" = "Ndihmoni të përmirësohet %@"; @@ -1579,3 +1579,19 @@ "accessibility_button_label" = "kopsë"; "open" = "Hapur"; "enable" = "Aktivizoje"; +"location_sharing_settings_toggle_title" = "Aktivizoni tregim vendndodhjeje"; +"location_sharing_settings_header" = "Tregim vendndodhjeje"; +"location_sharing_open_google_maps" = "Hape në Google Maps"; +"location_sharing_open_apple_maps" = "Hape në Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Rregullime"; +"location_sharing_invalid_authorization_not_now" = "Jo tani"; +"location_sharing_locating_user_error_title" = "%@ s’njohu dot vendndodhjen tuaj. Ju lutemi, riprovoni më vonë."; +"location_sharing_invalid_authorization_error_title" = "%@ s’ka leje të njohë vendndodhjen tuaj. Njohjen mund ta lejoni që nga Rregullime > Vendndodhje"; +"location_sharing_loading_map_error_title" = "%@ s’ngarkoi dot hartën. Ju lutemi, riprovoni më vonë."; +"location_sharing_share_action" = "Ndajeni me të tjerë"; +"location_sharing_close_action" = "Mbylle"; + +// MARK: - Location sharing + +"location_sharing_title" = "Vendndodhje"; +"ok" = "OK"; From f396f0abb82fba841f053e6e95b56d55115d7c1d Mon Sep 17 00:00:00 2001 From: random Date: Tue, 11 Jan 2022 13:21:17 +0000 Subject: [PATCH 078/209] Translated using Weblate (Italian) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ --- Riot/Assets/it.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings index 797589e89..e45714f45 100644 --- a/Riot/Assets/it.lproj/Vector.strings +++ b/Riot/Assets/it.lproj/Vector.strings @@ -1454,7 +1454,7 @@ "space_private_join_rule" = "Spazio privato"; "space_participants_action_ban" = "Bandisci da questo spazio"; "space_participants_action_remove" = "Rimuovi da questo spazio"; -"spaces_coming_soon_detail" = "Questa funzionalità non è stata implementata qui, ma è in arrivo. Per adesso, puoi farlo con Element sul tuo computer."; +"spaces_coming_soon_detail" = "Questa funzionalità non è stata implementata qui, ma è in arrivo. Per adesso, puoi farlo con %@ sul tuo computer."; "spaces_invites_coming_soon_title" = "Inviti in arrivo"; "spaces_add_rooms_coming_soon_title" = "Aggiunta di stanze in arrivo"; "spaces_coming_soon_title" = "Prossimamente"; @@ -1554,10 +1554,26 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Puoi leggere i nostri termini di servizio %@."; "analytics_prompt_message_upgrade" = "Hai acconsentito precedentemente a condividere con noi dati di utilizzo anonimi. Ora, per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi."; -"analytics_prompt_message_new_user" = "Aiutaci a identificare problemi e a migliorare Element condividendo dati di utilizzo anonimi. Per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi."; +"analytics_prompt_message_new_user" = "Aiutaci a identificare problemi e a migliorare %@ condividendo dati di utilizzo anonimi. Per capire come le persone usano diversi dispositivi, genereremo un identificativo casuale, condiviso dai tuoi dispositivi."; // Analytics "analytics_prompt_title" = "Aiuta a migliorare %@"; "settings_analytics_and_crash_data" = "Invia crash e dati analitici"; "accessibility_button_label" = "pulsante"; "enable" = "Attiva"; +"location_sharing_settings_toggle_title" = "Attiva condivisione posizione"; +"location_sharing_settings_header" = "Condivisione posizione"; +"location_sharing_open_google_maps" = "Apri in Google Maps"; +"location_sharing_open_apple_maps" = "Apri in Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Impostazioni"; +"location_sharing_invalid_authorization_not_now" = "Non ora"; +"location_sharing_invalid_authorization_error_title" = "%@ non ha l'autorizzazione per accedere alla tua posizione. Puoi attivarne l'accesso in Impostazioni > Localizzazione"; +"location_sharing_locating_user_error_title" = "%@ non ha potuto rilevare la tua posizione. Riprova più tardi."; +"location_sharing_loading_map_error_title" = "%@ non ha potuto caricare la mappa. Riprova più tardi."; +"location_sharing_share_action" = "Condividi"; +"location_sharing_close_action" = "Chiudi"; + +// MARK: - Location sharing + +"location_sharing_title" = "Posizione"; +"ok" = "OK"; From 12979692ad2acee2ee5bc4b11778cab6f7a7baf2 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Tue, 11 Jan 2022 13:34:37 +0000 Subject: [PATCH 079/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ --- Riot/Assets/pt_BR.lproj/Vector.strings | 76 ++++++++++++++++---------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index 7820fc1f4..045ebd3f5 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -87,7 +87,7 @@ "auth_reset_password_error_unauthorized" = "Falha para verificar endereço de email: assegure que você clicou no link no email"; "auth_reset_password_error_not_found" = "Seu endereço de email não parece estar associado com uma ID Matrix neste servidorcasa."; "auth_reset_password_success_message" = "Sua senha tem sido resettada.\n\nVocê tem sido feito logout de todas as sessões e não vai mais receber notificações push. Para re-habilitar notificações, refaça login em cada dispositivo."; -"auth_add_email_and_phone_warning" = "Registro com email e número de telefone ao mesmo tempo não é suportado ainda até que a api exista. Somente o número de telefone vai ser levado em conta. Você pode adicionar seu email a seu perfil em configurações."; +"auth_add_email_and_phone_warning" = "Registro com email e número de telefone ao mesmo tempo não é suportado ainda até que a api exista. Somente o número de telefone vai ser levado em conta. Você pode adicionar seu email a seu perfil em ajustes."; "room_creation_appearance" = "Aparência"; "room_creation_appearance_name" = "Nome"; "room_creation_appearance_picture" = "Imagem de Chat (opcional)"; @@ -275,7 +275,7 @@ "room_preview_try_join_an_unknown_room" = "Você está tentando acessar %@. Você gostaria de se juntar para participar na discussão?"; "room_preview_try_join_an_unknown_room_default" = "uma sala"; // Settings -"settings_title" = "Configurações"; +"settings_title" = "Ajustes"; "account_logout_all" = "Fazer logout de todas as contas"; "settings_config_no_build_info" = "Nenhuma info de build"; "settings_mark_all_as_read" = "Marcar todas as mensagens como lidas"; @@ -283,7 +283,7 @@ "settings_config_home_server" = "Servidorcasa é %@"; "settings_config_identity_server" = "Servidor de identidade é %@"; "settings_config_user_id" = "Feito login como %@"; -"settings_user_settings" = "CONFIGURAÇÕES DE USUÁRIA(O)"; +"settings_user_settings" = "AJUSTES DE USUÁRIA(O)"; "settings_notifications_settings" = "CONFIGURAÇÕES DE NOTIFICAÇÃO"; "settings_calls_settings" = "CHAMADAS"; "settings_user_interface" = "INTERFACE DE USUÁRIA(O)"; @@ -316,7 +316,7 @@ "settings_fail_to_update_profile" = "Falha para atualizar perfil"; "settings_enable_push_notif" = "Notificações neste dispositivo"; "settings_show_decrypted_content" = "Mostrar conteúdo decriptado"; -"settings_global_settings_info" = "Configurações de notificação globais estão disponíveis em seu cliente web %@"; +"settings_global_settings_info" = "Ajustes de notificação globais estão disponíveis em seu cliente web %@"; "settings_enable_callkit" = "Chamamento integrado"; "settings_callkit_info" = "Receba chamadas entrantes em sua tela de bloqueio. Veja suas chamadas %@ no histórico de chamadas do sistema. Se iCloud está habilitado, este histórico de chamadas vai ser compartilhado com Apple."; "settings_ui_language" = "Língua"; @@ -361,7 +361,7 @@ "settings_deactivate_my_account" = "Desativar minha conta"; "room_details_people" = "Membros"; "room_details_files" = "Uploads"; -"room_details_settings" = "Configurações"; +"room_details_settings" = "Ajustes"; "room_details_photo" = "Foto de Sala"; "room_details_room_name" = "Nome de Sala"; "room_details_topic" = "Tópico"; @@ -482,7 +482,7 @@ "bug_report_prompt" = "O aplicativo tem crashado da última vez. Você gostaria de submeter um reporte de crash?"; "rage_shake_prompt" = "Você parece estar agitando o telefone em frustração. Você gostaria de submeter um reporte de bug?"; "do_not_ask_again" = "Não perguntar de novo"; -"camera_access_not_granted" = "%@ não tem permissão para usar Câmera, por favor mude configurações de privacidade"; +"camera_access_not_granted" = "%@ não tem permissão para usar Câmera, por favor mude ajustes de privacidade"; "large_badge_value_k_format" = "%.1fK"; // Call "call_incoming_voice_prompt" = "Chamada de voz entrante de %@"; @@ -497,7 +497,7 @@ // Crash report "google_analytics_use_prompt" = "Você gostaria de ajudar a melhorar %@ ao reportar automaticamente reportes de crash e dados de uso anônimos?"; // Crypto -"e2e_enabling_on_app_update" = "%@ agora suporta encriptação ponta-a-ponta mas você precisa fazer login de novo para habilitá-la.\n\nVocê pode fazê-lo agora ou mais tarde desde as configurações do aplicativo."; +"e2e_enabling_on_app_update" = "%@ agora suporta encriptação ponta-a-ponta mas você precisa fazer login de novo para habilitá-la.\n\nVocê pode fazê-lo agora ou mais tarde desde os ajustes do aplicativo."; "e2e_need_log_in_again" = "Você precisa fazer login de volta para gerar chaves de encriptação ponta-a-ponta para esta sessão e submeter a chave pública a seu servidorcasa.\nIsto é só desta vez; desculpe pela inconveniência."; // Bug report "bug_report_title" = "Report de Bug"; @@ -528,7 +528,7 @@ "widget_integration_room_not_visible" = "Sala %@ não está visível."; // Share extension "share_extension_auth_prompt" = "Faça login no app principal para compartilhar conteúdo"; -"share_extension_failed_to_encrypt" = "Falha para enviar. Cheque no app principal as configurações de encriptação para esta sala"; +"share_extension_failed_to_encrypt" = "Falha para enviar. Cheque no app principal os ajustes de encriptação para esta sala"; // Room key request dialog "e2e_room_key_request_title" = "Requisição de chave de encriptação"; "e2e_room_key_request_message_new_device" = "Você adicionou uma nova sessão '%@', que está requisitando chaves de encriptação."; @@ -586,8 +586,8 @@ "room_does_not_exist" = "%@ não existe"; // Key backup wrong version "e2e_key_backup_wrong_version_title" = "Novo Backup de Chave"; -"e2e_key_backup_wrong_version" = "Um novo backup de chave de mensagem segura tem sido detectado.\n\nSe isto não foi você, defina uma nova Frase de Segurança em Configurações."; -"e2e_key_backup_wrong_version_button_settings" = "Configurações"; +"e2e_key_backup_wrong_version" = "Um novo backup de chave de mensagem segura tem sido detectado.\n\nSe isto não foi você, defina uma nova Frase de Segurança em Ajustes."; +"e2e_key_backup_wrong_version_button_settings" = "Ajustes"; "e2e_key_backup_wrong_version_button_wasme" = "Foi eu"; "key_backup_setup_title" = "Backup de Chave"; "key_backup_setup_skip_alert_title" = "Você tem certeza?"; @@ -625,7 +625,7 @@ "key_backup_recover_title" = "Mensagens Seguras"; "key_backup_recover_invalid_passphrase_title" = "Frase de Segurança Incorreta"; "key_backup_recover_invalid_passphrase" = "Backup não pôde ser decriptado com esta frase: por favor verifique que você entrou a Frase de Segurança correta."; -"key_backup_recover_invalid_recovery_key_title" = "Disparidade de Chave de Segurança"; +"key_backup_recover_invalid_recovery_key_title" = "Correspondência Errada de Chave de Segurança"; "key_backup_recover_invalid_recovery_key" = "Backup não pôde ser decriptografado com esta chave: por favor verifique que você entrou a Chave de Segurança correta."; "key_backup_recover_from_passphrase_info" = "Use sua Frase de Segurança para destrancar seu histórico de mensagens seguras"; "key_backup_recover_from_passphrase_passphrase_title" = "Entrar"; @@ -638,7 +638,7 @@ "key_backup_recover_from_recovery_key_recovery_key_title" = "Entrar"; "key_backup_recover_from_recovery_key_recovery_key_placeholder" = "Entrar Chave de Segurança"; "key_backup_recover_from_recovery_key_recover_action" = "Destrancar Histórico"; -"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "Perdeu sua Chave de Segurança? Você pode configurar uma nova em configurações."; +"key_backup_recover_from_recovery_key_lost_recovery_key_action" = "Perdeu sua Chave de Segurança? Você pode configurar uma nova em ajustes."; "key_backup_recover_success_info" = "Backup Restaurado!"; "key_backup_recover_done_action" = "Feito"; "key_backup_setup_banner_title" = "Nunca perca mensagens criptografadas"; @@ -677,7 +677,7 @@ "secure_key_backup_setup_existing_backup_error_unlock_it" = "Destrancá-lo"; "secure_key_backup_setup_existing_backup_error_delete_it" = "Deletá-lo"; "secure_key_backup_setup_cancel_alert_title" = "Você tem certeza?"; -"secure_key_backup_setup_cancel_alert_message" = "Se você cancelar agora, você pode perder mensagens & dados encriptados se você perder acesso a seus logins.\n\nVocê também pode configurar Backup Seguro & gerenciar suas chaves em Configurações."; +"secure_key_backup_setup_cancel_alert_message" = "Se você cancelar agora, você pode perder mensagens & dados encriptados se você perder acesso a seus logins.\n\nVocê também pode configurar Backup Seguro & gerenciar suas chaves em Ajustes."; "secure_backup_setup_banner_title" = "Backup Seguro"; "secure_backup_setup_banner_subtitle" = "Salvaguardar-se contra perda de acesso a mensagens & dados encriptados"; // Recover from private key @@ -722,7 +722,7 @@ "settings_integrations_allow_button" = "Gerenciar integrações"; "settings_integrations_allow_description" = "Use um gerenciador de integrações (%@) para gerenciar bots, bridges, widgets e pacotes de stickers.\n\nGerenciadores de integrações recebem dados de configuração, e podem modificar widgets, enviar convites de sala e definir níveis de poder em seu nome."; "settings_add_3pid_password_title_email" = "Adicionar endereço de email"; -"settings_discovery_three_pids_management_information_part2" = "Configurações de Usuária(o)"; +"settings_discovery_three_pids_management_information_part2" = "Ajustes de Usuária(o)"; "settings_discovery_three_pids_management_information_part3" = "."; "settings_discovery_three_pid_details_share_action" = "Compartilhar"; "settings_discovery_three_pid_details_revoke_action" = "Revogar"; @@ -747,7 +747,7 @@ // Media picker "media_picker_title" = "Biblioteca de mídia"; "image_picker_action_library" = "Escolher de biblioteca"; -"photo_library_access_not_granted" = "%@ não tem permissão para acessar biblioteca de fotos, por favor mude configurações de privacidade"; +"photo_library_access_not_granted" = "%@ não tem permissão para acessar biblioteca de fotos, por favor mude ajustes de privacidade"; "room_widget_permission_display_name_permission" = "Seu nome de exibição"; "device_verification_security_advice_emoji" = "Compare os emoji únicos, garantindo que eles aparecem na mesma ordem."; "device_verification_self_verify_alert_message" = "Verifique o novo login acessando sua conta: %@"; @@ -794,14 +794,14 @@ "identity_server_settings_disconnect_info" = "Desconectar-se de seu servidor de identidade vai significar que você não vai ser descobertável por outras(os) usuárias(os) e ser capaz de convidar outras(os) por email ou telefone."; "identity_server_settings_alert_disconnect_still_sharing_3pid" = "Você ainda está compartilhando seus dados pessoais no servidor de identidade %@.\n\nNós recomendamos que você remova seus endereços de email e números de telefone do servidor de identidade antes de se desconectar."; "call_no_stun_server_error_title" = "Chamada falhou devido a servidor malconfigurado"; -"widget_integration_manager_disabled" = "Você precisa habilitar gerenciador de integrações em configurações"; +"widget_integration_manager_disabled" = "Você precisa habilitar gerenciador de integrações em ajustes"; "service_terms_modal_description_for_identity_server_1" = "Encontrar outras(os) por telefone ou email"; "service_terms_modal_description_for_identity_server_2" = "Ser encontrada(o) por telefone ou email"; "device_verification_self_verify_wait_additional_information" = "Isto funciona com %@ e outros clientes Matrix capazes de assinatura cruzada."; "key_verification_verified_user_information" = "Mensagens com esta(e) usuária(o) são encriptadas ponta-a-ponta e não podem ser lidas por terceiros."; "device_verification_emoji_smiley" = "Smiley"; // Generic errors -"error_invite_3pid_with_no_identity_server" = "Adicione um servidor de identidade em suas configurações para convidar por email."; +"error_invite_3pid_with_no_identity_server" = "Adicione um servidor de identidade em seus ajustes para convidar por email."; "key_verification_bootstrap_not_setup_message" = "Você precisa fazer bootstrap de assinatura cruzada primeiro."; "user_verification_sessions_list_user_trust_level_warning_title" = "Aviso"; "user_verification_sessions_list_information" = "Mensagens com esta(e) usuária(o) nesta sala são encriptadas ponta-a-ponta e não podem ser lidas por terceiros."; @@ -907,7 +907,7 @@ "event_formatter_widget_added_by_you" = "Você adicionou o widget: %@"; "event_formatter_widget_removed_by_you" = "Você removeu o widget: %@"; "camera_unavailable" = "A câmera está indisponível em seu dispositivo"; -"call_no_stun_server_error_message_2" = "Alternativamente, você pode tentar usar o servidor público em %@, mas isto não vai ser tão confiável, e vai compartilhar seu endereço de IP com esse servidor. Você também pode gerenciar isto em Configurações"; +"call_no_stun_server_error_message_2" = "Alternativamente, você pode tentar usar o servidor público em %@, mas isto não vai ser tão confiável, e vai compartilhar seu endereço de IP com esse servidor. Você também pode gerenciar isto em Ajustes"; "call_no_stun_server_error_use_fallback_button" = "Tentar usar %@"; // Widget "widget_no_integrations_server_configured" = "Nenhum servidor de integrações configurado"; @@ -974,7 +974,7 @@ "key_verification_verify_sas_cancel_action" = "Eles não correspondem"; "key_verification_verify_sas_validate_action" = "Eles correspondem"; "key_verification_verify_sas_additional_information" = "Para segurança ótima, use um outro meio de comunicação confiado ou faça isto em pessoa."; -"key_verification_manually_verify_device_instruction" = "Confirme ao comparar o seguinte com as Configurações de Usuária(o) em sua outra sessão:"; +"key_verification_manually_verify_device_instruction" = "Confirme ao comparar o seguinte com os Ajustes de Usuária(o) em sua outra sessão:"; "key_verification_manually_verify_device_name_title" = "Nome de sessão"; "key_verification_manually_verify_device_id_title" = "ID de sessão"; "key_verification_manually_verify_device_key_title" = "Chave de sessão"; @@ -1350,7 +1350,7 @@ "side_menu_app_version" = "Versão %@"; "side_menu_action_feedback" = "Feedback"; "side_menu_action_help" = "Ajuda"; -"side_menu_action_settings" = "Configurações"; +"side_menu_action_settings" = "Ajustes"; "side_menu_action_invite_friends" = "Convidar amigas(os)"; // Mark: - Side menu @@ -1370,13 +1370,13 @@ "security_settings_secure_backup_reset" = "Resettar"; "security_settings_secure_backup_info_valid" = "Esta sessão está fazendo backup de suas chaves."; "security_settings_secure_backup_info_checking" = "Checando…"; -"settings_ui_theme_picker_message_match_system_theme" = "\"Auto\" corresponde ao tema de sistema de seu dispositivo"; -"settings_ui_theme_picker_message_invert_colours" = "\"Auto\" usa as configurações \"Inverter Cores\" de seu dispositivo"; +"settings_ui_theme_picker_message_match_system_theme" = "\"Auto\" corresponde com o tema de sistema de seu dispositivo"; +"settings_ui_theme_picker_message_invert_colours" = "\"Auto\" usa os ajustes \"Inverter Cores\" de seu dispositivo"; "room_recents_unknown_room_error_message" = "Não dá para encontrar esta sala. Assegure que ela existe"; "room_creation_dm_error" = "Nós não conseguimos criar sua DM. Por favor cheque as/os usuárias(os) que você quer convidar e tente de novo."; "key_verification_verify_qr_code_scan_code_other_device_action" = "Scannar com este dispositivo"; "room_notifs_settings_encrypted_room_notice" = "Por favor note que notificações de menções & palavrachave não estão disponíveis em salas encriptadas no celular."; -"room_notifs_settings_account_settings" = "Configurações de conta"; +"room_notifs_settings_account_settings" = "Ajustes de conta"; "room_notifs_settings_manage_notifications" = "Você pode gerenciar notificações em %@"; "room_notifs_settings_cancel_action" = "Cancelar"; "room_notifs_settings_done_action" = "Feito"; @@ -1395,7 +1395,7 @@ "voice_message_release_to_send" = "Segure para gravar, solte para enviar"; "settings_labs_voice_messages" = "Mensagens de voz"; "settings_notifications_disabled_alert_title" = "Notificações desabilitadas"; -"settings_notifications_disabled_alert_message" = "Para habilitar notificações, vá para suas configurações de dispositivo."; +"settings_notifications_disabled_alert_message" = "Para habilitar notificações, vá para os ajustes de seu dispositivo."; "settings_device_notifications" = "Notificações de dispositivo"; "event_formatter_call_incoming_video" = "Chamada de vídeo entrante"; "event_formatter_call_incoming_voice" = "Chamada de voz entrante"; @@ -1451,7 +1451,7 @@ "space_private_join_rule" = "Espaço privado"; "space_participants_action_ban" = "Banir deste espaço"; "space_participants_action_remove" = "Remover deste espaço"; -"spaces_coming_soon_detail" = "Esta funcionalidade não tem sido implementada ainda, mas está a caminho. Por enquanto, você pode fazer isso com Element em seu computador."; +"spaces_coming_soon_detail" = "Esta funcionalidade não tem sido implementada ainda, mas está a caminho. Por enquanto, você pode fazer isso com %@ em seu computador."; "spaces_invites_coming_soon_title" = "Convites chegando em breve"; "spaces_add_rooms_coming_soon_title" = "Adicionar salas chegando em breve"; "spaces_coming_soon_title" = "Chegando em breve"; @@ -1484,7 +1484,7 @@ "service_terms_modal_description_identity_server" = "Isto vai permitir alguém encontrar você se ela/ele tem seu número de telefone ou email salvo nos contatos de telefone dela/dele."; "service_terms_modal_table_header_integration_manager" = "TERMOS DE GERENCIADOR DE INTEGRAÇÕES"; "service_terms_modal_table_header_identity_server" = "TERMOS DE SERVIDOR DE IDENTIDADE"; -"service_terms_modal_footer" = "Isto pode ser desabilitado a qualquer hora em configurações."; +"service_terms_modal_footer" = "Isto pode ser desabilitado a qualquer hora em ajustes."; // Service terms "service_terms_modal_title_message" = "Para continuar, aceite os termos e condições abaixo"; @@ -1492,11 +1492,11 @@ "settings_contacts_enable_sync" = "Encontre seus contatos"; "settings_phone_contacts" = "CONTATOS DE TELEFONE"; "find_your_contacts_identity_service_error" = "Incapaz de se conectar ao servidor de identidade."; -"find_your_contacts_footer" = "Isto pode ser desabilitado a qualquer hora a partir de configurações."; +"find_your_contacts_footer" = "Isto pode ser desabilitado a qualquer hora a partir de ajustes."; "find_your_contacts_button_title" = "Encontre seus contatos"; "find_your_contacts_message" = "Deixe %@ mostrar seus contatos para que você possa rapidamente começar a conversar com aqueles que você conhece melhor."; "find_your_contacts_title" = "Comece por listar seus contatos"; -"contacts_address_book_permission_denied_alert_message" = "Para habilitar contatos, vá para as configurações de seu dispositivo."; +"contacts_address_book_permission_denied_alert_message" = "Para habilitar contatos, vá para os ajustes de seu dispositivo."; "contacts_address_book_permission_denied_alert_title" = "Contatos desabilitados"; "space_home_show_all_rooms" = "Mostrar todas as salas"; "room_event_action_forward" = "Encaminhar"; @@ -1539,7 +1539,7 @@ "analytics_prompt_stop" = "Parar de compartilhar"; "analytics_prompt_yes" = "Sim, pode ser"; "analytics_prompt_not_now" = "Não agora"; -"analytics_prompt_point_3" = "Você pode desativar isto a qualquer hora em configurações"; +"analytics_prompt_point_3" = "Você pode desativar isto a qualquer hora em ajustes"; /* Note: The word "don't" is formatted in bold */ "analytics_prompt_point_2" = "Nós não compartilhamos informação com terceiros"; /* Note: The word "don't" is formatted in bold */ @@ -1551,10 +1551,26 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Você pode ler todos os nossos termos %@."; "analytics_prompt_message_upgrade" = "Você previamente consentiu a compartilhar dados de uso anônimos conosco. Agora, para ajudar a entender como pessoas usam múltiplos dispositivos, nós vamos gerar um identificador aleatório, compartilhado por seus dispositivos."; -"analytics_prompt_message_new_user" = "Ajude-nos a identificar problemas e melhorar Element ao compartilhar dados de uso anônimos. Para entender como pessoas usam múltiplos dispositivos, nós geramos um identificador aleatório, compartilhado por seus dispositivos."; +"analytics_prompt_message_new_user" = "Ajude-nos a identificar problemas e melhorar %@ ao compartilhar dados de uso anônimos. Para entender como pessoas usam múltiplos dispositivos, nós geramos um identificador aleatório, compartilhado por seus dispositivos."; // Analytics "analytics_prompt_title" = "Ajudar a melhorar %@"; "settings_analytics_and_crash_data" = "Enviar dados de crash e analítica"; "accessibility_button_label" = "botão"; "enable" = "Habilitar"; +"location_sharing_settings_toggle_title" = "Habilitar compartilhamento de local"; +"location_sharing_settings_header" = "Compartilhamento de local"; +"location_sharing_invalid_authorization_error_title" = "%@ não tem permissão para acessar seu local. Você pode habilitar acesso em Ajustes > Local"; +"location_sharing_locating_user_error_title" = "%@ não pôde acessar seu local. Por favor tente de novo mais tarde."; + +// MARK: - Location sharing + +"location_sharing_title" = "Local"; +"location_sharing_open_google_maps" = "Abrir em Google Maps"; +"location_sharing_open_apple_maps" = "Abrir em Apple Mapas"; +"location_sharing_invalid_authorization_settings" = "Ajustes"; +"location_sharing_invalid_authorization_not_now" = "Não agora"; +"location_sharing_loading_map_error_title" = "%@ não pôde carregar o mapa. Por favor tente de novo mais tarde."; +"location_sharing_share_action" = "Compartilhar"; +"location_sharing_close_action" = "Fechar"; +"ok" = "OK"; From 9109d9c30844839c754c11cb60b228c5578f366c Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Tue, 11 Jan 2022 12:46:54 +0000 Subject: [PATCH 080/209] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ --- Riot/Assets/uk.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/uk.lproj/Vector.strings b/Riot/Assets/uk.lproj/Vector.strings index 7694f2d5e..3cbda465e 100644 --- a/Riot/Assets/uk.lproj/Vector.strings +++ b/Riot/Assets/uk.lproj/Vector.strings @@ -1414,7 +1414,7 @@ "spaces_no_room_found_detail" = "Деяких результатів може бути не видно, бо вони закриті й потребують запрошення."; "spaces_no_member_found_detail" = "Шукаєте когось, хто ще не в %@? Запросіть їх вебпереглядачем або комп'ютером."; "spaces_invites_coming_soon_title" = "Запрошення ще в розробці"; -"spaces_coming_soon_detail" = "Ця можливість тут іще не втілена, але скоро буде. Поки що можете зробити це в Element на комп'ютері."; +"spaces_coming_soon_detail" = "Ця можливість ще не втілена, але скоро буде. Поки що можете зробити це в %@ на комп'ютері."; "space_participants_action_remove" = "Вилучити з цього простору"; "space_participants_action_ban" = "Заблокувати в цьому просторі"; @@ -1476,7 +1476,7 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Можете прочитати всі наші умови %@."; "analytics_prompt_message_upgrade" = "Раніше ви погодилися надсилати нам анонімні дані про використання. Тепер, щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор."; -"analytics_prompt_message_new_user" = "Допомагайте нам визначати проблеми й удосконалювати Element, надсилаючи анонімні дані про використання. Щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор."; +"analytics_prompt_message_new_user" = "Допомагайте нам визначати проблеми й удосконалювати %@, надсилаючи анонімні дані про використання. Щоб розуміти, як люди використовують кілька пристроїв, ми створимо спільний для ваших пристроїв випадковий ідентифікатор."; // Analytics "analytics_prompt_title" = "Допоможіть удосконалити %@"; @@ -1702,3 +1702,19 @@ "room_details_flair_section" = "Показувати значки для спільнот"; "settings_flair" = "Показувати значок, де це дозволено"; "room_warning_about_encryption" = "Наскрізне шифрування ще на етапі бета-тестування й може бути ненадійним.\n\nПоки що не варто довіряти йому захист даних.\n\nПристрої ще не зможуть розшифрувати історію до того, як з них приєдналися до кімнати.\n\nЗашифровані повідомлення не буде показано у клієнтах, які ще не використовують шифрування."; +"location_sharing_settings_toggle_title" = "Увімкнути надсилання місцеперебування"; +"location_sharing_settings_header" = "Надсилання місцеперебування"; +"location_sharing_open_google_maps" = "Відкрити в Картах Google"; +"location_sharing_open_apple_maps" = "Відкрити в Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Налаштування"; +"location_sharing_invalid_authorization_not_now" = "Не зараз"; +"location_sharing_invalid_authorization_error_title" = "%@ не має дозволу на доступ до вашого місцеперебування. Ви можете увімкнути доступ у Налаштування > Місцеперебування"; +"location_sharing_locating_user_error_title" = "%@ не може отримати доступ до вашого місцеперебування. Повторіть спробу пізніше."; +"location_sharing_loading_map_error_title" = "%@ не може завантажити карту. Повторіть спробу пізніше."; +"location_sharing_share_action" = "Поділиться"; +"location_sharing_close_action" = "Закрити"; + +// MARK: - Location sharing + +"location_sharing_title" = "Місцеперебування"; +"ok" = "Гаразд"; From d0f14a94c42849614a70963039dbfdf40c9e655a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Wed, 12 Jan 2022 22:15:04 +0000 Subject: [PATCH 081/209] Translated using Weblate (Estonian) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ --- Riot/Assets/et.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings index 2a1abaf1d..4a0ee7794 100644 --- a/Riot/Assets/et.lproj/Vector.strings +++ b/Riot/Assets/et.lproj/Vector.strings @@ -1420,7 +1420,7 @@ "space_private_join_rule" = "Privaatne kogukond"; "space_participants_action_ban" = "Sea selles kogukonnakeskus suhtluskeeld"; "space_participants_action_remove" = "Eemalda sellest kogukonnakeskusest"; -"spaces_coming_soon_detail" = "See funktsionaalsus pole siin rakenduses hetkel veel saadaval, aga üsna varsti saab olema. Seni saad sa seda toimingut teha Element'i töölauarakenduses."; +"spaces_coming_soon_detail" = "See funktsionaalsus pole siin rakenduses hetkel veel saadaval, aga üsna varsti saab olema. Seni saad sa seda toimingut teha %@'i töölauarakenduses."; "spaces_invites_coming_soon_title" = "Varsti lisandub kutsete saatmine"; "spaces_add_rooms_coming_soon_title" = "Varsti on jututubade lisamine võimalik"; "spaces_coming_soon_title" = "Mõne aja pärast on meil uuendusi"; @@ -1520,10 +1520,26 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Meie kasutustingimused leiad %@."; "analytics_prompt_message_upgrade" = "Sa oled varem nõustunud meiega anonüümsete andmete jagamisega. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad, me loome sinu seadmetele ühise juhusliku tunnuse."; -"analytics_prompt_message_new_user" = "Võimalike vigade leidmiseks ja Element'i arendamiseks jaga meiega anonüümseid andmeid. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad me loome sinu seadmetele ühise juhusliku tunnuse."; +"analytics_prompt_message_new_user" = "Võimalike vigade leidmiseks ja %@'i arendamiseks jaga meiega anonüümseid andmeid. Selleks, et mõistaksime, kuidas kasutajad erinevaid seadmeid pruugivad, me loome sinu seadmetele ühise juhusliku tunnuse."; // Analytics "analytics_prompt_title" = "Aita arendada %@ rakendust"; "settings_analytics_and_crash_data" = "Saada rakenduse vigade ja analüütika andmeid"; "accessibility_button_label" = "nupp"; "enable" = "Võta kasutusele"; +"location_sharing_settings_toggle_title" = "Luba asukohta jagada"; +"location_sharing_settings_header" = "Asukoha jagamine"; +"location_sharing_open_google_maps" = "Ava rakendusega Google Maps"; +"location_sharing_open_apple_maps" = "Ava rakendusega Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Seadistused"; +"location_sharing_invalid_authorization_not_now" = "Mitte praegu"; +"location_sharing_invalid_authorization_error_title" = "%@ vajab asukoha määramiseks õigusi, mida saad määrata Seadistused > Asukoht valikust"; +"location_sharing_locating_user_error_title" = "%@ ei saanud asukohta tuvastada. Palun proovi hiljem uuesti."; +"location_sharing_loading_map_error_title" = "%@ ei saanud kaarti avada. Palun proovi hiljem uuesti."; +"location_sharing_share_action" = "Jaga"; +"location_sharing_close_action" = "Sulge"; + +// MARK: - Location sharing + +"location_sharing_title" = "Asukoht"; +"ok" = "Sobib"; From a34707672a63374be973eab24de964fb9c093923 Mon Sep 17 00:00:00 2001 From: Linerly Date: Tue, 11 Jan 2022 13:53:54 +0000 Subject: [PATCH 082/209] Translated using Weblate (Indonesian) Currently translated at 100.0% (1385 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ --- Riot/Assets/id.lproj/Vector.strings | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/id.lproj/Vector.strings b/Riot/Assets/id.lproj/Vector.strings index e92ace022..3eb7b52d4 100644 --- a/Riot/Assets/id.lproj/Vector.strings +++ b/Riot/Assets/id.lproj/Vector.strings @@ -611,7 +611,7 @@ "open" = "Buka"; "version_check_banner_subtitle_deprecated" = "Kami tidak mendukung %@ di iOS %@ lagi. Untuk terus menggunakan %@ secara maksimal, kami menyarankan Anda untuk meningkatkan versi iOS Anda."; "version_check_banner_subtitle_supported" = "Kami akan segera mengakhiri dukungan untuk %@ di iOS %@. Untuk terus menggunakan %@ secara maksimal, kami menyarankan Anda untuk meningkatkan versi iOS Anda."; -"spaces_coming_soon_detail" = "Fitur ini belum ada di sini, tetapi sedang dalam proses. Untuk saat ini, Anda dapat melakukannya dengan Element di komputer Anda."; +"spaces_coming_soon_detail" = "Fitur ini belum ada di sini, tetapi sedang dalam proses. Untuk saat ini, Anda dapat melakukannya dengan %@ di komputer Anda."; "spaces_no_member_found_detail" = "Mencari seseorang yang tidak ada di %@? Untuk saat ini, Anda dapat mengundangnya di web atau desktop."; "spaces_no_room_found_detail" = "Beberapa hasil mungkin disembunyikan karena ruangannya pribadi dan Anda memerlukan sebuah undangan untuk bergabung."; "spaces_empty_space_detail" = "Beberapa ruangan mungkin disembunyikan karena ruangannya pribadi dan Anda memerlukan sebuah undangan."; @@ -1699,10 +1699,26 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Anda dapat membaca semua kebijakan kami %@."; "analytics_prompt_message_upgrade" = "Anda sebelumnya setuju untuk mengirimkan data penggunaan anonim dengan kami. Sekarang, supaya kami dapat memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda."; -"analytics_prompt_message_new_user" = "Bantu kami mengidentifikasi masalah-masalah dan membuat Element lebih baik dengan membagikan data penggunaan anonim. Untuk memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda."; +"analytics_prompt_message_new_user" = "Bantu kami mengidentifikasi masalah-masalah dan membuat %@ lebih baik dengan membagikan data penggunaan anonim. Untuk memahami bagaimana orang-orang menggunakan beberapa perangkat-perangkat, kami akan membuat pengenal acak, yang dibagikan oleh perangkat Anda."; // Analytics "analytics_prompt_title" = "Bantu membuat %@ lebih baik"; "settings_analytics_and_crash_data" = "Kirim data crash dan analitik"; "accessibility_button_label" = "tombol"; "enable" = "Aktifkan"; +"location_sharing_invalid_authorization_error_title" = "%@ tidak memiliki izin untuk mengakses lokasi. Anda dapat mengaktifkan akses di Pengaturan > Lokasi"; +"location_sharing_settings_toggle_title" = "Aktifkan pembagian lokasi"; +"location_sharing_settings_header" = "Pembagian lokasi"; +"location_sharing_open_google_maps" = "Buka di Google Maps"; +"location_sharing_open_apple_maps" = "Buka di Apple Maps"; +"location_sharing_invalid_authorization_settings" = "Pengaturan"; +"location_sharing_invalid_authorization_not_now" = "Jangan sekarang"; +"location_sharing_locating_user_error_title" = "%@ tidak dapat mengakses lokasi Anda. Silakan coba lagi nanti."; +"location_sharing_loading_map_error_title" = "%@ tidak dapat memuat peta. Silakan coba lagi nanti."; +"location_sharing_share_action" = "Bagikan"; +"location_sharing_close_action" = "Tutup"; + +// MARK: - Location sharing + +"location_sharing_title" = "Lokasi"; +"ok" = "OKE"; From 7982df4494f51d161bca222070976bdbc36699d3 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Tue, 11 Jan 2022 21:01:34 +0000 Subject: [PATCH 083/209] Translated using Weblate (Slovak) Currently translated at 95.0% (1317 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ --- Riot/Assets/sk.lproj/Vector.strings | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/Riot/Assets/sk.lproj/Vector.strings b/Riot/Assets/sk.lproj/Vector.strings index ded23fa74..a8ed26c07 100644 --- a/Riot/Assets/sk.lproj/Vector.strings +++ b/Riot/Assets/sk.lproj/Vector.strings @@ -753,7 +753,7 @@ "secrets_recovery_with_passphrase_invalid_passphrase_title" = "Nie je možné získať prístup k tajnému úložisku"; "secrets_recovery_with_passphrase_lost_passphrase_action_part2" = "použiť váš bezpečnostný kľúč"; "secrets_recovery_with_passphrase_lost_passphrase_action_part1" = "Neviete svoju bezpečnostnú frázu? Môžete "; -"secrets_recovery_with_passphrase_passphrase_placeholder" = "Vložiť bezpečnostnú frázu"; +"secrets_recovery_with_passphrase_passphrase_placeholder" = "Zadajte bezpečnostnú frázu"; "secrets_recovery_with_passphrase_information_verify_device" = "Na overenie tohto zariadenia použite bezpečnostnú frázu."; "user_verification_session_details_information_untrusted_current_user" = "Overte túto reláciu, aby ste ju označili za dôveryhodnú a udelili jej prístup k zašifrovaným správam:"; "user_verification_session_details_information_trusted_other_user_part2" = " ste ju overili:"; @@ -1186,7 +1186,7 @@ "space_home_show_all_rooms" = "Zobraziť všetky miestnosti"; "space_participants_action_ban" = "Vylúčiť z tohto priestoru"; "space_participants_action_remove" = "Odstrániť z tohto priestoru"; -"spaces_coming_soon_detail" = "Táto funkcia tu ešte nebola zapracovaná, ale je na ceste k jej zapracovaniu. Zatiaľ to môžete urobiť pomocou aplikácie Element v počítači."; +"spaces_coming_soon_detail" = "Táto funkcia tu ešte nebola zapracovaná, ale je na ceste k jej zapracovaniu. Zatiaľ to môžete urobiť pomocou %@ na vašom počítači."; "spaces_invites_coming_soon_title" = "Pozvánky už čoskoro"; "spaces_add_rooms_coming_soon_title" = "Pridávanie miestností už čoskoro"; "spaces_no_member_found_detail" = "Hľadáte niekoho, kto nie je v %@? Zatiaľ ich môžete pozvať na webe alebo na počítači."; @@ -1502,7 +1502,7 @@ "analytics_prompt_stop" = "Zastaviť zdieľanie"; "analytics_prompt_yes" = "Áno, je to v poriadku"; "analytics_prompt_message_upgrade" = "Predtým ste nám udelili súhlas so zdieľaním anonymných údajov o používaní. Teraz, aby sme pomohli pochopiť, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor zdieľaný vašimi zariadeniami."; -"analytics_prompt_message_new_user" = "Pomôžte nám identifikovať problémy a zlepšiť Element zdieľaním anonymných údajov o používaní. Aby sme pochopili, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor, ktorý zdieľajú vaše zariadenia."; +"analytics_prompt_message_new_user" = "Pomôžte nám identifikovať problémy a zlepšiť %@ zdieľaním anonymných údajov o používaní. Aby sme pochopili, ako ľudia používajú viacero zariadení, vygenerujeme náhodný identifikátor zdieľaný vašimi zariadeniami."; // Analytics "analytics_prompt_title" = "Pomôžte zlepšiť %@"; @@ -1619,3 +1619,16 @@ // Recover from recovery key "key_backup_recover_from_recovery_key_info" = "Použite svoju bezpečnostný kľúč na odomknutie histórie zabezpečených správ"; +"widget_sticker_picker_no_stickerpacks_alert" = "Momentálne nemáte aktívne žiadne balíčky s nálepkami."; +"widget_integrations_server_failed_to_connect" = "Nepodarilo sa pripojiť k integračnému serveru"; +"no_voip" = "%@ vám volá, ale %@ zatiaľ nepodporuje hovory.\nToto oznámenie môžete ignorovať a prijať hovor z iného zariadenia alebo ho môžete odmietnuť."; +"call_actions_unhold" = "Pokračovať"; +"call_jitsi_error" = "Nepodarilo sa pripojiť ku konferenčnému hovoru."; +"rage_shake_prompt" = "Zdá sa, že rozčúlene trasiete telefónom. Chceli by ste odoslať hlásenie o chybe?"; +"room_details_addresses_disable_main_address_prompt_msg" = "Nebudete mať zadanú žiadnu hlavnú adresu. Predvolená hlavná adresa pre túto miestnosť sa vyberie náhodne"; +"settings_enable_rageshake" = "Zúrivo potraste pre nahlásenie chyby"; +"settings_ui_theme_picker_message_match_system_theme" = "\"Auto\" zodpovedá systémovej téme vášho zariadenia"; +"settings_pin_rooms_with_unread" = "Pripnúť miestnosti s neprečítanými správami"; +"settings_pin_rooms_with_missed_notif" = "Pripnúť miestnosti so zmeškanými oznámeniami"; +"settings_confirm_media_size" = "Potvrdiť veľkosť pri odosielaní"; +"ok" = "OK"; From 51fb12b33d9daf62dff0ff276d6cec5734ceac30 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 09:48:18 +0100 Subject: [PATCH 084/209] RiotSettings: Add convenient method to get current room timeline style identifier. --- Riot/Managers/Settings/RiotSettings.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 852dedae5..e3c832d67 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -197,6 +197,10 @@ final class RiotSettings: NSObject { @UserDefault(key: "roomScreenEnableMessageBubbles", defaultValue: BuildSettings.roomScreenEnableMessageBubblesByDefault, storage: defaults) var roomScreenEnableMessageBubbles + var roomTimelineStyleIdentifier: RoomTimelineStyleIdentifier { + return self.roomScreenEnableMessageBubbles ? .bubble : .plain + } + // MARK: - Room Contextual Menu @UserDefault(key: "roomContextualMenuShowMoreOptionForMessages", defaultValue: BuildSettings.roomContextualMenuShowMoreOptionForMessages, storage: defaults) From f90fe009559c59f1ba0262bcba90050cf18c7a08 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 09:51:08 +0100 Subject: [PATCH 085/209] Add cell layout updater implementation for bubbles. --- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 293 ++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift new file mode 100644 index 000000000..874be05e3 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -0,0 +1,293 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +@objcMembers +class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { + + // MARK: - Constants + + private enum Constants { + static let bubbleBackgroundViewCornerRadius: CGFloat = 12.0 + } + + // MARK: - Properties + + private var incomingColor: UIColor { + return ThemeService.shared().theme.colors.system + } + + private var outgoingColor: UIColor { + return ThemeService.shared().theme.colors.accent.withAlphaComponent(0.10) + } + + // MARK: - Public + + func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { + + var isMessageSenderCurrentUser: Bool = false + + if let senderId = cellData.senderId, let currentUserId = cellData.mxSession.myUserId, senderId == currentUserId { + isMessageSenderCurrentUser = true + } + + if isMessageSenderCurrentUser { + self.updateLayout(forOutgoingTextMessageCell: cell, andCellData: cellData) + } else { + self.updateLayout(forIncomingTextMessageCell: cell, andCellData: cellData) + } + + } + + func updateLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { + + if let messageBubbleBackgroundView = self.getMessageBubbleBackgroundView(from: cell) { + + if self.canUseBubbleBackground(forCell: cell, withCellData: cellData) { + + messageBubbleBackgroundView.isHidden = false + + self.updateMessageBubbleBackgroundView(messageBubbleBackgroundView, withCell: cell, andCellData: cellData) + } else { + messageBubbleBackgroundView.isHidden = true + } + } + } + + func updateLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { + + if let messageBubbleBackgroundView = self.getMessageBubbleBackgroundView(from: cell) { + + if self.canUseBubbleBackground(forCell: cell, withCellData: cellData) { + + messageBubbleBackgroundView.isHidden = false + + self.updateMessageBubbleBackgroundView(messageBubbleBackgroundView, withCell: cell, andCellData: cellData) + } else { + messageBubbleBackgroundView.isHidden = true + } + } + } + + func setupLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell) { + + self.setupIncomingMessageTextViewMargins(for: cell) + + self.addBubbleBackgroundViewToCell(cell, backgroundColor: self.incomingColor) + + cell.setNeedsUpdateConstraints() + } + + func setupLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell) { + + self.setupOutgoingMessageTextViewMargins(for: cell) + + // Hide avatar view + cell.pictureView?.isHidden = true + + self.addBubbleBackgroundViewToCell(cell, backgroundColor: self.outgoingColor) + + cell.setNeedsUpdateConstraints() + } + + // MARK: - Private + + // MARK: Bubble background view + + private func createBubbleBackgroundView(with backgroundColor: UIColor) -> RoomMessageBubbleBackgroundView { + + let bubbleBackgroundView = RoomMessageBubbleBackgroundView() + bubbleBackgroundView.backgroundColor = backgroundColor + + return bubbleBackgroundView + } + + func getMessageBubbleBackgroundView(from cell: MXKRoomBubbleTableViewCell) -> RoomMessageBubbleBackgroundView? { + + let foundView = cell.contentView.subviews.first { view in + return view is RoomMessageBubbleBackgroundView + } + + return foundView as? RoomMessageBubbleBackgroundView + } + + private func addBubbleBackgroundViewToCell(_ bubbleCell: MXKRoomBubbleTableViewCell, backgroundColor: UIColor) { + + guard let messageTextView = bubbleCell.messageTextView else { + return + } + + let topMargin: CGFloat = 0.0 + let leftMargin: CGFloat = -5.0 + let rightMargin: CGFloat = 5.0 + + let bubbleBackgroundView = self.createBubbleBackgroundView(with: backgroundColor) + + bubbleCell.contentView.insertSubview(bubbleBackgroundView, at: 0) + + let topAnchor = messageTextView.topAnchor + let leadingAnchor = messageTextView.leadingAnchor + let trailingAnchor = messageTextView.trailingAnchor + + bubbleBackgroundView.updateHeight(messageTextView.frame.height) + + NSLayoutConstraint.activate([ + bubbleBackgroundView.topAnchor.constraint(equalTo: topAnchor, constant: topMargin), + bubbleBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: leftMargin), + bubbleBackgroundView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: rightMargin) + ]) + } + + private func canUseBubbleBackground(forCell cell: MXKRoomBubbleTableViewCell, withCellData cellData: MXKRoomBubbleCellData) -> Bool { + + guard let firstComponent = cellData.getFirstBubbleComponentWithDisplay(), let firstEvent = firstComponent.event else { + return false + } + + switch firstEvent.eventType { + case .roomMessage: + if let messageTypeString = firstEvent.content["msgtype"] as? String { + + let messageType = MXMessageType(identifier: messageTypeString) + + switch messageType { + case .text : + return true + default: + break + } + } + default: + break + } + + return false + } + + private func getTextMessageHeight(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> CGFloat? { + + guard let roomBubbleCellData = cellData as? RoomBubbleCellData, + let lastBubbleComponent = cellData.getLastBubbleComponentWithDisplay(), + let firstComponent = roomBubbleCellData.getFirstBubbleComponentWithDisplay() else { + return nil + } + + + let bubbleHeight: CGFloat + let bottomMargin: CGFloat = 4.0 + + let lastEventId = lastBubbleComponent.event.eventId + let lastMessageBottomPosition = cell.bottomPosition(ofEvent: lastEventId) + + let firstEventId = firstComponent.event.eventId + let firstMessageTopPosition = cell.topPosition(ofEvent: firstEventId) + + let additionalContentHeight = roomBubbleCellData.additionalHeight(forEvent: lastEventId) + + bubbleHeight = lastMessageBottomPosition - firstMessageTopPosition - additionalContentHeight + bottomMargin + + guard bubbleHeight >= 0 else { + return nil + } + + return bubbleHeight + } + + @discardableResult + private func updateMessageBubbleBackgroundView(_ roomMessageBubbleBackgroundView: RoomMessageBubbleBackgroundView, withCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> Bool { + + var finalBubbleHeight: CGFloat? + + if let bubbleHeight = self.getTextMessageHeight(for: cell, andCellData: cellData) { + finalBubbleHeight = bubbleHeight + + } else if let messageTextViewHeight = cell.messageTextView?.frame.height { + + finalBubbleHeight = messageTextViewHeight + } + + if let finalBubbleHeight = finalBubbleHeight { + return roomMessageBubbleBackgroundView.updateHeight(finalBubbleHeight) + } else { + return false + } + } + + private func getIncomingMessageTextViewInsets(from bubbleCell: MXKRoomBubbleTableViewCell) -> UIEdgeInsets { + + let messageViewMarginTop: CGFloat + let messageViewMarginBottom: CGFloat = -2.0 + let messageViewMarginLeft: CGFloat = 3.0 + let messageViewMarginRight: CGFloat = 0.0 + + if bubbleCell.userNameLabel != nil { + messageViewMarginTop = 10.0 + } else { + messageViewMarginTop = 0.0 + } + + let messageViewInsets = UIEdgeInsets(top: messageViewMarginTop, left: messageViewMarginLeft, bottom: messageViewMarginBottom, right: messageViewMarginRight) + + return messageViewInsets + } + + // MARK: Text message + + private func setupIncomingMessageTextViewMargins(for cell: MXKRoomBubbleTableViewCell) { + + guard cell.messageTextView != nil else { + return + } + + let messageViewInsets = self.getIncomingMessageTextViewInsets(from: cell) + + cell.msgTextViewBottomConstraint.constant += messageViewInsets.bottom + cell.msgTextViewTopConstraint.constant += messageViewInsets.top + cell.msgTextViewLeadingConstraint.constant += messageViewInsets.left + cell.msgTextViewTrailingConstraint.constant += messageViewInsets.right + } + + private func setupOutgoingMessageTextViewMargins(for cell: MXKRoomBubbleTableViewCell) { + + guard let messageTextView = cell.messageTextView else { + return + } + + let contentView = cell.contentView + + let leftMargin: CGFloat = 80.0 + let rightMargin: CGFloat = 38.0 + let bottomMargin: CGFloat = -2.0 + + cell.msgTextViewLeadingConstraint.isActive = false + cell.msgTextViewTrailingConstraint.isActive = false + + let leftConstraint = messageTextView.leadingAnchor.constraint(greaterThanOrEqualTo: contentView.leadingAnchor, constant: leftMargin) + + let rightConstraint = messageTextView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -rightMargin) + + NSLayoutConstraint.activate([ + leftConstraint, + rightConstraint + ]) + + cell.msgTextViewLeadingConstraint = leftConstraint + cell.msgTextViewTrailingConstraint = rightConstraint + + cell.msgTextViewBottomConstraint.constant += bottomMargin + } +} From 4dd4a1da4c2d523e9e4ce2bdc9b0a8db988634cd Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 09:55:00 +0100 Subject: [PATCH 086/209] Add RoomTimelineStyle that describes a room timeline style used to customize timeline appearance. --- .../Styles/RoomTimelineStyle.swift | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift new file mode 100644 index 000000000..b0e4fe216 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -0,0 +1,39 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import MatrixSDK + +/// RoomTimelineStyle describes a room timeline style used to customize timeline appearance +@objc +protocol RoomTimelineStyle { + + // MARK: - Properties + + /// Style identifier + var identifier: RoomTimelineStyleIdentifier { get } + + /// Update layout if needed for cells provided by the cell provider + var cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? { get } + + /// Register and provide timeline cells + var cellProvider: RoomTimelineCellProviderProtocol { get } + + // MARK: - Methods + + /// Indicate to merge or not event in timeline + func canAddEvent(_ event: MXEvent, and roomState: MXRoomState, to cellData: MXKRoomBubbleCellData) -> Bool +} From 54c313e94f772d516d31b078f474591927fec144 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 09:58:55 +0100 Subject: [PATCH 087/209] Add RoomMessageBubbleBackgroundView. --- .../RoomMessageBubbleBackgroundView.swift | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/RoomMessageBubbleBackgroundView.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/RoomMessageBubbleBackgroundView.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/RoomMessageBubbleBackgroundView.swift new file mode 100644 index 000000000..1408b48c7 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/RoomMessageBubbleBackgroundView.swift @@ -0,0 +1,74 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +class RoomMessageBubbleBackgroundView: UIView { + + // MARK: - Constant + + private enum Constants { + static let cornerRadius: CGFloat = 12.0 + } + + // MARK: - Properties + + private var heightConstraint: NSLayoutConstraint? + + // MARK: - Setup + + convenience init() { + self.init(frame: CGRect.zero) + } + + override init(frame: CGRect) { + super.init(frame: frame) + self.commonInit() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + self.commonInit() + } + + private func commonInit() { + self.translatesAutoresizingMaskIntoConstraints = false + self.layer.masksToBounds = true + self.layer.cornerRadius = Constants.cornerRadius + } + + // MARK: - Public + + @discardableResult + func updateHeight(_ height: CGFloat) -> Bool { + if let heightConstraint = self.heightConstraint { + + guard heightConstraint.constant != height else { + return false + } + + heightConstraint.constant = height + + return true + } else { + let heightConstraint = self.heightAnchor.constraint(equalToConstant: height) + heightConstraint.isActive = true + self.heightConstraint = heightConstraint + + return true + } + } +} From dba432b6dff0405e108c0962463edbe257ca7182 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 09:59:25 +0100 Subject: [PATCH 088/209] Add room timeline style for bubbles. --- .../Bubble/BubbleRoomTimelineStyle.swift | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift new file mode 100644 index 000000000..be1cfec05 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -0,0 +1,43 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +class BubbleRoomTimelineStyle: RoomTimelineStyle { + + // MARK: - Properties + + let identifier: RoomTimelineStyleIdentifier + + let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? + + let cellProvider: RoomTimelineCellProviderProtocol + + // MARK: - Setup + + init() { + self.identifier = .bubble + self.cellLayoutUpdater = BubbleRoomCellLayoutUpdater() + self.cellProvider = BubbleRoomTimelineCellProvider() + } + + // MARK: - Public + + func canAddEvent(_ event: MXEvent, and roomState: MXRoomState, to cellData: MXKRoomBubbleCellData) -> Bool { + return false + } + +} From 9321086b8395ccb15a175249115819b28b66de93 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:00:21 +0100 Subject: [PATCH 089/209] Add room timeline style for default cell style. --- .../Styles/Plain/PlainRoomTimelineStyle.swift | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift new file mode 100644 index 000000000..77065460c --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -0,0 +1,42 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +class PlainRoomTimelineStyle: RoomTimelineStyle { + + // MARK: - Properties + + let identifier: RoomTimelineStyleIdentifier + + let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? + + let cellProvider: RoomTimelineCellProviderProtocol + + // MARK: - Setup + + init() { + self.identifier = .plain + self.cellLayoutUpdater = nil + self.cellProvider = PlainRoomTimelineCellProvider() + } + + // MARK: - Methods + + func canAddEvent(_ event: MXEvent, and roomState: MXRoomState, to cellData: MXKRoomBubbleCellData) -> Bool { + return true + } +} From e704740d712692ffdb70914583b6572c10429ad9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:02:23 +0100 Subject: [PATCH 090/209] Add RoomTimelineConfiguration that enables to manage room timeline appearance configuration. --- .../RoomTimelineConfiguration.swift | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift new file mode 100644 index 000000000..422a6465a --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift @@ -0,0 +1,78 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +/// RoomTimelineConfiguration enables to manage room timeline appearance configuration +@objcMembers +class RoomTimelineConfiguration: NSObject { + + // MARK: - Constants + + static let shared = RoomTimelineConfiguration() + + // MARK: - Properties + + private(set) var currentStyle: RoomTimelineStyle + + // MARK: - Setup + + init(style: RoomTimelineStyle) { + self.currentStyle = style + + super.init() + } + + convenience init(styleIdentifier: RoomTimelineStyleIdentifier) { + + let style = type(of: self).style(for: styleIdentifier) + self.init(style: style) + } + + convenience override init() { + let styleIdentifier = RiotSettings.shared.roomTimelineStyleIdentifier + self.init(styleIdentifier: styleIdentifier) + } + + // MARK: - Public + + func updateStyle(_ roomTimelineStyle: RoomTimelineStyle) { + self.currentStyle = roomTimelineStyle + } + + func updateStyle(withIdentifier identifier: RoomTimelineStyleIdentifier) { + + let style = type(of: self).style(for: identifier) + + self.updateStyle(style) + } + + // MARK: - Private + + private class func style(for identifier: RoomTimelineStyleIdentifier) -> RoomTimelineStyle { + + let roomTimelineStyle: RoomTimelineStyle + + switch identifier { + case .plain: + roomTimelineStyle = PlainRoomTimelineStyle() + case .bubble: + roomTimelineStyle = BubbleRoomTimelineStyle() + } + + return roomTimelineStyle + } +} From f87f7d45d54f68c38ce3524ff960855eca75a33c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:03:08 +0100 Subject: [PATCH 091/209] Update MatrixKit text message cells. --- .../Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m | 4 +--- .../Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m index 4a66ba815..fefdbb677 100644 --- a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m @@ -23,10 +23,8 @@ - (void)setupViews { RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; - - id currentStyle = timelineConfiguration.currentStyle; - [currentStyle.cellLayoutUpdater setupLayoutForIncomingMessageCell:self]; + [timelineConfiguration.currentStyle.cellLayoutUpdater setupLayoutForIncomingTextMessageCell:self]; } @end diff --git a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m index 4f49a219f..932b6095c 100644 --- a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m @@ -23,10 +23,8 @@ - (void)setupViews { RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; - - id currentStyle = timelineConfiguration.currentStyle; - - [currentStyle.cellLayoutUpdater setupLayoutForOutgoingMessageCell:self]; + + [timelineConfiguration.currentStyle.cellLayoutUpdater setupLayoutForOutgoingTextMessageCell:self]; } From 52252241be944bab1c5bea913724808ec9f07576 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:06:40 +0100 Subject: [PATCH 092/209] SettingsVC: Handle possibility to change room timeline style and apply changes. --- Riot/Modules/Settings/SettingsViewController.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 782d8a3d8..6675ae83e 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -3898,6 +3898,13 @@ TableViewSectionsDelegate> - (void)toggleEnableRoomMessageBubbles:(UISwitch *)sender { RiotSettings.shared.roomScreenEnableMessageBubbles = sender.isOn; + + [[RoomTimelineConfiguration shared] updateStyleWithIdentifier:RiotSettings.shared.roomTimelineStyleIdentifier]; + + // Close all room data sources + // Be sure to use new room timeline style configurations + MXKRoomDataSourceManager *roomDataSourceManager = [MXKRoomDataSourceManager sharedManagerForMatrixSession:self.mainSession]; + [roomDataSourceManager reset]; } #pragma mark - TextField listener From 34587d4118bee7d1850176afe7d1ce7b0931f439 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:11:13 +0100 Subject: [PATCH 093/209] RoomDataSource: Handle extra cell layout update if needed. --- Riot/Modules/Room/DataSources/RoomDataSource.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 1f6b51137..19080d6d4 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -717,11 +717,20 @@ const CGFloat kTypingCellHeight = 24; { [bubbleCell updateTickViewWithFailedEventIds:self.failedEventIds]; } + + [self updateCellLayoutIfNeeded:bubbleCell withCellData:cellData]; } return cell; } +- (void)updateCellLayoutIfNeeded:(MXKRoomBubbleTableViewCell*)cell withCellData:(MXKRoomBubbleCellData*)cellData { + + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + [timelineConfiguration.currentStyle.cellLayoutUpdater updateLayoutIfNeededFor:cell andCellData:cellData]; +} + - (RoomBubbleCellData*)roomBubbleCellDataForEventId:(NSString*)eventId { id cellData = [self cellDataOfEventWithEventId:eventId]; From 79ecc8b4d65b07457151f97cbc7aac76ec557226 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 10:23:15 +0100 Subject: [PATCH 094/209] RoomVC: Handle cell provider. --- Riot/Modules/Room/RoomViewController.m | 225 ++++++------------------- 1 file changed, 56 insertions(+), 169 deletions(-) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 10af1f3bc..5975ace6a 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -54,55 +54,7 @@ #import "JitsiViewController.h" #import "RoomEmptyBubbleCell.h" - -#import "RoomIncomingTextMsgBubbleCell.h" -#import "RoomIncomingTextMsgWithoutSenderInfoBubbleCell.h" -#import "RoomIncomingTextMsgWithPaginationTitleBubbleCell.h" -#import "RoomIncomingTextMsgWithoutSenderNameBubbleCell.h" -#import "RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" -#import "RoomIncomingAttachmentBubbleCell.h" -#import "RoomIncomingAttachmentWithoutSenderInfoBubbleCell.h" -#import "RoomIncomingAttachmentWithPaginationTitleBubbleCell.h" - -#import "RoomIncomingEncryptedTextMsgBubbleCell.h" -#import "RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" -#import "RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.h" -#import "RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.h" -#import "RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" -#import "RoomIncomingEncryptedAttachmentBubbleCell.h" -#import "RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.h" -#import "RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.h" - -#import "RoomOutgoingTextMsgBubbleCell.h" -#import "RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h" -#import "RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h" -#import "RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h" -#import "RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" -#import "RoomOutgoingAttachmentBubbleCell.h" -#import "RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" -#import "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" - -#import "RoomOutgoingEncryptedTextMsgBubbleCell.h" -#import "RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" -#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h" -#import "RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h" -#import "RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" -#import "RoomOutgoingEncryptedAttachmentBubbleCell.h" -#import "RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h" -#import "RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h" - -#import "RoomMembershipBubbleCell.h" -#import "RoomMembershipWithPaginationTitleBubbleCell.h" -#import "RoomMembershipCollapsedBubbleCell.h" -#import "RoomMembershipCollapsedWithPaginationTitleBubbleCell.h" #import "RoomMembershipExpandedBubbleCell.h" -#import "RoomMembershipExpandedWithPaginationTitleBubbleCell.h" -#import "RoomCreationWithPaginationCollapsedBubbleCell.h" -#import "RoomCreationCollapsedBubbleCell.h" - -#import "RoomSelectedStickerBubbleCell.h" -#import "RoomPredecessorBubbleCell.h" - #import "MXKRoomBubbleTableViewCell+Riot.h" #import "AvatarGenerator.h" @@ -130,6 +82,8 @@ #import "MXSDKOptions.h" +#import "RoomTimelineCellProviderProtocol.h" + #import "GeneratedInterface-Swift.h" NSNotificationName const RoomCallTileTappedNotification = @"RoomCallTileTappedNotification"; @@ -349,83 +303,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [super viewDidLoad]; // Register first customized cell view classes used to render bubbles - [self.bubblesTableView registerClass:RoomIncomingTextMsgBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingAttachmentBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomIncomingEncryptedTextMsgBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedAttachmentBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomOutgoingAttachmentBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingTextMsgBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomOutgoingEncryptedAttachmentBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedTextMsgBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomEmptyBubbleCell.class forCellReuseIdentifier:RoomEmptyBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomMembershipBubbleCell.class forCellReuseIdentifier:RoomMembershipBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomMembershipWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomMembershipCollapsedBubbleCell.class forCellReuseIdentifier:RoomMembershipCollapsedBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomMembershipCollapsedWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipCollapsedWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomMembershipExpandedBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomMembershipExpandedWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomMembershipExpandedWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomSelectedStickerBubbleCell.class forCellReuseIdentifier:RoomSelectedStickerBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomPredecessorBubbleCell.class forCellReuseIdentifier:RoomPredecessorBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:KeyVerificationIncomingRequestApprovalBubbleCell.class forCellReuseIdentifier:KeyVerificationIncomingRequestApprovalBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:KeyVerificationRequestStatusBubbleCell.class forCellReuseIdentifier:KeyVerificationRequestStatusBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:KeyVerificationRequestStatusWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationRequestStatusWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:KeyVerificationConclusionBubbleCell.class forCellReuseIdentifier:KeyVerificationConclusionBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:KeyVerificationConclusionWithPaginationTitleBubbleCell.class forCellReuseIdentifier:KeyVerificationConclusionWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomCreationCollapsedBubbleCell.class forCellReuseIdentifier:RoomCreationCollapsedBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomCreationWithPaginationCollapsedBubbleCell.class forCellReuseIdentifier:RoomCreationWithPaginationCollapsedBubbleCell.defaultReuseIdentifier]; - - // call cells - [self.bubblesTableView registerClass:RoomDirectCallStatusBubbleCell.class forCellReuseIdentifier:RoomDirectCallStatusBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:RoomGroupCallStatusBubbleCell.class forCellReuseIdentifier:RoomGroupCallStatusBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:RoomCreationIntroCell.class forCellReuseIdentifier:RoomCreationIntroCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerNib:RoomTypingBubbleCell.nib forCellReuseIdentifier:RoomTypingBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:VoiceMessageBubbleCell.class forCellReuseIdentifier:VoiceMessageBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:VoiceMessageWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:VoiceMessageWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:VoiceMessageWithPaginationTitleBubbleCell.class forCellReuseIdentifier:VoiceMessageWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:PollBubbleCell.class forCellReuseIdentifier:PollBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:PollWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:PollWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:PollWithPaginationTitleBubbleCell.class forCellReuseIdentifier:PollWithPaginationTitleBubbleCell.defaultReuseIdentifier]; - - [self.bubblesTableView registerClass:LocationBubbleCell.class forCellReuseIdentifier:LocationBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:LocationWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:LocationWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; - [self.bubblesTableView registerClass:LocationWithPaginationTitleBubbleCell.class forCellReuseIdentifier:LocationWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [[RoomTimelineConfiguration shared].currentStyle.cellProvider registerCellsForTableView:self.bubblesTableView]; [self vc_removeBackTitle]; @@ -2634,14 +2512,23 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; - (Class)cellViewClassForCellData:(MXKCellData*)cellData { - Class cellViewClass = nil; - BOOL showEncryptionBadge = NO; + RoomTimelineCellIdentifier cellIdentifier = [self cellIdentifierForCellData:cellData andRoomDataSource:customizedRoomDataSource]; + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + return [timelineConfiguration.currentStyle.cellProvider cellViewClassForCellIdentifier:cellIdentifier];; +} + +- (RoomTimelineCellIdentifier)cellIdentifierForCellData:(MXKCellData*)cellData andRoomDataSource:(RoomDataSource *)customizedRoomDataSource; +{ // Sanity check if (![cellData conformsToProtocol:@protocol(MXKRoomBubbleCellDataStoring)]) { - return nil; + return RoomTimelineCellIdentifierUnknown; } + + BOOL showEncryptionBadge = NO; + RoomTimelineCellIdentifier cellIdentifier; id bubbleData = (id)cellData; @@ -2656,27 +2543,27 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Select the suitable table view cell class, by considering first the empty bubble cell. if (bubbleData.hasNoDisplay) { - cellViewClass = RoomEmptyBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierEmpty; } else if (bubbleData.tag == RoomBubbleCellDataTagRoomCreationIntro) { - cellViewClass = RoomCreationIntroCell.class; + cellIdentifier = RoomTimelineCellIdentifierRoomCreationIntro; } else if (bubbleData.tag == RoomBubbleCellDataTagRoomCreateWithPredecessor) { - cellViewClass = RoomPredecessorBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierRoomPredecessor; } else if (bubbleData.tag == RoomBubbleCellDataTagKeyVerificationRequestIncomingApproval) { - cellViewClass = bubbleData.isPaginationFirstBubble ? KeyVerificationIncomingRequestApprovalWithPaginationTitleBubbleCell.class : KeyVerificationIncomingRequestApprovalBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierKeyVerificationIncomingRequestApprovalWithPaginationTitle : RoomTimelineCellIdentifierKeyVerificationIncomingRequestApproval; } else if (bubbleData.tag == RoomBubbleCellDataTagKeyVerificationRequest) { - cellViewClass = bubbleData.isPaginationFirstBubble ? KeyVerificationRequestStatusWithPaginationTitleBubbleCell.class : KeyVerificationRequestStatusBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierKeyVerificationRequestStatusWithPaginationTitle : RoomTimelineCellIdentifierKeyVerificationRequestStatus; } else if (bubbleData.tag == RoomBubbleCellDataTagKeyVerificationConclusion) { - cellViewClass = bubbleData.isPaginationFirstBubble ? KeyVerificationConclusionWithPaginationTitleBubbleCell.class : KeyVerificationConclusionBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierKeyVerificationConclusionWithPaginationTitle : RoomTimelineCellIdentifierKeyVerificationConclusion; } else if (bubbleData.tag == RoomBubbleCellDataTagMembership) { @@ -2684,80 +2571,80 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { if (bubbleData.nextCollapsableCellData) { - cellViewClass = bubbleData.isPaginationFirstBubble ? RoomMembershipCollapsedWithPaginationTitleBubbleCell.class : RoomMembershipCollapsedBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipCollapsedWithPaginationTitle : RoomTimelineCellIdentifierMembershipCollapsed; } else { // Use a normal membership cell for a single membership event - cellViewClass = bubbleData.isPaginationFirstBubble ? RoomMembershipWithPaginationTitleBubbleCell.class : RoomMembershipBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipWithPaginationTitle : RoomTimelineCellIdentifierMembership; } } else if (bubbleData.collapsedAttributedTextMessage) { // The cell (and its series) is not collapsed but this cell is the first // of the series. So, use the cell with the "collapse" button. - cellViewClass = bubbleData.isPaginationFirstBubble ? RoomMembershipExpandedWithPaginationTitleBubbleCell.class : RoomMembershipExpandedBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipExpandedWithPaginationTitle : RoomTimelineCellIdentifierMembershipExpanded; } else { - cellViewClass = bubbleData.isPaginationFirstBubble ? RoomMembershipWithPaginationTitleBubbleCell.class : RoomMembershipBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierMembershipWithPaginationTitle : RoomTimelineCellIdentifierMembership; } } else if (bubbleData.tag == RoomBubbleCellDataTagRoomCreateConfiguration) { - cellViewClass = bubbleData.isPaginationFirstBubble ? RoomCreationWithPaginationCollapsedBubbleCell.class : RoomCreationCollapsedBubbleCell.class; + cellIdentifier = bubbleData.isPaginationFirstBubble ? RoomTimelineCellIdentifierRoomCreationCollapsedWithPaginationTitle : RoomTimelineCellIdentifierRoomCreationCollapsed; } else if (bubbleData.tag == RoomBubbleCellDataTagCall) { - cellViewClass = RoomDirectCallStatusBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierDirectCallStatus; } else if (bubbleData.tag == RoomBubbleCellDataTagGroupCall) { - cellViewClass = RoomGroupCallStatusBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierGroupCallStatus; } else if (bubbleData.attachment.type == MXKAttachmentTypeVoiceMessage || bubbleData.attachment.type == MXKAttachmentTypeAudio) { if (bubbleData.isPaginationFirstBubble) { - cellViewClass = VoiceMessageWithPaginationTitleBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierVoiceMessageWithPaginationTitle; } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = VoiceMessageWithoutSenderInfoBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierVoiceMessageWithoutSenderInfo; } else { - cellViewClass = VoiceMessageBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierVoiceMessage; } } else if (bubbleData.tag == RoomBubbleCellDataTagPoll) { if (bubbleData.isPaginationFirstBubble) { - cellViewClass = PollWithPaginationTitleBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierPollWithPaginationTitle; } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = PollWithoutSenderInfoBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierPollWithoutSenderInfo; } else { - cellViewClass = PollBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierPoll; } } else if (bubbleData.tag == RoomBubbleCellDataTagLocation) { if (bubbleData.isPaginationFirstBubble) { - cellViewClass = LocationWithPaginationTitleBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierLocationWithPaginationTitle; } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = LocationWithoutSenderInfoBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierLocationWithoutSenderInfo; } else { - cellViewClass = LocationBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierLocation; } } else if (bubbleData.isIncoming) @@ -2767,19 +2654,19 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Check whether the provided celldata corresponds to a selected sticker if (customizedRoomDataSource.selectedEventId && (bubbleData.attachment.type == MXKAttachmentTypeSticker) && [bubbleData.attachment.eventId isEqualToString:customizedRoomDataSource.selectedEventId]) { - cellViewClass = RoomSelectedStickerBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierSelectedSticker; } else if (bubbleData.isPaginationFirstBubble) { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedAttachmentWithPaginationTitleBubbleCell.class : RoomIncomingAttachmentWithPaginationTitleBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithPaginationTitle : RoomTimelineCellIdentifierIncomingAttachmentWithPaginationTitle; } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedAttachmentWithoutSenderInfoBubbleCell.class : RoomIncomingAttachmentWithoutSenderInfoBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingAttachmentEncryptedWithoutSenderInfo : RoomTimelineCellIdentifierIncomingAttachmentWithoutSenderInfo; } else { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedAttachmentBubbleCell.class : RoomIncomingAttachmentBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingAttachmentEncrypted : RoomTimelineCellIdentifierIncomingAttachment; } } else @@ -2788,24 +2675,24 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { if (bubbleData.shouldHideSenderName) { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class : RoomIncomingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitleWithoutSenderName : RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitleWithoutSenderName; } else { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedTextMsgWithPaginationTitleBubbleCell.class : RoomIncomingTextMsgWithPaginationTitleBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithPaginationTitle : RoomTimelineCellIdentifierIncomingTextMessageWithPaginationTitle; } } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedTextMsgWithoutSenderInfoBubbleCell.class : RoomIncomingTextMsgWithoutSenderInfoBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderInfo : RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderInfo; } else if (bubbleData.shouldHideSenderName) { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedTextMsgWithoutSenderNameBubbleCell.class : RoomIncomingTextMsgWithoutSenderNameBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingTextMessageEncryptedWithoutSenderName : RoomTimelineCellIdentifierIncomingTextMessageWithoutSenderName; } else { - cellViewClass = showEncryptionBadge ? RoomIncomingEncryptedTextMsgBubbleCell.class : RoomIncomingTextMsgBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierIncomingTextMessageEncrypted : RoomTimelineCellIdentifierIncomingTextMessage; } } } @@ -2817,19 +2704,19 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; // Check whether the provided celldata corresponds to a selected sticker if (customizedRoomDataSource.selectedEventId && (bubbleData.attachment.type == MXKAttachmentTypeSticker) && [bubbleData.attachment.eventId isEqualToString:customizedRoomDataSource.selectedEventId]) { - cellViewClass = RoomSelectedStickerBubbleCell.class; + cellIdentifier = RoomTimelineCellIdentifierSelectedSticker; } else if (bubbleData.isPaginationFirstBubble) { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class :RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithPaginationTitle : RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle; } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo : RoomTimelineCellIdentifierOutgoingAttachmentWithoutSenderInfo; } else { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedAttachmentBubbleCell.class : RoomOutgoingAttachmentBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingAttachmentEncrypted : RoomTimelineCellIdentifierOutgoingAttachment; } } else @@ -2838,29 +2725,29 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; { if (bubbleData.shouldHideSenderName) { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class : RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitleWithoutSenderName : RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitleWithoutSenderName; } else { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.class : RoomOutgoingTextMsgWithPaginationTitleBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithPaginationTitle : RoomTimelineCellIdentifierOutgoingTextMessageWithPaginationTitle; } } else if (bubbleData.shouldHideSenderInformation) { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.class :RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderInfo : RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderInfo; } else if (bubbleData.shouldHideSenderName) { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.class : RoomOutgoingTextMsgWithoutSenderNameBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingTextMessageEncryptedWithoutSenderName : RoomTimelineCellIdentifierOutgoingTextMessageWithoutSenderName; } else { - cellViewClass = showEncryptionBadge ? RoomOutgoingEncryptedTextMsgBubbleCell.class : RoomOutgoingTextMsgBubbleCell.class; + cellIdentifier = showEncryptionBadge ? RoomTimelineCellIdentifierOutgoingTextMessageEncrypted : RoomTimelineCellIdentifierOutgoingTextMessage; } } } - return cellViewClass; + return cellIdentifier; } #pragma mark - MXKDataSource delegate From ab40dcd98fbb1a8bff2efd3c6cf637248d88a1d8 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 11:14:50 +0100 Subject: [PATCH 095/209] RoomBubbleCellData: Handle event merge configuration. --- Riot/Modules/Room/CellData/RoomBubbleCellData.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 81867be76..5be5d8022 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -826,6 +826,12 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat - (BOOL)addEvent:(MXEvent*)event andRoomState:(MXRoomState*)roomState { + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + if (NO == [timelineConfiguration.currentStyle canAddEvent:event and:roomState to:self]) { + return NO; + } + BOOL shouldAddEvent = YES; switch (self.tag) From a79c6efec3cc7b97e012088dd58ceaf361b3bf3d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 11:15:38 +0100 Subject: [PATCH 096/209] BubbleRoomCellLayoutUpdater: Update bubble height computation. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 874be05e3..af7360cd2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -196,7 +196,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { let firstEventId = firstComponent.event.eventId let firstMessageTopPosition = cell.topPosition(ofEvent: firstEventId) - let additionalContentHeight = roomBubbleCellData.additionalHeight(forEvent: lastEventId) + let additionalContentHeight = roomBubbleCellData.additionalContentHeight bubbleHeight = lastMessageBottomPosition - firstMessageTopPosition - additionalContentHeight + bottomMargin From b0107ce9351ae6d659e2690c4283ff8c730cf1a7 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 14 Jan 2022 11:40:41 +0100 Subject: [PATCH 097/209] Settings: Enable message bubble configuration. --- Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index fe1bdcf8e..f05c3b592 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -293,7 +293,7 @@ final class BuildSettings: NSObject { static let roomScreenAllowFilesAction: Bool = true // Timeline style - static let roomScreenAllowTimelineStyleConfiguration: Bool = false + static let roomScreenAllowTimelineStyleConfiguration: Bool = true static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain static var roomScreenEnableMessageBubblesByDefault: Bool { return self.roomScreenTimelineDefaultStyleIdentifier == .bubble From 1ccdc23c8e6d329b1d13a1a74d0cd7b438800e39 Mon Sep 17 00:00:00 2001 From: Doug Date: Fri, 14 Jan 2022 15:05:54 +0000 Subject: [PATCH 098/209] Add onboarding splash screen strings for Weblate. --- Riot/Assets/en.lproj/Vector.strings | 12 +++++++++ Riot/Generated/Strings.swift | 40 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 32a5fc949..899f88db0 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -81,6 +81,18 @@ "accessibility_checkbox_label" = "checkbox"; "accessibility_button_label" = "button"; +// Onboarding +"onboarding_splash_register_button_title" = "Create account"; +"onboarding_splash_login_button_title" = "I already have an account"; +"onboarding_splash_page_1_title" = "Own your conversations."; +"onboarding_splash_page_1_message" = "Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home."; +"onboarding_splash_page_2_title" = "You’re in control."; +"onboarding_splash_page_2_message" = "Choose where your conversations are kept, giving you control and independence. Connected via Matrix."; +"onboarding_splash_page_3_title" = "Secure messaging."; +"onboarding_splash_page_3_message" = "End-to-end encrypted and no phone number required. No ads or datamining."; +"onboarding_splash_page_4_title_no_pun" = "Messaging for your team."; +"onboarding_splash_page_4_message" = "Element is also great for the workplace. It’s trusted by the world’s most secure organisations."; + // Authentication "auth_login" = "Log in"; "auth_register" = "Register"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 3893e0098..96d4f6299 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -2347,6 +2347,46 @@ public class VectorL10n: NSObject { public static var on: String { return VectorL10n.tr("Vector", "on") } + /// I already have an account + public static var onboardingSplashLoginButtonTitle: String { + return VectorL10n.tr("Vector", "onboarding_splash_login_button_title") + } + /// Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home. + public static var onboardingSplashPage1Message: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_1_message") + } + /// Own your conversations. + public static var onboardingSplashPage1Title: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_1_title") + } + /// Choose where your conversations are kept, giving you control and independence. Connected via Matrix. + public static var onboardingSplashPage2Message: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_2_message") + } + /// You’re in control. + public static var onboardingSplashPage2Title: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_2_title") + } + /// End-to-end encrypted and no phone number required. No ads or datamining. + public static var onboardingSplashPage3Message: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_3_message") + } + /// Secure messaging. + public static var onboardingSplashPage3Title: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_3_title") + } + /// Element is also great for the workplace. It’s trusted by the world’s most secure organisations. + public static var onboardingSplashPage4Message: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_4_message") + } + /// Messaging for your team. + public static var onboardingSplashPage4TitleNoPun: String { + return VectorL10n.tr("Vector", "onboarding_splash_page_4_title_no_pun") + } + /// Create account + public static var onboardingSplashRegisterButtonTitle: String { + return VectorL10n.tr("Vector", "onboarding_splash_register_button_title") + } /// Open public static var `open`: String { return VectorL10n.tr("Vector", "open") From 46543bf073c2d603ae8b25852f97b04cc39ec9f0 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 14 Jan 2022 13:26:14 +0200 Subject: [PATCH 099/209] Fix vector-im/element-ios/issues/4208 - Home screen doesn't update properly on theme changes. --- Riot/Modules/Common/Recents/RecentsViewController.m | 7 ++----- changelog.d/4208.bugfix | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) create mode 100644 changelog.d/4208.bugfix diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index 0b8e9efbb..f950b2b23 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -193,11 +193,8 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro [ThemeService.shared.theme applyStyleOnSearchBar:tableSearchBar]; [ThemeService.shared.theme applyStyleOnSearchBar:self.recentsSearchBar]; - if (self.recentsTableView.dataSource) - { - // Force table refresh - [self cancelEditionMode:YES]; - } + // Force table refresh + [self.recentsTableView reloadData]; [self.emptyView updateWithTheme:ThemeService.shared.theme]; diff --git a/changelog.d/4208.bugfix b/changelog.d/4208.bugfix new file mode 100644 index 000000000..135c79d86 --- /dev/null +++ b/changelog.d/4208.bugfix @@ -0,0 +1 @@ +Fixed home screen not updating properly on theme changes. \ No newline at end of file From ce551e92fe3383223a9d0438ef5320cee3b973f4 Mon Sep 17 00:00:00 2001 From: libexus Date: Thu, 13 Jan 2022 17:12:52 +0000 Subject: [PATCH 100/209] Translated using Weblate (German) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/de/ --- .../Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings index 12a8826cc..dfa373dc7 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/de.lproj/MatrixKit.strings @@ -505,3 +505,4 @@ "attachment_unsupported_preview_title" = "Vorschau kann nicht angezeigt werden"; "auth_reset_password_error_unauthorized" = "Nicht Authorisiert"; "message_reply_to_sender_sent_their_location" = "hat den eigenen Standort geteilt."; +"room_displayname_all_other_members_left" = "%@ (Verlassen)"; From af8ea417b5ca4520f64e3d58697d0464012a1e9c Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Fri, 14 Jan 2022 13:43:19 +0000 Subject: [PATCH 101/209] Translated using Weblate (German) Currently translated at 99.8% (1383 of 1385 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index bb433b561..be91f3689 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -136,10 +136,10 @@ "room_participants_action_section_other" = "Optionen"; "room_participants_action_invite" = "Einladen"; "room_participants_action_leave" = "Diesen Raum verlassen"; -"room_participants_action_remove" = "Von diesem Raum entfernen"; +"room_participants_action_remove" = "Aus diesem Raum entfernen"; "room_participants_action_ban" = "Aus diesem Raum bannen"; -"room_participants_action_ignore" = "Alle Nachrichten von diesem Nutzer verbergen"; -"room_participants_action_unignore" = "Zeige alle Nachrichten von diesem Nutzer"; +"room_participants_action_ignore" = "Alle Nachrichten dieser Person verbergen"; +"room_participants_action_unignore" = "Alle Nachrichten dieser Person zeigen"; "room_participants_action_set_moderator" = "Moderationsrechte vergeben"; "room_participants_action_set_admin" = "Administrationsrechte vergeben"; "room_participants_action_start_new_chat" = "Starte neuen Chat"; @@ -299,7 +299,7 @@ "room_participants_ago" = "her"; "room_participants_action_section_admin_tools" = "Admin-Werkzeuge"; "room_participants_action_unban" = "Entsperren"; -"room_participants_action_set_default_power_level" = "Zurück auf normale Berechtigung"; +"room_participants_action_set_default_power_level" = "Besondere Berechtigungen entziehen"; "room_participants_action_start_voice_call" = "Starte Sprach-Anruf"; "room_ongoing_conference_call" = "Laufender Konferenz-Anruf. Trete bei als %@ oder %@."; "room_event_action_redact" = "Entfernen"; From 7f149b402faaaed48f0bb1bf71dc4877846ee03a Mon Sep 17 00:00:00 2001 From: UwUnyaa Date: Fri, 14 Jan 2022 19:49:53 +0000 Subject: [PATCH 102/209] Translated using Weblate (Polish) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/pl/ --- Riot/Assets/pl.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/pl.lproj/Localizable.strings b/Riot/Assets/pl.lproj/Localizable.strings index 761802de0..3be30e2fb 100644 --- a/Riot/Assets/pl.lproj/Localizable.strings +++ b/Riot/Assets/pl.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Powiadomienie"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ udostępnił(-a) swoją lokację"; From 10a56672cf00bbc02bd85621a16e0c622904e0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 15 Jan 2022 14:16:39 +0000 Subject: [PATCH 103/209] Translated using Weblate (Estonian) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/et/ --- .../Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings index 310a27da6..458efee70 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/et.lproj/MatrixKit.strings @@ -270,7 +270,7 @@ // Language picker "language_picker_title" = "Vali keel"; "language_picker_default_language" = "Vaikimisi (%@)"; -"notice_room_invite" = "%@ kutsus kasutajat %@"; +"notice_room_invite" = "%@ saatis kutse kasutajale %@"; "notice_room_third_party_invite" = "%@ saatis kasutajale %@ kutse jututoaga liitumiseks"; "notice_room_third_party_registered_invite" = "%@ võttis vastu kutse %@ nimel"; "notice_room_third_party_revoked_invite" = "%@ võttis tagasi jututoaga liitumise kutse kasutajalt %@"; @@ -433,7 +433,7 @@ "notice_room_history_visible_to_members_from_invited_point_for_dm" = "%@ määras, et jututoa tulevane ajalugu on nähtav kõikidele selle liikmetele liitumiskutse saatmise hetkest."; "notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ määras, et jututoa tulevane ajalugu on nähtav kõikidele selle liikmetele nende liitumise hetkest."; "room_left_for_dm" = "Sina lahkusid"; -"notice_room_third_party_invite_for_dm" = "%@ kutsus kasutajat %@"; +"notice_room_third_party_invite_for_dm" = "%@ saatis kutse kasutajale %@"; "notice_room_third_party_revoked_invite_for_dm" = "%@ võttis tagasi kasutaja %@ kutse"; "notice_room_name_changed_for_dm" = "%@ muutis jututoa uueks nimeks %@."; "notice_room_third_party_invite_by_you_for_dm" = "Sina kutsusid kasutajat %@"; From cf7b2805f53c5fe78b432f95919adf4e0cfd0f03 Mon Sep 17 00:00:00 2001 From: UwUnyaa Date: Fri, 14 Jan 2022 19:49:19 +0000 Subject: [PATCH 104/209] Translated using Weblate (Polish) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/pl/ --- .../MatrixKitAssets.bundle/pl.lproj/MatrixKit.strings | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pl.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pl.lproj/MatrixKit.strings index d90ed3c37..1f9c919dd 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pl.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/pl.lproj/MatrixKit.strings @@ -496,3 +496,12 @@ "attachment_small_with_resolution" = "Mały %@ (~%@)"; "attachment_size_prompt_message" = "Możesz to wyłączyć w ustawieniach."; "attachment_size_prompt_title" = "Potwierdź rozmiar, który chcesz wysłać"; +"auth_reset_password_error_not_found" = "Nie znaleziono"; +"auth_reset_password_error_unauthorized" = "Brak autoryzacji"; +"auth_invalid_user_name" = "Niepoprawna nazwa użytkownika"; +"attachment_unsupported_preview_message" = "Ten format pliku nie jest obsługiwany."; +"attachment_unsupported_preview_title" = "Brak podglądu"; +"message_reply_to_sender_sent_their_location" = "udostępnił(-a) swoją lokację."; +"room_displayname_all_other_members_left" = "%@ (Opuścił-a)"; +"auth_username_in_use" = "Nazwa użytkownika jest już używana"; +"rename" = "Zmień nazwę"; From bbcc316ff7c1894d2ec4c853f55e201812891415 Mon Sep 17 00:00:00 2001 From: Ekaterina Gerasimova Date: Thu, 9 Dec 2021 22:37:53 +0000 Subject: [PATCH 105/209] Fix graphql warnings in issue automation Fixes #5294 --- .github/workflows/triage-move-labelled.yml | 10 +++++----- changelog.d/5294.misc | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) create mode 100644 changelog.d/5294.misc diff --git a/.github/workflows/triage-move-labelled.yml b/.github/workflows/triage-move-labelled.yml index 44704833b..e6a23f00d 100644 --- a/.github/workflows/triage-move-labelled.yml +++ b/.github/workflows/triage-move-labelled.yml @@ -34,7 +34,7 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { + mutation add_to_project($projectid:ID!,$contentid:ID!) { addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { projectNextItem { id @@ -59,7 +59,7 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { + mutation add_to_project($projectid:ID!,$contentid:ID!) { addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { projectNextItem { id @@ -82,7 +82,7 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { + mutation add_to_project($projectid:ID!,$contentid:ID!) { addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { projectNextItem { id @@ -105,7 +105,7 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { + mutation add_to_project($projectid:ID!,$contentid:ID!) { addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { projectNextItem { id @@ -128,7 +128,7 @@ jobs: with: headers: '{"GraphQL-Features": "projects_next_graphql"}' query: | - mutation add_to_project($projectid:String!,$contentid:String!) { + mutation add_to_project($projectid:ID!,$contentid:ID!) { addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { projectNextItem { id diff --git a/changelog.d/5294.misc b/changelog.d/5294.misc new file mode 100644 index 000000000..c1a31bb4a --- /dev/null +++ b/changelog.d/5294.misc @@ -0,0 +1 @@ +Fix graphql warnings in issue workflow automation From 3ea9de7c53d3ed99509390b7f4bf512bbbdd1ae9 Mon Sep 17 00:00:00 2001 From: Ekaterina Gerasimova Date: Sun, 16 Jan 2022 17:37:19 +0000 Subject: [PATCH 106/209] Sync issue automation with element-web Add automation for * labelling Labs issues * adding design and product issues to boards * adding design and product PRs to boards * add UISI issues to Crypto team board Fixes issue #5380 --- .github/workflows/triage-move-labelled.yml | 52 ++++++- .github/workflows/triage-move-unlabelled.yml | 26 ++++ .github/workflows/triage-priority-bugs.yml | 1 + .github/workflows/triage-review-requests.yml | 139 +++++++++++++++++++ 4 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/triage-review-requests.yml diff --git a/.github/workflows/triage-move-labelled.yml b/.github/workflows/triage-move-labelled.yml index e6a23f00d..320360fd5 100644 --- a/.github/workflows/triage-move-labelled.yml +++ b/.github/workflows/triage-move-labelled.yml @@ -5,6 +5,31 @@ on: types: [labeled] jobs: + apply_Z-Labs_label: + name: Add Z-Labs label for features behind labs flags + runs-on: ubuntu-latest + if: > + contains(github.event.issue.labels.*.name, 'A-Maths') || + contains(github.event.issue.labels.*.name, 'A-Message-Pinning') || + contains(github.event.issue.labels.*.name, 'A-Threads') || + contains(github.event.issue.labels.*.name, 'A-Polls') || + contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || + contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') || + contains(github.event.issue.labels.*.name, 'Z-IA') || + contains(github.event.issue.labels.*.name, 'A-Themes-Custom') || + contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || + contains(github.event.issue.labels.*.name, 'A-Tags') + steps: + - uses: actions/github-script@v5 + with: + script: | + github.rest.issues.addLabels({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['Z-Labs'] + }) + move_needs_info_issues: name: X-Needs-Info issues to Need info column on triage board runs-on: ubuntu-latest @@ -47,13 +72,38 @@ jobs: PROJECT_ID: "PN_kwDOAM0swc0sUA" GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + add_product_issues_to_project: + name: X-Needs-Product to Design project board + runs-on: ubuntu-latest + if: > + contains(github.event.issue.labels.*.name, 'X-Needs-Product') + steps: + - uses: octokit/graphql-action@v2.x + id: add_to_project + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + mutation add_to_project($projectid:ID!,$contentid:ID!) { + addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { + projectNextItem { + id + } + } + } + projectid: ${{ env.PROJECT_ID }} + contentid: ${{ github.event.issue.node_id }} + env: + PROJECT_ID: "PN_kwDOAM0swc4AAg6N" + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + Delight_issues_to_board: name: Spaces issues to Delight project board runs-on: ubuntu-latest if: > contains(github.event.issue.labels.*.name, 'A-Spaces') || contains(github.event.issue.labels.*.name, 'A-Space-Settings') || - contains(github.event.issue.labels.*.name, 'A-Subspaces') + contains(github.event.issue.labels.*.name, 'A-Subspaces') || + contains(github.event.issue.labels.*.name, 'Z-IA') steps: - uses: octokit/graphql-action@v2.x with: diff --git a/.github/workflows/triage-move-unlabelled.yml b/.github/workflows/triage-move-unlabelled.yml index 94bd049b9..453fafe54 100644 --- a/.github/workflows/triage-move-unlabelled.yml +++ b/.github/workflows/triage-move-unlabelled.yml @@ -33,3 +33,29 @@ jobs: project: Issue triage column: Triaged repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }} + + remove_Z-Labs_label: + name: Remove Z-Labs label when features behind labs flags are removed + runs-on: ubuntu-latest + if: > + !(contains(github.event.issue.labels.*.name, 'A-Maths') || + contains(github.event.issue.labels.*.name, 'A-Message-Pinning') || + contains(github.event.issue.labels.*.name, 'A-Threads') || + contains(github.event.issue.labels.*.name, 'A-Polls') || + contains(github.event.issue.labels.*.name, 'A-Location-Sharing') || + contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') || + contains(github.event.issue.labels.*.name, 'Z-IA') || + contains(github.event.issue.labels.*.name, 'A-Themes-Custom') || + contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || + contains(github.event.issue.labels.*.name, 'A-Tags')) && + contains(github.event.issue.labels.*.name, 'Z-Labs') + steps: + - uses: actions/github-script@v5 + with: + script: | + github.rest.issues.removeLabel({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + name: ['Z-Labs'] + }) diff --git a/.github/workflows/triage-priority-bugs.yml b/.github/workflows/triage-priority-bugs.yml index 0a4d1c49f..843c6234c 100644 --- a/.github/workflows/triage-priority-bugs.yml +++ b/.github/workflows/triage-priority-bugs.yml @@ -34,6 +34,7 @@ jobs: P1_issues_to_crypto_team_workboard: runs-on: ubuntu-latest if: > + contains(github.event.issue.labels.*.name, 'Z-UISI') || (contains(github.event.issue.labels.*.name, 'A-E2EE') || contains(github.event.issue.labels.*.name, 'A-E2EE-Cross-Signing') || contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') || diff --git a/.github/workflows/triage-review-requests.yml b/.github/workflows/triage-review-requests.yml new file mode 100644 index 000000000..8306cffef --- /dev/null +++ b/.github/workflows/triage-review-requests.yml @@ -0,0 +1,139 @@ +name: Move pull requests asking for review to the relevant project +on: + pull_request_target: + types: [review_requested] + +jobs: + add_design_pr_to_project: + name: Move PRs asking for design review to the design board + runs-on: ubuntu-latest + steps: + - uses: octokit/graphql-action@v2.x + id: find_team_members + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + query find_team_members($team: String!) { + organization(login: "vector-im") { + team(slug: $team) { + members { + nodes { + login + } + } + } + } + } + team: ${{ env.TEAM }} + env: + TEAM: "design" + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + - id: any_matching_reviewers + run: | + # Fetch requested reviewers, and people who are on the team + echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json + echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json + jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt + jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt + + # Fetch requested team reviewers, and the name of the team + echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json + jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt + echo '${{ env.TEAM }}' | tee /tmp/team.txt + + # If either a reviewer matches a team member, or a team matches our team, say "true" + if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then + echo "::set-output name=match::true" + elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then + echo "::set-output name=match::true" + else + echo "::set-output name=match::false" + fi + env: + TEAM: "design" + - uses: octokit/graphql-action@v2.x + id: add_to_project + if: steps.any_matching_reviewers.outputs.match == 'true' + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + mutation add_to_project($projectid:ID!, $contentid:ID!) { + addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { + projectNextItem { + id + } + } + } + projectid: ${{ env.PROJECT_ID }} + contentid: ${{ github.event.pull_request.node_id }} + env: + PROJECT_ID: "PN_kwDOAM0swc0sUA" + TEAM: "design" + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + + add_product_pr_to_project: + name: Move PRs asking for design review to the design board + runs-on: ubuntu-latest + steps: + - uses: octokit/graphql-action@v2.x + id: find_team_members + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + query find_team_members($team: String!) { + organization(login: "vector-im") { + team(slug: $team) { + members { + nodes { + login + } + } + } + } + } + team: ${{ env.TEAM }} + env: + TEAM: "product" + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} + - id: any_matching_reviewers + run: | + # Fetch requested reviewers, and people who are on the team + echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json + echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json + jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt + jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt + + # Fetch requested team reviewers, and the name of the team + echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json + jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt + echo '${{ env.TEAM }}' | tee /tmp/team.txt + + # If either a reviewer matches a team member, or a team matches our team, say "true" + if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then + echo "::set-output name=match::true" + elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then + echo "::set-output name=match::true" + else + echo "::set-output name=match::false" + fi + env: + TEAM: "product" + - uses: octokit/graphql-action@v2.x + id: add_to_project + if: steps.any_matching_reviewers.outputs.match == 'true' + with: + headers: '{"GraphQL-Features": "projects_next_graphql"}' + query: | + mutation add_to_project($projectid:ID!, $contentid:ID!) { + addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) { + projectNextItem { + id + } + } + } + projectid: ${{ env.PROJECT_ID }} + contentid: ${{ github.event.pull_request.node_id }} + env: + PROJECT_ID: "PN_kwDOAM0swc4AAg6N" + TEAM: "product" + GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }} From 77649017576d0b578eef10c9a89e6df23c33e6b8 Mon Sep 17 00:00:00 2001 From: Jozef Gaal Date: Fri, 14 Jan 2022 22:00:41 +0000 Subject: [PATCH 107/209] Translated using Weblate (Slovak) Currently translated at 96.2% (1344 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ --- Riot/Assets/sk.lproj/Vector.strings | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Riot/Assets/sk.lproj/Vector.strings b/Riot/Assets/sk.lproj/Vector.strings index a8ed26c07..b86434589 100644 --- a/Riot/Assets/sk.lproj/Vector.strings +++ b/Riot/Assets/sk.lproj/Vector.strings @@ -1632,3 +1632,35 @@ "settings_pin_rooms_with_missed_notif" = "Pripnúť miestnosti so zmeškanými oznámeniami"; "settings_confirm_media_size" = "Potvrdiť veľkosť pri odosielaní"; "ok" = "OK"; +"poll_edit_form_question_or_topic" = "Otázka alebo téma"; +"poll_timeline_vote_not_registered_title" = "Hlas nebol zaznamenaný"; +"poll_timeline_vote_not_registered_subtitle" = "Je nám ľúto, váš hlas nebol zaznamenaný. Skúste to prosím znova"; +"poll_timeline_not_closed_title" = "Nepodarilo sa ukončiť anketu"; + +// MARK: - Location sharing + +"location_sharing_title" = "Poloha"; +"location_sharing_close_action" = "Zavrieť"; +"location_sharing_share_action" = "Zdieľať"; +"location_sharing_loading_map_error_title" = "%@ sa nepodarilo načítať mapu. Skúste to prosím neskôr."; +"location_sharing_locating_user_error_title" = "%@ sa nepodarilo získať prístup k vašej polohe. Skúste to prosím neskôr."; +"location_sharing_invalid_authorization_error_title" = "%@ nemá povolenie na prístup k vašej polohe. Prístup môžete povoliť v ponuke Nastavenia > Poloha"; +"location_sharing_invalid_authorization_not_now" = "Teraz nie"; +"location_sharing_invalid_authorization_settings" = "Nastavenia"; +"location_sharing_open_apple_maps" = "Otvoriť v službe Apple Mapy"; +"location_sharing_open_google_maps" = "Otvoriť v službe Mapy Google"; +"location_sharing_settings_header" = "Zdieľanie polohy"; +"location_sharing_settings_toggle_title" = "Povoliť zdieľanie polohy"; + +// Onboarding +"onboarding_splash_register_button_title" = "Vytvoriť účet"; +"onboarding_splash_login_button_title" = "Už mám účet"; +"onboarding_splash_page_1_title" = "Vlastnite svoje konverzácie."; +"onboarding_splash_page_1_message" = "Bezpečná a nezávislá komunikácia, ktorá vám poskytuje rovnakú úroveň súkromia ako rozhovor zoči-voči vo vašom vlastnom dome."; +"onboarding_splash_page_2_title" = "Vy máte všetko pod kontrolou."; +"onboarding_splash_page_2_message" = "Vyberte si, kde budú vaše rozhovory uložené, a získajte tak kontrolu a nezávislosť. Pripojené cez Matrix."; +"onboarding_splash_page_3_title" = "Zabezpečené zasielanie správ."; +"onboarding_splash_page_3_message" = "End-to-end šifrovanie a bez potreby telefónneho čísla. Žiadne reklamy ani zneužívanie údajov."; +"onboarding_splash_page_4_title_no_pun" = "Zasielanie správ pre váš tím."; +"onboarding_splash_page_4_message" = "Element je skvelý aj na pracovisku. Dôverujú mu najbezpečnejšie organizácie na svete."; +"settings_enable_room_message_bubbles" = "Správy v bublinách"; From 2d7922453167bc60ac18395917c28442af46238a Mon Sep 17 00:00:00 2001 From: Ihor Hordiichuk Date: Fri, 14 Jan 2022 18:41:37 +0000 Subject: [PATCH 108/209] Translated using Weblate (Ukrainian) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ --- Riot/Assets/uk.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/uk.lproj/Vector.strings b/Riot/Assets/uk.lproj/Vector.strings index 3cbda465e..e85515b74 100644 --- a/Riot/Assets/uk.lproj/Vector.strings +++ b/Riot/Assets/uk.lproj/Vector.strings @@ -1718,3 +1718,16 @@ "location_sharing_title" = "Місцеперебування"; "ok" = "Гаразд"; +"settings_enable_room_message_bubbles" = "Бульбашки повідомлень"; +"onboarding_splash_page_4_message" = "Елемент також чудово підходить для роботи. Йому довіряють найбезпечніші організації світу."; +"onboarding_splash_page_4_title_no_pun" = "Спілкування зі своєю командою."; +"onboarding_splash_page_3_message" = "Наскрізне шифрування та відсутність потреби у телефонному номері. Без реклами чи аналізу даних."; +"onboarding_splash_page_3_title" = "Безпечне спілкування."; +"onboarding_splash_page_2_message" = "Оберіть, де зберігати ваші бесіди, що дасть вам контроль і незалежність. Спілкуйтеся через Matrix."; +"onboarding_splash_page_2_title" = "Ви контролюєте все."; +"onboarding_splash_page_1_message" = "Безпечне та незалежне спілкування, яке дає вам такий же рівень приватності як особиста розмова у вашому власному домі."; +"onboarding_splash_page_1_title" = "Будьте господарем свого спілкування."; +"onboarding_splash_login_button_title" = "У мене вже є обліковий запис"; + +// Onboarding +"onboarding_splash_register_button_title" = "Створити обліковий запис"; From 2d8b3868bd246e1505a4a1e48941bbf30a652671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Priit=20J=C3=B5er=C3=BC=C3=BCt?= Date: Sat, 15 Jan 2022 14:32:33 +0000 Subject: [PATCH 109/209] Translated using Weblate (Estonian) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ --- Riot/Assets/et.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/et.lproj/Vector.strings b/Riot/Assets/et.lproj/Vector.strings index 4a0ee7794..c88b9e297 100644 --- a/Riot/Assets/et.lproj/Vector.strings +++ b/Riot/Assets/et.lproj/Vector.strings @@ -1543,3 +1543,16 @@ "location_sharing_title" = "Asukoht"; "ok" = "Sobib"; +"settings_enable_room_message_bubbles" = "Jutumullid"; +"onboarding_splash_page_4_message" = "Element sobib ideaalselt kasutamiseks töökeskkonnas. Ta on kasutusel ka mitmetes üliturvalistes organisatsioonides."; +"onboarding_splash_page_4_title_no_pun" = "Sõnumisuhtlus sinu tiimi või kogukonna jaoks."; +"onboarding_splash_page_3_message" = "Tagatud on andmete läbiv krüptimine ning oma telefoninumbrit ei pea sa jagama. Pole reklaame ega sinu andmete kogumist."; +"onboarding_splash_page_3_title" = "Turvaline sõnumisuhtlus."; +"onboarding_splash_page_2_message" = "Sa ise valid serveri, kus sinu vestlusi hoitakse ning sellega tagadki kontrolli oma andmete üle. Lahendus põhineb Matrix'i võrgul."; +"onboarding_splash_page_2_title" = "Sul on kontroll oma andmete üle."; +"onboarding_splash_page_1_message" = "Turvaline ja sõltumatu suhtluslahendus, mis tagab sama privaatsuse, kui omavaheline vestlus sinu kodus."; +"onboarding_splash_page_1_title" = "Vestlused, mida sa tegelikult ka omad."; +"onboarding_splash_login_button_title" = "Mul on kasutajakonto juba olemas"; + +// Onboarding +"onboarding_splash_register_button_title" = "Loo kasutajakonto"; From e4d9022ace82c9ea07c410624d54c0d4689449b6 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Sat, 15 Jan 2022 14:53:16 +0000 Subject: [PATCH 110/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ --- Riot/Assets/pt_BR.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index 045ebd3f5..0da05e327 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -1574,3 +1574,16 @@ "location_sharing_share_action" = "Compartilhar"; "location_sharing_close_action" = "Fechar"; "ok" = "OK"; +"onboarding_splash_page_1_message" = "Comunicação segura e independente que lhe dá o mesmo nível de privacidade que uma conversa face-a-face em sua própria casa."; +"settings_enable_room_message_bubbles" = "Bolhas de mensagem"; +"onboarding_splash_page_4_message" = "Elemente também é ótimo para o lugar de trabalho. É confiado pelas organizações mais seguras do mundo."; +"onboarding_splash_page_4_title_no_pun" = "Mensageria para seu time."; +"onboarding_splash_page_3_message" = "Encriptado ponta-a-ponta e nenhum número de telefone requerido. Sem publicidade ou datamining."; +"onboarding_splash_page_3_title" = "Mensageria segura."; +"onboarding_splash_page_2_message" = "Escolha onde suas conversas são mantidas, dando-lhe controle e independência. Conectado via Matrix."; +"onboarding_splash_page_2_title" = "Você está em controle."; +"onboarding_splash_page_1_title" = "Tenha posse de suas conversas."; +"onboarding_splash_login_button_title" = "Eu já tenho uma conta"; + +// Onboarding +"onboarding_splash_register_button_title" = "Criar conta"; From 51753cd705bbbee73162757cc61decdff8438609 Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Sun, 16 Jan 2022 12:14:14 +0000 Subject: [PATCH 111/209] Translated using Weblate (German) Currently translated at 99.8% (1394 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index be91f3689..103566d64 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -509,7 +509,7 @@ "room_action_send_photo_or_video" = "Foto oder Video senden"; "room_action_send_sticker" = "Aufkleber senden"; "settings_deactivate_account" = "DEAKTIVIERTES KONTO"; -"settings_deactivate_my_account" = "Benutzerkonto deaktiveren"; +"settings_deactivate_my_account" = "Mein Konto deaktivieren"; "widget_sticker_picker_no_stickerpacks_alert" = "Du hast aktuell keine Aufkleberpakete aktiviert."; "widget_sticker_picker_no_stickerpacks_alert_add_now" = "Welche hinzufügen?"; // GDPR @@ -548,8 +548,8 @@ "room_resource_limit_exceeded_message_contact_3" = " um diesen Dienst weiter zu nutzen."; "homeserver_connection_lost" = "Konnte keine Verbindung zum Heimserver herstellen."; "room_resource_usage_limit_reached_message_1_default" = "Dieser Heimserver hat eine seiner Ressourcengrenzen überschritten, sodass "; -"room_resource_usage_limit_reached_message_1_monthly_active_user" = "Dieser Heimserver hat seine Begrenzung an monatlich aktiven Benutzern überschritten, sodass "; -"room_resource_usage_limit_reached_message_2" = "einige Benutzer nicht in der Lage sein werden, sich anzumelden."; +"room_resource_usage_limit_reached_message_1_monthly_active_user" = "Dieser Heimserver hat seine Grenze an monatlich aktiven Benutzenden erreicht, sodass "; +"room_resource_usage_limit_reached_message_2" = "einige Benutzende nicht in der Lage sein werden, sich anzumelden."; "room_resource_usage_limit_reached_message_contact_3" = " um diese Obergrenze erhöhen zu lassen."; "auth_accept_policies" = "Bitte Regeln dieses Heimservers ansehen und akzeptieren:"; "settings_key_backup" = "SCHLÜSSEL-SICHERHEITSKOPIE"; @@ -634,13 +634,13 @@ "sign_out_existing_key_backup_alert_sign_out_action" = "Abmelden"; "sign_out_non_existing_key_backup_alert_title" = "Du verlierst den Zugriff auf deine verschlüsselten Nachrichten, wenn du dich jetzt abmeldest"; "sign_out_non_existing_key_backup_alert_setup_key_backup_action" = "Beginne Schlüsselsicherung zu nutzen"; -"sign_out_non_existing_key_backup_alert_discard_key_backup_action" = "Ich möchte meine verschlüsselten Nachrichten nicht"; +"sign_out_non_existing_key_backup_alert_discard_key_backup_action" = "Ich brauche meine verschlüsselten Nachrichten nicht"; "sign_out_non_existing_key_backup_sign_out_confirmation_alert_title" = "Du wirst deine verschlüsselten Nachrichten verlieren"; "sign_out_non_existing_key_backup_sign_out_confirmation_alert_message" = "Du verlierst den Zugriff auf deine verschlüsselten Nachrichten, es sei denn, du sicherst deine Schlüssel, bevor du dich abmeldest."; "sign_out_non_existing_key_backup_sign_out_confirmation_alert_sign_out_action" = "Abmelden"; "sign_out_non_existing_key_backup_sign_out_confirmation_alert_backup_action" = "Sicherungskopie"; "sign_out_key_backup_in_progress_alert_title" = "Schlüsselsicherung läuft. Wenn du dich jetzt abmeldest, verlierst du den Zugriff auf deine verschlüsselten Nachrichten."; -"sign_out_key_backup_in_progress_alert_discard_key_backup_action" = "Ich möchte meine verschlüsselten Nachrichten nicht"; +"sign_out_key_backup_in_progress_alert_discard_key_backup_action" = "Ich brauche meine verschlüsselten Nachrichten nicht"; "sign_out_key_backup_in_progress_alert_cancel_action" = "Ich werde warten"; // Key backup wrong version "e2e_key_backup_wrong_version_title" = "Neue Schlüsselsicherung"; @@ -1002,10 +1002,10 @@ "security_settings_crosssigning_info_not_bootstrapped" = "Quersignierung ist bisher nicht konfiguriert."; "room_member_power_level_admin_in" = "Admin in %@"; "room_member_power_level_moderator_in" = "Mod in %@"; -"room_member_power_level_custom_in" = "Benutzerdefiniert (%@) in %@"; +"room_member_power_level_custom_in" = "Selbstdefiniert (%@) in %@"; "room_member_power_level_short_admin" = "Admin"; "room_member_power_level_short_moderator" = "Mod"; -"room_member_power_level_short_custom" = "Benutzerdefiniert"; +"room_member_power_level_short_custom" = "Selbstdefiniert"; "security_settings_secure_backup" = "SICHERE SICHERHEITSKOPIE"; "security_settings_secure_backup_synchronise" = "Synchronisiere"; "security_settings_secure_backup_delete" = "Backup löschen"; @@ -1349,7 +1349,7 @@ "event_formatter_call_ringing" = "Läuten…"; "event_formatter_call_connecting" = "Verbinden…"; "settings_labs_enable_ringing_for_group_calls" = "Bei Gruppenanrufen klingeln"; -"room_no_privileges_to_create_group_call" = "Du musst Admin oder Mod sein, um einen Anruf zu starten."; +"room_no_privileges_to_create_group_call" = "Du musst Administrations- oder Moderationsrechte besitzen, um einen Anruf zu starten."; "room_join_group_call" = "Beitreten"; // Chat @@ -1583,3 +1583,16 @@ // MARK: - Location sharing "location_sharing_title" = "Standort"; +"onboarding_splash_page_4_title_no_pun" = "Nachrichtenaustausch für dein Team."; +"onboarding_splash_page_3_title" = "Sicherer Nachrichtenaustausch."; +"onboarding_splash_page_2_message" = "Wähle wo deine Gespräche liegen, für Kontrolle und Unabhängigkeit. Verbunden mit Matrix."; +"onboarding_splash_page_1_title" = "Nimm deine Gespräche in die eigene Hand."; +"onboarding_splash_login_button_title" = "Ich habe bereits ein Konto"; +"onboarding_splash_page_4_message" = "Element ist auch für die Arbeit großartig. Ihm vertrauen die sichersten Unternehmen der Welt."; +"onboarding_splash_page_3_message" = "Ende-zu-Ende-verschlüsselt und ohne Telefonnummer nutzbar. Keine Werbung oder Datenerfassung."; +"onboarding_splash_page_2_title" = "Du hast die Kontrolle."; +"onboarding_splash_page_1_message" = "Sichere und unabhängige Kommunikation, die für die gleiche Vertraulichkeit sorgt, wie ein Gespräch von Angesicht zu Angesicht in deinem eigenen Zuhause."; + +// Onboarding +"onboarding_splash_register_button_title" = "Konto erstellen"; +"settings_enable_room_message_bubbles" = "Nachrichtenblasen"; From 9451147dc6a2d07f465d4c9c865634e50cd564df Mon Sep 17 00:00:00 2001 From: Besnik Bleta Date: Fri, 14 Jan 2022 18:52:10 +0000 Subject: [PATCH 112/209] Translated using Weblate (Albanian) Currently translated at 99.6% (1391 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sq/ --- Riot/Assets/sq.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/sq.lproj/Vector.strings b/Riot/Assets/sq.lproj/Vector.strings index 4aacf6cb9..9c8151004 100644 --- a/Riot/Assets/sq.lproj/Vector.strings +++ b/Riot/Assets/sq.lproj/Vector.strings @@ -1595,3 +1595,16 @@ "location_sharing_title" = "Vendndodhje"; "ok" = "OK"; +"settings_enable_room_message_bubbles" = "Flluska mesazhesh"; +"onboarding_splash_page_4_message" = "Element-i është gjithashtu i goditur për në punë. Është i besuar nga entet më të sigurta të botës."; +"onboarding_splash_page_4_title_no_pun" = "Shkëmbim mesazhesh për ekipin tuaj."; +"onboarding_splash_page_3_message" = "I fshehtëzuar skaj më skaj dhe pa u dashur numër telefoni. Pa reklama, apo shfrytëzim të dhënash."; +"onboarding_splash_page_3_title" = "Shkëmbim i sigurt mesazhesh."; +"onboarding_splash_page_2_message" = "Zgjidhni ku mbahen bisedat tuaja, duke ju dhënë kontroll dhe pavarësi. Të lidhur përmes Matrix-i."; +"onboarding_splash_page_2_title" = "Kontrollin e keni ju."; +"onboarding_splash_page_1_message" = "Komunikim i sigurt dhe i pavarur, që ju jep të njëjtën shkallë privatësie si biseda kokë më kokë, në shtëpinë tuaj."; +"onboarding_splash_page_1_title" = "Jini zot i bisedave tuaja."; +"onboarding_splash_login_button_title" = "Kam tashmë një llogari"; + +// Onboarding +"onboarding_splash_register_button_title" = "Krijoni llogari"; From 41f35b43af0b0d9bfff19ac90a23d2326ed3d2d4 Mon Sep 17 00:00:00 2001 From: Linerly Date: Sat, 15 Jan 2022 00:17:35 +0000 Subject: [PATCH 113/209] Translated using Weblate (Indonesian) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ --- Riot/Assets/id.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/id.lproj/Vector.strings b/Riot/Assets/id.lproj/Vector.strings index 3eb7b52d4..a4fddb9be 100644 --- a/Riot/Assets/id.lproj/Vector.strings +++ b/Riot/Assets/id.lproj/Vector.strings @@ -1722,3 +1722,16 @@ "location_sharing_title" = "Lokasi"; "ok" = "OKE"; +"settings_enable_room_message_bubbles" = "Gelembung pesan"; +"onboarding_splash_page_4_message" = "Element juga bagus untuk tempat kerja. Terpercayai oleh organisasi paling aman di dunia."; +"onboarding_splash_page_4_title_no_pun" = "Perpesanan untuk tim Anda."; +"onboarding_splash_page_3_message" = "Terenkripsi secara ujung-ke-ujung dan tidak memerlukan nomor telepon. Tidak ada iklan atau penambangan data."; +"onboarding_splash_page_3_title" = "Perpesanan aman."; +"onboarding_splash_page_2_message" = "Pilihlah di mana percakapan Anda disimpan, memberikan Anda kendali dan kebebasan. Terhubung via Matrix."; +"onboarding_splash_page_2_title" = "Anda dalam kendali."; +"onboarding_splash_page_1_message" = "Komunikasi aman dan independen yang memberikan tingkat privasi yang sama seperti percakapan tatap muka di rumah Anda sendiri."; +"onboarding_splash_page_1_title" = "Miliki percakapan Anda."; +"onboarding_splash_login_button_title" = "Saya sudah punya akun"; + +// Onboarding +"onboarding_splash_register_button_title" = "Buat akun"; From 0048e2a11daa237eb07f9e97164a03e31db02821 Mon Sep 17 00:00:00 2001 From: UwUnyaa Date: Fri, 14 Jan 2022 20:03:10 +0000 Subject: [PATCH 114/209] Translated using Weblate (Polish) Currently translated at 94.2% (1316 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pl/ --- Riot/Assets/pl.lproj/Vector.strings | 65 +++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/Riot/Assets/pl.lproj/Vector.strings b/Riot/Assets/pl.lproj/Vector.strings index c4445fe9b..4f027c5db 100644 --- a/Riot/Assets/pl.lproj/Vector.strings +++ b/Riot/Assets/pl.lproj/Vector.strings @@ -217,9 +217,9 @@ "settings_calls_settings" = "POŁĄCZENIA"; "settings_user_interface" = "INTERFEJS UŻYTKOWNIKA"; "settings_ignored_users" = "IGNOROWANI UŻYTKOWNICY"; -"settings_contacts" = "LOKALNE KONTAKTY"; +"settings_contacts" = "KONTAKTY NA URZĄDZENIU"; "settings_advanced" = "ZAAWANSOWANE"; -"settings_other" = "Pozostałe powiadomienia"; +"settings_other" = "Pozostałe ustawienia"; "settings_devices" = "SESJE"; "settings_cryptography" = "KRYPTOGRAFIA"; "settings_deactivate_account" = "DEZAKTYWUJ KONTO"; @@ -416,7 +416,7 @@ "auth_email_not_found" = "Nie udało się wysłać wiadomości e-mail: Adres e-mail nie został znaleziony"; "auth_accept_policies" = "Przeczytaj i zaakceptuj zasady tego serwera domowego:"; "room_creation_wait_for_creation" = "Pokój jest już tworzony. Proszę czekaj."; -"room_creation_invite_another_user" = "Szukaj / zaproś przez ID Użytkownika, Nazwę lub e-mail"; +"room_creation_invite_another_user" = "ID użytkownika, nazwa lub email"; "search_people_placeholder" = "Szukaj przez ID Użytkownika, Nazwę lub e-mail"; "contacts_user_directory_offline_section" = "KATALOG UŻYTKOWNIKÓW (offline)"; "room_participants_remove_prompt_msg" = "Czy na pewno chcesz usunąć %@ z tej rozmowy?"; @@ -1265,7 +1265,7 @@ // Widget Picker "widget_picker_title" = "Integracje"; -"widget_integration_manager_disabled" = "Musisz włączyć Menadżer Integracji w ustawieniach"; +"widget_integration_manager_disabled" = "Musisz włączyć menadżer integracji w ustawieniach"; "widget_menu_remove" = "Usuń dla wszystkich"; "widget_menu_revoke_permission" = "Odbierz mi dostęp"; "widget_menu_open_outside" = "Otwórz w przeglądarce"; @@ -1321,7 +1321,7 @@ "identity_server_settings_description" = "Obecnie używasz %@ do wyszukiwania i bycia znalezionym przez kontakty, które znasz."; // Identity server settings -"identity_server_settings_title" = "Serwer Tożsamości"; +"identity_server_settings_title" = "Serwer tożsamości"; // AuthenticatedSessionViewControllerFactory "authenticated_session_flow_not_supported" = "Ta aplikacja nie obsługuje mechanizmu uwierzytelniania na Twoim serwerze domowym."; @@ -1365,7 +1365,7 @@ "settings_discovery_terms_not_signed" = "Zaakceptuj warunki korzystania z usługi serwera tożsamości (%@), aby umożliwić innym osobom wyszukiwanie Ciebie za pomocą adresu e-mail lub numeru telefonu."; "settings_discovery_no_identity_server" = "Obecnie nie używasz serwera tożsamości. Pomyśl o tym, aby go dodać by móc być odnalezionym przez osoby, które znasz."; "settings_devices_description" = "Publiczna nazwa sesji jest widoczna dla osób, z którymi się komunikujesz"; -"settings_integrations_allow_description" = "Użyj Menedżera Integracji (%@) do zarządzania botami, mostami, widżetami i pakietami naklejek.\n\nMenedżerowie integracji otrzymują dane konfiguracyjne i mogą modyfikować widżety, wysyłać zaproszenia do pokojów i ustawiać poziomy mocy w Twoim imieniu."; +"settings_integrations_allow_description" = "Użyj menedżera integracji (%@) do zarządzania botami, mostami, widżetami i pakietami naklejek.\n\nMenedżerowie integracji otrzymują dane konfiguracyjne i mogą modyfikować widżety, wysyłać zaproszenia do pokojów i ustawiać poziomy mocy w Twoim imieniu."; "settings_calls_stun_server_fallback_description" = "Zezwalaj na użycie rezerwowego serwera połączeń %@ w przypadku, gdy Twój serwer domowy go nie oferuje (Twój adres IP będzie udostępniany podczas połączenia)."; "settings_three_pids_management_information_part1" = "Wybierz, które adresy e-mail lub numery telefonów chcesz wykorzystać do logowania się lub odzyskiwania konta. Kontroluj, kto może Cię dzięki nim znaleźć przechodząc do "; "room_multiple_typing_notification" = "%@ i inni"; @@ -1535,7 +1535,58 @@ "settings_default" = "Powiadomienia dotyczące wiadomości"; "settings_notifications" = "POWIADOMIENIA"; "settings_show_url_previews_description" = "Podgląd URL będzie wyświetlany tylko w niezaszyfrowanych pokojach."; -"settings_show_url_previews" = "Pokaż podgląd adresów URL"; +"settings_show_url_previews" = "Pokaż podgląd stron"; "settings_confirm_media_size_description" = "Gdy ta opcja jest włączona, zostaniesz poproszony o potwierdzenie, w jakim rozmiarze obrazy i filmy będą wysyłane."; "settings_confirm_media_size" = "Potwierdź rozmiar podczas wysyłania"; "settings_sending_media" = "WYSYŁANIE ZDJĘĆ I WIDEO"; +"service_terms_modal_table_header_integration_manager" = "WARUNKI KORZYSTANIA Z MENEDŻERA INTEGRACJI"; +"service_terms_modal_table_header_identity_server" = "WARUNKI KORZYSTANIA Z SERWERA TOŻSAMOŚCI"; +"service_terms_modal_footer" = "To może być wyłączone później w ustawieniach."; + +// Service terms +"service_terms_modal_title_message" = "Aby kontynuować, wyraź zgodę na poniższe warunki użytkowania"; +"share_extension_send_now" = "Udostępnij teraz"; +"share_extension_low_quality_video_message" = "Udostępnij w %@ by uzyskać lepszą jakość, lub udostępnij w niskiej jakości poniżej."; +"share_extension_low_quality_video_title" = "Video będzie udostępnianie w niskiej jakości"; +"analytics_prompt_stop" = "Przestań udostępniać"; +"analytics_prompt_yes" = "Tak, to jest w porządku"; +"analytics_prompt_not_now" = "Nie teraz"; +"analytics_prompt_point_3" = "Możesz to wyłączyć w dowolnym momencie w ustawieniach"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_2" = "Nie dzielimy się informacjami z żadnymi firmami zewnętrznymi"; +/* Note: The word "don't" is formatted in bold */ +"analytics_prompt_point_1" = "Nie gromadzimy ani profilujemy żadnych danych na temat kont"; +"analytics_prompt_terms_link_upgrade" = "tutaj"; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_upgrade */ +"analytics_prompt_terms_upgrade" = "Przeczytaj nasze warunki użytkowania %@. Czy odpowiadają one Tobie?"; +"analytics_prompt_terms_link_new_user" = "tutaj"; +/* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ +"analytics_prompt_terms_new_user" = "Tutaj możesz przeczytać nasze warunki użytkowania %@."; +"analytics_prompt_message_upgrade" = "Wcześniej dostaliśmy Twoją zgodę na używanie zanonimizowanych danych na temat użytkowania. Teraz, by zrozumieć jak użytkownicy korzystają z wielu urządzeń, wygenerujemy identyfikator używany przez nie wszystkie."; +"analytics_prompt_message_new_user" = "Pomóż nam zidentyfikować problemy i poprawić @% udostępniając zanonimizowane dane o użytkowaniu. W celu zrozumienia jak użytkownicy korzystają z wielu urządzeń wygenerujemy identyfikator używany przez nie wszystkie."; + +// Analytics +"analytics_prompt_title" = "Pomóż ulepszyć %@"; +"settings_discovery_accept_terms" = "Zaakceptuj warunki używania serwera tożsamości"; +"settings_analytics_and_crash_data" = "Wysyłaj dane analityczne i o zawieszeniu aplikacji"; +"settings_labs_enabled_polls" = "Ankiety"; +"settings_contacts_enable_sync" = "Znajdź swoje kontakty"; +"settings_phone_contacts" = "KONTAKTY TELEFONICZNE"; +"settings_links" = "LINKI"; +"room_event_action_forward" = "Przekaż dalej"; +"room_event_action_end_poll" = "Zakończ ankietę"; +"room_event_action_remove_poll" = "Usuń ankietę"; +"find_your_contacts_identity_service_error" = "Nie można połączyć się s serwerem tożsamości."; +"contacts_address_book_permission_denied_alert_message" = "Aby włączyć kontakty, wejdź do ustawień Twojego urządzenia."; +"contacts_address_book_permission_denied_alert_title" = "Kontakty wyłączone"; +"room_recents_suggested_rooms_section" = "SUGEROWANE POKOJE"; +"onboarding_splash_page_1_message" = "Bezpieczna i niezależna komunikacja dająca Tobie ten sam poziom prywatności jak rozmowa twarzą w twarz w Twoim domu."; +"onboarding_splash_login_button_title" = "Mam już konto"; + +// Onboarding +"onboarding_splash_register_button_title" = "Stwórz konto"; +"accessibility_button_label" = "przycisk"; +"done" = "Gotowe"; +"open" = "Otwórz"; +"enable" = "Włącz"; +"ok" = "OK"; From a247b53bf1b080227b1923778d51f7edf894cb27 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 14:21:16 +0100 Subject: [PATCH 115/209] Add CollectionViewRightAlignFlowLayout to have right alignement display for collection view. --- .../CollectionViewRightAlignFlowLayout.swift | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 Riot/Modules/Common/CollectionView/CollectionViewRightAlignFlowLayout.swift diff --git a/Riot/Modules/Common/CollectionView/CollectionViewRightAlignFlowLayout.swift b/Riot/Modules/Common/CollectionView/CollectionViewRightAlignFlowLayout.swift new file mode 100644 index 000000000..946388de3 --- /dev/null +++ b/Riot/Modules/Common/CollectionView/CollectionViewRightAlignFlowLayout.swift @@ -0,0 +1,29 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +/// UICollectionViewFlowLayout with right align behavior +class CollectionViewRightAlignFlowLayout: UICollectionViewFlowLayout { + + override var flipsHorizontallyInOppositeLayoutDirection: Bool { + return true + } + + override var developmentLayoutDirection: UIUserInterfaceLayoutDirection { + return UIUserInterfaceLayoutDirection.rightToLeft + } +} From ee00af86edb25f3bed67a4564315e6bb3802ed09 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 14:23:07 +0100 Subject: [PATCH 116/209] BubbleReactionsView: Add alignement option (left or right). --- .../BubbleReactions/BubbleReactionsView.swift | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift b/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift index a5dcb54ac..844f79db9 100644 --- a/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift +++ b/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift @@ -18,6 +18,13 @@ import Foundation import MatrixSDK import Reusable import DGCollectionViewLeftAlignFlowLayout +import UIKit + +/// BubbleReactionsView items alignement +enum BubbleReactionsViewAlignement { + case left + case right +} @objcMembers final class BubbleReactionsView: UIView, NibOwnerLoadable { @@ -51,6 +58,12 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { } } + var alignment: BubbleReactionsViewAlignement = .left { + didSet { + self.updateCollectionViewLayout(for: alignment) + } + } + // MARK: - Setup private func commonInit() { @@ -87,7 +100,18 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { self.collectionView.isScrollEnabled = false self.collectionView.delegate = self self.collectionView.dataSource = self - self.collectionView.collectionViewLayout = DGCollectionViewLeftAlignFlowLayout() + self.alignment = .left + + self.collectionView.register(cellType: BubbleReactionViewCell.self) + self.collectionView.register(cellType: BubbleReactionActionViewCell.self) + self.collectionView.reloadData() + } + + private func updateCollectionViewLayout(for alignement: BubbleReactionsViewAlignement) { + + let collectionViewLayout = self.collectionViewLayout(for: alignement) + + self.collectionView.collectionViewLayout = collectionViewLayout if let collectionViewFlowLayout = self.collectionView.collectionViewLayout as? UICollectionViewFlowLayout { collectionViewFlowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize @@ -95,9 +119,22 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { collectionViewFlowLayout.minimumLineSpacing = Constants.minimumLineSpacing } - self.collectionView.register(cellType: BubbleReactionViewCell.self) - self.collectionView.register(cellType: BubbleReactionActionViewCell.self) self.collectionView.reloadData() + self.collectionView.collectionViewLayout.invalidateLayout() + } + + private func collectionViewLayout(for alignement: BubbleReactionsViewAlignement) -> UICollectionViewLayout { + + let collectionViewLayout: UICollectionViewLayout + + switch alignment { + case .left: + collectionViewLayout = DGCollectionViewLeftAlignFlowLayout() + case .right: + collectionViewLayout = CollectionViewRightAlignFlowLayout() + } + + return collectionViewLayout } private func setupLongPressGestureRecognizer() { From e4b65b0c8644ba63814c5598d182ac79de2f1f56 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 14:25:43 +0100 Subject: [PATCH 117/209] MXKRoomBubbleTableViewCell: Add convenient method to add temporary subview. --- .../Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h | 3 +++ .../Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h index 60cad3248..958da908a 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h +++ b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h @@ -325,4 +325,7 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction; */ - (void)setupViews; +/// Add temporary subview to `tmpSubviews` property. +- (void)addTmpSubview:(UIView*)subview; + @end diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m index b550a1ef1..36b7dcd38 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m +++ b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m @@ -1130,6 +1130,16 @@ static BOOL _disableLongPressGestureOnEvent; [self resetAttachmentViewBottomConstraintConstant]; } +- (void)addTmpSubview:(UIView*)subview +{ + if (!self.tmpSubviews) + { + self.tmpSubviews = [NSMutableArray new]; + } + + [self.tmpSubviews addObject:subview]; +} + #pragma mark - Attachment progress handling - (void)updateProgressUI:(NSDictionary*)statisticsDict From 843341b8793839b0a2db5c0e2cbcfe1dd293b57d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 14:58:34 +0100 Subject: [PATCH 118/209] Create RoomTimelineCellDecorator enables to add decoration on a cell (reactions, read receipts, timestamp, URL preview). --- .../Styles/RoomTimelineCellDecorator.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift new file mode 100644 index 000000000..ac4bae16c --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift @@ -0,0 +1,45 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +/// RoomTimelineCellDecorator enables to add decoration on a cell (reactions, read receipts, timestamp, URL preview). +@objc +protocol RoomTimelineCellDecorator { + + func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData) + + func addURLPreviewView(_ urlPreviewView: URLPreviewView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat) + + func addReactionView(_ reactionsView: BubbleReactionsView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) + + func addReadReceiptsView(_ readReceiptsView: MXKReceiptSendersContainer, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) + + func addSendStatusView(toCell cell: MXKRoomBubbleTableViewCell, + withFailedEventIds failedEventIds: Set) +} From 20d914da39f3e552f351d0ffa3416b78b781c24c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 14:59:48 +0100 Subject: [PATCH 119/209] RoomTimelineStyle: Add cell decorator property. --- .../Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index b0e4fe216..b57f498ee 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -32,6 +32,9 @@ protocol RoomTimelineStyle { /// Register and provide timeline cells var cellProvider: RoomTimelineCellProviderProtocol { get } + /// Handle cell decorations (reactions, read receipts, URL preview, …) + var cellDecorator: RoomTimelineCellDecorator { get } + // MARK: - Methods /// Indicate to merge or not event in timeline From 9fc83ca823d763a66789d4f5cbb4f62738f7f948 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:00:10 +0100 Subject: [PATCH 120/209] Implement PlainRoomTimelineCellDecorator. --- .../PlainRoomTimelineCellDecorator.swift | 138 ++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift new file mode 100644 index 000000000..5706e4e9e --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift @@ -0,0 +1,138 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +@objcMembers +class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { + + func addTimestampLabel(toCell bubbleCell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + bubbleCell.addTimestampLabel(forComponent: UInt(cellData.mostRecentComponentIndex)) + } + + func addURLPreviewView(_ urlPreviewView: URLPreviewView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat) { + cell.addTmpSubview(urlPreviewView) + + let cellContentView = cell.contentView + + urlPreviewView.translatesAutoresizingMaskIntoConstraints = false + urlPreviewView.availableWidth = cellData.maxTextViewWidth + cellContentView.addSubview(urlPreviewView) + + var leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin + if cellData.containsBubbleComponentWithEncryptionBadge { + leftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin + } + + let topMargin = contentViewPositionY + RoomBubbleCellLayout.urlPreviewViewTopMargin + RoomBubbleCellLayout.reactionsViewTopMargin + + // Set the preview view's origin + NSLayoutConstraint.activate([ + urlPreviewView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin), + urlPreviewView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: topMargin) + ]) + } + + func addReactionView(_ reactionsView: BubbleReactionsView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) { + + cell.addTmpSubview(reactionsView) + + if let reactionsDisplayable = cell as? BubbleCellReactionsDisplayable { + reactionsDisplayable.addReactionsView(reactionsView) + } else { + reactionsView.translatesAutoresizingMaskIntoConstraints = false + + let cellContentView = cell.contentView + + cellContentView.addSubview(reactionsView) + + var leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin + + if cellData.containsBubbleComponentWithEncryptionBadge { + leftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin + } + + let rightMargin = RoomBubbleCellLayout.reactionsViewRightMargin + let topMargin = RoomBubbleCellLayout.reactionsViewTopMargin + + // The top constraint may need to include the URL preview view + let topConstraint: NSLayoutConstraint + if let upperDecorationView = upperDecorationView { + topConstraint = reactionsView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, constant: topMargin) + } else { + topConstraint = reactionsView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: contentViewPositionY + topMargin) + } + + NSLayoutConstraint.activate([ + reactionsView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin), + reactionsView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin), + topConstraint + ]) + } + } + + func addReadReceiptsView(_ readReceiptsView: MXKReceiptSendersContainer, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat, + upperDecorationView: UIView?) { + + cell.addTmpSubview(readReceiptsView) + + if let readReceiptsDisplayable = cell as? BubbleCellReadReceiptsDisplayable { + readReceiptsDisplayable.addReadReceiptsView(readReceiptsView) + } else { + + let cellContentView = cell.contentView + + cellContentView.addSubview(readReceiptsView) + + // Force receipts container size + let widthConstraint = readReceiptsView.widthAnchor.constraint(equalToConstant: RoomBubbleCellLayout.readReceiptsViewWidth) + let heightConstraint = readReceiptsView.heightAnchor.constraint(equalToConstant: RoomBubbleCellLayout.readReceiptsViewHeight) + + // Force receipts container position + let trailingConstraint = readReceiptsView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -RoomBubbleCellLayout.readReceiptsViewRightMargin) + + let topMargin = RoomBubbleCellLayout.readReceiptsViewTopMargin + + let topConstraint: NSLayoutConstraint + if let upperDecorationView = upperDecorationView { + topConstraint = readReceiptsView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, constant: topMargin) + } else { + topConstraint = readReceiptsView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: contentViewPositionY + topMargin) + } + + NSLayoutConstraint.activate([ + widthConstraint, + heightConstraint, + trailingConstraint, + topConstraint + ]) + } + } + + func addSendStatusView(toCell cell: MXKRoomBubbleTableViewCell, withFailedEventIds failedEventIds: Set) { + cell.updateTickView(withFailedEventIds: failedEventIds) + } +} From 027b3e8de129572a3a4adb04d0ea937850a8f44e Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:01:20 +0100 Subject: [PATCH 121/209] PlainRoomTimelineStyle handle cell decorator. --- .../BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index 77065460c..4a5b812dc 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -26,12 +26,15 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { let cellProvider: RoomTimelineCellProviderProtocol + let cellDecorator: RoomTimelineCellDecorator + // MARK: - Setup init() { self.identifier = .plain self.cellLayoutUpdater = nil self.cellProvider = PlainRoomTimelineCellProvider() + self.cellDecorator = PlainRoomTimelineCellDecorator() } // MARK: - Methods From 990cf2d7db3a0352e6b8389388609b0fa9f4fca8 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:02:30 +0100 Subject: [PATCH 122/209] Create BubbleRoomTimelineCellDecorator. --- .../BubbleRoomTimelineCellDecorator.swift | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift new file mode 100644 index 000000000..37c51ceae --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -0,0 +1,21 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import UIKit + +class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { + +} From e0c6275e195cd8cc6b27902081e1523ed866ed89 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:03:56 +0100 Subject: [PATCH 123/209] BubbleRoomTimelineStyle handle cell decorator. --- .../BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index be1cfec05..37bcee15a 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -26,12 +26,15 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { let cellProvider: RoomTimelineCellProviderProtocol + let cellDecorator: RoomTimelineCellDecorator + // MARK: - Setup init() { self.identifier = .bubble self.cellLayoutUpdater = BubbleRoomCellLayoutUpdater() self.cellProvider = BubbleRoomTimelineCellProvider() + self.cellDecorator = BubbleRoomTimelineCellDecorator() } // MARK: - Public From 4fabe2f9b29b417657a78250c1bcd755e8c1d294 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:04:46 +0100 Subject: [PATCH 124/209] RoomDataSource: Handle RoomTimelineCellDecorator. --- .../Modules/Room/DataSources/RoomDataSource.m | 144 ++---------------- 1 file changed, 16 insertions(+), 128 deletions(-) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 19080d6d4..15b1513e1 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -321,6 +321,8 @@ const CGFloat kTypingCellHeight = 24; UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; + id cellDecorator = [RoomTimelineConfiguration shared].currentStyle.cellDecorator; + // Finalize cell view customization here if ([cell isKindOfClass:MXKRoomBubbleTableViewCell.class]) { @@ -335,7 +337,7 @@ const CGFloat kTypingCellHeight = 24; // Display timestamp of the last message if (cellData.containsLastMessage && !isCollapsableCellCollapsed) { - [bubbleCell addTimestampLabelForComponent:cellData.mostRecentComponentIndex]; + [cellDecorator addTimestampLabelToCell:bubbleCell cellData:cellData]; } NSMutableArray *temporaryViews = [NSMutableArray new]; @@ -381,27 +383,8 @@ const CGFloat kTypingCellHeight = 24; [temporaryViews addObject:urlPreviewView]; - if (!bubbleCell.tmpSubviews) - { - bubbleCell.tmpSubviews = [NSMutableArray array]; - } - [bubbleCell.tmpSubviews addObject:urlPreviewView]; - - urlPreviewView.translatesAutoresizingMaskIntoConstraints = NO; - urlPreviewView.availableWidth = cellData.maxTextViewWidth; - [bubbleCell.contentView addSubview:urlPreviewView]; - - CGFloat leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin; - if (roomBubbleCellData.containsBubbleComponentWithEncryptionBadge) - { - leftMargin+= RoomBubbleCellLayout.encryptedContentLeftMargin; - } - - // Set the preview view's origin - [NSLayoutConstraint activateConstraints: @[ - [urlPreviewView.leadingAnchor constraintEqualToAnchor:urlPreviewView.superview.leadingAnchor constant:leftMargin], - [urlPreviewView.topAnchor constraintEqualToAnchor:urlPreviewView.superview.topAnchor constant:bottomPositionY + RoomBubbleCellLayout.urlPreviewViewTopMargin + RoomBubbleCellLayout.reactionsViewTopMargin], - ]]; + [cellDecorator addURLPreviewView:urlPreviewView + toCell:bubbleCell cellData:cellData contentViewPositionY:bottomPositionY]; } MXAggregatedReactions* reactions = cellData.reactions[componentEventId].aggregatedReactionsWithNonZeroCount; @@ -424,48 +407,8 @@ const CGFloat kTypingCellHeight = 24; [temporaryViews addObject:reactionsView]; - if (!bubbleCell.tmpSubviews) - { - bubbleCell.tmpSubviews = [NSMutableArray array]; - } - [bubbleCell.tmpSubviews addObject:reactionsView]; - - if ([[bubbleCell class] conformsToProtocol:@protocol(BubbleCellReactionsDisplayable)]) - { - id reactionsDisplayable = (id)bubbleCell; - [reactionsDisplayable addReactionsView:reactionsView]; - } - else - { - reactionsView.translatesAutoresizingMaskIntoConstraints = NO; - [bubbleCell.contentView addSubview:reactionsView]; - - CGFloat leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin; - - if (roomBubbleCellData.containsBubbleComponentWithEncryptionBadge) - { - leftMargin+= RoomBubbleCellLayout.encryptedContentLeftMargin; - } - - // The top constraint may need to include the URL preview view - NSLayoutConstraint *topConstraint; - if (urlPreviewView) - { - topConstraint = [reactionsView.topAnchor constraintEqualToAnchor:urlPreviewView.bottomAnchor constant:RoomBubbleCellLayout.reactionsViewTopMargin]; - } - else - { - topConstraint = [reactionsView.topAnchor constraintEqualToAnchor:reactionsView.superview.topAnchor constant:bottomPositionY + RoomBubbleCellLayout.reactionsViewTopMargin]; - } - - // Force receipts container size - [NSLayoutConstraint activateConstraints: - @[ - [reactionsView.leadingAnchor constraintEqualToAnchor:reactionsView.superview.leadingAnchor constant:leftMargin], - [reactionsView.trailingAnchor constraintEqualToAnchor:reactionsView.superview.trailingAnchor constant:-RoomBubbleCellLayout.reactionsViewRightMargin], - topConstraint - ]]; - } + [cellDecorator addReactionView:reactionsView toCell:bubbleCell + cellData:cellData contentViewPositionY:bottomPositionY upperDecorationView:urlPreviewView]; } MXKReceiptSendersContainer* avatarsContainer; @@ -524,70 +467,13 @@ const CGFloat kTypingCellHeight = 24; [temporaryViews addObject:avatarsContainer]; - // Add this read receipts container in the content view - if (!bubbleCell.tmpSubviews) - { - bubbleCell.tmpSubviews = [NSMutableArray arrayWithArray:@[avatarsContainer]]; - } - else - { - [bubbleCell.tmpSubviews addObject:avatarsContainer]; - } + UIView *upperDecorationView = reactionsView ?: urlPreviewView; - if ([[bubbleCell class] conformsToProtocol:@protocol(BubbleCellReadReceiptsDisplayable)]) - { - id readReceiptsDisplayable = (id)bubbleCell; - - [readReceiptsDisplayable addReadReceiptsView:avatarsContainer]; - } - else - { - [bubbleCell.contentView addSubview:avatarsContainer]; - - // Force receipts container size - NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer - attribute:NSLayoutAttributeWidth - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1.0 - constant:RoomBubbleCellLayout.readReceiptsViewWidth]; - NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer - attribute:NSLayoutAttributeHeight - relatedBy:NSLayoutRelationEqual - toItem:nil - attribute:NSLayoutAttributeNotAnAttribute - multiplier:1.0 - constant:RoomBubbleCellLayout.readReceiptsViewHeight]; - - // Force receipts container position - NSLayoutConstraint *trailingConstraint = [NSLayoutConstraint constraintWithItem:avatarsContainer - attribute:NSLayoutAttributeTrailing - relatedBy:NSLayoutRelationEqual - toItem:avatarsContainer.superview - attribute:NSLayoutAttributeTrailing - multiplier:1.0 - constant:-RoomBubbleCellLayout.readReceiptsViewRightMargin]; - - // At the bottom, we either have reactions, a URL preview or nothing - NSLayoutConstraint *topConstraint; - if (reactionsView) - { - topConstraint = [avatarsContainer.topAnchor constraintEqualToAnchor:reactionsView.bottomAnchor constant:RoomBubbleCellLayout.readReceiptsViewTopMargin]; - } - else if (urlPreviewView) - { - topConstraint = [avatarsContainer.topAnchor constraintEqualToAnchor:urlPreviewView.bottomAnchor constant:RoomBubbleCellLayout.readReceiptsViewTopMargin]; - } - else - { - topConstraint = [avatarsContainer.topAnchor constraintEqualToAnchor:avatarsContainer.superview.topAnchor constant:bottomPositionY + RoomBubbleCellLayout.readReceiptsViewTopMargin]; - } - - - // Available on iOS 8 and later - [NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, topConstraint, trailingConstraint]]; - } + [cellDecorator addReadReceiptsView:avatarsContainer + toCell:bubbleCell + cellData:cellData + contentViewPositionY:bottomPositionY + upperDecorationView:upperDecorationView]; } } @@ -715,9 +601,11 @@ const CGFloat kTypingCellHeight = 24; // We are interested only by outgoing messages if ([cellData.senderId isEqualToString: self.mxSession.credentials.userId]) { - [bubbleCell updateTickViewWithFailedEventIds:self.failedEventIds]; + [cellDecorator addSendStatusViewToCell:bubbleCell + withFailedEventIds:self.failedEventIds]; } + // Make extra cell layout updates if needed [self updateCellLayoutIfNeeded:bubbleCell withCellData:cellData]; } From 43021a58843cbd68b833386eb9c60613254f6707 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:13:34 +0100 Subject: [PATCH 125/209] MXKRoomBubbleCellData: Add convenient method to check if the sender is the current user. --- .../MXKRoomBubbleCellData+Riot.swift | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 Riot/Categories/MXKRoomBubbleCellData+Riot.swift diff --git a/Riot/Categories/MXKRoomBubbleCellData+Riot.swift b/Riot/Categories/MXKRoomBubbleCellData+Riot.swift new file mode 100644 index 000000000..c3bce95c7 --- /dev/null +++ b/Riot/Categories/MXKRoomBubbleCellData+Riot.swift @@ -0,0 +1,28 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +extension MXKRoomBubbleCellData { + + /// Indicate true if the sender is the session user + var isSenderCurrentUser: Bool { + if let senderId = self.senderId, let currentUserId = self.mxSession.myUserId, senderId == currentUserId { + return true + } + return false + } +} From fa4befcf7eb046e0bae334d4c62028de880f0997 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:15:40 +0100 Subject: [PATCH 126/209] BubbleRoomCellLayoutUpdater: Update incoming text message right margin. --- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index af7360cd2..15dcf1626 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -18,12 +18,6 @@ import UIKit @objcMembers class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { - - // MARK: - Constants - - private enum Constants { - static let bubbleBackgroundViewCornerRadius: CGFloat = 12.0 - } // MARK: - Properties @@ -38,19 +32,12 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { // MARK: - Public func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { - - var isMessageSenderCurrentUser: Bool = false - if let senderId = cellData.senderId, let currentUserId = cellData.mxSession.myUserId, senderId == currentUserId { - isMessageSenderCurrentUser = true - } - - if isMessageSenderCurrentUser { + if cellData.isSenderCurrentUser { self.updateLayout(forOutgoingTextMessageCell: cell, andCellData: cellData) } else { self.updateLayout(forIncomingTextMessageCell: cell, andCellData: cellData) } - } func updateLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { @@ -232,7 +219,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { let messageViewMarginTop: CGFloat let messageViewMarginBottom: CGFloat = -2.0 let messageViewMarginLeft: CGFloat = 3.0 - let messageViewMarginRight: CGFloat = 0.0 + let messageViewMarginRight: CGFloat = 80 if bubbleCell.userNameLabel != nil { messageViewMarginTop = 10.0 From e4786f77408982def1cf51ab1c55bc7b29162652 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:22:58 +0100 Subject: [PATCH 127/209] BubbleRoomTimelineCellDecorator: Handle reactions view for incoming and outgoing messages. --- .../BubbleRoomTimelineCellDecorator.swift | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 37c51ceae..06439f0c2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -18,4 +18,74 @@ import UIKit class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { + override func addReactionView(_ reactionsView: BubbleReactionsView, + toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData, contentViewPositionY: CGFloat, upperDecorationView: UIView?) { + + cell.addTmpSubview(reactionsView) + + if let reactionsDisplayable = cell as? BubbleCellReactionsDisplayable { + reactionsDisplayable.addReactionsView(reactionsView) + return + } + + reactionsView.translatesAutoresizingMaskIntoConstraints = false + + let cellContentView = cell.contentView + + cellContentView.addSubview(reactionsView) + + // TODO: Use constants + let topMargin: CGFloat = 4.0 + let leftMargin: CGFloat + let rightMargin: CGFloat + + // Outgoing message + if cellData.isSenderCurrentUser { + reactionsView.alignment = .right + + // TODO: Use constants + var outgointLeftMargin = 80.0 + + if cellData.containsBubbleComponentWithEncryptionBadge { + outgointLeftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin + } + + leftMargin = outgointLeftMargin + + // TODO: Use constants + rightMargin = 33 + } else { + // Incoming message + + var incomingLeftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin + + if cellData.containsBubbleComponentWithEncryptionBadge { + incomingLeftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin + } + + leftMargin = incomingLeftMargin - 6.0 + + // TODO: Use constants + let messageViewMarginRight: CGFloat = 42.0 + + rightMargin = messageViewMarginRight + } + + let leadingConstraint = reactionsView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin) + + let trailingConstraint = reactionsView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin) + + let topConstraint: NSLayoutConstraint + if let upperDecorationView = upperDecorationView { + topConstraint = reactionsView.topAnchor.constraint(equalTo: upperDecorationView.bottomAnchor, constant: topMargin) + } else { + topConstraint = reactionsView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: contentViewPositionY + topMargin) + } + + NSLayoutConstraint.activate([ + leadingConstraint, + trailingConstraint, + topConstraint + ]) + } } From 4aeba18ce5ba8e896d012722bcc94746c850c334 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 15:25:14 +0100 Subject: [PATCH 128/209] BubbleRoomTimelineCellDecorator: Handle URL preview. --- .../BubbleRoomTimelineCellDecorator.swift | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 06439f0c2..c567e1bc1 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -88,4 +88,48 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { topConstraint ]) } + + override func addURLPreviewView(_ urlPreviewView: URLPreviewView, + toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData, + contentViewPositionY: CGFloat) { + + cell.addTmpSubview(urlPreviewView) + + let cellContentView = cell.contentView + + urlPreviewView.translatesAutoresizingMaskIntoConstraints = false + urlPreviewView.availableWidth = cellData.maxTextViewWidth + cellContentView.addSubview(urlPreviewView) + + let leadingOrTrailingConstraint: NSLayoutConstraint + + // Outgoing message + if cellData.isSenderCurrentUser { + + // TODO: Use constants + let rightMargin = 34.0 + + leadingOrTrailingConstraint = urlPreviewView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin) + } else { + // Incoming message + + var leftMargin = RoomBubbleCellLayout.reactionsViewLeftMargin + if cellData.containsBubbleComponentWithEncryptionBadge { + leftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin + } + + leftMargin-=5.0 + + leadingOrTrailingConstraint = urlPreviewView.leadingAnchor.constraint(equalTo: cellContentView.leadingAnchor, constant: leftMargin) + } + + let topMargin = contentViewPositionY + RoomBubbleCellLayout.urlPreviewViewTopMargin + RoomBubbleCellLayout.reactionsViewTopMargin + + // Set the preview view's origin + NSLayoutConstraint.activate([ + leadingOrTrailingConstraint, + urlPreviewView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: topMargin) + ]) + } } From 98915571ff09e79a9cf24a165365c2bcd73f2630 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:22:13 +0100 Subject: [PATCH 129/209] MXKRoomBubbleTableViewCell: Add convenient method to retrieve RoomMessageBubbleBackgroundView. --- ...KRoomBubbleTableViewCell+BubbleStyle.swift | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/MXKRoomBubbleTableViewCell+BubbleStyle.swift diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/MXKRoomBubbleTableViewCell+BubbleStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/MXKRoomBubbleTableViewCell+BubbleStyle.swift new file mode 100644 index 000000000..a0fd3f527 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/MXKRoomBubbleTableViewCell+BubbleStyle.swift @@ -0,0 +1,30 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +extension MXKRoomBubbleTableViewCell { + + // Enables to get existing bubble background view + // This used while there is no dedicated cell classes for bubble style + var messageBubbleBackgroundView: RoomMessageBubbleBackgroundView? { + + let foundView = self.contentView.subviews.first { view in + return view is RoomMessageBubbleBackgroundView + } + return foundView as? RoomMessageBubbleBackgroundView + } +} From 5db667e5678fb135bad326ce834d9bb5ddfc20ae Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:25:32 +0100 Subject: [PATCH 130/209] BubbleRoomCellLayoutUpdater: Add extra right space for timestamp. --- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 15dcf1626..a93f91124 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -42,7 +42,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { func updateLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { - if let messageBubbleBackgroundView = self.getMessageBubbleBackgroundView(from: cell) { + if let messageBubbleBackgroundView = cell.messageBubbleBackgroundView { if self.canUseBubbleBackground(forCell: cell, withCellData: cellData) { @@ -57,7 +57,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { func updateLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) { - if let messageBubbleBackgroundView = self.getMessageBubbleBackgroundView(from: cell) { + if let messageBubbleBackgroundView = cell.messageBubbleBackgroundView { if self.canUseBubbleBackground(forCell: cell, withCellData: cellData) { @@ -103,15 +103,6 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { return bubbleBackgroundView } - func getMessageBubbleBackgroundView(from cell: MXKRoomBubbleTableViewCell) -> RoomMessageBubbleBackgroundView? { - - let foundView = cell.contentView.subviews.first { view in - return view is RoomMessageBubbleBackgroundView - } - - return foundView as? RoomMessageBubbleBackgroundView - } - private func addBubbleBackgroundViewToCell(_ bubbleCell: MXKRoomBubbleTableViewCell, backgroundColor: UIColor) { guard let messageTextView = bubbleCell.messageTextView else { @@ -119,8 +110,8 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { } let topMargin: CGFloat = 0.0 - let leftMargin: CGFloat = -5.0 - let rightMargin: CGFloat = 5.0 + let leftMargin: CGFloat = 5.0 + let rightMargin: CGFloat = 45.0 // Add extra space for timestamp let bubbleBackgroundView = self.createBubbleBackgroundView(with: backgroundColor) @@ -134,7 +125,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { NSLayoutConstraint.activate([ bubbleBackgroundView.topAnchor.constraint(equalTo: topAnchor, constant: topMargin), - bubbleBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: leftMargin), + bubbleBackgroundView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: -leftMargin), bubbleBackgroundView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: rightMargin) ]) } @@ -257,7 +248,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { let contentView = cell.contentView let leftMargin: CGFloat = 80.0 - let rightMargin: CGFloat = 38.0 + let rightMargin: CGFloat = 78.0 let bottomMargin: CGFloat = -2.0 cell.msgTextViewLeadingConstraint.isActive = false From 7f55799f6d4304e47d6cca37ff13d10b49d80787 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:46:49 +0100 Subject: [PATCH 131/209] RoomTimelineCellDecorator: Update add timestamp interface. --- .../BubbleCells/Styles/RoomTimelineCellDecorator.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift index ac4bae16c..4e8a09e31 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift @@ -19,9 +19,9 @@ import UIKit /// RoomTimelineCellDecorator enables to add decoration on a cell (reactions, read receipts, timestamp, URL preview). @objc protocol RoomTimelineCellDecorator { - - func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, - cellData: RoomBubbleCellData) + + func addTimestampLabelIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, + cellData: RoomBubbleCellData) func addURLPreviewView(_ urlPreviewView: URLPreviewView, toCell cell: MXKRoomBubbleTableViewCell, From ec13863c0490244d600e5448825b92e8bb0add68 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:47:22 +0100 Subject: [PATCH 132/209] MXKRoomBubbleCellData: Add convenient method. --- Riot/Categories/MXKRoomBubbleCellData+Riot.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Riot/Categories/MXKRoomBubbleCellData+Riot.swift b/Riot/Categories/MXKRoomBubbleCellData+Riot.swift index c3bce95c7..b7e7eaa9c 100644 --- a/Riot/Categories/MXKRoomBubbleCellData+Riot.swift +++ b/Riot/Categories/MXKRoomBubbleCellData+Riot.swift @@ -25,4 +25,9 @@ extension MXKRoomBubbleCellData { } return false } + + // Indicate true if the cell data is collapsable and collapsed + var isCollapsableAndCollapsed: Bool { + return self.collapsable && self.collapsed + } } From a0b51cae7ab4f6a419516700efeac9a7431cc5c2 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:49:47 +0100 Subject: [PATCH 133/209] PlainRoomTimelineCellDecorator: Update timestamp management. --- .../Plain/PlainRoomTimelineCellDecorator.swift | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift index 5706e4e9e..95cbc04a8 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift @@ -18,9 +18,19 @@ import UIKit @objcMembers class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { + + func addTimestampLabelIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + + guard cellData.containsLastMessage && cellData.isCollapsableAndCollapsed == false else { + return + } + + // Display timestamp of the last message + self.addTimestampLabel(toCell: cell, cellData: cellData) + } - func addTimestampLabel(toCell bubbleCell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { - bubbleCell.addTimestampLabel(forComponent: UInt(cellData.mostRecentComponentIndex)) + func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + cell.addTimestampLabel(forComponent: UInt(cellData.mostRecentComponentIndex)) } func addURLPreviewView(_ urlPreviewView: URLPreviewView, From e1f5e00cdef8cecd39247d1b8be545a7d09b9320 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:51:41 +0100 Subject: [PATCH 134/209] BubbleRoomTimelineCellDecorator: Show timestamp on every text messages in bubble background. --- .../BubbleRoomTimelineCellDecorator.swift | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index c567e1bc1..7e89cafe1 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -17,6 +17,54 @@ import UIKit class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { + + override func addTimestampLabelIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + + guard self.canShowTimestamp(forCellData: cellData) else { + return + } + + self.addTimestampLabel(toCell: cell, cellData: cellData) + } + + override func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + + // If cell contains a bubble background, add the timestamp inside of it + if let bubbleBackgroundView = cell.messageBubbleBackgroundView, bubbleBackgroundView.isHidden == false { + + let componentIndex = cellData.mostRecentComponentIndex + + guard let bubbleComponents = cellData.bubbleComponents, + componentIndex < bubbleComponents.count else { + return + } + + let component = bubbleComponents[componentIndex] + + let timestampLabel = self.createTimestampLabel(cellData: cellData, + bubbleComponent: component, + viewTag: componentIndex) + timestampLabel.translatesAutoresizingMaskIntoConstraints = false + + cell.addTmpSubview(timestampLabel) + + bubbleBackgroundView.addSubview(timestampLabel) + + let rightMargin: CGFloat = 8.0 + let bottomMargin: CGFloat = 4.0 + + let trailingConstraint = timestampLabel.trailingAnchor.constraint(equalTo: bubbleBackgroundView.trailingAnchor, constant: -rightMargin) + + let bottomConstraint = timestampLabel.bottomAnchor.constraint(equalTo: bubbleBackgroundView.bottomAnchor, constant: -bottomMargin) + + NSLayoutConstraint.activate([ + trailingConstraint, + bottomConstraint + ]) + } else { + super.addTimestampLabel(toCell: cell, cellData: cellData) + } + } override func addReactionView(_ reactionsView: BubbleReactionsView, toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData, contentViewPositionY: CGFloat, upperDecorationView: UIView?) { @@ -132,4 +180,51 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { urlPreviewView.topAnchor.constraint(equalTo: cellContentView.topAnchor, constant: topMargin) ]) } + + // MARK: - Private + + private func createTimestampLabel(cellData: MXKRoomBubbleCellData, bubbleComponent: MXKRoomBubbleComponent, viewTag: Int) -> UILabel { + + let timeLabel = UILabel() + + timeLabel.text = cellData.eventFormatter.timeString(from: bubbleComponent.date) + timeLabel.textAlignment = .right + timeLabel.textColor = ThemeService.shared().theme.textSecondaryColor + timeLabel.font = UIFont.systemFont(ofSize: 11, weight: .light) + timeLabel.adjustsFontSizeToFitWidth = true + timeLabel.tag = viewTag + timeLabel.accessibilityIdentifier = "timestampLabel" + + return timeLabel + } + + private func canShowTimestamp(forCellData cellData: MXKRoomBubbleCellData) -> Bool { + + guard cellData.isCollapsableAndCollapsed == false else { + return false + } + + guard let firstComponent = cellData.getFirstBubbleComponentWithDisplay(), let firstEvent = firstComponent.event else { + return false + } + + switch firstEvent.eventType { + case .roomMessage: + if let messageTypeString = firstEvent.content["msgtype"] as? String { + + let messageType = MXMessageType(identifier: messageTypeString) + + switch messageType { + case .text: + return true + default: + break + } + } + default: + break + } + + return false + } } From 9be828028c59ef60f8818455fa626c23c47f562d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 17:52:32 +0100 Subject: [PATCH 135/209] RoomDataSource: Update timestamp decoration. --- Riot/Modules/Room/DataSources/RoomDataSource.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 15b1513e1..3c68b8e13 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -334,11 +334,8 @@ const CGFloat kTypingCellHeight = 24; BOOL isCollapsableCellCollapsed = cellData.collapsable && cellData.collapsed; - // Display timestamp of the last message - if (cellData.containsLastMessage && !isCollapsableCellCollapsed) - { - [cellDecorator addTimestampLabelToCell:bubbleCell cellData:cellData]; - } + // Display timestamp of the message if needed + [cellDecorator addTimestampLabelIfNeededToCell:bubbleCell cellData:cellData]; NSMutableArray *temporaryViews = [NSMutableArray new]; From 7d5ff31361164c800415af181f38fcd85bf239bd Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 18:25:48 +0100 Subject: [PATCH 136/209] BubbleRoomTimelineCellDecorator: Fix CGFloat type issues. --- .../Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 1 - .../Styles/Bubble/BubbleRoomTimelineCellDecorator.swift | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index a93f91124..3fc2bf8fa 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -164,7 +164,6 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { return nil } - let bubbleHeight: CGFloat let bottomMargin: CGFloat = 4.0 diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 7e89cafe1..8451fe650 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -92,7 +92,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { reactionsView.alignment = .right // TODO: Use constants - var outgointLeftMargin = 80.0 + var outgointLeftMargin: CGFloat = 80.0 if cellData.containsBubbleComponentWithEncryptionBadge { outgointLeftMargin += RoomBubbleCellLayout.encryptedContentLeftMargin @@ -156,7 +156,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { if cellData.isSenderCurrentUser { // TODO: Use constants - let rightMargin = 34.0 + let rightMargin: CGFloat = 34.0 leadingOrTrailingConstraint = urlPreviewView.trailingAnchor.constraint(equalTo: cellContentView.trailingAnchor, constant: -rightMargin) } else { From 67e7db38c2a313d558fafc8a2b35adf7457f1a04 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jan 2022 08:44:53 +0200 Subject: [PATCH 137/209] vector-im/element-ios/issues/5114 - Allow editing poll start events. --- Riot/Assets/en.lproj/Vector.strings | 4 + Riot/Generated/Strings.swift | 8 ++ .../Utils/EventFormatter/MXKEventFormatter.m | 5 ++ .../Room/CellData/RoomBubbleCellData.m | 4 + Riot/Modules/Room/RoomCoordinator.swift | 56 +++++++++----- Riot/Modules/Room/RoomViewController.h | 6 ++ Riot/Modules/Room/RoomViewController.m | 36 ++++++--- .../LocationSharingModels.swift | 4 +- .../LocationSharingViewModel.swift | 40 +++++----- .../Coordinator/PollEditFormCoordinator.swift | 75 +++++++++++++++---- .../PollEditForm/PollEditFormModels.swift | 32 +++++++- .../PollEditFormScreenState.swift | 3 +- .../PollEditForm/PollEditFormViewModel.swift | 53 ++++++++----- .../Room/PollEditForm/View/PollEditForm.swift | 25 +++++-- .../Coordinator/PollTimelineCoordinator.swift | 6 +- 15 files changed, 264 insertions(+), 93 deletions(-) diff --git a/Riot/Assets/en.lproj/Vector.strings b/Riot/Assets/en.lproj/Vector.strings index 899f88db0..498591a72 100644 --- a/Riot/Assets/en.lproj/Vector.strings +++ b/Riot/Assets/en.lproj/Vector.strings @@ -1836,6 +1836,10 @@ Tap the + to start adding people."; "poll_edit_form_post_failure_subtitle" = "Please try again"; +"poll_edit_form_update_failure_title" = "Failed to update poll"; + +"poll_edit_form_update_failure_subtitle" = "Please try again"; + "poll_timeline_one_vote" = "1 vote"; "poll_timeline_votes_count" = "%lu votes"; diff --git a/Riot/Generated/Strings.swift b/Riot/Generated/Strings.swift index 96d4f6299..f6f0d6a19 100644 --- a/Riot/Generated/Strings.swift +++ b/Riot/Generated/Strings.swift @@ -2548,6 +2548,14 @@ public class VectorL10n: NSObject { return VectorL10n.tr("Vector", "poll_edit_form_question_or_topic") } /// Please try again + public static var pollEditFormUpdateFailureSubtitle: String { + return VectorL10n.tr("Vector", "poll_edit_form_update_failure_subtitle") + } + /// Failed to update poll + public static var pollEditFormUpdateFailureTitle: String { + return VectorL10n.tr("Vector", "poll_edit_form_update_failure_title") + } + /// Please try again public static var pollTimelineNotClosedSubtitle: String { return VectorL10n.tr("Vector", "poll_timeline_not_closed_subtitle") } diff --git a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m index 46abe46ab..1533da277 100644 --- a/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m +++ b/Riot/Modules/MatrixKit/Utils/EventFormatter/MXKEventFormatter.m @@ -1577,6 +1577,11 @@ static NSString *const kHTMLATagRegexPattern = @"([^<]*)"; } case MXEventTypePollStart: { + if (event.isEditEvent) + { + return nil; + } + displayText = [MXEventContentPollStart modelFromJSON:event.content].question; break; } diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 81867be76..c90287f4d 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -279,6 +279,10 @@ NSString *const URLPreviewDidUpdateNotification = @"URLPreviewDidUpdateNotificat if (self.tag == RoomBubbleCellDataTagPoll) { + if (self.events.lastObject.isEditEvent) { + return YES; + } + return NO; } diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index fec16dd93..da10cfbcf 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -246,6 +246,29 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { navigationRouter.present(coordinator, animated: true) coordinator.start() } + + private func startEditPollCoordinator(startEvent: MXEvent? = nil) { + guard #available(iOS 14.0, *) else { + return + } + + let parameters = PollEditFormCoordinatorParameters(room: roomViewController.roomDataSource.room, pollStartEvent: startEvent) + let coordinator = PollEditFormCoordinator(parameters: parameters) + + coordinator.completion = { [weak self, weak coordinator] in + guard let self = self, let coordinator = coordinator else { + return + } + + self.navigationRouter?.dismissModule(animated: true, completion: nil) + self.remove(childCoordinator: coordinator) + } + + add(childCoordinator: coordinator) + + navigationRouter?.present(coordinator, animated: true) + coordinator.start() + } } // MARK: - RoomIdentifiable @@ -305,26 +328,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { } func roomViewControllerDidRequestPollCreationFormPresentation(_ roomViewController: RoomViewController) { - guard #available(iOS 14.0, *) else { - return - } - - let parameters = PollEditFormCoordinatorParameters(room: roomViewController.roomDataSource.room) - let coordinator = PollEditFormCoordinator(parameters: parameters) - - coordinator.completion = { [weak self, weak coordinator] in - guard let self = self, let coordinator = coordinator else { - return - } - - self.navigationRouter?.dismissModule(animated: true, completion: nil) - self.remove(childCoordinator: coordinator) - } - - add(childCoordinator: coordinator) - - navigationRouter?.present(coordinator, animated: true) - coordinator.start() + startEditPollCoordinator() } func roomViewControllerDidRequestLocationSharingFormPresentation(_ roomViewController: RoomViewController) { @@ -350,4 +354,16 @@ extension RoomCoordinator: RoomViewControllerDelegate { PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.endPoll() } + + func roomViewController(_ roomViewController: RoomViewController, canEditPollWithEventIdentifier eventIdentifier: String) -> Bool { + guard #available(iOS 14.0, *) else { + return false + } + + return PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.canEditPoll() ?? false + } + + func roomViewController(_ roomViewController: RoomViewController, didRequestEditForPollWithStart startEvent: MXEvent) { + startEditPollCoordinator(startEvent: startEvent) + } } diff --git a/Riot/Modules/Room/RoomViewController.h b/Riot/Modules/Room/RoomViewController.h index f3b9f6fa6..6e30853af 100644 --- a/Riot/Modules/Room/RoomViewController.h +++ b/Riot/Modules/Room/RoomViewController.h @@ -207,6 +207,12 @@ canEndPollWithEventIdentifier:(NSString *)eventIdentifier; - (void)roomViewController:(RoomViewController *)roomViewController endPollWithEventIdentifier:(NSString *)eventIdentifier; +- (BOOL)roomViewController:(RoomViewController *)roomViewController +canEditPollWithEventIdentifier:(NSString *)eventIdentifier; + +- (void)roomViewController:(RoomViewController *)roomViewController +didRequestEditForPollWithStartEvent:(MXEvent *)startEvent; + @end NS_ASSUME_NONNULL_END diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 10af1f3bc..059c01be8 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -6103,16 +6103,34 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; MXWeakify(self); RoomContextualMenuItem *editMenuItem = [[RoomContextualMenuItem alloc] initWithMenuAction:RoomContextualMenuActionEdit]; - editMenuItem.action = ^{ - MXStrongifyAndReturnIfNil(self); - [self hideContextualMenuAnimated:YES cancelEventSelection:NO completion:nil]; - [self editEventContentWithId:event.eventId]; - - // And display the keyboard - [self.inputToolbarView becomeFirstResponder]; - }; - editMenuItem.isEnabled = [self.roomDataSource canEditEventWithId:event.eventId]; + switch (event.eventType) { + case MXEventTypePollStart: { + editMenuItem.action = ^{ + MXStrongifyAndReturnIfNil(self); + [self hideContextualMenuAnimated:YES cancelEventSelection:YES completion:nil]; + [self.delegate roomViewController:self didRequestEditForPollWithStartEvent:event]; + }; + + editMenuItem.isEnabled = [self.delegate roomViewController:self canEditPollWithEventIdentifier:event.eventId]; + + break; + } + default: { + editMenuItem.action = ^{ + MXStrongifyAndReturnIfNil(self); + [self hideContextualMenuAnimated:YES cancelEventSelection:NO completion:nil]; + [self editEventContentWithId:event.eventId]; + + // And display the keyboard + [self.inputToolbarView becomeFirstResponder]; + }; + + editMenuItem.isEnabled = [self.roomDataSource canEditEventWithId:event.eventId]; + + break; + } + } return editMenuItem; } diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift index be9c188f9..88b0ee9cb 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingModels.swift @@ -66,11 +66,11 @@ struct LocationSharingViewState: BindableState { } struct LocationSharingViewStateBindings { - var alertInfo: ErrorAlertInfo? + var alertInfo: LocationSharingErrorAlertInfo? var userLocation: CLLocationCoordinate2D? } -struct ErrorAlertInfo: Identifiable { +struct LocationSharingErrorAlertInfo: Identifiable { enum AlertType { case mapLoadingError case userLocatingError diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift index 765c0b558..40b750f85 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingViewModel.swift @@ -72,24 +72,24 @@ class LocationSharingViewModel: LocationSharingViewModelType { switch error { case .failedLoadingMap: - state.bindings.alertInfo = ErrorAlertInfo(id: .mapLoadingError, - title: VectorL10n.locationSharingLoadingMapErrorTitle(AppInfo.current.displayName) , - primaryButton: (VectorL10n.ok, { completion?(.cancel) }), - secondaryButton: nil) + state.bindings.alertInfo = LocationSharingErrorAlertInfo(id: .mapLoadingError, + title: VectorL10n.locationSharingLoadingMapErrorTitle(AppInfo.current.displayName) , + primaryButton: (VectorL10n.ok, { completion?(.cancel) }), + secondaryButton: nil) case .failedLocatingUser: - state.bindings.alertInfo = ErrorAlertInfo(id: .userLocatingError, - title: VectorL10n.locationSharingLocatingUserErrorTitle(AppInfo.current.displayName), - primaryButton: (VectorL10n.ok, { completion?(.cancel) }), - secondaryButton: nil) + state.bindings.alertInfo = LocationSharingErrorAlertInfo(id: .userLocatingError, + title: VectorL10n.locationSharingLocatingUserErrorTitle(AppInfo.current.displayName), + primaryButton: (VectorL10n.ok, { completion?(.cancel) }), + secondaryButton: nil) case .invalidLocationAuthorization: - state.bindings.alertInfo = ErrorAlertInfo(id: .authorizationError, - title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName), - primaryButton: (VectorL10n.locationSharingInvalidAuthorizationNotNow, { completion?(.cancel) }), - secondaryButton: (VectorL10n.locationSharingInvalidAuthorizationSettings, { - if let applicationSettingsURL = URL(string:UIApplication.openSettingsURLString) { - UIApplication.shared.open(applicationSettingsURL) - } - })) + state.bindings.alertInfo = LocationSharingErrorAlertInfo(id: .authorizationError, + title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName), + primaryButton: (VectorL10n.locationSharingInvalidAuthorizationNotNow, { completion?(.cancel) }), + secondaryButton: (VectorL10n.locationSharingInvalidAuthorizationSettings, { + if let applicationSettingsURL = URL(string:UIApplication.openSettingsURLString) { + UIApplication.shared.open(applicationSettingsURL) + } + })) default: break } @@ -100,10 +100,10 @@ class LocationSharingViewModel: LocationSharingViewModelType { state.showLoadingIndicator = false if error != nil { - state.bindings.alertInfo = ErrorAlertInfo(id: .locationSharingError, - title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName), - primaryButton: (VectorL10n.ok, nil), - secondaryButton: nil) + state.bindings.alertInfo = LocationSharingErrorAlertInfo(id: .locationSharingError, + title: VectorL10n.locationSharingInvalidAuthorizationErrorTitle(AppInfo.current.displayName), + primaryButton: (VectorL10n.ok, nil), + secondaryButton: nil) } } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift index ee0f60a78..45527fb1a 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift @@ -22,6 +22,7 @@ import SwiftUI struct PollEditFormCoordinatorParameters { let room: MXRoom + let pollStartEvent: MXEvent? } final class PollEditFormCoordinator: Coordinator, Presentable { @@ -51,9 +52,21 @@ final class PollEditFormCoordinator: Coordinator, Presentable { init(parameters: PollEditFormCoordinatorParameters) { self.parameters = parameters - let viewModel = PollEditFormViewModel() - let view = PollEditForm(viewModel: viewModel.context) + var viewModel: PollEditFormViewModel + if let startEvent = parameters.pollStartEvent, + let pollContent = MXEventContentPollStart(fromJSON: startEvent.content) { + viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .editing, + pollDetails: PollDetails(question: pollContent.question, + answerOptions: pollContent.answerOptions.map { $0.text }))) + } else { + viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, + pollDetails: PollDetails(question: "", + answerOptions: ["", ""]))) + } + + let view = PollEditForm(viewModel: viewModel.context) + _pollEditFormViewModel = viewModel pollEditFormHostingController = VectorHostingController(rootView: view) } @@ -70,16 +83,9 @@ final class PollEditFormCoordinator: Coordinator, Presentable { switch result { case .cancel: self.completion?() - case .create(let question, let answerOptions): - var options = [MXEventContentPollStartAnswerOption]() - for answerOption in answerOptions { - options.append(MXEventContentPollStartAnswerOption(uuid: UUID().uuidString, text: answerOption)) - } + case .create(let details): - let pollStartContent = MXEventContentPollStart(question: question, - kind: kMXMessageContentKeyExtensiblePollKindDisclosed, - maxSelections: 1, - answerOptions: options) + let pollStartContent = self.buildPollContentWithDetails(details) self.pollEditFormViewModel.dispatch(action: .startLoading) @@ -92,15 +98,58 @@ final class PollEditFormCoordinator: Coordinator, Presentable { guard let self = self else { return } MXLog.error("Failed creating poll with error: \(String(describing: error))") - self.pollEditFormViewModel.dispatch(action: .stopLoading(error)) + self.pollEditFormViewModel.dispatch(action: .stopLoading(.failedCreatingPoll)) } + + case .update(let details): + guard let pollStartEvent = self.parameters.pollStartEvent else { + fatalError() + } + + self.pollEditFormViewModel.dispatch(action: .startLoading) + + guard let oldPollContent = MXEventContentPollStart(fromJSON: pollStartEvent.content) else { + self.pollEditFormViewModel.dispatch(action: .stopLoading(.failedUpdatingPoll)) + return + } + + let newPollContent = self.buildPollContentWithDetails(details) + + self.parameters.room.sendPollUpdate(for: pollStartEvent, + oldContent: oldPollContent, + newContent: newPollContent, localEcho: nil) { [weak self] result in + guard let self = self else { return } + + self.pollEditFormViewModel.dispatch(action: .stopLoading(nil)) + self.completion?() + } failure: { [weak self] error in + guard let self = self else { return } + + MXLog.error("Failed updating poll with error: \(String(describing: error))") + self.pollEditFormViewModel.dispatch(action: .stopLoading(.failedUpdatingPoll)) + } } } } - // MARK: - Private + // MARK: - Presentable func toPresentable() -> UIViewController { return pollEditFormHostingController } + + // MARK: - Private + + private func buildPollContentWithDetails(_ details: PollDetails) -> MXEventContentPollStart { + var options = [MXEventContentPollStartAnswerOption]() + for answerOption in details.answerOptions { + options.append(MXEventContentPollStartAnswerOption(uuid: UUID().uuidString, text: answerOption)) + } + + return MXEventContentPollStart(question: details.question, + kind: (details.disclosed ? kMXMessageContentKeyExtensiblePollKindDisclosed : kMXMessageContentKeyExtensiblePollKindUndisclosed) , + maxSelections: NSNumber(value: details.maxSelections), + answerOptions: options) + + } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift index 9c7d856c8..86835ff74 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift @@ -19,10 +19,22 @@ import Foundation import SwiftUI +struct PollDetails { + let question: String + let answerOptions: [String] + let maxSelections: UInt = 1 + let disclosed: Bool = true +} + +enum PollEditFormMode { + case creation + case editing +} + enum PollEditFormStateAction { case viewAction(PollEditFormViewAction) case startLoading - case stopLoading(Error?) + case stopLoading(PollEditFormErrorAlertInfo.AlertType?) } enum PollEditFormViewAction { @@ -30,11 +42,13 @@ enum PollEditFormViewAction { case deleteAnswerOption(PollEditFormAnswerOption) case cancel case create + case update } enum PollEditFormViewModelResult { case cancel - case create(String, [String]) + case create(PollDetails) + case update(PollDetails) } struct PollEditFormQuestion { @@ -61,6 +75,7 @@ struct PollEditFormAnswerOption: Identifiable, Equatable { struct PollEditFormViewState: BindableState { var maxAnswerOptionsCount: Int + var mode: PollEditFormMode var bindings: PollEditFormViewStateBindings var confirmationButtonEnabled: Bool { @@ -79,5 +94,16 @@ struct PollEditFormViewStateBindings { var question: PollEditFormQuestion var answerOptions: [PollEditFormAnswerOption] - var showsFailureAlert: Bool = false + var alertInfo: PollEditFormErrorAlertInfo? +} + +struct PollEditFormErrorAlertInfo: Identifiable { + enum AlertType { + case failedCreatingPoll + case failedUpdatingPoll + } + + let id: AlertType + let title: String + let subtitle: String } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift index 2e545a9d4..5cd584854 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift @@ -28,7 +28,8 @@ enum MockPollEditFormScreenState: MockScreenState, CaseIterable { } var screenView: ([Any], AnyView) { - let viewModel = PollEditFormViewModel() + let viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .editing, + pollDetails: PollDetails(question: "", answerOptions: ["", ""]))) return ([viewModel], AnyView(PollEditForm(viewModel: viewModel.context))) } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index f38ac9fc9..183aef356 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -19,6 +19,11 @@ import SwiftUI import Combine +struct PollEditFormViewModelParameters { + let mode: PollEditFormMode + let pollDetails: PollDetails +} + @available(iOS 14, *) typealias PollEditFormViewModelType = StateStoreViewModel< PollEditFormViewState, PollEditFormStateAction, @@ -42,20 +47,17 @@ class PollEditFormViewModel: PollEditFormViewModelType { // MARK: - Setup - init() { - super.init(initialViewState: Self.defaultState()) - } - - private static func defaultState() -> PollEditFormViewState { - return PollEditFormViewState( + init(parameters: PollEditFormViewModelParameters) { + let state = PollEditFormViewState( maxAnswerOptionsCount: Constants.maxAnswerOptionsCount, + mode: parameters.mode, bindings: PollEditFormViewStateBindings( - question: PollEditFormQuestion(text: "", maxLength: Constants.maxQuestionLength), - answerOptions: [PollEditFormAnswerOption(text: "", maxLength: Constants.maxAnswerOptionLength), - PollEditFormAnswerOption(text: "", maxLength: Constants.maxAnswerOptionLength) - ] + question: PollEditFormQuestion(text: parameters.pollDetails.question, maxLength: Constants.maxQuestionLength), + answerOptions: parameters.pollDetails.answerOptions.map { PollEditFormAnswerOption(text: $0, maxLength: Constants.maxAnswerOptionLength) } ) ) + + super.init(initialViewState: state) } // MARK: - Public @@ -65,11 +67,9 @@ class PollEditFormViewModel: PollEditFormViewModelType { case .cancel: completion?(.cancel) case .create: - completion?(.create(state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), - state.bindings.answerOptions.compactMap({ answerOption in - let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) - return text.isEmpty ? nil : text - }))) + completion?(.create(buildPollDetails())) + case .update: + completion?(.update(buildPollDetails())) default: dispatch(action: .viewAction(viewAction)) } @@ -92,10 +92,29 @@ class PollEditFormViewModel: PollEditFormViewModelType { case .stopLoading(let error): state.showLoadingIndicator = false - if error != nil { - state.bindings.showsFailureAlert = true + switch error { + case .failedCreatingPoll: + state.bindings.alertInfo = PollEditFormErrorAlertInfo(id: .failedCreatingPoll, + title: VectorL10n.pollEditFormPostFailureTitle, + subtitle: VectorL10n.pollEditFormPostFailureSubtitle) + case .failedUpdatingPoll: + state.bindings.alertInfo = PollEditFormErrorAlertInfo(id: .failedCreatingPoll, + title: VectorL10n.pollEditFormUpdateFailureTitle, + subtitle: VectorL10n.pollEditFormUpdateFailureSubtitle) + case .none: + break } break } } + + // MARK: - Private + + private func buildPollDetails() -> PollDetails { + return PollDetails(question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), + answerOptions: state.bindings.answerOptions.compactMap({ answerOption in + let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) + return text.isEmpty ? nil : text + })) + } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift index 57f3a63a3..be7434bd6 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift @@ -76,17 +76,19 @@ struct PollEditForm: View { Spacer() - Button(VectorL10n.pollEditFormCreatePoll) { - viewModel.send(viewAction: .create) + if viewModel.viewState.mode == .creation { + Button(VectorL10n.pollEditFormCreatePoll) { + viewModel.send(viewAction: .create) + } + .buttonStyle(PrimaryActionButtonStyle()) + .disabled(!viewModel.viewState.confirmationButtonEnabled) } - .buttonStyle(PrimaryActionButtonStyle()) - .disabled(!viewModel.viewState.confirmationButtonEnabled) } .padding() .activityIndicator(show: viewModel.viewState.showLoadingIndicator) - .alert(isPresented: $viewModel.showsFailureAlert) { - Alert(title: Text(VectorL10n.pollEditFormPostFailureTitle), - message: Text(VectorL10n.pollEditFormPostFailureSubtitle), + .alert(item: $viewModel.alertInfo) { info in + Alert(title: Text(info.title), + message: Text(info.subtitle), dismissButton: .default(Text(VectorL10n.ok))) } .frame(minHeight: proxy.size.height) // Make the VStack fill the ScrollView's parent @@ -101,6 +103,15 @@ struct PollEditForm: View { .font(.headline) .foregroundColor(theme.colors.primaryContent) } + + ToolbarItem(placement: .navigationBarTrailing) { + if viewModel.viewState.mode == .editing { + Button(VectorL10n.save, action: { + viewModel.send(viewAction: .update) + }) + .disabled(!viewModel.viewState.confirmationButtonEnabled) + } + } } .navigationBarTitleDisplayMode(.inline) } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift index 78c53acec..d7b51a8bf 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift @@ -51,7 +51,7 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel init(parameters: PollTimelineCoordinatorParameters) throws { self.parameters = parameters - try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollStartEvent: parameters.pollStartEvent) + try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollStartEventId: parameters.pollStartEvent.eventId) pollAggregator.delegate = self pollTimelineViewModel = PollTimelineViewModel(timelinePoll: buildTimelinePollFrom(pollAggregator.poll)) @@ -96,6 +96,10 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel return pollAggregator.poll.isClosed == false } + func canEditPoll() -> Bool { + return (pollAggregator.poll.isClosed == false && pollAggregator.poll.totalAnswerCount == 0) + } + func endPoll() { parameters.room.sendPollEnd(for: parameters.pollStartEvent, localEcho: nil, success: nil) { [weak self] error in self?.pollTimelineViewModel.dispatch(action: .showClosingFailure) From 85b07ba1d56e019410d85982ef4bee3f07ba1f97 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 12 Jan 2022 14:00:09 +0200 Subject: [PATCH 138/209] vector-im/element-ios/issues/5114 - Allow seeing whether a poll has been edited. --- .../Coordinator/PollTimelineCoordinator.swift | 3 ++- .../Modules/Room/PollTimeline/PollTimelineModels.swift | 8 +++++++- .../Room/PollTimeline/PollTimelineScreenState.swift | 3 ++- .../Room/PollTimeline/View/PollTimelineView.swift | 9 +++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift index d7b51a8bf..d466b4279 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift @@ -142,6 +142,7 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel closed: poll.isClosed, totalAnswerCount: poll.totalAnswerCount, type: (poll.kind == .disclosed ? .disclosed : .undisclosed), - maxAllowedSelections: poll.maxAllowedSelections) + maxAllowedSelections: poll.maxAllowedSelections, + hasBeenEdited: poll.hasBeenEdited) } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift index d01eaf864..e822aede1 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift @@ -64,14 +64,20 @@ class TimelinePoll { var totalAnswerCount: UInt var type: TimelinePollType var maxAllowedSelections: UInt + var hasBeenEdited: Bool = true - init(question: String, answerOptions: [TimelineAnswerOption], closed: Bool, totalAnswerCount: UInt, type: TimelinePollType, maxAllowedSelections: UInt) { + init(question: String, answerOptions: [TimelineAnswerOption], + closed: Bool, + totalAnswerCount: UInt, + type: TimelinePollType, + maxAllowedSelections: UInt, hasBeenEdited: Bool) { self.question = question self.answerOptions = answerOptions self.closed = closed self.totalAnswerCount = totalAnswerCount self.type = type self.maxAllowedSelections = maxAllowedSelections + self.hasBeenEdited = hasBeenEdited } var hasCurrentUserVoted: Bool { diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift index b7752acf5..28347836b 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift @@ -38,7 +38,8 @@ enum MockPollTimelineScreenState: MockScreenState, CaseIterable { closed: (self == .closed ? true : false), totalAnswerCount: 20, type: .disclosed, - maxAllowedSelections: 1) + maxAllowedSelections: 1, + hasBeenEdited: false) let viewModel = PollTimelineViewModel(timelinePoll: poll) diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift index 70efcc067..2f0bc5884 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift @@ -35,8 +35,13 @@ struct PollTimelineView: View { let poll = viewModel.viewState.poll VStack(alignment: .leading, spacing: 16.0) { + Text(poll.question) .font(theme.fonts.bodySB) + .foregroundColor(theme.colors.primaryContent) + + Text(editedText) + .font(theme.fonts.footnote) + .foregroundColor(theme.colors.secondaryContent) VStack(spacing: 24.0) { ForEach(poll.answerOptions) { answerOption in @@ -103,6 +108,10 @@ struct PollTimelineView: View { return poll.type == .disclosed && poll.totalAnswerCount > 0 && poll.hasCurrentUserVoted } } + + private var editedText: String { + viewModel.viewState.poll.hasBeenEdited ? " \(VectorL10n.eventFormatterMessageEditedMention)" : "" + } } // MARK: - Previews From e261a5310f6f20b3a97511f3e3f7693edc8ac075 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jan 2022 15:57:26 +0200 Subject: [PATCH 139/209] vector-im/element-ios/issues/5114 - Added UI for creating undisclosed polls and logic for displaying them in the timeline. --- .../Contents.json | 23 +++ .../poll_type_checkbox_default.png | Bin 0 -> 615 bytes .../poll_type_checkbox_default@2x.png | Bin 0 -> 1153 bytes .../poll_type_checkbox_default@3x.png | Bin 0 -> 1705 bytes .../Contents.json | 23 +++ .../poll_type_checkbox_selected.png | Bin 0 -> 729 bytes .../poll_type_checkbox_selected@2x.png | Bin 0 -> 1348 bytes .../poll_type_checkbox_selected@3x.png | Bin 0 -> 2072 bytes Riot/Assets/en.lproj/Vector.strings | 10 ++ Riot/Generated/Images.swift | 2 + Riot/Generated/Strings.swift | 20 +++ .../Coordinator/PollEditFormCoordinator.swift | 22 ++- .../PollEditForm/PollEditFormModels.swift | 8 +- .../PollEditFormScreenState.swift | 6 +- .../PollEditForm/PollEditFormViewModel.swift | 6 +- .../Unit/PollEditFormViewModelTests.swift | 15 +- .../Room/PollEditForm/View/PollEditForm.swift | 41 +---- .../View/PollEditFormAnswerOptionView.swift | 64 ++++++++ .../View/PollEditFormTypeView.swift | 94 ++++++++++++ .../Coordinator/PollTimelineCoordinator.swift | 9 +- .../PollTimeline/PollTimelineModels.swift | 13 +- .../PollTimelineScreenState.swift | 10 +- .../PollTimeline/PollTimelineViewModel.swift | 8 +- .../Test/UI/PollTimelineUITests.swift | 47 +++++- .../Unit/PollTimelineViewModelTests.swift | 3 +- .../View/PollTimelineAnswerOptionButton.swift | 140 ++++++++++-------- .../PollTimeline/View/PollTimelineView.swift | 36 ++--- 27 files changed, 443 insertions(+), 157 deletions(-) create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default.png create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default@2x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default@3x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/Contents.json create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected.png create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected@2x.png create mode 100644 Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected@3x.png create mode 100644 RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift create mode 100644 RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/Contents.json new file mode 100644 index 000000000..945c5c337 --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "poll_type_checkbox_default.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "poll_type_checkbox_default@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "poll_type_checkbox_default@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default.png b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default.png new file mode 100644 index 0000000000000000000000000000000000000000..84e419079478efbbd5b03ef22c5b6c750ec45e79 GIT binary patch literal 615 zcmV-t0+{`YP)p&1avqt&2U+LibR&Zl+xe`GLTtQ3+PywU@k_tix&;g`^MM6ms4<&S9I^Y}R9d9{b zK%EKcQpASQUM8d#4c-ifr*#bxy(_7b6JBTJCKQn zP0NNa2Bsa>x6ZHvx_^J7pgJyFQmx(XpuJQ;_Z|-=8;K>$aOeLB1)zI(HASAbVby>S z!ur3f?A=U>EVln}2g%R&*mhCtVjqw*Hz1Qgf} z+5>H)BoZXulr1k{!{6z&!llW9HeBr$(cioPu{07sQ~P;@+d-U$eqP{JSSiq^*JYCK<?p-hInDV`jh3@1+5=9&tATqJFAHJSOt;^8U+O9hf*1T)yaUqy)<{&lLtOv>002ovPDHLkV1lm0 B5dr`J literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default@2x.png b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_default.imageset/poll_type_checkbox_default@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7e6083bc319d633e3955789d9d89f19b8123b096 GIT binary patch literal 1153 zcmV-{1b+L8P)iLCFA}0fvWHP*_3J70|ALu!6!02rDREfddRM!(##~sJnxFbxMk* zUKs{z0X81C7NI? zV30v5#VrKt-pWE91)whizTcRcc!ez?#Fr;yvm;;(_3%$?$MY5g^oX7aD8rp8Y)g>g z1%QaudL@#ZfPZ$i!6n=8VaB^55E47y@?0%Xqg(`z&l=x4%z9HY97=&BAiTl!WZ;#{ zP4&WWG-mMouM0S{U~-*T^u zS2)8q{dJ8lX-Tav&VA0(PbLB>#y5o&d*1Rw6@9=zy{yu#Z|mh*NpvM}a^Bb`L#tY= zK!|YDTmEo^0^pxFTrPzV?Q1ab-PNV?*G_Fa5{N(ZzSbfTXpzI{-St_=N+BU2H@&6# z!?bp(1jtpod`jzZK*m3fX(!PXcl@2_+4mPu>x@r@RT#4|IO7$(#WK0laFhPF8ylTD zX>F_o)a=uAe`+tIeXuh~;~$~+m2wX4Wy*D{!_!vZN+6#7XVB8=*W2VlJXVk>EZtkr zpOhuU*4m$hK<0y`CYf z<#ot~{zw!$6sBw7W&ul7dWdaC1j*{!^SWNevIqFvorUQOuC8Z z)?|QD!5rIgr8X~=sFZdB4g;34GZFZ&U?Y%Vopu5a1D3Ik)zFmyN-C2Y5sa}}pjR;o zNO`N37`}ISa1vuvjPy&dVGs~Z*4v*Mch)c>aLS*PCDL%|<`)Q&sKg{TMz;^5sed3CU&(F zSE&aW5|oetEgO_*Swng&fhZD`(ul|X(~E(7B$W;7DhNfywX|$7{UmNVRcL#GGv~YS zpSu_k+JuB>(ArO%eT7s4aXhXIOEf^q9|Q@j3WA4huv0GHF&0vKjJ}jG0201`F>5tm z2?<@Y!LGraw>(eDv^>y?6^WnmX6p;84_y(T<#`BTEr3ZOEx`GneNV{Jk@_QCN=zvS5-$C^cn-#zGCCCHjTG#Nw3?fuu35(zZF6Btggid{gJ?F4ZG?-7)$ zJb2oZt^d3S6;O#lAC6956X>l1 zQ$~caPbr*&q6F}tAuKPCqTaU%6(1jm9JNA;cBtqHyAemb8!Y6{D2RfBd^|pJ<~JPT_w};sH6@M^t@RRp zu6mLW|b2ke%^Mu96#d*KjS`l;w=#Sd#Jj0 zGnVxxT7S3=b3lCf<&8poVHqB=wf*S39(lW%>ZaRZ5l7r=Uc?ci^#@xHcgwPU@We}? zEdK!9G!F8DOn239FlVIa*)t`kG1&^qei1zI5-7lqb#c=$j_L~Ivmh>{Dc!J*%Vrup z$Q4MGwneRM-C3)@CQ}xPq**RzKz@^t73B(~6q=(FyOtz@Fz<}BXEa*4j}1=_ncafqXvRe5Ud`>Zs^X#sWp*>$ zZv~e?3i_s(wWd>ODZCFmFb)JzTp%?qaoz-J0Ih|LmXD~cbuFtvJn0AHKnksMuW!gn zt>IO|;uge91Xn^L%<*k;Pqr2kg}m7%ae zd3%@t8ZLnn`ERdSwf91O5^R>Y^R#@aeB&;wTj>CA&tNDs`DaI<~+P}Wm)10sCq zn&nOu&pUgTk*w_mT7vWxfX%(sc;K3wdp7TAbt!bleOrj7tFAr)gFsxTKHy_&=W>y| z)kxFS*5}s>E9xwRG%2e}PZUYk{i z6>)S3-p}KLec@WMZJbEI1P{Cfk`n<(J4sliounx)o+&hq5yGCY)q9saF4{?q3$nD6 zlxc6Pi)ovnCF7TN9Ts~Qzx-7T9~N|{9k>KXgXrq8u2aVxQ$SsJ}6xek@rylo)iFCL~E zeh1P+Ijy}KSu(ej!vU#(YYel?znT}{0(a4>YHF|ULY?>Ro7&0Jks{snE~>qfDaR_5 zZYx_)bU4{alMcm&l@u0lr|NYAMmy zDa<9c3Uo>4dRq4pX>(Sq%0$t40N<&-Cfbl25$G!M2}h{EC#%xphtp#ij!YQhwZ)y} zIGAX}^^{?D`B$Rd_nl!Idb1ZSSg>Hhg8ATI6MEZVK&@sK00000NkvXXu0mjfI}#^A literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/Contents.json new file mode 100644 index 000000000..b7fbce06b --- /dev/null +++ b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "poll_type_checkbox_selected.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "poll_type_checkbox_selected@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "poll_type_checkbox_selected@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected.png b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..6a744d6bed5a4753d6cdfde938f85ea02d685d63 GIT binary patch literal 729 zcmV;~0w(>5P)>k%Ly)OFd9QChHvOJpg&f9sjGX}Wtz-^08;5kcp)Bz1`M644*&1^!rBBGGZ$*g(w zY8`V__12!EXd^tOK>#rrKPRGAQ7OkO|J-H!9e8rpVER7?w0nyj2?wL%&lGbJtQlF=O(zo*sHqFo4iMeImS{iI*C6mGNEVa=&3m3LJJvmJL*R8%Mb0?Joqu8eI zb?ewmzN-eOZ<0P*CC#96aoXWb&e@E3ptai9 zWE14%N~^$x{!g-81_>U2AA8(*$ruQwyEQl9-1dmvw0*tTA%u3)D-t{_*;WF9i~uRx zPCp#dz1hLBzitr=Hro-d_?Jnwq}!!uh>)|vNlDH8$n|z<$a{)^ahVuYI-wB^00000 LNkvXXu0mjf1<*je literal 0 HcmV?d00001 diff --git a/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected@2x.png b/Riot/Assets/Images.xcassets/Room/Polls/poll_type_checkbox_selected.imageset/poll_type_checkbox_selected@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..67c3bbd64f75d22ed14d368c2a93d7f84aecb799 GIT binary patch literal 1348 zcmV-K1-tr*P)ps1;?uYanlYXH_*o(7+6UJeh=dpVu~kwkuNw$>p+d)FZuN!-XU!~jG7;dN$3RKd9ldF}umU!JYr80bne}WWQVDE(Kha^8 zt|9iNP)Fn1`6Cp7s(0l`S@z7;Am=)N9JEf8o=qg6ms#&iL+nq)Q*D*d$H7Jd6dn!h zXZN<}FsH$P#QBslgOVt}4r-_D`6}CtO{Zm-=sAnBH0Q(oAU7H>*?9ImBIqovx7)|0 zFd2~TjbE>iLVMZ1r#M5>&cTeR0ew#RzPA?S1nQ*_K;JsnzNs)!6QT;Ad8p zdwT2zQI&GWeoQYWkkU}Xgb;?g(mn^8*^8=o8{2x}enTn4$Ei0}Lqse}rQT93q{j$IX~bT@LtCbl0M;5QJM489t;}19_$CIXN{j&A zakWyU2C-$z@joP0{+7jKQIt!v<(|`6Y0=^o}SP5zj>#YW5(k|o$5g*mht%YE` z&We^5bFc(xe|HR#Lsg>-7L4j=y0zFu$P!vHply1piQ6>7Mgo|(!3n$7taswghno%^ zn#Gw9s5w;||B&2?m@U0{OV1itN_?co?x(c=5qBF*YOy3->Tj!4`J@d+_Tj&9sZSi! zT1td#G-s;Htq$stBT<-_$ zjo8qXjx6{33M%OqSAmH?k2c!j2~->bR98u%OOr!e3q~imr2McF0gdFg_$r_YP}AnH z{_Z}{Q@JlRdaDQuYpawHCiJYA#OQTi=QVP#z#_t=LtQ-G2+O}Bv-b<-^0<@d#YoHw z6a?LLqP`6^#Y#Jrg&hjNj`5l`m}g^M@p6UP8f&bPAAbYwO>Yf)G^|Yk0000Fj2CX!EJ`2^l0 zC;^qh+MQ1KV#?Uw*_mDKu5n7=3x#H8clB-e^zR5@j4{R-V~jDrRUlN1T4%Es!uJiO z{RRQvL8OL!Oa%4o^AI5*fB=a42=qoP-Sy$3*Kck1p+ZzbkdUJFH#-Mk1$a1A!>uA!uP}n9Up|`y^n{!md|d?m3|pu7*AJlp6hhEUXM2}4 zthld0u|#dLPDB_Chr`~jTNnN77V6d?PwT$#*OdaXcK3KL|NYd`rQSio=D)4AEf^6a z5frNwO}=p3Yp{=`k2GQX?7>{Eb4RR9{lM_vL z`3iT^XJVf;?fd>o&K`cf{aj*5i_0NE&dI* zJvF#n6*+=Fn{}o9yK-;iB!1?ZlkHu|h)fbBde2J^Oyfkfe>S_G!I~A1slT>2Q&o;| z{&e#ef~k2m24VCv=09tXk8hT*=a{M)Ykk+X_Lk-uryaWUODgB-!x z?4y+wbz^UTcmR%YlAy^B`yU!#8-@efbFx~h*b>4Ia~MGb6y9TpvHsBuXGapL$LbJ( zijF;a*Uf(YUCtncugwwvqOvGfct z*3qh2RcxxW-87LS`%abzp6To?b1?gs-`-}nm`&!=;)M2J&zwASHUfiR*Ly4h$>9cn zC*IJTmP^?NhE_U+D~cMNR^;SdriYo;F?Zga`uWQ zN5DDkMx-Mr$1hEaw0^&sx;AZ)U(V4xiB~}NFm0`o zpjgKZo3p1b_Q3*C&&$oYT=1T>;j$m;$lw?8cT8JvBq)TiVHgVf4!K`(EGx<`vcL1* zDn%cBo}UG9Pf zQ4}@#PZiR01qmPKY?F{wqU1{f)3nCCNh|m<>0_;xLmH#{ss@|=hHZ}IzZ2I2W|tr| z#4w>B24I7NpP_0H-m^{dyrDsYAp0i$d9C~kPN4kYkXT`ArpoQtoNqq)|$^U*a6jtpu6YmI@ADZBxX%Hw*=)HE9x* z_(moo<*)(ME2tU<6Mh{b`1QmA%s~)=PV|^rI_h8nTR;b2sbElaY@4FA!MbYt$GFBc zkjLx1f~O`VFsyPP>U-XIUE3rw1m7t6Zv%`3X>F1Mw0g;LdI7*1@fQbdyO?k^hq-%#AO-ND#Mkn?LDQw$ zDpeI}v`W4X9oy8?8fs8v+((?HNJu)JU0dWmN#6Jf8#ngZx~|H#Tuad!rk9Q7XF{ub zj$C@y5#5yvCO9IlwMo7j@nM$IbDlQ7)ViKy>Dh@OG3%(HV;By&_;xpID&exAIMs}^ zkCI>`$?AP)ap2<=z+OR4TQ(kT?%F2VP#K`tXQ!cm0Xnx?Qr_7YD}9aW$6|vs;RvYf&{LoZ^{R String { + let mapping = [PollEditFormType.disclosed : kMXMessageContentKeyExtensiblePollKindDisclosed, + PollEditFormType.undisclosed : kMXMessageContentKeyExtensiblePollKindUndisclosed] + + return mapping[type] ?? kMXMessageContentKeyExtensiblePollKindDisclosed + } + + private static func pollKindKeyToDetailsType(_ key: String) -> PollEditFormType { + let mapping = [kMXMessageContentKeyExtensiblePollKindDisclosed : PollEditFormType.disclosed, + kMXMessageContentKeyExtensiblePollKindUndisclosed : PollEditFormType.undisclosed] + + return mapping[key] ?? PollEditFormType.disclosed + } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift index 86835ff74..927dbe6c5 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift @@ -20,10 +20,10 @@ import Foundation import SwiftUI struct PollDetails { + let type: PollEditFormType let question: String let answerOptions: [String] let maxSelections: UInt = 1 - let disclosed: Bool = true } enum PollEditFormMode { @@ -51,6 +51,11 @@ enum PollEditFormViewModelResult { case update(PollDetails) } +enum PollEditFormType { + case disclosed + case undisclosed +} + struct PollEditFormQuestion { var text: String { didSet { @@ -93,6 +98,7 @@ struct PollEditFormViewState: BindableState { struct PollEditFormViewStateBindings { var question: PollEditFormQuestion var answerOptions: [PollEditFormAnswerOption] + var type: PollEditFormType var alertInfo: PollEditFormErrorAlertInfo? } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift index 5cd584854..e6e01405c 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift @@ -28,8 +28,10 @@ enum MockPollEditFormScreenState: MockScreenState, CaseIterable { } var screenView: ([Any], AnyView) { - let viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .editing, - pollDetails: PollDetails(question: "", answerOptions: ["", ""]))) + let viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, + pollDetails: PollDetails(type: .disclosed, + question: "", + answerOptions: ["", ""]))) return ([viewModel], AnyView(PollEditForm(viewModel: viewModel.context))) } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index 183aef356..6cbb2dc8c 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -53,7 +53,8 @@ class PollEditFormViewModel: PollEditFormViewModelType { mode: parameters.mode, bindings: PollEditFormViewStateBindings( question: PollEditFormQuestion(text: parameters.pollDetails.question, maxLength: Constants.maxQuestionLength), - answerOptions: parameters.pollDetails.answerOptions.map { PollEditFormAnswerOption(text: $0, maxLength: Constants.maxAnswerOptionLength) } + answerOptions: parameters.pollDetails.answerOptions.map { PollEditFormAnswerOption(text: $0, maxLength: Constants.maxAnswerOptionLength) }, + type: parameters.pollDetails.type ) ) @@ -111,7 +112,8 @@ class PollEditFormViewModel: PollEditFormViewModelType { // MARK: - Private private func buildPollDetails() -> PollDetails { - return PollDetails(question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), + return PollDetails(type: state.bindings.type, + question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), answerOptions: state.bindings.answerOptions.compactMap({ answerOption in let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) return text.isEmpty ? nil : text diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift index 739361197..48f035c5d 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift @@ -28,10 +28,11 @@ class PollEditFormViewModelTests: XCTestCase { var cancellables = Set() override func setUpWithError() throws { - viewModel = PollEditFormViewModel() + viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, + pollDetails: PollDetails(question: "", answerOptions: ["", ""]))) context = viewModel.context } - + func testInitialState() { XCTAssertTrue(context.question.text.isEmpty) XCTAssertFalse(context.viewState.confirmationButtonEnabled) @@ -100,14 +101,14 @@ class PollEditFormViewModelTests: XCTestCase { let thirdAnswer = " " viewModel.completion = { result in - if case PollEditFormViewModelResult.create(let resultQuestion, let resultAnswerOptions) = result { - XCTAssertEqual(question.trimmingCharacters(in: .whitespacesAndNewlines), resultQuestion) + if case PollEditFormViewModelResult.create(let result) = result { + XCTAssertEqual(question.trimmingCharacters(in: .whitespacesAndNewlines), result.question) // The last answer option should be automatically dropped as it's empty - XCTAssertEqual(resultAnswerOptions.count, 2) + XCTAssertEqual(result.answerOptions.count, 2) - XCTAssertEqual(resultAnswerOptions[0], firstAnswer.trimmingCharacters(in: .whitespacesAndNewlines)) - XCTAssertEqual(resultAnswerOptions[1], secondAnswer.trimmingCharacters(in: .whitespacesAndNewlines)) + XCTAssertEqual(result.answerOptions[0], firstAnswer.trimmingCharacters(in: .whitespacesAndNewlines)) + XCTAssertEqual(result.answerOptions[1], secondAnswer.trimmingCharacters(in: .whitespacesAndNewlines)) } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift index be7434bd6..c5a327ba7 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift @@ -37,6 +37,8 @@ struct PollEditForm: View { ScrollView { VStack(alignment: .leading, spacing: 32.0) { + PollEditFormTypeView(selectedType: $viewModel.type) + VStack(alignment: .leading, spacing: 16.0) { Text(VectorL10n.pollEditFormPollQuestionOrTopic) .font(theme.fonts.title3SB) @@ -58,7 +60,7 @@ struct PollEditForm: View { ForEach(0.. Void - - var body: some View { - VStack(alignment: .leading, spacing: 8.0) { - Text(VectorL10n.pollEditFormOptionNumber(index + 1)) - .font(theme.fonts.subheadline) - .foregroundColor(theme.colors.primaryContent) - - HStack(spacing: 16.0) { - TextField(VectorL10n.pollEditFormInputPlaceholder, text: $text, onEditingChanged: { edit in - self.focused = edit - }) - .textFieldStyle(BorderedInputFieldStyle(theme: _theme, isEditing: focused)) - Button { - onDelete() - } label: { - Image(uiImage:Asset.Images.pollDeleteOptionIcon.image) - } - .accessibilityIdentifier("Delete answer option") - } - } - } -} - // MARK: - Previews @available(iOS 14.0, *) diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift new file mode 100644 index 000000000..819c851dc --- /dev/null +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift @@ -0,0 +1,64 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +@available(iOS 14.0, *) +struct PollEditFormAnswerOptionView: View { + + @Environment(\.theme) private var theme: ThemeSwiftUI + + @State private var focused = false + + @Binding var text: String + + let index: Int + let onDelete: () -> Void + + var body: some View { + VStack(alignment: .leading, spacing: 8.0) { + Text(VectorL10n.pollEditFormOptionNumber(index + 1)) + .font(theme.fonts.subheadline) + .foregroundColor(theme.colors.primaryContent) + + HStack(spacing: 16.0) { + TextField(VectorL10n.pollEditFormInputPlaceholder, text: $text, onEditingChanged: { edit in + self.focused = edit + }) + .textFieldStyle(BorderedInputFieldStyle(theme: _theme, isEditing: focused)) + Button { + onDelete() + } label: { + Image(uiImage:Asset.Images.pollDeleteOptionIcon.image) + } + } + } + } +} + +@available(iOS 14.0, *) +struct PollEditFormAnswerOptionView_Previews: PreviewProvider { + static var previews: some View { + VStack(spacing: 32.0) { + PollEditFormAnswerOptionView(text: Binding.constant(""), index: 0) { + + } + PollEditFormAnswerOptionView(text: Binding.constant("Test"), index: 5) { + + } + } + } +} diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift new file mode 100644 index 000000000..2858f7a89 --- /dev/null +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift @@ -0,0 +1,94 @@ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import SwiftUI + +@available(iOS 14.0, *) +struct PollEditFormTypeView: View { + @Environment(\.theme) private var theme: ThemeSwiftUI + + @Binding var selectedType: PollEditFormType + + var body: some View { + VStack(alignment: .leading, spacing: 16.0) { + Text(VectorL10n.pollEditFormPollType) + .font(theme.fonts.title3SB) + .foregroundColor(theme.colors.primaryContent) + PollTypeViewButton(type: .disclosed, selectedType: $selectedType) + PollTypeViewButton(type: .undisclosed, selectedType: $selectedType) + } + } +} + +@available(iOS 14.0, *) +private struct PollTypeViewButton: View { + @Environment(\.theme) private var theme: ThemeSwiftUI + + var type: PollEditFormType + @Binding var selectedType: PollEditFormType + + var body: some View { + Button { + selectedType = type + } label: { + HStack(alignment: .top, spacing: 8.0) { + + if type == selectedType { + Image(uiImage: Asset.Images.pollTypeCheckboxSelected.image) + } else { + Image(uiImage: Asset.Images.pollTypeCheckboxDefault.image) + } + + VStack(alignment: .leading, spacing: 2) { + Text(title) + .font(theme.fonts.body) + .foregroundColor(theme.colors.primaryContent) + Text(description) + .font(theme.fonts.footnote) + .foregroundColor(theme.colors.secondaryContent) + } + } + } + } + + private var title: String { + switch type { + case .disclosed: + return VectorL10n.pollEditFormPollTypeOpen + case .undisclosed: + return VectorL10n.pollEditFormPollTypeClosed + } + } + + private var description: String { + switch type { + case .disclosed: + return VectorL10n.pollEditFormPollTypeOpenDescription + case .undisclosed: + return VectorL10n.pollEditFormPollTypeClosedDescription + } + } +} + +@available(iOS 14.0, *) +struct PollEditFormTypeView_Previews: PreviewProvider { + static var previews: some View { + VStack { + PollEditFormTypeView(selectedType: Binding.constant(.disclosed)) + PollEditFormTypeView(selectedType: Binding.constant(.undisclosed)) + } + } +} diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift index d466b4279..97206ac86 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift @@ -141,8 +141,15 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel answerOptions: answerOptions, closed: poll.isClosed, totalAnswerCount: poll.totalAnswerCount, - type: (poll.kind == .disclosed ? .disclosed : .undisclosed), + type: pollKindToTimelinePollType(poll.kind), maxAllowedSelections: poll.maxAllowedSelections, hasBeenEdited: poll.hasBeenEdited) } + + private func pollKindToTimelinePollType(_ kind: PollKind) -> TimelinePollType { + let mapping = [PollKind.disclosed: TimelinePollType.disclosed, + PollKind.undisclosed: TimelinePollType.undisclosed] + + return mapping[kind] ?? .disclosed + } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift index e822aede1..2b80896c1 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift @@ -91,7 +91,16 @@ struct PollTimelineViewState: BindableState { } struct PollTimelineViewStateBindings { - var showsAnsweringFailureAlert: Bool = false - var showsClosingFailureAlert: Bool = false + var alertInfo: PollTimelineErrorAlertInfo? } +struct PollTimelineErrorAlertInfo: Identifiable { + enum AlertType { + case failedClosingPoll + case failedSubmittingAnswer + } + + let id: AlertType + let title: String + let subtitle: String +} diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift index 28347836b..3bcf508b3 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift @@ -21,8 +21,10 @@ import SwiftUI @available(iOS 14.0, *) enum MockPollTimelineScreenState: MockScreenState, CaseIterable { - case open - case closed + case openDisclosed + case closedDisclosed + case openUndisclosed + case closedUndisclosed var screenType: Any.Type { MockPollTimelineScreenState.self @@ -35,9 +37,9 @@ enum MockPollTimelineScreenState: MockScreenState, CaseIterable { let poll = TimelinePoll(question: "Question", answerOptions: answerOptions, - closed: (self == .closed ? true : false), + closed: (self == .closedDisclosed || self == .closedUndisclosed ? true : false), totalAnswerCount: 20, - type: .disclosed, + type: (self == .closedDisclosed || self == .openDisclosed ? .disclosed : .undisclosed), maxAllowedSelections: 1, hasBeenEdited: false) diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift index eb802509b..cc5cfdfba 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift @@ -69,9 +69,13 @@ class PollTimelineViewModel: PollTimelineViewModelType { case .updateWithPoll(let poll): state.poll = poll case .showAnsweringFailure: - state.bindings.showsAnsweringFailureAlert = true + state.bindings.alertInfo = PollTimelineErrorAlertInfo(id: .failedSubmittingAnswer, + title: VectorL10n.pollTimelineVoteNotRegisteredTitle, + subtitle: VectorL10n.pollTimelineVoteNotRegisteredSubtitle) case .showClosingFailure: - state.bindings.showsClosingFailureAlert = true + state.bindings.alertInfo = PollTimelineErrorAlertInfo(id: .failedClosingPoll, + title: VectorL10n.pollTimelineNotClosedTitle, + subtitle: VectorL10n.pollTimelineNotClosedSubtitle) } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift b/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift index f36660e54..85989e953 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift @@ -31,8 +31,8 @@ class PollTimelineUITests: XCTestCase { app.launch() } - func testOpenPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.open.title) + func testOpenDisclosedPoll() { + app.goToScreenWithIdentifier(MockPollTimelineScreenState.openDisclosed.title) XCTAssert(app.staticTexts["Question"].exists) XCTAssert(app.staticTexts["20 votes cast"].exists) @@ -69,9 +69,48 @@ class PollTimelineUITests: XCTestCase { XCTAssertEqual(app.buttons["Third, 16 votes"].value as! String, "80%") } - func testClosedPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.closed.title) + func testOpenUndisclosedPoll() { + app.goToScreenWithIdentifier(MockPollTimelineScreenState.openUndisclosed.title) + XCTAssert(app.staticTexts["Question"].exists) + XCTAssert(app.staticTexts["20 votes cast"].exists) + + XCTAssert(!app.buttons["First, 10 votes"].exists) + XCTAssert(app.buttons["First"].exists) + XCTAssertTrue((app.buttons["First"].value as! String).isEmpty) + + XCTAssert(!app.buttons["Second, 5 votes"].exists) + XCTAssert(app.buttons["Second"].exists) + XCTAssertTrue((app.buttons["Second"].value as! String).isEmpty) + + XCTAssert(!app.buttons["Third, 15 votes"].exists) + XCTAssert(app.buttons["Third"].exists) + XCTAssertTrue((app.buttons["Third"].value as! String).isEmpty) + + app.buttons["First"].tap() + + XCTAssert(app.buttons["First"].exists) + XCTAssert(app.buttons["Second"].exists) + XCTAssert(app.buttons["Third"].exists) + + app.buttons["Third"].tap() + + XCTAssert(app.buttons["First"].exists) + XCTAssert(app.buttons["Second"].exists) + XCTAssert(app.buttons["Third"].exists) + } + + func testClosedDisclosedPoll() { + app.goToScreenWithIdentifier(MockPollTimelineScreenState.closedDisclosed.title) + checkClosedPoll() + } + + func testClosedUndisclosedPoll() { + app.goToScreenWithIdentifier(MockPollTimelineScreenState.closedUndisclosed.title) + checkClosedPoll() + } + + private func checkClosedPoll() { XCTAssert(app.staticTexts["Question"].exists) XCTAssert(app.staticTexts["Final results based on 20 votes"].exists) diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift index 9ad80e5b9..ac5a44e28 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift @@ -37,7 +37,8 @@ class PollTimelineViewModelTests: XCTestCase { closed: false, totalAnswerCount: 3, type: .disclosed, - maxAllowedSelections: 1) + maxAllowedSelections: 1, + hasBeenEdited: false) viewModel = PollTimelineViewModel(timelinePoll: timelinePoll) context = viewModel.context diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift index e5daad842..f3547cb1f 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift @@ -25,10 +25,8 @@ struct PollTimelineAnswerOptionButton: View { @Environment(\.theme) private var theme: ThemeSwiftUI + let poll: TimelinePoll let answerOption: TimelineAnswerOption - let pollClosed: Bool - let showResults: Bool - let totalAnswerCount: UInt let action: () -> Void // MARK: Public @@ -37,9 +35,10 @@ struct PollTimelineAnswerOptionButton: View { Button(action: action) { let rect = RoundedRectangle(cornerRadius: 4.0) answerOptionLabel + .frame(maxWidth: .infinity, alignment: .leading) .padding(.horizontal, 8.0) .padding(.top, 12.0) - .padding(.bottom, 4.0) + .padding(.bottom, 12.0) .clipShape(rect) .overlay(rect.stroke(borderAccentColor, lineWidth: 1.0)) .accentColor(progressViewAccentColor) @@ -50,7 +49,7 @@ struct PollTimelineAnswerOptionButton: View { VStack(alignment: .leading, spacing: 12.0) { HStack(alignment: .top, spacing: 8.0) { - if !pollClosed { + if !poll.closed { Image(uiImage: answerOption.selected ? Asset.Images.pollCheckboxSelected.image : Asset.Images.pollCheckboxDefault.image) } @@ -58,30 +57,31 @@ struct PollTimelineAnswerOptionButton: View { .font(theme.fonts.body) .foregroundColor(theme.colors.primaryContent) - if pollClosed && answerOption.winner { + if poll.closed && answerOption.winner { Spacer() Image(uiImage: Asset.Images.pollWinnerIcon.image) } } - HStack { - ProgressView(value: Double(showResults ? answerOption.count : 0), - total: Double(totalAnswerCount)) - .progressViewStyle(LinearProgressViewStyle()) - .scaleEffect(x: 1.0, y: 1.2, anchor: .center) - .padding(.vertical, 8.0) - - if (showResults) { - Text(answerOption.count == 1 ? VectorL10n.pollTimelineOneVote : VectorL10n.pollTimelineVotesCount(Int(answerOption.count))) - .font(theme.fonts.footnote) - .foregroundColor(pollClosed && answerOption.winner ? theme.colors.accent : theme.colors.secondaryContent) + if poll.type == .disclosed || poll.closed { + HStack { + ProgressView(value: Double(shouldDiscloseResults ? answerOption.count : 0), + total: Double(poll.totalAnswerCount)) + .progressViewStyle(LinearProgressViewStyle()) + .scaleEffect(x: 1.0, y: 1.2, anchor: .center) + + if (shouldDiscloseResults) { + Text(answerOption.count == 1 ? VectorL10n.pollTimelineOneVote : VectorL10n.pollTimelineVotesCount(Int(answerOption.count))) + .font(theme.fonts.footnote) + .foregroundColor(poll.closed && answerOption.winner ? theme.colors.accent : theme.colors.secondaryContent) + } } } } } var borderAccentColor: Color { - guard !pollClosed else { + guard !poll.closed else { return (answerOption.winner ? theme.colors.accent : theme.colors.quinaryContent) } @@ -89,67 +89,77 @@ struct PollTimelineAnswerOptionButton: View { } var progressViewAccentColor: Color { - guard !pollClosed else { + guard !poll.closed else { return (answerOption.winner ? theme.colors.accent : theme.colors.quarterlyContent) } return answerOption.selected ? theme.colors.accent : theme.colors.quarterlyContent } + + private var shouldDiscloseResults: Bool { + if poll.closed { + return poll.totalAnswerCount > 0 + } else { + return poll.type == .disclosed && poll.totalAnswerCount > 0 && poll.hasCurrentUserVoted + } + } } @available(iOS 14.0, *) struct PollTimelineAnswerOptionButton_Previews: PreviewProvider { static let stateRenderer = MockPollTimelineScreenState.stateRenderer + static var previews: some View { - Group { - VStack { - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 5, winner: false, selected: false), - pollClosed: false, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 5, winner: false, selected: false), - pollClosed: false, showResults: false, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 8, winner: false, selected: true), - pollClosed: false, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 8, winner: false, selected: true), - pollClosed: false, showResults: false, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - count: 200, winner: false, selected: false), - pollClosed: false, showResults: true, totalAnswerCount: 1000, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - count: 200, winner: false, selected: false), - pollClosed: false, showResults: false, totalAnswerCount: 1000, action: {}) - } + let pollTypes: [TimelinePollType] = [.disclosed, .undisclosed] - VStack { - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 5, winner: false, selected: false), - pollClosed: true, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 5, winner: true, selected: false), - pollClosed: true, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 8, winner: false, selected: true), - pollClosed: true, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", text: "Test", count: 8, winner: true, selected: true), - pollClosed: true, showResults: true, totalAnswerCount: 100, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - count: 200, winner: false, selected: false), - pollClosed: true, showResults: true, totalAnswerCount: 1000, action: {}) - - PollTimelineAnswerOptionButton(answerOption: TimelineAnswerOption(id: "", - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", - count: 200, winner: true, selected: false), - pollClosed: true, showResults: true, totalAnswerCount: 1000, action: {}) + ForEach(pollTypes, id: \.self) { type in + VStack { + PollTimelineAnswerOptionButton(poll: buildPoll(closed: false, type: type), + answerOption: buildAnswerOption(selected: false), + action: {}) + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: false, type: type), + answerOption: buildAnswerOption(selected: true), + action: {}) + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + answerOption: buildAnswerOption(selected: false, winner: false), + action: {}) + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + answerOption: buildAnswerOption(selected: false, winner: true), + action: {}) + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + answerOption: buildAnswerOption(selected: true, winner: false), + action: {}) + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + answerOption: buildAnswerOption(selected: true, winner: true), + action: {}) + + let longText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." + + PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + answerOption: buildAnswerOption(text: longText, selected: true, winner: true), + action: {}) + } } } } + + static func buildPoll(closed: Bool, type: TimelinePollType) -> TimelinePoll { + TimelinePoll(question: "", + answerOptions: [], + closed: closed, + totalAnswerCount: 100, + type: type, + maxAllowedSelections: 1, + hasBeenEdited: false) + } + + static func buildAnswerOption(text: String = "Test", selected: Bool, winner: Bool = false) -> TimelineAnswerOption { + TimelineAnswerOption(id: "1", text: text, count: 5, winner: winner, selected: selected) + } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift index 2f0bc5884..8f36a5ac6 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift +++ b/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift @@ -39,24 +39,16 @@ struct PollTimelineView: View { Text(poll.question) .font(theme.fonts.bodySB) .foregroundColor(theme.colors.primaryContent) + - Text(editedText) + Text(editedText) .font(theme.fonts.footnote) .foregroundColor(theme.colors.secondaryContent) VStack(spacing: 24.0) { ForEach(poll.answerOptions) { answerOption in - PollTimelineAnswerOptionButton(answerOption: answerOption, - pollClosed: poll.closed, - showResults: shouldDiscloseResults, - totalAnswerCount: poll.totalAnswerCount) { + PollTimelineAnswerOptionButton(poll: poll, answerOption: answerOption) { viewModel.send(viewAction: .selectAnswerOptionWithIdentifier(answerOption.id)) } } - .alert(isPresented: $viewModel.showsClosingFailureAlert) { - Alert(title: Text(VectorL10n.pollTimelineNotClosedTitle), - message: Text(VectorL10n.pollTimelineNotClosedSubtitle), - dismissButton: .default(Text(VectorL10n.ok))) - } } .disabled(poll.closed) .fixedSize(horizontal: false, vertical: true) @@ -64,14 +56,14 @@ struct PollTimelineView: View { Text(totalVotesString) .font(theme.fonts.footnote) .foregroundColor(theme.colors.tertiaryContent) - .alert(isPresented: $viewModel.showsAnsweringFailureAlert) { - Alert(title: Text(VectorL10n.pollTimelineVoteNotRegisteredTitle), - message: Text(VectorL10n.pollTimelineVoteNotRegisteredSubtitle), - dismissButton: .default(Text(VectorL10n.ok))) - } } .padding([.horizontal, .top], 2.0) .padding([.bottom]) + .alert(item: $viewModel.alertInfo) { info in + Alert(title: Text(info.title), + message: Text(info.subtitle), + dismissButton: .default(Text(VectorL10n.ok))) + } } private var totalVotesString: String { @@ -89,26 +81,16 @@ struct PollTimelineView: View { case 0: return VectorL10n.pollTimelineTotalNoVotes case 1: - return (poll.hasCurrentUserVoted ? + return (poll.hasCurrentUserVoted || poll.type == .undisclosed ? VectorL10n.pollTimelineTotalOneVote : VectorL10n.pollTimelineTotalOneVoteNotVoted) default: - return (poll.hasCurrentUserVoted ? + return (poll.hasCurrentUserVoted || poll.type == .undisclosed ? VectorL10n.pollTimelineTotalVotes(Int(poll.totalAnswerCount)) : VectorL10n.pollTimelineTotalVotesNotVoted(Int(poll.totalAnswerCount))) } } - private var shouldDiscloseResults: Bool { - let poll = viewModel.viewState.poll - - if poll.closed { - return poll.totalAnswerCount > 0 - } else { - return poll.type == .disclosed && poll.totalAnswerCount > 0 && poll.hasCurrentUserVoted - } - } - private var editedText: String { viewModel.viewState.poll.hasBeenEdited ? " \(VectorL10n.eventFormatterMessageEditedMention)" : "" } From fb07920235b17acb72095999e626c7ff8258db71 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jan 2022 17:25:14 +0200 Subject: [PATCH 140/209] vector-im/element-ios/issues/5114 - Cleanup + rename PollTimeline to TimelinePoll. --- Riot/Modules/Room/RoomCoordinator.swift | 8 +-- .../BubbleCells/Poll/PollBubbleCell.swift | 2 +- .../AnalyticsPromptModels.swift | 2 - .../AnalyticsPromptViewModel.swift | 2 - .../AnalyticsPromptCoordinator.swift | 32 +++++----- .../MockAnalyticsPromptScreenState.swift | 2 - .../Test/UI/AnalyticsPromptUITests.swift | 2 - .../View/AnalyticsPrompt.swift | 2 - .../Modules/Common/Mock/MockAppScreens.swift | 2 +- .../LocationSharingScreenState.swift | 2 +- .../RoomNotificationSettingsCoordinator.swift | 32 +++++----- .../Coordinator/PollEditFormCoordinator.swift | 32 +++++----- .../PollEditForm/PollEditFormModels.swift | 2 - .../PollEditFormScreenState.swift | 4 +- .../PollEditForm/PollEditFormViewModel.swift | 2 - .../Test/UI/PollEditFormUITests.swift | 2 - .../Unit/PollEditFormViewModelTests.swift | 4 +- .../Room/PollEditForm/View/PollEditForm.swift | 2 - .../View/PollEditFormAnswerOptionView.swift | 1 + .../TimelinePollCoordinator.swift} | 58 +++++++++---------- .../Coordinator/TimelinePollProvider.swift} | 14 ++--- .../Test/UI/TimelinePollUITests.swift} | 12 ++-- .../Unit/TimelinePollViewModelTests.swift} | 16 +++-- .../TimelinePollModels.swift} | 28 +++++---- .../TimelinePollScreenState.swift} | 16 +++-- .../TimelinePollViewModel.swift} | 28 +++++---- .../TimelinePollAnswerOptionButton.swift} | 26 ++++----- .../View/TimelinePollView.swift} | 12 ++-- .../UserSuggestionCoordinator.swift | 32 +++++----- .../UserSuggestionCoordinatorParameters.swift | 2 - .../Model/UserSuggestionStateAction.swift | 2 - .../Model/UserSuggestionViewAction.swift | 2 - .../Model/UserSuggestionViewModelResult.swift | 2 - .../Model/UserSuggestionViewState.swift | 2 - .../Mock/MockUserSuggestionScreenState.swift | 4 +- .../Service/UserSuggestionService.swift | 2 - .../UserSuggestionServiceProtocol.swift | 2 - .../Test/UI/UserSuggestionUITests.swift | 2 - .../Unit/UserSuggestionServiceTests.swift | 2 - .../View/UserSuggestionList.swift | 2 - .../View/UserSuggestionListItem.swift | 2 - .../ViewModel/UserSuggestionViewModel.swift | 2 - .../UserSuggestionViewModelProtocol.swift | 2 - .../NotificationSettingsCoordinator.swift | 32 +++++----- .../TemplateRoomsCoordinator.swift | 32 +++++----- .../TemplateRoomsCoordinatorParameters.swift | 32 +++++----- .../View/TemplateRoomListRow.swift | 2 +- 47 files changed, 215 insertions(+), 292 deletions(-) rename RiotSwiftUI/Modules/Room/{PollTimeline/Coordinator/PollTimelineCoordinator.swift => TimelinePoll/Coordinator/TimelinePollCoordinator.swift} (71%) rename RiotSwiftUI/Modules/Room/{PollTimeline/Coordinator/PollTimelineProvider.swift => TimelinePoll/Coordinator/TimelinePollProvider.swift} (78%) rename RiotSwiftUI/Modules/Room/{PollTimeline/Test/UI/PollTimelineUITests.swift => TimelinePoll/Test/UI/TimelinePollUITests.swift} (92%) rename RiotSwiftUI/Modules/Room/{PollTimeline/Test/Unit/PollTimelineViewModelTests.swift => TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift} (90%) rename RiotSwiftUI/Modules/Room/{PollTimeline/PollTimelineModels.swift => TimelinePoll/TimelinePollModels.swift} (75%) rename RiotSwiftUI/Modules/Room/{PollTimeline/PollTimelineScreenState.swift => TimelinePoll/TimelinePollScreenState.swift} (66%) rename RiotSwiftUI/Modules/Room/{PollTimeline/PollTimelineViewModel.swift => TimelinePoll/TimelinePollViewModel.swift} (77%) rename RiotSwiftUI/Modules/Room/{PollTimeline/View/PollTimelineAnswerOptionButton.swift => TimelinePoll/View/TimelinePollAnswerOptionButton.swift} (88%) rename RiotSwiftUI/Modules/Room/{PollTimeline/View/PollTimelineView.swift => TimelinePoll/View/TimelinePollView.swift} (90%) diff --git a/Riot/Modules/Room/RoomCoordinator.swift b/Riot/Modules/Room/RoomCoordinator.swift index da10cfbcf..ef5116b17 100644 --- a/Riot/Modules/Room/RoomCoordinator.swift +++ b/Riot/Modules/Room/RoomCoordinator.swift @@ -76,7 +76,7 @@ final class RoomCoordinator: NSObject, RoomCoordinatorProtocol { self.activityIndicatorPresenter = ActivityIndicatorPresenter() if #available(iOS 14, *) { - PollTimelineProvider.shared.session = parameters.session + TimelinePollProvider.shared.session = parameters.session } super.init() @@ -344,7 +344,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { return false } - return PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.canEndPoll() ?? false + return TimelinePollProvider.shared.timelinePollCoordinatorForEventIdentifier(eventIdentifier)?.canEndPoll() ?? false } func roomViewController(_ roomViewController: RoomViewController, endPollWithEventIdentifier eventIdentifier: String) { @@ -352,7 +352,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { return } - PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.endPoll() + TimelinePollProvider.shared.timelinePollCoordinatorForEventIdentifier(eventIdentifier)?.endPoll() } func roomViewController(_ roomViewController: RoomViewController, canEditPollWithEventIdentifier eventIdentifier: String) -> Bool { @@ -360,7 +360,7 @@ extension RoomCoordinator: RoomViewControllerDelegate { return false } - return PollTimelineProvider.shared.pollTimelineCoordinatorForEventIdentifier(eventIdentifier)?.canEditPoll() ?? false + return TimelinePollProvider.shared.timelinePollCoordinatorForEventIdentifier(eventIdentifier)?.canEditPoll() ?? false } func roomViewController(_ roomViewController: RoomViewController, didRequestEditForPollWithStart startEvent: MXEvent) { diff --git a/Riot/Modules/Room/Views/BubbleCells/Poll/PollBubbleCell.swift b/Riot/Modules/Room/Views/BubbleCells/Poll/PollBubbleCell.swift index 4d3d42e28..2165549d8 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Poll/PollBubbleCell.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Poll/PollBubbleCell.swift @@ -29,7 +29,7 @@ class PollBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable { let bubbleData = cellData as? RoomBubbleCellData, let event = bubbleData.events.last, event.eventType == __MXEventType.pollStart, - let view = PollTimelineProvider.shared.buildPollTimelineViewForEvent(event) else { + let view = TimelinePollProvider.shared.buildTimelinePollViewForEvent(event) else { return } diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptModels.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptModels.swift index b9678fdbd..99f96bce8 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptModels.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptModels.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptViewModel.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptViewModel.swift index 999e2a95f..971929ab4 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptViewModel.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/AnalyticsPromptViewModel.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptCoordinator.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptCoordinator.swift index c9e5f44b4..6e107b62b 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptCoordinator.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/Coordinator/AnalyticsPromptCoordinator.swift @@ -1,20 +1,18 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import SwiftUI diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/MockAnalyticsPromptScreenState.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/MockAnalyticsPromptScreenState.swift index 9c303bbbe..ed947e303 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/MockAnalyticsPromptScreenState.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/MockAnalyticsPromptScreenState.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/Test/UI/AnalyticsPromptUITests.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/Test/UI/AnalyticsPromptUITests.swift index b8a38a117..c24e1fa63 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/Test/UI/AnalyticsPromptUITests.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/Test/UI/AnalyticsPromptUITests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift b/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift index 8f7acf49d..5e622ab5d 100644 --- a/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift +++ b/RiotSwiftUI/Modules/AnalyticsPrompt/View/AnalyticsPrompt.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh AnalyticsPrompt AnalyticsPrompt // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift b/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift index f64a1a51f..cedc46d0f 100644 --- a/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift +++ b/RiotSwiftUI/Modules/Common/Mock/MockAppScreens.swift @@ -24,7 +24,7 @@ enum MockAppScreens { MockAnalyticsPromptScreenState.self, MockUserSuggestionScreenState.self, MockPollEditFormScreenState.self, - MockPollTimelineScreenState.self, + MockTimelinePollScreenState.self, MockTemplateUserProfileScreenState.self, MockTemplateRoomListScreenState.self, MockTemplateRoomChatScreenState.self diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift index f316d761e..386471b02 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift @@ -25,7 +25,7 @@ enum MockLocationSharingScreenState: MockScreenState, CaseIterable { case displayExistingLocation var screenType: Any.Type { - MockLocationSharingScreenState.self + LocationSharingView.self } var screenView: ([Any], AnyView) { diff --git a/RiotSwiftUI/Modules/Room/NotificationSettings/Coordinator/RoomNotificationSettingsCoordinator.swift b/RiotSwiftUI/Modules/Room/NotificationSettings/Coordinator/RoomNotificationSettingsCoordinator.swift index 6d79f5e67..b150c5bb4 100644 --- a/RiotSwiftUI/Modules/Room/NotificationSettings/Coordinator/RoomNotificationSettingsCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/NotificationSettings/Coordinator/RoomNotificationSettingsCoordinator.swift @@ -1,20 +1,18 @@ -// File created from ScreenTemplate -// $ createScreen.sh Room/NotificationSettings RoomNotificationSettings -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import Foundation import UIKit diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift index c071100c7..1c6c7f569 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift @@ -1,20 +1,18 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import Foundation import UIKit diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift index 927dbe6c5..db08276ec 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift index e6e01405c..53d2d75e2 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // @@ -24,7 +22,7 @@ enum MockPollEditFormScreenState: MockScreenState, CaseIterable { case standard var screenType: Any.Type { - MockPollEditFormScreenState.self + PollEditForm.self } var screenView: ([Any], AnyView) { diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index 6cbb2dc8c..9b87ce138 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Test/UI/PollEditFormUITests.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Test/UI/PollEditFormUITests.swift index 2780739cd..70042a696 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Test/UI/PollEditFormUITests.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Test/UI/PollEditFormUITests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift index 48f035c5d..c62afc61f 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // @@ -29,7 +27,7 @@ class PollEditFormViewModelTests: XCTestCase { override func setUpWithError() throws { viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, - pollDetails: PollDetails(question: "", answerOptions: ["", ""]))) + pollDetails: PollDetails(type: .disclosed, question: "", answerOptions: ["", ""]))) context = viewModel.context } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift index c5a327ba7..6bcb1e233 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift index 819c851dc..ab74d8685 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift @@ -44,6 +44,7 @@ struct PollEditFormAnswerOptionView: View { } label: { Image(uiImage:Asset.Images.pollDeleteOptionIcon.image) } + .accessibilityIdentifier("Delete answer option") } } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift similarity index 71% rename from RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift index 97206ac86..87a0db032 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift @@ -1,43 +1,41 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollTimeline PollTimeline -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import SwiftUI import MatrixSDK import Combine -struct PollTimelineCoordinatorParameters { +struct TimelinePollCoordinatorParameters { let session: MXSession let room: MXRoom let pollStartEvent: MXEvent } @available(iOS 14.0, *) -final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDelegate { +final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDelegate { // MARK: - Properties // MARK: Private - private let parameters: PollTimelineCoordinatorParameters + private let parameters: TimelinePollCoordinatorParameters private let selectedAnswerIdentifiersSubject = PassthroughSubject<[String], Never>() private var pollAggregator: PollAggregator - private var pollTimelineViewModel: PollTimelineViewModel! + private var viewModel: TimelinePollViewModel! private var cancellables = Set() // MARK: Public @@ -48,14 +46,14 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel // MARK: - Setup @available(iOS 14.0, *) - init(parameters: PollTimelineCoordinatorParameters) throws { + init(parameters: TimelinePollCoordinatorParameters) throws { self.parameters = parameters try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollStartEventId: parameters.pollStartEvent.eventId) pollAggregator.delegate = self - pollTimelineViewModel = PollTimelineViewModel(timelinePoll: buildTimelinePollFrom(pollAggregator.poll)) - pollTimelineViewModel.callback = { [weak self] result in + viewModel = TimelinePollViewModel(timelinePoll: buildTimelinePollFrom(pollAggregator.poll)) + viewModel.callback = { [weak self] result in guard let self = self else { return } switch result { @@ -75,9 +73,9 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel localEcho: nil, success: nil) { [weak self] error in guard let self = self else { return } - MXLog.error("[PollTimelineCoordinator]] Failed submitting response with error \(String(describing: error))") + MXLog.error("[TimelinePollCoordinator]] Failed submitting response with error \(String(describing: error))") - self.pollTimelineViewModel.dispatch(action: .showAnsweringFailure) + self.viewModel.dispatch(action: .showAnsweringFailure) } } .store(in: &cancellables) @@ -89,7 +87,7 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel } func toPresentable() -> UIViewController { - return VectorHostingController(rootView: PollTimelineView(viewModel: pollTimelineViewModel.context)) + return VectorHostingController(rootView: TimelinePollView(viewModel: viewModel.context)) } func canEndPoll() -> Bool { @@ -102,14 +100,14 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel func endPoll() { parameters.room.sendPollEnd(for: parameters.pollStartEvent, localEcho: nil, success: nil) { [weak self] error in - self?.pollTimelineViewModel.dispatch(action: .showClosingFailure) + self?.viewModel.dispatch(action: .showClosingFailure) } } // MARK: - PollAggregatorDelegate func pollAggregatorDidUpdateData(_ aggregator: PollAggregator) { - pollTimelineViewModel.dispatch(action: .updateWithPoll(buildTimelinePollFrom(aggregator.poll))) + viewModel.dispatch(action: .updateWithPoll(buildTimelinePollFrom(aggregator.poll))) } func pollAggregatorDidStartLoading(_ aggregator: PollAggregator) { @@ -130,7 +128,7 @@ final class PollTimelineCoordinator: Coordinator, Presentable, PollAggregatorDel // to add the SDK as a dependency to it. We need to translate from one to the other on this level. func buildTimelinePollFrom(_ poll: PollProtocol) -> TimelinePoll { let answerOptions = poll.answerOptions.map { pollAnswerOption in - TimelineAnswerOption(id: pollAnswerOption.id, + TimelinePollAnswerOption(id: pollAnswerOption.id, text: pollAnswerOption.text, count: pollAnswerOption.count, winner: pollAnswerOption.isWinner, diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineProvider.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollProvider.swift similarity index 78% rename from RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineProvider.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollProvider.swift index d778cbedf..0fa488ebd 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Coordinator/PollTimelineProvider.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollProvider.swift @@ -17,11 +17,11 @@ import Foundation @available(iOS 14, *) -class PollTimelineProvider { - static let shared = PollTimelineProvider() +class TimelinePollProvider { + static let shared = TimelinePollProvider() var session: MXSession? - var coordinatorsForEventIdentifiers = [String: PollTimelineCoordinator]() + var coordinatorsForEventIdentifiers = [String: TimelinePollCoordinator]() private init() { @@ -29,7 +29,7 @@ class PollTimelineProvider { /// Create or retrieve the poll timeline coordinator for this event and return /// a view to be displayed in the timeline - func buildPollTimelineViewForEvent(_ event: MXEvent) -> UIView? { + func buildTimelinePollViewForEvent(_ event: MXEvent) -> UIView? { guard let session = session, let room = session.room(withRoomId: event.roomId) else { return nil } @@ -38,8 +38,8 @@ class PollTimelineProvider { return coordinator.toPresentable().view } - let parameters = PollTimelineCoordinatorParameters(session: session, room: room, pollStartEvent: event) - guard let coordinator = try? PollTimelineCoordinator(parameters: parameters) else { + let parameters = TimelinePollCoordinatorParameters(session: session, room: room, pollStartEvent: event) + guard let coordinator = try? TimelinePollCoordinator(parameters: parameters) else { return nil } @@ -49,7 +49,7 @@ class PollTimelineProvider { } /// Retrieve the poll timeline coordinator for the given event or nil if it hasn't been created yet - func pollTimelineCoordinatorForEventIdentifier(_ eventIdentifier: String) -> PollTimelineCoordinator? { + func timelinePollCoordinatorForEventIdentifier(_ eventIdentifier: String) -> TimelinePollCoordinator? { return coordinatorsForEventIdentifiers[eventIdentifier] } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/UI/TimelinePollUITests.swift similarity index 92% rename from RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/Test/UI/TimelinePollUITests.swift index 85989e953..9c4efe9c1 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Test/UI/PollTimelineUITests.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/UI/TimelinePollUITests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollTimeline PollTimeline // // Copyright 2021 New Vector Ltd // @@ -20,7 +18,7 @@ import XCTest import RiotSwiftUI @available(iOS 14.0, *) -class PollTimelineUITests: XCTestCase { +class TimelinePollUITests: XCTestCase { private var app: XCUIApplication! @@ -32,7 +30,7 @@ class PollTimelineUITests: XCTestCase { } func testOpenDisclosedPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.openDisclosed.title) + app.goToScreenWithIdentifier(MockTimelinePollScreenState.openDisclosed.title) XCTAssert(app.staticTexts["Question"].exists) XCTAssert(app.staticTexts["20 votes cast"].exists) @@ -70,7 +68,7 @@ class PollTimelineUITests: XCTestCase { } func testOpenUndisclosedPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.openUndisclosed.title) + app.goToScreenWithIdentifier(MockTimelinePollScreenState.openUndisclosed.title) XCTAssert(app.staticTexts["Question"].exists) XCTAssert(app.staticTexts["20 votes cast"].exists) @@ -101,12 +99,12 @@ class PollTimelineUITests: XCTestCase { } func testClosedDisclosedPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.closedDisclosed.title) + app.goToScreenWithIdentifier(MockTimelinePollScreenState.closedDisclosed.title) checkClosedPoll() } func testClosedUndisclosedPoll() { - app.goToScreenWithIdentifier(MockPollTimelineScreenState.closedUndisclosed.title) + app.goToScreenWithIdentifier(MockTimelinePollScreenState.closedUndisclosed.title) checkClosedPoll() } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift similarity index 90% rename from RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift index ac5a44e28..8b580f2a6 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/Test/Unit/PollTimelineViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollTimeline PollTimeline // // Copyright 2021 New Vector Ltd // @@ -22,15 +20,15 @@ import Combine @testable import RiotSwiftUI @available(iOS 14.0, *) -class PollTimelineViewModelTests: XCTestCase { - var viewModel: PollTimelineViewModel! - var context: PollTimelineViewModelType.Context! +class TimelinePollViewModelTests: XCTestCase { + var viewModel: TimelinePollViewModel! + var context: TimelinePollViewModelType.Context! var cancellables = Set() override func setUpWithError() throws { - let answerOptions = [TimelineAnswerOption(id: "1", text: "1", count: 1, winner: false, selected: false), - TimelineAnswerOption(id: "2", text: "2", count: 1, winner: false, selected: false), - TimelineAnswerOption(id: "3", text: "3", count: 1, winner: false, selected: false)] + let answerOptions = [TimelinePollAnswerOption(id: "1", text: "1", count: 1, winner: false, selected: false), + TimelinePollAnswerOption(id: "2", text: "2", count: 1, winner: false, selected: false), + TimelinePollAnswerOption(id: "3", text: "3", count: 1, winner: false, selected: false)] let timelinePoll = TimelinePoll(question: "Question", answerOptions: answerOptions, @@ -40,7 +38,7 @@ class PollTimelineViewModelTests: XCTestCase { maxAllowedSelections: 1, hasBeenEdited: false) - viewModel = PollTimelineViewModel(timelinePoll: timelinePoll) + viewModel = TimelinePollViewModel(timelinePoll: timelinePoll) context = viewModel.context } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift similarity index 75% rename from RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift index 2b80896c1..af33cf012 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineModels.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollTimeline PollTimeline // // Copyright 2021 New Vector Ltd // @@ -19,20 +17,20 @@ import Foundation import SwiftUI -typealias PollTimelineViewModelCallback = ((PollTimelineViewModelResult) -> Void) +typealias TimelinePollViewModelCallback = ((TimelinePollViewModelResult) -> Void) -enum PollTimelineStateAction { - case viewAction(PollTimelineViewAction, PollTimelineViewModelCallback?) +enum TimelinePollStateAction { + case viewAction(TimelinePollViewAction, TimelinePollViewModelCallback?) case updateWithPoll(TimelinePoll) case showAnsweringFailure case showClosingFailure } -enum PollTimelineViewAction { +enum TimelinePollViewAction { case selectAnswerOptionWithIdentifier(String) } -enum PollTimelineViewModelResult { +enum TimelinePollViewModelResult { case selectedAnswerOptionsWithIdentifiers([String]) } @@ -41,7 +39,7 @@ enum TimelinePollType { case undisclosed } -class TimelineAnswerOption: Identifiable { +class TimelinePollAnswerOption: Identifiable { var id: String var text: String var count: UInt @@ -59,14 +57,14 @@ class TimelineAnswerOption: Identifiable { class TimelinePoll { var question: String - var answerOptions: [TimelineAnswerOption] + var answerOptions: [TimelinePollAnswerOption] var closed: Bool var totalAnswerCount: UInt var type: TimelinePollType var maxAllowedSelections: UInt var hasBeenEdited: Bool = true - init(question: String, answerOptions: [TimelineAnswerOption], + init(question: String, answerOptions: [TimelinePollAnswerOption], closed: Bool, totalAnswerCount: UInt, type: TimelinePollType, @@ -85,16 +83,16 @@ class TimelinePoll { } } -struct PollTimelineViewState: BindableState { +struct TimelinePollViewState: BindableState { var poll: TimelinePoll - var bindings: PollTimelineViewStateBindings + var bindings: TimelinePollViewStateBindings } -struct PollTimelineViewStateBindings { - var alertInfo: PollTimelineErrorAlertInfo? +struct TimelinePollViewStateBindings { + var alertInfo: TimelinePollErrorAlertInfo? } -struct PollTimelineErrorAlertInfo: Identifiable { +struct TimelinePollErrorAlertInfo: Identifiable { enum AlertType { case failedClosingPoll case failedSubmittingAnswer diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift similarity index 66% rename from RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift index 3bcf508b3..fd8dcbb83 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineScreenState.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // @@ -20,20 +18,20 @@ import Foundation import SwiftUI @available(iOS 14.0, *) -enum MockPollTimelineScreenState: MockScreenState, CaseIterable { +enum MockTimelinePollScreenState: MockScreenState, CaseIterable { case openDisclosed case closedDisclosed case openUndisclosed case closedUndisclosed var screenType: Any.Type { - MockPollTimelineScreenState.self + TimelinePoll.self } var screenView: ([Any], AnyView) { - let answerOptions = [TimelineAnswerOption(id: "1", text: "First", count: 10, winner: false, selected: false), - TimelineAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true), - TimelineAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)] + let answerOptions = [TimelinePollAnswerOption(id: "1", text: "First", count: 10, winner: false, selected: false), + TimelinePollAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true), + TimelinePollAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)] let poll = TimelinePoll(question: "Question", answerOptions: answerOptions, @@ -43,8 +41,8 @@ enum MockPollTimelineScreenState: MockScreenState, CaseIterable { maxAllowedSelections: 1, hasBeenEdited: false) - let viewModel = PollTimelineViewModel(timelinePoll: poll) + let viewModel = TimelinePollViewModel(timelinePoll: poll) - return ([viewModel], AnyView(PollTimelineView(viewModel: viewModel.context))) + return ([viewModel], AnyView(TimelinePollView(viewModel: viewModel.context))) } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift similarity index 77% rename from RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift index cc5cfdfba..adbb110c4 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/PollTimelineViewModel.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollTimeline PollTimeline // // Copyright 2021 New Vector Ltd // @@ -20,11 +18,11 @@ import SwiftUI import Combine @available(iOS 14, *) -typealias PollTimelineViewModelType = StateStoreViewModel +typealias TimelinePollViewModelType = StateStoreViewModel @available(iOS 14, *) -class PollTimelineViewModel: PollTimelineViewModelType { +class TimelinePollViewModel: TimelinePollViewModelType { // MARK: - Properties @@ -32,24 +30,24 @@ class PollTimelineViewModel: PollTimelineViewModelType { // MARK: Public - var callback: PollTimelineViewModelCallback? + var callback: TimelinePollViewModelCallback? // MARK: - Setup init(timelinePoll: TimelinePoll) { - super.init(initialViewState: PollTimelineViewState(poll: timelinePoll, bindings: PollTimelineViewStateBindings())) + super.init(initialViewState: TimelinePollViewState(poll: timelinePoll, bindings: TimelinePollViewStateBindings())) } // MARK: - Public - override func process(viewAction: PollTimelineViewAction) { + override func process(viewAction: TimelinePollViewAction) { switch viewAction { case .selectAnswerOptionWithIdentifier(_): dispatch(action: .viewAction(viewAction, callback)) } } - override class func reducer(state: inout PollTimelineViewState, action: PollTimelineStateAction) { + override class func reducer(state: inout TimelinePollViewState, action: TimelinePollStateAction) { switch action { case .viewAction(let viewAction, let callback): switch viewAction { @@ -69,11 +67,11 @@ class PollTimelineViewModel: PollTimelineViewModelType { case .updateWithPoll(let poll): state.poll = poll case .showAnsweringFailure: - state.bindings.alertInfo = PollTimelineErrorAlertInfo(id: .failedSubmittingAnswer, + state.bindings.alertInfo = TimelinePollErrorAlertInfo(id: .failedSubmittingAnswer, title: VectorL10n.pollTimelineVoteNotRegisteredTitle, subtitle: VectorL10n.pollTimelineVoteNotRegisteredSubtitle) case .showClosingFailure: - state.bindings.alertInfo = PollTimelineErrorAlertInfo(id: .failedClosingPoll, + state.bindings.alertInfo = TimelinePollErrorAlertInfo(id: .failedClosingPoll, title: VectorL10n.pollTimelineNotClosedTitle, subtitle: VectorL10n.pollTimelineNotClosedSubtitle) } @@ -81,7 +79,7 @@ class PollTimelineViewModel: PollTimelineViewModelType { // MARK: - Private - static func updateSingleSelectPollLocalState(_ state: inout PollTimelineViewState, selectedAnswerIdentifier: String, callback: PollTimelineViewModelCallback?) { + static func updateSingleSelectPollLocalState(_ state: inout TimelinePollViewState, selectedAnswerIdentifier: String, callback: TimelinePollViewModelCallback?) { for answerOption in state.poll.answerOptions { if answerOption.selected { answerOption.selected = false @@ -102,7 +100,7 @@ class PollTimelineViewModel: PollTimelineViewModelType { informCoordinatorOfSelectionUpdate(state: state, callback: callback) } - static func updateMultiSelectPollLocalState(_ state: inout PollTimelineViewState, selectedAnswerIdentifier: String, callback: PollTimelineViewModelCallback?) { + static func updateMultiSelectPollLocalState(_ state: inout TimelinePollViewState, selectedAnswerIdentifier: String, callback: TimelinePollViewModelCallback?) { let selectedAnswerOptions = state.poll.answerOptions.filter { $0.selected == true } let isDeselecting = selectedAnswerOptions.filter { $0.id == selectedAnswerIdentifier }.count > 0 @@ -126,7 +124,7 @@ class PollTimelineViewModel: PollTimelineViewModelType { informCoordinatorOfSelectionUpdate(state: state, callback: callback) } - static func informCoordinatorOfSelectionUpdate(state: PollTimelineViewState, callback: PollTimelineViewModelCallback?) { + static func informCoordinatorOfSelectionUpdate(state: TimelinePollViewState, callback: TimelinePollViewModelCallback?) { let selectedIdentifiers = state.poll.answerOptions.compactMap { answerOption in answerOption.selected ? answerOption.id : nil } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift similarity index 88% rename from RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift index f3547cb1f..e67139c88 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineAnswerOptionButton.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift @@ -17,7 +17,7 @@ import SwiftUI @available(iOS 14.0, *) -struct PollTimelineAnswerOptionButton: View { +struct TimelinePollAnswerOptionButton: View { // MARK: - Properties @@ -26,7 +26,7 @@ struct PollTimelineAnswerOptionButton: View { @Environment(\.theme) private var theme: ThemeSwiftUI let poll: TimelinePoll - let answerOption: TimelineAnswerOption + let answerOption: TimelinePollAnswerOption let action: () -> Void // MARK: Public @@ -106,8 +106,8 @@ struct PollTimelineAnswerOptionButton: View { } @available(iOS 14.0, *) -struct PollTimelineAnswerOptionButton_Previews: PreviewProvider { - static let stateRenderer = MockPollTimelineScreenState.stateRenderer +struct TimelinePollAnswerOptionButton_Previews: PreviewProvider { + static let stateRenderer = MockTimelinePollScreenState.stateRenderer static var previews: some View { Group { @@ -115,33 +115,33 @@ struct PollTimelineAnswerOptionButton_Previews: PreviewProvider { ForEach(pollTypes, id: \.self) { type in VStack { - PollTimelineAnswerOptionButton(poll: buildPoll(closed: false, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: false, type: type), answerOption: buildAnswerOption(selected: false), action: {}) - PollTimelineAnswerOptionButton(poll: buildPoll(closed: false, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: false, type: type), answerOption: buildAnswerOption(selected: true), action: {}) - PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: true, type: type), answerOption: buildAnswerOption(selected: false, winner: false), action: {}) - PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: true, type: type), answerOption: buildAnswerOption(selected: false, winner: true), action: {}) - PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: true, type: type), answerOption: buildAnswerOption(selected: true, winner: false), action: {}) - PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: true, type: type), answerOption: buildAnswerOption(selected: true, winner: true), action: {}) let longText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat." - PollTimelineAnswerOptionButton(poll: buildPoll(closed: true, type: type), + TimelinePollAnswerOptionButton(poll: buildPoll(closed: true, type: type), answerOption: buildAnswerOption(text: longText, selected: true, winner: true), action: {}) } @@ -159,7 +159,7 @@ struct PollTimelineAnswerOptionButton_Previews: PreviewProvider { hasBeenEdited: false) } - static func buildAnswerOption(text: String = "Test", selected: Bool, winner: Bool = false) -> TimelineAnswerOption { - TimelineAnswerOption(id: "1", text: text, count: 5, winner: winner, selected: selected) + static func buildAnswerOption(text: String = "Test", selected: Bool, winner: Bool = false) -> TimelinePollAnswerOption { + TimelinePollAnswerOption(id: "1", text: text, count: 5, winner: winner, selected: selected) } } diff --git a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollView.swift similarity index 90% rename from RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift rename to RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollView.swift index 8f36a5ac6..89efbeb17 100644 --- a/RiotSwiftUI/Modules/Room/PollTimeline/View/PollTimelineView.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollView.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/PollEditForm PollEditForm // // Copyright 2021 New Vector Ltd // @@ -19,7 +17,7 @@ import SwiftUI @available(iOS 14.0, *) -struct PollTimelineView: View { +struct TimelinePollView: View { // MARK: - Properties @@ -29,7 +27,7 @@ struct PollTimelineView: View { // MARK: Public - @ObservedObject var viewModel: PollTimelineViewModel.Context + @ObservedObject var viewModel: TimelinePollViewModel.Context var body: some View { let poll = viewModel.viewState.poll @@ -45,7 +43,7 @@ struct PollTimelineView: View { VStack(spacing: 24.0) { ForEach(poll.answerOptions) { answerOption in - PollTimelineAnswerOptionButton(poll: poll, answerOption: answerOption) { + TimelinePollAnswerOptionButton(poll: poll, answerOption: answerOption) { viewModel.send(viewAction: .selectAnswerOptionWithIdentifier(answerOption.id)) } } @@ -99,8 +97,8 @@ struct PollTimelineView: View { // MARK: - Previews @available(iOS 14.0, *) -struct PollTimelineView_Previews: PreviewProvider { - static let stateRenderer = MockPollTimelineScreenState.stateRenderer +struct TimelinePollView_Previews: PreviewProvider { + static let stateRenderer = MockTimelinePollScreenState.stateRenderer static var previews: some View { stateRenderer.screenGroup() } diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift index d960a9796..4163d0668 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinator.swift @@ -1,20 +1,18 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import Foundation import UIKit diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorParameters.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorParameters.swift index dbad53c94..bd9d54e8b 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorParameters.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Coordinator/UserSuggestionCoordinatorParameters.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionStateAction.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionStateAction.swift index 153848943..f21630348 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionStateAction.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionStateAction.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewAction.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewAction.swift index 6352ed5ae..d08fa62ec 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewAction.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewAction.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewModelResult.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewModelResult.swift index 0336e5be0..b15a983b6 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewModelResult.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewModelResult.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewState.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewState.swift index b47e436c4..0b992b6d1 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewState.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Model/UserSuggestionViewState.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift index 7d4180201..16941ab76 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/Mock/MockUserSuggestionScreenState.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // @@ -26,7 +24,7 @@ enum MockUserSuggestionScreenState: MockScreenState, CaseIterable { static private var members: [RoomMembersProviderMember]! var screenType: Any.Type { - MockUserSuggestionScreenState.self + UserSuggestionList.self } var screenView: ([Any], AnyView) { diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift index 1491aa579..a2a59ec86 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionService.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionServiceProtocol.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionServiceProtocol.swift index 42faeb6c7..44009d0c8 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionServiceProtocol.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Service/UserSuggestionServiceProtocol.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Test/UI/UserSuggestionUITests.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Test/UI/UserSuggestionUITests.swift index c0fa3c926..af864f6a7 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Test/UI/UserSuggestionUITests.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Test/UI/UserSuggestionUITests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/Test/Unit/UserSuggestionServiceTests.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/Test/Unit/UserSuggestionServiceTests.swift index fce852059..a8eaf6e45 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/Test/Unit/UserSuggestionServiceTests.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/Test/Unit/UserSuggestionServiceTests.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionList.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionList.swift index a8c400a1f..4063e75a9 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionList.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionList.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListItem.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListItem.swift index dcfa53fa8..dd9068fdc 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListItem.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/View/UserSuggestionListItem.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModel.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModel.swift index 3d7dca491..62ba522e4 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModel.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModel.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModelProtocol.swift b/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModelProtocol.swift index 10207210c..169b89735 100644 --- a/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModelProtocol.swift +++ b/RiotSwiftUI/Modules/Room/UserSuggestion/ViewModel/UserSuggestionViewModelProtocol.swift @@ -1,5 +1,3 @@ -// File created from SimpleUserProfileExample -// $ createScreen.sh Room/UserSuggestion UserSuggestion // // Copyright 2021 New Vector Ltd // diff --git a/RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsCoordinator.swift b/RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsCoordinator.swift index 06b8a6518..eeb9e0b00 100644 --- a/RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsCoordinator.swift +++ b/RiotSwiftUI/Modules/Settings/Notifications/Coordinator/NotificationSettingsCoordinator.swift @@ -1,20 +1,18 @@ -// File created from ScreenTemplate -// $ createScreen.sh Settings/Notifications NotificationSettings -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import Foundation import SwiftUI diff --git a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinator.swift b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinator.swift index d7af25881..be453b948 100644 --- a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinator.swift +++ b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinator.swift @@ -1,20 +1,18 @@ -// File created from FlowTemplate -// $ createRootCoordinator.sh TemplateRoomsCoordinator TemplateRooms -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import UIKit diff --git a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinatorParameters.swift b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinatorParameters.swift index 8454b3ee2..dd9cd4295 100644 --- a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinatorParameters.swift +++ b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/Coordinator/TemplateRoomsCoordinatorParameters.swift @@ -1,20 +1,18 @@ -// File created from FlowTemplate -// $ createRootCoordinator.sh TemplateRoomsCoordinator TemplateRooms -/* - Copyright 2021 New Vector Ltd - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ +// +// Copyright 2021 New Vector Ltd +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// import Foundation diff --git a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomList/View/TemplateRoomListRow.swift b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomList/View/TemplateRoomListRow.swift index d417c315b..a61fef6c3 100644 --- a/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomList/View/TemplateRoomListRow.swift +++ b/RiotSwiftUI/Modules/Template/TemplateAdvancedRoomsExample/TemplateRoomList/View/TemplateRoomListRow.swift @@ -35,7 +35,7 @@ struct TemplateRoomListRow: View { AvatarImage(avatarData: avatar, size: .medium) Text(displayName ?? "") .foregroundColor(theme.colors.primaryContent) - .accessibility(identifier: "roomNameText") + .accessibility(identifier: "roomNameText") Spacer() } //add to a style From c6409b535c6e63f783c673c7d8bc37fef4e0c04d Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Thu, 13 Jan 2022 17:25:36 +0200 Subject: [PATCH 141/209] Enabled location sharing for testing purposes. --- Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index fe1bdcf8e..98483d53f 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -375,6 +375,6 @@ final class BuildSettings: NSObject { return false } - return false + return true } } From b8623464ef4e7ec6c36d85290d152720e66b2a54 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 14 Jan 2022 17:02:04 +0200 Subject: [PATCH 142/209] vector-im/element-ios/issues/5114 - Various tweaks following PR review. --- .../Coordinator/PollEditFormCoordinator.swift | 29 ++++++------ .../PollEditForm/PollEditFormModels.swift | 24 +++++----- .../PollEditFormScreenState.swift | 5 +-- .../PollEditForm/PollEditFormViewModel.swift | 8 ++-- .../Unit/PollEditFormViewModelTests.swift | 3 +- .../Room/PollEditForm/View/PollEditForm.swift | 2 +- .../View/PollEditFormAnswerOptionView.swift | 4 +- ...iew.swift => PollEditFormTypePicker.swift} | 44 ++++++++++--------- .../Coordinator/TimelinePollCoordinator.swift | 8 ++-- .../Unit/TimelinePollViewModelTests.swift | 16 +++---- .../TimelinePoll/TimelinePollModels.swift | 17 +++++-- .../TimelinePollScreenState.swift | 22 +++++----- .../TimelinePoll/TimelinePollViewModel.swift | 4 +- .../View/TimelinePollAnswerOptionButton.swift | 18 +++----- 14 files changed, 102 insertions(+), 102 deletions(-) rename RiotSwiftUI/Modules/Room/PollEditForm/View/{PollEditFormTypeView.swift => PollEditFormTypePicker.swift} (71%) diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift index 1c6c7f569..17bcf2548 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Coordinator/PollEditFormCoordinator.swift @@ -39,7 +39,7 @@ final class PollEditFormCoordinator: Coordinator, Presentable { } // MARK: Public - + var childCoordinators: [Coordinator] = [] var completion: (() -> Void)? @@ -54,15 +54,12 @@ final class PollEditFormCoordinator: Coordinator, Presentable { if let startEvent = parameters.pollStartEvent, let pollContent = MXEventContentPollStart(fromJSON: startEvent.content) { viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .editing, - pollDetails: PollDetails(type: Self.pollKindKeyToDetailsType(pollContent.kind), - question: pollContent.question, - answerOptions: pollContent.answerOptions.map { $0.text }))) + pollDetails: EditFormPollDetails(type: Self.pollKindKeyToDetailsType(pollContent.kind), + question: pollContent.question, + answerOptions: pollContent.answerOptions.map { $0.text }))) } else { - viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, - pollDetails: PollDetails(type: .disclosed, - question: "", - answerOptions: ["", ""]))) + viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, pollDetails: .default)) } let view = PollEditForm(viewModel: viewModel.context) @@ -140,7 +137,7 @@ final class PollEditFormCoordinator: Coordinator, Presentable { // MARK: - Private - private func buildPollContentWithDetails(_ details: PollDetails) -> MXEventContentPollStart { + private func buildPollContentWithDetails(_ details: EditFormPollDetails) -> MXEventContentPollStart { var options = [MXEventContentPollStartAnswerOption]() for answerOption in details.answerOptions { options.append(MXEventContentPollStartAnswerOption(uuid: UUID().uuidString, text: answerOption)) @@ -153,17 +150,17 @@ final class PollEditFormCoordinator: Coordinator, Presentable { } - private static func pollDetailsTypeToKindKey(_ type: PollEditFormType) -> String { - let mapping = [PollEditFormType.disclosed : kMXMessageContentKeyExtensiblePollKindDisclosed, - PollEditFormType.undisclosed : kMXMessageContentKeyExtensiblePollKindUndisclosed] + private static func pollDetailsTypeToKindKey(_ type: EditFormPollType) -> String { + let mapping = [EditFormPollType.disclosed : kMXMessageContentKeyExtensiblePollKindDisclosed, + EditFormPollType.undisclosed : kMXMessageContentKeyExtensiblePollKindUndisclosed] return mapping[type] ?? kMXMessageContentKeyExtensiblePollKindDisclosed } - private static func pollKindKeyToDetailsType(_ key: String) -> PollEditFormType { - let mapping = [kMXMessageContentKeyExtensiblePollKindDisclosed : PollEditFormType.disclosed, - kMXMessageContentKeyExtensiblePollKindUndisclosed : PollEditFormType.undisclosed] + private static func pollKindKeyToDetailsType(_ key: String) -> EditFormPollType { + let mapping = [kMXMessageContentKeyExtensiblePollKindDisclosed : EditFormPollType.disclosed, + kMXMessageContentKeyExtensiblePollKindUndisclosed : EditFormPollType.undisclosed] - return mapping[key] ?? PollEditFormType.disclosed + return mapping[key] ?? EditFormPollType.disclosed } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift index db08276ec..f8929bc38 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift @@ -17,11 +17,20 @@ import Foundation import SwiftUI -struct PollDetails { - let type: PollEditFormType +enum EditFormPollType { + case disclosed + case undisclosed +} + +struct EditFormPollDetails { + let type: EditFormPollType let question: String let answerOptions: [String] let maxSelections: UInt = 1 + + static var `default`: EditFormPollDetails { + EditFormPollDetails(type: .disclosed, question: "", answerOptions: ["", ""]) + } } enum PollEditFormMode { @@ -45,13 +54,8 @@ enum PollEditFormViewAction { enum PollEditFormViewModelResult { case cancel - case create(PollDetails) - case update(PollDetails) -} - -enum PollEditFormType { - case disclosed - case undisclosed + case create(EditFormPollDetails) + case update(EditFormPollDetails) } struct PollEditFormQuestion { @@ -96,7 +100,7 @@ struct PollEditFormViewState: BindableState { struct PollEditFormViewStateBindings { var question: PollEditFormQuestion var answerOptions: [PollEditFormAnswerOption] - var type: PollEditFormType + var type: EditFormPollType var alertInfo: PollEditFormErrorAlertInfo? } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift index 53d2d75e2..8d6720340 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormScreenState.swift @@ -26,10 +26,7 @@ enum MockPollEditFormScreenState: MockScreenState, CaseIterable { } var screenView: ([Any], AnyView) { - let viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, - pollDetails: PollDetails(type: .disclosed, - question: "", - answerOptions: ["", ""]))) + let viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, pollDetails: .default)) return ([viewModel], AnyView(PollEditForm(viewModel: viewModel.context))) } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index 9b87ce138..63761a53a 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -19,7 +19,7 @@ import Combine struct PollEditFormViewModelParameters { let mode: PollEditFormMode - let pollDetails: PollDetails + let pollDetails: EditFormPollDetails } @available(iOS 14, *) @@ -97,7 +97,7 @@ class PollEditFormViewModel: PollEditFormViewModelType { title: VectorL10n.pollEditFormPostFailureTitle, subtitle: VectorL10n.pollEditFormPostFailureSubtitle) case .failedUpdatingPoll: - state.bindings.alertInfo = PollEditFormErrorAlertInfo(id: .failedCreatingPoll, + state.bindings.alertInfo = PollEditFormErrorAlertInfo(id: .failedUpdatingPoll, title: VectorL10n.pollEditFormUpdateFailureTitle, subtitle: VectorL10n.pollEditFormUpdateFailureSubtitle) case .none: @@ -109,8 +109,8 @@ class PollEditFormViewModel: PollEditFormViewModelType { // MARK: - Private - private func buildPollDetails() -> PollDetails { - return PollDetails(type: state.bindings.type, + private func buildPollDetails() -> EditFormPollDetails { + return EditFormPollDetails(type: state.bindings.type, question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), answerOptions: state.bindings.answerOptions.compactMap({ answerOption in let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift index c62afc61f..662f12c1a 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/Test/Unit/PollEditFormViewModelTests.swift @@ -26,8 +26,7 @@ class PollEditFormViewModelTests: XCTestCase { var cancellables = Set() override func setUpWithError() throws { - viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, - pollDetails: PollDetails(type: .disclosed, question: "", answerOptions: ["", ""]))) + viewModel = PollEditFormViewModel(parameters: PollEditFormViewModelParameters(mode: .creation, pollDetails: .default)) context = viewModel.context } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift index 6bcb1e233..05a736b5d 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift @@ -35,7 +35,7 @@ struct PollEditForm: View { ScrollView { VStack(alignment: .leading, spacing: 32.0) { - PollEditFormTypeView(selectedType: $viewModel.type) + PollEditFormTypePicker(selectedType: $viewModel.type) VStack(alignment: .leading, spacing: 16.0) { Text(VectorL10n.pollEditFormPollQuestionOrTopic) diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift index ab74d8685..e3de14987 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormAnswerOptionView.swift @@ -39,9 +39,7 @@ struct PollEditFormAnswerOptionView: View { self.focused = edit }) .textFieldStyle(BorderedInputFieldStyle(theme: _theme, isEditing: focused)) - Button { - onDelete() - } label: { + Button(action: onDelete) { Image(uiImage:Asset.Images.pollDeleteOptionIcon.image) } .accessibilityIdentifier("Delete answer option") diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypePicker.swift similarity index 71% rename from RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift rename to RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypePicker.swift index 2858f7a89..590587d83 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypeView.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditFormTypePicker.swift @@ -17,28 +17,28 @@ import SwiftUI @available(iOS 14.0, *) -struct PollEditFormTypeView: View { +struct PollEditFormTypePicker: View { @Environment(\.theme) private var theme: ThemeSwiftUI - @Binding var selectedType: PollEditFormType + @Binding var selectedType: EditFormPollType var body: some View { VStack(alignment: .leading, spacing: 16.0) { Text(VectorL10n.pollEditFormPollType) .font(theme.fonts.title3SB) .foregroundColor(theme.colors.primaryContent) - PollTypeViewButton(type: .disclosed, selectedType: $selectedType) - PollTypeViewButton(type: .undisclosed, selectedType: $selectedType) + PollEditFormTypeButton(type: .disclosed, selectedType: $selectedType) + PollEditFormTypeButton(type: .undisclosed, selectedType: $selectedType) } } } @available(iOS 14.0, *) -private struct PollTypeViewButton: View { +private struct PollEditFormTypeButton: View { @Environment(\.theme) private var theme: ThemeSwiftUI - var type: PollEditFormType - @Binding var selectedType: PollEditFormType + let type: EditFormPollType + @Binding var selectedType: EditFormPollType var body: some View { Button { @@ -46,11 +46,7 @@ private struct PollTypeViewButton: View { } label: { HStack(alignment: .top, spacing: 8.0) { - if type == selectedType { - Image(uiImage: Asset.Images.pollTypeCheckboxSelected.image) - } else { - Image(uiImage: Asset.Images.pollTypeCheckboxDefault.image) - } + Image(uiImage: selectionImage) VStack(alignment: .leading, spacing: 2) { Text(title) @@ -81,14 +77,22 @@ private struct PollTypeViewButton: View { return VectorL10n.pollEditFormPollTypeClosedDescription } } -} - -@available(iOS 14.0, *) -struct PollEditFormTypeView_Previews: PreviewProvider { - static var previews: some View { - VStack { - PollEditFormTypeView(selectedType: Binding.constant(.disclosed)) - PollEditFormTypeView(selectedType: Binding.constant(.undisclosed)) + + private var selectionImage: UIImage { + if type == selectedType { + return Asset.Images.pollTypeCheckboxSelected.image + } else { + return Asset.Images.pollTypeCheckboxDefault.image + } + } +} + +@available(iOS 14.0, *) +struct PollEditFormTypePicker_Previews: PreviewProvider { + static var previews: some View { + VStack { + PollEditFormTypePicker(selectedType: Binding.constant(.disclosed)) + PollEditFormTypePicker(selectedType: Binding.constant(.undisclosed)) } } } diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift index 87a0db032..0851f71d2 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift @@ -52,7 +52,7 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel try pollAggregator = PollAggregator(session: parameters.session, room: parameters.room, pollStartEventId: parameters.pollStartEvent.eventId) pollAggregator.delegate = self - viewModel = TimelinePollViewModel(timelinePoll: buildTimelinePollFrom(pollAggregator.poll)) + viewModel = TimelinePollViewModel(timelinePollDetails: buildTimelinePollFrom(pollAggregator.poll)) viewModel.callback = { [weak self] result in guard let self = self else { return } @@ -95,7 +95,7 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel } func canEditPoll() -> Bool { - return (pollAggregator.poll.isClosed == false && pollAggregator.poll.totalAnswerCount == 0) + return pollAggregator.poll.isClosed == false && pollAggregator.poll.totalAnswerCount == 0 } func endPoll() { @@ -126,7 +126,7 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel // PollProtocol is intentionally not available in the SwiftUI target as we don't want // to add the SDK as a dependency to it. We need to translate from one to the other on this level. - func buildTimelinePollFrom(_ poll: PollProtocol) -> TimelinePoll { + func buildTimelinePollFrom(_ poll: PollProtocol) -> TimelinePollDetails { let answerOptions = poll.answerOptions.map { pollAnswerOption in TimelinePollAnswerOption(id: pollAnswerOption.id, text: pollAnswerOption.text, @@ -135,7 +135,7 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel selected: pollAnswerOption.isCurrentUserSelection) } - return TimelinePoll(question: poll.text, + return TimelinePollDetails(question: poll.text, answerOptions: answerOptions, closed: poll.isClosed, totalAnswerCount: poll.totalAnswerCount, diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift index 8b580f2a6..3de360418 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Test/Unit/TimelinePollViewModelTests.swift @@ -30,15 +30,15 @@ class TimelinePollViewModelTests: XCTestCase { TimelinePollAnswerOption(id: "2", text: "2", count: 1, winner: false, selected: false), TimelinePollAnswerOption(id: "3", text: "3", count: 1, winner: false, selected: false)] - let timelinePoll = TimelinePoll(question: "Question", - answerOptions: answerOptions, - closed: false, - totalAnswerCount: 3, - type: .disclosed, - maxAllowedSelections: 1, - hasBeenEdited: false) + let timelinePoll = TimelinePollDetails(question: "Question", + answerOptions: answerOptions, + closed: false, + totalAnswerCount: 3, + type: .disclosed, + maxAllowedSelections: 1, + hasBeenEdited: false) - viewModel = TimelinePollViewModel(timelinePoll: timelinePoll) + viewModel = TimelinePollViewModel(timelinePollDetails: timelinePoll) context = viewModel.context } diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift index af33cf012..da8abd7eb 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollModels.swift @@ -21,7 +21,7 @@ typealias TimelinePollViewModelCallback = ((TimelinePollViewModelResult) -> Void enum TimelinePollStateAction { case viewAction(TimelinePollViewAction, TimelinePollViewModelCallback?) - case updateWithPoll(TimelinePoll) + case updateWithPoll(TimelinePollDetails) case showAnsweringFailure case showClosingFailure } @@ -55,7 +55,7 @@ class TimelinePollAnswerOption: Identifiable { } } -class TimelinePoll { +class TimelinePollDetails { var question: String var answerOptions: [TimelinePollAnswerOption] var closed: Bool @@ -68,7 +68,8 @@ class TimelinePoll { closed: Bool, totalAnswerCount: UInt, type: TimelinePollType, - maxAllowedSelections: UInt, hasBeenEdited: Bool) { + maxAllowedSelections: UInt, + hasBeenEdited: Bool) { self.question = question self.answerOptions = answerOptions self.closed = closed @@ -81,10 +82,18 @@ class TimelinePoll { var hasCurrentUserVoted: Bool { answerOptions.filter { $0.selected == true}.count > 0 } + + var shouldDiscloseResults: Bool { + if closed { + return totalAnswerCount > 0 + } else { + return type == .disclosed && totalAnswerCount > 0 && hasCurrentUserVoted + } + } } struct TimelinePollViewState: BindableState { - var poll: TimelinePoll + var poll: TimelinePollDetails var bindings: TimelinePollViewStateBindings } diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift index fd8dcbb83..3fe93f8b8 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollScreenState.swift @@ -25,23 +25,23 @@ enum MockTimelinePollScreenState: MockScreenState, CaseIterable { case closedUndisclosed var screenType: Any.Type { - TimelinePoll.self + TimelinePollDetails.self } var screenView: ([Any], AnyView) { let answerOptions = [TimelinePollAnswerOption(id: "1", text: "First", count: 10, winner: false, selected: false), - TimelinePollAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true), - TimelinePollAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)] + TimelinePollAnswerOption(id: "2", text: "Second", count: 5, winner: false, selected: true), + TimelinePollAnswerOption(id: "3", text: "Third", count: 15, winner: true, selected: false)] - let poll = TimelinePoll(question: "Question", - answerOptions: answerOptions, - closed: (self == .closedDisclosed || self == .closedUndisclosed ? true : false), - totalAnswerCount: 20, - type: (self == .closedDisclosed || self == .openDisclosed ? .disclosed : .undisclosed), - maxAllowedSelections: 1, - hasBeenEdited: false) + let poll = TimelinePollDetails(question: "Question", + answerOptions: answerOptions, + closed: (self == .closedDisclosed || self == .closedUndisclosed ? true : false), + totalAnswerCount: 20, + type: (self == .closedDisclosed || self == .openDisclosed ? .disclosed : .undisclosed), + maxAllowedSelections: 1, + hasBeenEdited: false) - let viewModel = TimelinePollViewModel(timelinePoll: poll) + let viewModel = TimelinePollViewModel(timelinePollDetails: poll) return ([viewModel], AnyView(TimelinePollView(viewModel: viewModel.context))) } diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift index adbb110c4..f28c7185c 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/TimelinePollViewModel.swift @@ -34,8 +34,8 @@ class TimelinePollViewModel: TimelinePollViewModelType { // MARK: - Setup - init(timelinePoll: TimelinePoll) { - super.init(initialViewState: TimelinePollViewState(poll: timelinePoll, bindings: TimelinePollViewStateBindings())) + init(timelinePollDetails: TimelinePollDetails) { + super.init(initialViewState: TimelinePollViewState(poll: timelinePollDetails, bindings: TimelinePollViewStateBindings())) } // MARK: - Public diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift index e67139c88..7cd02911d 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/View/TimelinePollAnswerOptionButton.swift @@ -25,7 +25,7 @@ struct TimelinePollAnswerOptionButton: View { @Environment(\.theme) private var theme: ThemeSwiftUI - let poll: TimelinePoll + let poll: TimelinePollDetails let answerOption: TimelinePollAnswerOption let action: () -> Void @@ -65,12 +65,12 @@ struct TimelinePollAnswerOptionButton: View { if poll.type == .disclosed || poll.closed { HStack { - ProgressView(value: Double(shouldDiscloseResults ? answerOption.count : 0), + ProgressView(value: Double(poll.shouldDiscloseResults ? answerOption.count : 0), total: Double(poll.totalAnswerCount)) .progressViewStyle(LinearProgressViewStyle()) .scaleEffect(x: 1.0, y: 1.2, anchor: .center) - if (shouldDiscloseResults) { + if (poll.shouldDiscloseResults) { Text(answerOption.count == 1 ? VectorL10n.pollTimelineOneVote : VectorL10n.pollTimelineVotesCount(Int(answerOption.count))) .font(theme.fonts.footnote) .foregroundColor(poll.closed && answerOption.winner ? theme.colors.accent : theme.colors.secondaryContent) @@ -95,14 +95,6 @@ struct TimelinePollAnswerOptionButton: View { return answerOption.selected ? theme.colors.accent : theme.colors.quarterlyContent } - - private var shouldDiscloseResults: Bool { - if poll.closed { - return poll.totalAnswerCount > 0 - } else { - return poll.type == .disclosed && poll.totalAnswerCount > 0 && poll.hasCurrentUserVoted - } - } } @available(iOS 14.0, *) @@ -149,8 +141,8 @@ struct TimelinePollAnswerOptionButton_Previews: PreviewProvider { } } - static func buildPoll(closed: Bool, type: TimelinePollType) -> TimelinePoll { - TimelinePoll(question: "", + static func buildPoll(closed: Bool, type: TimelinePollType) -> TimelinePollDetails { + TimelinePollDetails(question: "", answerOptions: [], closed: closed, totalAnswerCount: 100, From 06c8f6029efdb1a7d83927a67e1f2ba1ce73f991 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 18 Jan 2022 13:57:50 +0200 Subject: [PATCH 143/209] vector-im/element-ios/issues/5114 - Small answer option count limit code tweak. --- RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift | 3 ++- .../Modules/Room/PollEditForm/PollEditFormViewModel.swift | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift index f8929bc38..346ba3d57 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormModels.swift @@ -81,13 +81,14 @@ struct PollEditFormAnswerOption: Identifiable, Equatable { } struct PollEditFormViewState: BindableState { + var minAnswerOptionsCount: Int var maxAnswerOptionsCount: Int var mode: PollEditFormMode var bindings: PollEditFormViewStateBindings var confirmationButtonEnabled: Bool { !bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty && - bindings.answerOptions.filter({ !$0.text.isEmpty }).count >= 2 + bindings.answerOptions.filter({ !$0.text.isEmpty }).count >= minAnswerOptionsCount } var addAnswerOptionButtonEnabled: Bool { diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index 63761a53a..3672fbb94 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -30,6 +30,7 @@ typealias PollEditFormViewModelType = StateStoreViewModel< PollEditFormViewState class PollEditFormViewModel: PollEditFormViewModelType { private struct Constants { + static let minAnswerOptionsCount = 2 static let maxAnswerOptionsCount = 20 static let maxQuestionLength = 340 static let maxAnswerOptionLength = 340 @@ -47,6 +48,7 @@ class PollEditFormViewModel: PollEditFormViewModelType { init(parameters: PollEditFormViewModelParameters) { let state = PollEditFormViewState( + minAnswerOptionsCount: Constants.minAnswerOptionsCount, maxAnswerOptionsCount: Constants.maxAnswerOptionsCount, mode: parameters.mode, bindings: PollEditFormViewStateBindings( From 459359a31efd1b2975d263e8c8722a49fdbff95d Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 18 Jan 2022 14:17:58 +0200 Subject: [PATCH 144/209] vector-im/element-ios/issues/5114 - De-labs-ed polls, disabled editing and undisclosed polls until platform parity. --- Riot/Managers/Settings/RiotSettings.swift | 5 +---- Riot/Modules/Room/RoomViewController.m | 2 +- .../Modules/Settings/SettingsViewController.m | 22 +------------------ .../PollEditForm/PollEditFormViewModel.swift | 10 ++++----- .../Room/PollEditForm/View/PollEditForm.swift | 3 ++- .../Coordinator/TimelinePollCoordinator.swift | 3 ++- 6 files changed, 12 insertions(+), 33 deletions(-) diff --git a/Riot/Managers/Settings/RiotSettings.swift b/Riot/Managers/Settings/RiotSettings.swift index 852dedae5..dd2abd40f 100644 --- a/Riot/Managers/Settings/RiotSettings.swift +++ b/Riot/Managers/Settings/RiotSettings.swift @@ -184,10 +184,7 @@ final class RiotSettings: NSObject { @UserDefault(key: "roomScreenAllowFilesAction", defaultValue: BuildSettings.roomScreenAllowFilesAction, storage: defaults) var roomScreenAllowFilesAction - - @UserDefault(key: "roomScreenAllowPollsAction", defaultValue: false, storage: defaults) - var roomScreenAllowPollsAction - + @UserDefault(key: "roomScreenAllowLocationAction", defaultValue: false, storage: defaults) var roomScreenAllowLocationAction diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 059c01be8..7c0926b9f 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2026,7 +2026,7 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [self roomInputToolbarViewDidTapFileUpload]; }]]; } - if (RiotSettings.shared.roomScreenAllowPollsAction) + if (BuildSettings.pollsEnabled) { [actionItems addObject:[[RoomActionItem alloc] initWithImage:[UIImage imageNamed:@"action_poll"] andAction:^{ MXStrongifyAndReturnIfNil(self); diff --git a/Riot/Modules/Settings/SettingsViewController.m b/Riot/Modules/Settings/SettingsViewController.m index 782d8a3d8..9b44220ea 100644 --- a/Riot/Modules/Settings/SettingsViewController.m +++ b/Riot/Modules/Settings/SettingsViewController.m @@ -163,8 +163,7 @@ typedef NS_ENUM(NSUInteger, ABOUT) typedef NS_ENUM(NSUInteger, LABS_ENABLE) { - LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX, - LABS_ENABLE_POLLS + LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX }; typedef NS_ENUM(NSUInteger, SECURITY) @@ -579,7 +578,6 @@ TableViewSectionsDelegate> { Section *sectionLabs = [Section sectionWithTag:SECTION_TAG_LABS]; [sectionLabs addRowWithTag:LABS_ENABLE_RINGING_FOR_GROUP_CALLS_INDEX]; - [sectionLabs addRowWithTag:LABS_ENABLE_POLLS]; sectionLabs.headerTitle = [VectorL10n settingsLabs]; if (sectionLabs.hasAnyRows) @@ -2464,19 +2462,6 @@ TableViewSectionsDelegate> cell = labelAndSwitchCell; } - - if (row == LABS_ENABLE_POLLS && BuildSettings.pollsEnabled) - { - MXKTableViewCellWithLabelAndSwitch *labelAndSwitchCell = [self getLabelAndSwitchCell:tableView forIndexPath:indexPath]; - - labelAndSwitchCell.mxkLabel.text = [VectorL10n settingsLabsEnabledPolls]; - labelAndSwitchCell.mxkSwitch.on = RiotSettings.shared.roomScreenAllowPollsAction; - labelAndSwitchCell.mxkSwitch.onTintColor = ThemeService.shared.theme.tintColor; - - [labelAndSwitchCell.mxkSwitch addTarget:self action:@selector(toggleEnablePolls:) forControlEvents:UIControlEventValueChanged]; - - cell = labelAndSwitchCell; - } } else if (section == SECTION_TAG_FLAIR) { @@ -3209,11 +3194,6 @@ TableViewSectionsDelegate> RiotSettings.shared.enableRingingForGroupCalls = sender.isOn; } -- (void)toggleEnablePolls:(UISwitch *)sender -{ - RiotSettings.shared.roomScreenAllowPollsAction = sender.isOn; -} - - (void)togglePinRoomsWithMissedNotif:(UISwitch *)sender { RiotSettings.shared.pinRoomsWithMissedNotificationsOnHome = sender.isOn; diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift index 3672fbb94..022b4b727 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/PollEditFormViewModel.swift @@ -113,10 +113,10 @@ class PollEditFormViewModel: PollEditFormViewModelType { private func buildPollDetails() -> EditFormPollDetails { return EditFormPollDetails(type: state.bindings.type, - question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), - answerOptions: state.bindings.answerOptions.compactMap({ answerOption in - let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) - return text.isEmpty ? nil : text - })) + question: state.bindings.question.text.trimmingCharacters(in: .whitespacesAndNewlines), + answerOptions: state.bindings.answerOptions.compactMap({ answerOption in + let text = answerOption.text.trimmingCharacters(in: .whitespacesAndNewlines) + return text.isEmpty ? nil : text + })) } } diff --git a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift index 05a736b5d..c4f4608e2 100644 --- a/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift +++ b/RiotSwiftUI/Modules/Room/PollEditForm/View/PollEditForm.swift @@ -35,7 +35,8 @@ struct PollEditForm: View { ScrollView { VStack(alignment: .leading, spacing: 32.0) { - PollEditFormTypePicker(selectedType: $viewModel.type) + // Intentionally disabled until platform parity. + // PollEditFormTypePicker(selectedType: $viewModel.type) VStack(alignment: .leading, spacing: 16.0) { Text(VectorL10n.pollEditFormPollQuestionOrTopic) diff --git a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift index 0851f71d2..e54fd8013 100644 --- a/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/TimelinePoll/Coordinator/TimelinePollCoordinator.swift @@ -95,7 +95,8 @@ final class TimelinePollCoordinator: Coordinator, Presentable, PollAggregatorDel } func canEditPoll() -> Bool { - return pollAggregator.poll.isClosed == false && pollAggregator.poll.totalAnswerCount == 0 + return false // Intentionally disabled until platform parity. + // return pollAggregator.poll.isClosed == false && pollAggregator.poll.totalAnswerCount == 0 } func endPoll() { From 468241e7ad4c7086d9c601f2535e258f04f5876f Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 18 Jan 2022 16:01:43 +0200 Subject: [PATCH 145/209] vector-im/element-ios/issues/5114 - Renamed unstable extensible audio key. --- Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m index c439bb54b..a0da54d62 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomDataSource.m @@ -2050,8 +2050,8 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) { [self removeEventWithEventId:eventId]; if (event.isVoiceMessage) { - NSNumber *duration = event.content[kMXMessageContentKeyExtensibleAudio][kMXMessageContentKeyExtensibleAudioDuration]; - NSArray *samples = event.content[kMXMessageContentKeyExtensibleAudio][kMXMessageContentKeyExtensibleAudioWaveform]; + NSNumber *duration = event.content[kMXMessageContentKeyExtensibleAudioMSC1767][kMXMessageContentKeyExtensibleAudioDuration]; + NSArray *samples = event.content[kMXMessageContentKeyExtensibleAudioMSC1767][kMXMessageContentKeyExtensibleAudioWaveform]; [self sendVoiceMessage:localFileURL mimeType:mimetype duration:duration.doubleValue samples:samples success:success failure:failure]; } else { From d216a4ba0f8245e82aa15cac97345616885579ed Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 19:35:30 +0100 Subject: [PATCH 146/209] Text message bubble cells: Fix call to super.setupViews --- .../Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m | 2 ++ .../Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m index fefdbb677..f4cfc616c 100644 --- a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Incoming/Common/MXKRoomIncomingTextMsgBubbleCell.m @@ -22,6 +22,8 @@ - (void)setupViews { + [super setupViews]; + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; [timelineConfiguration.currentStyle.cellLayoutUpdater setupLayoutForIncomingTextMessageCell:self]; diff --git a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m index 932b6095c..bf6c70ae8 100644 --- a/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/TextMessage/Outgoing/Common/MXKRoomOutgoingTextMsgBubbleCell.m @@ -22,6 +22,8 @@ - (void)setupViews { + [super setupViews]; + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; [timelineConfiguration.currentStyle.cellLayoutUpdater setupLayoutForOutgoingTextMessageCell:self]; From fc9e5c401fa6e6111f225e18d471a051a59e721d Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 20:46:34 +0100 Subject: [PATCH 147/209] RoomTimelineStyle: Add method to apply selected style. --- .../Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index b57f498ee..f851e02b2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -39,4 +39,7 @@ protocol RoomTimelineStyle { /// Indicate to merge or not event in timeline func canAddEvent(_ event: MXEvent, and roomState: MXRoomState, to cellData: MXKRoomBubbleCellData) -> Bool + + /// Apply selected or blurred style on cell + func applySelectedStyleIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) } From 51c7c673972f8b09d9c441e4af79856f290b88d1 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 20:46:59 +0100 Subject: [PATCH 148/209] PlainRoomTimelineStyle: Handle selected style. --- .../Styles/Plain/PlainRoomTimelineStyle.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index 4a5b812dc..0f08aba78 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -42,4 +42,20 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { func canAddEvent(_ event: MXEvent, and roomState: MXRoomState, to cellData: MXKRoomBubbleCellData) -> Bool { return true } + + func applySelectedStyleIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + + // Check whether the selected event belongs to this bubble + let selectedComponentIndex = cellData.selectedComponentIndex + if selectedComponentIndex != NSNotFound { + + let showTimestamp = cellData.showTimestampForSelectedComponent + + cell.selectComponent(UInt(selectedComponentIndex), + showEditButton: false, + showTimestamp: showTimestamp) + } else { + cell.blurred = true + } + } } From 46a793a93ce1fdde64a50a3cdeb838f9720b2754 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 20:49:13 +0100 Subject: [PATCH 149/209] BubbleRoomTimelineStyle: Handle selected style. --- .../Styles/Bubble/BubbleRoomTimelineStyle.swift | 15 +++++++++++++++ .../Styles/RoomTimelineCellDecorator.swift | 2 ++ 2 files changed, 17 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index 37bcee15a..57a74dacb 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -43,4 +43,19 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { return false } + func applySelectedStyleIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) { + + // Check whether the selected event belongs to this bubble + let selectedComponentIndex = cellData.selectedComponentIndex + if selectedComponentIndex != NSNotFound { + + cell.selectComponent(UInt(selectedComponentIndex), + showEditButton: false, + showTimestamp: false) + + self.cellDecorator.addTimestampLabel(toCell: cell, cellData: cellData) + } else { + cell.blurred = true + } + } } diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift index 4e8a09e31..89a665fe8 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellDecorator.swift @@ -23,6 +23,8 @@ protocol RoomTimelineCellDecorator { func addTimestampLabelIfNeeded(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) + func addTimestampLabel(toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData) + func addURLPreviewView(_ urlPreviewView: URLPreviewView, toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData, From b19253b3bd0a1592c2f88afec8c22318f4e50cb8 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 18 Jan 2022 20:51:59 +0100 Subject: [PATCH 150/209] RoomDataSource: Use RoomTimelineStyle to apply cell selection style. --- Riot/Modules/Room/DataSources/RoomDataSource.m | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index 3c68b8e13..0a3293b91 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -553,16 +553,7 @@ const CGFloat kTypingCellHeight = 24; // Check whether an event is currently selected: the other messages are then blurred if (_selectedEventId) { - // Check whether the selected event belongs to this bubble - NSInteger selectedComponentIndex = cellData.selectedComponentIndex; - if (selectedComponentIndex != NSNotFound) - { - [bubbleCell selectComponent:cellData.selectedComponentIndex showEditButton:NO showTimestamp:cellData.showTimestampForSelectedComponent]; - } - else - { - bubbleCell.blurred = YES; - } + [[RoomTimelineConfiguration shared].currentStyle applySelectedStyleIfNeededToCell:bubbleCell cellData:cellData]; } // Reset the marker if any From 1bf3e5179c89a23b6d9c96032cf4d65f6405ece9 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 18 Jan 2022 21:35:53 +0000 Subject: [PATCH 151/209] Specify source of alertView popup for selecting video/image size on upload --- Riot/Modules/Room/RoomViewController.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 10af1f3bc..d4961377d 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -2172,6 +2172,8 @@ const NSTimeInterval kResizeComposerAnimationDuration = .05; [MXSDKOptions sharedInstance].videoConversionPresetName = presetName; [roomInputToolbarView sendSelectedVideoAsset:videoAsset isPhotoLibraryAsset:isPhotoLibraryAsset]; }]; + compressionPrompt.popoverPresentationController.sourceView = roomInputToolbarView.attachMediaButton; + compressionPrompt.popoverPresentationController.sourceRect = roomInputToolbarView.attachMediaButton.bounds; [self presentViewController:compressionPrompt animated:YES completion:nil]; } From 12ce4ab250c3b5ec0ed52fb5bc1217a7c98b614b Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 18 Jan 2022 21:37:28 +0000 Subject: [PATCH 152/209] Create 5399.bugfix --- changelog.d/5399.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5399.bugfix diff --git a/changelog.d/5399.bugfix b/changelog.d/5399.bugfix new file mode 100644 index 000000000..015ecfc41 --- /dev/null +++ b/changelog.d/5399.bugfix @@ -0,0 +1 @@ +Fix crash when uploading a video on iPad when "Confirm size when sending" is enabled in settings. From 74026d7aebc107e43042ece0547746488c5a0c97 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 18 Jan 2022 22:13:10 +0000 Subject: [PATCH 153/209] Add `sideMenuShowInviteFriends` and remove the non functioning `settingsScreenShowInviteFriends` --- Config/BuildSettings.swift | 5 +++-- Riot/Modules/SideMenu/SideMenuViewModel.swift | 9 +++++++-- changelog.d/5402.bugfix | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 changelog.d/5402.bugfix diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 98483d53f..a4bb7eae1 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -213,8 +213,10 @@ final class BuildSettings: NSObject { static let allowInviteExernalUsers: Bool = true + // MARK: - Side Menu static let enableSideMenu: Bool = true - + static let sideMenuShowInviteFriends: Bool = true + /// Whether to read the `io.element.functional_members` state event and exclude any service members when computing a room's name and avatar. static let supportFunctionalMembers: Bool = true @@ -261,7 +263,6 @@ final class BuildSettings: NSObject { static let settingsScreenAllowBugReportingManually: Bool = true static let settingsScreenAllowDeactivatingAccount: Bool = true static let settingsScreenShowChangePassword:Bool = true - static let settingsScreenShowInviteFriends:Bool = true static let settingsScreenShowEnableStunServerFallback: Bool = true static let settingsScreenShowNotificationDecodedContentOption: Bool = true static let settingsScreenShowNsfwRoomsOption: Bool = true diff --git a/Riot/Modules/SideMenu/SideMenuViewModel.swift b/Riot/Modules/SideMenu/SideMenuViewModel.swift index c8baac060..7c9d128ee 100644 --- a/Riot/Modules/SideMenu/SideMenuViewModel.swift +++ b/Riot/Modules/SideMenu/SideMenuViewModel.swift @@ -97,8 +97,13 @@ final class SideMenuViewModel: SideMenuViewModelType { return } - let sideMenuItems: [SideMenuItem] = [ - .inviteFriends, + var sideMenuItems: [SideMenuItem] = [] + + if BuildSettings.sideMenuShowInviteFriends { + sideMenuItems += [.inviteFriends] + } + + sideMenuItems += [ .settings, .help, .feedback diff --git a/changelog.d/5402.bugfix b/changelog.d/5402.bugfix new file mode 100644 index 000000000..44e0c482e --- /dev/null +++ b/changelog.d/5402.bugfix @@ -0,0 +1 @@ +Fix BuildSetting to show/hide the "Invite Friends" button in the side SideMenu. From 79fd2e3ec47c8e9f817e50480f893c3fa8998746 Mon Sep 17 00:00:00 2001 From: David Langley Date: Tue, 18 Jan 2022 22:36:50 +0000 Subject: [PATCH 154/209] Add build setting to hide social login --- Config/BuildSettings.swift | 1 + Riot/Modules/Authentication/AuthenticationViewController.m | 7 ++++--- changelog.d/5404.bugfix | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 changelog.d/5404.bugfix diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 98483d53f..ee6af5707 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -349,6 +349,7 @@ final class BuildSettings: NSObject { static let authScreenShowPhoneNumber = true static let authScreenShowForgotPassword = true static let authScreenShowCustomServerOptions = true + static let authScreenShowSocialLoginSection = true // MARK: - Unified Search static let unifiedSearchScreenShowPublicDirectory = true diff --git a/Riot/Modules/Authentication/AuthenticationViewController.m b/Riot/Modules/Authentication/AuthenticationViewController.m index 67b2a9e8b..3a859b7d5 100644 --- a/Riot/Modules/Authentication/AuthenticationViewController.m +++ b/Riot/Modules/Authentication/AuthenticationViewController.m @@ -482,7 +482,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0; // Hide input view when there is only social login actions to present if ((self.authType == MXKAuthenticationTypeLogin || self.authType == MXKAuthenticationTypeRegister) && self.currentLoginSSOFlow - && !self.isAuthSessionContainsPasswordFlow) + && !self.isAuthSessionContainsPasswordFlow + && BuildSettings.authScreenShowSocialLoginSection) { hideAuthInputView = YES; } @@ -1735,8 +1736,8 @@ static const CGFloat kAuthInputContainerViewMinHeightConstraintConstant = 150.0; - (void)updateSocialLoginViewVisibility { SocialLoginButtonMode socialLoginButtonMode = SocialLoginButtonModeContinue; - - BOOL showSocialLoginView = self.currentLoginSSOFlow ? YES : NO; + + BOOL showSocialLoginView = BuildSettings.authScreenShowSocialLoginSection && (self.currentLoginSSOFlow ? YES : NO); switch (self.authType) { diff --git a/changelog.d/5404.bugfix b/changelog.d/5404.bugfix new file mode 100644 index 000000000..1c829a4f0 --- /dev/null +++ b/changelog.d/5404.bugfix @@ -0,0 +1 @@ +Add BuildSetting to hide social login in favour of the simple SSO button. From 6e424dc85404961504fd5ca53a8e90e033db1fa9 Mon Sep 17 00:00:00 2001 From: David Langley Date: Wed, 19 Jan 2022 09:48:16 +0000 Subject: [PATCH 155/209] Change HomeViewControllerWithBannerWrapperViewController to MXKViewControllerActivityHandling conformance. --- Riot/Modules/Application/LegacyAppDelegate.m | 14 +++++++------ ...ollerWithBannerWrapperViewController.swift | 20 ++++++++++++++++++- changelog.d/5407.bugfix | 1 + 3 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 changelog.d/5407.bugfix diff --git a/Riot/Modules/Application/LegacyAppDelegate.m b/Riot/Modules/Application/LegacyAppDelegate.m index fd6354ad3..fc7e503a2 100644 --- a/Riot/Modules/Application/LegacyAppDelegate.m +++ b/Riot/Modules/Application/LegacyAppDelegate.m @@ -1372,9 +1372,9 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni else { void(^findRoom)(void) = ^{ - if ([_masterTabBarController.selectedViewController isKindOfClass:MXKActivityHandlingViewController.class]) + if ([_masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)]) { - MXKActivityHandlingViewController *homeViewController = (MXKActivityHandlingViewController*)_masterTabBarController.selectedViewController; + UIViewController *homeViewController = (UIViewController*)_masterTabBarController.selectedViewController; [homeViewController startActivityIndicator]; @@ -1651,11 +1651,13 @@ NSString *const AppDelegateUniversalLinkDidChangeNotification = @"AppDelegateUni // Try to get more information about the room before opening its preview [roomPreviewData peekInRoom:^(BOOL succeeded) { MXStrongifyAndReturnIfNil(self); - - MXKViewController *homeViewController = (MXKViewController*)self.masterTabBarController.selectedViewController; + if ([self.masterTabBarController.selectedViewController conformsToProtocol:@protocol(MXKViewControllerActivityHandling)]) + { + UIViewController *homeViewController = (UIViewController*)self.masterTabBarController.selectedViewController; - // Note: the activity indicator will not disappear if the session is not ready - [homeViewController stopActivityIndicator]; + // Note: the activity indicator will not disappear if the session is not ready + [homeViewController stopActivityIndicator]; + } // If no data is available for this room, we name it with the known room alias (if any). if (!succeeded && self->universalLinkFragmentPendingRoomAlias[roomIdOrAlias]) diff --git a/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift b/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift index 85abec4d1..764dc2d59 100644 --- a/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift +++ b/Riot/Modules/Home/VersionCheck/HomeViewControllerWithBannerWrapperViewController.swift @@ -16,7 +16,7 @@ import Foundation -class HomeViewControllerWithBannerWrapperViewController: MXKActivityHandlingViewController, BannerPresentationProtocol { +class HomeViewControllerWithBannerWrapperViewController: UIViewController, MXKViewControllerActivityHandling, BannerPresentationProtocol { @objc let homeViewController: HomeViewController private var bannerContainerView: UIView! @@ -85,4 +85,22 @@ class HomeViewControllerWithBannerWrapperViewController: MXKActivityHandlingView bannerView.removeFromSuperview() } } + + // MARK: - MXKViewControllerActivityHandling + var activityIndicator: UIActivityIndicatorView! { + get { + return homeViewController.activityIndicator + } + set { + homeViewController.activityIndicator = newValue + } + } + + func startActivityIndicator() { + homeViewController.startActivityIndicator() + } + + func stopActivityIndicator() { + homeViewController.stopActivityIndicator() + } } diff --git a/changelog.d/5407.bugfix b/changelog.d/5407.bugfix new file mode 100644 index 000000000..f4ed72863 --- /dev/null +++ b/changelog.d/5407.bugfix @@ -0,0 +1 @@ +Fix grey spinner showing indefinitely over the home view after launch. From 7a4efa6bbf5e07d4c77472715ce1f15150a9810a Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 19 Jan 2022 11:46:36 +0100 Subject: [PATCH 156/209] BubbleRoomCellLayoutUpdater: Update bubble height methods. --- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 73 +++++++++++++------ 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 3fc2bf8fa..eef734079 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -157,48 +157,77 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { } private func getTextMessageHeight(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> CGFloat? { - + guard let roomBubbleCellData = cellData as? RoomBubbleCellData, let lastBubbleComponent = cellData.getLastBubbleComponentWithDisplay(), let firstComponent = roomBubbleCellData.getFirstBubbleComponentWithDisplay() else { return nil } - + let bubbleHeight: CGFloat - let bottomMargin: CGFloat = 4.0 - + let lastEventId = lastBubbleComponent.event.eventId let lastMessageBottomPosition = cell.bottomPosition(ofEvent: lastEventId) - + let firstEventId = firstComponent.event.eventId let firstMessageTopPosition = cell.topPosition(ofEvent: firstEventId) - + let additionalContentHeight = roomBubbleCellData.additionalContentHeight - - bubbleHeight = lastMessageBottomPosition - firstMessageTopPosition - additionalContentHeight + bottomMargin - + + bubbleHeight = lastMessageBottomPosition - firstMessageTopPosition - additionalContentHeight + guard bubbleHeight >= 0 else { return nil } - + return bubbleHeight } + // TODO: Improve text message height calculation + // This method is closer to final result but lack of stability because of extra vertical space not handled here. +// private func getTextMessageHeight(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> CGFloat? { +// +// guard let roomBubbleCellData = cellData as? RoomBubbleCellData, +// let firstComponent = roomBubbleCellData.getFirstBubbleComponentWithDisplay() else { +// return nil +// } +// +// let bubbleHeight: CGFloat +// +// let componentIndex = cellData.bubbleComponentIndex(forEventId: firstComponent.event.eventId) +// +// let componentFrame = cell.componentFrameInContentView(for: componentIndex) +// +// bubbleHeight = componentFrame.height +// +// guard bubbleHeight >= 0 else { +// return nil +// } +// +// return bubbleHeight +// } + + private func getMessageBubbleBackgroundHeight(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> CGFloat? { + + var finalBubbleHeight: CGFloat? + let extraMargin = 4.0 + + if let bubbleHeight = self.getTextMessageHeight(for: cell, andCellData: cellData) { + finalBubbleHeight = bubbleHeight + extraMargin + + } else if let messageTextViewHeight = cell.messageTextView?.frame.height { + + finalBubbleHeight = messageTextViewHeight + extraMargin + } + + return finalBubbleHeight + } + @discardableResult private func updateMessageBubbleBackgroundView(_ roomMessageBubbleBackgroundView: RoomMessageBubbleBackgroundView, withCell cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> Bool { - var finalBubbleHeight: CGFloat? - - if let bubbleHeight = self.getTextMessageHeight(for: cell, andCellData: cellData) { - finalBubbleHeight = bubbleHeight - - } else if let messageTextViewHeight = cell.messageTextView?.frame.height { - - finalBubbleHeight = messageTextViewHeight - } - - if let finalBubbleHeight = finalBubbleHeight { - return roomMessageBubbleBackgroundView.updateHeight(finalBubbleHeight) + if let bubbleHeight = self.getMessageBubbleBackgroundHeight(for: cell, andCellData: cellData) { + return roomMessageBubbleBackgroundView.updateHeight(bubbleHeight) } else { return false } From 5b93056017bcbd29fcba1b0785d7a4b1e5fb252a Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 19 Jan 2022 12:08:40 +0100 Subject: [PATCH 157/209] Update changes. --- changelog.d/5208.feature | 1 + changelog.d/5212.feature | 1 + changelog.d/5214.feature | 1 + 3 files changed, 3 insertions(+) create mode 100644 changelog.d/5208.feature create mode 100644 changelog.d/5212.feature create mode 100644 changelog.d/5214.feature diff --git a/changelog.d/5208.feature b/changelog.d/5208.feature new file mode 100644 index 000000000..1883900f3 --- /dev/null +++ b/changelog.d/5208.feature @@ -0,0 +1 @@ +Message bubbles: Text message layout. \ No newline at end of file diff --git a/changelog.d/5212.feature b/changelog.d/5212.feature new file mode 100644 index 000000000..abb4530c7 --- /dev/null +++ b/changelog.d/5212.feature @@ -0,0 +1 @@ +Message Bubbles: Support URL Previews. \ No newline at end of file diff --git a/changelog.d/5214.feature b/changelog.d/5214.feature new file mode 100644 index 000000000..31d4c5a0e --- /dev/null +++ b/changelog.d/5214.feature @@ -0,0 +1 @@ +Message Bubbles: Support reactions. \ No newline at end of file From 1fdf364686f6afe90d3fc15354735306119eaab8 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Tue, 18 Jan 2022 11:32:30 +0200 Subject: [PATCH 158/209] vector-im/element-ios/issues/5298 - Add support for location `m.asset` types. --- .../Contents.json | 3 +++ ...kerView.swift => LocationMarkerView.swift} | 2 +- ...rMarkerView.xib => LocationMarkerView.xib} | 12 +++++++++- .../Location/RoomTimelineLocationView.swift | 22 ++++++++----------- .../Location/RoomTimelineLocationView.xib | 1 + .../Location/LocationBubbleCell.swift | 16 +++++++++----- 6 files changed, 36 insertions(+), 20 deletions(-) rename Riot/Modules/Room/Location/{LocationUserMarkerView.swift => LocationMarkerView.swift} (93%) rename Riot/Modules/Room/Location/{LocationUserMarkerView.xib => LocationMarkerView.xib} (77%) diff --git a/Riot/Assets/Images.xcassets/Room/Location/location_marker_icon.imageset/Contents.json b/Riot/Assets/Images.xcassets/Room/Location/location_marker_icon.imageset/Contents.json index 707b2f06b..0bf02ac7f 100644 --- a/Riot/Assets/Images.xcassets/Room/Location/location_marker_icon.imageset/Contents.json +++ b/Riot/Assets/Images.xcassets/Room/Location/location_marker_icon.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } } diff --git a/Riot/Modules/Room/Location/LocationUserMarkerView.swift b/Riot/Modules/Room/Location/LocationMarkerView.swift similarity index 93% rename from Riot/Modules/Room/Location/LocationUserMarkerView.swift rename to Riot/Modules/Room/Location/LocationMarkerView.swift index 995d1ae56..caf101a1b 100644 --- a/Riot/Modules/Room/Location/LocationUserMarkerView.swift +++ b/Riot/Modules/Room/Location/LocationMarkerView.swift @@ -18,7 +18,7 @@ import UIKit import Reusable import Mapbox -class LocationUserMarkerView: MGLAnnotationView, NibLoadable { +class LocationMarkerView: MGLAnnotationView, NibLoadable { @IBOutlet private var avatarView: UserAvatarView! diff --git a/Riot/Modules/Room/Location/LocationUserMarkerView.xib b/Riot/Modules/Room/Location/LocationMarkerView.xib similarity index 77% rename from Riot/Modules/Room/Location/LocationUserMarkerView.xib rename to Riot/Modules/Room/Location/LocationMarkerView.xib index 26495f925..8c4339ffa 100644 --- a/Riot/Modules/Room/Location/LocationUserMarkerView.xib +++ b/Riot/Modules/Room/Location/LocationMarkerView.xib @@ -10,12 +10,21 @@ - + + + + + + + + + + @@ -41,6 +50,7 @@ + diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift index 82cebe7cd..a4a8bb635 100644 --- a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift +++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift @@ -36,9 +36,10 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat @IBOutlet private var descriptionContainerView: UIView! @IBOutlet private var descriptionLabel: UILabel! + @IBOutlet private var descriptionIcon: UIImageView! private var mapView: MGLMapView! - private var annotationView: LocationUserMarkerView? + private var annotationView: LocationMarkerView? // MARK: Public @@ -73,19 +74,13 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat // MARK: - Public - public func displayLocation(_ location: CLLocationCoordinate2D, - userIdentifier: String, - userDisplayName: String, - userAvatarURLString: String?, - mediaManager: MXMediaManager) { - - annotationView = LocationUserMarkerView.loadFromNib() + public func displayLocation(_ location: CLLocationCoordinate2D, userAvatarData: AvatarViewData? = nil) { - annotationView?.setAvatarData(AvatarViewData(matrixItemId: userIdentifier, - displayName: userDisplayName, - avatarUrl: userAvatarURLString, - mediaManager: mediaManager, - fallbackImage: .matrixItem(userIdentifier, userDisplayName))) + annotationView = LocationMarkerView.loadFromNib() + + if let userAvatarData = userAvatarData { + annotationView?.setAvatarData(userAvatarData) + } if let annotations = mapView.annotations { mapView.removeAnnotations(annotations) @@ -103,6 +98,7 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat func update(theme: Theme) { descriptionLabel.textColor = theme.colors.primaryContent descriptionLabel.font = theme.fonts.footnote + descriptionIcon.tintColor = theme.colors.accent layer.borderColor = theme.colors.quinaryContent.cgColor } diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.xib b/Riot/Modules/Room/Location/RoomTimelineLocationView.xib index 8beacacbe..acc469b74 100644 --- a/Riot/Modules/Room/Location/RoomTimelineLocationView.xib +++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.xib @@ -58,6 +58,7 @@ + diff --git a/Riot/Modules/Room/Views/BubbleCells/Location/LocationBubbleCell.swift b/Riot/Modules/Room/Views/BubbleCells/Location/LocationBubbleCell.swift index 2795d2647..cb56e7839 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Location/LocationBubbleCell.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Location/LocationBubbleCell.swift @@ -37,11 +37,17 @@ class LocationBubbleCell: SizableBaseBubbleCell, BubbleCellReactionsDisplayable let location = CLLocationCoordinate2D(latitude: locationContent.latitude, longitude: locationContent.longitude) - locationView.displayLocation(location, - userIdentifier: bubbleData.senderId, - userDisplayName: bubbleData.senderDisplayName, - userAvatarURLString: bubbleData.senderAvatarUrl, - mediaManager: bubbleData.mxSession.mediaManager) + if locationContent.assetType == .user { + let avatarViewData = AvatarViewData(matrixItemId: bubbleData.senderId, + displayName: bubbleData.senderDisplayName, + avatarUrl: bubbleData.senderAvatarUrl, + mediaManager: bubbleData.mxSession.mediaManager, + fallbackImage: .matrixItem(bubbleData.senderId, bubbleData.senderDisplayName)) + + locationView.displayLocation(location, userAvatarData: avatarViewData) + } else { + locationView.displayLocation(location) + } } override func setupViews() { From 8ea122b1a65c7e06152c28ac84adac84ce4ea460 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 19 Jan 2022 11:48:44 +0200 Subject: [PATCH 159/209] vector-im/element-ios/issues/5298 - Added bottom padding on location markers so they point to the location instead of being centered on it. --- .../Room/Location/LocationMarkerView.xib | 66 ++++++++++++------- .../View/LocationSharingUserMarkerView.swift | 6 +- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/Riot/Modules/Room/Location/LocationMarkerView.xib b/Riot/Modules/Room/Location/LocationMarkerView.xib index 8c4339ffa..837db5503 100644 --- a/Riot/Modules/Room/Location/LocationMarkerView.xib +++ b/Riot/Modules/Room/Location/LocationMarkerView.xib @@ -4,41 +4,61 @@ - - - + + - + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + + + @@ -46,7 +66,7 @@ - + diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift index 0727e0b5b..7c8729aac 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift @@ -25,16 +25,20 @@ struct LocationSharingUserMarkerView: View { @Environment(\.theme) private var theme: ThemeSwiftUI + @State var frame: CGRect = .zero + // MARK: Public let avatarData: AvatarInputProtocol var body: some View { - ZStack(alignment: .center) { + ZStack { Image(uiImage: Asset.Images.locationUserMarker.image) AvatarImage(avatarData: avatarData, size: .large) .offset(.init(width: 0.0, height: -1.5)) } + .background(ViewFrameReader(frame: $frame)) + .padding(.bottom, frame.height) .accentColor(theme.colors.accent) } } From 9f72ba51383f70acf69d8f419d7efa08f8483b50 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 19 Jan 2022 13:06:26 +0200 Subject: [PATCH 160/209] vector-im/element-ios/issues/5298 - Removed cocoapods-keys and moved the MapTiler key to the buildSettings. --- .github/workflows/ci-build.yml | 1 - .github/workflows/ci-tests.yml | 1 - .github/workflows/release-alpha.yml | 1 - Config/BuildSettings.swift | 3 +-- Gemfile | 1 - Gemfile.lock | 11 +---------- Podfile | 5 ----- Podfile.lock | 9 ++------- .../Room/Location/RoomTimelineLocationView.swift | 2 -- .../Coordinator/LocationSharingCoordinator.swift | 1 - .../LocationSharing/LocationSharingScreenState.swift | 3 +-- 11 files changed, 5 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 68a169237..24e8ab2e6 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -11,7 +11,6 @@ on: env: # Make the git branch for a PR available to our Fastfile MX_GIT_BRANCH: ${{ github.event.pull_request.head.ref }} - MapTilerAPIKey: ${{ secrets.MAPTILER_API_KEY }} jobs: build: diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 3fcc19ed3..00d4fa2f9 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -12,7 +12,6 @@ on: env: # Make the git branch for a PR available to our Fastfile MX_GIT_BRANCH: ${{ github.event.pull_request.head.ref }} - MapTilerAPIKey: ${{ secrets.MAPTILER_API_KEY }} jobs: tests: diff --git a/.github/workflows/release-alpha.yml b/.github/workflows/release-alpha.yml index 7ab8b331d..dfbd7ac6a 100644 --- a/.github/workflows/release-alpha.yml +++ b/.github/workflows/release-alpha.yml @@ -11,7 +11,6 @@ on: env: # Make the git branch for a PR available to our Fastfile MX_GIT_BRANCH: ${{ github.event.pull_request.head.ref }} - MapTilerAPIKey: ${{ secrets.MAPTILER_API_KEY }} jobs: build: diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index fda0e436f..3f3e1c15c 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -15,7 +15,6 @@ // import Foundation -import Keys /// BuildSettings provides settings computed at build time. /// In future, it may be automatically generated from xcconfig files @@ -370,7 +369,7 @@ final class BuildSettings: NSObject { // MARK: - Location Sharing - static let tileServerMapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=" + RiotKeys().mapTilerAPIKey)! + static let tileServerMapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")! static var locationSharingEnabled: Bool { guard #available(iOS 14, *) else { diff --git a/Gemfile b/Gemfile index ea061a17e..53efbaf92 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,6 @@ source "https://rubygems.org" gem "xcode-install" gem "fastlane" gem "cocoapods", '~>1.11.2' -gem "cocoapods-keys" plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/Gemfile.lock b/Gemfile.lock index 78fe028a3..610cbbadd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,9 +3,6 @@ GEM specs: CFPropertyList (3.0.5) rexml - RubyInline (3.12.5) - ZenTest (~> 4.3) - ZenTest (4.12.0) activesupport (6.1.4.4) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) @@ -67,9 +64,6 @@ GEM typhoeus (~> 1.0) cocoapods-deintegrate (1.0.5) cocoapods-downloader (1.5.1) - cocoapods-keys (2.2.1) - dotenv - osx_keychain cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.1) @@ -231,8 +225,6 @@ GEM netrc (0.11.0) optparse (0.1.1) os (1.1.4) - osx_keychain (1.0.2) - RubyInline (~> 3) plist (3.6.0) public_suffix (4.0.6) rake (13.0.6) @@ -300,7 +292,6 @@ PLATFORMS DEPENDENCIES cocoapods (~> 1.11.2) - cocoapods-keys fastlane fastlane-plugin-diawi fastlane-plugin-versioning @@ -308,4 +299,4 @@ DEPENDENCIES xcode-install BUNDLED WITH - 2.2.28 + 2.2.32 diff --git a/Podfile b/Podfile index 6a5620b94..1898c52bb 100644 --- a/Podfile +++ b/Podfile @@ -129,11 +129,6 @@ abstract_target 'RiotPods' do end -plugin 'cocoapods-keys', { - :project => "Riot", - :keys => ["MapTilerAPIKey"] -} - post_install do |installer| installer.pods_project.targets.each do |target| diff --git a/Podfile.lock b/Podfile.lock index 749fe065f..8d3206d35 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -49,7 +49,6 @@ PODS: - Introspect (0.1.3) - JitsiMeetSDK (3.10.2) - KeychainAccess (4.2.2) - - Keys (1.0.1) - KituraContracts (1.2.1): - LoggerAPI (~> 1.7) - KTCenterFlowLayout (1.3.1) @@ -115,7 +114,6 @@ DEPENDENCIES: - HPGrowingTextView (~> 1.1) - Introspect (~> 0.1) - KeychainAccess (~> 4.2.2) - - Keys (from `Pods/CocoaPodsKeys`) - KTCenterFlowLayout (~> 1.3.1) - libPhoneNumber-iOS (~> 0.9.13) - MatrixSDK (= 0.20.16) @@ -179,12 +177,10 @@ EXTERNAL SOURCES: AnalyticsEvents: :branch: release/swift :git: https://github.com/matrix-org/matrix-analytics-events.git - Keys: - :path: Pods/CocoaPodsKeys CHECKOUT OPTIONS: AnalyticsEvents: - :commit: f1805ad7c3fafa7fd9c6e2eaa9e0165f8142ecd2 + :commit: 8058dc6ec07ce0acfe5fdb19eb7e309b0c13845c :git: https://github.com/matrix-org/matrix-analytics-events.git SPEC CHECKSUMS: @@ -207,7 +203,6 @@ SPEC CHECKSUMS: Introspect: 2be020f30f084ada52bb4387fff83fa52c5c400e JitsiMeetSDK: 2f118fa770f23e518f3560fc224fae3ac7062223 KeychainAccess: c0c4f7f38f6fc7bbe58f5702e25f7bd2f65abf51 - Keys: a576f4c9c1c641ca913a959a9c62ed3f215a8de9 KituraContracts: e845e60dc8627ad0a76fa55ef20a45451d8f830b KTCenterFlowLayout: 6e02b50ab2bd865025ae82fe266ed13b6d9eaf97 libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd @@ -230,6 +225,6 @@ SPEC CHECKSUMS: zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb -PODFILE CHECKSUM: 2493587902f8f28bb2638303dd583c47e9f24d8b +PODFILE CHECKSUM: c9a50c445e32b40b22fadd0f54b376f1bd624ebb COCOAPODS: 1.11.2 diff --git a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift index a4a8bb635..17ee83b4c 100644 --- a/Riot/Modules/Room/Location/RoomTimelineLocationView.swift +++ b/Riot/Modules/Room/Location/RoomTimelineLocationView.swift @@ -17,7 +17,6 @@ import UIKit import Reusable import Mapbox -import Keys class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegate { @@ -25,7 +24,6 @@ class RoomTimelineLocationView: UIView, NibLoadable, Themable, MGLMapViewDelegat private struct Constants { static let mapHeight: CGFloat = 300.0 - static let mapTilerKey = RiotKeys().mapTilerAPIKey static let mapZoomLevel = 15.0 static let cellBorderRadius: CGFloat = 1.0 static let cellCornerRadius: CGFloat = 8.0 diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift index 931c6a3d7..471187dd5 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/Coordinator/LocationSharingCoordinator.swift @@ -17,7 +17,6 @@ import Foundation import UIKit import SwiftUI -import Keys struct LocationSharingCoordinatorParameters { let roomDataSource: MXKRoomDataSource diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift index 386471b02..fd4ca6a4a 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/LocationSharingScreenState.swift @@ -16,7 +16,6 @@ import Foundation import SwiftUI -import Keys import CoreLocation @available(iOS 14.0, *) @@ -35,7 +34,7 @@ enum MockLocationSharingScreenState: MockScreenState, CaseIterable { location = CLLocationCoordinate2D(latitude: 51.4932641, longitude: -0.257096) } - let mapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=" + RiotKeys().mapTilerAPIKey)! + let mapURL = URL(string: "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx")! let viewModel = LocationSharingViewModel(tileServerMapURL: mapURL, avatarData: AvatarInput(mxContentUri: "", matrixItemId: "", displayName: "Alice"), location: location) From b375c31c25b2d44a28526e112c4c359b34076110 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 19 Jan 2022 13:19:45 +0200 Subject: [PATCH 161/209] vector-im/element-ios/issues/5298 - Added changelog entry. --- changelog.d/5298.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5298.feature diff --git a/changelog.d/5298.feature b/changelog.d/5298.feature new file mode 100644 index 000000000..605f18e07 --- /dev/null +++ b/changelog.d/5298.feature @@ -0,0 +1 @@ +Added static location sharing sending and rendering support. \ No newline at end of file From 23d58c0cc9350ff0203ede60937045770e13695d Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Wed, 19 Jan 2022 16:10:08 +0200 Subject: [PATCH 162/209] vector-im/element-ios/issues/5298 - Small tweaks following code review. --- .../LocationSharing/View/LocationSharingUserMarkerView.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift index 7c8729aac..26bc101d3 100644 --- a/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift +++ b/RiotSwiftUI/Modules/Room/LocationSharing/View/LocationSharingUserMarkerView.swift @@ -25,7 +25,7 @@ struct LocationSharingUserMarkerView: View { @Environment(\.theme) private var theme: ThemeSwiftUI - @State var frame: CGRect = .zero + @State private var frame: CGRect = .zero // MARK: Public @@ -35,7 +35,7 @@ struct LocationSharingUserMarkerView: View { ZStack { Image(uiImage: Asset.Images.locationUserMarker.image) AvatarImage(avatarData: avatarData, size: .large) - .offset(.init(width: 0.0, height: -1.5)) + .offset(y: -1.5) } .background(ViewFrameReader(frame: $frame)) .padding(.bottom, frame.height) From 95bff0e3d2c292443e67141190f5261355afca23 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Wed, 19 Jan 2022 15:44:20 +0100 Subject: [PATCH 163/209] PlainRoomTimelineCellProvider: Fix missing outgoing attachment cells. --- .../BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m index 85f6711c2..58a460dfe 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -278,7 +278,7 @@ NSDictionary *incomingAttachmentCellsMapping = [self incomingAttachmentCellsMapping]; [cellClasses addEntriesFromDictionary:incomingAttachmentCellsMapping]; - NSDictionary *outgoingAttachmentCellsMapping = [self outgoingTextMessageCellsMapping]; + NSDictionary *outgoingAttachmentCellsMapping = [self outgoingAttachmentCellsMapping]; [cellClasses addEntriesFromDictionary:outgoingAttachmentCellsMapping]; // Other cells From 3656824cd6796f80dc9c7c2872f9d37049d36176 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 14:46:29 +0100 Subject: [PATCH 164/209] BubbleReactionsView: Fix typos. --- .../Room/BubbleReactions/BubbleReactionsView.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift b/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift index 844f79db9..8248786a5 100644 --- a/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift +++ b/Riot/Modules/Room/BubbleReactions/BubbleReactionsView.swift @@ -20,8 +20,8 @@ import Reusable import DGCollectionViewLeftAlignFlowLayout import UIKit -/// BubbleReactionsView items alignement -enum BubbleReactionsViewAlignement { +/// BubbleReactionsView items alignment +enum BubbleReactionsViewAlignment { case left case right } @@ -58,7 +58,7 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { } } - var alignment: BubbleReactionsViewAlignement = .left { + var alignment: BubbleReactionsViewAlignment = .left { didSet { self.updateCollectionViewLayout(for: alignment) } @@ -107,9 +107,9 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { self.collectionView.reloadData() } - private func updateCollectionViewLayout(for alignement: BubbleReactionsViewAlignement) { + private func updateCollectionViewLayout(for alignment: BubbleReactionsViewAlignment) { - let collectionViewLayout = self.collectionViewLayout(for: alignement) + let collectionViewLayout = self.collectionViewLayout(for: alignment) self.collectionView.collectionViewLayout = collectionViewLayout @@ -123,7 +123,7 @@ final class BubbleReactionsView: UIView, NibOwnerLoadable { self.collectionView.collectionViewLayout.invalidateLayout() } - private func collectionViewLayout(for alignement: BubbleReactionsViewAlignement) -> UICollectionViewLayout { + private func collectionViewLayout(for alignment: BubbleReactionsViewAlignment) -> UICollectionViewLayout { let collectionViewLayout: UICollectionViewLayout From b5fe6bd2e6c562020165e2003474ba1509b3388f Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 15:09:04 +0100 Subject: [PATCH 165/209] BubbleRoomCellLayoutUpdater: Fix CGFloat type. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index eef734079..ee370b9fb 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -210,7 +210,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { private func getMessageBubbleBackgroundHeight(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) -> CGFloat? { var finalBubbleHeight: CGFloat? - let extraMargin = 4.0 + let extraMargin: CGFloat = 4.0 if let bubbleHeight = self.getTextMessageHeight(for: cell, andCellData: cellData) { finalBubbleHeight = bubbleHeight + extraMargin From 95a31a9f96e2c48bf70d86620072364b4e00d698 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 15:33:39 +0100 Subject: [PATCH 166/209] MXKRoomBubbleTableViewCell: Update a method name. --- .../Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h | 2 +- .../Styles/Bubble/BubbleRoomTimelineCellDecorator.swift | 6 +++--- .../Styles/Plain/PlainRoomTimelineCellDecorator.swift | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h index 958da908a..4f2873629 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h +++ b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h @@ -326,6 +326,6 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction; - (void)setupViews; /// Add temporary subview to `tmpSubviews` property. -- (void)addTmpSubview:(UIView*)subview; +- (void)addTemporarySubview:(UIView*)subview; @end diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 8451fe650..8fd1ccbcd 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -46,7 +46,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { viewTag: componentIndex) timestampLabel.translatesAutoresizingMaskIntoConstraints = false - cell.addTmpSubview(timestampLabel) + cell.addTemporarySubview(timestampLabel) bubbleBackgroundView.addSubview(timestampLabel) @@ -69,7 +69,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { override func addReactionView(_ reactionsView: BubbleReactionsView, toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData, contentViewPositionY: CGFloat, upperDecorationView: UIView?) { - cell.addTmpSubview(reactionsView) + cell.addTemporarySubview(reactionsView) if let reactionsDisplayable = cell as? BubbleCellReactionsDisplayable { reactionsDisplayable.addReactionsView(reactionsView) @@ -142,7 +142,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { cellData: RoomBubbleCellData, contentViewPositionY: CGFloat) { - cell.addTmpSubview(urlPreviewView) + cell.addTemporarySubview(urlPreviewView) let cellContentView = cell.contentView diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift index 95cbc04a8..d684267e0 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellDecorator.swift @@ -37,7 +37,7 @@ class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { toCell cell: MXKRoomBubbleTableViewCell, cellData: RoomBubbleCellData, contentViewPositionY: CGFloat) { - cell.addTmpSubview(urlPreviewView) + cell.addTemporarySubview(urlPreviewView) let cellContentView = cell.contentView @@ -65,7 +65,7 @@ class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { contentViewPositionY: CGFloat, upperDecorationView: UIView?) { - cell.addTmpSubview(reactionsView) + cell.addTemporarySubview(reactionsView) if let reactionsDisplayable = cell as? BubbleCellReactionsDisplayable { reactionsDisplayable.addReactionsView(reactionsView) @@ -107,7 +107,7 @@ class PlainRoomTimelineCellDecorator: RoomTimelineCellDecorator { contentViewPositionY: CGFloat, upperDecorationView: UIView?) { - cell.addTmpSubview(readReceiptsView) + cell.addTemporarySubview(readReceiptsView) if let readReceiptsDisplayable = cell as? BubbleCellReadReceiptsDisplayable { readReceiptsDisplayable.addReadReceiptsView(readReceiptsView) From ccf2633c64b5b5bfc5e5e8beb0547fd1af54a9b9 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 15:47:07 +0100 Subject: [PATCH 167/209] MXKRoomBubbleTableViewCell: Update a method name. --- .../MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m index 36b7dcd38..b79ea8667 100644 --- a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m +++ b/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m @@ -1130,7 +1130,7 @@ static BOOL _disableLongPressGestureOnEvent; [self resetAttachmentViewBottomConstraintConstant]; } -- (void)addTmpSubview:(UIView*)subview +- (void)addTemporarySubview:(UIView*)subview { if (!self.tmpSubviews) { From 731badb2dc3c91b55d2d62847f2a55f77e1a1a78 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 16:01:45 +0100 Subject: [PATCH 168/209] MXKRoomBubbleCellData: Improve getFirstBubbleComponentWithDisplay and getLastBubbleComponentWithDisplay. --- .../MatrixKit/Models/Room/MXKRoomBubbleCellData.m | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m index cd1fa9b70..84912efb1 100644 --- a/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m +++ b/Riot/Modules/MatrixKit/Models/Room/MXKRoomBubbleCellData.m @@ -306,16 +306,15 @@ return first; } -- (MXKRoomBubbleComponent*) getFirstBubbleComponentWithDisplay +- (MXKRoomBubbleComponent*)getFirstBubbleComponentWithDisplay { // Look for the first component which is actually displayed (some event are ignored in room history display). MXKRoomBubbleComponent* first = nil; @synchronized(bubbleComponents) { - for (NSInteger index = 0; index < bubbleComponents.count; index++) + for (MXKRoomBubbleComponent *component in bubbleComponents) { - MXKRoomBubbleComponent *component = bubbleComponents[index]; if (component.attributedTextMessage) { first = component; @@ -331,19 +330,19 @@ { // Look for the first component which is actually displayed (some event are ignored in room history display). MXKRoomBubbleComponent* lastVisibleComponent = nil; - + @synchronized(bubbleComponents) { - for (NSInteger index = 0; index < bubbleComponents.count; index++) + for (MXKRoomBubbleComponent *component in bubbleComponents.reverseObjectEnumerator) { - MXKRoomBubbleComponent *component = bubbleComponents[index]; if (component.attributedTextMessage) { lastVisibleComponent = component; + break; } } } - + return lastVisibleComponent; } From 08430961d054d210b0ca3448574c3319bca3e61c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 16:56:32 +0100 Subject: [PATCH 169/209] RoomTimelineStyle: Conforms to Themable. --- Riot/Managers/Theme/ThemeService.m | 2 +- .../RoomTimelineConfiguration.swift | 22 +++++++++++++++++-- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 18 +++++++++++++-- .../Bubble/BubbleRoomTimelineStyle.swift | 19 ++++++++++++++-- .../Styles/Plain/PlainRoomTimelineStyle.swift | 21 ++++++++++++++---- .../RoomCellLayoutUpdaterProtocol.swift | 2 +- .../Styles/RoomTimelineStyle.swift | 2 +- 7 files changed, 73 insertions(+), 13 deletions(-) diff --git a/Riot/Managers/Theme/ThemeService.m b/Riot/Managers/Theme/ThemeService.m index b205bbb6d..7adcadd7c 100644 --- a/Riot/Managers/Theme/ThemeService.m +++ b/Riot/Managers/Theme/ThemeService.m @@ -52,7 +52,7 @@ NSString *const kThemeServiceDidChangeThemeNotification = @"kThemeServiceDidChan [self updateAppearance]; - [[NSNotificationCenter defaultCenter] postNotificationName:kThemeServiceDidChangeThemeNotification object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:kThemeServiceDidChangeThemeNotification object:self]; } } diff --git a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift index 422a6465a..1cd3b60d7 100644 --- a/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift +++ b/Riot/Modules/Room/Views/BubbleCells/RoomTimelineConfiguration.swift @@ -34,6 +34,8 @@ class RoomTimelineConfiguration: NSObject { self.currentStyle = style super.init() + + self.registerThemeDidChange() } convenience init(styleIdentifier: RoomTimelineStyleIdentifier) { @@ -61,16 +63,32 @@ class RoomTimelineConfiguration: NSObject { } // MARK: - Private + + private func registerThemeDidChange() { + NotificationCenter.default.addObserver(self, selector: #selector(themeDidChange(notification:)), name: .themeServiceDidChangeTheme, object: nil) + + } + + @objc private func themeDidChange(notification: Notification) { + + guard let themeService = notification.object as? ThemeService else { + return + } + + self.currentStyle.update(theme: themeService.theme) + } private class func style(for identifier: RoomTimelineStyleIdentifier) -> RoomTimelineStyle { let roomTimelineStyle: RoomTimelineStyle + let theme = ThemeService.shared().theme + switch identifier { case .plain: - roomTimelineStyle = PlainRoomTimelineStyle() + roomTimelineStyle = PlainRoomTimelineStyle(theme: theme) case .bubble: - roomTimelineStyle = BubbleRoomTimelineStyle() + roomTimelineStyle = BubbleRoomTimelineStyle(theme: theme) } return roomTimelineStyle diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index ee370b9fb..37bb565a2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -21,12 +21,20 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { // MARK: - Properties + private var theme: Theme + private var incomingColor: UIColor { - return ThemeService.shared().theme.colors.system + return self.theme.colors.system } private var outgoingColor: UIColor { - return ThemeService.shared().theme.colors.accent.withAlphaComponent(0.10) + return self.theme.colors.accent.withAlphaComponent(0.10) + } + + // MARK: - Setup + + init(theme: Theme) { + self.theme = theme } // MARK: - Public @@ -91,6 +99,12 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { cell.setNeedsUpdateConstraints() } + // MARK: Themable + + func update(theme: Theme) { + self.theme = theme + } + // MARK: - Private // MARK: Bubble background view diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index 57a74dacb..96e232653 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -20,6 +20,12 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { // MARK: - Properties + // MARK: Private + + private var theme: Theme + + // MARK: Public + let identifier: RoomTimelineStyleIdentifier let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? @@ -30,9 +36,10 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { // MARK: - Setup - init() { + init(theme: Theme) { + self.theme = theme self.identifier = .bubble - self.cellLayoutUpdater = BubbleRoomCellLayoutUpdater() + self.cellLayoutUpdater = BubbleRoomCellLayoutUpdater(theme: theme) self.cellProvider = BubbleRoomTimelineCellProvider() self.cellDecorator = BubbleRoomTimelineCellDecorator() } @@ -58,4 +65,12 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { cell.blurred = true } } + + // MARK: Themable + + func update(theme: Theme) { + self.theme = theme + self.cellLayoutUpdater?.update(theme: theme) + } + } diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index 0f08aba78..cf3773003 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -17,20 +17,27 @@ import Foundation class PlainRoomTimelineStyle: RoomTimelineStyle { - + // MARK: - Properties + // MARK: Private + + private var theme: Theme + + // MARK: Public + let identifier: RoomTimelineStyleIdentifier let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? let cellProvider: RoomTimelineCellProviderProtocol - let cellDecorator: RoomTimelineCellDecorator - + let cellDecorator: RoomTimelineCellDecorator + // MARK: - Setup - init() { + init(theme: Theme) { + self.theme = theme self.identifier = .plain self.cellLayoutUpdater = nil self.cellProvider = PlainRoomTimelineCellProvider() @@ -58,4 +65,10 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { cell.blurred = true } } + + // MARK: Themable + + func update(theme: Theme) { + self.theme = theme + } } diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift index 8b56c19e3..3b18df1e8 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift @@ -18,7 +18,7 @@ import Foundation /// Enables to setup or update a room timeline cell view @objc -protocol RoomCellLayoutUpdaterProtocol: AnyObject { +protocol RoomCellLayoutUpdaterProtocol: Themable { func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index f851e02b2..eaf483651 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -19,7 +19,7 @@ import MatrixSDK /// RoomTimelineStyle describes a room timeline style used to customize timeline appearance @objc -protocol RoomTimelineStyle { +protocol RoomTimelineStyle: Themable { // MARK: - Properties From f9808afc63ca38b0c7ceffa93ac59f2ba2821218 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 17:00:13 +0100 Subject: [PATCH 170/209] Refactor RoomCellLayoutUpdaterProtocol to RoomCellLayoutUpdater. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- .../BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift | 2 +- .../Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift | 2 +- ...lLayoutUpdaterProtocol.swift => RoomCellLayoutUpdater.swift} | 2 +- .../Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/Styles/{RoomCellLayoutUpdaterProtocol.swift => RoomCellLayoutUpdater.swift} (95%) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 37bb565a2..da6cb173d 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -17,7 +17,7 @@ import UIKit @objcMembers -class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdaterProtocol { +class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdater { // MARK: - Properties diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index 96e232653..5c5c6d4ac 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -28,7 +28,7 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { let identifier: RoomTimelineStyleIdentifier - let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? + let cellLayoutUpdater: RoomCellLayoutUpdater? let cellProvider: RoomTimelineCellProviderProtocol diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index cf3773003..1d4f498ec 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -28,7 +28,7 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { let identifier: RoomTimelineStyleIdentifier - let cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? + let cellLayoutUpdater: RoomCellLayoutUpdater? let cellProvider: RoomTimelineCellProviderProtocol diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift similarity index 95% rename from Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift rename to Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift index 3b18df1e8..485470964 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdaterProtocol.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift @@ -18,7 +18,7 @@ import Foundation /// Enables to setup or update a room timeline cell view @objc -protocol RoomCellLayoutUpdaterProtocol: Themable { +protocol RoomCellLayoutUpdater: Themable { func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index eaf483651..18c91be97 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -27,7 +27,7 @@ protocol RoomTimelineStyle: Themable { var identifier: RoomTimelineStyleIdentifier { get } /// Update layout if needed for cells provided by the cell provider - var cellLayoutUpdater: RoomCellLayoutUpdaterProtocol? { get } + var cellLayoutUpdater: RoomCellLayoutUpdater? { get } /// Register and provide timeline cells var cellProvider: RoomTimelineCellProviderProtocol { get } From 0c99258253d28b1610bfde77ee06cfebc2f88e14 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Thu, 20 Jan 2022 17:09:34 +0100 Subject: [PATCH 171/209] Refactor RoomTimelineCellProviderProtocol to RoomTimelineCellProvider. --- Riot/Modules/Room/RoomViewController.m | 2 +- .../BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift | 2 +- .../Styles/Plain/PlainRoomTimelineCellProvider.h | 6 ++++-- .../BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift | 2 +- ...ineCellProviderProtocol.h => RoomTimelineCellProvider.h} | 2 +- .../Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift | 2 +- Riot/SupportingFiles/Riot-Bridging-Header.h | 2 +- 7 files changed, 10 insertions(+), 8 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/Styles/{RoomTimelineCellProviderProtocol.h => RoomTimelineCellProvider.h} (95%) diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 5975ace6a..dbdc1126a 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -82,7 +82,7 @@ #import "MXSDKOptions.h" -#import "RoomTimelineCellProviderProtocol.h" +#import "RoomTimelineCellProvider.h" #import "GeneratedInterface-Swift.h" diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index 5c5c6d4ac..2952550a0 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -30,7 +30,7 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { let cellLayoutUpdater: RoomCellLayoutUpdater? - let cellProvider: RoomTimelineCellProviderProtocol + let cellProvider: RoomTimelineCellProvider let cellDecorator: RoomTimelineCellDecorator diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h index 7c3d16294..12b1876ee 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.h @@ -14,14 +14,16 @@ // limitations under the License. // -#import "RoomTimelineCellProviderProtocol.h" +#import "RoomTimelineCellProvider.h" NS_ASSUME_NONNULL_BEGIN -@interface PlainRoomTimelineCellProvider: NSObject +@interface PlainRoomTimelineCellProvider: NSObject - (NSDictionary*)outgoingTextMessageCellsMapping; +- (NSDictionary*)outgoingAttachmentCellsMapping; + @end NS_ASSUME_NONNULL_END diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index 1d4f498ec..542f2709a 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -30,7 +30,7 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { let cellLayoutUpdater: RoomCellLayoutUpdater? - let cellProvider: RoomTimelineCellProviderProtocol + let cellProvider: RoomTimelineCellProvider let cellDecorator: RoomTimelineCellDecorator diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProvider.h similarity index 95% rename from Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h rename to Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProvider.h index 66fc17ee4..40037c3a2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProviderProtocol.h +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineCellProvider.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN /// Enables to register and provide room timeline cells -@protocol RoomTimelineCellProviderProtocol +@protocol RoomTimelineCellProvider /// Register timeline cells for the given table view - (void)registerCellsForTableView:(UITableView*)tableView; diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index 18c91be97..dc6e67ca1 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -30,7 +30,7 @@ protocol RoomTimelineStyle: Themable { var cellLayoutUpdater: RoomCellLayoutUpdater? { get } /// Register and provide timeline cells - var cellProvider: RoomTimelineCellProviderProtocol { get } + var cellProvider: RoomTimelineCellProvider { get } /// Handle cell decorations (reactions, read receipts, URL preview, …) var cellDecorator: RoomTimelineCellDecorator { get } diff --git a/Riot/SupportingFiles/Riot-Bridging-Header.h b/Riot/SupportingFiles/Riot-Bridging-Header.h index ed95cb775..9eaae3a43 100644 --- a/Riot/SupportingFiles/Riot-Bridging-Header.h +++ b/Riot/SupportingFiles/Riot-Bridging-Header.h @@ -46,7 +46,7 @@ #import "NSArray+Element.h" #import "ShareItemSender.h" #import "HTMLFormatter.h" -#import "RoomTimelineCellProviderProtocol.h" +#import "RoomTimelineCellProvider.h" #import "PlainRoomTimelineCellProvider.h" #import "BubbleRoomTimelineCellProvider.h" From c3cb9f64b462044a26e94871847ebf1222b754e9 Mon Sep 17 00:00:00 2001 From: libexus Date: Wed, 19 Jan 2022 18:38:45 +0000 Subject: [PATCH 172/209] Translated using Weblate (German) Currently translated at 99.8% (1394 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index 103566d64..05fee81ce 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -1588,7 +1588,7 @@ "onboarding_splash_page_2_message" = "Wähle wo deine Gespräche liegen, für Kontrolle und Unabhängigkeit. Verbunden mit Matrix."; "onboarding_splash_page_1_title" = "Nimm deine Gespräche in die eigene Hand."; "onboarding_splash_login_button_title" = "Ich habe bereits ein Konto"; -"onboarding_splash_page_4_message" = "Element ist auch für die Arbeit großartig. Ihm vertrauen die sichersten Unternehmen der Welt."; +"onboarding_splash_page_4_message" = "Element ist auch für die Arbeit großartig. Uns vertrauen einige der sichersten Organisationen der Welt."; "onboarding_splash_page_3_message" = "Ende-zu-Ende-verschlüsselt und ohne Telefonnummer nutzbar. Keine Werbung oder Datenerfassung."; "onboarding_splash_page_2_title" = "Du hast die Kontrolle."; "onboarding_splash_page_1_message" = "Sichere und unabhängige Kommunikation, die für die gleiche Vertraulichkeit sorgt, wie ein Gespräch von Angesicht zu Angesicht in deinem eigenen Zuhause."; From af3735a9b0b60fd24576ea9bb4b533f1b794ae5f Mon Sep 17 00:00:00 2001 From: artevaeckt Date: Tue, 18 Jan 2022 12:13:45 +0000 Subject: [PATCH 173/209] Translated using Weblate (German) Currently translated at 99.8% (1394 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ --- Riot/Assets/de.lproj/Vector.strings | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Riot/Assets/de.lproj/Vector.strings b/Riot/Assets/de.lproj/Vector.strings index 05fee81ce..df03d8813 100644 --- a/Riot/Assets/de.lproj/Vector.strings +++ b/Riot/Assets/de.lproj/Vector.strings @@ -1327,16 +1327,16 @@ "room_accessibility_video_call" = "Videoanruf"; "room_message_replying_to" = "%@ anworten"; "room_message_editing" = "Bearbeitung"; -"space_beta_announce_information" = "Spaces are a new way to group rooms and people. Bald werden sie auch auf iOS verfügbar sein, bis dahin kannst du sie schon auf %@ Web/Desktop testen."; -"space_feature_unavailable_information" = "Wir haben Spaces entwickelt, damit ihr eure vielen Räume besser organisieren könnt.\n\nBald werden sie auch auf iOS verfügbar sein, bis dahin kannst du sie schon auf %@ Web/Desktop testen. Alle Räume die du dort betrittst, sind natürlich auch hier verfügbar."; +"space_beta_announce_information" = "Spaces bieten neue Möglichkeiten um Räume und Personen zu gruppieren. Sie sind noch nicht auf iOS verfügbar, aber du kannst sie jetzt schon mit Web und Desktop nutzen."; +"space_feature_unavailable_information" = "Spaces bieten neue Möglichkeiten um Räume und Personen zu gruppieren.\n\nBald werden sie auch hier verfügbar sein. Für den Moment kannst du ihnen auf einer der anderen Plattformen beitreten und hier auf alle Räume zugreifen, denen du dort beitrittst."; "space_beta_announce_subtitle" = "Die verbesserte Version von Communities"; "space_beta_announce_title" = "Spaces sind bald verfügbar"; "space_beta_announce_badge" = "Beta (in Entwicklung)"; -"space_feature_unavailable_subtitle" = "Spaces sind auf iOS noch nicht verfügbar. Du kannst sie aber schon auf %@ Web oder Desktop ausprobieren"; +"space_feature_unavailable_subtitle" = "Spaces sind auf iOS noch nicht verfügbar. Du kannst sie aber schon auf Web oder Desktop benutzen"; // Mark: - Spaces -"space_feature_unavailable_title" = "Spaces sind noch in der Entwicklung und werden bald verfügbar sein"; +"space_feature_unavailable_title" = "Spaces sind bald verfügbar"; "event_formatter_group_call_incoming" = "%@ in %@"; "event_formatter_group_call_leave" = "Verlassen"; "event_formatter_group_call_join" = "Beitreten"; From 146692d499b6b163b0555b93eaf0e77f1277c356 Mon Sep 17 00:00:00 2001 From: Szimszon Date: Wed, 19 Jan 2022 19:24:04 +0000 Subject: [PATCH 174/209] Translated using Weblate (Hungarian) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ --- Riot/Assets/hu.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/hu.lproj/Vector.strings b/Riot/Assets/hu.lproj/Vector.strings index dd01bbcac..29e3902c1 100644 --- a/Riot/Assets/hu.lproj/Vector.strings +++ b/Riot/Assets/hu.lproj/Vector.strings @@ -1606,3 +1606,16 @@ "location_sharing_title" = "Földrajzi helyzet"; "ok" = "OK"; +"onboarding_splash_page_4_message" = "Element megállja a helyét a munkahelyen is. A világ legbiztonságosabb szervezetei bíznak meg benne."; +"onboarding_splash_page_3_message" = "Telefonszám nélkül végpontok között titkosított. Reklámok és adatbányászat nélkül."; +"onboarding_splash_page_2_message" = "Válaszd meg hol legyenek a beszélgetéseid tárolva, visszaadja az irányítást és függetlenné tesz. Csatlakozva a Matrixhoz."; +"onboarding_splash_page_1_message" = "Biztonságos és független kommunikáció ami olyan biztonságos mintha valakivel négyszemközt beszélgetnél a házadban."; +"settings_enable_room_message_bubbles" = "Üzenet buborékok"; +"onboarding_splash_page_4_title_no_pun" = "Üzenetküldés a csoportodnak."; +"onboarding_splash_page_3_title" = "Biztonságos üzenetküldés."; +"onboarding_splash_page_2_title" = "Te irányítasz."; +"onboarding_splash_page_1_title" = "Az ön beszélgetései csak az öné."; +"onboarding_splash_login_button_title" = "Már van fiókom"; + +// Onboarding +"onboarding_splash_register_button_title" = "Fiók létrehozása"; From 132710340fecd73bed830959294d09e76b6b9998 Mon Sep 17 00:00:00 2001 From: random Date: Mon, 17 Jan 2022 14:23:03 +0000 Subject: [PATCH 175/209] Translated using Weblate (Italian) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ --- Riot/Assets/it.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/it.lproj/Vector.strings b/Riot/Assets/it.lproj/Vector.strings index e45714f45..26065f880 100644 --- a/Riot/Assets/it.lproj/Vector.strings +++ b/Riot/Assets/it.lproj/Vector.strings @@ -1577,3 +1577,16 @@ "location_sharing_title" = "Posizione"; "ok" = "OK"; +"settings_enable_room_message_bubbles" = "Messaggi"; +"onboarding_splash_page_4_message" = "Element è ottimo anche per i luoghi di lavoro. È considerato affidabile dalle più sicure organizzazioni del mondo."; +"onboarding_splash_page_4_title_no_pun" = "Messaggistica per la tua squadra."; +"onboarding_splash_page_3_message" = "Crittografia end-to-end e nessun numero di telefono richiesto. Niente pubblicità o raccolta di dati."; +"onboarding_splash_page_3_title" = "Messaggistica sicura."; +"onboarding_splash_page_2_message" = "Scegli dove vengono tenute le tue conversazioni, dandoti controllo e indipendenza. Connesso via Matrix."; +"onboarding_splash_page_2_title" = "Tu hai il controllo."; +"onboarding_splash_page_1_message" = "Comunicazioni sicure e indipendenti che ti danno lo stesso livello di riservatezza di una conversazione faccia a faccia in casa tua."; +"onboarding_splash_page_1_title" = "Prendi il controllo delle tue conversazioni."; +"onboarding_splash_login_button_title" = "Ho già un account"; + +// Onboarding +"onboarding_splash_register_button_title" = "Crea account"; From 670eec04eaacb0ee917edddd04d4ea5316bedf05 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 15:35:34 +0100 Subject: [PATCH 176/209] Remane RoomCellLayoutUpdater to RoomCellLayoutUpdating. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- .../BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift | 2 +- .../Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift | 2 +- ...RoomCellLayoutUpdater.swift => RoomCellLayoutUpdating.swift} | 2 +- .../Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) rename Riot/Modules/Room/Views/BubbleCells/Styles/{RoomCellLayoutUpdater.swift => RoomCellLayoutUpdating.swift} (95%) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index da6cb173d..28fdcb163 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -17,7 +17,7 @@ import UIKit @objcMembers -class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdater { +class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating { // MARK: - Properties diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift index 2952550a0..137338e57 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineStyle.swift @@ -28,7 +28,7 @@ class BubbleRoomTimelineStyle: RoomTimelineStyle { let identifier: RoomTimelineStyleIdentifier - let cellLayoutUpdater: RoomCellLayoutUpdater? + let cellLayoutUpdater: RoomCellLayoutUpdating? let cellProvider: RoomTimelineCellProvider diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift index 542f2709a..f3fba9c4e 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineStyle.swift @@ -28,7 +28,7 @@ class PlainRoomTimelineStyle: RoomTimelineStyle { let identifier: RoomTimelineStyleIdentifier - let cellLayoutUpdater: RoomCellLayoutUpdater? + let cellLayoutUpdater: RoomCellLayoutUpdating? let cellProvider: RoomTimelineCellProvider diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift similarity index 95% rename from Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift rename to Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift index 485470964..71212d94d 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift @@ -18,7 +18,7 @@ import Foundation /// Enables to setup or update a room timeline cell view @objc -protocol RoomCellLayoutUpdater: Themable { +protocol RoomCellLayoutUpdating: Themable { func updateLayoutIfNeeded(for cell: MXKRoomBubbleTableViewCell, andCellData cellData: MXKRoomBubbleCellData) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift index dc6e67ca1..b430171b5 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomTimelineStyle.swift @@ -27,7 +27,7 @@ protocol RoomTimelineStyle: Themable { var identifier: RoomTimelineStyleIdentifier { get } /// Update layout if needed for cells provided by the cell provider - var cellLayoutUpdater: RoomCellLayoutUpdater? { get } + var cellLayoutUpdater: RoomCellLayoutUpdating? { get } /// Register and provide timeline cells var cellProvider: RoomTimelineCellProvider { get } From 2dfb11c747004c396f66a9cbcae6daa99ad16237 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 15:37:14 +0100 Subject: [PATCH 177/209] BuildSettings: Disable room timeline style configuration atm. --- Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index f05c3b592..fe1bdcf8e 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -293,7 +293,7 @@ final class BuildSettings: NSObject { static let roomScreenAllowFilesAction: Bool = true // Timeline style - static let roomScreenAllowTimelineStyleConfiguration: Bool = true + static let roomScreenAllowTimelineStyleConfiguration: Bool = false static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain static var roomScreenEnableMessageBubblesByDefault: Bool { return self.roomScreenTimelineDefaultStyleIdentifier == .bubble From 679c036efcd3faef416b1cccfb1006a47b5bb1f0 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 17:18:59 +0100 Subject: [PATCH 178/209] Move all MatrixKit cells + MXKRoomViewController into appropriated folders. --- Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h | 2 -- .../{MatrixKit/Controllers => Room}/MXKRoomViewController.h | 0 .../{MatrixKit/Controllers => Room}/MXKRoomViewController.m | 0 .../{MatrixKit/Controllers => Room}/MXKRoomViewController.xib | 0 .../Views/BubbleCells/Common}/MXKRoomBubbleTableViewCell.h | 0 .../Views/BubbleCells/Common}/MXKRoomBubbleTableViewCell.m | 0 .../Views/BubbleCells/Common}/MXKRoomIOSBubbleTableViewCell.h | 0 .../Views/BubbleCells/Common}/MXKRoomIOSBubbleTableViewCell.m | 0 .../BubbleCells/Common}/MXKRoomIOSOutgoingBubbleTableViewCell.h | 0 .../BubbleCells/Common}/MXKRoomIOSOutgoingBubbleTableViewCell.m | 0 .../Common}/MXKRoomIOSOutgoingBubbleTableViewCell.xib | 0 .../BubbleCells/Common}/MXKRoomIncomingBubbleTableViewCell.h | 0 .../BubbleCells/Common}/MXKRoomIncomingBubbleTableViewCell.m | 0 .../BubbleCells/Common}/MXKRoomOutgoingBubbleTableViewCell.h | 0 .../BubbleCells/Common}/MXKRoomOutgoingBubbleTableViewCell.m | 0 .../BubbleCells/EmptyContent}/MXKRoomEmptyBubbleTableViewCell.h | 0 .../BubbleCells/EmptyContent}/MXKRoomEmptyBubbleTableViewCell.m | 0 .../EmptyContent}/MXKRoomEmptyBubbleTableViewCell.xib | 0 .../Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.h | 0 .../Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.m | 0 .../Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.xib | 0 .../MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h | 0 .../MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m | 0 .../MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib | 0 .../Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.h | 0 .../Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.m | 0 .../Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.xib | 0 .../MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h | 0 .../MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m | 0 .../MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib | 0 30 files changed, 2 deletions(-) rename Riot/Modules/{MatrixKit/Controllers => Room}/MXKRoomViewController.h (100%) rename Riot/Modules/{MatrixKit/Controllers => Room}/MXKRoomViewController.m (100%) rename Riot/Modules/{MatrixKit/Controllers => Room}/MXKRoomViewController.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIOSBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIOSBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIOSOutgoingBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIOSOutgoingBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIOSOutgoingBubbleTableViewCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIncomingBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomIncomingBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomOutgoingBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/Common}/MXKRoomOutgoingBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/EmptyContent}/MXKRoomEmptyBubbleTableViewCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/EmptyContent}/MXKRoomEmptyBubbleTableViewCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/EmptyContent}/MXKRoomEmptyBubbleTableViewCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Incoming/Common}/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentBubbleCell.xib (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m (100%) rename Riot/Modules/{MatrixKit/Views/RoomBubbleList => Room/Views/BubbleCells/FileAttachment/Outgoing/Common}/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib (100%) diff --git a/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h b/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h index 3f50b38c7..64b8a348e 100644 --- a/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h +++ b/Riot/Modules/MatrixKit/MatrixKit-Bridging-Header.h @@ -14,6 +14,4 @@ #import "MXKRoomInputToolbarView.h" #import "MXKImageView.h" -#import "MXKRoomBubbleTableViewCell.h" #import "MXKRoomBubbleCellData.h" -#import "MXKRoomBubbleTableViewCell.h" diff --git a/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.h b/Riot/Modules/Room/MXKRoomViewController.h similarity index 100% rename from Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.h rename to Riot/Modules/Room/MXKRoomViewController.h diff --git a/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m b/Riot/Modules/Room/MXKRoomViewController.m similarity index 100% rename from Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.m rename to Riot/Modules/Room/MXKRoomViewController.m diff --git a/Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.xib b/Riot/Modules/Room/MXKRoomViewController.xib similarity index 100% rename from Riot/Modules/MatrixKit/Controllers/MXKRoomViewController.xib rename to Riot/Modules/Room/MXKRoomViewController.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.xib b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIOSOutgoingBubbleTableViewCell.xib rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIOSOutgoingBubbleTableViewCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIncomingBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIncomingBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIncomingBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomIncomingBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomOutgoingBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomOutgoingBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomOutgoingBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomOutgoingBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.h rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.m b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.m rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.xib b/Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomEmptyBubbleTableViewCell.xib rename to Riot/Modules/Room/Views/BubbleCells/EmptyContent/MXKRoomEmptyBubbleTableViewCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Incoming/Common/MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.xib diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.m diff --git a/Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib similarity index 100% rename from Riot/Modules/MatrixKit/Views/RoomBubbleList/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib rename to Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib From 10ce5651c3aa24248b986359b93fe3ba42dcde51 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 17:34:27 +0100 Subject: [PATCH 179/209] MXKRoomBubbleTableViewCell: Expose attachViewLeadingConstraint property. --- .../Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h | 1 + .../Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib | 5 +++-- .../RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib | 5 +++-- .../RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib | 5 +++-- .../BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h | 1 - 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h index 4f2873629..410747d1d 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h +++ b/Riot/Modules/Room/Views/BubbleCells/Common/MXKRoomBubbleTableViewCell.h @@ -216,6 +216,7 @@ extern NSString *const kMXKRoomBubbleCellUrlItemInteraction; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewMinHeightConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewTopConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewBottomConstraint; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewLeadingConstraint; /** The constraints which defines the relationship between bubbleInfoContainer and its superview diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib index 7d8f2e78f..bdc4ee247 100644 --- a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentBubbleCell.xib @@ -1,9 +1,9 @@ - + - + @@ -128,6 +128,7 @@ + diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib index c6d5de460..c09b26ed2 100644 --- a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleBubbleCell.xib @@ -1,9 +1,9 @@ - + - + @@ -161,6 +161,7 @@ + diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib index e31cd5257..73ca69699 100644 --- a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.xib @@ -1,9 +1,9 @@ - + - + @@ -95,6 +95,7 @@ + diff --git a/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h index 689b39403..67526a1dd 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h +++ b/Riot/Modules/Room/Views/BubbleCells/Sticker/RoomSelectedStickerBubbleCell.h @@ -27,7 +27,6 @@ @property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *userNameLabelTopConstraint; -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewLeadingConstraint; @property (weak, nonatomic) IBOutlet NSLayoutConstraint *descriptionContainerViewBottomConstraint; @end From 2257acf364ed218f79fc97ed269918de5e810012 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:13:47 +0100 Subject: [PATCH 180/209] BubbleRoomTimelineCellProvider: Handle outgoing file attachment cells. --- .../Bubble/BubbleRoomTimelineCellProvider.m | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m index e1329b190..a412b8109 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m @@ -16,21 +16,39 @@ #import "BubbleRoomTimelineCellProvider.h" +#pragma mark - Imports + +#pragma mark Text message + +// Outgoing + +// Clear #import "RoomOutgoingTextMsgBubbleCell.h" #import "RoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h" #import "RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h" #import "RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h" #import "RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +// Encrypted + #import "RoomOutgoingEncryptedTextMsgBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgWithPaginationTitleBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgWithoutSenderNameBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#pragma mark Attachment + +// Outgoing + +// Clear #import "RoomOutgoingAttachmentBubbleCell.h" #import "RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" #import "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" +// Encrypted +#import "RoomOutgoingEncryptedAttachmentBubbleCell.h" +#import "RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.h" +#import "RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.h" @implementation BubbleRoomTimelineCellProvider @@ -53,4 +71,19 @@ }; } +- (NSDictionary*)outgoingAttachmentCellsMapping +{ + // Hide sender info and avatar for bubble outgoing file attachment + return @{ + // Clear + @(RoomTimelineCellIdentifierOutgoingAttachment) : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentWithoutSenderInfo) : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle) : RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class, + // Encrypted + @(RoomTimelineCellIdentifierOutgoingAttachmentEncrypted) : RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithPaginationTitle) : RoomOutgoingEncryptedAttachmentWithPaginationTitleBubbleCell.class + }; +} + @end From 61dd93714ca0ddc0b6c73d87735396b74c4fc10e Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:16:01 +0100 Subject: [PATCH 181/209] RoomCellLayoutUpdating: Add setup method for outgoing file attachement cell. --- .../Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift index 71212d94d..aaacccb6f 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/RoomCellLayoutUpdating.swift @@ -25,4 +25,6 @@ protocol RoomCellLayoutUpdating: Themable { func setupLayout(forIncomingTextMessageCell cell: MXKRoomBubbleTableViewCell) func setupLayout(forOutgoingTextMessageCell cell: MXKRoomBubbleTableViewCell) + + func setupLayout(forOutgoingFileAttachmentCell cell: MXKRoomBubbleTableViewCell) } From c12a1a12e6d01de141d3accb41fc0fbe79934d7c Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:21:05 +0100 Subject: [PATCH 182/209] BubbleRoomCellLayoutUpdater: Handle setup outgoing file attachment layout. --- .../Bubble/BubbleRoomCellLayoutUpdater.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 28fdcb163..efa90a5e0 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -99,6 +99,14 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating { cell.setNeedsUpdateConstraints() } + func setupLayout(forOutgoingFileAttachmentCell cell: MXKRoomBubbleTableViewCell) { + + // Hide avatar view + cell.pictureView?.isHidden = true + + self.setupOutgoingFileAttachViewMargins(for: cell) + } + // MARK: Themable func update(theme: Theme) { @@ -310,4 +318,28 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating { cell.msgTextViewBottomConstraint.constant += bottomMargin } + + private func setupOutgoingFileAttachViewMargins(for cell: MXKRoomBubbleTableViewCell) { + + guard let attachmentView = cell.attachmentView else { + return + } + + let contentView = cell.contentView + + // TODO: Use constants + // Same as URL preview + let rightMargin: CGFloat = 34.0 + + if let attachViewLeadingConstraint = cell.attachViewLeadingConstraint { + attachViewLeadingConstraint.isActive = false + cell.attachViewLeadingConstraint = nil + } + + let rightConstraint = attachmentView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -rightMargin) + + NSLayoutConstraint.activate([ + rightConstraint + ]) + } } From faf9c039697a5bb3274ad12f170c5d52eb72c870 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:23:03 +0100 Subject: [PATCH 183/209] MXKRoomOutgoingAttachmentBubbleCell: Handle cellLayoutUpdater. --- .../Common/MXKRoomOutgoingAttachmentBubbleCell.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m index 9a3e1cfe1..84c05d49a 100644 --- a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Common/MXKRoomOutgoingAttachmentBubbleCell.m @@ -23,6 +23,8 @@ #import "MXKImageView.h" #import "MXKPieChartView.h" +#import "GeneratedInterface-Swift.h" + @implementation MXKRoomOutgoingAttachmentBubbleCell - (void)dealloc @@ -30,6 +32,15 @@ [self stopAnimating]; } +- (void)setupViews +{ + [super setupViews]; + + RoomTimelineConfiguration *timelineConfiguration = [RoomTimelineConfiguration shared]; + + [timelineConfiguration.currentStyle.cellLayoutUpdater setupLayoutForOutgoingFileAttachmentCell:self]; +} + - (void)render:(MXKCellData *)cellData { [super render:cellData]; From c3a78afc358232f72eb00ebc2fd439428bb7d2a1 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:24:47 +0100 Subject: [PATCH 184/209] BuildSettings: Enable room timeline style configuration for the PR. --- Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 3f3e1c15c..076d8dec9 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -293,7 +293,7 @@ final class BuildSettings: NSObject { static let roomScreenAllowFilesAction: Bool = true // Timeline style - static let roomScreenAllowTimelineStyleConfiguration: Bool = false + static let roomScreenAllowTimelineStyleConfiguration: Bool = true static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain static var roomScreenEnableMessageBubblesByDefault: Bool { return self.roomScreenTimelineDefaultStyleIdentifier == .bubble From ae4841115e5834641eb949b7a4c520ee798825df Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 18:33:10 +0100 Subject: [PATCH 185/209] Update changes. --- changelog.d/5209.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5209.feature diff --git a/changelog.d/5209.feature b/changelog.d/5209.feature new file mode 100644 index 000000000..30ed3c629 --- /dev/null +++ b/changelog.d/5209.feature @@ -0,0 +1 @@ +Message Bubbles: Layout for Media. \ No newline at end of file From 6c0e75028cfe22f0bdd410b3baa334567dd9a978 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 19:18:57 +0100 Subject: [PATCH 186/209] Add RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell. --- ...ginationTitleWithoutSenderNameBubbleCell.h | 24 +++ ...ginationTitleWithoutSenderNameBubbleCell.m | 32 ++++ ...nationTitleWithoutSenderNameBubbleCell.xib | 161 ++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h create mode 100644 Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.m create mode 100644 Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.xib diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h new file mode 100644 index 000000000..24c064505 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h @@ -0,0 +1,24 @@ +/* + Copyright 2015 OpenMarket 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 "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" + +/** + `RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell` displays outgoing attachment bubbles and pagination title but no sender name. + */ +@interface RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell : RoomOutgoingAttachmentWithPaginationTitleBubbleCell + +@end diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.m b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.m new file mode 100644 index 000000000..46ea41861 --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.m @@ -0,0 +1,32 @@ +/* + Copyright 2015 OpenMarket Ltd + Copyright 2017 Vector Creations 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 "RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h" + +#import "ThemeService.h" +#import "GeneratedInterface-Swift.h" + +@implementation RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell + +- (void)customizeTableViewCellRendering +{ + [super customizeTableViewCellRendering]; + + self.messageTextView.tintColor = ThemeService.shared.theme.tintColor; +} + +@end diff --git a/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.xib b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.xib new file mode 100644 index 000000000..cae2140da --- /dev/null +++ b/Riot/Modules/Room/Views/BubbleCells/FileAttachment/Outgoing/Clear/RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.xib @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a2cfa1912b9357aff4fac650441ae0655f9635a3 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Fri, 21 Jan 2022 19:26:59 +0100 Subject: [PATCH 187/209] BubbleRoomTimelineCellProvider: Remove sender name for pagination title case. --- .../BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m | 3 ++- .../BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m index a412b8109..f36d21fdf 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellProvider.m @@ -28,6 +28,7 @@ #import "RoomOutgoingTextMsgWithPaginationTitleBubbleCell.h" #import "RoomOutgoingTextMsgWithoutSenderNameBubbleCell.h" #import "RoomOutgoingTextMsgWithPaginationTitleWithoutSenderNameBubbleCell.h" +#import "RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h" // Encrypted @@ -78,7 +79,7 @@ // Clear @(RoomTimelineCellIdentifierOutgoingAttachment) : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class, @(RoomTimelineCellIdentifierOutgoingAttachmentWithoutSenderInfo) : RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class, - @(RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle) : RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class, + @(RoomTimelineCellIdentifierOutgoingAttachmentWithPaginationTitle) : RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.class, // Encrypted @(RoomTimelineCellIdentifierOutgoingAttachmentEncrypted) : RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, @(RoomTimelineCellIdentifierOutgoingAttachmentEncryptedWithoutSenderInfo) : RoomOutgoingEncryptedAttachmentWithoutSenderInfoBubbleCell.class, diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m index 58a460dfe..54ad2569a 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -46,6 +46,7 @@ #import "RoomOutgoingAttachmentBubbleCell.h" #import "RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h" #import "RoomOutgoingAttachmentWithPaginationTitleBubbleCell.h" +#import "RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgBubbleCell.h" #import "RoomOutgoingEncryptedTextMsgWithoutSenderInfoBubbleCell.h" @@ -199,6 +200,7 @@ [tableView registerClass:RoomOutgoingAttachmentBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentBubbleCell.defaultReuseIdentifier]; [tableView registerClass:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithoutSenderInfoBubbleCell.defaultReuseIdentifier]; [tableView registerClass:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithPaginationTitleBubbleCell.defaultReuseIdentifier]; + [tableView registerClass:RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.class forCellReuseIdentifier:RoomOutgoingAttachmentWithPaginationTitleWithoutSenderNameBubbleCell.defaultReuseIdentifier]; // Encrypted From 632bd620384505175f06d01c126756778daa4be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Marhoun?= Date: Fri, 21 Jan 2022 23:40:19 +0000 Subject: [PATCH 188/209] Added translation using Weblate (Czech) --- Riot/Assets/cs.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) create mode 100644 Riot/Assets/cs.lproj/InfoPlist.strings diff --git a/Riot/Assets/cs.lproj/InfoPlist.strings b/Riot/Assets/cs.lproj/InfoPlist.strings new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Riot/Assets/cs.lproj/InfoPlist.strings @@ -0,0 +1 @@ + From 54a4688bbad0511f7f8defe816d1f2146e0233ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Marhoun?= Date: Sat, 22 Jan 2022 00:22:03 +0000 Subject: [PATCH 189/209] Translated using Weblate (Czech) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/cs/ --- Riot/Assets/cs.lproj/Localizable.strings | 169 +++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/Riot/Assets/cs.lproj/Localizable.strings b/Riot/Assets/cs.lproj/Localizable.strings index 8b1378917..15e6ddbbf 100644 --- a/Riot/Assets/cs.lproj/Localizable.strings +++ b/Riot/Assets/cs.lproj/Localizable.strings @@ -1 +1,170 @@ + + +/** Reactions **/ + +/* A user has reacted to a message, including the reaction e.g. "Alice reacted 👍". */ +"REACTION_FROM_USER" = "%@ reagoval/a %@"; + +/* Look, stuff's happened, alright? Just open the app. */ +"MSGS_IN_TWO_PLUS_ROOMS" = "%@ nových zpráv v %@, %@ a dalších"; + +/* Multiple messages in two rooms */ +"MSGS_IN_TWO_ROOMS" = "%@ nových zpráv v %@ a %@"; + +/* Multiple unread messages from two plus people (ie. for 4+ people: 'others' replaces the third person) */ +"MSGS_FROM_TWO_PLUS_USERS" = "%@ nových zpráv od %@, %@ a dalších"; + +/* Multiple unread messages from three people */ +"MSGS_FROM_THREE_USERS" = "%@ nových zpráv od %@, %@ a %@"; + +/* Multiple unread messages from two people */ +"MSGS_FROM_TWO_USERS" = "%@ nových zpráv od %@ a %@"; + +/* Multiple unread messages from a specific person, not referencing a room */ +"MSGS_FROM_USER" = "%@ nové zprávy od %@"; + +/** Coalesced messages **/ + +/* Multiple unread messages in a room */ +"UNREAD_IN_ROOM" = "%@ nové zprávy v %@"; + +/* New message with hidden content due to PIN enabled */ +"MESSAGE_PROTECTED" = "Nová zpráva"; + +/* New message indicator on a room */ +"MESSAGE_IN_X" = "Zpráva v %@"; + +/* New message indicator from a DM */ +"MESSAGE_FROM_X" = "Zpráva od %@"; + +/** Notification messages **/ + +/* New message indicator on unknown room */ +"MESSAGE" = "Zpráva"; + +/* Sticker from a specific person, not referencing a room. */ +"STICKER_FROM_USER" = "%@ poslal/a nálepku"; + +/* A single unread message */ +"SINGLE_UNREAD" = "Dostali jste zprávu"; + +/* A single unread message in a room */ +"SINGLE_UNREAD_IN_ROOM" = "V %@ vám přišla zpráva"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ sdílel/a svou polohu"; + +/** Single, unencrypted messages (where we can include the content */ + +/* New message from a specific person, not referencing a room. Content included. */ +"MSG_FROM_USER_WITH_CONTENT" = "%@: %@"; + +/** Key verification **/ + +"KEY_VERIFICATION_REQUEST_FROM_USER" = "%@ žádá o ověření"; + +/* Group call from user, CallKit caller name */ +"GROUP_CALL_FROM_USER" = "%@ (Skupinový hovor)"; + +/* A user added a Jitsi call to a room */ +"GROUP_CALL_STARTED" = "Začal skupinový hovor"; + +/* Incoming named video conference invite from a specific person */ +"VIDEO_CONF_NAMED_FROM_USER" = "Skupinový videohovor od %@: '%@'"; + +/* Incoming named voice conference invite from a specific person */ +"VOICE_CONF_NAMED_FROM_USER" = "Skupinový hovor od %@: '%@'"; + +/* Incoming unnamed video conference invite from a specific person */ +"VIDEO_CONF_FROM_USER" = "Skupinový videohovor od %@"; + +/* Incoming unnamed voice conference invite from a specific person */ +"VOICE_CONF_FROM_USER" = "Skupinový hovor od %@"; + +/* Incoming one-to-one video call */ +"VIDEO_CALL_FROM_USER" = "Videohovor od %@"; + +/** Calls **/ + +/* Incoming one-to-one voice call */ +"VOICE_CALL_FROM_USER" = "Hovor od %@"; + +/* A user's membership has updated in an unknown way */ +"USER_MEMBERSHIP_UPDATED" = "%@ aktualizoval/a svůj profil"; + +/* A user has change their avatar */ +"USER_UPDATED_AVATAR" = "%@ změnil/a svůj avatar"; + +/* A user has change their name to a new name which we don't know */ +"GENERIC_USER_UPDATED_DISPLAYNAME" = "%@ změnil/a svůj alias"; + +/** Membership Updates **/ + +/* A user has change their name to a new name */ +"USER_UPDATED_DISPLAYNAME" = "%@ změnil/a svůj alias na %@"; + +/* A user has invited you to a named room */ +"USER_INVITE_TO_NAMED_ROOM" = "%@ vás pozval/a do %@"; + +/* A user has invited you to an (unamed) group chat */ +"USER_INVITE_TO_CHAT_GROUP_CHAT" = "%@ vás pozval/a ke skupinové konverzaci"; + +/** Invites **/ + +/* A user has invited you to a chat */ +"USER_INVITE_TO_CHAT" = "%@ vás pozval/a ke konverzaci"; + +/* A user has reacted to a message, but the reaction content is unknown */ +"GENERIC_REACTION_FROM_USER" = "%@ poslal/a reakci"; + +/* New message from a specific person in a named room */ +"MSG_FROM_USER_IN_ROOM" = "%@ něco zveřejnil v %@"; + +/* New file message from a specific person, not referencing a room. */ +"FILE_FROM_USER" = "%@ poslal/a soubor %@"; + +/* New voice message from a specific person, not referencing a room. */ +"VOICE_MESSAGE_FROM_USER" = "%@ poslal/a zvukový soubor"; + +/* New audio message from a specific person, not referencing a room. */ +"AUDIO_FROM_USER" = "%@ poslal/a zvukový soubor %@"; + +/* New video message from a specific person, not referencing a room. */ +"VIDEO_FROM_USER" = "%@ poslal/a video"; + +/* New image message from a specific person in a named room. */ +"IMAGE_FROM_USER_IN_ROOM" = "%@ zveřejnil/a obrázek %@ v %@"; + +/** Media Messages **/ + +/* New image message from a specific person, not referencing a room. */ +"PICTURE_FROM_USER" = "%@ poslal/a obrázek"; + +/* New action message from a specific person in a named room. */ +"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@"; + +/* New action message from a specific person, not referencing a room. */ +"ACTION_FROM_USER" = "* %@ %@"; + +/* New message from a specific person in a named room. Content included. */ +"MSG_FROM_USER_IN_ROOM_WITH_CONTENT" = "%@ v %@: %@"; + +/** Single, end-to-end encrypted messages (ie. we don't know what they say) */ + +/* New message from a specific person, not referencing a room */ +"MSG_FROM_USER" = "%@ poslal/a zprávu"; + +/* New message reply from a specific person in a named room. */ +"REPLY_FROM_USER_IN_ROOM_TITLE" = "%@ odpověděl/a v %@"; + +/* New message reply from a specific person, not referencing a room. */ +"REPLY_FROM_USER_TITLE" = "%@ odpověděl/a"; + +/** Titles **/ + +/* Message title for a specific person in a named room */ +"MSG_FROM_USER_IN_ROOM_TITLE" = "%@ v %@"; +/** General **/ + +"NOTIFICATION" = "Oznámení"; From 3816bd98e13ac3d765cb35a6a98032ee7fec9430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Marhoun?= Date: Sat, 22 Jan 2022 00:31:07 +0000 Subject: [PATCH 190/209] Translated using Weblate (Czech) Currently translated at 57.1% (4 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/cs/ --- Riot/Assets/cs.lproj/InfoPlist.strings | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Riot/Assets/cs.lproj/InfoPlist.strings b/Riot/Assets/cs.lproj/InfoPlist.strings index 8b1378917..88c506408 100644 --- a/Riot/Assets/cs.lproj/InfoPlist.strings +++ b/Riot/Assets/cs.lproj/InfoPlist.strings @@ -1 +1,7 @@ + +// Permissions usage explanations +"NSCameraUsageDescription" = "Kamera slouží k focení, zachycení videí a k videohovorům."; +"NSPhotoLibraryUsageDescription" = "Galerie se používá k posílání obrázků a videí."; +"NSCalendarsUsageDescription" = "Zobrazuje události v aplikaci."; +"NSFaceIDUsageDescription" = "Face ID se používá k přístupu do aplikace."; From 80245309dea9f395d2c89e16c12d9a5f5395c532 Mon Sep 17 00:00:00 2001 From: Johan Smits Date: Sat, 22 Jan 2022 11:08:11 +0000 Subject: [PATCH 191/209] Translated using Weblate (Dutch) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ --- Riot/Assets/nl.lproj/Vector.strings | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Riot/Assets/nl.lproj/Vector.strings b/Riot/Assets/nl.lproj/Vector.strings index c400a6ba9..b8eefab2b 100644 --- a/Riot/Assets/nl.lproj/Vector.strings +++ b/Riot/Assets/nl.lproj/Vector.strings @@ -1706,3 +1706,16 @@ "location_sharing_title" = "Locatie"; "ok" = "OK"; +"settings_enable_room_message_bubbles" = "Bericht bubbels"; +"onboarding_splash_page_4_message" = "Element is ook zeer geschikt voor op de werkvloer. Het wordt vertrouwd door 's werelds veiligste organisaties."; +"onboarding_splash_page_4_title_no_pun" = "Berichten voor uw team."; +"onboarding_splash_page_3_message" = "End-to-end versleuteld en geen telefoonnummer vereist. Geen advertenties of datamining."; +"onboarding_splash_page_3_title" = "Veilig berichtenverkeer."; +"onboarding_splash_page_2_message" = "Kies waar u gesprekken worden gehouden, zodat u controle en onafhankelijkheid heeft. Verbonden via Matrix."; +"onboarding_splash_page_2_title" = "U heeft de controle."; +"onboarding_splash_page_1_message" = "Veilige en onafhankelijke communicatie die u dezelfde mate van privacy geeft als een persoonlijk gesprek in uw eigen huis."; +"onboarding_splash_page_1_title" = "Word eigenaar van uw gesprekken."; +"onboarding_splash_login_button_title" = "Ik heb al een account"; + +// Onboarding +"onboarding_splash_register_button_title" = "Account aanmaken"; From 16025f30f8cb0ae3c1cd739f30b295b3b0ba0112 Mon Sep 17 00:00:00 2001 From: lvre <7uu3qrbvm@relay.firefox.com> Date: Fri, 21 Jan 2022 11:16:11 +0000 Subject: [PATCH 192/209] Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ --- Riot/Assets/pt_BR.lproj/Vector.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Assets/pt_BR.lproj/Vector.strings b/Riot/Assets/pt_BR.lproj/Vector.strings index 0da05e327..8e6dbc79e 100644 --- a/Riot/Assets/pt_BR.lproj/Vector.strings +++ b/Riot/Assets/pt_BR.lproj/Vector.strings @@ -1554,7 +1554,7 @@ "analytics_prompt_message_new_user" = "Ajude-nos a identificar problemas e melhorar %@ ao compartilhar dados de uso anônimos. Para entender como pessoas usam múltiplos dispositivos, nós geramos um identificador aleatório, compartilhado por seus dispositivos."; // Analytics -"analytics_prompt_title" = "Ajudar a melhorar %@"; +"analytics_prompt_title" = "Ajude a melhorar %@"; "settings_analytics_and_crash_data" = "Enviar dados de crash e analítica"; "accessibility_button_label" = "botão"; "enable" = "Habilitar"; From 86e80b7cd3c0e894e2450e692a7a642faf1fc37a Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 24 Jan 2022 10:25:37 +0100 Subject: [PATCH 193/209] PlainRoomTimelineCellProvider: Fix outgoing text message cells. --- .../BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m index 54ad2569a..e36abb851 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Plain/PlainRoomTimelineCellProvider.m @@ -272,7 +272,7 @@ NSDictionary *incomingTextMessageCellsMapping = [self incomingTextMessageCellsMapping]; [cellClasses addEntriesFromDictionary:incomingTextMessageCellsMapping]; - NSDictionary *outgoingTextMessageCellsMapping = [self incomingTextMessageCellsMapping]; + NSDictionary *outgoingTextMessageCellsMapping = [self outgoingTextMessageCellsMapping]; [cellClasses addEntriesFromDictionary:outgoingTextMessageCellsMapping]; // Attachment From c527656e79811c76c89eecc5b40aa84a2df29927 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 24 Jan 2022 11:10:59 +0100 Subject: [PATCH 194/209] Message bubbles: Handle file messages. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- .../Styles/Bubble/BubbleRoomTimelineCellDecorator.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index efa90a5e0..3fe1930fa 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -165,7 +165,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating { let messageType = MXMessageType(identifier: messageTypeString) switch messageType { - case .text : + case .text, .file: return true default: break diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 8fd1ccbcd..31c477706 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -215,7 +215,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { let messageType = MXMessageType(identifier: messageTypeString) switch messageType { - case .text: + case .text, .file: return true default: break From 60f423c923e8b2a28b68fb22ca2fd389ce1e0e31 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Mon, 24 Jan 2022 11:14:30 +0100 Subject: [PATCH 195/209] Message bubbles: Handle emotes. --- .../BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift | 2 +- .../Styles/Bubble/BubbleRoomTimelineCellDecorator.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift index 3fe1930fa..42c0f3aac 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomCellLayoutUpdater.swift @@ -165,7 +165,7 @@ class BubbleRoomCellLayoutUpdater: RoomCellLayoutUpdating { let messageType = MXMessageType(identifier: messageTypeString) switch messageType { - case .text, .file: + case .text, .emote, .file: return true default: break diff --git a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift index 31c477706..2ea6ab381 100644 --- a/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift +++ b/Riot/Modules/Room/Views/BubbleCells/Styles/Bubble/BubbleRoomTimelineCellDecorator.swift @@ -215,7 +215,7 @@ class BubbleRoomTimelineCellDecorator: PlainRoomTimelineCellDecorator { let messageType = MXMessageType(identifier: messageTypeString) switch messageType { - case .text, .file: + case .text, .emote, .file: return true default: break From 8836d6d0cf9ec3406fb3ed73f53dd6103fa46a09 Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 25 Jan 2022 03:22:56 +0300 Subject: [PATCH 196/209] Fix tab bar badges on section-only updates --- Riot/Modules/Common/Recents/RecentsViewController.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Riot/Modules/Common/Recents/RecentsViewController.m b/Riot/Modules/Common/Recents/RecentsViewController.m index f950b2b23..1e23a936c 100644 --- a/Riot/Modules/Common/Recents/RecentsViewController.m +++ b/Riot/Modules/Common/Recents/RecentsViewController.m @@ -1025,6 +1025,12 @@ NSString *const RecentsViewControllerDataReadyNotification = @"RecentsViewContro { [super dataSource:dataSource didCellChange:changes]; } + else + { + // Since we've enabled room list pagination, `refreshRecentsTable` not called in this case. + // Refresh tab bar badges separately. + [[AppDelegate theDelegate].masterTabBarController refreshTabBarBadges]; + } if (changes == nil) { From 0d725002c24fedcdafb12e932093668cd7c178cb Mon Sep 17 00:00:00 2001 From: ismailgulek Date: Tue, 25 Jan 2022 03:23:41 +0300 Subject: [PATCH 197/209] Add changelog --- changelog.d/5421.bugfix | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/5421.bugfix diff --git a/changelog.d/5421.bugfix b/changelog.d/5421.bugfix new file mode 100644 index 000000000..97de8c3cb --- /dev/null +++ b/changelog.d/5421.bugfix @@ -0,0 +1 @@ +RecentsViewController: Update tab bar badges on section-only updates. From 9791bf81bff155f6a871ea6f0b9437985ce41fc8 Mon Sep 17 00:00:00 2001 From: SBiOSoftWhare Date: Tue, 25 Jan 2022 10:06:08 +0100 Subject: [PATCH 198/209] BuildSettings: Disable room timeline style configuration atm. --- Config/BuildSettings.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Config/BuildSettings.swift b/Config/BuildSettings.swift index 076d8dec9..3f3e1c15c 100644 --- a/Config/BuildSettings.swift +++ b/Config/BuildSettings.swift @@ -293,7 +293,7 @@ final class BuildSettings: NSObject { static let roomScreenAllowFilesAction: Bool = true // Timeline style - static let roomScreenAllowTimelineStyleConfiguration: Bool = true + static let roomScreenAllowTimelineStyleConfiguration: Bool = false static let roomScreenTimelineDefaultStyleIdentifier: RoomTimelineStyleIdentifier = .plain static var roomScreenEnableMessageBubblesByDefault: Bool { return self.roomScreenTimelineDefaultStyleIdentifier == .bubble From e7bd09ad6ed40c345c2c290f7e18ec5e3b04246f Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 25 Jan 2022 08:43:20 +0000 Subject: [PATCH 199/209] Update Analytics docs. --- Riot/Modules/Analytics/Analytics.swift | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Riot/Modules/Analytics/Analytics.swift b/Riot/Modules/Analytics/Analytics.swift index 6a48f5c6c..3f6147c6a 100644 --- a/Riot/Modules/Analytics/Analytics.swift +++ b/Riot/Modules/Analytics/Analytics.swift @@ -23,11 +23,14 @@ import AnalyticsEvents /// ## Creating Analytics Events /// /// Events are managed in a shared repo for all Element clients https://github.com/matrix-org/matrix-analytics-events -/// To add a new event create a PR to that repo with the new/updated schema. +/// To add a new event create a PR to that repo with the new/updated schema. Element's Podfile has +/// a local version of the pod (commented out) for development purposes. /// Once merged into `main`, follow the steps below to integrate the changes into the project: -/// 1. Merge `main` into the `release/swift` branch. -/// 2. Run `bundle exec pod update AnalyticsEvents` to update the pod. -/// 3. Make sure to commit `Podfile.lock` with the new commit hash. +/// 1. Check if `main` contains any source breaking changes to the events. If so, please +/// wait until you are ready to merge your work into element-ios. +/// 2. Merge `main` into the `release/swift` branch. +/// 3. Run `bundle exec pod update AnalyticsEvents` to update the pod. +/// 4. Make sure to commit `Podfile.lock` with the new commit hash. /// @objcMembers class Analytics: NSObject { From bb5b0f1e126a453b3fc2738ae6de8263264bdf38 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Jan 2022 11:25:41 +0100 Subject: [PATCH 200/209] Add case for local or non public homeserver. (#5431) * Add case for local or non public homeserver. See https://github.com/vector-im/element-android/pull/4963 Co-authored-by: Kat Gerasimova --- .github/ISSUE_TEMPLATE/bug.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index f170a1fd1..697e08e0e 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -57,8 +57,9 @@ body: id: homeserver attributes: label: Homeserver - description: Which server is your account registered on? - placeholder: e.g. matrix.org + description: | + Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version. + placeholder: e.g. matrix.org or Synapse 1.50.0rc1 validations: required: false - type: dropdown From 60fc31d04dee327081082c006f31e1f2bc670d55 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Tue, 25 Jan 2022 09:07:21 +0000 Subject: [PATCH 201/209] Translated using Weblate (French) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/fr/ --- Riot/Assets/fr.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/fr.lproj/InfoPlist.strings b/Riot/Assets/fr.lproj/InfoPlist.strings index 38d044ce1..c2a08df8d 100644 --- a/Riot/Assets/fr.lproj/InfoPlist.strings +++ b/Riot/Assets/fr.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSContactsUsageDescription" = "Element affichera vos contacts pour que vous puissiez les inviter à parler."; "NSCalendarsUsageDescription" = "Voir vos rendez-vous dans l’application."; "NSFaceIDUsageDescription" = "Face ID est utilisé pour accéder à votre application."; +"NSLocationWhenInUseUsageDescription" = "Element doit accéder à votre emplacement pour vous permettre de la partager aux autres utilisateurs sur une carte."; From 0b4eba4c99e6043e6f8dc78fd7342e181cdb3836 Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Tue, 25 Jan 2022 08:48:09 +0000 Subject: [PATCH 202/209] Translated using Weblate (French) Currently translated at 99.7% (441 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/fr/ --- .../Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings index 61a64b321..03688dc76 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/fr.lproj/MatrixKit.strings @@ -275,7 +275,7 @@ "notice_conference_call_started" = "Téléconférence en VoIP démarrée"; "notice_conference_call_finished" = "Téléconférence en VoIP terminée"; // button names -"ok" = "OK"; +"ok" = "Ok"; "send" = "Envoyer"; "copy_button_name" = "Copier"; "resend" = "Renvoyer"; From 515be1e04e30fdd7e36cd75ffb82b5384ca3d792 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 24 Jan 2022 20:49:34 +0000 Subject: [PATCH 203/209] Translated using Weblate (Swedish) Currently translated at 100.0% (49 of 49 strings) Translation: Element iOS/Element iOS (Push) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-push/sv/ --- Riot/Assets/sv.lproj/Localizable.strings | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Riot/Assets/sv.lproj/Localizable.strings b/Riot/Assets/sv.lproj/Localizable.strings index 4883fb894..9c4df7f81 100644 --- a/Riot/Assets/sv.lproj/Localizable.strings +++ b/Riot/Assets/sv.lproj/Localizable.strings @@ -116,3 +116,6 @@ /** General **/ "NOTIFICATION" = "Avisering"; + +/* New file message from a specific person, not referencing a room. */ +"LOCATION_FROM_USER" = "%@ delade sin plats"; From 806b8974bb0a37162bcb4632ba15e99a547ea18f Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 24 Jan 2022 20:48:24 +0000 Subject: [PATCH 204/209] Translated using Weblate (Swedish) Currently translated at 100.0% (7 of 7 strings) Translation: Element iOS/Element iOS (Dialogs) Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios-dialogs/sv/ --- Riot/Assets/sv.lproj/InfoPlist.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Assets/sv.lproj/InfoPlist.strings b/Riot/Assets/sv.lproj/InfoPlist.strings index 45ccee26b..4d03e8e0c 100644 --- a/Riot/Assets/sv.lproj/InfoPlist.strings +++ b/Riot/Assets/sv.lproj/InfoPlist.strings @@ -5,3 +5,4 @@ "NSMicrophoneUsageDescription" = "Element behöver åtkomst till din mikrofon för att kunna ringa och ta emot samtal samt spela in video och röstmeddelanden."; "NSContactsUsageDescription" = "Element kommer att visa dina kontakter så du kan bjuda in dem att chatta."; "NSFaceIDUsageDescription" = "Face ID används för att komma åt appen."; +"NSLocationWhenInUseUsageDescription" = "När du delar din plats med folk så behöver Element åtkomst för att visa dem en karta."; From aaabbd9ed22c50b6b7252f9a087c0571ad04a210 Mon Sep 17 00:00:00 2001 From: LinAGKar Date: Mon, 24 Jan 2022 20:48:38 +0000 Subject: [PATCH 205/209] Translated using Weblate (Swedish) Currently translated at 100.0% (442 of 442 strings) Translation: Element iOS/Element iOS (MatrixKit) Translate-URL: https://translate.element.io/projects/riot-ios/element-ios-matrixkit/sv/ --- .../Assets/MatrixKitAssets.bundle/sv.lproj/MatrixKit.strings | 1 + 1 file changed, 1 insertion(+) diff --git a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sv.lproj/MatrixKit.strings b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sv.lproj/MatrixKit.strings index 2dba03f74..d030f2d6e 100644 --- a/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sv.lproj/MatrixKit.strings +++ b/Riot/Modules/MatrixKit/Assets/MatrixKitAssets.bundle/sv.lproj/MatrixKit.strings @@ -478,3 +478,4 @@ "attachment_unsupported_preview_message" = "Den här filtypen stöds inte."; "attachment_unsupported_preview_title" = "Kunde inte förhandsgranska"; "room_displayname_all_other_members_left" = "%@ (Kvar)"; +"message_reply_to_sender_sent_their_location" = "har delat sin plats."; From ec206e35b5dad29b6f830b32f457fcac2448f7cb Mon Sep 17 00:00:00 2001 From: Thibault Martin Date: Tue, 25 Jan 2022 09:01:00 +0000 Subject: [PATCH 206/209] Translated using Weblate (French) Currently translated at 100.0% (1396 of 1396 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/fr/ --- Riot/Assets/fr.lproj/Vector.strings | 33 +++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/Riot/Assets/fr.lproj/Vector.strings b/Riot/Assets/fr.lproj/Vector.strings index aafd1db9a..0f012f74f 100644 --- a/Riot/Assets/fr.lproj/Vector.strings +++ b/Riot/Assets/fr.lproj/Vector.strings @@ -1492,7 +1492,7 @@ "space_private_join_rule" = "Espace privé"; "space_participants_action_ban" = "Supprimer de cet espace"; "space_participants_action_remove" = "Enlever de cet espace"; -"spaces_coming_soon_detail" = "Cette fonctionnalité n’a pas été implémentée ici, mais elle arrive. Pour effectuer cette action, vous pouvez utiliser Element sur votre ordinateur."; +"spaces_coming_soon_detail" = "Cette fonctionnalité n’a pas été implémentée ici, mais elle arrive. Pour effectuer cette action, vous pouvez utiliser %@ sur votre ordinateur."; "spaces_invites_coming_soon_title" = "Les invitations arrivent prochainement"; "spaces_add_rooms_coming_soon_title" = "L’ajout de salons arrive bientôt"; "spaces_coming_soon_title" = "Prochainement"; @@ -1581,7 +1581,7 @@ /* Note: The placeholder is for the contents of analytics_prompt_terms_link_new_user */ "analytics_prompt_terms_new_user" = "Vous pouvez lire nos conditions d’utilisation %@."; "analytics_prompt_message_upgrade" = "Vous aviez consenti précédemment à partager des rapports d’utilisation avec nous. Désormais, pour nous aider à comprendre comment les gens utilisent cette application sur plusieurs appareils, nous allons générer un identifiant aléatoire commun à tous vos appareils."; -"analytics_prompt_message_new_user" = "Aidez nous à identifier les problèmes et améliorer Element en envoyant des rapports d’usage anonymes. Pour comprendre de quelle manière les gens utilisent Element sur plusieurs appareils, nous créeront un identifiant aléatoire commun à tous vos appareils."; +"analytics_prompt_message_new_user" = "Aidez nous à identifier les problèmes et améliorer %@ en envoyant des rapports d’usage anonymes. Pour comprendre de quelle manière les gens utilisent Element sur plusieurs appareils, nous créeront un identifiant aléatoire commun à tous vos appareils."; // Analytics "analytics_prompt_title" = "Aidez à améliorer %@"; @@ -1604,3 +1604,32 @@ "find_your_contacts_title" = "Commencez par lister vos contacts"; "settings_contacts_enable_sync_description" = "Cette fonctionnalité utilisera votre serveur d'identité pour vous connecter avec vos contacts, ainsi que pour les aider à vous trouver."; "settings_contacts_enable_sync" = "Trouvez vos contacts"; +"location_sharing_settings_toggle_title" = "Activer le partage de localisation"; +"location_sharing_settings_header" = "Partage de localisation"; +"location_sharing_open_google_maps" = "Ouvrir dans Google Maps"; +"location_sharing_open_apple_maps" = "Ouvrir dans Apple Plans"; +"location_sharing_invalid_authorization_settings" = "Paramètres"; +"location_sharing_invalid_authorization_not_now" = "Pas maintenant"; +"location_sharing_invalid_authorization_error_title" = "%@ n’a pas les autorisations pour accéder à votre localisation. Vous pouvez l’autoriser dans Réglages > Confidentialité"; +"location_sharing_locating_user_error_title" = "%@ n’a pas pu déterminer votre localisation. Veuillez ré-essayer plus tard."; +"location_sharing_loading_map_error_title" = "%@ n’a pas pu charger la carte. Veuillez ré-essayer plus tard."; +"location_sharing_share_action" = "Partager"; +"location_sharing_close_action" = "Fermer"; + +// MARK: - Location sharing + +"location_sharing_title" = "Localisation"; +"settings_enable_room_message_bubbles" = "Messages en bulles"; +"onboarding_splash_page_4_message" = "Element est parfaite pour le bureau. Les sociétés aux plus gros besoins de sécurité lui font confiance."; +"onboarding_splash_page_4_title_no_pun" = "Une messagerie pour votre équipe."; +"onboarding_splash_page_3_message" = "Chiffrée de bout en bout, aucun numéro de téléphone requis. Pas de pub ni d’exploitation de données."; +"onboarding_splash_page_3_title" = "Messagerie sécurisée."; +"onboarding_splash_page_2_message" = "Décidez où vos conversations sont stockées, en toute liberté et indépendance. Grâce à Matrix."; +"onboarding_splash_page_2_title" = "C’est vous qui décidez."; +"onboarding_splash_page_1_message" = "Une messagerie sécurisée et indépendante qui vous garantit le même niveau de confidentialité qu’une conversation en face à face chez vous."; +"onboarding_splash_page_1_title" = "Maîtrisez vos conversations."; +"onboarding_splash_login_button_title" = "J’ai déjà un compte"; + +// Onboarding +"onboarding_splash_register_button_title" = "Créer un compte"; +"ok" = "Ok"; From a3e293c9c9599288ce7caa425379879bd1d41523 Mon Sep 17 00:00:00 2001 From: Kat Gerasimova Date: Tue, 25 Jan 2022 12:10:49 +0000 Subject: [PATCH 207/209] Fix issue template indentation --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 697e08e0e..88458a696 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -58,7 +58,7 @@ body: attributes: label: Homeserver description: | - Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version. + Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version. placeholder: e.g. matrix.org or Synapse 1.50.0rc1 validations: required: false From de2e8cc57f3b5718bea28e5018bb0e49bb316ca4 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 25 Jan 2022 12:58:20 +0000 Subject: [PATCH 208/209] changelog.d: Upgrade MatrixSDK version ([v0.21.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.21.0)). --- Config/AppVersion.xcconfig | 4 ++-- Podfile | 2 +- changelog.d/x-nolink-0.change | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 changelog.d/x-nolink-0.change diff --git a/Config/AppVersion.xcconfig b/Config/AppVersion.xcconfig index f0f3b8161..08d0bfcfc 100644 --- a/Config/AppVersion.xcconfig +++ b/Config/AppVersion.xcconfig @@ -15,5 +15,5 @@ // // Version -MARKETING_VERSION = 1.6.13 -CURRENT_PROJECT_VERSION = 1.6.13 +MARKETING_VERSION = 1.7.0 +CURRENT_PROJECT_VERSION = 1.7.0 diff --git a/Podfile b/Podfile index 1898c52bb..495a84db4 100644 --- a/Podfile +++ b/Podfile @@ -13,7 +13,7 @@ use_frameworks! # - `{ :specHash => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for MatrixSDK repo. Used by Fastfile during CI # # Warning: our internal tooling depends on the name of this variable name, so be sure not to change it -$matrixSDKVersion = '= 0.20.16' +$matrixSDKVersion = '= 0.21.0' # $matrixSDKVersion = :local # $matrixSDKVersion = { :branch => 'develop'} # $matrixSDKVersion = { :specHash => { git: 'https://git.io/fork123', branch: 'fix' } } diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change new file mode 100644 index 000000000..5735b4206 --- /dev/null +++ b/changelog.d/x-nolink-0.change @@ -0,0 +1 @@ +Upgrade MatrixSDK version ([v0.21.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.21.0)). \ No newline at end of file From d0b9a8fe89f7b71c15239bb6548ac2d6de85bcb1 Mon Sep 17 00:00:00 2001 From: Doug Date: Tue, 25 Jan 2022 12:58:20 +0000 Subject: [PATCH 209/209] version++ --- CHANGES.md | 32 ++++++++++++++++++++++++++++++++ changelog.d/4208.bugfix | 1 - changelog.d/4384.change | 1 - changelog.d/5208.feature | 1 - changelog.d/5209.feature | 1 - changelog.d/5212.feature | 1 - changelog.d/5214.feature | 1 - changelog.d/5294.misc | 1 - changelog.d/5298.feature | 1 - changelog.d/5321.feature | 1 - changelog.d/5345.change | 1 - changelog.d/5375.bugfix | 1 - changelog.d/5399.bugfix | 1 - changelog.d/5402.bugfix | 1 - changelog.d/5404.bugfix | 1 - changelog.d/5407.bugfix | 1 - changelog.d/5421.bugfix | 1 - changelog.d/x-nolink-0.change | 1 - 18 files changed, 32 insertions(+), 17 deletions(-) delete mode 100644 changelog.d/4208.bugfix delete mode 100644 changelog.d/4384.change delete mode 100644 changelog.d/5208.feature delete mode 100644 changelog.d/5209.feature delete mode 100644 changelog.d/5212.feature delete mode 100644 changelog.d/5214.feature delete mode 100644 changelog.d/5294.misc delete mode 100644 changelog.d/5298.feature delete mode 100644 changelog.d/5321.feature delete mode 100644 changelog.d/5345.change delete mode 100644 changelog.d/5375.bugfix delete mode 100644 changelog.d/5399.bugfix delete mode 100644 changelog.d/5402.bugfix delete mode 100644 changelog.d/5404.bugfix delete mode 100644 changelog.d/5407.bugfix delete mode 100644 changelog.d/5421.bugfix delete mode 100644 changelog.d/x-nolink-0.change diff --git a/CHANGES.md b/CHANGES.md index 8c2112418..c5c23b33f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,35 @@ +## Changes in 1.7.0 (2022-01-25) + +✨ Features + +- Message bubbles: Text message layout. ([#5208](https://github.com/vector-im/element-ios/issues/5208)) +- Message Bubbles: Layout for Media. ([#5209](https://github.com/vector-im/element-ios/issues/5209)) +- Message Bubbles: Support URL Previews. ([#5212](https://github.com/vector-im/element-ios/issues/5212)) +- Message Bubbles: Support reactions. ([#5214](https://github.com/vector-im/element-ios/issues/5214)) +- Added static location sharing sending and rendering support. ([#5298](https://github.com/vector-im/element-ios/issues/5298)) +- Message bubbles: Add settings and build flag. ([#5321](https://github.com/vector-im/element-ios/issues/5321)) + +🙌 Improvements + +- Upgrade MatrixSDK version ([v0.21.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.21.0)). +- Using mutable room list fetch sort options after chaning them to be a structure. Adaptation to MXStore api changes. ([#4384](https://github.com/vector-im/element-ios/issues/4384)) +- Reduce grace period to report decryption failure ([#5345](https://github.com/vector-im/element-ios/issues/5345)) + +🐛 Bugfixes + +- Fixed home screen not updating properly on theme changes. ([#4208](https://github.com/vector-im/element-ios/issues/4208)) +- Fixes DTMF(dial tones) during voice calls. ([#5375](https://github.com/vector-im/element-ios/issues/5375)) +- Fix crash when uploading a video on iPad when "Confirm size when sending" is enabled in settings. ([#5399](https://github.com/vector-im/element-ios/issues/5399)) +- Fix BuildSetting to show/hide the "Invite Friends" button in the side SideMenu. ([#5402](https://github.com/vector-im/element-ios/issues/5402)) +- Add BuildSetting to hide social login in favour of the simple SSO button. ([#5404](https://github.com/vector-im/element-ios/issues/5404)) +- Fix grey spinner showing indefinitely over the home view after launch. ([#5407](https://github.com/vector-im/element-ios/issues/5407)) +- RecentsViewController: Update tab bar badges on section-only updates. ([#5421](https://github.com/vector-im/element-ios/issues/5421)) + +Others + +- Fix graphql warnings in issue workflow automation ([#5294](https://github.com/vector-im/element-ios/issues/5294)) + + ## Changes in 1.6.12 (2022-01-11) 🙌 Improvements diff --git a/changelog.d/4208.bugfix b/changelog.d/4208.bugfix deleted file mode 100644 index 135c79d86..000000000 --- a/changelog.d/4208.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixed home screen not updating properly on theme changes. \ No newline at end of file diff --git a/changelog.d/4384.change b/changelog.d/4384.change deleted file mode 100644 index 13dd82545..000000000 --- a/changelog.d/4384.change +++ /dev/null @@ -1 +0,0 @@ -Using mutable room list fetch sort options after chaning them to be a structure. Adaptation to MXStore api changes. diff --git a/changelog.d/5208.feature b/changelog.d/5208.feature deleted file mode 100644 index 1883900f3..000000000 --- a/changelog.d/5208.feature +++ /dev/null @@ -1 +0,0 @@ -Message bubbles: Text message layout. \ No newline at end of file diff --git a/changelog.d/5209.feature b/changelog.d/5209.feature deleted file mode 100644 index 30ed3c629..000000000 --- a/changelog.d/5209.feature +++ /dev/null @@ -1 +0,0 @@ -Message Bubbles: Layout for Media. \ No newline at end of file diff --git a/changelog.d/5212.feature b/changelog.d/5212.feature deleted file mode 100644 index abb4530c7..000000000 --- a/changelog.d/5212.feature +++ /dev/null @@ -1 +0,0 @@ -Message Bubbles: Support URL Previews. \ No newline at end of file diff --git a/changelog.d/5214.feature b/changelog.d/5214.feature deleted file mode 100644 index 31d4c5a0e..000000000 --- a/changelog.d/5214.feature +++ /dev/null @@ -1 +0,0 @@ -Message Bubbles: Support reactions. \ No newline at end of file diff --git a/changelog.d/5294.misc b/changelog.d/5294.misc deleted file mode 100644 index c1a31bb4a..000000000 --- a/changelog.d/5294.misc +++ /dev/null @@ -1 +0,0 @@ -Fix graphql warnings in issue workflow automation diff --git a/changelog.d/5298.feature b/changelog.d/5298.feature deleted file mode 100644 index 605f18e07..000000000 --- a/changelog.d/5298.feature +++ /dev/null @@ -1 +0,0 @@ -Added static location sharing sending and rendering support. \ No newline at end of file diff --git a/changelog.d/5321.feature b/changelog.d/5321.feature deleted file mode 100644 index 8fc5d69a2..000000000 --- a/changelog.d/5321.feature +++ /dev/null @@ -1 +0,0 @@ -Message bubbles: Add settings and build flag. \ No newline at end of file diff --git a/changelog.d/5345.change b/changelog.d/5345.change deleted file mode 100644 index 80ee600a1..000000000 --- a/changelog.d/5345.change +++ /dev/null @@ -1 +0,0 @@ -Reduce grace period to report decryption failure diff --git a/changelog.d/5375.bugfix b/changelog.d/5375.bugfix deleted file mode 100644 index b8c851286..000000000 --- a/changelog.d/5375.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fixes DTMF(dial tones) during voice calls. diff --git a/changelog.d/5399.bugfix b/changelog.d/5399.bugfix deleted file mode 100644 index 015ecfc41..000000000 --- a/changelog.d/5399.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix crash when uploading a video on iPad when "Confirm size when sending" is enabled in settings. diff --git a/changelog.d/5402.bugfix b/changelog.d/5402.bugfix deleted file mode 100644 index 44e0c482e..000000000 --- a/changelog.d/5402.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix BuildSetting to show/hide the "Invite Friends" button in the side SideMenu. diff --git a/changelog.d/5404.bugfix b/changelog.d/5404.bugfix deleted file mode 100644 index 1c829a4f0..000000000 --- a/changelog.d/5404.bugfix +++ /dev/null @@ -1 +0,0 @@ -Add BuildSetting to hide social login in favour of the simple SSO button. diff --git a/changelog.d/5407.bugfix b/changelog.d/5407.bugfix deleted file mode 100644 index f4ed72863..000000000 --- a/changelog.d/5407.bugfix +++ /dev/null @@ -1 +0,0 @@ -Fix grey spinner showing indefinitely over the home view after launch. diff --git a/changelog.d/5421.bugfix b/changelog.d/5421.bugfix deleted file mode 100644 index 97de8c3cb..000000000 --- a/changelog.d/5421.bugfix +++ /dev/null @@ -1 +0,0 @@ -RecentsViewController: Update tab bar badges on section-only updates. diff --git a/changelog.d/x-nolink-0.change b/changelog.d/x-nolink-0.change deleted file mode 100644 index 5735b4206..000000000 --- a/changelog.d/x-nolink-0.change +++ /dev/null @@ -1 +0,0 @@ -Upgrade MatrixSDK version ([v0.21.0](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.21.0)). \ No newline at end of file