mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 16:10:20 +00:00
Group together voice message and poll actions (#2054)
* Group together voice message and poll actions * Extract nested switches into separate methods
This commit is contained in:
@@ -18,6 +18,18 @@ import SwiftUI
|
|||||||
import UIKit
|
import UIKit
|
||||||
import WysiwygComposer
|
import WysiwygComposer
|
||||||
|
|
||||||
|
enum ComposerToolbarVoiceMessageAction {
|
||||||
|
case startRecording
|
||||||
|
case stopRecording
|
||||||
|
case cancelRecording
|
||||||
|
case deleteRecording
|
||||||
|
case startPlayback
|
||||||
|
case pausePlayback
|
||||||
|
case scrubPlayback(scrubbing: Bool)
|
||||||
|
case seekPlayback(progress: Double)
|
||||||
|
case send
|
||||||
|
}
|
||||||
|
|
||||||
enum ComposerToolbarViewModelAction {
|
enum ComposerToolbarViewModelAction {
|
||||||
case sendMessage(plain: String, html: String?, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions)
|
case sendMessage(plain: String, html: String?, mode: RoomScreenComposerMode, intentionalMentions: IntentionalMentions)
|
||||||
case displayCameraPicker
|
case displayCameraPicker
|
||||||
@@ -31,15 +43,7 @@ enum ComposerToolbarViewModelAction {
|
|||||||
case composerModeChanged(mode: RoomScreenComposerMode)
|
case composerModeChanged(mode: RoomScreenComposerMode)
|
||||||
case composerFocusedChanged(isFocused: Bool)
|
case composerFocusedChanged(isFocused: Bool)
|
||||||
|
|
||||||
case startVoiceMessageRecording
|
case voiceMessage(ComposerToolbarVoiceMessageAction)
|
||||||
case stopVoiceMessageRecording
|
|
||||||
case cancelVoiceMessageRecording
|
|
||||||
case deleteVoiceMessageRecording
|
|
||||||
case startVoiceMessagePlayback
|
|
||||||
case pauseVoiceMessagePlayback
|
|
||||||
case scrubVoiceMessagePlayback(scrubbing: Bool)
|
|
||||||
case seekVoiceMessagePlayback(progress: Double)
|
|
||||||
case sendVoiceMessage
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ComposerToolbarViewAction {
|
enum ComposerToolbarViewAction {
|
||||||
@@ -56,14 +60,8 @@ enum ComposerToolbarViewAction {
|
|||||||
case enableTextFormatting
|
case enableTextFormatting
|
||||||
case composerAction(action: ComposerAction)
|
case composerAction(action: ComposerAction)
|
||||||
case selectedSuggestion(_ suggestion: SuggestionItem)
|
case selectedSuggestion(_ suggestion: SuggestionItem)
|
||||||
case startVoiceMessageRecording
|
|
||||||
case stopVoiceMessageRecording
|
case voiceMessage(ComposerToolbarVoiceMessageAction)
|
||||||
case cancelVoiceMessageRecording
|
|
||||||
case deleteVoiceMessageRecording
|
|
||||||
case startVoiceMessagePlayback
|
|
||||||
case pauseVoiceMessagePlayback
|
|
||||||
case scrubVoiceMessagePlayback(scrubbing: Bool)
|
|
||||||
case seekVoiceMessagePlayback(progress: Double)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ComposerToolbarViewState: BindableState {
|
struct ComposerToolbarViewState: BindableState {
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
|||||||
|
|
||||||
switch state.composerMode {
|
switch state.composerMode {
|
||||||
case .previewVoiceMessage:
|
case .previewVoiceMessage:
|
||||||
actionsSubject.send(.sendVoiceMessage)
|
actionsSubject.send(.voiceMessage(.send))
|
||||||
default:
|
default:
|
||||||
let sendHTML = ServiceLocator.shared.settings.richTextEditorEnabled
|
let sendHTML = ServiceLocator.shared.settings.richTextEditorEnabled
|
||||||
actionsSubject.send(.sendMessage(plain: wysiwygViewModel.content.markdown,
|
actionsSubject.send(.sendMessage(plain: wysiwygViewModel.content.markdown,
|
||||||
@@ -143,23 +143,8 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
|||||||
}
|
}
|
||||||
case .selectedSuggestion(let suggestion):
|
case .selectedSuggestion(let suggestion):
|
||||||
handleSuggestion(suggestion)
|
handleSuggestion(suggestion)
|
||||||
case .startVoiceMessageRecording:
|
case .voiceMessage(let voiceMessageAction):
|
||||||
state.bindings.composerActionsEnabled = false
|
processVoiceMessageAction(voiceMessageAction)
|
||||||
actionsSubject.send(.startVoiceMessageRecording)
|
|
||||||
case .stopVoiceMessageRecording:
|
|
||||||
actionsSubject.send(.stopVoiceMessageRecording)
|
|
||||||
case .cancelVoiceMessageRecording:
|
|
||||||
actionsSubject.send(.cancelVoiceMessageRecording)
|
|
||||||
case .deleteVoiceMessageRecording:
|
|
||||||
actionsSubject.send(.deleteVoiceMessageRecording)
|
|
||||||
case .startVoiceMessagePlayback:
|
|
||||||
actionsSubject.send(.startVoiceMessagePlayback)
|
|
||||||
case .pauseVoiceMessagePlayback:
|
|
||||||
actionsSubject.send(.pauseVoiceMessagePlayback)
|
|
||||||
case .seekVoiceMessagePlayback(let progress):
|
|
||||||
actionsSubject.send(.seekVoiceMessagePlayback(progress: progress))
|
|
||||||
case .scrubVoiceMessagePlayback(let scrubbing):
|
|
||||||
actionsSubject.send(.scrubVoiceMessagePlayback(scrubbing: scrubbing))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +174,30 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
|||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func processVoiceMessageAction(_ action: ComposerToolbarVoiceMessageAction) {
|
||||||
|
switch action {
|
||||||
|
case .startRecording:
|
||||||
|
state.bindings.composerActionsEnabled = false
|
||||||
|
actionsSubject.send(.voiceMessage(.startRecording))
|
||||||
|
case .stopRecording:
|
||||||
|
actionsSubject.send(.voiceMessage(.stopRecording))
|
||||||
|
case .cancelRecording:
|
||||||
|
actionsSubject.send(.voiceMessage(.cancelRecording))
|
||||||
|
case .deleteRecording:
|
||||||
|
actionsSubject.send(.voiceMessage(.deleteRecording))
|
||||||
|
case .startPlayback:
|
||||||
|
actionsSubject.send(.voiceMessage(.startPlayback))
|
||||||
|
case .pausePlayback:
|
||||||
|
actionsSubject.send(.voiceMessage(.pausePlayback))
|
||||||
|
case .scrubPlayback(let scrubbing):
|
||||||
|
actionsSubject.send(.voiceMessage(.scrubPlayback(scrubbing: scrubbing)))
|
||||||
|
case .seekPlayback(let progress):
|
||||||
|
actionsSubject.send(.voiceMessage(.seekPlayback(progress: progress)))
|
||||||
|
case .send:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func setupMentionsHandling(mentionDisplayHelper: MentionDisplayHelper) {
|
private func setupMentionsHandling(mentionDisplayHelper: MentionDisplayHelper) {
|
||||||
wysiwygViewModel.textView.mentionDisplayHelper = mentionDisplayHelper
|
wysiwygViewModel.textView.mentionDisplayHelper = mentionDisplayHelper
|
||||||
|
|
||||||
|
|||||||
@@ -250,12 +250,12 @@ struct ComposerToolbar: View {
|
|||||||
|
|
||||||
private var voiceMessageRecordingButton: some View {
|
private var voiceMessageRecordingButton: some View {
|
||||||
VoiceMessageRecordingButton {
|
VoiceMessageRecordingButton {
|
||||||
context.send(viewAction: .startVoiceMessageRecording)
|
context.send(viewAction: .voiceMessage(.startRecording))
|
||||||
} stopRecording: { minimumRecordTimeReached in
|
} stopRecording: { minimumRecordTimeReached in
|
||||||
if minimumRecordTimeReached {
|
if minimumRecordTimeReached {
|
||||||
context.send(viewAction: .stopVoiceMessageRecording)
|
context.send(viewAction: .voiceMessage(.stopRecording))
|
||||||
} else {
|
} else {
|
||||||
context.send(viewAction: .cancelVoiceMessageRecording)
|
context.send(viewAction: .voiceMessage(.cancelRecording))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(4)
|
.padding(4)
|
||||||
@@ -263,7 +263,7 @@ struct ComposerToolbar: View {
|
|||||||
|
|
||||||
private var voiceMessageTrashButton: some View {
|
private var voiceMessageTrashButton: some View {
|
||||||
Button(role: .destructive) {
|
Button(role: .destructive) {
|
||||||
context.send(viewAction: .deleteVoiceMessageRecording)
|
context.send(viewAction: .voiceMessage(.deleteRecording))
|
||||||
} label: {
|
} label: {
|
||||||
CompoundIcon(\.delete)
|
CompoundIcon(\.delete)
|
||||||
.padding(EdgeInsets(top: 10, leading: 11, bottom: 10, trailing: 11))
|
.padding(EdgeInsets(top: 10, leading: 11, bottom: 10, trailing: 11))
|
||||||
@@ -274,13 +274,13 @@ struct ComposerToolbar: View {
|
|||||||
|
|
||||||
private func voiceMessagePreviewComposer(audioPlayerState: AudioPlayerState, waveform: WaveformSource) -> some View {
|
private func voiceMessagePreviewComposer(audioPlayerState: AudioPlayerState, waveform: WaveformSource) -> some View {
|
||||||
VoiceMessagePreviewComposer(playerState: audioPlayerState, waveform: waveform) {
|
VoiceMessagePreviewComposer(playerState: audioPlayerState, waveform: waveform) {
|
||||||
context.send(viewAction: .startVoiceMessagePlayback)
|
context.send(viewAction: .voiceMessage(.startPlayback))
|
||||||
} onPause: {
|
} onPause: {
|
||||||
context.send(viewAction: .pauseVoiceMessagePlayback)
|
context.send(viewAction: .voiceMessage(.pausePlayback))
|
||||||
} onSeek: { progress in
|
} onSeek: { progress in
|
||||||
context.send(viewAction: .seekVoiceMessagePlayback(progress: progress))
|
context.send(viewAction: .voiceMessage(.seekPlayback(progress: progress)))
|
||||||
} onScrubbing: { isScrubbing in
|
} onScrubbing: { isScrubbing in
|
||||||
context.send(viewAction: .scrubVoiceMessagePlayback(scrubbing: isScrubbing))
|
context.send(viewAction: .voiceMessage(.scrubPlayback(scrubbing: isScrubbing)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,16 @@ enum RoomScreenComposerMode: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum RoomScreenViewPollAction {
|
||||||
|
case selectOption(pollStartID: String, optionID: String)
|
||||||
|
case end(pollStartID: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum RoomScreenViewAudioAction {
|
||||||
|
case playPause(itemID: TimelineItemIdentifier)
|
||||||
|
case seek(itemID: TimelineItemIdentifier, progress: Double)
|
||||||
|
}
|
||||||
|
|
||||||
enum RoomScreenViewAction {
|
enum RoomScreenViewAction {
|
||||||
case displayRoomDetails
|
case displayRoomDetails
|
||||||
case itemAppeared(itemID: TimelineItemIdentifier)
|
case itemAppeared(itemID: TimelineItemIdentifier)
|
||||||
@@ -71,8 +81,6 @@ enum RoomScreenViewAction {
|
|||||||
case toggleReaction(key: String, itemID: TimelineItemIdentifier)
|
case toggleReaction(key: String, itemID: TimelineItemIdentifier)
|
||||||
case sendReadReceiptIfNeeded(TimelineItemIdentifier)
|
case sendReadReceiptIfNeeded(TimelineItemIdentifier)
|
||||||
case paginateBackwards
|
case paginateBackwards
|
||||||
case selectedPollOption(pollStartID: String, optionID: String)
|
|
||||||
case endPoll(pollStartID: String)
|
|
||||||
|
|
||||||
case timelineItemMenu(itemID: TimelineItemIdentifier)
|
case timelineItemMenu(itemID: TimelineItemIdentifier)
|
||||||
case timelineItemMenuAction(itemID: TimelineItemIdentifier, action: TimelineItemMenuAction)
|
case timelineItemMenuAction(itemID: TimelineItemIdentifier, action: TimelineItemMenuAction)
|
||||||
@@ -80,6 +88,7 @@ enum RoomScreenViewAction {
|
|||||||
case displayEmojiPicker(itemID: TimelineItemIdentifier)
|
case displayEmojiPicker(itemID: TimelineItemIdentifier)
|
||||||
|
|
||||||
case handlePasteOrDrop(provider: NSItemProvider)
|
case handlePasteOrDrop(provider: NSItemProvider)
|
||||||
|
|
||||||
case tappedOnUser(userID: String)
|
case tappedOnUser(userID: String)
|
||||||
|
|
||||||
case reactionSummary(itemID: TimelineItemIdentifier, key: String)
|
case reactionSummary(itemID: TimelineItemIdentifier, key: String)
|
||||||
@@ -89,8 +98,9 @@ enum RoomScreenViewAction {
|
|||||||
|
|
||||||
case scrolledToBottom
|
case scrolledToBottom
|
||||||
|
|
||||||
case playPauseAudio(itemID: TimelineItemIdentifier)
|
case poll(RoomScreenViewPollAction)
|
||||||
case seekAudio(itemID: TimelineItemIdentifier, progress: Double)
|
|
||||||
|
case audio(RoomScreenViewAudioAction)
|
||||||
|
|
||||||
case presentCall
|
case presentCall
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,18 +160,10 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
if state.swiftUITimelineEnabled {
|
if state.swiftUITimelineEnabled {
|
||||||
renderPendingTimelineItems()
|
renderPendingTimelineItems()
|
||||||
}
|
}
|
||||||
case let .selectedPollOption(pollStartID, optionID):
|
case .poll(let pollAction):
|
||||||
roomScreenInteractionHandler.sendPollResponse(pollStartID: pollStartID, optionID: optionID)
|
processPollAction(pollAction)
|
||||||
case .playPauseAudio(let itemID):
|
case .audio(let audioAction):
|
||||||
Task { await roomScreenInteractionHandler.playPauseAudio(for: itemID) }
|
processAudioAction(audioAction)
|
||||||
case .seekAudio(let itemID, let progress):
|
|
||||||
Task { await roomScreenInteractionHandler.seekAudio(for: itemID, progress: progress) }
|
|
||||||
case let .endPoll(pollStartID):
|
|
||||||
state.bindings.confirmationAlertInfo = .init(id: .init(),
|
|
||||||
title: L10n.actionEndPoll,
|
|
||||||
message: L10n.commonPollEndConfirmation,
|
|
||||||
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
|
||||||
secondaryButton: .init(title: L10n.actionOk, action: { self.roomScreenInteractionHandler.endPoll(pollStartID: pollStartID) }))
|
|
||||||
case .presentCall:
|
case .presentCall:
|
||||||
actionsSubject.send(.displayCallScreen)
|
actionsSubject.send(.displayCallScreen)
|
||||||
}
|
}
|
||||||
@@ -202,31 +194,60 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
|||||||
trackComposerMode(mode)
|
trackComposerMode(mode)
|
||||||
case .composerFocusedChanged(isFocused: let isFocused):
|
case .composerFocusedChanged(isFocused: let isFocused):
|
||||||
composerFocusedSubject.send(isFocused)
|
composerFocusedSubject.send(isFocused)
|
||||||
case .startVoiceMessageRecording:
|
case .voiceMessage(let voiceMessageAction):
|
||||||
Task {
|
processVoiceMessageAction(voiceMessageAction)
|
||||||
await mediaPlayerProvider.detachAllStates(except: nil)
|
|
||||||
await roomScreenInteractionHandler.startRecordingVoiceMessage()
|
|
||||||
}
|
|
||||||
case .stopVoiceMessageRecording:
|
|
||||||
Task { await roomScreenInteractionHandler.stopRecordingVoiceMessage() }
|
|
||||||
case .cancelVoiceMessageRecording:
|
|
||||||
Task { await roomScreenInteractionHandler.cancelRecordingVoiceMessage() }
|
|
||||||
case .deleteVoiceMessageRecording:
|
|
||||||
Task { await roomScreenInteractionHandler.deleteCurrentVoiceMessage() }
|
|
||||||
case .sendVoiceMessage:
|
|
||||||
Task { await roomScreenInteractionHandler.sendCurrentVoiceMessage() }
|
|
||||||
case .startVoiceMessagePlayback:
|
|
||||||
Task { await roomScreenInteractionHandler.startPlayingRecordedVoiceMessage() }
|
|
||||||
case .pauseVoiceMessagePlayback:
|
|
||||||
roomScreenInteractionHandler.pausePlayingRecordedVoiceMessage()
|
|
||||||
case .seekVoiceMessagePlayback(let progress):
|
|
||||||
Task { await roomScreenInteractionHandler.seekRecordedVoiceMessage(to: progress) }
|
|
||||||
case .scrubVoiceMessagePlayback(let scrubbing):
|
|
||||||
Task { await roomScreenInteractionHandler.scrubVoiceMessagePlayback(scrubbing: scrubbing) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Private
|
// MARK: - Private
|
||||||
|
|
||||||
|
private func processPollAction(_ action: RoomScreenViewPollAction) {
|
||||||
|
switch action {
|
||||||
|
case let .selectOption(pollStartID, optionID):
|
||||||
|
roomScreenInteractionHandler.sendPollResponse(pollStartID: pollStartID, optionID: optionID)
|
||||||
|
case let .end(pollStartID):
|
||||||
|
state.bindings.confirmationAlertInfo = .init(id: .init(),
|
||||||
|
title: L10n.actionEndPoll,
|
||||||
|
message: L10n.commonPollEndConfirmation,
|
||||||
|
primaryButton: .init(title: L10n.actionCancel, role: .cancel, action: nil),
|
||||||
|
secondaryButton: .init(title: L10n.actionOk, action: { self.roomScreenInteractionHandler.endPoll(pollStartID: pollStartID) }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func processAudioAction(_ action: RoomScreenViewAudioAction) {
|
||||||
|
switch action {
|
||||||
|
case .playPause(let itemID):
|
||||||
|
Task { await roomScreenInteractionHandler.playPauseAudio(for: itemID) }
|
||||||
|
case .seek(let itemID, let progress):
|
||||||
|
Task { await roomScreenInteractionHandler.seekAudio(for: itemID, progress: progress) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func processVoiceMessageAction(_ action: ComposerToolbarVoiceMessageAction) {
|
||||||
|
switch action {
|
||||||
|
case .startRecording:
|
||||||
|
Task {
|
||||||
|
await mediaPlayerProvider.detachAllStates(except: nil)
|
||||||
|
await roomScreenInteractionHandler.startRecordingVoiceMessage()
|
||||||
|
}
|
||||||
|
case .stopRecording:
|
||||||
|
Task { await roomScreenInteractionHandler.stopRecordingVoiceMessage() }
|
||||||
|
case .cancelRecording:
|
||||||
|
Task { await roomScreenInteractionHandler.cancelRecordingVoiceMessage() }
|
||||||
|
case .deleteRecording:
|
||||||
|
Task { await roomScreenInteractionHandler.deleteCurrentVoiceMessage() }
|
||||||
|
case .send:
|
||||||
|
Task { await roomScreenInteractionHandler.sendCurrentVoiceMessage() }
|
||||||
|
case .startPlayback:
|
||||||
|
Task { await roomScreenInteractionHandler.startPlayingRecordedVoiceMessage() }
|
||||||
|
case .pausePlayback:
|
||||||
|
roomScreenInteractionHandler.pausePlayingRecordedVoiceMessage()
|
||||||
|
case .seekPlayback(let progress):
|
||||||
|
Task { await roomScreenInteractionHandler.seekRecordedVoiceMessage(to: progress) }
|
||||||
|
case .scrubPlayback(let scrubbing):
|
||||||
|
Task { await roomScreenInteractionHandler.scrubVoiceMessagePlayback(scrubbing: scrubbing) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func setupSubscriptions() {
|
private func setupSubscriptions() {
|
||||||
appSettings.$swiftUITimelineEnabled
|
appSettings.$swiftUITimelineEnabled
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ struct PollRoomTimelineView: View {
|
|||||||
ForEach(poll.options, id: \.id) { option in
|
ForEach(poll.options, id: \.id) { option in
|
||||||
Button {
|
Button {
|
||||||
guard let eventID, !option.isSelected else { return }
|
guard let eventID, !option.isSelected else { return }
|
||||||
context.send(viewAction: .selectedPollOption(pollStartID: eventID, optionID: option.id))
|
context.send(viewAction: .poll(.selectOption(pollStartID: eventID, optionID: option.id)))
|
||||||
feedbackGenerator.impactOccurred()
|
feedbackGenerator.impactOccurred()
|
||||||
} label: {
|
} label: {
|
||||||
PollOptionView(pollOption: option,
|
PollOptionView(pollOption: option,
|
||||||
@@ -93,7 +93,7 @@ struct PollRoomTimelineView: View {
|
|||||||
private var toolbarView: some View {
|
private var toolbarView: some View {
|
||||||
if !poll.hasEnded, poll.createdByAccountOwner, let eventID {
|
if !poll.hasEnded, poll.createdByAccountOwner, let eventID {
|
||||||
Button {
|
Button {
|
||||||
context.send(viewAction: .endPoll(pollStartID: eventID))
|
context.send(viewAction: .poll(.end(pollStartID: eventID)))
|
||||||
} label: {
|
} label: {
|
||||||
Text(L10n.actionEndPoll)
|
Text(L10n.actionEndPoll)
|
||||||
.lineLimit(2, reservesSpace: false)
|
.lineLimit(2, reservesSpace: false)
|
||||||
|
|||||||
+1
-1
@@ -150,7 +150,7 @@ struct SecureBackupScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
}
|
}
|
||||||
.previewDisplayName("Recovery incomplete")
|
.previewDisplayName("Recovery incomplete")
|
||||||
}
|
}
|
||||||
.snapshot(delay: 0.5)
|
.snapshot(delay: 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func viewModel(keyBackupState: SecureBackupKeyBackupState,
|
static func viewModel(keyBackupState: SecureBackupKeyBackupState,
|
||||||
|
|||||||
+4
-4
@@ -40,22 +40,22 @@ struct VoiceMessageRoomTimelineView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func onPlaybackPlayPause() {
|
private func onPlaybackPlayPause() {
|
||||||
context.send(viewAction: .playPauseAudio(itemID: timelineItem.id))
|
context.send(viewAction: .audio(.playPause(itemID: timelineItem.id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func onPlaybackSeek(_ progress: Double) {
|
private func onPlaybackSeek(_ progress: Double) {
|
||||||
context.send(viewAction: .seekAudio(itemID: timelineItem.id, progress: progress))
|
context.send(viewAction: .audio(.seek(itemID: timelineItem.id, progress: progress)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private func onPlaybackScrubbing(_ dragging: Bool) {
|
private func onPlaybackScrubbing(_ dragging: Bool) {
|
||||||
if dragging {
|
if dragging {
|
||||||
if playerState.playbackState == .playing {
|
if playerState.playbackState == .playing {
|
||||||
resumePlaybackAfterScrubbing = true
|
resumePlaybackAfterScrubbing = true
|
||||||
context.send(viewAction: .playPauseAudio(itemID: timelineItem.id))
|
context.send(viewAction: .audio(.playPause(itemID: timelineItem.id)))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if resumePlaybackAfterScrubbing {
|
if resumePlaybackAfterScrubbing {
|
||||||
context.send(viewAction: .playPauseAudio(itemID: timelineItem.id))
|
context.send(viewAction: .audio(.playPause(itemID: timelineItem.id)))
|
||||||
resumePlaybackAfterScrubbing = false
|
resumePlaybackAfterScrubbing = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user