From 27da68ee48905f47d6c785320197945770ab12da Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Wed, 26 Nov 2025 22:38:31 +0530 Subject: [PATCH 1/3] fix(ui): add top bar with scrim to reliably show status bar icons --- .../nrw/commons/media/ZoomableActivity.kt | 5 ++ .../main/res/drawable-night/ic_arrow_back.xml | 3 ++ app/src/main/res/drawable/ic_arrow_back.xml | 3 ++ app/src/main/res/layout/activity_zoomable.xml | 48 ++++++++++++------- app/src/main/res/values-night/colors.xml | 2 + app/src/main/res/values/colors.xml | 2 + 6 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 app/src/main/res/drawable-night/ic_arrow_back.xml create mode 100644 app/src/main/res/drawable/ic_arrow_back.xml diff --git a/app/src/main/java/fr/free/nrw/commons/media/ZoomableActivity.kt b/app/src/main/java/fr/free/nrw/commons/media/ZoomableActivity.kt index de65e317a3..7cb3a2c8ae 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/ZoomableActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/media/ZoomableActivity.kt @@ -39,6 +39,7 @@ import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.FileProcessor import fr.free.nrw.commons.upload.FileUtilsWrapper import fr.free.nrw.commons.utils.CustomSelectorUtils +import fr.free.nrw.commons.utils.applyEdgeToEdgeTopPaddingInsets import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -137,6 +138,10 @@ class ZoomableActivity : BaseActivity() { binding = ActivityZoomableBinding.inflate(layoutInflater) setContentView(binding.root) + binding.topBar.applyEdgeToEdgeTopPaddingInsets(WindowInsetsCompat.Type.statusBars()) + binding.btnBack.setOnClickListener { + onBackPressed() + } prefs = applicationContext.getSharedPreferences( ImageHelper.CUSTOM_SELECTOR_PREFERENCE_KEY, diff --git a/app/src/main/res/drawable-night/ic_arrow_back.xml b/app/src/main/res/drawable-night/ic_arrow_back.xml new file mode 100644 index 0000000000..b6fa83231b --- /dev/null +++ b/app/src/main/res/drawable-night/ic_arrow_back.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_back.xml b/app/src/main/res/drawable/ic_arrow_back.xml new file mode 100644 index 0000000000..cb840d860c --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_back.xml @@ -0,0 +1,3 @@ + + + diff --git a/app/src/main/res/layout/activity_zoomable.xml b/app/src/main/res/layout/activity_zoomable.xml index b0dd45aaca..4b54a44403 100644 --- a/app/src/main/res/layout/activity_zoomable.xml +++ b/app/src/main/res/layout/activity_zoomable.xml @@ -12,6 +12,7 @@ android:layout_height="match_parent" android:layout_width="match_parent" app:actualImageScaleType="fitCenter" + android:background="@color/background" /> - - + app:layout_constraintTop_toTopOf="parent"> + + + + + diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 7465ef30e7..22f0b23b04 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -2,4 +2,6 @@ #1e8cab #1e8cab + #000000 + #60000000 \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index dd0750baeb..f9a131f974 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -23,6 +23,8 @@ #ffbc46 #ffffff #000000 + #ffffff + #99ffffff #D32F2F #90960a0a From 67256819bd11adb26bfd3dfd3dc49224a0729cfc Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Wed, 26 Nov 2025 22:44:45 +0530 Subject: [PATCH 2/3] refactor: preserve existing view padding when applying system bar insets --- .../free/nrw/commons/utils/EdgeToEdgeUtils.kt | 98 +++++++++++++++---- app/src/main/res/values/ids.xml | 4 + 2 files changed, 82 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt b/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt index 04007485d0..c42586f9cb 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt +++ b/app/src/main/java/fr/free/nrw/commons/utils/EdgeToEdgeUtils.kt @@ -3,7 +3,6 @@ package fr.free.nrw.commons.utils import android.view.View import android.view.ViewGroup.MarginLayoutParams import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsAnimationCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.marginBottom import androidx.core.view.marginLeft @@ -14,16 +13,16 @@ import androidx.core.view.updatePadding import fr.free.nrw.commons.R /** - * Applies edge-to-edge system bar insets to a [View]’s margins using a custom adjustment block. + * Applies edge-to-edge insets to a [View]’s margins using a custom adjustment modifier [block]. * * Stores the initial margins to ensure inset calculations are additive, and applies the provided * [block] with an [InsetsAccumulator] containing initial and system bar inset values. * - * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. + * @param typeMask The type of window insets to apply. Default to [WindowInsetsCompat.Type.systemBars]. * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. * @param block Lambda applied to update [MarginLayoutParams] using the accumulated insets. */ -fun View.applyEdgeToEdgeInsets( +fun View.applyEdgeToEdgeInsetsAsMargin( typeMask: Int = WindowInsetsCompat.Type.systemBars(), shouldConsumeInsets: Boolean = true, block: MarginLayoutParams.(InsetsAccumulator) -> Unit @@ -79,23 +78,84 @@ fun View.applyEdgeToEdgeInsets( } /** - * Applies edge-to-edge system bar insets to the top padding of the view. + * Applies edge-to-edge insets to a [View]’s padding using a custom adjustment modifier [block]. + * + * Stores the initial paddings to ensure inset calculations are additive, and applies the provided + * [block] with an [InsetsAccumulator] containing initial and system bar inset values. * * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. + * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. + * @param block Lambda applied to update [View]'s padding using the values from [InsetsAccumulator]. */ -fun View.applyEdgeToEdgeTopPaddingInsets( +fun View.applyEdgeToEdgeInsetsAsPadding( typeMask: Int = WindowInsetsCompat.Type.systemBars(), + shouldConsumeInsets: Boolean = true, + block: View.(InsetsAccumulator) -> Unit ) { ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> val insets = windowInsets.getInsets(typeMask) - view.updatePadding( - left = insets.left, - right = insets.right, - top = insets.top + val initialTop = if (view.getTag(R.id.initial_padding_top) != null) { + view.getTag(R.id.initial_padding_top) as Int + } else { + view.setTag(R.id.initial_padding_top, view.paddingTop) + view.paddingTop + } + + val initialBottom = if (view.getTag(R.id.initial_padding_bottom) != null) { + view.getTag(R.id.initial_padding_bottom) as Int + } else { + view.setTag(R.id.initial_padding_bottom, view.paddingBottom) + view.paddingBottom + } + + val initialLeft = if (view.getTag(R.id.initial_padding_left) != null) { + view.getTag(R.id.initial_padding_left) as Int + } else { + view.setTag(R.id.initial_padding_left, view.paddingLeft) + view.paddingLeft + } + + val initialRight = if (view.getTag(R.id.initial_padding_right) != null) { + view.getTag(R.id.initial_padding_right) as Int + } else { + view.setTag(R.id.initial_padding_right, view.paddingRight) + view.paddingRight + } + + val accumulator = InsetsAccumulator( + initialTop, + insets.top, + initialBottom, + insets.bottom, + initialLeft, + insets.left, + initialRight, + insets.right ) - WindowInsetsCompat.CONSUMED + block(accumulator) + + if(shouldConsumeInsets) WindowInsetsCompat.CONSUMED else windowInsets + } +} + +/** + * Applies edge-to-edge system bar insets to the top padding of the view. + * + * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. + * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. + */ +fun View.applyEdgeToEdgeTopPaddingInsets( + typeMask: Int = WindowInsetsCompat.Type.systemBars(), + shouldConsumeInsets: Boolean = true +) { + applyEdgeToEdgeInsetsAsPadding(typeMask, shouldConsumeInsets) { insets -> + updatePadding( + left = insets.left, + top = insets.top, + right = insets.right + ) } } @@ -103,20 +163,18 @@ fun View.applyEdgeToEdgeTopPaddingInsets( * Applies edge-to-edge system bar insets to the bottom padding of the view. * * @param typeMask The type of window insets to apply. Defaults to [WindowInsetsCompat.Type.systemBars]. + * @param shouldConsumeInsets If `true`, the insets are consumed and not propagated to child views. */ fun View.applyEdgeToEdgeBottomPaddingInsets( typeMask: Int = WindowInsetsCompat.Type.systemBars(), + shouldConsumeInsets: Boolean = true ) { - ViewCompat.setOnApplyWindowInsetsListener(this) { view, windowInsets -> - val insets = windowInsets.getInsets(typeMask) - - view.updatePadding( + applyEdgeToEdgeInsetsAsPadding(typeMask, shouldConsumeInsets) { insets -> + updatePadding( left = insets.left, right = insets.right, bottom = insets.bottom ) - - WindowInsetsCompat.CONSUMED } } @@ -129,7 +187,7 @@ fun View.applyEdgeToEdgeBottomPaddingInsets( fun applyEdgeToEdgeAllInsets( view: View, shouldConsumeInsets: Boolean = true -) = view.applyEdgeToEdgeInsets(shouldConsumeInsets = shouldConsumeInsets) { insets -> +) = view.applyEdgeToEdgeInsetsAsMargin(shouldConsumeInsets = shouldConsumeInsets) { insets -> leftMargin = insets.left rightMargin = insets.right topMargin = insets.top @@ -141,7 +199,7 @@ fun applyEdgeToEdgeAllInsets( * * @param view The target view. */ -fun applyEdgeToEdgeTopInsets(view: View) = view.applyEdgeToEdgeInsets { insets -> +fun applyEdgeToEdgeTopInsets(view: View) = view.applyEdgeToEdgeInsetsAsMargin { insets -> leftMargin = insets.left rightMargin = insets.right topMargin = insets.top @@ -152,7 +210,7 @@ fun applyEdgeToEdgeTopInsets(view: View) = view.applyEdgeToEdgeInsets { insets - * * @param view The target view. */ -fun applyEdgeToEdgeBottomInsets(view: View) = view.applyEdgeToEdgeInsets { insets -> +fun applyEdgeToEdgeBottomInsets(view: View) = view.applyEdgeToEdgeInsetsAsMargin { insets -> leftMargin = insets.left rightMargin = insets.right bottomMargin = insets.bottom diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 83eb08801c..23cf99a4ba 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -4,4 +4,8 @@ + + + + \ No newline at end of file From 23d05d08a7eb5a8bcdda4644cef18e58657a60f0 Mon Sep 17 00:00:00 2001 From: Rohit Verma Date: Wed, 26 Nov 2025 23:01:39 +0530 Subject: [PATCH 3/3] fix: selected count not visible on light mode at view image screen --- app/src/main/res/layout/activity_zoomable.xml | 2 +- app/src/main/res/values-night/colors.xml | 3 ++- app/src/main/res/values/colors.xml | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/layout/activity_zoomable.xml b/app/src/main/res/layout/activity_zoomable.xml index 4b54a44403..24367301b1 100644 --- a/app/src/main/res/layout/activity_zoomable.xml +++ b/app/src/main/res/layout/activity_zoomable.xml @@ -49,7 +49,7 @@ android:layout_height="wrap_content" android:textSize="@dimen/normal_text" android:textStyle="bold" - android:textColor="@color/white" + android:textColor="@color/onBackground" android:layout_marginStart="12dp" style="@style/TextAppearance.AppCompat.Small" android:text="12" diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 22f0b23b04..4f2ae9863d 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -3,5 +3,6 @@ #1e8cab #1e8cab #000000 - #60000000 + #ffffff + #50000000 \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f9a131f974..6421bbaca4 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -24,7 +24,8 @@ #ffffff #000000 #ffffff - #99ffffff + #000000 + #f2ffffff #D32F2F #90960a0a