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/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/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..24367301b1 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..4f2ae9863d 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -2,4 +2,7 @@
#1e8cab
#1e8cab
+ #000000
+ #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 dd0750baeb..6421bbaca4 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -23,6 +23,9 @@
#ffbc46
#ffffff
#000000
+ #ffffff
+ #000000
+ #f2ffffff
#D32F2F
#90960a0a
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