mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-21 00:52:43 +02:00
d572d54a0f
* Update voice broadcast tiles UI (#6965) * Translated using Weblate (German) Currently translated at 100.0% (2307 of 2307 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * speeding the animation a bit * tests and identifier improvements * fix * changelog * removed unused code * Avoid unnecessary send state request (#6970) * comment * Curate MXCrypto protocol methods * Add voice broadcast initial state in bubble data (#6972) - Add voice broadcast initial state in bubble data - Remove the local record after sending * Voice Broadcast: log and block unexpected state change * Sing out bottom bar * new line * Enable WYSIWYG plain text support * Remove change on Apple swift-collections revision * removed RiotSettings a non RiotSwiftUI reference from the ViewState code * fixed a test * Complete MXCryptoV2 implementation * Multi session logut * Switch the CI to code 14 and the iOS 14 simulator, fix UI tests * Fixes #6987 - Prevent ZXing from unnecessarily requesting camera access * Fixes #6988 - Prevent actor switching when tearing down the rendezvous * Separator fix * Removed warnings * add Z-Labs tag or rich text editor and update to the new label naming * changelog * Hide old sessions list when the new dm is enabled * Add changelog.d file * Sing out filtering * Avoid simultaneous state changes (#6986) * Improve kebab menu in UserSessionOverview * Add UI tests * Add changelog.d file * No customization for emptycell (#7000) * PSG-976 Exclude current session from security recommendations and other sessions * Padding fix * Fixed unit tests * Add empty onLearnMoreAction closure * Add InfoView skeleton * Add UserSessionOverviewViewBindings * Style info view * Add bottom sheet modifier * Localise content * Add inactive sessions copy * Fix bug in InlineTextButton * Improve UserSessionCardView * Add “learn more” button in UserOtherSessions * Show bottom sheet in user other sessions * Show rename info alert * Refine UX * Add iOS 15- fallback * Refine InfoView * Add UI tests * Improve UserOtherSessionsUITests * Improve InlineTextButton API * Add changelod.d file * Fix failing UTs * Hide keyboard in UserSessionName * Add .viewSessionInfo view action * Voice Broadcast - BugFix - send the last chunk (#7002) * Voice Broadcast - BugFix - send the last chunk with the right sequence number - we reset now and teardown the service only after the last chunk is sent * updated package + tests * change log * Bug Fix : Crash if the room has avatar and voice broadcast tiles * Add MVVM-C for InfoSheet * improving UI tests for slow CI * removing comment * test improvements for slow ci * Show bottom sheet in other sessions screen * Show bottom sheet in rename session screen * Delete bottom sheet modifier * Show rename sheet * UI and unit tests * Refresh fix * Changelog * Add InfoSheet SwiftUI preview * simplify the test to make it pass on the CI * Fix memory leak * Cleanup UI tests * improving tests for the CI * Fixed IRC-style message and commands support in Rich text editor * tests updated for the CI * test improvements * removing a test that can't pass on the CI due to its speed * Changelog * CryptoV2 changes * Display crypto version * Voice broadcast - Disable the sleep mode during the recording until we are able to handle it Currently go to "sleep mode" pauses the voice broadcast recording * Add issue automation for the VoIP team * Renamed sign out to logout * Renamed sign out to logout * Renamed sign out to logout * Sign out of all other sessions * Fix typo in issue automation * Fixed unit tests * Translations update from Weblate (#7017) * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Dutch) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Johan Smits <johan@smitsmail.net> * Prepare for new sprint * Prepare for new sprint * Threads: added support to read receipts (MSC3771) - Update after review * Threads: added support to notifications count (MSC3773) * Update RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift Co-authored-by: aringenbach <80891108+aringenbach@users.noreply.github.com> * Update RiotSwiftUI/Modules/UserSessions/UserOtherSessions/Test/UI/UserOtherSessionsUITests.swift Co-authored-by: aringenbach <80891108+aringenbach@users.noreply.github.com> * Comment fix * the test may fail on CI without blocking the task/check * tests may fail on CI * test improvement * test may fail on CI * Hide push toggles for http pushers when there is no server support * changelog * Code review fixes * Threads: added support to read receipts (MSC3771) - Update after review * Synchronise composer and toolbar resizing animation duration * Add kResizeComposerAnimationDuration constant description * fix for 6946 * Threads: add support to labs flag for read receipts * Cleanup * Code review fixes, created DestructiveButton * Update issue automation Stop using deprecated ProjectNext API in favour of the new ProjectV2 one * Update PR automation Stop using deprecated ProjectNext API in favour of the new ProjectV2 one * Code review fixes * Map location info * Map location info * Add location feature in UserSessionsOverview * Add “show location” feature in other sessions list * Add “show location“ feature in session overview * Fix Package.resolved * Cleanup merge leftovers * Cleanup code * Cleanup * Add show/hide ip persistency * Add location info in UserOtherSessions * Refine settings logic * Mock settings in UserSessionsOverviewViewModel * Add settings service in UserOtherSessionsViewModel * Inject setting service in UserSessionOverviewViewModel * Add changelog.d file * Fix UTs * Cleanup merge leftovers * Add animations * Fix failing test * Amend title font * Amend copies * Device Manager: Session list item is not tappable everywhere * changelog * Threads notification count in main timeline including un participated threads * Changed title and body * Removed "Do not ask again" button * Remove indication about plain text mode coming soon * Prevent `Unable to activate constraint with anchors .. because they have no common ancestor.` crashes. Only link toasts to the top safe area instead of the navigation controller * Revert "Replace attributed string height calculation with a more reliable implementation" This reverts commit 81773cd1e515cc391c1f21b499f61141cb03c810. * Revert "Fix timeline items text height calculation" This reverts commit 8f9eddee501702de84192316bd5b2ff9512d681a. * Revert "Fixes vector-im/element-ios/issues/6441 - Incorrect timeline item text height calculation (#6679)" This reverts commit 405c2d8e324c08c1a40e037aeb3c54e93f30bc9f. * Fixes vector-im/element-ios/issues/6441 - Incorrect timeline item text height calculation * Prepare for new sprint * Refine bottom sheet layout * updated pod * changelog * Switch to using an API key for interactions with AppStoreConnect while on CI; update fastlane and dependencies * Rich-text editor: Fix text formatting enabled inconsistent state * Labs: Rich-text editor - Fix text formatting switch losing the current content of the composer * Re-order View computed properties and move to private mark * Add intrinsic sized bottom sheet * Snooze controller * Changelog * Fix composer view model tests * Rich-text editor: enable translations between Markdown and HTML when toggling text formatting * Force a layout on the room bubble cell messageTextView to get a correct frame * Move Move UserAgentParserTests * Add UserSessionDetailsUITests * Improve UserSessionNameUITests * Cleanup tests * Improve UserSessionNameViewModelTests * Test empty state for UserOtherSessions * Fix typo * Cleanup unused code * Add changelog.d file * Threads: removed "unread_thread_notifications" from sync filters for server that doesn't support MSC3773 * Remove 10s wait on failed initial sync * Threads: removed "unread_thread_notifications" from sync filters for server that doesn't support MSC3773 - Update after review * Revert "Device Manager: Session list item is not tappable everywhere" This reverts commit e6367cba4c8f0cb2cdfe5e3381dcbb7bc0f94c52. * Fixup session list item is not tappable everywhere * Fix accessibility id in UserOtherSessions * Poll not usable after logging out and back in * Changelog * Removed init * voice dictation now works * plain text * Add voice broadcast slider (#7010) * Display number of unread messages above threads button * Translations update from Weblate (#7080) * Translated using Weblate (Dutch) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ * Translated using Weblate (German) Currently translated at 100.0% (2311 of 2311 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Dutch) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ * Translated using Weblate (German) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Albanian) Currently translated at 99.6% (2303 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sq/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2312 of 2312 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (German) Currently translated at 100.0% (2313 of 2313 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2313 of 2313 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2313 of 2313 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Dutch) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/nl/ * Translated using Weblate (German) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Italian) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2315 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Albanian) Currently translated at 99.5% (2305 of 2315 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sq/ * Translated using Weblate (German) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Japanese) Currently translated at 66.2% (1534 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ja/ * Translated using Weblate (Portuguese (Brazil)) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/pt_BR/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2317 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Japanese) Currently translated at 66.2% (1534 of 2317 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ja/ * Translated using Weblate (German) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (German) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/de/ * Translated using Weblate (Ukrainian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/uk/ * Translated using Weblate (Estonian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/et/ * Translated using Weblate (Slovak) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/sk/ * Translated using Weblate (Italian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/it/ * Translated using Weblate (Hungarian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/hu/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (2326 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/id/ * Translated using Weblate (French) Currently translated at 97.6% (2272 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/fr/ * Translated using Weblate (Russian) Currently translated at 80.5% (1873 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ * Translated using Weblate (Russian) Currently translated at 80.7% (1879 of 2326 strings) Translation: Element iOS/Element iOS Translate-URL: https://translate.element.io/projects/riot-ios/riot-ios/ru/ Co-authored-by: Roel ter Maat <roel.termaat@nedap.com> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Besnik Bleta <besnik@programeshqip.org> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Suguru Hirahara <ovestekona@protonmail.com> Co-authored-by: Thibault Martin <mail@thibaultmart.in> Co-authored-by: Platon Terekhov <ockenfels_vevent@aleeas.com> * changelog.d: Upgrade MatrixSDK version ([v0.24.3](https://github.com/matrix-org/matrix-ios-sdk/releases/tag/v0.24.3)). * version++ Co-authored-by: giomfo <gforet@matrix.org> Co-authored-by: Yoan Pintas <y.pintas@gmail.com> Co-authored-by: Vri <element@vrifox.cc> Co-authored-by: Anderas <andyuhnak@gmail.com> Co-authored-by: Mauro Romito <mauro.romito@element.io> Co-authored-by: Velin92 <34335419+Velin92@users.noreply.github.com> Co-authored-by: Giom Foret <giom@matrix.org> Co-authored-by: Aleksandrs Proskurins <paleksandrs@gmail.com> Co-authored-by: aringenbach <arnaudr@element.io> Co-authored-by: manuroe <manuroe@users.noreply.github.com> Co-authored-by: David Langley <langley.dave@gmail.com> Co-authored-by: Stefan Ceriu <stefanc@matrix.org> Co-authored-by: Alfonso Grillo <alfogrillo@gmail.com> Co-authored-by: Alfonso Grillo <alfogrillo@element.io> Co-authored-by: Kat Gerasimova <ekaterinag@element.io> Co-authored-by: Element Translate Bot <admin@riot.im> Co-authored-by: lvre <7uu3qrbvm@relay.firefox.com> Co-authored-by: Priit Jõerüüt <riot@joeruut.com> Co-authored-by: Johan Smits <johan@smitsmail.net> Co-authored-by: gulekismail <ismailgulek0@gmail.com> Co-authored-by: Gil Eluard <gile@element.io> Co-authored-by: Aleksandrs Proskurins <aleksandrsp@element.io> Co-authored-by: aringenbach <80891108+aringenbach@users.noreply.github.com> Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com> Co-authored-by: Roel ter Maat <roel.termaat@nedap.com> Co-authored-by: Besnik Bleta <besnik@programeshqip.org> Co-authored-by: Ihor Hordiichuk <igor_ck@outlook.com> Co-authored-by: Linerly <linerly@protonmail.com> Co-authored-by: Jozef Gaal <preklady@mayday.sk> Co-authored-by: random <dictionary@tutamail.com> Co-authored-by: Szimszon <github@oregpreshaz.eu> Co-authored-by: Suguru Hirahara <ovestekona@protonmail.com> Co-authored-by: Thibault Martin <mail@thibaultmart.in> Co-authored-by: Platon Terekhov <ockenfels_vevent@aleeas.com>
346 lines
13 KiB
Swift
346 lines
13 KiB
Swift
// File created from ScreenTemplate
|
|
// $ createScreen.sh Threads/ThreadList ThreadList
|
|
/*
|
|
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
|
|
|
|
final class ThreadListViewModel: ThreadListViewModelProtocol {
|
|
|
|
// MARK: - Properties
|
|
|
|
// MARK: Private
|
|
|
|
private let session: MXSession
|
|
private let roomId: String
|
|
private var threads: [MXThreadProtocol] = []
|
|
private var eventFormatter: MXKEventFormatter?
|
|
private var roomState: MXRoomState?
|
|
|
|
private var currentOperation: MXHTTPOperation?
|
|
private var longPressedThread: MXThreadProtocol?
|
|
|
|
// MARK: Public
|
|
|
|
weak var viewDelegate: ThreadListViewModelViewDelegate?
|
|
weak var coordinatorDelegate: ThreadListViewModelCoordinatorDelegate?
|
|
var selectedFilterType: ThreadListFilterType = .all
|
|
|
|
private(set) var viewState: ThreadListViewState = .idle {
|
|
didSet {
|
|
self.viewDelegate?.threadListViewModel(self, didUpdateViewState: viewState)
|
|
}
|
|
}
|
|
|
|
// MARK: - Setup
|
|
|
|
init(session: MXSession,
|
|
roomId: String) {
|
|
self.session = session
|
|
self.roomId = roomId
|
|
session.threadingService.addDelegate(self)
|
|
}
|
|
|
|
deinit {
|
|
session.threadingService.removeDelegate(self)
|
|
self.cancelOperations()
|
|
}
|
|
|
|
// MARK: - Public
|
|
|
|
func process(viewAction: ThreadListViewAction) {
|
|
switch viewAction {
|
|
case .loadData:
|
|
loadData()
|
|
case .complete:
|
|
coordinatorDelegate?.threadListViewModelDidLoadThreads(self)
|
|
case .showFilterTypes:
|
|
viewState = .showingFilterTypes
|
|
case .selectFilterType(let type):
|
|
selectedFilterType = type
|
|
loadData()
|
|
case .selectThread(let index):
|
|
selectThread(index)
|
|
case .longPressThread(let index):
|
|
longPressThread(index)
|
|
case .actionViewInRoom:
|
|
actionViewInRoom()
|
|
case .actionCopyLinkToThread:
|
|
actionCopyLinkToThread()
|
|
case .actionShare:
|
|
actionShare()
|
|
case .cancel:
|
|
cancelOperations()
|
|
coordinatorDelegate?.threadListViewModelDidCancel(self)
|
|
}
|
|
}
|
|
|
|
var numberOfThreads: Int {
|
|
return threads.count
|
|
}
|
|
|
|
func threadModel(at index: Int) -> ThreadModel? {
|
|
guard index < threads.count else {
|
|
return nil
|
|
}
|
|
return model(forThread: threads[index])
|
|
}
|
|
|
|
var titleModel: ThreadRoomTitleModel {
|
|
guard let room = session.room(withRoomId: roomId) else {
|
|
return .empty
|
|
}
|
|
|
|
let avatarViewData = AvatarViewData(matrixItemId: room.matrixItemId,
|
|
displayName: room.displayName,
|
|
avatarUrl: room.mxContentUri,
|
|
mediaManager: room.mxSession.mediaManager,
|
|
fallbackImage: AvatarFallbackImage.matrixItem(room.matrixItemId,
|
|
room.displayName))
|
|
|
|
let encrpytionBadge: UIImage?
|
|
if let summary = room.summary, summary.isEncrypted, session.crypto != nil {
|
|
encrpytionBadge = EncryptionTrustLevelBadgeImageHelper.roomBadgeImage(for: summary.roomEncryptionTrustLevel())
|
|
} else {
|
|
encrpytionBadge = nil
|
|
}
|
|
|
|
return ThreadRoomTitleModel(roomAvatar: avatarViewData,
|
|
roomEncryptionBadge: encrpytionBadge,
|
|
roomDisplayName: room.displayName)
|
|
}
|
|
|
|
private var emptyViewModel: ThreadListEmptyModel {
|
|
switch selectedFilterType {
|
|
case .all:
|
|
return ThreadListEmptyModel(icon: Asset.Images.threadsIcon.image,
|
|
title: VectorL10n.threadsEmptyTitle,
|
|
info: VectorL10n.threadsEmptyInfoAll,
|
|
tip: VectorL10n.threadsEmptyTip,
|
|
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
|
showAllThreadsButtonHidden: true)
|
|
case .myThreads:
|
|
return ThreadListEmptyModel(icon: Asset.Images.threadsIcon.image,
|
|
title: VectorL10n.threadsEmptyTitle,
|
|
info: VectorL10n.threadsEmptyInfoMy,
|
|
tip: nil,
|
|
showAllThreadsButtonTitle: VectorL10n.threadsEmptyShowAllThreads,
|
|
showAllThreadsButtonHidden: false)
|
|
}
|
|
}
|
|
|
|
// MARK: - Private
|
|
|
|
private func model(forThread thread: MXThreadProtocol) -> ThreadModel {
|
|
let rootAvatarViewData: AvatarViewData?
|
|
let rootMessageSender: MXUser?
|
|
let lastAvatarViewData: AvatarViewData?
|
|
let lastMessageSender: MXUser?
|
|
let rootMessageText = rootMessageText(forThread: thread)
|
|
let (lastMessageText, lastMessageTime) = lastMessageTextAndTime(forThread: thread)
|
|
let notificationStatus = ThreadNotificationStatus(withThread: thread)
|
|
|
|
// root message
|
|
if let rootMessage = thread.rootMessage, let senderId = rootMessage.sender {
|
|
rootMessageSender = session.user(withUserId: rootMessage.sender)
|
|
|
|
let fallbackImage = AvatarFallbackImage.matrixItem(senderId,
|
|
rootMessageSender?.displayname)
|
|
rootAvatarViewData = AvatarViewData(matrixItemId: senderId,
|
|
displayName: rootMessageSender?.displayname,
|
|
avatarUrl: rootMessageSender?.avatarUrl,
|
|
mediaManager: session.mediaManager,
|
|
fallbackImage: fallbackImage)
|
|
} else {
|
|
rootAvatarViewData = nil
|
|
rootMessageSender = nil
|
|
}
|
|
|
|
// last message
|
|
if let lastMessage = thread.lastMessage, let senderId = lastMessage.sender {
|
|
lastMessageSender = session.user(withUserId: lastMessage.sender)
|
|
|
|
let fallbackImage = AvatarFallbackImage.matrixItem(senderId,
|
|
lastMessageSender?.displayname)
|
|
lastAvatarViewData = AvatarViewData(matrixItemId: senderId,
|
|
displayName: lastMessageSender?.displayname,
|
|
avatarUrl: lastMessageSender?.avatarUrl,
|
|
mediaManager: session.mediaManager,
|
|
fallbackImage: fallbackImage)
|
|
} else {
|
|
lastAvatarViewData = nil
|
|
lastMessageSender = nil
|
|
}
|
|
|
|
let summaryModel = ThreadSummaryModel(numberOfReplies: thread.numberOfReplies,
|
|
lastMessageSenderAvatar: lastAvatarViewData,
|
|
lastMessageText: lastMessageText)
|
|
|
|
return ThreadModel(rootMessageSenderUserId: rootMessageSender?.userId,
|
|
rootMessageSenderAvatar: rootAvatarViewData,
|
|
rootMessageSenderDisplayName: rootMessageSender?.displayname,
|
|
rootMessageText: rootMessageText,
|
|
rootMessageRedacted: thread.rootMessage?.isRedactedEvent() ?? false,
|
|
lastMessageTime: lastMessageTime,
|
|
summaryModel: summaryModel,
|
|
notificationStatus: notificationStatus)
|
|
}
|
|
|
|
private func rootMessageText(forThread thread: MXThreadProtocol) -> NSAttributedString? {
|
|
guard let eventFormatter = eventFormatter else {
|
|
return nil
|
|
}
|
|
guard let message = thread.rootMessage else {
|
|
return nil
|
|
}
|
|
let formatterError = UnsafeMutablePointer<MXKEventFormatterError>.allocate(capacity: 1)
|
|
return eventFormatter.attributedString(from: message.replyStrippedVersion,
|
|
with: roomState,
|
|
andLatestRoomState: nil,
|
|
error: formatterError)?.vc_byRemovingLinks
|
|
}
|
|
|
|
private func lastMessageTextAndTime(forThread thread: MXThreadProtocol) -> (NSAttributedString?, String?) {
|
|
guard let eventFormatter = eventFormatter else {
|
|
return (nil, nil)
|
|
}
|
|
guard let message = thread.lastMessage else {
|
|
return (nil, nil)
|
|
}
|
|
let formatterError = UnsafeMutablePointer<MXKEventFormatterError>.allocate(capacity: 1)
|
|
return (
|
|
eventFormatter.attributedString(from: message.replyStrippedVersion,
|
|
with: roomState,
|
|
andLatestRoomState: nil,
|
|
error: formatterError),
|
|
eventFormatter.dateString(from: message, withTime: true)
|
|
)
|
|
}
|
|
|
|
private func loadData(showLoading: Bool = true) {
|
|
|
|
if showLoading {
|
|
viewState = .loading
|
|
}
|
|
|
|
let onlyParticipated: Bool
|
|
|
|
switch selectedFilterType {
|
|
case .all:
|
|
onlyParticipated = false
|
|
case .myThreads:
|
|
onlyParticipated = true
|
|
}
|
|
|
|
session.threadingService.allThreads(inRoom: roomId,
|
|
onlyParticipated: onlyParticipated) { [weak self] response in
|
|
guard let self = self else { return }
|
|
switch response {
|
|
case .success(let threads):
|
|
self.threads = threads
|
|
self.threadsLoaded()
|
|
case .failure(let error):
|
|
MXLog.error("[ThreadListViewModel] loadData", context: error)
|
|
self.viewState = .error(error)
|
|
}
|
|
}
|
|
}
|
|
|
|
private func threadsLoaded() {
|
|
if threads.isEmpty {
|
|
viewState = .empty(emptyViewModel)
|
|
return
|
|
}
|
|
|
|
guard let eventFormatter = session.roomSummaryUpdateDelegate as? MXKEventFormatter,
|
|
let room = session.room(withRoomId: roomId) else {
|
|
// go into loaded state
|
|
self.viewState = .loaded
|
|
|
|
return
|
|
}
|
|
|
|
room.state { [weak self] roomState in
|
|
guard let self = self else { return }
|
|
self.eventFormatter = eventFormatter
|
|
self.roomState = roomState
|
|
|
|
// go into loaded state
|
|
self.viewState = .loaded
|
|
}
|
|
}
|
|
|
|
private func selectThread(_ index: Int) {
|
|
guard index < threads.count else {
|
|
return
|
|
}
|
|
let thread = threads[index]
|
|
coordinatorDelegate?.threadListViewModelDidSelectThread(self, thread: thread)
|
|
}
|
|
|
|
private func longPressThread(_ index: Int) {
|
|
guard index < threads.count else {
|
|
return
|
|
}
|
|
longPressedThread = threads[index]
|
|
viewState = .showingLongPressActions(index)
|
|
}
|
|
|
|
private func actionViewInRoom() {
|
|
guard let thread = longPressedThread else {
|
|
return
|
|
}
|
|
coordinatorDelegate?.threadListViewModelDidSelectThreadViewInRoom(self, thread: thread)
|
|
longPressedThread = nil
|
|
}
|
|
|
|
private func actionCopyLinkToThread() {
|
|
guard let thread = longPressedThread else {
|
|
return
|
|
}
|
|
if let permalink = MXTools.permalink(toEvent: thread.id, inRoom: thread.roomId),
|
|
let url = URL(string: permalink) {
|
|
MXKPasteboardManager.shared.pasteboard.url = url
|
|
viewState = .toastForCopyLink
|
|
}
|
|
longPressedThread = nil
|
|
}
|
|
|
|
private func actionShare() {
|
|
guard let thread = longPressedThread,
|
|
let index = threads.firstIndex(where: { thread.id == $0.id }) else {
|
|
return
|
|
}
|
|
if let permalink = MXTools.permalink(toEvent: thread.id, inRoom: thread.roomId),
|
|
let url = URL(string: permalink) {
|
|
viewState = .share(url, index)
|
|
}
|
|
longPressedThread = nil
|
|
}
|
|
|
|
private func cancelOperations() {
|
|
self.currentOperation?.cancel()
|
|
}
|
|
}
|
|
|
|
extension ThreadListViewModel: MXThreadingServiceDelegate {
|
|
|
|
func threadingServiceDidUpdateThreads(_ service: MXThreadingService) {
|
|
loadData(showLoading: false)
|
|
}
|
|
|
|
}
|