Media gallery - part 1(#3588)

* Introduce a `MediaEventsTimelineFlowCoordinator`
* Update SDK API and architecture
* Add a feature flag, add translations
* Move the media events timeline presentation under the room flow coordinator state machine
* Rename `TimelineViewState.timelineViewState` of type `TimelineState` to `timelineState`
* Enabled SwiftLint's `trailing_closure` rule and fix the warnings.
This commit is contained in:
Stefan Ceriu
2024-12-06 16:58:14 +02:00
committed by GitHub
parent a9e4837b62
commit caaa89af62
83 changed files with 1247 additions and 279 deletions
@@ -29,6 +29,7 @@ enum RoomDetailsScreenCoordinatorAction {
case presentRolesAndPermissionsScreen
case presentCall
case presentPinnedEventsTimeline
case presentMediaEventsTimeline
case presentKnockingRequestsListScreen
}
@@ -80,6 +81,8 @@ final class RoomDetailsScreenCoordinator: CoordinatorProtocol {
actionsSubject.send(.presentCall)
case .displayPinnedEventsTimeline:
actionsSubject.send(.presentPinnedEventsTimeline)
case .displayMediaEventsTimeline:
actionsSubject.send(.presentMediaEventsTimeline)
case .displayKnockingRequests:
actionsSubject.send(.presentKnockingRequestsListScreen)
}
@@ -22,6 +22,7 @@ enum RoomDetailsScreenViewModelAction {
case requestRolesAndPermissionsPresentation
case startCall
case displayPinnedEventsTimeline
case displayMediaEventsTimeline
case displayKnockingRequests
}
@@ -48,13 +49,15 @@ struct RoomDetailsScreenViewState: BindableState {
var notificationSettingsState: RoomDetailsNotificationSettingsState = .loading
var canJoinCall = false
var pinnedEventsActionState = RoomDetailsScreenPinnedEventsActionState.loading
var knockingEnabled = false
var isKnockableRoom = false
var canSeeKnockingRequests: Bool {
knockingEnabled && dmRecipient == nil && isKnockableRoom && (canInviteUsers || canKickUsers || canBanUsers)
}
var mediaBrowserEnabled = false
var canEdit: Bool {
!isDirect && (canEditRoomName || canEditRoomTopic || canEditRoomAvatar)
}
@@ -197,6 +200,7 @@ enum RoomDetailsScreenViewAction {
case processTapRolesAndPermissions
case processTapCall
case processTapPinnedEvents
case processTapMediaEvents
case processTapRequestsToJoin
}
@@ -79,6 +79,10 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
.weakAssign(to: \.state.knockingEnabled, on: self)
.store(in: &cancellables)
appSettings.$mediaBrowserEnabled
.weakAssign(to: \.state.mediaBrowserEnabled, on: self)
.store(in: &cancellables)
appMediator.networkMonitor.reachabilityPublisher
.filter { $0 == .reachable }
.receive(on: DispatchQueue.main)
@@ -164,6 +168,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
case .processTapPinnedEvents:
analyticsService.trackInteraction(name: .PinnedMessageRoomInfoButton)
actionsSubject.send(.displayPinnedEventsTimeline)
case .processTapMediaEvents:
actionsSubject.send(.displayMediaEventsTimeline)
case .processTapRequestsToJoin:
actionsSubject.send(.displayKnockingRequests)
}
@@ -207,8 +213,8 @@ class RoomDetailsScreenViewModel: RoomDetailsScreenViewModelType, RoomDetailsScr
.receive(on: DispatchQueue.main)
.sink { [weak self, ownUserID = roomProxy.ownUserID] members in
guard let self else { return }
let accountOwner = members.first(where: { $0.userID == ownUserID })
let dmRecipient = members.first(where: { $0.userID != ownUserID })
let accountOwner = members.first { $0.userID == ownUserID }
let dmRecipient = members.first { $0.userID != ownUserID }
self.dmRecipient = dmRecipient
self.state.dmRecipient = dmRecipient.map(RoomMemberDetails.init(withProxy:))
self.state.accountOwner = accountOwner.map(RoomMemberDetails.init(withProxy:))
@@ -164,9 +164,9 @@ struct RoomDetailsScreen: View {
ListRow(label: .default(title: L10n.screenRoomDetailsPinnedEventsRowTitle,
icon: \.pin),
details: context.viewState.pinnedEventsActionState.isLoading ? .isWaiting(true) : .title(context.viewState.pinnedEventsActionState.count),
kind: context.viewState.pinnedEventsActionState.isLoading ? .label : .navigationLink(action: {
kind: context.viewState.pinnedEventsActionState.isLoading ? .label : .navigationLink {
context.send(viewAction: .processTapPinnedEvents)
}))
})
.disabled(context.viewState.pinnedEventsActionState.isLoading)
if context.viewState.canSeeKnockingRequests {
@@ -184,6 +184,13 @@ struct RoomDetailsScreen: View {
context.send(viewAction: .processTapPolls)
})
.accessibilityIdentifier(A11yIdentifiers.roomDetailsScreen.pollsHistory)
if context.viewState.mediaBrowserEnabled {
ListRow(label: .default(title: L10n.screenMediaBrowserTitle, icon: \.image),
kind: .navigationLink {
context.send(viewAction: .processTapMediaEvents)
})
}
}
}