diff --git a/app/build.gradle b/app/build.gradle index 0497e42f6..2744fab62 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -97,9 +97,6 @@ dependencies { // Dialogs implementation 'com.afollestad.material-dialogs:core:3.3.0' - // Edge-To-Edge insets - implementation "dev.chrisbanes:insetter-ktx:0.3.1" - // --- DEV --- // Lint diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 327938937..05cfa91d8 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -7,12 +7,14 @@ import android.os.Bundle import android.util.Log import android.view.View import android.view.WindowInsets +import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.databinding.DataBindingUtil import org.oxycblt.auxio.databinding.ActivityMainBinding import org.oxycblt.auxio.playback.PlaybackService import org.oxycblt.auxio.settings.SettingsManager +import org.oxycblt.auxio.settings.SettingsViewModel import org.oxycblt.auxio.ui.accent import org.oxycblt.auxio.ui.handleTransparentSystemBars import org.oxycblt.auxio.ui.toColor @@ -22,11 +24,14 @@ import org.oxycblt.auxio.ui.toColor // TODO: Landscape UI layouts // FIXME: Compat issue with Versions 5 that leads to progress bar looking off class MainActivity : AppCompatActivity() { + private val settingsModel: SettingsViewModel by viewModels() @Suppress("DEPRECATION") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + // --- UI SETUP --- + val binding = DataBindingUtil.setContentView( this, R.layout.activity_main ) @@ -42,35 +47,33 @@ class MainActivity : AppCompatActivity() { // Apply the theme setTheme(accent.second) - // If enabled and possible, go through a stupidly long & complicated process - // just to get edge-to-edge to work. - // TODO: Make the navigation bar fully transparent if (settingsManager.getEdgeToEdge() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { - window?.apply { - statusBarColor = Color.TRANSPARENT - navigationBarColor = R.color.nav_color.toColor(this@MainActivity) + doEdgeToEdgeSetup(binding) + } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - Log.d(this::class.simpleName, "Doing R+ edge-to-edge.") + // --- VIEWMODEL SETUP --- - setDecorFitsSystemWindows(false) + settingsModel.theme.observe(this) { + if (it != null) { + doThemeRecreate(it) - binding.root.setOnApplyWindowInsetsListener { _, insets -> - WindowInsets.Builder() - .setInsets( - WindowInsets.Type.systemBars(), - insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) - ) - .build() - } - } else { - Log.d(this::class.simpleName, "Doing legacy edge-to-edge.") + settingsModel.doneWithThemeUpdate() + } + } - binding.root.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - } + settingsModel.accent.observe(this) { + if (it != null) { + recreate() - handleTransparentSystemBars(resources.configuration) + settingsModel.doneWithAccentUpdate() + } + } + + settingsModel.edge.observe(this) { + if (it != null) { + recreate() + + settingsModel.doneWithEdgeUpdate() } } } @@ -83,6 +86,43 @@ class MainActivity : AppCompatActivity() { } } + private fun doEdgeToEdgeSetup(binding: ActivityMainBinding) { + window?.apply { + statusBarColor = Color.TRANSPARENT + + // Use a heavily transparent scrim on the nav bar as otherwise the transparency wont + // work. + navigationBarColor = R.color.nav_color.toColor(this@MainActivity) + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + // Do modern edge to edge [Which is really a shot in the dark tbh] + Log.d(this::class.simpleName, "Doing R+ edge-to-edge.") + + setDecorFitsSystemWindows(false) + + binding.root.setOnApplyWindowInsetsListener { _, insets -> + WindowInsets.Builder() + .setInsets( + WindowInsets.Type.systemBars(), + insets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()) + ) + .build() + } + } else { + // Do old edge-to-edge otherwise + Log.d(this::class.simpleName, "Doing legacy edge-to-edge.") + + binding.root.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + } + + handleTransparentSystemBars(resources.configuration) + } + } + + /** + * + */ fun doThemeRecreate(newTheme: Int) { AppCompatDelegate.setDefaultNightMode(newTheme) } diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 904558bd8..1f05107d5 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -120,6 +120,7 @@ class MainFragment : Fragment() { return binding.root } + // Functions that check if MainFragment should nav over to LibraryFragment, or whether // it should stay put. Mostly by checking if the navController is currently in a detail // fragment, and if the playing item is already being shown. diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt index 7f0c7b779..00f4eedad 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt @@ -4,12 +4,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.appcompat.widget.Toolbar +import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.ItemTouchHelper -import dev.chrisbanes.insetter.applySystemWindowInsetsToMargin +import com.afollestad.materialdialogs.utils.MDUtil.updatePadding import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentQueueBinding import org.oxycblt.auxio.music.BaseModel @@ -44,8 +44,18 @@ class QueueFragment : Fragment() { // --- UI SETUP --- - binding.queueToolbar.setNavigationOnClickListener { - findNavController().navigateUp() + binding.queueToolbar.apply { + setNavigationOnClickListener { + findNavController().navigateUp() + } + + setOnApplyWindowInsetsListener { v, insets -> + (parent as View).updatePadding( + top = insets.systemWindowInsetTop + ) + + insets + } } binding.queueRecycler.apply { @@ -77,12 +87,6 @@ class QueueFragment : Fragment() { return binding.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - - view.findViewById(R.id.queue_toolbar).applySystemWindowInsetsToMargin(top = true) - } - private fun createQueueData(): MutableList { val queue = mutableListOf() diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt index d42f7eecb..b2de1e784 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt @@ -11,7 +11,6 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.customview.customView -import org.oxycblt.auxio.MainActivity import org.oxycblt.auxio.R import org.oxycblt.auxio.settings.adapters.AccentAdapter import org.oxycblt.auxio.ui.ACCENTS @@ -60,28 +59,12 @@ class SettingsListFragment : PreferenceFragmentCompat() { else -> R.drawable.ic_auto } ) - - (requireActivity() as MainActivity).doThemeRecreate(it) - - settingsModel.doneWithThemeUpdate() } } settingsModel.accent.observe(viewLifecycleOwner) { if (it != null) { accentPref?.summary = getDetailedAccentSummary(requireActivity(), it) - - requireActivity().recreate() - - settingsModel.doneWithAccentUpdate() - } - } - - settingsModel.edge.observe(viewLifecycleOwner) { - if (it != null) { - requireActivity().recreate() - - settingsModel.doneWithEdgeUpdate() } } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 7809b730c..8641d34bd 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -9,9 +9,6 @@ import org.oxycblt.auxio.ui.ACCENTS /** * Wrapper around the [SharedPreferences] class that writes & reads values without a context. - * - * **Note:** Run any getter in a IO coroutine if possible, as SharedPrefs will read from disk - * the first time it occurs. * @author OxygenCobalt */ class SettingsManager private constructor(context: Context) : diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsViewModel.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsViewModel.kt index 6d1bb65b8..7f6f9828f 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsViewModel.kt @@ -4,6 +4,12 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +/** + * A [ViewModel] that provides a better interface for observing settings updates compared to + * [SettingsManager.Callback] or the default SharedPreferences listener. + * // TODO: Roll values & updates into this viewmodel + * @author OxygenCobalt + */ class SettingsViewModel : ViewModel(), SettingsManager.Callback { private val mTheme = MutableLiveData() val theme: LiveData get() = mTheme diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 9fd552f04..3d1e64f53 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -73,7 +73,7 @@ fun Spanned.render(): Spanned { } /** - * Handle transparent system bars on light mode. Adapted from Music Player GO + * Handle the new transparent system bars on light mode. Adapted from Music Player GO * (https://github.com/enricocid/Music-Player-GO) */ @TargetApi(Build.VERSION_CODES.O_MR1) diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt index 2c341ff9c..a22dca713 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/ThemeUtils.kt @@ -100,11 +100,18 @@ fun resolveAttr(context: Context, @AttrRes attr: Int): Int { return color.toColor(context) } +/** + * Get the name of an accent. + * TODO: Make these use translatable string resources!!!! + */ fun getAccentItemSummary(context: Context, newAccent: Pair): String { return context.resources.getResourceEntryName(newAccent.first) .replace("_", " ").capitalize(Locale.getDefault()) } +/** + * Get the name [in bold]] and the hex value of a theme. + */ fun getDetailedAccentSummary(context: Context, newAccent: Pair): Spanned { val name = getAccentItemSummary(context, newAccent) val hex = context.getString(accent.first).toUpperCase(Locale.getDefault()) diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 453e3b992..3f8241ec0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -87,9 +87,11 @@ 18sp + \ No newline at end of file