Merge branch 'lineage-21.0' of https://github.com/LineageOS/android_packages_apps_Glimpse into leaf-3.2

Change-Id: I1808b686058b6c020da4fb62a940fed5faa79a3e
diff --git a/app/Android.bp b/app/Android.bp
index 8eadd7c..816036b 100644
--- a/app/Android.bp
+++ b/app/Android.bp
@@ -19,6 +19,8 @@
     sdk_version: "34",
     product_specific: true,
 
+    use_embedded_native_libs: true,
+
     overrides: [
         "Gallery",
         "Gallery2",
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index c91493e..30686ae 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -18,7 +18,7 @@
 
 buildscript {
     repositories {
-        maven("https://raw.githubusercontent.com/lineage-next/gradle-generatebp/v1.7/.m2")
+        maven("https://raw.githubusercontent.com/lineage-next/gradle-generatebp/v1.9/.m2")
     }
 
     dependencies {
diff --git a/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt b/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
index ca6e7c6..8be1a44 100644
--- a/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
+++ b/app/src/main/java/org/lineageos/glimpse/GlimpseApplication.kt
@@ -8,7 +8,6 @@
 import android.app.Application
 import coil.ImageLoader
 import coil.ImageLoaderFactory
-import coil.decode.GifDecoder
 import coil.decode.ImageDecoderDecoder
 import coil.decode.VideoFrameDecoder
 import coil.memory.MemoryCache
@@ -24,7 +23,6 @@
 
     override fun newImageLoader() = ImageLoader.Builder(this).components {
         add(ImageDecoderDecoder.Factory())
-        add(GifDecoder.Factory())
         add(VideoFrameDecoder.Factory())
     }.memoryCache {
         MemoryCache.Builder(this).maxSizePercent(0.25).build()
diff --git a/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt b/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
index c0178a0..2b77017 100644
--- a/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
+++ b/app/src/main/java/org/lineageos/glimpse/ViewActivity.kt
@@ -14,15 +14,11 @@
 import android.provider.MediaStore
 import android.view.View
 import android.webkit.MimeTypeMap
-import android.widget.HorizontalScrollView
-import android.widget.ImageButton
 import android.widget.LinearLayout
-import android.widget.TextView
 import android.widget.Toast
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.activity.viewModels
 import androidx.appcompat.app.AppCompatActivity
-import androidx.constraintlayout.widget.ConstraintLayout
 import androidx.core.os.bundleOf
 import androidx.core.view.ViewCompat
 import androidx.core.view.WindowCompat
@@ -37,6 +33,8 @@
 import androidx.media3.common.Player
 import androidx.media3.exoplayer.ExoPlayer
 import androidx.viewpager2.widget.ViewPager2
+import com.google.android.material.appbar.AppBarLayout
+import com.google.android.material.appbar.MaterialToolbar
 import com.google.android.material.button.MaterialButton
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
@@ -80,18 +78,15 @@
 
     // Views
     private val adjustButton by lazy { findViewById<MaterialButton>(R.id.adjustButton) }
-    private val backButton by lazy { findViewById<ImageButton>(R.id.backButton) }
+    private val appBarLayout by lazy { findViewById<AppBarLayout>(R.id.appBarLayout) }
     private val bottomSheetLinearLayout by lazy { findViewById<LinearLayout>(R.id.bottomSheetLinearLayout) }
-    private val bottomSheetHorizontalScrollView by lazy { findViewById<HorizontalScrollView>(R.id.bottomSheetHorizontalScrollView) }
     private val contentView by lazy { findViewById<View>(android.R.id.content) }
-    private val dateTextView by lazy { findViewById<TextView>(R.id.dateTextView) }
     private val deleteButton by lazy { findViewById<MaterialButton>(R.id.deleteButton) }
     private val favoriteButton by lazy { findViewById<MaterialButton>(R.id.favoriteButton) }
-    private val infoButton by lazy { findViewById<MaterialButton>(R.id.infoButton) }
+    private val infoButton by lazy { toolbar.menu.findItem(R.id.info) }
     private val shareButton by lazy { findViewById<MaterialButton>(R.id.shareButton) }
-    private val timeTextView by lazy { findViewById<TextView>(R.id.timeTextView) }
-    private val topSheetConstraintLayout by lazy { findViewById<ConstraintLayout>(R.id.topSheetConstraintLayout) }
-    private val useAsButton by lazy { findViewById<MaterialButton>(R.id.useAsButton) }
+    private val toolbar by lazy { findViewById<MaterialToolbar>(R.id.toolbar) }
+    private val useAsButton by lazy { toolbar.menu.findItem(R.id.useAs) }
     private val viewPager by lazy { findViewById<ViewPager2>(R.id.viewPager) }
 
     // System services
@@ -155,9 +150,9 @@
 
             MediaDialogsUtils.showDeleteForeverResultSnackbar(
                 this,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
                 succeeded, 1,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
             )
         }
 
@@ -167,9 +162,9 @@
 
             MediaDialogsUtils.showMoveToTrashResultSnackbar(
                 this,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
                 succeeded, 1,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
                 lastProcessedMedia?.let { trashedMedia ->
                     { trashMedia(trashedMedia, false) }
                 },
@@ -184,9 +179,9 @@
 
             MediaDialogsUtils.showRestoreFromTrashResultSnackbar(
                 this,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
                 succeeded, 1,
-                bottomSheetHorizontalScrollView,
+                bottomSheetLinearLayout,
                 lastProcessedMedia?.let { trashedMedia ->
                     { trashMedia(trashedMedia, true) }
                 },
@@ -267,8 +262,8 @@
 
         // Observe fullscreen mode
         uiModel.fullscreenModeLiveData.observe(this@ViewActivity) { fullscreenMode ->
-            topSheetConstraintLayout.fade(!fullscreenMode)
-            bottomSheetHorizontalScrollView.fade(!fullscreenMode)
+            appBarLayout.fade(!fullscreenMode)
+            bottomSheetLinearLayout.fade(!fullscreenMode)
 
             window.setBarsVisibility(systemBars = !fullscreenMode)
 
@@ -283,11 +278,12 @@
             val mediaStoreMedia = MediaStoreMedia::class.safeCast(displayedMedia)
 
             // Update date and time text
-            dateTextView.isVisible = mediaStoreMedia != null
-            timeTextView.isVisible = mediaStoreMedia != null
             mediaStoreMedia?.let {
-                dateTextView.text = dateFormatter.format(it.dateAdded)
-                timeTextView.text = timeFormatter.format(it.dateAdded)
+                toolbar.title = dateFormatter.format(it.dateAdded)
+                toolbar.subtitle = timeFormatter.format(it.dateAdded)
+            } ?: run {
+                toolbar.title = ""
+                toolbar.subtitle = ""
             }
 
             // Update favorite button
@@ -346,17 +342,10 @@
             // Once the system bars will be made visible again, this function
             // will be called again.
             if (uiModel.fullscreenModeLiveData.value != true) {
-                topSheetConstraintLayout.updatePadding(
-                    left = insets.left,
-                    right = insets.right,
-                    top = insets.top,
-                )
                 bottomSheetLinearLayout.updatePadding(
                     left = insets.left,
                     right = insets.right,
-                )
-                bottomSheetHorizontalScrollView.updatePadding(
-                    bottom = insets.bottom,
+                    bottom = insets.bottom
                 )
 
                 updateSheetsHeight()
@@ -365,7 +354,29 @@
             windowInsets
         }
 
-        backButton.setOnClickListener {
+        toolbar.setOnMenuItemClickListener { menuItem ->
+            when (menuItem.itemId) {
+                R.id.info -> {
+                    MediaStoreMedia::class.safeCast(uiModel.displayedMedia.value)?.let {
+                        MediaInfoBottomSheetDialog(
+                            this@ViewActivity, it, mediaInfoBottomSheetDialogCallbacks, secure
+                        ).show()
+                    }
+                    true
+                }
+
+                R.id.useAs -> {
+                    uiModel.displayedMedia.value?.let {
+                        startActivity(Intent.createChooser(buildUseAsIntent(it), null))
+                    }
+                    true
+                }
+
+                else -> false
+            }
+        }
+
+        toolbar.setNavigationOnClickListener {
             finish()
         }
 
@@ -390,25 +401,6 @@
             }
         }
 
-        useAsButton.setOnClickListener {
-            uiModel.displayedMedia.value?.let {
-                startActivity(
-                    Intent.createChooser(
-                        buildUseAsIntent(it),
-                        null
-                    )
-                )
-            }
-        }
-
-        infoButton.setOnClickListener {
-            MediaStoreMedia::class.safeCast(uiModel.displayedMedia.value)?.let {
-                MediaInfoBottomSheetDialog(
-                    this, it, mediaInfoBottomSheetDialogCallbacks, secure
-                ).show()
-            }
-        }
-
         adjustButton.setOnClickListener {
             uiModel.displayedMedia.value?.let {
                 startActivity(
@@ -530,14 +522,14 @@
     }
 
     private fun updateSheetsHeight() {
-        topSheetConstraintLayout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
-        bottomSheetHorizontalScrollView.measure(
+        appBarLayout.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+        bottomSheetLinearLayout.measure(
             View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED
         )
 
         uiModel.sheetsHeightLiveData.value = Pair(
-            topSheetConstraintLayout.measuredHeight,
-            bottomSheetHorizontalScrollView.measuredHeight,
+            appBarLayout.measuredHeight,
+            bottomSheetLinearLayout.measuredHeight,
         )
     }
 
diff --git a/app/src/main/java/org/lineageos/glimpse/fragments/MainFragment.kt b/app/src/main/java/org/lineageos/glimpse/fragments/MainFragment.kt
index f962451..3ac603e 100644
--- a/app/src/main/java/org/lineageos/glimpse/fragments/MainFragment.kt
+++ b/app/src/main/java/org/lineageos/glimpse/fragments/MainFragment.kt
@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2023 The LineageOS Project
+ * SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
  * SPDX-License-Identifier: Apache-2.0
  */
 
@@ -16,7 +16,7 @@
 
 class MainFragment : Fragment(R.layout.fragment_main) {
     // Views
-    private val bottomNavigationView by getViewProperty<NavigationBarView>(R.id.bottomNavigationView)
+    private val navigationBarView by getViewProperty<NavigationBarView>(R.id.navigationBarView)
 
     // Fragments
     private val childNavHostFragment by lazy { childFragmentManager.findFragmentById(R.id.childNavHostFragment) as NavHostFragment }
@@ -26,6 +26,6 @@
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
-        bottomNavigationView.setupWithNavController(childNavController)
+        navigationBarView.setupWithNavController(childNavController)
     }
 }
diff --git a/app/src/main/res/drawable/bg_media_viewer_bottom_sheet.xml b/app/src/main/res/drawable/bg_media_viewer_bottom_sheet.xml
index 19a4eaa..c3ef816 100644
--- a/app/src/main/res/drawable/bg_media_viewer_bottom_sheet.xml
+++ b/app/src/main/res/drawable/bg_media_viewer_bottom_sheet.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     SPDX-FileCopyrightText: 2023 The LineageOS Project
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
      SPDX-License-Identifier: Apache-2.0
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
@@ -8,7 +8,7 @@
         <shape>
             <gradient
                 android:angle="270"
-                android:endColor="@android:color/black"
+                android:endColor="#DD000000"
                 android:startColor="@android:color/transparent"
                 android:type="linear" />
         </shape>
diff --git a/app/src/main/res/drawable/bg_media_viewer_top_sheet.xml b/app/src/main/res/drawable/bg_media_viewer_top_sheet.xml
index 9c1799c..c4a5090 100644
--- a/app/src/main/res/drawable/bg_media_viewer_top_sheet.xml
+++ b/app/src/main/res/drawable/bg_media_viewer_top_sheet.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     SPDX-FileCopyrightText: 2023 The LineageOS Project
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
      SPDX-License-Identifier: Apache-2.0
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
@@ -9,7 +9,7 @@
             <gradient
                 android:angle="270"
                 android:endColor="@android:color/transparent"
-                android:startColor="@android:color/black"
+                android:startColor="#DD000000"
                 android:type="linear" />
         </shape>
     </item>
diff --git a/app/src/main/res/layout-sw600dp/fragment_main.xml b/app/src/main/res/layout-sw600dp/fragment_main.xml
new file mode 100644
index 0000000..65ac8bf
--- /dev/null
+++ b/app/src/main/res/layout-sw600dp/fragment_main.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     SPDX-FileCopyrightText: 2024 The LineageOS Project
+     SPDX-License-Identifier: Apache-2.0
+-->
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".MainActivity">
+
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/childNavHostFragment"
+        android:name="androidx.navigation.fragment.NavHostFragment"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        app:defaultNavHost="true"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/navigationBarView"
+        app:layout_constraintTop_toTopOf="parent"
+        app:navGraph="@navigation/main_fragment_navigation" />
+
+    <com.google.android.material.navigationrail.NavigationRailView
+        android:id="@+id/navigationBarView"
+        style="@style/Widget.Material3.BottomAppBar"
+        android:layout_width="wrap_content"
+        android:layout_height="0dp"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:menu="@menu/fragment_main_bottom_app_bar"
+        app:menuGravity="center" />
+
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/app/src/main/res/layout/activity_view.xml b/app/src/main/res/layout/activity_view.xml
index eacd8a9..3e02376 100644
--- a/app/src/main/res/layout/activity_view.xml
+++ b/app/src/main/res/layout/activity_view.xml
@@ -3,7 +3,7 @@
      SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
      SPDX-License-Identifier: Apache-2.0
 -->
-<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
@@ -13,123 +13,76 @@
 
     <androidx.viewpager2.widget.ViewPager2
         android:id="@+id/viewPager"
-        android:layout_width="0dp"
-        android:layout_height="0dp"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
 
-    <androidx.constraintlayout.widget.ConstraintLayout
-        android:id="@+id/topSheetConstraintLayout"
-        android:layout_width="0dp"
+    <com.google.android.material.appbar.AppBarLayout
+        android:id="@+id/appBarLayout"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:background="@drawable/bg_media_viewer_top_sheet"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent">
+        android:fitsSystemWindows="true">
 
-        <ImageButton
-            android:id="@+id/backButton"
-            style="@style/Theme.Glimpse.MediaViewer.TopSheet.Button"
-            android:layout_width="wrap_content"
+        <com.google.android.material.appbar.MaterialToolbar
+            android:id="@+id/toolbar"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="12dp"
-            android:layout_marginBottom="12dp"
-            android:layout_marginStart="8dp"
-            android:src="@drawable/ic_back"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintStart_toStartOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+            app:menu="@menu/activity_view_toolbar"
+            app:navigationIcon="@drawable/ic_back"
+            app:navigationIconTint="@android:color/white"
+            app:subtitleTextAppearance="?attr/textAppearanceTitleSmall"
+            app:subtitleTextColor="@android:color/white"
+            app:titleTextAppearance="?attr/textAppearanceTitleSmall"
+            app:titleTextColor="@android:color/white" />
 
-        <TextView
-            android:id="@+id/dateTextView"
-            style="@style/Theme.Glimpse.MediaViewer.DateTimeText"
-            android:layout_marginEnd="24dp"
-            android:layout_marginTop="16dp"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toTopOf="parent" />
+    </com.google.android.material.appbar.AppBarLayout>
 
-        <TextView
-            android:id="@+id/timeTextView"
-            style="@style/Theme.Glimpse.MediaViewer.DateTimeText"
-            android:layout_marginBottom="16dp"
-            android:layout_marginEnd="24dp"
-            app:layout_constraintBottom_toBottomOf="parent"
-            app:layout_constraintEnd_toEndOf="parent"
-            app:layout_constraintTop_toBottomOf="@+id/dateTextView" />
-    </androidx.constraintlayout.widget.ConstraintLayout>
-
-    <HorizontalScrollView
-        android:id="@+id/bottomSheetHorizontalScrollView"
-        android:layout_width="wrap_content"
+    <LinearLayout
+        android:id="@+id/bottomSheetLinearLayout"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
         android:background="@drawable/bg_media_viewer_bottom_sheet"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintStart_toStartOf="parent">
+        android:gravity="top|center">
 
-        <LinearLayout
-            android:id="@+id/bottomSheetLinearLayout"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_marginVertical="8dp"
-            android:gravity="top|center">
+        <!-- Cannot mess with fixed padding from here because of insets -->
+        <Space
+            android:layout_width="16dp"
+            android:layout_height="match_parent" />
 
-            <!-- Cannot mess with fixed padding from here because of insets -->
-            <Space
-                android:layout_width="16dp"
-                android:layout_height="match_parent" />
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/favoriteButton"
+            style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
+            android:contentDescription="@string/file_action_add_to_favorites"
+            android:drawableTop="@drawable/ic_star_toggle"
+            android:text="@string/file_action_add_to_favorites" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/favoriteButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_add_to_favorites"
-                android:drawableTop="@drawable/ic_star_toggle"
-                android:text="@string/file_action_add_to_favorites" />
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/shareButton"
+            style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
+            android:contentDescription="@string/file_action_share"
+            android:drawableTop="@drawable/ic_share"
+            android:text="@string/file_action_share" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/shareButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_share"
-                android:drawableTop="@drawable/ic_share"
-                android:text="@string/file_action_share" />
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/adjustButton"
+            style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
+            android:contentDescription="@string/file_action_edit"
+            android:drawableTop="@drawable/ic_edit"
+            android:text="@string/file_action_edit" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/useAsButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_use_as"
-                android:drawableTop="@drawable/ic_contact_page"
-                android:text="@string/file_action_use_as" />
+        <com.google.android.material.button.MaterialButton
+            android:id="@+id/deleteButton"
+            style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
+            android:contentDescription="@string/file_action_move_to_trash"
+            android:drawableTop="@drawable/ic_delete"
+            android:text="@string/file_action_move_to_trash" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/infoButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_information"
-                android:drawableTop="@drawable/ic_info"
-                android:text="@string/file_action_information" />
+        <!-- Cannot mess with fixed padding from here because of insets -->
+        <Space
+            android:layout_width="16dp"
+            android:layout_height="match_parent" />
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/adjustButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_edit"
-                android:drawableTop="@drawable/ic_edit"
-                android:text="@string/file_action_edit" />
+    </LinearLayout>
 
-            <com.google.android.material.button.MaterialButton
-                android:id="@+id/deleteButton"
-                style="@style/Theme.Glimpse.MediaViewer.BottomSheet.Button"
-                android:contentDescription="@string/file_action_move_to_trash"
-                android:drawableTop="@drawable/ic_delete"
-                android:text="@string/file_action_move_to_trash" />
-
-            <!-- Cannot mess with fixed padding from here because of insets -->
-            <Space
-                android:layout_width="16dp"
-                android:layout_height="match_parent" />
-
-        </LinearLayout>
-
-    </HorizontalScrollView>
-
-</androidx.constraintlayout.widget.ConstraintLayout>
+</FrameLayout>
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index e16013e..eac0420 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-     SPDX-FileCopyrightText: 2023 The LineageOS Project
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
      SPDX-License-Identifier: Apache-2.0
 -->
 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -16,14 +16,14 @@
         android:layout_width="0dp"
         android:layout_height="0dp"
         app:defaultNavHost="true"
-        app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
+        app:layout_constraintBottom_toTopOf="@+id/navigationBarView"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toTopOf="parent"
         app:navGraph="@navigation/main_fragment_navigation" />
 
     <com.google.android.material.bottomnavigation.BottomNavigationView
-        android:id="@+id/bottomNavigationView"
+        android:id="@+id/navigationBarView"
         style="@style/Widget.Material3.BottomAppBar"
         android:layout_width="0dp"
         android:layout_height="wrap_content"
diff --git a/app/src/main/res/menu/activity_view_toolbar.xml b/app/src/main/res/menu/activity_view_toolbar.xml
new file mode 100644
index 0000000..67dfbc9
--- /dev/null
+++ b/app/src/main/res/menu/activity_view_toolbar.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     SPDX-FileCopyrightText: 2024 The LineageOS Project
+     SPDX-License-Identifier: Apache-2.0
+-->
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item
+        style="@style/Theme.Glimpse.TopAppBarOption"
+        android:id="@+id/useAs"
+        android:icon="@drawable/ic_contact_page"
+        android:title="@string/file_action_use_as"
+        android:contentDescription="@string/file_action_use_as" />
+
+    <item
+        style="@style/Theme.Glimpse.TopAppBarOption"
+        android:id="@+id/info"
+        android:icon="@drawable/ic_info"
+        android:title="@string/file_action_information"
+        android:contentDescription="@string/file_action_information" />
+
+</menu>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index ed6bd34..e67e9b1 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -65,6 +65,7 @@
     <string name="intent_action_not_supported">Aktion wird nicht unterstützt</string>
     <string name="intent_media_type_not_found">Medientyp nicht gefunden</string>
     <string name="intent_media_type_not_supported">Medientyp wird nicht unterstützt</string>
+    <string name="intent_no_system_wallpaper_cropper_available">Kein Zuschneidewerkzeug verfügbar</string>
     <string name="intent_wallpaper_cannot_be_changed">Hintergrundbild kann nicht geändert werden</string>
     <string name="file_action_add_to_favorites">Zu Favoriten hinzufügen</string>
     <string name="file_action_delete_forever">Endgültig löschen</string>
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
new file mode 100644
index 0000000..ad6ad40
--- /dev/null
+++ b/app/src/main/res/values-hu/strings.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
+     SPDX-License-Identifier: Apache-2.0
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Galéria</string>
+    <string name="app_permissions_toast">A jogosultságot a felhasználó nem adta meg.</string>
+    <string name="reels_title">Tekercsek</string>
+    <string name="albums_title">Albumok</string>
+    <string name="search_title">Keresés</string>
+    <string name="categories_title">Kategóriák</string>
+    <string name="album_favorites">Kedvencek</string>
+    <string name="album_trash">Lomtár</string>
+    <string name="album_reels">Tekercsek</string>
+    <string name="album_photos">Fotók</string>
+    <string name="album_videos">Videók</string>
+    <plurals name="album_thumbnail_items">
+        <item quantity="one">%d elem</item>
+        <item quantity="other">%d elem</item>
+    </plurals>
+    <plurals name="delete_file_forever_confirm_message">
+        <item quantity="one">Biztos benne, hogy véglegesen törli ezt a fájlt?</item>
+        <item quantity="other">Biztos benne, hogy véglegesen töröl %d fájlt?</item>
+    </plurals>
+    <plurals name="delete_file_forever_successful">
+        <item quantity="one">A fájl véglegesen törölve</item>
+        <item quantity="other">%d fájl véglegesen törölve</item>
+    </plurals>
+    <plurals name="delete_file_forever_unsuccessful">
+        <item quantity="one">Ez a fájl nem törölhető véglegesen</item>
+        <item quantity="other">Ez a(z) %d fájl nem törölhető véglegesen</item>
+    </plurals>
+    <plurals name="move_file_to_trash_confirm_message">
+        <item quantity="one">Biztos benne, hogy ezt az egy fájlt a lomtárba dobja?</item>
+        <item quantity="other">Biztos benne, hogy ezt a(z) %d fájlt a lomtárba dobja?</item>
+    </plurals>
+    <plurals name="move_file_to_trash_successful">
+        <item quantity="one">A fájl a lomtárba került</item>
+        <item quantity="other">%d fájl a lomtárba került</item>
+    </plurals>
+    <plurals name="move_file_to_trash_unsuccessful">
+        <item quantity="one">Ez a fájl nem dobható a lomtárba</item>
+        <item quantity="other">Ez a(z) %d fájl nem dobható a lomtárba</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_confirm_message">
+        <item quantity="one">Biztos benne, hogy egy fáljt visszaállít a lomtárból?</item>
+        <item quantity="other">Biztos benne, hogy %d fáljt visszaállít a lomtárból?</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_successful">
+        <item quantity="one">Egy fájl visszaállításra került</item>
+        <item quantity="other">%d fájl visszaállításra került</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_unsuccessful">
+        <item quantity="one">A fájl nem állítható vissza a lomtárból</item>
+        <item quantity="other">%d fájl nem állítható vissza a lomtárból</item>
+    </plurals>
+    <string name="manage_media_permission_title">A médiajogosultságok kezelése</string>
+    <string name="manage_media_permission_message">A képek és videók jobb feldolgozásához engedélyezze az alkalmazásnak a médiafájlok kezelését</string>
+    <string name="media_info_unknown">Ismeretlen</string>
+    <string name="media_info_add_description_hint">Egy leírás hozzáadása</string>
+    <string name="media_info_write_description_failed">A médialeírás módosítása meghiúsult</string>
+    <string name="media_info_location_loading_placeholder">Betöltés…</string>
+    <string name="media_info_location_open_with">Hely megtekintése a következővel:</string>
+    <string name="intent_action_not_supported">Nem támogatott művelet</string>
+    <string name="intent_media_not_found">Nem található média</string>
+    <string name="intent_media_type_not_found">Nem található médiatipus</string>
+    <string name="intent_media_type_not_supported">Ez a médiatípus nem támogatott</string>
+    <string name="intent_no_system_wallpaper_cropper_available">Nem áll rendelkezésre vágóeszköz</string>
+    <string name="intent_wallpaper_cannot_be_changed">Nem változtatható meg a háttérkép</string>
+    <string name="file_action_add_to_favorites">Hozzáadás a kedvencekhez</string>
+    <string name="file_action_delete_forever">Végleges törlés</string>
+    <string name="file_action_edit">Szerkesztés</string>
+    <string name="file_action_empty_trash">Lomtárürítés</string>
+    <string name="file_action_information">Információ</string>
+    <string name="file_action_move_to_trash">Lomtárba helyezés</string>
+    <string name="file_action_remove_from_favorites">Eltávolítás a kedvencek közül</string>
+    <string name="file_action_restore_from_trash">Visszaállítás a Lomtárból</string>
+    <string name="file_action_share">Megosztás</string>
+    <string name="file_action_use_as">Használja mint</string>
+    <string name="file_action_undo_action">Visszavonás</string>
+    <string name="no_media">Nem található médiafájl</string>
+    <plurals name="thumbnail_selection_count">
+        <item quantity="one">%d kiválasztva</item>
+        <item quantity="other">%d kiválasztva</item>
+    </plurals>
+    <string name="pick_a_photo">Válasszon egy képet</string>
+    <string name="pick_a_video">Válasszon egy videót</string>
+    <string name="pick_a_media">Válasszon egy médiafájlt</string>
+    <string name="picker_done">Kész</string>
+    <string name="set_wallpaper_label">Háttérkép</string>
+    <string name="set_wallpaper">Háttérkép-beállítás</string>
+    <string name="set_wallpaper_dialog_title">Állítsa be a háttérképet</string>
+    <string name="set_wallpaper_home_screen">Kezdőképernyőre</string>
+    <string name="set_wallpaper_lock_screen">Záróképernyőre</string>
+    <string name="set_wallpaper_both">Kezdő- és Záróképernyőre</string>
+</resources>
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..40fdd53
--- /dev/null
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
+     SPDX-License-Identifier: Apache-2.0
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">Galeria</string>
+    <string name="app_permissions_toast">Permissões não concedidas pelo usuário.</string>
+    <string name="reels_title">Reels</string>
+    <string name="albums_title">Álbuns</string>
+    <string name="search_title">Pesquisar</string>
+    <string name="categories_title">Categorias</string>
+    <string name="album_favorites">Favoritos</string>
+    <string name="album_trash">Lixeira</string>
+    <string name="album_reels">Reels</string>
+    <string name="album_photos">Fotos</string>
+    <string name="album_videos">Vídeos</string>
+    <plurals name="album_thumbnail_items">
+        <item quantity="one">%d item</item>
+        <item quantity="other">%d itens</item>
+    </plurals>
+    <plurals name="delete_file_forever_confirm_message">
+        <item quantity="one">Tem certeza que quer excluir permanentemente este arquivo?</item>
+        <item quantity="other">Tem certeza que deseja excluir %d arquivos permanentemente?</item>
+    </plurals>
+    <plurals name="delete_file_forever_successful">
+        <item quantity="one">Arquivo excluído permanentemente</item>
+        <item quantity="other">%d arquivos excluídos permanentemente</item>
+    </plurals>
+    <plurals name="delete_file_forever_unsuccessful">
+        <item quantity="one">O arquivo não pôde ser excluído permanentemente</item>
+        <item quantity="other">%d arquivos não puderam ser excluídos permanentemente</item>
+    </plurals>
+    <plurals name="move_file_to_trash_confirm_message">
+        <item quantity="one">Tem certeza de que deseja mover um arquivo para a Lixeira?</item>
+        <item quantity="other">Tem certeza de que deseja mover %d arquivos para a Lixeira?</item>
+    </plurals>
+    <plurals name="move_file_to_trash_successful">
+        <item quantity="one">Arquivo movido para a Lixeira</item>
+        <item quantity="other">%d arquivos movidos para a Lixeira</item>
+    </plurals>
+    <plurals name="move_file_to_trash_unsuccessful">
+        <item quantity="one">O arquivo não pôde ser movido para a Lixeira</item>
+        <item quantity="other">%d arquivos não puderam ser movidos para a Lixeira</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_confirm_message">
+        <item quantity="one">Tem certeza de que deseja restaurar um arquivo da Lixeira?</item>
+        <item quantity="other">Tem certeza de que deseja restaurar %d arquivos da Lixeira?</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_successful">
+        <item quantity="one">Arquivo restaurado da Lixeira</item>
+        <item quantity="other">%d arquivos restaurados da Lixeira</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_unsuccessful">
+        <item quantity="one">Arquivo não pôde ser restaurado da Lixeira</item>
+        <item quantity="other">%d arquivos não puderam ser restaurados da Lixeira</item>
+    </plurals>
+    <string name="manage_media_permission_title">Gerenciar permissões de mídia</string>
+    <string name="manage_media_permission_message">Para gerenciar melhor suas imagens e vídeos, permita que o app gerencie seus arquivos de mídia</string>
+    <string name="media_info_unknown">Desconhecido</string>
+    <string name="media_info_add_description_hint">Adicionar uma descrição</string>
+    <string name="media_info_write_description_failed">Falha ao alterar descrição da mídia</string>
+    <string name="media_info_location_loading_placeholder">Carregando…</string>
+    <string name="media_info_location_open_with">Veja a localização com</string>
+    <string name="intent_action_not_supported">Ação não suportada</string>
+    <string name="intent_media_not_found">Mídia não encontrada</string>
+    <string name="intent_media_type_not_found">Tipo de mídia não encontrado</string>
+    <string name="intent_media_type_not_supported">Tipo de mídia não suportado</string>
+    <string name="intent_no_system_wallpaper_cropper_available">Nenhuma ferramenta de recorte disponível no sistema</string>
+    <string name="intent_wallpaper_cannot_be_changed">O plano de fundo não pode ser alterado</string>
+    <string name="file_action_add_to_favorites">Adicionar aos favoritos</string>
+    <string name="file_action_delete_forever">Excluir permanentemente</string>
+    <string name="file_action_edit">Editar</string>
+    <string name="file_action_empty_trash">Esvaziar Lixeira</string>
+    <string name="file_action_information">Informações</string>
+    <string name="file_action_move_to_trash">Mover para Lixeira</string>
+    <string name="file_action_remove_from_favorites">Remover dos favoritos</string>
+    <string name="file_action_restore_from_trash">Restaurar da Lixeira</string>
+    <string name="file_action_share">Compartilhar</string>
+    <string name="file_action_use_as">Usar como</string>
+    <string name="file_action_undo_action">Desfazer</string>
+    <string name="no_media">Nenhuma mídia</string>
+    <plurals name="thumbnail_selection_count">
+        <item quantity="one">%d selecionado</item>
+        <item quantity="other">%d selecionados</item>
+    </plurals>
+    <string name="pick_a_photo">Escolha uma foto</string>
+    <string name="pick_a_video">Escolha um vídeo</string>
+    <string name="pick_a_media">Escolha uma mídia</string>
+    <string name="picker_done">Pronto</string>
+    <string name="set_wallpaper_label">Plano de fundo</string>
+    <string name="set_wallpaper">Definir plano de fundo</string>
+    <string name="set_wallpaper_dialog_title">Definir plano de fundo</string>
+    <string name="set_wallpaper_home_screen">Tela inicial</string>
+    <string name="set_wallpaper_lock_screen">Tela de bloqueio</string>
+    <string name="set_wallpaper_both">Tela inicial e de bloqueio</string>
+</resources>
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..a4e5460
--- /dev/null
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     SPDX-FileCopyrightText: 2023-2024 The LineageOS Project
+     SPDX-License-Identifier: Apache-2.0
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_name">相簿</string>
+    <string name="app_permissions_toast">使用者未授予權限。</string>
+    <string name="reels_title">Reels</string>
+    <string name="albums_title">相簿</string>
+    <string name="search_title">搜尋</string>
+    <string name="categories_title">類別</string>
+    <string name="album_favorites">我的最愛</string>
+    <string name="album_trash">垃圾桶</string>
+    <string name="album_reels">Reels</string>
+    <string name="album_photos">相片</string>
+    <string name="album_videos">影片</string>
+    <plurals name="album_thumbnail_items">
+        <item quantity="other">%d 個項目</item>
+    </plurals>
+    <plurals name="delete_file_forever_confirm_message">
+        <item quantity="other">您確定要永久刪除 %d 個檔案嗎?</item>
+    </plurals>
+    <plurals name="delete_file_forever_successful">
+        <item quantity="other">檔案已永久刪除</item>
+    </plurals>
+    <plurals name="delete_file_forever_unsuccessful">
+        <item quantity="other">檔案無法永久刪除</item>
+    </plurals>
+    <plurals name="move_file_to_trash_confirm_message">
+        <item quantity="other">您確定您要將檔案移到垃圾桶?</item>
+    </plurals>
+    <plurals name="move_file_to_trash_successful">
+        <item quantity="other">檔案已移動到垃圾桶</item>
+    </plurals>
+    <plurals name="move_file_to_trash_unsuccessful">
+        <item quantity="other">檔案無法移動到垃圾桶</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_confirm_message">
+        <item quantity="other">您確定要將檔案從垃圾桶中還原?</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_successful">
+        <item quantity="other">檔案已從垃圾桶中還原</item>
+    </plurals>
+    <plurals name="restore_file_from_trash_unsuccessful">
+        <item quantity="other">檔案無法從垃圾桶中還原</item>
+    </plurals>
+    <string name="manage_media_permission_title">管理媒體權限</string>
+    <string name="manage_media_permission_message">為了管理您的圖片及影片,請給予應用程式權限管理您的媒體檔案</string>
+    <string name="media_info_unknown">未知</string>
+    <string name="media_info_add_description_hint">新增描述</string>
+    <string name="media_info_write_description_failed">修改描述失敗</string>
+    <string name="media_info_location_loading_placeholder">讀取中...</string>
+    <string name="media_info_location_open_with">檢視地點</string>
+    <string name="intent_action_not_supported">不支援此操作</string>
+    <string name="intent_media_not_found">找不到媒體</string>
+    <string name="intent_media_type_not_found">找不到媒體格式</string>
+    <string name="intent_media_type_not_supported">不支援媒體格式</string>
+    <string name="intent_no_system_wallpaper_cropper_available">沒有系統的裁切工具可用</string>
+    <string name="intent_wallpaper_cannot_be_changed">桌布無法更改</string>
+    <string name="file_action_add_to_favorites">新增至我的最愛</string>
+    <string name="file_action_delete_forever">永久刪除</string>
+    <string name="file_action_edit">編輯</string>
+    <string name="file_action_empty_trash">清空垃圾桶</string>
+    <string name="file_action_information">資訊</string>
+    <string name="file_action_move_to_trash">移至垃圾桶</string>
+    <string name="file_action_remove_from_favorites">從我的最愛中移除</string>
+    <string name="file_action_restore_from_trash">從垃圾桶中還原</string>
+    <string name="file_action_share">分享</string>
+    <string name="file_action_use_as">作為使用</string>
+    <string name="file_action_undo_action">復原</string>
+    <string name="no_media">沒有媒體檔案</string>
+    <plurals name="thumbnail_selection_count">
+        <item quantity="other">%d 已選擇</item>
+    </plurals>
+    <string name="pick_a_photo">選擇照片</string>
+    <string name="pick_a_video">挑選影片</string>
+    <string name="pick_a_media">選擇媒體</string>
+    <string name="picker_done">完成</string>
+    <string name="set_wallpaper_label">桌布</string>
+    <string name="set_wallpaper">設定桌布</string>
+    <string name="set_wallpaper_dialog_title">設定桌布於</string>
+    <string name="set_wallpaper_home_screen">主畫面</string>
+    <string name="set_wallpaper_lock_screen">鎖定畫面</string>
+    <string name="set_wallpaper_both">桌面和鎖定畫面</string>
+</resources>
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index fd0b120..930a991 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -44,42 +44,21 @@
         <item name="android:windowLightStatusBar">?attr/isLightTheme</item>
     </style>
 
-    <!-- Media viewer top sheet -->
-    <style name="Theme.Glimpse.MediaViewer.TopSheet" />
-
-    <!-- Media viewer top sheet buttons -->
-    <style name="Theme.Glimpse.MediaViewer.TopSheet.Button">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:background">?attr/selectableItemBackgroundBorderless</item>
-        <item name="android:padding">8dp</item>
-        <item name="tint">?attr/colorOnSurface</item>
-    </style>
-
-    <!-- Media viewer top sheet date/time text -->
-    <style name="Theme.Glimpse.MediaViewer.DateTimeText">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:textColor">?attr/colorOnSurface</item>
-        <item name="android:textSize">11sp</item>
-        <item name="android:letterSpacing">0.05</item>
-        <item name="android:typeface">monospace</item>
-    </style>
-
     <!-- Media viewer bottom sheet -->
     <style name="Theme.Glimpse.MediaViewer.BottomSheet" />
 
     <!-- Media viewer bottom sheet buttons -->
     <style name="Theme.Glimpse.MediaViewer.BottomSheet.Button">
-        <item name="android:layout_width">96dp</item>
+        <item name="android:layout_width">0dp</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:drawableTint">?attr/colorOnSurface</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:drawableTint">@android:color/white</item>
         <item name="android:hyphenationFrequency">normal</item>
         <item name="android:maxLines">3</item>
+        <item name="android:maxWidth">320dp</item>
         <item name="android:padding">8dp</item>
         <item name="android:textAppearance">?attr/textAppearanceCaption</item>
-        <item name="android:textColor">?attr/colorOnSurface</item>
+        <item name="android:textColor">@android:color/white</item>
         <item name="backgroundTint">@android:color/transparent</item>
         <item name="rippleColor">?attr/colorControlHighlight</item>
     </style>
diff --git a/build.gradle.kts b/build.gradle.kts
index ccdec67..7a1d776 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -5,8 +5,8 @@
 
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 plugins {
-    id("com.android.application") version "8.2.1" apply false
-    id("com.android.library") version "8.2.1" apply false
+    id("com.android.application") version "8.4.0" apply false
+    id("com.android.library") version "8.4.0" apply false
     id("org.jetbrains.kotlin.android") version "1.8.10" apply false
 }
 
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index d64cd49..e644113 100644
--- a/gradle/wrapper/gradle-wrapper.jar
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 1af9e09..b82aa23 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew.bat b/gradlew.bat
index 6689b85..7101f8e 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -43,11 +43,11 @@
 %JAVA_EXE% -version >NUL 2>&1

 if %ERRORLEVEL% equ 0 goto execute

 

-echo.

-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

+echo. 1>&2

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2

+echo. 1>&2

+echo Please set the JAVA_HOME variable in your environment to match the 1>&2

+echo location of your Java installation. 1>&2

 

 goto fail

 

@@ -57,11 +57,11 @@
 

 if exist "%JAVA_EXE%" goto execute

 

-echo.

-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

-echo.

-echo Please set the JAVA_HOME variable in your environment to match the

-echo location of your Java installation.

+echo. 1>&2

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2

+echo. 1>&2

+echo Please set the JAVA_HOME variable in your environment to match the 1>&2

+echo location of your Java installation. 1>&2

 

 goto fail