mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Run SwiftFormat.
This commit is contained in:
@@ -21,7 +21,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
static let focusTimelineToastIndicatorID = "RoomScreenFocusTimelineToastIndicator"
|
||||
static let toastErrorID = "RoomScreenToastError"
|
||||
}
|
||||
|
||||
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let timelineController: TimelineControllerProtocol
|
||||
private let userSession: UserSessionProtocol
|
||||
@@ -46,7 +46,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
|
||||
private var paginateBackwardsTask: Task<Void, Never>?
|
||||
private var paginateForwardsTask: Task<Void, Never>?
|
||||
|
||||
|
||||
init(roomProxy: JoinedRoomProxyProtocol,
|
||||
focussedEventID: String? = nil,
|
||||
timelineController: TimelineControllerProtocol,
|
||||
@@ -144,7 +144,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
|
||||
updateRoomInfo(roomProxy.infoPublisher.value)
|
||||
updateMembers(roomProxy.membersPublisher.value)
|
||||
|
||||
|
||||
// Note: beware if we get to e.g. restore a reply / edit,
|
||||
// maybe we are tracking a non-needed first initial state
|
||||
trackComposerMode(.default)
|
||||
@@ -233,7 +233,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
actionsSubject.send(.displayRoom(roomID: predecessorID, via: Array(serverNames)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func process(composerAction: ComposerToolbarViewModelAction) {
|
||||
switch composerAction {
|
||||
case .sendMessage(let message, let html, let mode, let intentionalMentions):
|
||||
@@ -451,7 +451,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] callback in
|
||||
guard let self else { return }
|
||||
|
||||
|
||||
switch callback {
|
||||
case .updatedTimelineItems(let updatedItems, let isSwitchingTimelines):
|
||||
buildTimelineViews(timelineItems: updatedItems, isSwitchingTimelines: isSwitchingTimelines)
|
||||
@@ -477,7 +477,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
|
||||
roomProxy.infoPublisher
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] roomInfo in
|
||||
@@ -540,7 +540,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
||||
func viewInRoomTimeline(eventID: String) async {
|
||||
switch await roomProxy.loadOrFetchEventDetails(for: eventID) {
|
||||
case .success(let event):
|
||||
@@ -567,7 +567,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
appSettings.$threadsEnabled
|
||||
.weakAssign(to: \.state.areThreadsEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
|
||||
appSettings.$jumpToReadMarkerEnabled
|
||||
.weakAssign(to: \.state.jumpToReadMarkerEnabled, on: self)
|
||||
.store(in: &cancellables)
|
||||
@@ -592,39 +592,39 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
.weakAssign(to: \.state.hideTimelineMedia, on: self)
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
||||
private func setupDirectRoomSubscriptionsIfNeeded() {
|
||||
guard roomProxy.infoPublisher.value.isDirect else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let shouldShowInviteAlert = composerFocusedSubject
|
||||
.removeDuplicates()
|
||||
.map { [weak self] isFocused in
|
||||
guard let self else { return false }
|
||||
|
||||
|
||||
return isFocused && self.roomProxy.infoPublisher.value.isUserAloneInDirectRoom
|
||||
}
|
||||
// We want to show the alert just once, so we are taking the first "true" emitted
|
||||
.first { $0 }
|
||||
|
||||
|
||||
shouldShowInviteAlert
|
||||
.sink { [weak self] _ in
|
||||
self?.displayAlert(.inviteAgain)
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
||||
private func paginateBackwards() {
|
||||
guard paginateBackwardsTask == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
paginateBackwardsTask = Task { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
switch await timelineController.paginateBackwards(requestSize: Constants.paginationEventLimit) {
|
||||
case .failure:
|
||||
displayErrorToast(L10n.errorFailedLoadingMessages)
|
||||
@@ -639,12 +639,12 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
guard paginateForwardsTask == nil else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
paginateForwardsTask = Task { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
switch await timelineController.paginateForwards(requestSize: Constants.paginationEventLimit) {
|
||||
case .failure:
|
||||
displayErrorToast(L10n.errorFailedLoadingMessages)
|
||||
@@ -667,20 +667,20 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
focusLive()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func scrollToReadMarker() async {
|
||||
// Primary: SDK has materialised the virtual ReadMarker. Smooth in-window scroll.
|
||||
if let readMarkerID = state.timelineState.readMarkerUniqueID {
|
||||
state.timelineState.scrollToReadMarkerPublisher.send(readMarkerID)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// Fallback: mirror the same-room permalink flow exactly
|
||||
// (RoomFlowCoordinator.handleChildEventRoute lines 223-258): pre-fetch the
|
||||
// event first to prime the SDK's event cache, then focus on it via the
|
||||
// same focusOnEvent path permalinks use.
|
||||
guard let fullyReadEventID = state.timelineState.fullyReadEventID else { return }
|
||||
|
||||
|
||||
switch await roomProxy.loadOrFetchEventDetails(for: fullyReadEventID) {
|
||||
case .success:
|
||||
await focusOnEvent(eventID: fullyReadEventID)
|
||||
@@ -688,13 +688,13 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
displayErrorToast(L10n.errorMessageNotFound)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func sendReadReceiptIfNeeded(for lastVisibleItemID: TimelineItemIdentifier) async {
|
||||
guard appMediator.appState == .active else { return }
|
||||
|
||||
|
||||
await timelineController.sendReadReceipt(for: lastVisibleItemID)
|
||||
}
|
||||
|
||||
|
||||
private func handleMediaTapped(with itemID: TimelineItemIdentifier) async {
|
||||
state.showLoading = true
|
||||
let action = await timelineInteractionHandler.processItemTap(itemID)
|
||||
@@ -749,7 +749,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
private func handleJoinCommand(message: String) async {
|
||||
guard let alias = String(message.dropFirst(SlashCommand.join.rawValue.count))
|
||||
.components(separatedBy: .whitespacesAndNewlines)
|
||||
@@ -799,7 +799,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
|
||||
scrollToBottom()
|
||||
}
|
||||
|
||||
|
||||
private func trackComposerMode(_ mode: ComposerMode) {
|
||||
var isEdit = false
|
||||
var isReply = false
|
||||
@@ -846,7 +846,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
mediaPlayerProvider.unregister(audioPlayerState: playerState)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let itemsGroupedByTimelineDisplayStyle = timelineItems.chunked { current, next in
|
||||
canGroupItem(timelineItem: current, with: next)
|
||||
}
|
||||
@@ -881,13 +881,13 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
if isSwitchingTimelines {
|
||||
state.timelineState.isSwitchingTimelines = true
|
||||
}
|
||||
|
||||
|
||||
updateHasNewMessagesAtBottom(with: timelineItemsDictionary)
|
||||
|
||||
|
||||
state.timelineState.itemsDictionary = timelineItemsDictionary
|
||||
state.timelineState.recomputeReadMarkerUniqueID()
|
||||
}
|
||||
|
||||
|
||||
private func updateViewState(item: RoomTimelineItemProtocol, groupStyle: TimelineGroupStyle) -> RoomTimelineItemViewState {
|
||||
if let timelineItemViewState = state.timelineState.itemsDictionary[item.id.uniqueID] {
|
||||
timelineItemViewState.groupStyle = groupStyle
|
||||
@@ -897,7 +897,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
return RoomTimelineItemViewState(item: item, groupStyle: groupStyle)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func canGroupItem(timelineItem: RoomTimelineItemProtocol, with otherTimelineItem: RoomTimelineItemProtocol) -> Bool {
|
||||
if timelineItem is CollapsibleTimelineItem || otherTimelineItem is CollapsibleTimelineItem {
|
||||
return false
|
||||
@@ -917,7 +917,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
&& eventTimelineItem.properties.reactions.isEmpty // Reactions break the grouping.
|
||||
&& otherEventTimelineItem.timestamp.timeIntervalSince(eventTimelineItem.timestamp) < 5 * 60 // As does the passage of time.
|
||||
}
|
||||
|
||||
|
||||
/// Sets `hasNewMessagesAtBottom` to `true` when newer items arrive while the user is scrolled
|
||||
/// up in a live timeline. Skips initial load and timeline switches.
|
||||
private func updateHasNewMessagesAtBottom(with newTimelineItems: OrderedDictionary<TimelineItemIdentifier.UniqueID, RoomTimelineItemViewState>) {
|
||||
@@ -928,33 +928,33 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
!state.bindings.hasNewMessagesAtBottom else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
let oldDictionary = state.timelineState.itemsDictionary
|
||||
guard !oldDictionary.isEmpty,
|
||||
!newTimelineItems.isEmpty,
|
||||
oldDictionary.keys.last != newTimelineItems.keys.last else {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
state.bindings.hasNewMessagesAtBottom = true
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Direct chats logics
|
||||
|
||||
|
||||
private let inviteLoadingIndicatorID = UUID().uuidString
|
||||
|
||||
|
||||
private func inviteOtherDMUserBack() {
|
||||
guard roomProxy.infoPublisher.value.isUserAloneInDirectRoom else {
|
||||
displayAlert(.unknown)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Task {
|
||||
userIndicatorController.submitIndicator(.init(id: inviteLoadingIndicatorID, type: .toast, title: L10n.commonLoading))
|
||||
defer {
|
||||
userIndicatorController.retractIndicatorWithId(inviteLoadingIndicatorID)
|
||||
}
|
||||
|
||||
|
||||
guard
|
||||
let members = await roomProxy.members(),
|
||||
members.count == 2,
|
||||
@@ -963,7 +963,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
displayAlert(.unknown)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
switch await roomProxy.invite(userID: otherPerson.userID) {
|
||||
case .success:
|
||||
break
|
||||
@@ -974,7 +974,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
// MARK: - Reactions
|
||||
|
||||
|
||||
private func displayReactionSummary(for itemID: TimelineItemIdentifier, selectedKey: String) {
|
||||
guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
|
||||
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
@@ -985,7 +985,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
}
|
||||
|
||||
// MARK: - Read Receipts
|
||||
|
||||
|
||||
private func displayReadReceipts(for itemID: TimelineItemIdentifier) {
|
||||
guard let timelineItem = timelineController.timelineItems.firstUsingStableID(itemID),
|
||||
let eventTimelineItem = timelineItem as? EventBasedTimelineItemProtocol else {
|
||||
@@ -994,7 +994,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
||||
|
||||
state.bindings.readReceiptsSummaryInfo = .init(orderedReceipts: eventTimelineItem.properties.orderedReadReceipts, id: eventTimelineItem.id)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Message forwarding
|
||||
|
||||
private func forwardMessage(itemID: TimelineItemIdentifier) async {
|
||||
@@ -1120,9 +1120,9 @@ extension TimelineViewModel {
|
||||
clientProxyMock.roomSummaryForAliasReturnValue = .mock(id: "!room:matrix.org", name: "Room")
|
||||
clientProxyMock.roomSummaryForIdentifierReturnValue = .mock(id: "!room:matrix.org", name: "Room", canonicalAlias: "#room:matrix.org")
|
||||
let roomProxy = JoinedRoomProxyMock(.init(name: "Preview room", predecessor: hasPredecessor ? .init(roomId: UUID().uuidString) : nil))
|
||||
|
||||
|
||||
let appSettings = AppSettings.volatile()
|
||||
|
||||
|
||||
return TimelineViewModel(roomProxy: roomProxy,
|
||||
focussedEventID: nil,
|
||||
timelineController: timelineController ?? MockTimelineController(timelineKind: timelineKind),
|
||||
|
||||
Reference in New Issue
Block a user