Merge pull request #5614 from vector-im/feature/aris/threads_ui_enhancements

Feature/aris/threads UI enhancements
This commit is contained in:
Benoit Marty 2022-04-05 17:21:53 +02:00 committed by GitHub
commit ca418afcbb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 69 additions and 52 deletions

View File

@ -40,6 +40,7 @@
<dimen name="menu_item_icon_size">24dp</dimen> <dimen name="menu_item_icon_size">24dp</dimen>
<dimen name="menu_item_size">48dp</dimen> <dimen name="menu_item_size">48dp</dimen>
<dimen name="menu_item_ripple_size">48dp</dimen> <dimen name="menu_item_ripple_size">48dp</dimen>
<dimen name="menu_item_width_small">38dp</dimen>
<!-- Composer --> <!-- Composer -->
<dimen name="composer_min_height">56dp</dimen> <dimen name="composer_min_height">56dp</dimen>

View File

@ -40,6 +40,7 @@ import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.view.menu.MenuBuilder
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.DrawableCompat import androidx.core.graphics.drawable.DrawableCompat
import androidx.core.net.toUri import androidx.core.net.toUri
@ -998,7 +999,11 @@ class TimelineFragment @Inject constructor(
} }
} }
@SuppressLint("RestrictedApi")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
if (isThreadTimeLine()) {
if (menu is MenuBuilder) menu.setOptionalIconsVisible(true)
}
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
// We use a custom layout for this menu item, so we need to set a ClickListener // We use a custom layout for this menu item, so we need to set a ClickListener
menu.findItem(R.id.open_matrix_apps)?.let { menuItem -> menu.findItem(R.id.open_matrix_apps)?.let { menuItem ->
@ -1474,6 +1479,10 @@ class TimelineFragment @Inject constructor(
views.composerLayout.views.composerEmojiButton.isVisible = vectorPreferences.showEmojiKeyboard() views.composerLayout.views.composerEmojiButton.isVisible = vectorPreferences.showEmojiKeyboard()
if (isThreadTimeLine() && timelineArgs.threadTimelineArgs?.startsThread == true) {
// Show keyboard when the user started a thread
views.composerLayout.views.composerEditText.showKeyboard(andRequestFocus = true)
}
views.composerLayout.callback = object : MessageComposerView.Callback { views.composerLayout.callback = object : MessageComposerView.Callback {
override fun onAddAttachment() { override fun onAddAttachment() {
if (!::attachmentTypeSelector.isInitialized) { if (!::attachmentTypeSelector.isInitialized) {

View File

@ -710,8 +710,10 @@ class TimelineViewModel @AssistedInject constructor(
if (initialState.isThreadTimeline()) { if (initialState.isThreadTimeline()) {
when (itemId) { when (itemId) {
R.id.menu_thread_timeline_more -> true R.id.menu_thread_timeline_view_in_room,
else -> false R.id.menu_thread_timeline_copy_link,
R.id.menu_thread_timeline_share -> true
else -> false
} }
} else { } else {
when (itemId) { when (itemId) {

View File

@ -33,6 +33,7 @@ import im.vector.app.core.extensions.setLeftDrawable
import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.DimensionConverter
import im.vector.app.features.displayname.getBestName import im.vector.app.features.displayname.getBestName
import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.session.threads.ThreadNotificationState import org.matrix.android.sdk.api.session.threads.ThreadNotificationState
import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MatrixItem
@ -60,9 +61,11 @@ abstract class ThreadListItem : VectorEpoxyModel<ThreadListItem.Holder>() {
holder.dateTextView.text = date holder.dateTextView.text = date
if (rootMessageDeleted) { if (rootMessageDeleted) {
holder.rootMessageTextView.text = holder.view.context.getString(R.string.event_redacted) holder.rootMessageTextView.text = holder.view.context.getString(R.string.event_redacted)
holder.rootMessageTextView.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_secondary))
holder.rootMessageTextView.setLeftDrawable(R.drawable.ic_trash_16, R.attr.vctr_content_tertiary) holder.rootMessageTextView.setLeftDrawable(R.drawable.ic_trash_16, R.attr.vctr_content_tertiary)
holder.rootMessageTextView.compoundDrawablePadding = DimensionConverter(holder.view.context.resources).dpToPx(10) holder.rootMessageTextView.compoundDrawablePadding = DimensionConverter(holder.view.context.resources).dpToPx(10)
} else { } else {
holder.rootMessageTextView.setTextColor(ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_primary))
holder.rootMessageTextView.text = rootMessage holder.rootMessageTextView.text = rootMessage
holder.rootMessageTextView.clearDrawables() holder.rootMessageTextView.clearDrawables()
} }

View File

@ -61,11 +61,11 @@ class ThreadListBottomSheet : VectorBaseBottomSheetDialogFragment<BottomSheetThr
val radioOnDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.ic_radio_on) val radioOnDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.ic_radio_on)
if (state.shouldFilterThreads) { if (state.shouldFilterThreads) {
setRightIconDrawableAllThreads(radioOffDrawable, R.attr.vctr_content_primary) setRightIconDrawableAllThreads(radioOffDrawable, R.attr.vctr_content_secondary)
setRightIconDrawableMyThreads(radioOnDrawable, R.attr.colorPrimary) setRightIconDrawableMyThreads(radioOnDrawable, R.attr.colorPrimary)
} else { } else {
setRightIconDrawableAllThreads(radioOnDrawable, R.attr.colorPrimary) setRightIconDrawableAllThreads(radioOnDrawable, R.attr.colorPrimary)
setRightIconDrawableMyThreads(radioOffDrawable, R.attr.vctr_content_primary) setRightIconDrawableMyThreads(radioOffDrawable, R.attr.vctr_content_secondary)
} }
} }

View File

@ -18,6 +18,7 @@ package im.vector.app.features.home.room.threads.list.views
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@ -76,6 +77,15 @@ class ThreadListFragment @Inject constructor(
} }
} }
override fun onPrepareOptionsMenu(menu: Menu) {
withState(threadListViewModel) { state ->
when (threadListViewModel.canHomeserverUseThreading()) {
true -> menu.findItem(R.id.menu_thread_list_filter).isVisible = !state.threadSummaryList.invoke().isNullOrEmpty()
false -> menu.findItem(R.id.menu_thread_list_filter).isVisible = !state.rootThreadEventList.invoke().isNullOrEmpty()
}
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
initToolbar() initToolbar()
@ -102,6 +112,7 @@ class ThreadListFragment @Inject constructor(
} }
override fun invalidate() = withState(threadListViewModel) { state -> override fun invalidate() = withState(threadListViewModel) { state ->
invalidateOptionsMenu()
renderEmptyStateIfNeeded(state) renderEmptyStateIfNeeded(state)
threadListController.update(state) threadListController.update(state)
renderLoaderIfNeeded(state) renderLoaderIfNeeded(state)

View File

@ -5,7 +5,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?colorSurface" android:background="?colorSurface"
android:orientation="vertical" android:orientation="vertical"
android:padding="8dp"> android:padding="16dp">
<TextView <TextView
android:id="@+id/threadListModalTitle" android:id="@+id/threadListModalTitle"
@ -23,7 +23,7 @@
android:id="@+id/threadListModalAllThreads" android:id="@+id/threadListModalAllThreads"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="12dp"
app:actionDescription="@string/thread_list_modal_all_threads_subtitle" app:actionDescription="@string/thread_list_modal_all_threads_subtitle"
app:actionTitle="@string/thread_list_modal_all_threads_title" app:actionTitle="@string/thread_list_modal_all_threads_title"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
@ -35,7 +35,7 @@
android:id="@+id/threadListModalMyThreads" android:id="@+id/threadListModalMyThreads"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="24dp" android:layout_marginTop="4dp"
app:actionDescription="@string/thread_list_modal_my_threads_subtitle" app:actionDescription="@string/thread_list_modal_my_threads_subtitle"
app:actionTitle="@string/thread_list_modal_my_threads_title" app:actionTitle="@string/thread_list_modal_my_threads_title"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@ -73,8 +73,8 @@
style="@style/Widget.Vector.TextView.Body" style="@style/Widget.Vector.TextView.Body"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="3dp" android:layout_marginTop="2dp"
android:layout_marginEnd="25dp" android:layout_marginEnd="28dp"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
android:textColor="?vctr_content_primary" android:textColor="?vctr_content_primary"
@ -87,12 +87,12 @@
android:id="@+id/threadSummaryConstraintLayout" android:id="@+id/threadSummaryConstraintLayout"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="25dp" android:layout_marginEnd="28dp"
android:contentDescription="@string/room_threads_filter" android:contentDescription="@string/room_threads_filter"
android:maxWidth="496dp" android:maxWidth="496dp"
android:minWidth="144dp" android:minWidth="144dp"
android:paddingTop="10dp" android:paddingTop="8dp"
android:paddingBottom="12dp" android:paddingBottom="8dp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/threadSummaryTitleTextView" app:layout_constraintStart_toStartOf="@id/threadSummaryTitleTextView"
app:layout_constraintTop_toBottomOf="@id/threadSummaryRootMessageTextView" app:layout_constraintTop_toBottomOf="@id/threadSummaryRootMessageTextView"

View File

@ -34,11 +34,11 @@
android:layout_marginStart="8dp" android:layout_marginStart="8dp"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_marginEnd="4dp" android:layout_marginEnd="4dp"
android:textAlignment="viewStart"
android:layout_toStartOf="@id/messageTimeView" android:layout_toStartOf="@id/messageTimeView"
android:layout_toEndOf="@id/messageStartGuideline" android:layout_toEndOf="@id/messageStartGuideline"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAlignment="viewStart"
android:textColor="?vctr_content_primary" android:textColor="?vctr_content_primary"
android:textStyle="bold" android:textStyle="bold"
tools:text="@sample/users.json/data/displayName" /> tools:text="@sample/users.json/data/displayName" />
@ -152,16 +152,18 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/informationBottom" android:layout_below="@id/informationBottom"
android:layout_marginEnd="32dp" android:layout_marginEnd="48dp"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:paddingStart="13dp" android:layout_marginTop="4dp"
android:paddingEnd="13dp" android:layout_marginStart="8dp"
android:layout_toEndOf="@id/messageStartGuideline" android:layout_toEndOf="@id/messageStartGuideline"
android:background="@drawable/rounded_rect_shape_8" android:background="@drawable/rounded_rect_shape_8"
android:contentDescription="@string/room_threads_filter" android:contentDescription="@string/room_threads_filter"
android:maxWidth="496dp" android:maxWidth="496dp"
android:minWidth="144dp" android:minWidth="144dp"
android:paddingStart="12dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingEnd="12dp"
android:paddingBottom="8dp" android:paddingBottom="8dp"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">

View File

@ -26,8 +26,8 @@
<ImageView <ImageView
android:id="@+id/roomToolbarThreadImageView" android:id="@+id/roomToolbarThreadImageView"
android:layout_width="20dp" android:layout_width="16dp"
android:layout_height="20dp" android:layout_height="16dp"
android:importantForAccessibility="no" android:importantForAccessibility="no"
android:src="@drawable/ic_presence_offline" android:src="@drawable/ic_presence_offline"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View File

@ -2,7 +2,7 @@
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/menu_item_size" android:layout_width="@dimen/menu_item_width_small"
android:layout_height="@dimen/menu_item_size"> android:layout_height="@dimen/menu_item_size">
<FrameLayout <FrameLayout

View File

@ -6,8 +6,8 @@
<ImageView <ImageView
android:id="@+id/messageThreadSummaryImageView" android:id="@+id/messageThreadSummaryImageView"
android:layout_width="16dp" android:layout_width="18dp"
android:layout_height="16dp" android:layout_height="18dp"
android:layout_marginTop="2dp" android:layout_marginTop="2dp"
android:contentDescription="@string/room_threads_filter" android:contentDescription="@string/room_threads_filter"
android:src="@drawable/ic_thread_summary" android:src="@drawable/ic_thread_summary"

View File

@ -41,12 +41,13 @@
android:id="@+id/menu_timeline_thread_list" android:id="@+id/menu_timeline_thread_list"
android:title="@string/action_view_threads" android:title="@string/action_view_threads"
android:visible="false" android:visible="false"
app:iconTint="?colorPrimary"
app:actionLayout="@layout/view_thread_notification_badge" app:actionLayout="@layout/view_thread_notification_badge"
app:showAsAction="ifRoom" app:iconTint="?colorPrimary"
app:showAsAction="always"
tools:visible="true" /> tools:visible="true" />
<item android:id="@+id/join_conference" <item
android:id="@+id/join_conference"
android:title="@string/action_join" android:title="@string/action_join"
app:actionLayout="@layout/layout_join_conference_action" app:actionLayout="@layout/layout_join_conference_action"
app:showAsAction="always" /> app:showAsAction="always" />
@ -66,35 +67,23 @@
tools:visible="true" /> tools:visible="true" />
<item <item
android:id="@+id/menu_thread_timeline_more" android:id="@+id/menu_thread_timeline_view_in_room"
android:icon="@drawable/ic_more_vertical" android:icon="@drawable/ic_thread_view_in_room_menu_item"
android:title="@string/action_thread_view_in_room" android:title="@string/action_thread_view_in_room"
app:iconTint="?vctr_content_secondary" app:iconTint="?vctr_content_secondary"
app:showAsAction="always"> app:showAsAction="withText" />
<menu>
<item
android:id="@+id/menu_thread_timeline_view_in_room"
android:icon="@drawable/ic_thread_view_in_room_menu_item"
android:title="@string/action_thread_view_in_room"
app:iconTint="?vctr_content_secondary"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_thread_timeline_copy_link"
android:icon="@drawable/ic_thread_link_menu_item"
android:title="@string/action_thread_copy_link_to_thread"
app:iconTint="?vctr_content_secondary"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_thread_timeline_share"
android:icon="@drawable/ic_thread_share_menu_item"
android:title="@string/action_share"
app:iconTint="?vctr_content_secondary"
app:showAsAction="ifRoom" />
</menu>
</item>
<item
android:id="@+id/menu_thread_timeline_copy_link"
android:icon="@drawable/ic_thread_link_menu_item"
android:title="@string/action_thread_copy_link_to_thread"
app:iconTint="?vctr_content_secondary"
app:showAsAction="withText" />
<item
android:id="@+id/menu_thread_timeline_share"
android:icon="@drawable/ic_thread_share_menu_item"
android:title="@string/action_share"
app:iconTint="?vctr_content_secondary"
app:showAsAction="withText" />
</menu> </menu>

View File

@ -1550,7 +1550,7 @@
<string name="edit">Edit</string> <string name="edit">Edit</string>
<string name="reply">Reply</string> <string name="reply">Reply</string>
<string name="reply_in_thread">Reply In Thread</string> <string name="reply_in_thread">Reply in thread</string>
<string name="view_in_room">View In Room</string> <string name="view_in_room">View In Room</string>
<string name="global_retry">Retry</string> <string name="global_retry">Retry</string>