diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 9fb0b25ed..c0e8561ca 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -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() { diff --git a/app/src/main/java/org/oxycblt/auxio/list/recycler/DialogRecyclerView.kt b/app/src/main/java/org/oxycblt/auxio/list/recycler/DialogRecyclerView.kt index 90a5786f6..9fc255ce1 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/recycler/DialogRecyclerView.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/recycler/DialogRecyclerView.kt @@ -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. diff --git a/app/src/main/java/org/oxycblt/auxio/list/sort/SortAdapter.kt b/app/src/main/java/org/oxycblt/auxio/list/sort/SortAdapter.kt new file mode 100644 index 000000000..16ac05fd2 --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/list/sort/SortAdapter.kt @@ -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 . + */ + +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(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) { + 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() { + override fun areItemsTheSame(oldItem: Sort.Mode, newItem: Sort.Mode) = + oldItem == newItem + + override fun areContentsTheSame(oldItem: Sort.Mode, newItem: Sort.Mode) = + oldItem == newItem + } + } +} diff --git a/app/src/main/java/org/oxycblt/auxio/list/sort/SortDialog.kt b/app/src/main/java/org/oxycblt/auxio/list/sort/SortDialog.kt new file mode 100644 index 000000000..79bd9082b --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/list/sort/SortDialog.kt @@ -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 . + */ + +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() { + 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) + } +} diff --git a/app/src/main/res/layout/dialog_menu.xml b/app/src/main/res/layout/dialog_menu.xml index b38f3938f..1a5a7a605 100644 --- a/app/src/main/res/layout/dialog_menu.xml +++ b/app/src/main/res/layout/dialog_menu.xml @@ -13,7 +13,7 @@ + android:layout_height="wrap_content"> \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_music_dirs.xml b/app/src/main/res/layout/dialog_music_dirs.xml index 49458926a..fa48b8a9c 100644 --- a/app/src/main/res/layout/dialog_music_dirs.xml +++ b/app/src/main/res/layout/dialog_music_dirs.xml @@ -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" diff --git a/app/src/main/res/layout/dialog_sort.xml b/app/src/main/res/layout/dialog_sort.xml new file mode 100644 index 000000000..547c7476d --- /dev/null +++ b/app/src/main/res/layout/dialog_sort.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_sort_mode.xml b/app/src/main/res/layout/item_sort_mode.xml new file mode 100644 index 000000000..91638968e --- /dev/null +++ b/app/src/main/res/layout/item_sort_mode.xml @@ -0,0 +1,29 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/navigation/inner.xml b/app/src/main/res/navigation/inner.xml index fa9520ec3..f782d8456 100644 --- a/app/src/main/res/navigation/inner.xml +++ b/app/src/main/res/navigation/inner.xml @@ -162,6 +162,9 @@ + + + \ No newline at end of file