Implemented navigation header coloring based on selected server
This commit is contained in:
parent
477f6f5d7c
commit
7c66bc7ec8
|
@ -49,7 +49,7 @@ android {
|
||||||
baselineFile file("lint-baseline.xml")
|
baselineFile file("lint-baseline.xml")
|
||||||
ignore 'MissingTranslation'
|
ignore 'MissingTranslation'
|
||||||
warning 'ImpliedQuantity'
|
warning 'ImpliedQuantity'
|
||||||
disable 'IconMissingDensityFolder'
|
disable 'IconMissingDensityFolder', "VectorPath"
|
||||||
abortOnError true
|
abortOnError true
|
||||||
warningsAsErrors true
|
warningsAsErrors true
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.moire.ultrasonic.activity
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.app.SearchManager
|
import android.app.SearchManager
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -12,9 +13,11 @@ import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Button
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.GravityCompat
|
import androidx.core.view.GravityCompat
|
||||||
import androidx.drawerlayout.widget.DrawerLayout
|
import androidx.drawerlayout.widget.DrawerLayout
|
||||||
import androidx.fragment.app.FragmentContainerView
|
import androidx.fragment.app.FragmentContainerView
|
||||||
|
@ -27,6 +30,7 @@ import androidx.navigation.ui.onNavDestinationSelected
|
||||||
import androidx.navigation.ui.setupActionBarWithNavController
|
import androidx.navigation.ui.setupActionBarWithNavController
|
||||||
import androidx.navigation.ui.setupWithNavController
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.navigation.NavigationView
|
import com.google.android.material.navigation.NavigationView
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||||
|
@ -46,6 +50,7 @@ import org.moire.ultrasonic.util.FileUtil
|
||||||
import org.moire.ultrasonic.util.NowPlayingEventDistributor
|
import org.moire.ultrasonic.util.NowPlayingEventDistributor
|
||||||
import org.moire.ultrasonic.util.NowPlayingEventListener
|
import org.moire.ultrasonic.util.NowPlayingEventListener
|
||||||
import org.moire.ultrasonic.util.PermissionUtil
|
import org.moire.ultrasonic.util.PermissionUtil
|
||||||
|
import org.moire.ultrasonic.util.ServerColor
|
||||||
import org.moire.ultrasonic.util.Settings
|
import org.moire.ultrasonic.util.Settings
|
||||||
import org.moire.ultrasonic.util.SubsonicUncaughtExceptionHandler
|
import org.moire.ultrasonic.util.SubsonicUncaughtExceptionHandler
|
||||||
import org.moire.ultrasonic.util.ThemeChangedEventDistributor
|
import org.moire.ultrasonic.util.ThemeChangedEventDistributor
|
||||||
|
@ -66,7 +71,10 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
private var navigationView: NavigationView? = null
|
private var navigationView: NavigationView? = null
|
||||||
private var drawerLayout: DrawerLayout? = null
|
private var drawerLayout: DrawerLayout? = null
|
||||||
private var host: NavHostFragment? = null
|
private var host: NavHostFragment? = null
|
||||||
private var selectServerButton: Button? = null
|
private var selectServerButton: MaterialButton? = null
|
||||||
|
private var headerBackgroundImage: ImageView? = null
|
||||||
|
private var ultrasonicLogoImage: ImageView? = null
|
||||||
|
private var ultrasonicNameText: TextView? = null
|
||||||
|
|
||||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||||
private lateinit var nowPlayingEventListener: NowPlayingEventListener
|
private lateinit var nowPlayingEventListener: NowPlayingEventListener
|
||||||
|
@ -189,17 +197,35 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
this,
|
this,
|
||||||
{ count ->
|
{ count ->
|
||||||
cachedServerCount = count ?: 0
|
cachedServerCount = count ?: 0
|
||||||
setSelectServerButtonText()
|
updateNavigationHeaderForServer()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ActiveServerProvider.liveActiveServerId.observe(this, { setSelectServerButtonText() })
|
ActiveServerProvider.liveActiveServerId.observe(this, { updateNavigationHeaderForServer() })
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setSelectServerButtonText() {
|
private fun updateNavigationHeaderForServer() {
|
||||||
val activeServerName = activeServerProvider.getActiveServer().name
|
val activeServer = activeServerProvider.getActiveServer()
|
||||||
|
|
||||||
if (cachedServerCount == 0)
|
if (cachedServerCount == 0)
|
||||||
selectServerButton?.text = getString(R.string.main_setup_server, activeServerName)
|
selectServerButton?.text = getString(R.string.main_setup_server, activeServer.name)
|
||||||
else selectServerButton?.text = activeServerName
|
else selectServerButton?.text = activeServer.name
|
||||||
|
|
||||||
|
val foregroundColor = ServerColor.getForegroundColor(this, activeServer.color)
|
||||||
|
val backgroundColor = ServerColor.getBackgroundColor(this, activeServer.color)
|
||||||
|
|
||||||
|
if (activeServer.index == 0)
|
||||||
|
selectServerButton?.icon =
|
||||||
|
ContextCompat.getDrawable(this, R.drawable.ic_menu_screen_on_off_dark)
|
||||||
|
else
|
||||||
|
selectServerButton?.icon =
|
||||||
|
ContextCompat.getDrawable(this, R.drawable.ic_menu_select_server_dark)
|
||||||
|
|
||||||
|
selectServerButton?.iconTint = ColorStateList.valueOf(foregroundColor)
|
||||||
|
ultrasonicLogoImage?.imageTintList = ColorStateList.valueOf(foregroundColor)
|
||||||
|
|
||||||
|
selectServerButton?.setTextColor(foregroundColor)
|
||||||
|
ultrasonicNameText?.setTextColor(foregroundColor)
|
||||||
|
headerBackgroundImage?.setBackgroundColor(backgroundColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
|
@ -260,6 +286,12 @@ class NavigationActivity : AppCompatActivity() {
|
||||||
this.drawerLayout?.closeDrawer(GravityCompat.START)
|
this.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||||
navController.navigate(R.id.serverSelectorFragment)
|
navController.navigate(R.id.serverSelectorFragment)
|
||||||
}
|
}
|
||||||
|
headerBackgroundImage =
|
||||||
|
navigationView?.getHeaderView(0)?.findViewById(R.id.img_header_bg)
|
||||||
|
ultrasonicLogoImage =
|
||||||
|
navigationView?.getHeaderView(0)?.findViewById(R.id.img_profile)
|
||||||
|
ultrasonicNameText =
|
||||||
|
navigationView?.getHeaderView(0)?.findViewById(R.id.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupActionBar(navController: NavController, appBarConfig: AppBarConfiguration) {
|
private fun setupActionBar(navController: NavController, appBarConfig: AppBarConfiguration) {
|
||||||
|
|
|
@ -73,10 +73,8 @@ internal class FilePickerAdapter : RecyclerView.Adapter<FilePickerAdapter.FileLi
|
||||||
var fileList = LinkedList<FileListItem>()
|
var fileList = LinkedList<FileListItem>()
|
||||||
var storages: List<File>? = null
|
var storages: List<File>? = null
|
||||||
var storagePaths: List<String>? = null
|
var storagePaths: List<String>? = null
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
|
||||||
storages = context!!.getExternalFilesDirs(null).filterNotNull()
|
storages = context!!.getExternalFilesDirs(null).filterNotNull()
|
||||||
storagePaths = storages.map { i -> i.absolutePath }
|
storagePaths = storages.map { i -> i.absolutePath }
|
||||||
}
|
|
||||||
|
|
||||||
if (currentDirectory.absolutePath == "/" ||
|
if (currentDirectory.absolutePath == "/" ||
|
||||||
currentDirectory.absolutePath == "/storage" ||
|
currentDirectory.absolutePath == "/storage" ||
|
||||||
|
@ -84,13 +82,8 @@ internal class FilePickerAdapter : RecyclerView.Adapter<FilePickerAdapter.FileLi
|
||||||
currentDirectory.absolutePath == "/mnt"
|
currentDirectory.absolutePath == "/mnt"
|
||||||
) {
|
) {
|
||||||
isRealDirectory = false
|
isRealDirectory = false
|
||||||
fileList = if (
|
fileList =
|
||||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT
|
|
||||||
) {
|
|
||||||
getKitKatStorageItems(storages!!)
|
getKitKatStorageItems(storages!!)
|
||||||
} else {
|
|
||||||
getStorageItems()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
isRealDirectory = true
|
isRealDirectory = true
|
||||||
val files = currentDirectory.listFiles()
|
val files = currentDirectory.listFiles()
|
||||||
|
@ -129,14 +122,10 @@ internal class FilePickerAdapter : RecyclerView.Adapter<FilePickerAdapter.FileLi
|
||||||
if (currentDirectory.absolutePath != "/" && isRealDirectory) {
|
if (currentDirectory.absolutePath != "/" && isRealDirectory) {
|
||||||
// If we are on KitKat or later, only the default App folder is usable, so we can't
|
// If we are on KitKat or later, only the default App folder is usable, so we can't
|
||||||
// navigate the SD card. Jump to the root if "Up" is selected.
|
// navigate the SD card. Jump to the root if "Up" is selected.
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
|
||||||
if (storagePaths!!.indexOf(currentDirectory.absolutePath) > 0)
|
if (storagePaths!!.indexOf(currentDirectory.absolutePath) > 0)
|
||||||
data.add(0, FileListItem(File("/"), "..", upIcon!!))
|
data.add(0, FileListItem(File("/"), "..", upIcon!!))
|
||||||
else
|
else
|
||||||
data.add(0, FileListItem(selectedDirectory.parentFile!!, "..", upIcon!!))
|
data.add(0, FileListItem(selectedDirectory.parentFile!!, "..", upIcon!!))
|
||||||
} else {
|
|
||||||
data.add(0, FileListItem(selectedDirectory.parentFile!!, "..", upIcon!!))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
|
|
|
@ -65,10 +65,6 @@ class BitmapUtils {
|
||||||
opt.inPreferQualityOverSpeed = true
|
opt.inPreferQualityOverSpeed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
opt.inPurgeable = true
|
|
||||||
}
|
|
||||||
|
|
||||||
opt.inSampleSize = Util.calculateInSampleSize(
|
opt.inSampleSize = Util.calculateInSampleSize(
|
||||||
opt,
|
opt,
|
||||||
size,
|
size,
|
||||||
|
@ -103,10 +99,6 @@ class BitmapUtils {
|
||||||
opt.inPreferQualityOverSpeed = true
|
opt.inPreferQualityOverSpeed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
|
|
||||||
opt.inPurgeable = true
|
|
||||||
}
|
|
||||||
|
|
||||||
opt.inSampleSize = Util.calculateInSampleSize(
|
opt.inSampleSize = Util.calculateInSampleSize(
|
||||||
opt,
|
opt,
|
||||||
size,
|
size,
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
/*
|
||||||
|
* ServerColor.kt
|
||||||
|
* Copyright (C) 2009-2021 Ultrasonic developers
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GNU GPLv3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.moire.ultrasonic.util
|
package org.moire.ultrasonic.util
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
@ -7,6 +14,9 @@ import org.moire.ultrasonic.R
|
||||||
|
|
||||||
private const val LUMINANCE_LIMIT = 0.25
|
private const val LUMINANCE_LIMIT = 0.25
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains functions for computing server display colors
|
||||||
|
*/
|
||||||
object ServerColor {
|
object ServerColor {
|
||||||
fun getBackgroundColor(context: Context, serverColor: Int?): Int {
|
fun getBackgroundColor(context: Context, serverColor: Int?): Int {
|
||||||
return serverColor ?: ContextCompat.getColor(
|
return serverColor ?: ContextCompat.getColor(
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
xmlns:a="http://schemas.android.com/apk/res/android"
|
xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
a:id="@+id/view_container"
|
a:id="@+id/view_container"
|
||||||
a:layout_width="match_parent"
|
a:layout_width="match_parent"
|
||||||
a:layout_height="wrap_content"
|
a:layout_height="wrap_content"
|
||||||
|
@ -13,9 +14,9 @@
|
||||||
a:layout_width="match_parent"
|
a:layout_width="match_parent"
|
||||||
a:layout_height="0dp"
|
a:layout_height="0dp"
|
||||||
a:scaleType="fitXY"
|
a:scaleType="fitXY"
|
||||||
a:src="?attr/color_navigation_header_background"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
a:id="@+id/img_profile"
|
a:id="@+id/img_profile"
|
||||||
|
@ -25,9 +26,10 @@
|
||||||
a:layout_marginLeft="16dp"
|
a:layout_marginLeft="16dp"
|
||||||
a:layout_marginTop="32dp"
|
a:layout_marginTop="32dp"
|
||||||
a:src="@drawable/ic_stat_ultrasonic"
|
a:src="@drawable/ic_stat_ultrasonic"
|
||||||
app:tint="?attr/colorOnPrimary"
|
tools:tint="@color/selected_menu_dark"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
a:id="@+id/name"
|
a:id="@+id/name"
|
||||||
|
@ -39,6 +41,7 @@
|
||||||
a:text="@string/common.appname"
|
a:text="@string/common.appname"
|
||||||
a:textAppearance="@style/TextAppearance.AppCompat.Title"
|
a:textAppearance="@style/TextAppearance.AppCompat.Title"
|
||||||
a:textColor="?attr/colorOnPrimary"
|
a:textColor="?attr/colorOnPrimary"
|
||||||
|
tools:textColor="@color/selected_menu_dark"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/img_profile"
|
app:layout_constraintBottom_toBottomOf="@+id/img_profile"
|
||||||
app:layout_constraintStart_toEndOf="@+id/img_profile"
|
app:layout_constraintStart_toEndOf="@+id/img_profile"
|
||||||
app:layout_constraintTop_toTopOf="@+id/img_profile" />
|
app:layout_constraintTop_toTopOf="@+id/img_profile" />
|
||||||
|
@ -53,16 +56,25 @@
|
||||||
a:textSize="14sp"
|
a:textSize="14sp"
|
||||||
app:icon="@drawable/ic_menu_select_server_dark"
|
app:icon="@drawable/ic_menu_select_server_dark"
|
||||||
app:iconPadding="16dp"
|
app:iconPadding="16dp"
|
||||||
app:iconTint="?attr/colorOnPrimary"
|
a:paddingHorizontal="22dp"
|
||||||
a:paddingTop="16dp"
|
a:paddingTop="14dp"
|
||||||
a:paddingBottom="16dp"
|
a:paddingBottom="14dp"
|
||||||
a:paddingStart="22dp"
|
|
||||||
a:paddingEnd="22dp"
|
|
||||||
a:text="@string/main.offline"
|
a:text="@string/main.offline"
|
||||||
a:textColor="?attr/colorOnPrimary"
|
a:textColor="?attr/colorOnPrimary"
|
||||||
a:background="@drawable/default_ripple"
|
a:background="@drawable/default_ripple"
|
||||||
|
tools:iconTint="@color/selected_menu_dark"
|
||||||
|
tools:textColor="@color/selected_menu_dark"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/img_profile" />
|
app:layout_constraintTop_toBottomOf="@+id/img_profile" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
a:id="@+id/img_shadow"
|
||||||
|
a:layout_width="match_parent"
|
||||||
|
a:layout_height="6dp"
|
||||||
|
a:layout_marginTop="-6dp"
|
||||||
|
a:scaleType="fitXY"
|
||||||
|
a:src="@drawable/drop_shadow"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/header_select_server" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -1,9 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<ScrollView xmlns:a="http://schemas.android.com/apk/res/android"
|
<ScrollView xmlns:a="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
a:layout_width="match_parent"
|
a:layout_width="match_parent"
|
||||||
a:layout_height="match_parent"
|
a:layout_height="match_parent"
|
||||||
a:fillViewport="true" >
|
a:fillViewport="true">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
a:layout_width="match_parent"
|
a:layout_width="match_parent"
|
||||||
|
@ -64,7 +65,7 @@
|
||||||
a:src="@drawable/rounded_border"
|
a:src="@drawable/rounded_border"
|
||||||
app:layout_constraintTop_toBottomOf="@id/edit_server_address"
|
app:layout_constraintTop_toBottomOf="@id/edit_server_address"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
/>
|
tools:ignore="ContentDescription" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
a:id="@+id/edit_authentication_header"
|
a:id="@+id/edit_authentication_header"
|
||||||
|
|
Loading…
Reference in New Issue