Draft: handle sharing so it doesn't destroy the previous draft
This commit is contained in:
parent
aa0520d47d
commit
91b81af5a8
|
@ -75,11 +75,7 @@ internal class DraftRepository @Inject constructor(@SessionDatabase private val
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun deleteDraftFromDb(realm: Realm, roomId: String) {
|
private fun deleteDraftFromDb(realm: Realm, roomId: String) {
|
||||||
UserDraftsEntity.where(realm, roomId).findFirst()?.let { userDraftsEntity ->
|
UserDraftsEntity.where(realm, roomId).findFirst()?.userDrafts?.clear()
|
||||||
if (userDraftsEntity.userDrafts.isNotEmpty()) {
|
|
||||||
userDraftsEntity.userDrafts.removeAt(userDraftsEntity.userDrafts.size - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveDraftInDb(realm: Realm, draft: UserDraft, roomId: String) {
|
private fun saveDraftInDb(realm: Realm, draft: UserDraft, roomId: String) {
|
||||||
|
|
|
@ -51,7 +51,7 @@ sealed class RoomDetailAction : VectorViewModelAction {
|
||||||
data class EnterEditMode(val eventId: String, val text: String) : RoomDetailAction()
|
data class EnterEditMode(val eventId: String, val text: String) : RoomDetailAction()
|
||||||
data class EnterQuoteMode(val eventId: String, val text: String) : RoomDetailAction()
|
data class EnterQuoteMode(val eventId: String, val text: String) : RoomDetailAction()
|
||||||
data class EnterReplyMode(val eventId: String, val text: String) : RoomDetailAction()
|
data class EnterReplyMode(val eventId: String, val text: String) : RoomDetailAction()
|
||||||
data class ExitSpecialMode(val text: String) : RoomDetailAction()
|
data class EnterRegularMode(val text: String, val fromSharing: Boolean) : RoomDetailAction()
|
||||||
|
|
||||||
data class ResendMessage(val eventId: String) : RoomDetailAction()
|
data class ResendMessage(val eventId: String) : RoomDetailAction()
|
||||||
data class RemoveFailedEcho(val eventId: String) : RoomDetailAction()
|
data class RemoveFailedEcho(val eventId: String) : RoomDetailAction()
|
||||||
|
|
|
@ -485,8 +485,7 @@ class RoomDetailFragment @Inject constructor(
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
when (val sharedData = roomDetailArgs.sharedData) {
|
when (val sharedData = roomDetailArgs.sharedData) {
|
||||||
is SharedData.Text -> {
|
is SharedData.Text -> {
|
||||||
// Save a draft to set the shared text to the composer
|
roomDetailViewModel.handle(RoomDetailAction.EnterRegularMode(sharedData.text, fromSharing = true))
|
||||||
roomDetailViewModel.handle(RoomDetailAction.SaveDraft(sharedData.text))
|
|
||||||
}
|
}
|
||||||
is SharedData.Attachments -> {
|
is SharedData.Attachments -> {
|
||||||
// open share edition
|
// open share edition
|
||||||
|
@ -1014,7 +1013,7 @@ class RoomDetailFragment @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCloseRelatedMessage() {
|
override fun onCloseRelatedMessage() {
|
||||||
roomDetailViewModel.handle(RoomDetailAction.ExitSpecialMode(composerLayout.text.toString()))
|
roomDetailViewModel.handle(RoomDetailAction.EnterRegularMode(composerLayout.text.toString(), false))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRichContentSelected(contentUri: Uri): Boolean {
|
override fun onRichContentSelected(contentUri: Uri): Boolean {
|
||||||
|
@ -1147,12 +1146,8 @@ class RoomDetailFragment @Inject constructor(
|
||||||
|
|
||||||
private fun renderSendMessageResult(sendMessageResult: RoomDetailViewEvents.SendMessageResult) {
|
private fun renderSendMessageResult(sendMessageResult: RoomDetailViewEvents.SendMessageResult) {
|
||||||
when (sendMessageResult) {
|
when (sendMessageResult) {
|
||||||
is RoomDetailViewEvents.MessageSent -> {
|
|
||||||
updateComposerText("")
|
|
||||||
}
|
|
||||||
is RoomDetailViewEvents.SlashCommandHandled -> {
|
is RoomDetailViewEvents.SlashCommandHandled -> {
|
||||||
sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) }
|
sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) }
|
||||||
updateComposerText("")
|
|
||||||
}
|
}
|
||||||
is RoomDetailViewEvents.SlashCommandError -> {
|
is RoomDetailViewEvents.SlashCommandError -> {
|
||||||
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
|
displayCommandError(getString(R.string.command_problem_with_parameters, sendMessageResult.command.command))
|
||||||
|
|
|
@ -164,7 +164,7 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
getUnreadState()
|
getUnreadState()
|
||||||
observeSyncState()
|
observeSyncState()
|
||||||
observeEventDisplayedActions()
|
observeEventDisplayedActions()
|
||||||
observeDrafts()
|
getDraftIfAny()
|
||||||
observeUnreadState()
|
observeUnreadState()
|
||||||
observeMyRoomMember()
|
observeMyRoomMember()
|
||||||
observeActiveRoomWidgets()
|
observeActiveRoomWidgets()
|
||||||
|
@ -226,52 +226,52 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
|
|
||||||
override fun handle(action: RoomDetailAction) {
|
override fun handle(action: RoomDetailAction) {
|
||||||
when (action) {
|
when (action) {
|
||||||
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
|
is RoomDetailAction.UserIsTyping -> handleUserIsTyping(action)
|
||||||
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
|
is RoomDetailAction.SaveDraft -> handleSaveDraft(action)
|
||||||
is RoomDetailAction.SendMessage -> handleSendMessage(action)
|
is RoomDetailAction.SendMessage -> handleSendMessage(action)
|
||||||
is RoomDetailAction.SendMedia -> handleSendMedia(action)
|
is RoomDetailAction.SendMedia -> handleSendMedia(action)
|
||||||
is RoomDetailAction.SendSticker -> handleSendSticker(action)
|
is RoomDetailAction.SendSticker -> handleSendSticker(action)
|
||||||
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
|
is RoomDetailAction.TimelineEventTurnsVisible -> handleEventVisible(action)
|
||||||
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
|
is RoomDetailAction.TimelineEventTurnsInvisible -> handleEventInvisible(action)
|
||||||
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
|
is RoomDetailAction.LoadMoreTimelineEvents -> handleLoadMore(action)
|
||||||
is RoomDetailAction.SendReaction -> handleSendReaction(action)
|
is RoomDetailAction.SendReaction -> handleSendReaction(action)
|
||||||
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
|
is RoomDetailAction.AcceptInvite -> handleAcceptInvite()
|
||||||
is RoomDetailAction.RejectInvite -> handleRejectInvite()
|
is RoomDetailAction.RejectInvite -> handleRejectInvite()
|
||||||
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
|
is RoomDetailAction.RedactAction -> handleRedactEvent(action)
|
||||||
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
|
is RoomDetailAction.UndoReaction -> handleUndoReact(action)
|
||||||
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
|
is RoomDetailAction.UpdateQuickReactAction -> handleUpdateQuickReaction(action)
|
||||||
is RoomDetailAction.ExitSpecialMode -> handleExitSpecialMode(action)
|
is RoomDetailAction.EnterRegularMode -> handleEnterRegularMode(action)
|
||||||
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
|
is RoomDetailAction.EnterEditMode -> handleEditAction(action)
|
||||||
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
|
is RoomDetailAction.EnterQuoteMode -> handleQuoteAction(action)
|
||||||
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
|
is RoomDetailAction.EnterReplyMode -> handleReplyAction(action)
|
||||||
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
|
is RoomDetailAction.DownloadOrOpen -> handleOpenOrDownloadFile(action)
|
||||||
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
|
is RoomDetailAction.NavigateToEvent -> handleNavigateToEvent(action)
|
||||||
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
|
is RoomDetailAction.HandleTombstoneEvent -> handleTombstoneEvent(action)
|
||||||
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
|
is RoomDetailAction.ResendMessage -> handleResendEvent(action)
|
||||||
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
|
is RoomDetailAction.RemoveFailedEcho -> handleRemove(action)
|
||||||
is RoomDetailAction.ClearSendQueue -> handleClearSendQueue()
|
is RoomDetailAction.ClearSendQueue -> handleClearSendQueue()
|
||||||
is RoomDetailAction.ResendAll -> handleResendAll()
|
is RoomDetailAction.ResendAll -> handleResendAll()
|
||||||
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
|
is RoomDetailAction.MarkAllAsRead -> handleMarkAllAsRead()
|
||||||
is RoomDetailAction.ReportContent -> handleReportContent(action)
|
is RoomDetailAction.ReportContent -> handleReportContent(action)
|
||||||
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
|
is RoomDetailAction.IgnoreUser -> handleIgnoreUser(action)
|
||||||
is RoomDetailAction.EnterTrackingUnreadMessagesState -> startTrackingUnreadMessages()
|
is RoomDetailAction.EnterTrackingUnreadMessagesState -> startTrackingUnreadMessages()
|
||||||
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
|
is RoomDetailAction.ExitTrackingUnreadMessagesState -> stopTrackingUnreadMessages()
|
||||||
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
|
is RoomDetailAction.ReplyToOptions -> handleReplyToOptions(action)
|
||||||
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
|
is RoomDetailAction.AcceptVerificationRequest -> handleAcceptVerification(action)
|
||||||
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
|
is RoomDetailAction.DeclineVerificationRequest -> handleDeclineVerification(action)
|
||||||
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
|
is RoomDetailAction.RequestVerification -> handleRequestVerification(action)
|
||||||
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
|
is RoomDetailAction.ResumeVerification -> handleResumeRequestVerification(action)
|
||||||
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
|
is RoomDetailAction.ReRequestKeys -> handleReRequestKeys(action)
|
||||||
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
|
is RoomDetailAction.TapOnFailedToDecrypt -> handleTapOnFailedToDecrypt(action)
|
||||||
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
|
is RoomDetailAction.SelectStickerAttachment -> handleSelectStickerAttachment()
|
||||||
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
|
is RoomDetailAction.OpenIntegrationManager -> handleOpenIntegrationManager()
|
||||||
is RoomDetailAction.StartCall -> handleStartCall(action)
|
is RoomDetailAction.StartCall -> handleStartCall(action)
|
||||||
is RoomDetailAction.EndCall -> handleEndCall()
|
is RoomDetailAction.EndCall -> handleEndCall()
|
||||||
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
is RoomDetailAction.ManageIntegrations -> handleManageIntegrations()
|
||||||
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
is RoomDetailAction.AddJitsiWidget -> handleAddJitsiConference(action)
|
||||||
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
is RoomDetailAction.RemoveWidget -> handleDeleteWidget(action.widgetId)
|
||||||
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
is RoomDetailAction.EnsureNativeWidgetAllowed -> handleCheckWidgetAllowed(action)
|
||||||
is RoomDetailAction.CancelSend -> handleCancel(action)
|
is RoomDetailAction.CancelSend -> handleCancel(action)
|
||||||
}.exhaustive
|
}.exhaustive
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,45 +451,48 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
*/
|
*/
|
||||||
private fun handleSaveDraft(action: RoomDetailAction.SaveDraft) {
|
private fun handleSaveDraft(action: RoomDetailAction.SaveDraft) {
|
||||||
withState {
|
withState {
|
||||||
when (it.sendMode) {
|
when {
|
||||||
is SendMode.REGULAR -> room.saveDraft(UserDraft.REGULAR(action.draft), NoOpMatrixCallback())
|
it.sendMode is SendMode.REGULAR && !it.sendMode.fromSharing -> {
|
||||||
is SendMode.REPLY -> room.saveDraft(UserDraft.REPLY(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
room.saveDraft(UserDraft.REGULAR(action.draft), NoOpMatrixCallback())
|
||||||
is SendMode.QUOTE -> room.saveDraft(UserDraft.QUOTE(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
}
|
||||||
is SendMode.EDIT -> room.saveDraft(UserDraft.EDIT(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
it.sendMode is SendMode.REPLY -> {
|
||||||
}.exhaustive
|
room.saveDraft(UserDraft.REPLY(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
||||||
|
}
|
||||||
|
it.sendMode is SendMode.QUOTE -> {
|
||||||
|
room.saveDraft(UserDraft.QUOTE(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
||||||
|
}
|
||||||
|
it.sendMode is SendMode.EDIT -> {
|
||||||
|
room.saveDraft(UserDraft.EDIT(it.sendMode.timelineEvent.root.eventId!!, action.draft), NoOpMatrixCallback())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeDrafts() {
|
private fun getDraftIfAny() {
|
||||||
room.rx().liveDrafts()
|
val currentDraft = room.getDraft() ?: return
|
||||||
.subscribe {
|
setState {
|
||||||
Timber.d("Draft update --> SetState")
|
copy(
|
||||||
setState {
|
// Create a sendMode from a draft and retrieve the TimelineEvent
|
||||||
val draft = it.lastOrNull() ?: UserDraft.REGULAR("")
|
sendMode = when (currentDraft) {
|
||||||
copy(
|
is UserDraft.REGULAR -> SendMode.REGULAR(currentDraft.text, false)
|
||||||
// Create a sendMode from a draft and retrieve the TimelineEvent
|
is UserDraft.QUOTE -> {
|
||||||
sendMode = when (draft) {
|
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
is UserDraft.REGULAR -> SendMode.REGULAR(draft.text)
|
SendMode.QUOTE(timelineEvent, currentDraft.text)
|
||||||
is UserDraft.QUOTE -> {
|
}
|
||||||
room.getTimeLineEvent(draft.linkedEventId)?.let { timelineEvent ->
|
}
|
||||||
SendMode.QUOTE(timelineEvent, draft.text)
|
is UserDraft.REPLY -> {
|
||||||
}
|
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
}
|
SendMode.REPLY(timelineEvent, currentDraft.text)
|
||||||
is UserDraft.REPLY -> {
|
}
|
||||||
room.getTimeLineEvent(draft.linkedEventId)?.let { timelineEvent ->
|
}
|
||||||
SendMode.REPLY(timelineEvent, draft.text)
|
is UserDraft.EDIT -> {
|
||||||
}
|
room.getTimeLineEvent(currentDraft.linkedEventId)?.let { timelineEvent ->
|
||||||
}
|
SendMode.EDIT(timelineEvent, currentDraft.text)
|
||||||
is UserDraft.EDIT -> {
|
}
|
||||||
room.getTimeLineEvent(draft.linkedEventId)?.let { timelineEvent ->
|
}
|
||||||
SendMode.EDIT(timelineEvent, draft.text)
|
} ?: SendMode.REGULAR("", fromSharing = false)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
} ?: SendMode.REGULAR("")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.disposeOnClear()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleUserIsTyping(action: RoomDetailAction.UserIsTyping) {
|
private fun handleUserIsTyping(action: RoomDetailAction.UserIsTyping) {
|
||||||
|
@ -740,11 +743,15 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun popDraft() {
|
private fun popDraft() = withState {
|
||||||
setState {
|
if (it.sendMode is SendMode.REGULAR && it.sendMode.fromSharing) {
|
||||||
copy(sendMode = SendMode.REGULAR(""))
|
// If we were sharing, we want to get back our last value from draft
|
||||||
|
getDraftIfAny()
|
||||||
|
} else {
|
||||||
|
// Otherwise we clear the composer and remove the draft from db
|
||||||
|
setState { copy(sendMode = SendMode.REGULAR("", false)) }
|
||||||
|
room.deleteDraft(NoOpMatrixCallback())
|
||||||
}
|
}
|
||||||
room.deleteDraft(NoOpMatrixCallback())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleJoinToAnotherRoomSlashCommand(command: ParsedCommand.JoinRoom) {
|
private fun handleJoinToAnotherRoomSlashCommand(command: ParsedCommand.JoinRoom) {
|
||||||
|
@ -935,9 +942,8 @@ class RoomDetailViewModel @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleExitSpecialMode(action: RoomDetailAction.ExitSpecialMode) = withState {
|
private fun handleEnterRegularMode(action: RoomDetailAction.EnterRegularMode) = setState {
|
||||||
room.deleteDraft(NoOpMatrixCallback())
|
copy(sendMode = SendMode.REGULAR(action.text, action.fromSharing))
|
||||||
setState { copy(sendMode = SendMode.REGULAR(action.text)) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleOpenOrDownloadFile(action: RoomDetailAction.DownloadOrOpen) {
|
private fun handleOpenOrDownloadFile(action: RoomDetailAction.DownloadOrOpen) {
|
||||||
|
|
|
@ -37,7 +37,12 @@ import org.matrix.android.sdk.api.session.widgets.model.Widget
|
||||||
* Depending on the state the bottom toolbar will change (icons/preview/actions...)
|
* Depending on the state the bottom toolbar will change (icons/preview/actions...)
|
||||||
*/
|
*/
|
||||||
sealed class SendMode(open val text: String) {
|
sealed class SendMode(open val text: String) {
|
||||||
data class REGULAR(override val text: String) : SendMode(text)
|
data class REGULAR(
|
||||||
|
override val text: String,
|
||||||
|
val fromSharing: Boolean,
|
||||||
|
// This is necessary for forcing refresh on selectSubscribe
|
||||||
|
private val ts: Long = System.currentTimeMillis()
|
||||||
|
) : SendMode(text)
|
||||||
data class QUOTE(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
data class QUOTE(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
||||||
data class EDIT(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
data class EDIT(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
||||||
data class REPLY(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
data class REPLY(val timelineEvent: TimelineEvent, override val text: String) : SendMode(text)
|
||||||
|
@ -58,7 +63,7 @@ data class RoomDetailViewState(
|
||||||
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
|
val asyncRoomSummary: Async<RoomSummary> = Uninitialized,
|
||||||
val activeRoomWidgets: Async<List<Widget>> = Uninitialized,
|
val activeRoomWidgets: Async<List<Widget>> = Uninitialized,
|
||||||
val typingMessage: String? = null,
|
val typingMessage: String? = null,
|
||||||
val sendMode: SendMode = SendMode.REGULAR(""),
|
val sendMode: SendMode = SendMode.REGULAR("", false),
|
||||||
val tombstoneEvent: Event? = null,
|
val tombstoneEvent: Event? = null,
|
||||||
val tombstoneEventHandling: Async<String> = Uninitialized,
|
val tombstoneEventHandling: Async<String> = Uninitialized,
|
||||||
val syncState: SyncState = SyncState.Idle,
|
val syncState: SyncState = SyncState.Idle,
|
||||||
|
|
Loading…
Reference in New Issue