diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt index 50b3dca2d1..8c985d45d9 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesPresenter.kt @@ -209,7 +209,8 @@ class MessagesPresenter @AssistedInject constructor( TimelineItemAction.Copy -> handleCopyContents(targetEvent) TimelineItemAction.Redact -> handleActionRedact(targetEvent) TimelineItemAction.Edit -> handleActionEdit(targetEvent, composerState) - TimelineItemAction.Reply -> handleActionReply(targetEvent, composerState) + TimelineItemAction.Reply, + TimelineItemAction.ReplyInThread -> handleActionReply(targetEvent, composerState) TimelineItemAction.Developer -> handleShowDebugInfoAction(targetEvent) TimelineItemAction.Forward -> handleForwardAction(targetEvent) TimelineItemAction.ReportContent -> handleReportAction(targetEvent) @@ -312,6 +313,7 @@ class MessagesPresenter @AssistedInject constructor( is TimelineItemUnknownContent -> null } val composerMode = MessageComposerMode.Reply( + isThreaded = targetEvent.isThreaded, senderName = targetEvent.safeSenderName, eventId = targetEvent.eventId, attachmentThumbnailInfo = attachmentThumbnailInfo, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt index b179261c72..e87523d702 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/ActionListPresenter.kt @@ -130,7 +130,11 @@ class ActionListPresenter @Inject constructor( if (timelineItem.isRemote) { // Can only reply or forward messages already uploaded to the server if (userCanSendMessage) { - add(TimelineItemAction.Reply) + if (timelineItem.isThreaded) { + add(TimelineItemAction.ReplyInThread) + } else { + add(TimelineItemAction.Reply) + } } add(TimelineItemAction.Forward) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt index 7a8a1fa1db..331edfa1a5 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/actionlist/model/TimelineItemAction.kt @@ -32,6 +32,7 @@ sealed class TimelineItemAction( data object Copy : TimelineItemAction(CommonStrings.action_copy, VectorIcons.Copy) data object Redact : TimelineItemAction(CommonStrings.action_remove, VectorIcons.Delete, destructive = true) data object Reply : TimelineItemAction(CommonStrings.action_reply, VectorIcons.Reply) + data object ReplyInThread : TimelineItemAction(CommonStrings.action_reply_in_thread, VectorIcons.Reply) data object Edit : TimelineItemAction(CommonStrings.action_edit, VectorIcons.Edit) data object Developer : TimelineItemAction(CommonStrings.action_view_source, VectorIcons.DeveloperMode) data object ReportContent : TimelineItemAction(CommonStrings.action_report_content, VectorIcons.ReportContent, destructive = true) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index befb576696..0158372c79 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -400,7 +400,7 @@ private fun MessageEventBubbleContent( Icon(resourceId = R.drawable.ic_thread_decoration, contentDescription = null, tint = ElementTheme.colors.iconSecondary) Spacer(modifier = Modifier.width(4.dp)) Text( - text = "Thread", + text = stringResource(CommonStrings.common_thread), style = ElementTheme.typography.fontBodyXsRegular, color = ElementTheme.colors.textPrimary, ) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt index d1d4a54073..07a4800ffb 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/textcomposer/MessageComposerPresenterTest.kt @@ -598,7 +598,7 @@ fun anEditMode( transactionId: TransactionId? = null, ) = MessageComposerMode.Edit(eventId, message, transactionId) -fun aReplyMode() = MessageComposerMode.Reply(A_USER_NAME, null, AN_EVENT_ID, A_MESSAGE) +fun aReplyMode() = MessageComposerMode.Reply(A_USER_NAME, null, false, AN_EVENT_ID, A_MESSAGE) fun aQuoteMode() = MessageComposerMode.Quote(AN_EVENT_ID, A_MESSAGE) private fun String.toMessage() = Message( diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 717f503e22..7f0f4ddc30 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -30,11 +30,13 @@ "You can change it in your %1$s." "global settings" "Default setting" + "Remove custom setting" "An error occurred while loading notification settings." "Failed restoring the default mode, please try again." "Failed setting the mode, please try again." "All messages" "Mentions and Keywords only" + "In this room, notify me for" "Block" "Blocked users won\'t be able to send you messages and all their messages will be hidden. You can unblock them anytime." "Block user" diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt index aa3e745ea2..3dbc652aaf 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/MessageComposerMode.kt @@ -41,6 +41,7 @@ sealed interface MessageComposerMode : Parcelable { class Reply( val senderName: String, val attachmentThumbnailInfo: AttachmentThumbnailInfo?, + val isThreaded: Boolean, override val eventId: EventId, override val defaultContent: String ) : Special(eventId, defaultContent) @@ -60,5 +61,5 @@ sealed interface MessageComposerMode : Parcelable { get() = this is Reply val inThread: Boolean - get() = false // TODO + get() = this is Reply && isThreaded } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 3cc09ce09f..c407e678dd 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -183,9 +183,13 @@ fun TextComposer( if (composerMode is MessageComposerMode.Special) { ComposerModeView(composerMode = composerMode, onResetComposerMode = onResetComposerMode) } - TextInput( state = state, + placeholder = if (composerMode.inThread) { + stringResource(id = CommonStrings.action_reply_in_thread) + } else { + stringResource(id = CommonStrings.rich_text_editor_composer_placeholder) + }, roundedCorners = roundedCorners, bgColor = bgColor, onError = onError, @@ -237,6 +241,7 @@ fun TextComposer( @Composable private fun TextInput( state: RichTextEditorState, + placeholder: String, roundedCorners: RoundedCornerShape, bgColor: Color, modifier: Modifier = Modifier, @@ -262,7 +267,7 @@ private fun TextInput( // Placeholder if (state.messageHtml.isEmpty()) { Text( - stringResource(CommonStrings.common_message), + placeholder, style = defaultTypography.copy( color = ElementTheme.colors.textDisabled, ), @@ -686,6 +691,7 @@ internal fun TextComposerReplyPreview() = ElementPreview { canSendMessage = false, onSendMessage = {}, composerMode = MessageComposerMode.Reply( + isThreaded = false, senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = null, @@ -701,6 +707,7 @@ internal fun TextComposerReplyPreview() = ElementPreview { canSendMessage = true, onSendMessage = {}, composerMode = MessageComposerMode.Reply( + isThreaded = true, senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( @@ -719,6 +726,7 @@ internal fun TextComposerReplyPreview() = ElementPreview { canSendMessage = true, onSendMessage = {}, composerMode = MessageComposerMode.Reply( + isThreaded = false, senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( @@ -737,6 +745,7 @@ internal fun TextComposerReplyPreview() = ElementPreview { canSendMessage = true, onSendMessage = {}, composerMode = MessageComposerMode.Reply( + isThreaded = false, senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( @@ -755,6 +764,7 @@ internal fun TextComposerReplyPreview() = ElementPreview { canSendMessage = true, onSendMessage = {}, composerMode = MessageComposerMode.Reply( + isThreaded = false, senderName = "Alice", eventId = EventId("$1234"), attachmentThumbnailInfo = AttachmentThumbnailInfo( diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index d6f9f2cbaf..3098b9b5b3 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -1,6 +1,5 @@ - "Use an identity server to invite by email. ""Use the default (%(defaultIdentityServerName)s)"" or manage in ""Settings""." "Hide password" "Mentions only" "Muted" @@ -37,6 +36,8 @@ "Learn more" "Leave" "Leave room" + "Manage account" + "Manage devices" "Next" "No" "Not now" @@ -47,6 +48,7 @@ "React" "Remove" "Reply" + "Reply in thread" "Report bug" "Report Content" "Retry" @@ -65,8 +67,12 @@ "Take photo" "View Source" "Yes" + "Ongoing call" + "Tap to return to the call" + "☎️ Call in progress" "About" "Acceptable use policy" + "Advanced settings" "Analytics" "Audio" "Bubbles" @@ -85,6 +91,7 @@ "Forward message" "GIF" "Image" + "In reply to %1$s" "This Matrix ID can\'t be found, so the invite might not be received." "Leaving room" "Link copied to clipboard" @@ -99,15 +106,16 @@ "Password" "People" "Permalink" - "Final votes: %1$s" "Total votes: %1$s" "Results will show after the poll has ended" "Privacy policy" + "Reaction" "Reactions" "Refreshing…" "Replying to %1$s" "Report a bug" "Report submitted" + "Rich text editor" "Room name" "e.g. your project name" "Search for someone" @@ -126,6 +134,7 @@ "Syncing" "Text" "Third-party notices" + "Thread" "Topic" "What is this room about?" "Unable to decrypt" @@ -162,10 +171,6 @@ "Are you sure that you want to leave this room? This room is not public and you won\'t be able to rejoin without an invite." "Are you sure that you want to leave the room?" "%1$s Android" - - "%(count)s room" - "%(count)s rooms" - "%1$d member" "%1$d members"