Use the Emoji/Map/Poll view models. (#4458)

* Toggle emojis in the EmojiPickerScreenViewModel.

* Send locations in the StaticLocationScreen.

* Send polls in the PollFormScreen.
This commit is contained in:
Doug
2025-09-03 16:52:28 +01:00
committed by GitHub
parent 441f5ae975
commit eda37eb626
21 changed files with 398 additions and 255 deletions
@@ -82,7 +82,7 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
case .displayUser(let userID):
actionsSubject.send(.displayUser(userID: userID))
case .presentLocationViewer(let geoURI, let description):
presentMapNavigator(geoURI: geoURI, description: description)
presentMapNavigator(geoURI: geoURI, description: description, timelineController: timelineController)
case .displayMessageForwarding(let forwardingItem):
presentMessageForwarding(with: forwardingItem)
case .displayRoomScreenWithFocussedPin(let eventID):
@@ -94,20 +94,20 @@ class PinnedEventsTimelineFlowCoordinator: FlowCoordinatorProtocol {
navigationStackCoordinator.setRootCoordinator(coordinator)
}
private func presentMapNavigator(geoURI: GeoURI, description: String?) {
private func presentMapNavigator(geoURI: GeoURI, description: String?, timelineController: TimelineControllerProtocol) {
let stackCoordinator = NavigationStackCoordinator()
let params = StaticLocationScreenCoordinatorParameters(interactionMode: .viewOnly(geoURI: geoURI, description: description),
mapURLBuilder: flowParameters.appSettings.mapTilerConfiguration,
appMediator: flowParameters.appMediator)
timelineController: timelineController,
appMediator: flowParameters.appMediator,
analytics: flowParameters.analytics,
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = StaticLocationScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
switch action {
case .selectedLocation:
// We don't handle the sending/picker case in this flow
break
case .close:
self.navigationStackCoordinator.setSheetCoordinator(nil)
}
@@ -1005,24 +1005,16 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
selectedEmoji: Set<String>,
timelineController: TimelineControllerProtocol,
animated: Bool) {
let params = EmojiPickerScreenCoordinatorParameters(emojiProvider: flowParameters.emojiProvider,
itemID: itemID, selectedEmojis: selectedEmoji)
let params = EmojiPickerScreenCoordinatorParameters(itemID: itemID,
selectedEmojis: selectedEmoji,
emojiProvider: flowParameters.emojiProvider,
timelineController: timelineController)
let coordinator = EmojiPickerScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
switch action {
case let .emojiSelected(emoji: emoji, itemID: itemID):
MXLog.debug("Selected \(emoji) for \(itemID)")
navigationStackCoordinator.setSheetCoordinator(nil)
Task {
guard case let .event(_, eventOrTransactionID) = itemID else {
fatalError()
}
await self.timelineController?.toggleReaction(emoji, to: eventOrTransactionID)
}
case .dismiss:
navigationStackCoordinator.setSheetCoordinator(nil)
}
@@ -1041,27 +1033,15 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
let params = StaticLocationScreenCoordinatorParameters(interactionMode: interactionMode,
mapURLBuilder: flowParameters.appSettings.mapTilerConfiguration,
appMediator: flowParameters.appMediator)
timelineController: timelineController,
appMediator: flowParameters.appMediator,
analytics: flowParameters.analytics,
userIndicatorController: flowParameters.userIndicatorController)
let coordinator = StaticLocationScreenCoordinator(parameters: params)
coordinator.actions.sink { [weak self] action in
guard let self else { return }
switch action {
case .selectedLocation(let geoURI, let isUserLocation):
Task {
_ = await timelineController.sendLocation(body: geoURI.bodyMessage,
geoURI: geoURI,
description: nil,
zoomLevel: 15,
assetType: isUserLocation ? .sender : .pin)
self.navigationStackCoordinator.setSheetCoordinator(nil)
}
self.flowParameters.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: isUserLocation ? .LocationUser : .LocationPin,
startsThread: nil)
case .close:
self.navigationStackCoordinator.setSheetCoordinator(nil)
}
@@ -1077,36 +1057,19 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
private func presentPollForm(mode: PollFormMode, timelineController: TimelineControllerProtocol) {
let stackCoordinator = NavigationStackCoordinator()
let coordinator = PollFormScreenCoordinator(parameters: .init(mode: mode))
let coordinator = PollFormScreenCoordinator(parameters: .init(mode: mode,
timelineController: timelineController,
analytics: flowParameters.analytics,
userIndicatorController: flowParameters.userIndicatorController))
stackCoordinator.setRootCoordinator(coordinator)
coordinator.actions
.sink { [weak self] action in
guard let self else {
return
}
self.navigationStackCoordinator.setSheetCoordinator(nil)
guard let self else { return }
switch action {
case .cancel:
break
case .delete:
deletePoll(mode: mode)
case let .submit(question, options, pollKind):
switch mode {
case .new:
createPoll(question: question,
options: options,
pollKind: pollKind,
timelineController: timelineController)
case .edit(let eventID, _):
editPoll(pollStartID: eventID,
question: question,
options: options,
pollKind: pollKind,
timelineController: timelineController)
}
case .close:
navigationStackCoordinator.setSheetCoordinator(nil)
}
}
.store(in: &cancellables)
@@ -1116,58 +1079,6 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
}
}
private func createPoll(question: String, options: [String], pollKind: Poll.Kind, timelineController: TimelineControllerProtocol) {
Task {
let result = await timelineController.createPoll(question: question, answers: options, pollKind: pollKind)
self.flowParameters.analytics.trackComposer(inThread: false,
isEditing: false,
isReply: false,
messageType: .Poll,
startsThread: nil)
self.flowParameters.analytics.trackPollCreated(isUndisclosed: pollKind == .undisclosed, numberOfAnswers: options.count)
switch result {
case .success:
break
case .failure:
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
private func editPoll(pollStartID: String, question: String, options: [String], pollKind: Poll.Kind, timelineController: TimelineControllerProtocol) {
Task {
let result = await timelineController.editPoll(original: pollStartID, question: question, answers: options, pollKind: pollKind)
switch result {
case .success:
break
case .failure:
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
private func deletePoll(mode: PollFormMode) {
Task {
guard case .edit(let pollStartID, _) = mode else {
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
return
}
let result = await roomProxy.redact(pollStartID)
switch result {
case .success:
break
case .failure:
self.flowParameters.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
}
}
}
private func presentRoomPollsHistory(animated: Bool) async {
let userID = userSession.clientProxy.userID