Pinned Events Timeline actions and differentiation (#3182)

This commit is contained in:
Mauro
2024-08-22 17:35:44 +02:00
committed by GitHub
parent d54e08e815
commit 4eb1ed5d09
44 changed files with 671 additions and 200 deletions
@@ -52,6 +52,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
init(roomProxy: JoinedRoomProxyProtocol,
focussedEventID: String? = nil,
timelineController: RoomTimelineControllerProtocol,
isPinnedEventsTimeline: Bool,
mediaProvider: MediaProviderProtocol,
mediaPlayerProvider: MediaPlayerProviderProtocol,
voiceMessageMediaManager: VoiceMessageMediaManagerProtocol,
@@ -80,7 +81,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
appSettings: appSettings,
analyticsService: analyticsService)
super.init(initialViewState: TimelineViewState(roomID: roomProxy.id,
super.init(initialViewState: TimelineViewState(isPinnedEventsTimeline: isPinnedEventsTimeline,
roomID: roomProxy.id,
isEncryptedOneToOneRoom: roomProxy.isEncryptedOneToOneRoom,
timelineViewState: TimelineState(focussedEvent: focussedEventID.map { .init(eventID: $0, appearance: .immediate) }),
ownUserID: roomProxy.ownUserID,
@@ -93,6 +95,10 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
showFocusLoadingIndicator()
}
Task {
await updatePinnedEventIDs()
}
setupSubscriptions()
setupDirectRoomSubscriptionsIfNeeded()
@@ -375,9 +381,6 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
.actionsPublisher
.filter { $0 == .roomInfoUpdate }
Task { [weak self] in
// Don't guard let self here, otherwise the for await will strongify the self reference creating a strong reference cycle.
// If the subscription has sent a value before the Task has started it might be lost, so before entering the loop we always do an update.
await self?.updatePinnedEventIDs()
for await _ in roomInfoSubscription.receive(on: DispatchQueue.main).values {
guard !Task.isCancelled else {
return
@@ -429,6 +432,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
}
case .showDebugInfo(let debugInfo):
state.bindings.debugInfo = debugInfo
case .viewInRoomTimeline(let eventID):
actionsSubject.send(.viewInRoomTimeline(eventID: eventID))
}
}
.store(in: &cancellables)
@@ -641,13 +646,13 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
} else {
for (index, item) in itemGroup.enumerated() {
if index == 0 {
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: .first),
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .first),
forKey: item.id.timelineID)
} else if index == itemGroup.count - 1 {
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: .last),
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .last),
forKey: item.id.timelineID)
} else {
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: .middle),
timelineItemsDictionary.updateValue(updateViewState(item: item, groupStyle: state.isPinnedEventsTimeline ? .single : .middle),
forKey: item.id.timelineID)
}
}
@@ -822,6 +827,7 @@ extension TimelineViewModel {
static let mock = TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
focussedEventID: nil,
timelineController: MockRoomTimelineController(),
isPinnedEventsTimeline: false,
mediaProvider: MockMediaProvider(),
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
@@ -829,6 +835,18 @@ extension TimelineViewModel {
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics)
static let pinnedEventsTimelineMock = TimelineViewModel(roomProxy: JoinedRoomProxyMock(.init(name: "Preview room")),
focussedEventID: nil,
timelineController: MockRoomTimelineController(),
isPinnedEventsTimeline: true,
mediaProvider: MockMediaProvider(),
mediaPlayerProvider: MediaPlayerProviderMock(),
voiceMessageMediaManager: VoiceMessageMediaManagerMock(),
userIndicatorController: ServiceLocator.shared.userIndicatorController,
appMediator: AppMediatorMock.default,
appSettings: ServiceLocator.shared.settings,
analyticsService: ServiceLocator.shared.analytics)
}
private struct TimelineContextKey: EnvironmentKey {