From bd9383117b6ceaa76594e586a8b41f8022d8c0cc Mon Sep 17 00:00:00 2001 From: ibrahim-iqbal Date: Wed, 23 Sep 2026 17:09:04 +0530 Subject: [PATCH 1/2] chore: add calens file Signed-off-by: ibrahim-iqbal --- changelog/unreleased/4985 | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 changelog/unreleased/4985 diff --git a/changelog/unreleased/4985 b/changelog/unreleased/4985 new file mode 100644 index 00000000000..04725349275 --- /dev/null +++ b/changelog/unreleased/4985 @@ -0,0 +1,8 @@ +Bugfix: Widen snackbars on tablets + +Snackbar width has been expanded to fill the parent on tablets with a +smallest-width of at least 600dp, so tablet users see a full-width snackbar +instead of the narrow Material default. + +https://github.com/owncloud/android/issues/4921 +https://github.com/owncloud/android/pull/4985 From b9374a19103742d31224e58d9f883d1654ddaf87 Mon Sep 17 00:00:00 2001 From: ibrahim-iqbal Date: Wed, 23 Sep 2026 17:09:11 +0530 Subject: [PATCH 2/2] fix: widen snackbars on tablets (#4921) Signed-off-by: ibrahim-iqbal --- .../android/extensions/ActivityExt.kt | 4 +-- .../android/extensions/FragmentExt.kt | 3 +- .../android/extensions/SnackbarExt.kt | 31 +++++++++++++++++++ .../ui/activity/FileDisplayActivity.kt | 5 ++- .../ui/preview/PreviewAudioFragment.kt | 9 ++++-- .../ui/preview/PreviewImageFragment.kt | 9 ++++-- .../android/ui/preview/PreviewTextFragment.kt | 9 ++++-- .../ui/preview/PreviewVideoActivity.kt | 5 +-- 8 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 owncloudApp/src/main/java/com/owncloud/android/extensions/SnackbarExt.kt diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/ActivityExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/ActivityExt.kt index c4027a9bb59..e7bfa24ecc8 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/extensions/ActivityExt.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/ActivityExt.kt @@ -100,7 +100,7 @@ fun Activity.showMessageInSnackbar( val bottomNavView = findViewById(R.id.bottom_nav_view) val snackbar = Snackbar.make(findViewById(layoutId), message, duration) if (bottomNavView?.isVisible == true) { snackbar.setAnchorView(bottomNavView) } - snackbar.show() + snackbar.applyResponsiveWidth().show() } fun Activity.showSnackbarWithAction( @@ -112,7 +112,7 @@ fun Activity.showSnackbarWithAction( val bottomNavView = findViewById(R.id.bottom_nav_view) val snackbar = Snackbar.make(findViewById(android.R.id.content), message, duration) if (bottomNavView?.isVisible == true) { snackbar.setAnchorView(bottomNavView) } - snackbar.setAction(actionText) { action() }.show() + snackbar.setAction(actionText) { action() }.applyResponsiveWidth().show() } fun Activity.showErrorInToast( diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentExt.kt index 9f642898940..d5d06a235ef 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentExt.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/FragmentExt.kt @@ -62,7 +62,7 @@ fun Fragment.showMessageInSnackbar( val bottomNavView = rootView.findViewById(R.id.bottom_nav_view) val snackbar = Snackbar.make(requiredView, message, duration) if (bottomNavView?.isVisible == true) { snackbar.setAnchorView(bottomNavView) } - snackbar.show() + snackbar.applyResponsiveWidth().show() } fun Fragment.showSnackbarWithAction( @@ -74,6 +74,7 @@ fun Fragment.showSnackbarWithAction( val requiredView = view ?: return Snackbar.make(requiredView, message, duration) .setAction(actionText) { action() } + .applyResponsiveWidth() .show() } diff --git a/owncloudApp/src/main/java/com/owncloud/android/extensions/SnackbarExt.kt b/owncloudApp/src/main/java/com/owncloud/android/extensions/SnackbarExt.kt new file mode 100644 index 00000000000..571ab26a80e --- /dev/null +++ b/owncloudApp/src/main/java/com/owncloud/android/extensions/SnackbarExt.kt @@ -0,0 +1,31 @@ +/** + * ownCloud Android client application + * + * Copyright (C) 2026 ownCloud GmbH. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.owncloud.android.extensions + +import android.view.ViewGroup +import androidx.core.view.updateLayoutParams +import com.google.android.material.snackbar.Snackbar + +fun Snackbar.applyResponsiveWidth(): Snackbar { + if (view.context.resources.configuration.smallestScreenWidthDp >= 600) { + view.updateLayoutParams { + width = ViewGroup.LayoutParams.MATCH_PARENT + } + } + return this +} diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt index dd165eb6920..6c639262166 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/activity/FileDisplayActivity.kt @@ -77,6 +77,7 @@ import com.owncloud.android.domain.files.model.OCFile.Companion.ROOT_PARENT_ID import com.owncloud.android.domain.spaces.model.OCSpace import com.owncloud.android.domain.utils.Event import com.owncloud.android.extensions.checkPasscodeEnforced +import com.owncloud.android.extensions.applyResponsiveWidth import com.owncloud.android.extensions.collectLatestLifecycleFlow import com.owncloud.android.extensions.goToUrl import com.owncloud.android.extensions.isDownloadPending @@ -1408,7 +1409,9 @@ class FileDisplayActivity : FileActivity(), is SynchronizeFileUseCase.SyncType.DownloadEnqueued -> { fileWaitingToPreview?.let { - Snackbar.make(findViewById(android.R.id.content), R.string.new_remote_version_found_msg, Snackbar.LENGTH_LONG).show() + Snackbar.make(findViewById(android.R.id.content), R.string.new_remote_version_found_msg, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() startSyncThenOpen(it) fileWaitingToPreview = null } ?: showSnackMessage(getString(R.string.download_enqueued_msg)) diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt index 3ffafb67d5f..f8591f932b7 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewAudioFragment.kt @@ -47,6 +47,7 @@ import androidx.core.view.WindowInsetsCompat import com.google.android.material.snackbar.Snackbar import com.owncloud.android.R import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.extensions.applyResponsiveWidth import com.owncloud.android.extensions.collectLatestLifecycleFlow import com.owncloud.android.extensions.filterMenuOptions import com.owncloud.android.extensions.sendDownloadedFilesByShareSheet @@ -305,13 +306,17 @@ class PreviewAudioFragment : FileFragment() { R.id.action_set_available_offline -> { fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(file))) - Snackbar.make(requireView(), R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireView(), R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } R.id.action_unset_available_offline -> { fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(file))) - Snackbar.make(requireView(), R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireView(), R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt index 162ab6aa852..a2bfa8f6e21 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewImageFragment.kt @@ -51,6 +51,7 @@ import com.owncloud.android.R import com.owncloud.android.databinding.PreviewImageFragmentBinding import com.owncloud.android.domain.files.model.MIME_SVG import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.extensions.applyResponsiveWidth import com.owncloud.android.extensions.collectLatestLifecycleFlow import com.owncloud.android.extensions.filterMenuOptions import com.owncloud.android.extensions.sendDownloadedFilesByShareSheet @@ -248,13 +249,17 @@ class PreviewImageFragment : FileFragment() { R.id.action_set_available_offline -> { fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(listOf(file))) - Snackbar.make(requireActivity().window.decorView, R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireActivity().window.decorView, R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } R.id.action_unset_available_offline -> { fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(listOf(file))) - Snackbar.make(requireActivity().window.decorView, R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireActivity().window.decorView, R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt index 40db2017c7e..d8afb6bf905 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewTextFragment.kt @@ -42,6 +42,7 @@ import com.google.android.material.tabs.TabLayoutMediator import com.owncloud.android.R import com.owncloud.android.databinding.PreviewTextFragmentBinding import com.owncloud.android.domain.files.model.OCFile +import com.owncloud.android.extensions.applyResponsiveWidth import com.owncloud.android.extensions.collectLatestLifecycleFlow import com.owncloud.android.extensions.filterMenuOptions import com.owncloud.android.extensions.sendDownloadedFilesByShareSheet @@ -170,7 +171,9 @@ class PreviewTextFragment : FileFragment() { val fileToSetAsAvailableOffline = ArrayList() fileToSetAsAvailableOffline.add(file) fileOperationsViewModel.performOperation(FileOperation.SetFilesAsAvailableOffline(fileToSetAsAvailableOffline)) - Snackbar.make(requireView(), R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireView(), R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } @@ -178,7 +181,9 @@ class PreviewTextFragment : FileFragment() { val fileToUnsetAsAvailableOffline = ArrayList() fileToUnsetAsAvailableOffline.add(file) fileOperationsViewModel.performOperation(FileOperation.UnsetFilesAsAvailableOffline(fileToUnsetAsAvailableOffline)) - Snackbar.make(requireView(), R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(requireView(), R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG) + .applyResponsiveWidth() + .show() true } diff --git a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt index c61b3d97476..91061119d89 100644 --- a/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt +++ b/owncloudApp/src/main/java/com/owncloud/android/ui/preview/PreviewVideoActivity.kt @@ -63,6 +63,7 @@ import com.owncloud.android.R import com.owncloud.android.databinding.VideoPreviewBinding import com.owncloud.android.domain.files.model.OCFile import com.owncloud.android.domain.utils.Event +import com.owncloud.android.extensions.applyResponsiveWidth import com.owncloud.android.extensions.filterMenuOptions import com.owncloud.android.extensions.sendDownloadedFilesByShareSheet import com.owncloud.android.extensions.showErrorInSnackbar @@ -411,7 +412,7 @@ class PreviewVideoActivity : FileActivity(), Player.Listener, OnPrepareVideoPlay val fileToSetAsAvailableOffline = ArrayList() fileToSetAsAvailableOffline.add(file) fileOperationsViewModel.performOperation(SetFilesAsAvailableOffline(fileToSetAsAvailableOffline)) - Snackbar.make(binding.root, R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.confirmation_set_available_offline, Snackbar.LENGTH_LONG).applyResponsiveWidth().show() true } @@ -419,7 +420,7 @@ class PreviewVideoActivity : FileActivity(), Player.Listener, OnPrepareVideoPlay val fileToUnsetAsAvailableOffline = ArrayList() fileToUnsetAsAvailableOffline.add(file) fileOperationsViewModel.performOperation(UnsetFilesAsAvailableOffline(fileToUnsetAsAvailableOffline)) - Snackbar.make(binding.root, R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG).show() + Snackbar.make(binding.root, R.string.confirmation_unset_available_offline, Snackbar.LENGTH_LONG).applyResponsiveWidth().show() true }