mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Refactor how drafts are handled on a coordinator level and add support for them on thread timelines.
This commit is contained in:
committed by
Stefan Ceriu
parent
eaf14eaaac
commit
6fc6df9375
@@ -39,6 +39,8 @@ enum ComposerToolbarViewModelAction {
|
|||||||
|
|
||||||
enum ComposerToolbarViewAction {
|
enum ComposerToolbarViewAction {
|
||||||
case composerAppeared
|
case composerAppeared
|
||||||
|
case composerDisappeared
|
||||||
|
|
||||||
case sendMessage
|
case sendMessage
|
||||||
case editLastMessage
|
case editLastMessage
|
||||||
case cancelReply
|
case cancelReply
|
||||||
|
|||||||
@@ -161,9 +161,22 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification).sink { [weak self] _ in
|
||||||
|
self?.saveDraft()
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
Task { await loadDraft() }
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop() {
|
||||||
|
saveDraft()
|
||||||
|
}
|
||||||
|
|
||||||
override func process(viewAction: ComposerToolbarViewAction) {
|
override func process(viewAction: ComposerToolbarViewAction) {
|
||||||
switch viewAction {
|
switch viewAction {
|
||||||
@@ -172,6 +185,8 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
|||||||
hasAppeard = true
|
hasAppeard = true
|
||||||
wysiwygViewModel.setup()
|
wysiwygViewModel.setup()
|
||||||
}
|
}
|
||||||
|
case .composerDisappeared:
|
||||||
|
saveDraft()
|
||||||
case .sendMessage:
|
case .sendMessage:
|
||||||
guard !state.sendButtonDisabled else { return }
|
guard !state.sendButtonDisabled else { return }
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -13,8 +13,9 @@ import WysiwygComposer
|
|||||||
protocol ComposerToolbarViewModelProtocol {
|
protocol ComposerToolbarViewModelProtocol {
|
||||||
var actions: AnyPublisher<ComposerToolbarViewModelAction, Never> { get }
|
var actions: AnyPublisher<ComposerToolbarViewModelAction, Never> { get }
|
||||||
var context: ComposerToolbarViewModelType.Context { get }
|
var context: ComposerToolbarViewModelType.Context { get }
|
||||||
|
|
||||||
|
func start()
|
||||||
|
func stop()
|
||||||
|
|
||||||
func process(timelineAction: TimelineComposerAction)
|
func process(timelineAction: TimelineComposerAction)
|
||||||
func loadDraft() async
|
|
||||||
func saveDraft()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,9 @@ struct ComposerToolbar: View {
|
|||||||
} onAppearAction: {
|
} onAppearAction: {
|
||||||
context.send(viewAction: .composerAppeared)
|
context.send(viewAction: .composerAppeared)
|
||||||
}
|
}
|
||||||
|
.onDisappear {
|
||||||
|
context.send(viewAction: .composerDisappeared)
|
||||||
|
}
|
||||||
.environmentObject(context)
|
.environmentObject(context)
|
||||||
.focused($composerFocused)
|
.focused($composerFocused)
|
||||||
.padding(.leading, context.composerFormattingEnabled ? 7 : 0)
|
.padding(.leading, context.composerFormattingEnabled ? 7 : 0)
|
||||||
|
|||||||
@@ -107,11 +107,6 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
analyticsService: ServiceLocator.shared.analytics,
|
analyticsService: ServiceLocator.shared.analytics,
|
||||||
composerDraftService: parameters.composerDraftService)
|
composerDraftService: parameters.composerDraftService)
|
||||||
self.composerViewModel = composerViewModel
|
self.composerViewModel = composerViewModel
|
||||||
|
|
||||||
NotificationCenter.default.publisher(for: UIApplication.willResignActiveNotification).sink { _ in
|
|
||||||
composerViewModel.saveDraft()
|
|
||||||
}
|
|
||||||
.store(in: &cancellables)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Public
|
// MARK: - Public
|
||||||
@@ -193,8 +188,9 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
// Loading the draft requires the subscriptions to be set up first otherwise the room won't be be able to propagate the information to the composer.
|
// Loading the draft requires the subscriptions to be set up first otherwise
|
||||||
Task { await composerViewModel.loadDraft() }
|
// the room won't be be able to propagate the information to the composer.
|
||||||
|
composerViewModel.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func focusOnEvent(_ focussedEvent: FocusEvent) {
|
func focusOnEvent(_ focussedEvent: FocusEvent) {
|
||||||
@@ -212,7 +208,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
composerViewModel.saveDraft()
|
composerViewModel.stop()
|
||||||
roomViewModel.stop()
|
roomViewModel.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,10 +217,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
|||||||
|
|
||||||
return AnyView(RoomScreen(context: roomViewModel.context,
|
return AnyView(RoomScreen(context: roomViewModel.context,
|
||||||
timelineContext: timelineViewModel.context,
|
timelineContext: timelineViewModel.context,
|
||||||
composerToolbar: composerToolbar)
|
composerToolbar: composerToolbar))
|
||||||
.onDisappear { [weak self] in
|
|
||||||
self?.composerViewModel.saveDraft()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,8 +74,6 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
|
|||||||
maxExpandedHeight: ComposerConstant.maxHeight,
|
maxExpandedHeight: ComposerConstant.maxHeight,
|
||||||
parserStyle: .elementX)
|
parserStyle: .elementX)
|
||||||
|
|
||||||
#warning("Drafts are not handled and they can't be without rust side changes")
|
|
||||||
|
|
||||||
composerViewModel = ComposerToolbarViewModel(initialText: nil,
|
composerViewModel = ComposerToolbarViewModel(initialText: nil,
|
||||||
roomProxy: parameters.roomProxy,
|
roomProxy: parameters.roomProxy,
|
||||||
isInThread: true,
|
isInThread: true,
|
||||||
@@ -144,9 +142,14 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
|
|||||||
timelineViewModel.process(composerAction: action)
|
timelineViewModel.process(composerAction: action)
|
||||||
}
|
}
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
// Loading the draft requires the subscriptions to be set up first otherwise
|
||||||
|
// the room won't be be able to propagate the information to the composer.
|
||||||
|
composerViewModel.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
func stop() {
|
func stop() {
|
||||||
|
composerViewModel.stop()
|
||||||
viewModel.stop()
|
viewModel.stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user