Heavily improve dialogs
Both improve and use dialogs - The AlertDialog style now properly colors dialogs with the primary coler - The accent & blacklist dialogs are now based on AlertDialog for their buttons, reducing layout complexity
This commit is contained in:
parent
53ec1aa8a5
commit
4d92df7896
8 changed files with 72 additions and 122 deletions
|
@ -4,6 +4,9 @@ import android.net.Uri
|
|||
|
||||
// --- MUSIC MODELS ---
|
||||
|
||||
// TODO: Implement some kind of hash system, removing the need to redundant names but alsow without the volitility of id
|
||||
// They need to be completely unique, however, and from whatever information I have about them.
|
||||
|
||||
/**
|
||||
* The base data object for all music.
|
||||
* @property id The ID that is assigned to this object
|
||||
|
@ -51,7 +54,7 @@ data class Song(
|
|||
val album: Album get() = requireNotNull(mAlbum)
|
||||
|
||||
val seconds = duration / 1000
|
||||
val formattedDuration: String = seconds.toDuration()
|
||||
val formattedDuration = seconds.toDuration()
|
||||
|
||||
fun linkAlbum(album: Album) {
|
||||
if (mAlbum == null) {
|
||||
|
|
|
@ -4,13 +4,13 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import org.oxycblt.auxio.databinding.DialogAccentBinding
|
||||
import org.oxycblt.auxio.logD
|
||||
import org.oxycblt.auxio.settings.SettingsManager
|
||||
import org.oxycblt.auxio.settings.ui.LifecycleDialog
|
||||
import org.oxycblt.auxio.ui.ACCENTS
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.inflater
|
||||
import org.oxycblt.auxio.ui.toColor
|
||||
|
||||
/**
|
||||
|
@ -38,25 +38,11 @@ class AccentDialog : LifecycleDialog() {
|
|||
adapter = AccentAdapter(pendingAccent) { accent ->
|
||||
pendingAccent = accent
|
||||
|
||||
updateAccent(binding)
|
||||
updateAccent()
|
||||
}
|
||||
}
|
||||
|
||||
binding.accentConfirm.setOnClickListener {
|
||||
if (pendingAccent != Accent.get()) {
|
||||
settingsManager.accent = pendingAccent
|
||||
|
||||
requireActivity().recreate()
|
||||
}
|
||||
|
||||
dismiss()
|
||||
}
|
||||
|
||||
binding.accentCancel.setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
|
||||
updateAccent(binding)
|
||||
updateAccent()
|
||||
|
||||
logD("Dialog created.")
|
||||
|
||||
|
@ -69,11 +55,28 @@ class AccentDialog : LifecycleDialog() {
|
|||
outState.putInt(KEY_PENDING_ACCENT, ACCENTS.indexOf(pendingAccent))
|
||||
}
|
||||
|
||||
private fun updateAccent(binding: DialogAccentBinding) {
|
||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
||||
builder.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
if (pendingAccent != Accent.get()) {
|
||||
settingsManager.accent = pendingAccent
|
||||
|
||||
requireActivity().recreate()
|
||||
}
|
||||
|
||||
dismiss()
|
||||
}
|
||||
|
||||
// Negative button just dismisses, no need for a listener.
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
}
|
||||
|
||||
private fun updateAccent() {
|
||||
val accentColor = pendingAccent.color.toColor(requireContext())
|
||||
|
||||
binding.accentCancel.setTextColor(accentColor)
|
||||
binding.accentConfirm.setTextColor(accentColor)
|
||||
(requireDialog() as AlertDialog).apply {
|
||||
getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor)
|
||||
getButton(AlertDialog.BUTTON_NEGATIVE)?.setTextColor(accentColor)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.fragment.app.viewModels
|
||||
|
@ -19,9 +20,7 @@ import org.oxycblt.auxio.databinding.DialogBlacklistBinding
|
|||
import org.oxycblt.auxio.logD
|
||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||
import org.oxycblt.auxio.settings.ui.LifecycleDialog
|
||||
import org.oxycblt.auxio.ui.Accent
|
||||
import org.oxycblt.auxio.ui.createToast
|
||||
import org.oxycblt.auxio.ui.toColor
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
/**
|
||||
|
@ -42,43 +41,30 @@ class BlacklistDialog : LifecycleDialog() {
|
|||
): View {
|
||||
val binding = DialogBlacklistBinding.inflate(inflater)
|
||||
|
||||
val launcher = registerForActivityResult(
|
||||
ActivityResultContracts.OpenDocumentTree(), ::addDocTreePath
|
||||
)
|
||||
|
||||
val accent = Accent.get().color.toColor(requireContext())
|
||||
|
||||
val adapter = BlacklistEntryAdapter { path ->
|
||||
blacklistModel.removePath(path)
|
||||
}
|
||||
|
||||
val launcher = registerForActivityResult(
|
||||
ActivityResultContracts.OpenDocumentTree(), ::addDocTreePath
|
||||
)
|
||||
|
||||
// --- UI SETUP ---
|
||||
|
||||
binding.blacklistRecycler.adapter = adapter
|
||||
|
||||
// Dialogs don't know how to into theming, so I have to manually set the accent color
|
||||
// to each of the buttons since the overall fragment theme is Neutral.
|
||||
binding.blacklistAdd.apply {
|
||||
setTextColor(accent)
|
||||
// Now that the dialog exists, we get the view manually when the dialog is shown
|
||||
// and override its click-listener so that the dialog does not auto-dismiss when we
|
||||
// click the "Add"/"Save" buttons. This prevents the dialog from disappearing in the former
|
||||
// and the app from crashing in the latter.
|
||||
val dialog = requireDialog() as AlertDialog
|
||||
|
||||
setOnClickListener {
|
||||
// showFileDialog()
|
||||
dialog.setOnShowListener {
|
||||
dialog.getButton(AlertDialog.BUTTON_NEUTRAL)?.setOnClickListener {
|
||||
launcher.launch(null)
|
||||
}
|
||||
}
|
||||
|
||||
binding.blacklistCancel.apply {
|
||||
setTextColor(accent)
|
||||
|
||||
setOnClickListener {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
binding.blacklistConfirm.apply {
|
||||
setTextColor(accent)
|
||||
|
||||
setOnClickListener {
|
||||
dialog.getButton(AlertDialog.BUTTON_POSITIVE)?.setOnClickListener {
|
||||
if (blacklistModel.isModified()) {
|
||||
saveAndRestart()
|
||||
} else {
|
||||
|
@ -107,6 +93,13 @@ class BlacklistDialog : LifecycleDialog() {
|
|||
blacklistModel.loadDatabasePaths()
|
||||
}
|
||||
|
||||
override fun onConfigDialog(builder: AlertDialog.Builder) {
|
||||
// Dont set the click listener here, we do some custom black magic in onCreateView instead.
|
||||
builder.setNeutralButton(R.string.label_add, null)
|
||||
builder.setPositiveButton(R.string.label_save, null)
|
||||
builder.setNegativeButton(android.R.string.cancel, null)
|
||||
}
|
||||
|
||||
private fun addDocTreePath(uri: Uri?) {
|
||||
uri ?: return
|
||||
|
||||
|
|
|
@ -5,15 +5,19 @@ import android.os.Bundle
|
|||
import android.view.View
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* [DialogFragment] that replicates the Fragment lifecycle in regards to [AlertDialog], which
|
||||
* doesn't seem to set the view from onCreateView correctly.
|
||||
* A wrapper around [DialogFragment] that allows the usage of the standard Auxio lifecycle
|
||||
* override [onCreateView] and [onDestroyView], but with a proper dialog being created.
|
||||
*/
|
||||
abstract class LifecycleDialog : DialogFragment() {
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
return MaterialAlertDialogBuilder(requireActivity(), theme).create()
|
||||
val builder = AlertDialog.Builder(requireActivity(), R.style.Theme_CustomDialog)
|
||||
|
||||
onConfigDialog(builder)
|
||||
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
@ -21,4 +25,6 @@ abstract class LifecycleDialog : DialogFragment() {
|
|||
|
||||
(requireDialog() as AlertDialog).setView(view)
|
||||
}
|
||||
|
||||
protected open fun onConfigDialog(builder: AlertDialog.Builder) {}
|
||||
}
|
||||
|
|
|
@ -36,28 +36,5 @@
|
|||
tools:itemCount="18"
|
||||
tools:listitem="@layout/item_accent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:padding="@dimen/padding_small">
|
||||
|
||||
<Button
|
||||
android:id="@+id/accent_cancel"
|
||||
style="@style/Widget.Button.Dialog"
|
||||
android:layout_marginEnd="@dimen/margin_small"
|
||||
android:text="@android:string/cancel"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/accent_confirm" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/accent_confirm"
|
||||
style="@style/Widget.Button.Dialog"
|
||||
android:text="@android:string/ok"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/accent_cancel"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/accent_cancel" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -44,37 +44,5 @@
|
|||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:textColor="?android:attr/textColorSecondary" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom"
|
||||
android:padding="@dimen/padding_small">
|
||||
|
||||
<Button
|
||||
android:id="@+id/blacklist_cancel"
|
||||
style="@style/Widget.Button.Dialog"
|
||||
android:layout_marginEnd="@dimen/padding_small"
|
||||
android:text="@android:string/cancel"
|
||||
app:layout_constraintEnd_toStartOf="@+id/blacklist_confirm"
|
||||
app:layout_constraintTop_toTopOf="@+id/blacklist_add" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/blacklist_confirm"
|
||||
style="@style/Widget.Button.Dialog"
|
||||
android:text="@string/label_save"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/blacklist_cancel"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/blacklist_cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/blacklist_add"
|
||||
style="@style/Widget.Button.Dialog"
|
||||
android:text="@string/label_add"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</layout>
|
|
@ -104,6 +104,7 @@
|
|||
<string name="error_load_failed">Laden die Musik fehlgeschlagen</string>
|
||||
<string name="error_no_perms">Auxio braucht Berechtigung, zu lesen deine Musikbibliothek</string>
|
||||
<string name="error_no_browser">Link könnte nicht geöffnet werden</string>
|
||||
<string name="error_bad_dir">Das Verzeichnis ist nicht gestützt</string>
|
||||
|
||||
<!-- Hint Namespace | EditText Hints -->
|
||||
<string name="hint_search_library">Durchsuche deine Musikbibliothek…</string>
|
||||
|
|
|
@ -79,11 +79,10 @@
|
|||
</style>
|
||||
|
||||
<!-- Custom Dialog EntryNames -->
|
||||
<style name="Theme.CustomDialog" parent="Theme.MaterialComponents.DayNight.Dialog">
|
||||
<item name="colorBackgroundFloating">@color/background</item>
|
||||
<style name="Theme.CustomDialog" parent="ThemeOverlay.AppCompat.Dialog.Alert">
|
||||
<item name="android:windowTitleStyle">@style/TextAppearance.Dialog.Title</item>
|
||||
<item name="colorPrimary">@color/control_color</item>
|
||||
<item name="colorSecondary">@color/control_color</item>
|
||||
<item name="colorBackgroundFloating">@color/background</item>
|
||||
<item name="buttonBarButtonStyle">@style/Widget.Button.Dialog</item>
|
||||
<item name="dialogCornerRadius">0dp</item>
|
||||
<item name="colorControlHighlight">@color/selection_color</item>
|
||||
</style>
|
||||
|
@ -93,6 +92,17 @@
|
|||
<item name="android:fontFamily">@font/inter_exbold</item>
|
||||
</style>
|
||||
|
||||
<!-- Style for dialog buttons -->
|
||||
<style name="Widget.Button.Dialog" parent="Widget.AppCompat.Button.ButtonBar.AlertDialog">
|
||||
<item name="android:layout_height">@dimen/height_dialog_button</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:paddingStart">@dimen/padding_mid_small</item>
|
||||
<item name="android:paddingEnd">@dimen/padding_mid_small</item>
|
||||
<item name="android:minWidth">@dimen/width_dialog_button_min</item>
|
||||
<item name="android:textColor">?attr/colorPrimary</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
</style>
|
||||
|
||||
<!-- Style for the general item background -->
|
||||
<style name="ItemSurroundings">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
|
@ -217,15 +227,4 @@
|
|||
<item name="android:scaleType">fitCenter</item>
|
||||
<item name="android:padding">@dimen/padding_medium</item>
|
||||
</style>
|
||||
|
||||
<!-- Style for dialog buttons -->
|
||||
<style name="Widget.Button.Dialog" parent="Widget.AppCompat.Button">
|
||||
<item name="android:layout_height">@dimen/height_dialog_button</item>
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:paddingStart">@dimen/padding_mid_small</item>
|
||||
<item name="android:paddingEnd">@dimen/padding_mid_small</item>
|
||||
<item name="android:minWidth">@dimen/width_dialog_button_min</item>
|
||||
<item name="android:background">@drawable/ui_ripple</item>
|
||||
<item name="android:fontFamily">@font/inter_semibold</item>
|
||||
</style>
|
||||
</resources>
|
Loading…
Reference in a new issue