From 6443881193259ccac2f382daba523200d7955bf1 Mon Sep 17 00:00:00 2001 From: Nite Date: Fri, 11 Apr 2025 17:48:08 +0000 Subject: [PATCH] Fixed DI to make the widget work --- build.gradle | 6 ++-- core/domain/build.gradle | 2 +- ultrasonic/build.gradle | 24 ++++++------- .../ultrasonic/activity/NavigationActivity.kt | 35 +++++++++---------- .../moire/ultrasonic/di/MediaPlayerModule.kt | 8 ++--- .../org/moire/ultrasonic/util/ServerColor.kt | 13 ++----- .../src/main/res/layout/navigation_header.xml | 8 ++--- 7 files changed, 40 insertions(+), 56 deletions(-) diff --git a/build.gradle b/build.gradle index ebc6fa8b..badd3719 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,7 @@ buildscript { google() mavenCentral() gradlePluginPortal() - maven { url "https://plugins.gradle.org/m2/" } + maven { url = "https://plugins.gradle.org/m2/" } } dependencies { classpath libs.gradle @@ -55,6 +55,6 @@ allprojects { } wrapper { - gradleVersion(libs.versions.gradle.get()) - distributionType("all") + gradleVersion = libs.versions.gradle.get() + distributionType = "all" } \ No newline at end of file diff --git a/core/domain/build.gradle b/core/domain/build.gradle index 75b14dc5..b5e81edb 100644 --- a/core/domain/build.gradle +++ b/core/domain/build.gradle @@ -12,7 +12,7 @@ dependencies { } android { - namespace 'org.moire.ultrasonic.subsonic.domain' + namespace = 'org.moire.ultrasonic.subsonic.domain' compileOptions { sourceCompatibility JavaVersion.VERSION_21 targetCompatibility JavaVersion.VERSION_21 diff --git a/ultrasonic/build.gradle b/ultrasonic/build.gradle index a92a3928..8f8dd4d2 100644 --- a/ultrasonic/build.gradle +++ b/ultrasonic/build.gradle @@ -34,10 +34,10 @@ android { 'minify/proguard-kotlin.pro' } debug { - minifyEnabled false - multiDexEnabled true - testCoverageEnabled true - applicationIdSuffix '.debug' + minifyEnabled = false + multiDexEnabled = true + testCoverageEnabled = true + applicationIdSuffix = '.debug' } } @@ -57,9 +57,9 @@ android { } buildFeatures { - viewBinding true - dataBinding true - buildConfig true + viewBinding = true + dataBinding = true + buildConfig = true } compileOptions { @@ -73,8 +73,8 @@ android { lint { baseline = file("lint-baseline.xml") - abortOnError true - warningsAsErrors true + abortOnError = true + warningsAsErrors = true warning 'ImpliedQuantity' disable 'IconMissingDensityFolder', 'VectorPath' disable 'MissingTranslation', 'UnusedQuantity', 'MissingQuantity' @@ -82,10 +82,10 @@ android { // We manage dependencies on Gitlab with RenovateBot disable 'GradleDependency' disable 'AndroidGradlePluginVersion' - textReport true - checkDependencies true + textReport = true + checkDependencies = true } - namespace 'org.moire.ultrasonic' + namespace = 'org.moire.ultrasonic' } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 3d3a339e..fdc46f0b 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -13,7 +13,6 @@ import android.content.Intent import android.content.res.ColorStateList import android.content.res.Resources import android.media.AudioManager -import android.os.Build import android.os.Bundle import android.provider.MediaStore import android.provider.SearchRecentSuggestions @@ -96,6 +95,7 @@ class NavigationActivity : ScopeActivity() { private var drawerLayout: DrawerLayout? = null private var host: NavHostFragment? = null private var selectServerButton: MaterialButton? = null + private var selectServerDropdownImage: ImageView? = null private var headerBackgroundImage: ImageView? = null // We store the last search string in this variable. @@ -165,7 +165,7 @@ class NavigationActivity : ScopeActivity() { drawerLayout ) - setupActionBar(navController, appBarConfiguration) + setupActionBarWithNavController(navController, appBarConfiguration) setupNavigationMenu(navController) @@ -333,9 +333,6 @@ class NavigationActivity : ScopeActivity() { } private fun updateNavigationHeaderForServer() { - // Only show the vector graphic on Android 11 or earlier - val showVectorBackground = (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) - val activeServer = activeServerProvider.getActiveServer() if (cachedServerCount == 0) { @@ -345,7 +342,7 @@ class NavigationActivity : ScopeActivity() { } val foregroundColor = - ServerColor.getForegroundColor(this, activeServer.color, showVectorBackground) + ServerColor.getForegroundColor(this, activeServer.color) val backgroundColor = ServerColor.getBackgroundColor(this, activeServer.color) @@ -359,12 +356,8 @@ class NavigationActivity : ScopeActivity() { selectServerButton?.iconTint = ColorStateList.valueOf(foregroundColor) selectServerButton?.setTextColor(foregroundColor) + selectServerDropdownImage?.imageTintList = ColorStateList.valueOf(foregroundColor) headerBackgroundImage?.setBackgroundColor(backgroundColor) - - // Hide the vector graphic on Android 12 or later - if (!showVectorBackground) { - headerBackgroundImage?.setImageDrawable(null) - } } private fun setupNavigationMenu(navController: NavController) { @@ -409,7 +402,7 @@ class NavigationActivity : ScopeActivity() { selectServerButton = navigationView?.getHeaderView(0)?.findViewById(R.id.header_select_server) - val dropDownButton: ImageView? = + selectServerDropdownImage = navigationView?.getHeaderView(0)?.findViewById(R.id.edit_server_button) val onClick: (View) -> Unit = { @@ -420,16 +413,12 @@ class NavigationActivity : ScopeActivity() { } selectServerButton?.setOnClickListener(onClick) - dropDownButton?.setOnClickListener(onClick) + selectServerDropdownImage?.setOnClickListener(onClick) headerBackgroundImage = navigationView?.getHeaderView(0)?.findViewById(R.id.img_header_bg) } - private fun setupActionBar(navController: NavController, appBarConfig: AppBarConfiguration) { - setupActionBarWithNavController(navController, appBarConfig) - } - private val closeNavigationDrawerOnBack = object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { drawerLayout?.closeDrawer(GravityCompat.START) @@ -446,13 +435,21 @@ class NavigationActivity : ScopeActivity() { } override fun onOptionsItemSelected(item: MenuItem): Boolean { + // Skip android.R.id.home so the drawer button doesn't get wrongly routed + if (item.itemId == android.R.id.home) { + return super.onOptionsItemSelected(item) + } return item.onNavDestinationSelected(findNavController(R.id.nav_host_fragment)) || super.onOptionsItemSelected(item) } - // TODO: Why is this needed? Shouldn't it just work by default? override fun onSupportNavigateUp(): Boolean { - return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) + // This override is required by design when using setupActionBarWithNavController() + // with an AppBarConfiguration. It ensures that the Up button behavior is correctly + // delegated — either navigating "up" in the back stack, or opening the drawer if + // we're at a top-level destination. + return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration) || + super.onSupportNavigateUp() } override fun onNewIntent(intent: Intent) { diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MediaPlayerModule.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MediaPlayerModule.kt index d4799b98..96091b9d 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MediaPlayerModule.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/di/MediaPlayerModule.kt @@ -1,7 +1,6 @@ package org.moire.ultrasonic.di import org.koin.dsl.module -import org.moire.ultrasonic.activity.NavigationActivity import org.moire.ultrasonic.service.ExternalStorageMonitor import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport import org.moire.ultrasonic.service.MediaPlayerManager @@ -20,8 +19,7 @@ val mediaPlayerModule = module { single { NetworkAndStorageChecker() } single { ShareHandler() } - scope { - scoped { MediaPlayerManager(get(), get()) } - scoped { MediaPlayerLifecycleSupport(get(), get(), get(), get()) } - } + // These MUST be singletons, for the media playback must work headless (without an activity) + single { MediaPlayerManager(get(), get()) } + single { MediaPlayerLifecycleSupport(get(), get(), get(), get()) } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ServerColor.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ServerColor.kt index 7d4d35d7..6baf36ff 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ServerColor.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/util/ServerColor.kt @@ -14,7 +14,6 @@ import androidx.core.graphics.ColorUtils import com.google.android.material.color.MaterialColors private const val LUMINANCE_LIMIT = 0.5 -private const val LUMINANCE_CORRECTION = -0.25 /** * Contains functions for computing server display colors @@ -31,17 +30,9 @@ object ServerColor { } @ColorInt - fun getForegroundColor( - context: Context, - serverColor: Int?, - showVectorBackground: Boolean = false - ): Int { + fun getForegroundColor(context: Context, serverColor: Int?): Int { val backgroundColor = getBackgroundColor(context, serverColor) - var luminance = ColorUtils.calculateLuminance(backgroundColor) - - // The actual luminance is a good bit lower - // when the background color is being overlayed by the vector - if (showVectorBackground) luminance += LUMINANCE_CORRECTION + val luminance = ColorUtils.calculateLuminance(backgroundColor) return if (luminance < LUMINANCE_LIMIT) { ContextCompat.getColor(context, org.moire.ultrasonic.R.color.selected_menu_dark) diff --git a/ultrasonic/src/main/res/layout/navigation_header.xml b/ultrasonic/src/main/res/layout/navigation_header.xml index d53e1eba..b751881c 100644 --- a/ultrasonic/src/main/res/layout/navigation_header.xml +++ b/ultrasonic/src/main/res/layout/navigation_header.xml @@ -52,11 +52,10 @@ \ No newline at end of file