Message state: adjust some ui

This commit is contained in:
ganfra 2021-03-10 17:57:15 +01:00
parent fad4140924
commit bbb5dd06a2
7 changed files with 148 additions and 125 deletions

View file

@ -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)
}
}
}

View file

@ -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)

View file

@ -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<EventSharedAction> {
val eventId = timelineEvent.eventId
val messageContent = timelineEvent.getLastMessageContent()
val msgType = messageContent?.msgType
return arrayListOf<EventSharedAction>().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<EventSharedAction>.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<EventSharedAction>.addActionsForSendingState(timelineEvent: TimelineEvent) {
// TODO is uploading attachment?
if (canCancel(timelineEvent)) {
add(EventSharedAction.Cancel(timelineEvent.eventId))
}
}
private fun ArrayList<EventSharedAction>.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
}

View file

@ -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">

View file

@ -136,8 +136,8 @@
<im.vector.app.core.ui.views.SendStateImageView
android:id="@+id/messageSendStateImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_alignBottom="@+id/viewStubContainer"
android:layout_alignParentEnd="true"
android:layout_marginStart="8dp"
@ -150,8 +150,8 @@
<ProgressBar
android:id="@+id/eventSendingIndicator"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_alignBottom="@+id/viewStubContainer"
android:indeterminateTint="?riotx_text_secondary"
android:layout_alignParentEnd="true"

View file

@ -9,7 +9,7 @@
<TextView
android:id="@+id/receiptMore"
android:layout_width="wrap_content"
android:layout_height="18dp"
android:layout_height="@dimen/item_event_message_state_size"
android:background="@drawable/pill_receipt"
android:gravity="center"
android:importantForAccessibility="no"
@ -20,8 +20,8 @@
<ImageView
android:id="@+id/receiptAvatar5"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
@ -30,8 +30,8 @@
<ImageView
android:id="@+id/receiptAvatar4"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
@ -40,8 +40,8 @@
<ImageView
android:id="@+id/receiptAvatar3"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
@ -50,8 +50,8 @@
<ImageView
android:id="@+id/receiptAvatar2"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
@ -60,8 +60,8 @@
<ImageView
android:id="@+id/receiptAvatar1"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_width="@dimen/item_event_message_state_size"
android:layout_height="@dimen/item_event_message_state_size"
android:layout_marginStart="2dp"
android:adjustViewBounds="true"
android:importantForAccessibility="no"

View file

@ -13,6 +13,7 @@
<dimen name="navigation_view_height">196dp</dimen>
<dimen name="navigation_avatar_top_margin">44dp</dimen>
<dimen name="item_decoration_left_margin">72dp</dimen>
<dimen name="item_event_message_state_size">16dp</dimen>
<dimen name="chat_avatar_size">40dp</dimen>
<dimen name="member_list_avatar_size">60dp</dimen>