From 8356d18a67dc39ad06f381366ee8fddb4cbfc595 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Mar 2021 14:49:52 +0100 Subject: [PATCH 1/4] Improve Snackbar duration (Fixes #2929) --- .idea/dictionaries/bmarty.xml | 1 + CHANGES.md | 1 + .../im/vector/app/core/extensions/TextView.kt | 4 +-- .../vector/app/core/platform/SnackbarExt.kt | 32 +++++++++++++++++++ .../app/core/platform/VectorBaseActivity.kt | 4 +-- .../app/core/platform/VectorBaseFragment.kt | 5 +-- .../home/room/detail/RoomDetailFragment.kt | 12 +++---- .../roomdirectory/PublicRoomsFragment.kt | 5 ++- 8 files changed, 46 insertions(+), 18 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/core/platform/SnackbarExt.kt diff --git a/.idea/dictionaries/bmarty.xml b/.idea/dictionaries/bmarty.xml index 4de90e9405..4585842153 100644 --- a/.idea/dictionaries/bmarty.xml +++ b/.idea/dictionaries/bmarty.xml @@ -31,6 +31,7 @@ signin signout signup + snackbar ssss sygnal threepid diff --git a/CHANGES.md b/CHANGES.md index 586291e9c7..a69e1f866b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Improvements 🙌: - Add tooltip for room quick actions - Pre-share session keys when opening a room or start typing (#2771) - Sending is now queuing by room and not uniquely to the session + - Improve Snackbar duration (#2929) Bugfix 🐛: - Try to fix crash about UrlPreview (#2640) diff --git a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt index b7f97dc6f7..574e25a5ee 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/TextView.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/TextView.kt @@ -32,8 +32,8 @@ import androidx.annotation.StringRes import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.core.view.isVisible -import com.google.android.material.snackbar.Snackbar import im.vector.app.R +import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.utils.copyToClipboard import im.vector.app.features.themes.ThemeUtils @@ -116,7 +116,7 @@ fun TextView.copyOnLongClick() { ?.text ?.let { text -> copyToClipboard(view.context, text, false) - Snackbar.make(view, view.resources.getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT).show() + view.showOptimizedSnackbar(view.resources.getString(R.string.copied_to_clipboard)) } true } diff --git a/vector/src/main/java/im/vector/app/core/platform/SnackbarExt.kt b/vector/src/main/java/im/vector/app/core/platform/SnackbarExt.kt new file mode 100644 index 0000000000..6cdcfabe63 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/platform/SnackbarExt.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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.platform + +import android.view.View +import com.google.android.material.snackbar.Snackbar + +private const val MIN_SNACKBAR_DURATION = 2000 +private const val MAX_SNACKBAR_DURATION = 8000 +private const val DURATION_PER_LETTER = 50 + +fun View.showOptimizedSnackbar(message: String) { + Snackbar.make(this, message, getDuration(message)).show() +} + +private fun getDuration(message: String): Int { + return (message.length * DURATION_PER_LETTER).coerceIn(MIN_SNACKBAR_DURATION, MAX_SNACKBAR_DURATION) +} diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt index 43c96d2468..b35d582a00 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseActivity.kt @@ -597,9 +597,7 @@ abstract class VectorBaseActivity : AppCompatActivity(), HasScr * ========================================================================================== */ fun showSnackbar(message: String) { - getCoordinatorLayout()?.let { - Snackbar.make(it, message, Snackbar.LENGTH_SHORT).show() - } + getCoordinatorLayout()?.showOptimizedSnackbar(message) } fun showSnackbar(message: String, @StringRes withActionTitle: Int?, action: (() -> Unit)?) { diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index 0b951fb5a2..b692ea3703 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -193,10 +193,7 @@ abstract class VectorBaseFragment : BaseMvRxFragment(), HasScre } protected fun showErrorInSnackbar(throwable: Throwable) { - vectorBaseActivity.getCoordinatorLayout()?.let { - Snackbar.make(it, errorFormatter.toHumanReadable(throwable), Snackbar.LENGTH_SHORT) - .show() - } + vectorBaseActivity.getCoordinatorLayout()?.showOptimizedSnackbar(errorFormatter.toHumanReadable(throwable)) } protected fun showLoadingDialog(message: CharSequence? = null, cancelable: Boolean = false) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt index d51ed08083..c627a4a94b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailFragment.kt @@ -69,7 +69,6 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState -import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding3.view.focusChanges import com.jakewharton.rxbinding3.widget.textChanges import com.vanniktech.emoji.EmojiPopup @@ -90,6 +89,7 @@ import im.vector.app.core.glide.GlideRequests import im.vector.app.core.intent.getFilenameFromUri import im.vector.app.core.intent.getMimeTypeFromUri import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.resources.ColorProvider import im.vector.app.core.ui.views.CurrentCallsView import im.vector.app.core.ui.views.KnownCallsViewHolder @@ -370,7 +370,7 @@ class RoomDetailFragment @Inject constructor( is RoomDetailViewEvents.OnNewTimelineEvents -> scrollOnNewMessageCallback.addNewTimelineEventIds(it.eventIds) is RoomDetailViewEvents.ActionSuccess -> displayRoomDetailActionSuccess(it) is RoomDetailViewEvents.ActionFailure -> displayRoomDetailActionFailure(it) - is RoomDetailViewEvents.ShowMessage -> showSnackWithMessage(it.message, Snackbar.LENGTH_LONG) + is RoomDetailViewEvents.ShowMessage -> showSnackWithMessage(it.message) is RoomDetailViewEvents.NavigateToEvent -> navigateToEvent(it) is RoomDetailViewEvents.FileTooBigError -> displayFileTooBigError(it) is RoomDetailViewEvents.DownloadFileState -> handleDownloadFileState(it) @@ -1692,7 +1692,7 @@ class RoomDetailFragment @Inject constructor( is EventSharedAction.Copy -> { // I need info about the current selected message :/ copyToClipboard(requireContext(), action.content, false) - showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) + showSnackWithMessage(getString(R.string.copied_to_clipboard)) } is EventSharedAction.Redact -> { promptConfirmationToRedactEvent(action) @@ -1736,7 +1736,7 @@ class RoomDetailFragment @Inject constructor( is EventSharedAction.CopyPermalink -> { val permalink = session.permalinkService().createPermalink(roomDetailArgs.roomId, action.eventId) copyToClipboard(requireContext(), permalink, false) - showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT) + showSnackWithMessage(getString(R.string.copied_to_clipboard)) } is EventSharedAction.Resend -> { roomDetailViewModel.handle(RoomDetailAction.ResendMessage(action.eventId)) @@ -1847,8 +1847,8 @@ class RoomDetailFragment @Inject constructor( } } - private fun showSnackWithMessage(message: String, duration: Int = Snackbar.LENGTH_SHORT) { - Snackbar.make(requireView(), message, duration).show() + private fun showSnackWithMessage(message: String) { + view?.showOptimizedSnackbar(message) } private fun showDialogWithMessage(message: String) { diff --git a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt index d200129ed9..cee30e7def 100644 --- a/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomdirectory/PublicRoomsFragment.kt @@ -23,7 +23,6 @@ import android.view.View import android.view.ViewGroup import com.airbnb.mvrx.activityViewModel import com.airbnb.mvrx.withState -import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding3.appcompat.queryTextChanges import im.vector.app.R import im.vector.app.core.extensions.cleanup @@ -31,6 +30,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.exhaustive import im.vector.app.core.extensions.trackItemsVisibilityChange import im.vector.app.core.platform.VectorBaseFragment +import im.vector.app.core.platform.showOptimizedSnackbar import im.vector.app.core.utils.toast import im.vector.app.databinding.FragmentPublicRoomsBinding import im.vector.app.features.permalink.NavigationInterceptor @@ -95,8 +95,7 @@ class PublicRoomsFragment @Inject constructor( private fun handleViewEvents(viewEvents: RoomDirectoryViewEvents) { when (viewEvents) { is RoomDirectoryViewEvents.Failure -> { - Snackbar.make(views.coordinatorLayout, errorFormatter.toHumanReadable(viewEvents.throwable), Snackbar.LENGTH_SHORT) - .show() + views.coordinatorLayout.showOptimizedSnackbar(errorFormatter.toHumanReadable(viewEvents.throwable)) } }.exhaustive } From 5aa8b0255ad96a7ef495132d33ef7a314f746318 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Mar 2021 15:34:28 +0100 Subject: [PATCH 2/4] Fix MainActivity display (Fixes #2927) --- CHANGES.md | 1 + .../im/vector/app/features/MainActivity.kt | 6 ++--- vector/src/main/res/layout/activity_main.xml | 26 +++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 vector/src/main/res/layout/activity_main.xml diff --git a/CHANGES.md b/CHANGES.md index a69e1f866b..2bf6249423 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,6 +18,7 @@ Bugfix 🐛: - Try to fix crash about UrlPreview (#2640) - Be robust if Event.type is missing (#2946) - Snappier message send status + - Fix MainActivity display (#2927) Translations 🗣: - All string resources and translations have been moved to the application module. Weblate project for the SDK will be removed. diff --git a/vector/src/main/java/im/vector/app/features/MainActivity.kt b/vector/src/main/java/im/vector/app/features/MainActivity.kt index 351163b026..143506d4df 100644 --- a/vector/src/main/java/im/vector/app/features/MainActivity.kt +++ b/vector/src/main/java/im/vector/app/features/MainActivity.kt @@ -31,7 +31,7 @@ import im.vector.app.core.error.ErrorFormatter import im.vector.app.core.extensions.startSyncing import im.vector.app.core.platform.VectorBaseActivity import im.vector.app.core.utils.deleteAllFiles -import im.vector.app.databinding.FragmentLoadingBinding +import im.vector.app.databinding.ActivityMainBinding import im.vector.app.features.home.HomeActivity import im.vector.app.features.home.ShortcutsHandler import im.vector.app.features.login.LoginActivity @@ -66,7 +66,7 @@ data class MainActivityArgs( * This Activity, when started with argument, is also doing some cleanup when user signs out, * clears cache, is logged out, or is soft logged out */ -class MainActivity : VectorBaseActivity(), UnlockedActivity { +class MainActivity : VectorBaseActivity(), UnlockedActivity { companion object { private const val EXTRA_ARGS = "EXTRA_ARGS" @@ -81,7 +81,7 @@ class MainActivity : VectorBaseActivity(), UnlockedActiv } } - override fun getBinding() = FragmentLoadingBinding.inflate(layoutInflater) + override fun getBinding() = ActivityMainBinding.inflate(layoutInflater) private lateinit var args: MainActivityArgs diff --git a/vector/src/main/res/layout/activity_main.xml b/vector/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000000..2ca8afcccf --- /dev/null +++ b/vector/src/main/res/layout/activity_main.xml @@ -0,0 +1,26 @@ + + + + + + + + From 5c07a5780cc14d407cee2548026f8fd42afd17d2 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 10 Mar 2021 15:38:29 +0100 Subject: [PATCH 3/4] Better with horizontal progress bar --- vector/src/main/res/layout/fragment_loading.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/vector/src/main/res/layout/fragment_loading.xml b/vector/src/main/res/layout/fragment_loading.xml index 7a6a791edf..27ae764a73 100644 --- a/vector/src/main/res/layout/fragment_loading.xml +++ b/vector/src/main/res/layout/fragment_loading.xml @@ -4,7 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - Date: Wed, 10 Mar 2021 17:20:51 +0100 Subject: [PATCH 4/4] Cleanup --- .../main/java/im/vector/app/core/platform/VectorBaseFragment.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt index b692ea3703..f515060db6 100644 --- a/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt +++ b/vector/src/main/java/im/vector/app/core/platform/VectorBaseFragment.kt @@ -35,7 +35,6 @@ import androidx.lifecycle.ViewModelProvider import androidx.viewbinding.ViewBinding import com.airbnb.mvrx.BaseMvRxFragment import com.bumptech.glide.util.Util.assertMainThread -import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding3.view.clicks import im.vector.app.R import im.vector.app.core.di.DaggerScreenComponent