From 4f92db76511a0b63d2555bc85d7abc8a9c141aa7 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 9 Oct 2020 14:45:36 +0300 Subject: [PATCH 1/4] Make long topic expandable. --- .../app/core/epoxy/ExpandableTextItem.kt | 86 +++++++++++++++++++ .../roomprofile/RoomProfileController.kt | 15 ++++ .../roomprofile/RoomProfileFragment.kt | 2 - .../src/main/res/drawable/ic_expand_less.xml | 9 ++ .../src/main/res/drawable/ic_expand_more.xml | 9 ++ .../res/layout/item_expandable_textview.xml | 33 +++++++ .../layout/view_stub_room_profile_header.xml | 18 ---- vector/src/main/res/values/strings.xml | 1 + 8 files changed, 153 insertions(+), 20 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt create mode 100644 vector/src/main/res/drawable/ic_expand_less.xml create mode 100644 vector/src/main/res/drawable/ic_expand_more.xml create mode 100644 vector/src/main/res/layout/item_expandable_textview.xml diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt new file mode 100644 index 0000000000..b55861571b --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2020 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.epoxy + +import android.animation.ObjectAnimator +import android.widget.ImageView +import android.widget.TextView +import androidx.core.view.doOnPreDraw +import androidx.core.view.isVisible +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.extensions.copyOnLongClick + +@EpoxyModelClass(layout = R.layout.item_expandable_textview) +abstract class ExpandableTextItem : VectorEpoxyModel() { + + @EpoxyAttribute + lateinit var content: String + + @EpoxyAttribute + var maxLines: Int = 3 + + private var isExpanded = false + private var expandedLines = 0 + + override fun bind(holder: Holder) { + super.bind(holder) + holder.content.text = content + holder.content.copyOnLongClick() + + holder.content.doOnPreDraw { + if (holder.content.lineCount > maxLines) { + expandedLines = holder.content.lineCount + holder.content.maxLines = maxLines + + holder.view.setOnClickListener { + if (isExpanded) { + collapse(holder) + } else { + expand(holder) + } + } + } else { + holder.arrow.isVisible = false + } + } + } + + private fun expand(holder: Holder) { + ObjectAnimator.ofInt(holder.content, "maxLines", expandedLines) + .apply { duration = 500 } + .also { it.start() } + + holder.arrow.setImageResource(R.drawable.ic_expand_less) + isExpanded = true + } + + private fun collapse(holder: Holder) { + ObjectAnimator.ofInt(holder.content, "maxLines", maxLines) + .apply { duration = 500 } + .also { it.start() } + + holder.arrow.setImageResource(R.drawable.ic_expand_more) + isExpanded = false + } + + class Holder : VectorEpoxyHolder() { + val content by bind(R.id.expandableContent) + val arrow by bind(R.id.expandableArrow) + } +} diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 160ebd56be..ad774fbeef 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -19,6 +19,7 @@ package im.vector.app.features.roomprofile import com.airbnb.epoxy.TypedEpoxyController import im.vector.app.R +import im.vector.app.core.epoxy.expandableTextItem import im.vector.app.core.epoxy.profiles.buildProfileAction import im.vector.app.core.epoxy.profiles.buildProfileSection import im.vector.app.core.resources.ColorProvider @@ -57,6 +58,20 @@ class RoomProfileController @Inject constructor( return } val roomSummary = data.roomSummary() ?: return + + // Topic + roomSummary + .topic + .takeIf { it.isNotBlank() } + ?.let { + buildProfileSection(stringProvider.getString(R.string.room_profile_section_topic)) + expandableTextItem { + id("topic") + content(roomSummary.topic) + maxLines(2) + } + } + // Security buildProfileSection(stringProvider.getString(R.string.room_profile_section_security)) val learnMoreSubtitle = if (roomSummary.isEncrypted) { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 399c1ecf32..c2f25c08d3 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -129,7 +129,6 @@ class RoomProfileFragment @Inject constructor( private fun setupLongClicks() { roomProfileNameView.copyOnLongClick() roomProfileAliasView.copyOnLongClick() - roomProfileTopicView.copyOnLongClick() } override fun onOptionsItemSelected(item: MenuItem): Boolean { @@ -187,7 +186,6 @@ class RoomProfileFragment @Inject constructor( roomProfileNameView.text = it.displayName matrixProfileToolbarTitleView.text = it.displayName roomProfileAliasView.setTextOrHide(it.canonicalAlias) - roomProfileTopicView.setTextOrHide(it.topic) val matrixItem = it.toMatrixItem() avatarRenderer.render(matrixItem, roomProfileAvatarView) avatarRenderer.render(matrixItem, matrixProfileToolbarAvatarImageView) diff --git a/vector/src/main/res/drawable/ic_expand_less.xml b/vector/src/main/res/drawable/ic_expand_less.xml new file mode 100644 index 0000000000..92bc86da08 --- /dev/null +++ b/vector/src/main/res/drawable/ic_expand_less.xml @@ -0,0 +1,9 @@ + + + diff --git a/vector/src/main/res/drawable/ic_expand_more.xml b/vector/src/main/res/drawable/ic_expand_more.xml new file mode 100644 index 0000000000..22c401f0c3 --- /dev/null +++ b/vector/src/main/res/drawable/ic_expand_more.xml @@ -0,0 +1,9 @@ + + + diff --git a/vector/src/main/res/layout/item_expandable_textview.xml b/vector/src/main/res/layout/item_expandable_textview.xml new file mode 100644 index 0000000000..34fbaf7ec0 --- /dev/null +++ b/vector/src/main/res/layout/item_expandable_textview.xml @@ -0,0 +1,33 @@ + + + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/view_stub_room_profile_header.xml b/vector/src/main/res/layout/view_stub_room_profile_header.xml index f7ae1c77a5..ecb7174f0e 100644 --- a/vector/src/main/res/layout/view_stub_room_profile_header.xml +++ b/vector/src/main/res/layout/view_stub_room_profile_header.xml @@ -54,27 +54,9 @@ android:textAppearance="@style/Vector.Toolbar.Title" android:textSize="14sp" android:textStyle="bold" - app:layout_constraintBottom_toTopOf="@+id/roomProfileTopicView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/roomProfileNameView" tools:text="@sample/matrix.json/data/roomAlias" /> - - diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index d48162de29..709bf4f4a1 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2124,6 +2124,7 @@ Messages here are not end-to-end encrypted. Messages in this room are end-to-end encrypted.\n\nYour messages are secured with locks and only you and the recipient have the unique keys to unlock them. Messages here are end-to-end encrypted.\n\nYour messages are secured with locks and only you and the recipient have the unique keys to unlock them. + Topic Security Learn more More From c3a423fdbe1c5e388174d76ee19be60559760972 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 9 Oct 2020 14:53:02 +0300 Subject: [PATCH 2/4] Changelog added. --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index ec853d96ef..0762a207ce 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -20,6 +20,7 @@ Bugfix 🐛: - Improve support for image/audio/video/file selection with intent changes (#1376) - Fix Splash layout on small screens - Simplifies draft management and should fix bunch of draft issues (#952, #683) + - Very long topic cannot be fully visible (#1957) Translations 🗣: - From beeb84043620fb39a876f582e44cca2996395884 Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Fri, 9 Oct 2020 15:06:54 +0300 Subject: [PATCH 3/4] Do not ellipsize content while expanding. --- .../java/im/vector/app/core/epoxy/ExpandableTextItem.kt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt index b55861571b..7e1114660f 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt @@ -17,6 +17,7 @@ package im.vector.app.core.epoxy import android.animation.ObjectAnimator +import android.text.TextUtils import android.widget.ImageView import android.widget.TextView import androidx.core.view.doOnPreDraw @@ -63,19 +64,21 @@ abstract class ExpandableTextItem : VectorEpoxyModel( private fun expand(holder: Holder) { ObjectAnimator.ofInt(holder.content, "maxLines", expandedLines) - .apply { duration = 500 } + .apply { duration = 200 } .also { it.start() } + holder.content.ellipsize = null holder.arrow.setImageResource(R.drawable.ic_expand_less) isExpanded = true } private fun collapse(holder: Holder) { ObjectAnimator.ofInt(holder.content, "maxLines", maxLines) - .apply { duration = 500 } + .apply { duration = 200 } .also { it.start() } - holder.arrow.setImageResource(R.drawable.ic_expand_more) + holder.content.ellipsize = TextUtils.TruncateAt.END + holder.arrow.setImageResource(R.drawable.ic_expand_more) isExpanded = false } From f8f091fa280926b394e34089d1f5117f741bef8c Mon Sep 17 00:00:00 2001 From: Onuray Sahin Date: Mon, 12 Oct 2020 14:26:06 +0300 Subject: [PATCH 4/4] Benoit code review fixes. --- .../app/core/epoxy/ExpandableTextItem.kt | 19 ++++++++++++------- .../roomprofile/RoomProfileController.kt | 6 +++--- .../res/layout/item_expandable_textview.xml | 5 +++++ vector/src/main/res/values/strings.xml | 1 - 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt index 7e1114660f..3dceec48ef 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/ExpandableTextItem.kt @@ -56,6 +56,7 @@ abstract class ExpandableTextItem : VectorEpoxyModel( expand(holder) } } + holder.arrow.isVisible = true } else { holder.arrow.isVisible = false } @@ -63,22 +64,26 @@ abstract class ExpandableTextItem : VectorEpoxyModel( } private fun expand(holder: Holder) { - ObjectAnimator.ofInt(holder.content, "maxLines", expandedLines) - .apply { duration = 200 } - .also { it.start() } + ObjectAnimator + .ofInt(holder.content, "maxLines", expandedLines) + .setDuration(200) + .start() holder.content.ellipsize = null holder.arrow.setImageResource(R.drawable.ic_expand_less) + holder.arrow.contentDescription = holder.view.context.getString(R.string.merged_events_collapse) isExpanded = true } private fun collapse(holder: Holder) { - ObjectAnimator.ofInt(holder.content, "maxLines", maxLines) - .apply { duration = 200 } - .also { it.start() } + ObjectAnimator + .ofInt(holder.content, "maxLines", maxLines) + .setDuration(200) + .start() holder.content.ellipsize = TextUtils.TruncateAt.END - holder.arrow.setImageResource(R.drawable.ic_expand_more) + holder.arrow.setImageResource(R.drawable.ic_expand_more) + holder.arrow.contentDescription = holder.view.context.getString(R.string.merged_events_expand) isExpanded = false } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index ad774fbeef..7dc744da31 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -62,12 +62,12 @@ class RoomProfileController @Inject constructor( // Topic roomSummary .topic - .takeIf { it.isNotBlank() } + .takeIf { it.isNotEmpty() } ?.let { - buildProfileSection(stringProvider.getString(R.string.room_profile_section_topic)) + buildProfileSection(stringProvider.getString(R.string.room_settings_topic)) expandableTextItem { id("topic") - content(roomSummary.topic) + content(it) maxLines(2) } } diff --git a/vector/src/main/res/layout/item_expandable_textview.xml b/vector/src/main/res/layout/item_expandable_textview.xml index 34fbaf7ec0..b0c232d77e 100644 --- a/vector/src/main/res/layout/item_expandable_textview.xml +++ b/vector/src/main/res/layout/item_expandable_textview.xml @@ -23,7 +23,12 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" + android:autoLink="web" + android:fontFamily="sans-serif" + android:gravity="center" android:src="@drawable/ic_expand_more" + android:textSize="14sp" + android:textStyle="normal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/expandableContent" diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 709bf4f4a1..d48162de29 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -2124,7 +2124,6 @@ Messages here are not end-to-end encrypted. Messages in this room are end-to-end encrypted.\n\nYour messages are secured with locks and only you and the recipient have the unique keys to unlock them. Messages here are end-to-end encrypted.\n\nYour messages are secured with locks and only you and the recipient have the unique keys to unlock them. - Topic Security Learn more More