weather: introduce display precipitation
Introduce a new datatype called DisplayPrecipitation that optimizes the precipitation level for UI display. This is primarily meant to fix improper precipitation displays when values lower than 0.1 in are shown, albiet that may need to change eventually.
This commit is contained in:
parent
5ed69e8b72
commit
48655360d4
9 changed files with 314 additions and 38 deletions
|
|
@ -41,7 +41,6 @@ import org.oxycblt.auxio.list.Item
|
|||
import org.oxycblt.auxio.list.ListFragment
|
||||
import org.oxycblt.auxio.list.ListViewModel
|
||||
import org.oxycblt.auxio.list.Menu
|
||||
import org.oxycblt.auxio.list.Sort
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Music
|
||||
import org.oxycblt.auxio.music.MusicParent
|
||||
|
|
@ -195,30 +194,34 @@ class AlbumDetailFragment :
|
|||
}
|
||||
|
||||
override fun onOpenSortMenu(anchor: View) {
|
||||
openMenu(anchor, R.menu.sort_album) {
|
||||
// Select the corresponding sort mode option
|
||||
val sort = detailModel.albumSongSort
|
||||
unlikelyToBeNull(menu.findItem(sort.mode.itemId)).isChecked = true
|
||||
// Select the corresponding sort direction option
|
||||
val directionItemId =
|
||||
when (sort.direction) {
|
||||
Sort.Direction.ASCENDING -> R.id.option_sort_asc
|
||||
Sort.Direction.DESCENDING -> R.id.option_sort_dec
|
||||
}
|
||||
unlikelyToBeNull(menu.findItem(directionItemId)).isChecked = true
|
||||
setOnMenuItemClickListener { item ->
|
||||
item.isChecked = !item.isChecked
|
||||
detailModel.albumSongSort =
|
||||
when (item.itemId) {
|
||||
// Sort direction options
|
||||
R.id.option_sort_asc -> sort.withDirection(Sort.Direction.ASCENDING)
|
||||
R.id.option_sort_dec -> sort.withDirection(Sort.Direction.DESCENDING)
|
||||
// Any other option is a sort mode
|
||||
else -> sort.withMode(unlikelyToBeNull(Sort.Mode.fromItemId(item.itemId)))
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
findNavController().navigateSafe(AlbumDetailFragmentDirections.sort())
|
||||
// openMenu(anchor, R.menu.sort_album) {
|
||||
// // Select the corresponding sort mode option
|
||||
// val sort = detailModel.albumSongSort
|
||||
// unlikelyToBeNull(menu.findItem(sort.mode.itemId)).isChecked = true
|
||||
// // Select the corresponding sort direction option
|
||||
// val directionItemId =
|
||||
// when (sort.direction) {
|
||||
// Sort.Direction.ASCENDING -> R.id.option_sort_asc
|
||||
// Sort.Direction.DESCENDING -> R.id.option_sort_dec
|
||||
// }
|
||||
// unlikelyToBeNull(menu.findItem(directionItemId)).isChecked = true
|
||||
// setOnMenuItemClickListener { item ->
|
||||
// item.isChecked = !item.isChecked
|
||||
// detailModel.albumSongSort =
|
||||
// when (item.itemId) {
|
||||
// // Sort direction options
|
||||
// R.id.option_sort_asc ->
|
||||
// sort.withDirection(Sort.Direction.ASCENDING)
|
||||
// R.id.option_sort_dec ->
|
||||
// sort.withDirection(Sort.Direction.DESCENDING)
|
||||
// // Any other option is a sort mode
|
||||
// else ->
|
||||
// sort.withMode(unlikelyToBeNull(Sort.Mode.fromItemId(item.itemId)))
|
||||
// }
|
||||
// true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onNavigateToParentArtist() {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import android.content.Context
|
|||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowInsets
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.updatePadding
|
||||
|
|
@ -32,7 +31,6 @@ import com.google.android.material.divider.MaterialDivider
|
|||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.list.recycler.DialogRecyclerView.ViewHolder
|
||||
import org.oxycblt.auxio.util.getDimenPixels
|
||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
|
||||
/**
|
||||
* A [RecyclerView] intended for use in Dialogs, adding features such as:
|
||||
|
|
@ -76,13 +74,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
|||
invalidateDividers()
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(insets: WindowInsets): WindowInsets {
|
||||
// Update the RecyclerView's padding such that the bottom insets are applied
|
||||
// while still preserving bottom padding.
|
||||
updatePadding(bottom = insets.systemBarInsetsCompat.bottom)
|
||||
return insets
|
||||
}
|
||||
|
||||
override fun onScrolled(dx: Int, dy: Int) {
|
||||
super.onScrolled(dx, dy)
|
||||
// Scroll event occurred, need to update the dividers.
|
||||
|
|
|
|||
88
app/src/main/java/org/oxycblt/auxio/list/sort/SortAdapter.kt
Normal file
88
app/src/main/java/org/oxycblt/auxio/list/sort/SortAdapter.kt
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
* SortAdapter.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.list.sort
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.oxycblt.auxio.databinding.ItemSortModeBinding
|
||||
import org.oxycblt.auxio.list.Sort
|
||||
import org.oxycblt.auxio.list.adapter.FlexibleListAdapter
|
||||
import org.oxycblt.auxio.util.inflater
|
||||
|
||||
class SortAdapter(var selectedMode: Sort.Mode) :
|
||||
FlexibleListAdapter<Sort.Mode, SortModeViewHolder>(SortModeViewHolder.DIFF_CALLBACK) {
|
||||
var currentlySelected = selectedMode
|
||||
private set
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
|
||||
SortModeViewHolder.from(parent)
|
||||
|
||||
override fun onBindViewHolder(holder: SortModeViewHolder, position: Int) {
|
||||
throw NotImplementedError()
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SortModeViewHolder, position: Int, payload: List<Any>) {
|
||||
val mode = getItem(position)
|
||||
if (payload.isEmpty()) {
|
||||
holder.bind(mode)
|
||||
}
|
||||
holder.setSelected(mode == currentlySelected)
|
||||
}
|
||||
|
||||
fun setSelected(mode: Sort.Mode) {
|
||||
if (mode == currentlySelected) return
|
||||
val oldMode = currentList.indexOf(currentlySelected)
|
||||
val newMode = currentList.indexOf(mode)
|
||||
currentlySelected = selectedMode
|
||||
notifyItemChanged(oldMode, PAYLOAD_SELECTION_CHANGED)
|
||||
notifyItemChanged(newMode, PAYLOAD_SELECTION_CHANGED)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
val PAYLOAD_SELECTION_CHANGED = Any()
|
||||
}
|
||||
}
|
||||
|
||||
class SortModeViewHolder private constructor(private val binding: ItemSortModeBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(mode: Sort.Mode) {
|
||||
// TODO: Add names to sort.mode
|
||||
binding.sortRadio.text = mode.toString()
|
||||
}
|
||||
|
||||
fun setSelected(selected: Boolean) {
|
||||
binding.sortRadio.isChecked = selected
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun from(parent: View) =
|
||||
SortModeViewHolder(ItemSortModeBinding.inflate(parent.context.inflater))
|
||||
|
||||
val DIFF_CALLBACK =
|
||||
object : DiffUtil.ItemCallback<Sort.Mode>() {
|
||||
override fun areItemsTheSame(oldItem: Sort.Mode, newItem: Sort.Mode) =
|
||||
oldItem == newItem
|
||||
|
||||
override fun areContentsTheSame(oldItem: Sort.Mode, newItem: Sort.Mode) =
|
||||
oldItem == newItem
|
||||
}
|
||||
}
|
||||
}
|
||||
44
app/src/main/java/org/oxycblt/auxio/list/sort/SortDialog.kt
Normal file
44
app/src/main/java/org/oxycblt/auxio/list/sort/SortDialog.kt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Auxio Project
|
||||
* SortDialog.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.list.sort
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.core.view.updatePadding
|
||||
import org.oxycblt.auxio.databinding.DialogSortBinding
|
||||
import org.oxycblt.auxio.list.Sort
|
||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||
import org.oxycblt.auxio.ui.ViewBindingBottomSheetDialogFragment
|
||||
import org.oxycblt.auxio.util.systemBarInsetsCompat
|
||||
|
||||
class SortDialog : ViewBindingBottomSheetDialogFragment<DialogSortBinding>() {
|
||||
private val sortAdapter = SortAdapter(Sort.Mode.ByName)
|
||||
|
||||
override fun onCreateBinding(inflater: LayoutInflater) = DialogSortBinding.inflate(inflater)
|
||||
|
||||
override fun onBindingCreated(binding: DialogSortBinding, savedInstanceState: Bundle?) {
|
||||
super.onBindingCreated(binding, savedInstanceState)
|
||||
binding.root.setOnApplyWindowInsetsListener { v, insets ->
|
||||
v.updatePadding(bottom = insets.systemBarInsetsCompat.bottom)
|
||||
insets
|
||||
}
|
||||
binding.sortModeRecycler.adapter = sortAdapter
|
||||
sortAdapter.update(listOf(Sort.Mode.ByName, Sort.Mode.ByDate), UpdateInstructions.Diff)
|
||||
}
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:id="@+id/menu_handle"
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
tools:text="Info A" />
|
||||
|
||||
<com.google.android.material.divider.MaterialDivider
|
||||
android:id="@+id/menu_divider"
|
||||
android:id="@+id/menu_mode_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_medium"
|
||||
|
|
@ -85,6 +85,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/menu_divider"
|
||||
app:layout_constraintTop_toBottomOf="@+id/menu_mode_group"
|
||||
tools:listitem="@layout/item_menu_option" />
|
||||
</LinearLayout>
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/spacing_large"
|
||||
android:layout_marginTop="@dimen/spacing_small"
|
||||
android:layout_marginTop="@dimen/spacing_tiny"
|
||||
android:layout_marginEnd="@dimen/spacing_large"
|
||||
android:gravity="center"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dirs_mode_header"
|
||||
|
|
|
|||
112
app/src/main/res/layout/dialog_sort.xml
Normal file
112
app/src/main/res/layout/dialog_sort.xml
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<LinearLayout 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"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
|
||||
android:id="@+id/menu_handle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<!--
|
||||
Required to use a LinearLayout here for space allocation to stop the BottomSheetDialog
|
||||
from flipping out and not allowing the RecyclerView to scroll fully.
|
||||
-->
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sort_name"
|
||||
style="@style/Widget.Auxio.TextView.Primary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/spacing_medium"
|
||||
android:text="Sort By"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<org.oxycblt.auxio.list.recycler.DialogRecyclerView
|
||||
android:id="@+id/sort_mode_recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
style="@style/Widget.Auxio.RecyclerView.Linear"
|
||||
tools:listitem="@layout/item_sort_mode" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dirs_mode_header"
|
||||
style="@style/Widget.Auxio.TextView.Header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Direction"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
android:id="@+id/folder_mode_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/spacing_tiny"
|
||||
android:gravity="center"
|
||||
android:layout_marginHorizontal="@dimen/spacing_medium"
|
||||
app:checkedButton="@+id/dirs_mode_exclude"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dirs_mode_header"
|
||||
app:selectionRequired="true"
|
||||
app:singleSelection="true"
|
||||
tools:layout_editor_absoluteX="24dp">
|
||||
|
||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
||||
android:id="@+id/dirs_mode_exclude"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/lbl_sort_asc"
|
||||
tools:icon="@drawable/ic_check_24" />
|
||||
|
||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
||||
android:id="@+id/dirs_mode_include"
|
||||
style="@style/Widget.Material3.Button.OutlinedButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/lbl_sort_dec" />
|
||||
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/spacing_small"
|
||||
android:text="@string/lbl_cancel"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sort_save"
|
||||
app:layout_constraintEnd_toStartOf="@+id/sort_save"
|
||||
app:layout_constraintTop_toTopOf="@+id/sort_save" />
|
||||
|
||||
<org.oxycblt.auxio.ui.RippleFixMaterialButton
|
||||
android:id="@+id/sort_save"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="@dimen/spacing_medium"
|
||||
android:layout_marginBottom="@dimen/spacing_mid_medium"
|
||||
android:layout_marginTop="@dimen/spacing_mid_medium"
|
||||
android:text="@string/lbl_ok"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/folder_mode_group" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
29
app/src/main/res/layout/item_sort_mode.xml
Normal file
29
app/src/main/res/layout/item_sort_mode.xml
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="@dimen/spacing_tiny"
|
||||
android:paddingBottom="@dimen/spacing_tiny">
|
||||
|
||||
<com.google.android.material.radiobutton.MaterialRadioButton
|
||||
android:id="@+id/sort_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/spacing_mid_medium"
|
||||
android:layout_marginEnd="@dimen/spacing_mid_medium"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:drawableTint="?attr/colorControlNormal"
|
||||
android:paddingStart="@dimen/spacing_medium"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAppearance="@style/TextAppearance.Auxio.BodyLarge"
|
||||
tools:ignore="RtlSymmetry,contentDescription"
|
||||
tools:text="Name" />
|
||||
|
||||
</FrameLayout>
|
||||
|
|
@ -162,6 +162,9 @@
|
|||
<action
|
||||
android:id="@+id/play_from_genre"
|
||||
app:destination="@id/play_from_genre_dialog" />
|
||||
<action
|
||||
android:id="@+id/sort"
|
||||
app:destination="@id/sort_dialog" />
|
||||
</fragment>
|
||||
|
||||
<fragment
|
||||
|
|
@ -388,4 +391,10 @@
|
|||
android:name="parcel"
|
||||
app:argType="org.oxycblt.auxio.list.Menu$ForPlaylist$Parcel" />
|
||||
</dialog>
|
||||
|
||||
<dialog
|
||||
android:id="@+id/sort_dialog"
|
||||
android:name="org.oxycblt.auxio.list.sort.SortDialog"
|
||||
android:label="sort_dialog"
|
||||
tools:layout="@layout/dialog_sort" />
|
||||
</navigation>
|
||||
Loading…
Reference in a new issue