diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/MessageColorProvider.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/MessageColorProvider.kt index 253619fdae..2b39eb1e26 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/MessageColorProvider.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/MessageColorProvider.kt @@ -50,17 +50,8 @@ class MessageColorProvider @Inject constructor( SendState.FAILED_UNKNOWN_DEVICES -> colorProvider.getColorFromAttribute(R.attr.vctr_unsent_message_text_color) } } else { - // When not in developer mode, we do not use special color for the encrypting state - when (sendState) { - SendState.UNKNOWN, - SendState.UNSENT, - SendState.ENCRYPTING, - SendState.SENDING, - SendState.SENT, - SendState.SYNCED -> colorProvider.getColorFromAttribute(R.attr.vctr_message_text_color) - SendState.UNDELIVERED, - SendState.FAILED_UNKNOWN_DEVICES -> colorProvider.getColorFromAttribute(R.attr.vctr_unsent_message_text_color) - } + // When not in developer mode, we use only one color + colorProvider.getColorFromAttribute(R.attr.vctr_message_text_color) } } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index fa92d5f136..1e93c29673 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -35,6 +35,7 @@ import im.vector.app.features.home.room.detail.timeline.item.E2EDecoration import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod import im.vector.app.features.home.room.detail.timeline.tools.linkify import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.session.room.send.SendState import javax.inject.Inject /** @@ -65,23 +66,23 @@ class MessageActionsEpoxyController @Inject constructor( // Send state val sendState = state.sendState() - if (sendState?.isSending().orFalse()) { - bottomSheetSendStateItem { - id("send_state") - showProgress(true) - text(stringProvider.getString(R.string.event_status_sending_message)) - } - } else if (sendState?.hasFailed().orFalse()) { + if (sendState?.hasFailed().orFalse()) { bottomSheetSendStateItem { id("send_state") showProgress(false) text(stringProvider.getString(R.string.unable_to_send_message)) drawableStart(R.drawable.ic_warning_badge) } + } else if (sendState != SendState.SYNCED) { + bottomSheetSendStateItem { + id("send_state") + showProgress(true) + text(stringProvider.getString(R.string.event_status_sending_message)) + } } when (state.informationData.e2eDecoration) { - E2EDecoration.WARN_IN_CLEAR -> { + E2EDecoration.WARN_IN_CLEAR -> { bottomSheetSendStateItem { id("e2e_clear") showProgress(false) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index aac622e45e..0b1f67c7b7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -18,10 +18,10 @@ package im.vector.app.features.home.room.detail.timeline.action import com.airbnb.mvrx.FragmentViewModelContext import com.airbnb.mvrx.MvRxViewModelFactory import com.airbnb.mvrx.ViewModelContext -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import dagger.assisted.AssistedFactory import dagger.Lazy +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject import im.vector.app.R import im.vector.app.core.extensions.canReact import im.vector.app.core.platform.EmptyViewEvents @@ -229,99 +229,19 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } private fun actionsForEvent(timelineEvent: TimelineEvent, actionPermissions: ActionPermissions): List { - val eventId = timelineEvent.eventId val messageContent = timelineEvent.getLastMessageContent() val msgType = messageContent?.msgType return arrayListOf().apply { - if (timelineEvent.root.sendState.hasFailed()) { - if (canRetry(timelineEvent, actionPermissions)) { - add(EventSharedAction.Resend(eventId)) + when { + timelineEvent.root.sendState.hasFailed() -> { + addActionsForFailedState(timelineEvent, actionPermissions, messageContent, msgType) } - add(EventSharedAction.Remove(eventId)) - if (vectorPreferences.developerMode()) { - addViewSourceItems(timelineEvent) + timelineEvent.root.sendState.isSending() -> { + addActionsForSendingState(timelineEvent) } - } else if (timelineEvent.root.sendState.isSending()) { - // TODO is uploading attachment? - if (canCancel(timelineEvent)) { - add(EventSharedAction.Cancel(eventId)) - } - } else if (timelineEvent.root.sendState == SendState.SYNCED) { - if (!timelineEvent.root.isRedacted()) { - if (canReply(timelineEvent, messageContent, actionPermissions)) { - add(EventSharedAction.Reply(eventId)) - } - - if (canEdit(timelineEvent, session.myUserId, actionPermissions)) { - add(EventSharedAction.Edit(eventId)) - } - - if (canRedact(timelineEvent, actionPermissions)) { - add(EventSharedAction.Redact(eventId, askForReason = informationData.senderId != session.myUserId)) - } - - if (canCopy(msgType)) { - // TODO copy images? html? see ClipBoard - add(EventSharedAction.Copy(messageContent!!.body)) - } - - if (timelineEvent.canReact() && actionPermissions.canReact) { - add(EventSharedAction.AddReaction(eventId)) - } - - if (canQuote(timelineEvent, messageContent, actionPermissions)) { - add(EventSharedAction.Quote(eventId)) - } - - if (canViewReactions(timelineEvent)) { - add(EventSharedAction.ViewReactions(informationData)) - } - - if (timelineEvent.hasBeenEdited()) { - add(EventSharedAction.ViewEditHistory(informationData)) - } - - if (canShare(msgType)) { - add(EventSharedAction.Share(timelineEvent.eventId, messageContent!!)) - } - - if (canSave(msgType) && messageContent is MessageWithAttachmentContent) { - add(EventSharedAction.Save(timelineEvent.eventId, messageContent)) - } - - if (timelineEvent.root.sendState == SendState.SENT) { - // TODO Can be redacted - - // TODO sent by me or sufficient power level - } - } - - if (vectorPreferences.developerMode()) { - if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) { - val keysBackupService = session.cryptoService().keysBackupService() - if (keysBackupService.state == KeysBackupState.NotTrusted - || (keysBackupService.state == KeysBackupState.ReadyToBackUp - && keysBackupService.canRestoreKeys()) - ) { - add(EventSharedAction.UseKeyBackup) - } - if (session.cryptoService().getCryptoDeviceInfo(session.myUserId).size > 1 - || timelineEvent.senderInfo.userId != session.myUserId) { - add(EventSharedAction.ReRequestKey(timelineEvent.eventId)) - } - } - addViewSourceItems(timelineEvent) - } - add(EventSharedAction.CopyPermalink(eventId)) - if (session.myUserId != timelineEvent.root.senderId) { - // not sent by me - if (timelineEvent.root.getClearType() == EventType.MESSAGE) { - add(EventSharedAction.ReportContent(eventId, timelineEvent.root.senderId)) - } - - add(EventSharedAction.Separator) - add(EventSharedAction.IgnoreUser(timelineEvent.root.senderId)) + timelineEvent.root.sendState == SendState.SYNCED -> { + addActionsForSyncedState(timelineEvent, actionPermissions, messageContent, msgType) } } } @@ -336,6 +256,116 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted } } + private fun ArrayList.addActionsForFailedState(timelineEvent: TimelineEvent, + actionPermissions: ActionPermissions, + messageContent: MessageContent?, + msgType: String?) { + val eventId = timelineEvent.eventId + if (canRetry(timelineEvent, actionPermissions)) { + add(EventSharedAction.Resend(eventId)) + } + add(EventSharedAction.Remove(eventId)) + if (canEdit(timelineEvent, session.myUserId, actionPermissions)) { + add(EventSharedAction.Edit(eventId)) + } + if (canCopy(msgType)) { + // TODO copy images? html? see ClipBoard + add(EventSharedAction.Copy(messageContent!!.body)) + } + if (vectorPreferences.developerMode()) { + addViewSourceItems(timelineEvent) + } + } + + private fun ArrayList.addActionsForSendingState(timelineEvent: TimelineEvent) { + // TODO is uploading attachment? + if (canCancel(timelineEvent)) { + add(EventSharedAction.Cancel(timelineEvent.eventId)) + } + } + + private fun ArrayList.addActionsForSyncedState(timelineEvent: TimelineEvent, + actionPermissions: ActionPermissions, + messageContent: MessageContent?, + msgType: String?) { + val eventId = timelineEvent.eventId + if (!timelineEvent.root.isRedacted()) { + if (canReply(timelineEvent, messageContent, actionPermissions)) { + add(EventSharedAction.Reply(eventId)) + } + + if (canEdit(timelineEvent, session.myUserId, actionPermissions)) { + add(EventSharedAction.Edit(eventId)) + } + + if (canRedact(timelineEvent, actionPermissions)) { + add(EventSharedAction.Redact(eventId, askForReason = informationData.senderId != session.myUserId)) + } + + if (canCopy(msgType)) { + // TODO copy images? html? see ClipBoard + add(EventSharedAction.Copy(messageContent!!.body)) + } + + if (timelineEvent.canReact() && actionPermissions.canReact) { + add(EventSharedAction.AddReaction(eventId)) + } + + if (canQuote(timelineEvent, messageContent, actionPermissions)) { + add(EventSharedAction.Quote(eventId)) + } + + if (canViewReactions(timelineEvent)) { + add(EventSharedAction.ViewReactions(informationData)) + } + + if (timelineEvent.hasBeenEdited()) { + add(EventSharedAction.ViewEditHistory(informationData)) + } + + if (canShare(msgType)) { + add(EventSharedAction.Share(timelineEvent.eventId, messageContent!!)) + } + + if (canSave(msgType) && messageContent is MessageWithAttachmentContent) { + add(EventSharedAction.Save(timelineEvent.eventId, messageContent)) + } + + if (timelineEvent.root.sendState == SendState.SENT) { + // TODO Can be redacted + + // TODO sent by me or sufficient power level + } + } + + if (vectorPreferences.developerMode()) { + if (timelineEvent.isEncrypted() && timelineEvent.root.mCryptoError != null) { + val keysBackupService = session.cryptoService().keysBackupService() + if (keysBackupService.state == KeysBackupState.NotTrusted + || (keysBackupService.state == KeysBackupState.ReadyToBackUp + && keysBackupService.canRestoreKeys()) + ) { + add(EventSharedAction.UseKeyBackup) + } + if (session.cryptoService().getCryptoDeviceInfo(session.myUserId).size > 1 + || timelineEvent.senderInfo.userId != session.myUserId) { + add(EventSharedAction.ReRequestKey(timelineEvent.eventId)) + } + } + addViewSourceItems(timelineEvent) + } + add(EventSharedAction.CopyPermalink(eventId)) + if (session.myUserId != timelineEvent.root.senderId) { + // not sent by me + if (timelineEvent.root.getClearType() == EventType.MESSAGE) { + add(EventSharedAction.ReportContent(eventId, timelineEvent.root.senderId)) + } + + add(EventSharedAction.Separator) + add(EventSharedAction.IgnoreUser(timelineEvent.root.senderId)) + } + } + private fun canCancel(@Suppress("UNUSED_PARAMETER") event: TimelineEvent): Boolean { return true } diff --git a/vector/src/main/res/layout/item_bottom_sheet_message_status.xml b/vector/src/main/res/layout/item_bottom_sheet_message_status.xml index 3d50cce72a..fcb373fa0d 100644 --- a/vector/src/main/res/layout/item_bottom_sheet_message_status.xml +++ b/vector/src/main/res/layout/item_bottom_sheet_message_status.xml @@ -5,7 +5,7 @@ android:id="@+id/messageStatusInfo" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="64dp" + android:layout_marginStart="16dp" android:layout_marginEnd="16dp" android:layout_marginBottom="4dp"> diff --git a/vector/src/main/res/layout/item_timeline_event_base.xml b/vector/src/main/res/layout/item_timeline_event_base.xml index 422cd5fef2..ce3460a21c 100644 --- a/vector/src/main/res/layout/item_timeline_event_base.xml +++ b/vector/src/main/res/layout/item_timeline_event_base.xml @@ -136,8 +136,8 @@ 196dp 44dp 72dp + 16dp 40dp 60dp