From 77c5aba326eb4a19d9dae7a61653f531119a7ae5 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 22 May 2026 13:01:22 +0300 Subject: [PATCH] Forward current composer text to the new poll form to serve as the question/topic --- .../CreatePollScreen/PollFormScreenModels.swift | 6 +++--- .../Screens/CreatePollScreen/View/PollFormScreen.swift | 2 +- .../MediaEventsTimelineScreenViewModel.swift | 4 ++-- .../PinnedEventsTimelineScreenCoordinator.swift | 2 +- .../Screens/RoomScreen/RoomScreenCoordinator.swift | 6 ++++-- .../ThreadTimelineScreenCoordinator.swift | 6 ++++-- .../Screens/Timeline/TimelineInteractionHandler.swift | 4 ++-- ElementX/Sources/Screens/Timeline/TimelineModels.swift | 3 ++- .../Sources/Screens/Timeline/TimelineViewModel.swift | 10 +++++----- ElementX/Sources/UITests/UITestsAppCoordinator.swift | 2 +- UnitTests/Sources/PollFormScreenViewModelTests.swift | 2 +- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/ElementX/Sources/Screens/CreatePollScreen/PollFormScreenModels.swift b/ElementX/Sources/Screens/CreatePollScreen/PollFormScreenModels.swift index 3dacee2d3..adfdc2eb1 100644 --- a/ElementX/Sources/Screens/CreatePollScreen/PollFormScreenModels.swift +++ b/ElementX/Sources/Screens/CreatePollScreen/PollFormScreenModels.swift @@ -22,8 +22,8 @@ struct PollFormScreenViewState: BindableState { self.maxNumberOfOptions = maxNumberOfOptions switch mode { - case .new: - bindings = .init() + case .new(let topic): + bindings = .init(question: topic ?? "") case .edit(_, let poll): bindings = .init(poll: poll) } @@ -71,7 +71,7 @@ struct PollFormScreenViewState: BindableState { } enum PollFormMode: Hashable { - case new + case new(topic: String?) case edit(eventID: String, poll: Poll) } diff --git a/ElementX/Sources/Screens/CreatePollScreen/View/PollFormScreen.swift b/ElementX/Sources/Screens/CreatePollScreen/View/PollFormScreen.swift index 60001c39b..99fdf03b4 100644 --- a/ElementX/Sources/Screens/CreatePollScreen/View/PollFormScreen.swift +++ b/ElementX/Sources/Screens/CreatePollScreen/View/PollFormScreen.swift @@ -198,7 +198,7 @@ private struct PollFormOptionRow: View { // MARK: - Previews struct PollFormScreen_Previews: PreviewProvider, TestablePreview { - static let viewModel = makeViewModel(mode: .new) + static let viewModel = makeViewModel(mode: .new(topic: nil)) static let editViewModel = makeViewModel(mode: .edit(eventID: "1234", poll: poll)) static let poll = Poll(question: "Cats or Dogs?", kind: .disclosed, diff --git a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift index 45fdb2b04..1f6387d37 100644 --- a/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift +++ b/ElementX/Sources/Screens/MediaEventsTimelineScreen/MediaEventsTimelineScreenViewModel.swift @@ -72,7 +72,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType case .displayMediaDetails(item: let item): displayMediaPreviewSheet(for: item) case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, - .displayDocumentPicker, .displayLocationPicker, .displayLiveLocation, .displayPollForm, .displayMediaUploadPreviewScreen, + .displayDocumentPicker, .displayLocationPicker, .displayLiveLocation, .displayNewPollForm, .displayEditPollForm, .displayMediaUploadPreviewScreen, .displaySenderDetails, .displayMessageForwarding, .displayLocation, .displayResolveSendFailure, .displayThread, .composer, .hasScrolled, .viewInRoomTimeline, .displayRoom: break @@ -97,7 +97,7 @@ class MediaEventsTimelineScreenViewModel: MediaEventsTimelineScreenViewModelType case .displayMediaDetails(item: let item): displayMediaPreviewSheet(for: item) case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, - .displayDocumentPicker, .displayLocationPicker, .displayLiveLocation, .displayPollForm, .displayMediaUploadPreviewScreen, + .displayDocumentPicker, .displayLocationPicker, .displayLiveLocation, .displayNewPollForm, .displayEditPollForm, .displayMediaUploadPreviewScreen, .displaySenderDetails, .displayMessageForwarding, .displayLocation, .displayResolveSendFailure, .displayThread, .composer, .hasScrolled, .viewInRoomTimeline, .displayRoom: break diff --git a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift index d0e5ab3fb..8095b887f 100644 --- a/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/PinnedEventsTimelineScreen/PinnedEventsTimelineScreenCoordinator.swift @@ -96,7 +96,7 @@ final class PinnedEventsTimelineScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.displayRoomScreenWithFocussedPin(eventID: eventID, threadRootEventID: threadRootEventID)) // These other actions will not be handled in this view case .displayEmojiPicker, .displayReportContent, .displayCameraPicker, .displayMediaPicker, - .displayDocumentPicker, .displayLocationPicker, .displayPollForm, .displayMediaUploadPreviewScreen, + .displayDocumentPicker, .displayLocationPicker, .displayNewPollForm, .displayEditPollForm, .displayMediaUploadPreviewScreen, .displayResolveSendFailure, .displayThread, .composer, .hasScrolled, .displayRoom, .displayMediaDetails: // These actions are not handled in this coordinator break diff --git a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift index d6929c0e1..8e6a3d555 100644 --- a/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift +++ b/ElementX/Sources/Screens/RoomScreen/RoomScreenCoordinator.swift @@ -134,8 +134,10 @@ final class RoomScreenCoordinator: CoordinatorProtocol { roomViewModel.displayMediaPreview(mediaPreviewViewModel) case .displayLocationPicker: actionsSubject.send(.presentLocationPicker) - case .displayPollForm(let mode): - actionsSubject.send(.presentPollForm(mode: mode)) + case .displayNewPollForm: + actionsSubject.send(.presentPollForm(mode: .new(topic: composerViewModel.context.plainComposerText.string))) + case .displayEditPollForm(let eventID, let poll): + actionsSubject.send(.presentPollForm(mode: .edit(eventID: eventID, poll: poll))) case .displayMediaUploadPreviewScreen(let mediaURLs): actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs, caption: composerViewModel.context.plainComposerText)) diff --git a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift index 6dd68658f..ce5570e0d 100644 --- a/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift +++ b/ElementX/Sources/Screens/ThreadTimelineScreen/ThreadTimelineScreenCoordinator.swift @@ -126,8 +126,10 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol { actionsSubject.send(.presentLocationViewer(location)) case .displayLiveLocation(let sender, let initialLiveLocationShare): actionsSubject.send(.presentLiveLocationViewer(sender: sender, initialLiveLocationShare: initialLiveLocationShare)) - case .displayPollForm(let mode): - actionsSubject.send(.presentPollForm(mode: mode)) + case .displayNewPollForm: + actionsSubject.send(.presentPollForm(mode: .new(topic: composerViewModel.context.plainComposerText.string))) + case .displayEditPollForm(let eventID, let poll): + actionsSubject.send(.presentPollForm(mode: .edit(eventID: eventID, poll: poll))) case .displayMediaUploadPreviewScreen(let mediaURLs): actionsSubject.send(.presentMediaUploadPreviewScreen(mediaURLs: mediaURLs, caption: composerViewModel.context.plainComposerText)) diff --git a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift index adc910251..705f9d9a2 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineInteractionHandler.swift @@ -16,7 +16,7 @@ enum TimelineInteractionHandlerAction { case displayReportContent(itemID: TimelineItemIdentifier, senderID: String) case displayMessageForwarding(itemID: TimelineItemIdentifier) case displayMediaUploadPreviewScreen(mediaURLs: [URL]) - case displayPollForm(mode: PollFormMode) + case displayEditPollForm(eventID: String, poll: Poll) case showActionMenu(TimelineItemActionMenuInfo) case showDebugInfo(TimelineItemDebugInfo) @@ -130,7 +130,7 @@ class TimelineInteractionHandler { MXLog.error("Cannot edit poll with id: \(timelineItem.id)") return } - actionsSubject.send(.displayPollForm(mode: .edit(eventID: eventID, poll: pollTimelineItem.poll))) + actionsSubject.send(.displayEditPollForm(eventID: eventID, poll: pollTimelineItem.poll)) default: MXLog.error("Cannot edit item with id: \(timelineItem.id)") } diff --git a/ElementX/Sources/Screens/Timeline/TimelineModels.swift b/ElementX/Sources/Screens/Timeline/TimelineModels.swift index d296421dd..acb332ef0 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineModels.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineModels.swift @@ -18,7 +18,8 @@ enum TimelineViewModelAction { case displayMediaPicker case displayDocumentPicker case displayLocationPicker - case displayPollForm(mode: PollFormMode) + case displayNewPollForm + case displayEditPollForm(eventID: String, poll: Poll) case displayMediaUploadPreviewScreen(mediaURLs: [URL]) case displaySenderDetails(userID: String) case displayMessageForwarding(forwardingItem: MessageForwardingItem) diff --git a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift index 999e815c4..f4eb57462 100644 --- a/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift +++ b/ElementX/Sources/Screens/Timeline/TimelineViewModel.swift @@ -370,7 +370,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { case .location: actionsSubject.send(.displayLocationPicker) case .poll: - actionsSubject.send(.displayPollForm(mode: .new)) + actionsSubject.send(.displayNewPollForm) } } @@ -380,8 +380,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { timelineInteractionHandler.sendPollResponse(pollStartID: pollStartID, optionID: optionID) case let .end(pollStartID): displayAlert(.pollEndConfirmation(pollStartID)) - case .edit(let pollStartID, let poll): - actionsSubject.send(.displayPollForm(mode: .edit(eventID: pollStartID, poll: poll))) + case .edit(let eventID, let poll): + actionsSubject.send(.displayEditPollForm(eventID: eventID, poll: poll)) } } @@ -514,8 +514,8 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol { actionsSubject.send(.displayEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis)) case .displayMessageForwarding(let itemID): Task { await self.forwardMessage(itemID: itemID) } - case .displayPollForm(let mode): - actionsSubject.send(.displayPollForm(mode: mode)) + case .displayEditPollForm(let eventID, let poll): + actionsSubject.send(.displayEditPollForm(eventID: eventID, poll: poll)) case .displayReportContent(let itemID, let senderID): actionsSubject.send(.displayReportContent(itemID: itemID, senderID: senderID)) case .displayMediaUploadPreviewScreen(let mediaURLs): diff --git a/ElementX/Sources/UITests/UITestsAppCoordinator.swift b/ElementX/Sources/UITests/UITestsAppCoordinator.swift index 69fb913fe..e2360e6e3 100644 --- a/ElementX/Sources/UITests/UITestsAppCoordinator.swift +++ b/ElementX/Sources/UITests/UITestsAppCoordinator.swift @@ -722,7 +722,7 @@ class MockScreen: Identifiable { return PlaceholderScreenCoordinator(hideBrandChrome: false) case .createPoll: let navigationStackCoordinator = NavigationStackCoordinator() - let coordinator = PollFormScreenCoordinator(parameters: .init(mode: .new, + let coordinator = PollFormScreenCoordinator(parameters: .init(mode: .new(topic: nil), maxNumberOfOptions: 10, timelineController: MockTimelineController(), analytics: analytics, diff --git a/UnitTests/Sources/PollFormScreenViewModelTests.swift b/UnitTests/Sources/PollFormScreenViewModelTests.swift index fc8a7ef08..e80acd34a 100644 --- a/UnitTests/Sources/PollFormScreenViewModelTests.swift +++ b/UnitTests/Sources/PollFormScreenViewModelTests.swift @@ -176,7 +176,7 @@ struct PollFormScreenViewModelTests { // MARK: - Helpers - private mutating func setupViewModel(mode: PollFormMode = .new) { + private mutating func setupViewModel(mode: PollFormMode = .new(topic: nil)) { viewModel = PollFormScreenViewModel(mode: mode, timelineController: MockTimelineController(timelineProxy: timelineProxy), analytics: AnalyticsServiceMock.default,