Merge branch 'dev' into feature/share

This commit is contained in:
Alexander Capehart 2023-05-24 15:49:53 +00:00 committed by GitHub
commit a5e01be34b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
106 changed files with 392 additions and 183 deletions

View file

@ -1,9 +1,9 @@
# Changelog # Changelog
## dev ## 3.1.0
#### What's New #### What's New
- **Playlists.** The long-awaited feature has arrived, with more functionality coming soon. - Added playlist functionality
#### What's Improved #### What's Improved
- Sorting now handles numbers of arbitrary length - Sorting now handles numbers of arbitrary length

View file

@ -2,8 +2,8 @@
<h1 align="center"><b>Auxio</b></h1> <h1 align="center"><b>Auxio</b></h1>
<h4 align="center">A simple, rational music player for android.</h4> <h4 align="center">A simple, rational music player for android.</h4>
<p align="center"> <p align="center">
<a href="https://github.com/oxygencobalt/Auxio/releases/tag/v3.0.5"> <a href="https://github.com/oxygencobalt/Auxio/releases/tag/v3.1.0">
<img alt="Latest Version" src="https://img.shields.io/static/v1?label=tag&message=v3.0.5&color=64B5F6&style=flat"> <img alt="Latest Version" src="https://img.shields.io/static/v1?label=tag&message=v3.1.0&color=64B5F6&style=flat">
</a> </a>
<a href="https://github.com/oxygencobalt/Auxio/releases/"> <a href="https://github.com/oxygencobalt/Auxio/releases/">
<img alt="Releases" src="https://img.shields.io/github/downloads/OxygenCobalt/Auxio/total.svg?color=4B95DE&style=flat"> <img alt="Releases" src="https://img.shields.io/github/downloads/OxygenCobalt/Auxio/total.svg?color=4B95DE&style=flat">
@ -21,7 +21,7 @@
## About ## About
Auxio is a local music player with a fast, reliable UI/UX without the many useless features present in other music players. Built off of <a href="https://exoplayer.dev/">Exoplayer</a>, Auxio has superior library support and listening quality compared to other apps that use outdated android functionality. In short, **It plays music.** Auxio is a local music player with a fast, reliable UI/UX without the many useless features present in other music players. Built off of [ExoPlayer](https://exoplayer.dev/), Auxio has superior library support and listening quality compared to other apps that use outdated android functionality. In short, **It plays music.**
I primarily built Auxio for myself, but you can use it too, I guess. I primarily built Auxio for myself, but you can use it too, I guess.
@ -42,7 +42,7 @@ I primarily built Auxio for myself, but you can use it too, I guess.
## Features ## Features
- [ExoPlayer](https://exoplayer.dev/) based playback - [ExoPlayer](https://exoplayer.dev/)-based playback
- Snappy UI derived from the latest Material Design guidelines - Snappy UI derived from the latest Material Design guidelines
- Opinionated UX that prioritizes ease of use over edge cases - Opinionated UX that prioritizes ease of use over edge cases
- Customizable behavior - Customizable behavior
@ -50,7 +50,8 @@ I primarily built Auxio for myself, but you can use it too, I guess.
precise/original dates, sort tags, and more precise/original dates, sort tags, and more
- Advanced artist system that unifies artists and album artists - Advanced artist system that unifies artists and album artists
- SD Card-aware folder management - SD Card-aware folder management
- Reliable playback state persistence - Reliable playlisting functionality
- Playback state persistence
- Full ReplayGain support (On MP3, FLAC, OGG, OPUS, and MP4 files) - Full ReplayGain support (On MP3, FLAC, OGG, OPUS, and MP4 files)
- External equalizer support (ex. Wavelet) - External equalizer support (ex. Wavelet)
- Edge-to-edge - Edge-to-edge

View file

@ -20,8 +20,8 @@ android {
defaultConfig { defaultConfig {
applicationId namespace applicationId namespace
versionName "3.0.5" versionName "3.1.0"
versionCode 29 versionCode 30
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33

View file

@ -16,8 +16,6 @@
package com.google.android.material.bottomsheet; package com.google.android.material.bottomsheet;
import com.google.android.material.R;
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
import static java.lang.Math.max; import static java.lang.Math.max;
import static java.lang.Math.min; import static java.lang.Math.min;
@ -44,6 +42,7 @@ import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams; import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewParent; import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import androidx.annotation.FloatRange; import androidx.annotation.FloatRange;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -63,11 +62,14 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.Accessibilit
import androidx.core.view.accessibility.AccessibilityViewCommand; import androidx.core.view.accessibility.AccessibilityViewCommand;
import androidx.customview.view.AbsSavedState; import androidx.customview.view.AbsSavedState;
import androidx.customview.widget.ViewDragHelper; import androidx.customview.widget.ViewDragHelper;
import com.google.android.material.R;
import com.google.android.material.internal.ViewUtils; import com.google.android.material.internal.ViewUtils;
import com.google.android.material.internal.ViewUtils.RelativePadding; import com.google.android.material.internal.ViewUtils.RelativePadding;
import com.google.android.material.resources.MaterialResources; import com.google.android.material.resources.MaterialResources;
import com.google.android.material.shape.MaterialShapeDrawable; import com.google.android.material.shape.MaterialShapeDrawable;
import com.google.android.material.shape.ShapeAppearanceModel; import com.google.android.material.shape.ShapeAppearanceModel;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;

View file

@ -16,20 +16,16 @@
package com.google.android.material.divider; package com.google.android.material.divider;
import com.google.android.material.R;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.ShapeDrawable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
import androidx.annotation.DimenRes; import androidx.annotation.DimenRes;
@ -39,6 +35,11 @@ import androidx.annotation.Px;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import com.google.android.material.R;
import com.google.android.material.internal.ThemeEnforcement; import com.google.android.material.internal.ThemeEnforcement;
import com.google.android.material.resources.MaterialResources; import com.google.android.material.resources.MaterialResources;

View file

@ -51,10 +51,8 @@ object IntegerTable {
const val VIEW_TYPE_DISC_HEADER = 0xA00B const val VIEW_TYPE_DISC_HEADER = 0xA00B
/** EditHeaderViewHolder */ /** EditHeaderViewHolder */
const val VIEW_TYPE_EDIT_HEADER = 0xA00C const val VIEW_TYPE_EDIT_HEADER = 0xA00C
/** ConfirmHeaderViewHolder */ /** PlaylistSongViewHolder */
const val VIEW_TYPE_CONFIRM_HEADER = 0xA00D const val VIEW_TYPE_PLAYLIST_SONG = 0xA00E
/** EditableSongViewHolder */
const val VIEW_TYPE_EDITABLE_SONG = 0xA00E
/** "Music playback" notification code */ /** "Music playback" notification code */
const val PLAYBACK_NOTIFICATION_CODE = 0xA0A0 const val PLAYBACK_NOTIFICATION_CODE = 0xA0A0
/** "Music loading" notification code */ /** "Music loading" notification code */

View file

@ -31,6 +31,7 @@ import androidx.navigation.NavController
import androidx.navigation.NavDestination import androidx.navigation.NavDestination
import androidx.navigation.findNavController import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.R as MR
import com.google.android.material.bottomsheet.BackportBottomSheetBehavior import com.google.android.material.bottomsheet.BackportBottomSheetBehavior
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
@ -50,7 +51,15 @@ import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.queue.QueueBottomSheetBehavior import org.oxycblt.auxio.playback.queue.QueueBottomSheetBehavior
import org.oxycblt.auxio.ui.ViewBindingFragment import org.oxycblt.auxio.ui.ViewBindingFragment
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.coordinatorLayoutBehavior
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.systemBarInsetsCompat
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* A wrapper around the home fragment that shows the playback fragment and controls the more * A wrapper around the home fragment that shows the playback fragment and controls the more
@ -122,7 +131,7 @@ class MainFragment :
// Emulate the elevated bottom sheet style. // Emulate the elevated bottom sheet style.
background = background =
MaterialShapeDrawable.createWithElevationOverlay(context).apply { MaterialShapeDrawable.createWithElevationOverlay(context).apply {
fillColor = context.getAttrColorCompat(R.attr.colorSurface) fillColor = context.getAttrColorCompat(MR.attr.colorSurface)
elevation = context.getDimen(R.dimen.elevation_normal) elevation = context.getDimen(R.dimen.elevation_normal)
} }
// Apply bar insets for the queue's RecyclerView to usee. // Apply bar insets for the queue's RecyclerView to usee.

View file

@ -51,7 +51,14 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Disc import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.canScroll
import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* A [ListFragment] that shows information about an [Album]. * A [ListFragment] that shows information about an [Album].

View file

@ -49,7 +49,13 @@ import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* A [ListFragment] that shows information about an [Artist]. * A [ListFragment] that shows information about an [Artist].

View file

@ -37,12 +37,22 @@ import org.oxycblt.auxio.list.Divider
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.list.adapter.UpdateInstructions
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Disc import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.music.info.ReleaseType import org.oxycblt.auxio.music.info.ReleaseType
import org.oxycblt.auxio.music.metadata.AudioProperties import org.oxycblt.auxio.music.metadata.AudioProperties
import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import org.oxycblt.auxio.util.logD
/** /**
* [ViewModel] that manages the Song, Album, Artist, and Genre detail views. Keeps track of the * [ViewModel] that manages the Song, Album, Artist, and Genre detail views. Keeps track of the
@ -59,10 +69,10 @@ constructor(
private val musicSettings: MusicSettings, private val musicSettings: MusicSettings,
private val playbackSettings: PlaybackSettings private val playbackSettings: PlaybackSettings
) : ViewModel(), MusicRepository.UpdateListener { ) : ViewModel(), MusicRepository.UpdateListener {
private var currentSongJob: Job? = null
// --- SONG --- // --- SONG ---
private var currentSongJob: Job? = null
private val _currentSong = MutableStateFlow<Song?>(null) private val _currentSong = MutableStateFlow<Song?>(null)
/** The current [Song] to display. Null if there is nothing to show. */ /** The current [Song] to display. Null if there is nothing to show. */
val currentSong: StateFlow<Song?> val currentSong: StateFlow<Song?>
@ -279,7 +289,7 @@ constructor(
* *
* @param uid The [Music.UID] of the [Playlist] to update [currentPlaylist] to. Must be valid. * @param uid The [Music.UID] of the [Playlist] to update [currentPlaylist] to. Must be valid.
*/ */
fun setPlaylistUid(uid: Music.UID) { fun setPlaylist(uid: Music.UID) {
logD("Opening Playlist [uid: $uid]") logD("Opening Playlist [uid: $uid]")
_currentPlaylist.value = _currentPlaylist.value =
musicRepository.userLibrary?.findPlaylist(uid)?.also(::refreshPlaylistList) musicRepository.userLibrary?.findPlaylist(uid)?.also(::refreshPlaylistList)

View file

@ -41,10 +41,22 @@ import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* A [ListFragment] that shows information for a particular [Genre]. * A [ListFragment] that shows information for a particular [Genre].

View file

@ -44,10 +44,22 @@ import org.oxycblt.auxio.list.Header
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* A [ListFragment] that shows information for a particular [Playlist]. * A [ListFragment] that shows information for a particular [Playlist].
@ -122,7 +134,7 @@ class PlaylistDetailFragment :
// --- VIEWMODEL SETUP --- // --- VIEWMODEL SETUP ---
// DetailViewModel handles most initialization from the navigation argument. // DetailViewModel handles most initialization from the navigation argument.
detailModel.setPlaylistUid(args.playlistUid) detailModel.setPlaylist(args.playlistUid)
collectImmediately(detailModel.currentPlaylist, ::updatePlaylist) collectImmediately(detailModel.currentPlaylist, ::updatePlaylist)
collectImmediately(detailModel.playlistList, ::updateList) collectImmediately(detailModel.playlistList, ::updateList)
collectImmediately(detailModel.editedPlaylist, ::updateEditedPlaylist) collectImmediately(detailModel.editedPlaylist, ::updateEditedPlaylist)

View file

@ -22,8 +22,8 @@ import android.content.Context
import android.os.Build import android.os.Build
import android.util.AttributeSet import android.util.AttributeSet
import android.view.View import android.view.View
import androidx.appcompat.R
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import org.oxycblt.auxio.R
/** /**
* A [TextInputEditText] that deliberately restricts all input except for selection. This will work * A [TextInputEditText] that deliberately restricts all input except for selection. This will work

View file

@ -29,7 +29,10 @@ import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.SelectableListListener import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater

View file

@ -26,13 +26,16 @@ import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.databinding.ItemSortHeaderBinding import org.oxycblt.auxio.databinding.ItemSortHeaderBinding
import org.oxycblt.auxio.detail.list.DetailListAdapter.Listener
import org.oxycblt.auxio.list.BasicHeader import org.oxycblt.auxio.list.BasicHeader
import org.oxycblt.auxio.list.Divider import org.oxycblt.auxio.list.Divider
import org.oxycblt.auxio.list.Header import org.oxycblt.auxio.list.Header
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.SelectableListListener import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.adapter.* import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.* import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
import org.oxycblt.auxio.list.recycler.BasicHeaderViewHolder
import org.oxycblt.auxio.list.recycler.DividerViewHolder
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater

View file

@ -27,6 +27,7 @@ import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.R as MR
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
@ -139,8 +140,7 @@ class PlaylistDetailListAdapter(private val listener: Listener) :
} }
/** /**
* A [RecyclerView.ViewHolder] that displays a [SortHeader] and it's actions. Use [from] to create * A [Header] variant that displays an edit button.
* an instance.
* *
* @param titleRes The string resource to use as the header title * @param titleRes The string resource to use as the header title
* @author Alexander Capehart (OxygenCobalt) * @author Alexander Capehart (OxygenCobalt)
@ -214,7 +214,7 @@ private constructor(private val binding: ItemEditableSongBinding) :
override val delete = binding.background override val delete = binding.background
override val background = override val background =
MaterialShapeDrawable.createWithElevationOverlay(binding.root.context).apply { MaterialShapeDrawable.createWithElevationOverlay(binding.root.context).apply {
fillColor = binding.context.getAttrColorCompat(R.attr.colorSurface) fillColor = binding.context.getAttrColorCompat(MR.attr.colorSurface)
elevation = binding.context.getDimen(R.dimen.elevation_normal) elevation = binding.context.getDimen(R.dimen.elevation_normal)
alpha = 0 alpha = 0
} }
@ -224,7 +224,7 @@ private constructor(private val binding: ItemEditableSongBinding) :
LayerDrawable( LayerDrawable(
arrayOf( arrayOf(
MaterialShapeDrawable.createWithElevationOverlay(binding.context).apply { MaterialShapeDrawable.createWithElevationOverlay(binding.context).apply {
fillColor = binding.context.getAttrColorCompat(R.attr.colorSurface) fillColor = binding.context.getAttrColorCompat(MR.attr.colorSurface)
}, },
background)) background))
} }
@ -265,7 +265,7 @@ private constructor(private val binding: ItemEditableSongBinding) :
companion object { companion object {
/** A unique ID for this [RecyclerView.ViewHolder] type. */ /** A unique ID for this [RecyclerView.ViewHolder] type. */
const val VIEW_TYPE = IntegerTable.VIEW_TYPE_EDITABLE_SONG const val VIEW_TYPE = IntegerTable.VIEW_TYPE_PLAYLIST_SONG
/** /**
* Create a new instance. * Create a new instance.

View file

@ -24,7 +24,8 @@ import androidx.annotation.StringRes
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemSongPropertyBinding import org.oxycblt.auxio.databinding.ItemSongPropertyBinding
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.adapter.* import org.oxycblt.auxio.list.adapter.FlexibleListAdapter
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
import org.oxycblt.auxio.list.recycler.DialogRecyclerView import org.oxycblt.auxio.list.recycler.DialogRecyclerView
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater

View file

@ -22,8 +22,8 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import com.google.android.material.R
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
/** /**

View file

@ -46,16 +46,38 @@ import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeBinding import org.oxycblt.auxio.databinding.FragmentHomeBinding
import org.oxycblt.auxio.home.list.* import org.oxycblt.auxio.home.list.AlbumListFragment
import org.oxycblt.auxio.home.list.ArtistListFragment
import org.oxycblt.auxio.home.list.GenreListFragment
import org.oxycblt.auxio.home.list.PlaylistListFragment
import org.oxycblt.auxio.home.list.SongListFragment
import org.oxycblt.auxio.home.tabs.AdaptiveTabStrategy import org.oxycblt.auxio.home.tabs.AdaptiveTabStrategy
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.selection.SelectionFragment import org.oxycblt.auxio.list.selection.SelectionFragment
import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.IndexingProgress
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.NoAudioPermissionException
import org.oxycblt.auxio.music.NoMusicException
import org.oxycblt.auxio.music.PERMISSION_READ_AUDIO
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.MainNavigationAction import org.oxycblt.auxio.navigation.MainNavigationAction
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.getColorCompat
import org.oxycblt.auxio.util.lazyReflectedField
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.unlikelyToBeNull
/** /**
* The starting [SelectionFragment] of Auxio. Shows the user's music library and enables navigation * The starting [SelectionFragment] of Auxio. Shows the user's music library and enables navigation

View file

@ -26,7 +26,14 @@ import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.home.tabs.Tab import org.oxycblt.auxio.home.tabs.Tab
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.list.adapter.UpdateInstructions
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.util.Event import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent import org.oxycblt.auxio.util.MutableEvent

View file

@ -33,6 +33,7 @@ import android.text.TextUtils
import android.util.AttributeSet import android.util.AttributeSet
import android.view.Gravity import android.view.Gravity
import androidx.core.widget.TextViewCompat import androidx.core.widget.TextViewCompat
import com.google.android.material.R as MR
import com.google.android.material.textview.MaterialTextView import com.google.android.material.textview.MaterialTextView
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getAttrColorCompat
@ -53,7 +54,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleRes: Int = 0)
minimumHeight = context.getDimenPixels(R.dimen.fast_scroll_popup_min_height) minimumHeight = context.getDimenPixels(R.dimen.fast_scroll_popup_min_height)
TextViewCompat.setTextAppearance(this, R.style.TextAppearance_Auxio_HeadlineLarge) TextViewCompat.setTextAppearance(this, R.style.TextAppearance_Auxio_HeadlineLarge)
setTextColor(context.getAttrColorCompat(R.attr.colorOnSecondary)) setTextColor(context.getAttrColorCompat(MR.attr.colorOnSecondary))
ellipsize = TextUtils.TruncateAt.MIDDLE ellipsize = TextUtils.TruncateAt.MIDDLE
gravity = Gravity.CENTER gravity = Gravity.CENTER
includeFontPadding = false includeFontPadding = false
@ -67,7 +68,10 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleRes: Int = 0)
private val paint: Paint = private val paint: Paint =
Paint().apply { Paint().apply {
isAntiAlias = true isAntiAlias = true
color = context.getAttrColorCompat(R.attr.colorSecondary).defaultColor color =
context
.getAttrColorCompat(com.google.android.material.R.attr.colorSecondary)
.defaultColor
style = Paint.Style.FILL style = Paint.Style.FILL
} }

View file

@ -37,7 +37,12 @@ import androidx.recyclerview.widget.RecyclerView
import kotlin.math.abs import kotlin.math.abs
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.recycler.AuxioRecyclerView import org.oxycblt.auxio.list.recycler.AuxioRecyclerView
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.getDimenPixels
import org.oxycblt.auxio.util.getDrawableCompat
import org.oxycblt.auxio.util.getInteger
import org.oxycblt.auxio.util.isRtl
import org.oxycblt.auxio.util.isUnder
import org.oxycblt.auxio.util.systemBarInsetsCompat
/** /**
* A [RecyclerView] that enables better fast-scrolling. This is fundamentally a implementation of * A [RecyclerView] that enables better fast-scrolling. This is fundamentally a implementation of

View file

@ -30,13 +30,17 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
import org.oxycblt.auxio.list.*
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.AlbumViewHolder import org.oxycblt.auxio.list.recycler.AlbumViewHolder
import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs

View file

@ -28,8 +28,8 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
import org.oxycblt.auxio.list.*
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.ArtistViewHolder import org.oxycblt.auxio.list.recycler.ArtistViewHolder

View file

@ -28,8 +28,8 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
import org.oxycblt.auxio.list.*
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.GenreViewHolder import org.oxycblt.auxio.list.recycler.GenreViewHolder

View file

@ -27,8 +27,8 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
import org.oxycblt.auxio.list.*
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.PlaylistViewHolder import org.oxycblt.auxio.list.recycler.PlaylistViewHolder

View file

@ -30,8 +30,8 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentHomeListBinding import org.oxycblt.auxio.databinding.FragmentHomeListBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.home.HomeViewModel
import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView import org.oxycblt.auxio.home.fastscroll.FastScrollRecyclerView
import org.oxycblt.auxio.list.*
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.SongViewHolder import org.oxycblt.auxio.list.recycler.SongViewHolder

View file

@ -28,9 +28,14 @@ import android.widget.FrameLayout
import android.widget.ImageView import android.widget.ImageView
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import androidx.core.view.updateMarginsRelative import androidx.core.view.updateMarginsRelative
import com.google.android.material.R as MR
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getColorCompat import org.oxycblt.auxio.util.getColorCompat
import org.oxycblt.auxio.util.getDimenPixels import org.oxycblt.auxio.util.getDimenPixels
@ -80,7 +85,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
PlaybackIndicatorView(context).apply { cornerRadius = this@ImageGroup.cornerRadius } PlaybackIndicatorView(context).apply { cornerRadius = this@ImageGroup.cornerRadius }
selectionIndicatorView = selectionIndicatorView =
ImageView(context).apply { ImageView(context).apply {
imageTintList = context.getAttrColorCompat(R.attr.colorOnPrimary) imageTintList = context.getAttrColorCompat(MR.attr.colorOnPrimary)
setImageResource(R.drawable.ic_check_20) setImageResource(R.drawable.ic_check_20)
setBackgroundResource(R.drawable.ui_selection_badge_bg) setBackgroundResource(R.drawable.ui_selection_badge_bg)
} }

View file

@ -22,7 +22,6 @@ import dagger.Binds
import dagger.Module import dagger.Module
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import org.oxycblt.auxio.image.extractor.*
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)

View file

@ -38,7 +38,12 @@ import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject import javax.inject.Inject
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.image.extractor.SquareFrameTransform import org.oxycblt.auxio.image.extractor.SquareFrameTransform
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.ui.UISettings import org.oxycblt.auxio.ui.UISettings
import org.oxycblt.auxio.util.getColorCompat import org.oxycblt.auxio.util.getColorCompat
import org.oxycblt.auxio.util.getDrawableCompat import org.oxycblt.auxio.util.getDrawableCompat

View file

@ -24,7 +24,7 @@ import coil.key.Keyer
import coil.request.Options import coil.request.Options
import coil.size.Size import coil.size.Size
import javax.inject.Inject import javax.inject.Inject
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Song
class SongKeyer @Inject constructor(private val coverExtractor: CoverExtractor) : class SongKeyer @Inject constructor(private val coverExtractor: CoverExtractor) :
Keyer<List<Song>> { Keyer<List<Song>> {

View file

@ -50,7 +50,6 @@ import okio.buffer
import okio.source import okio.source
import org.oxycblt.auxio.image.CoverMode import org.oxycblt.auxio.image.CoverMode
import org.oxycblt.auxio.image.ImageSettings import org.oxycblt.auxio.image.ImageSettings
import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
@ -81,8 +80,8 @@ constructor(
} }
} }
fun computeAlbumOrdering(songs: List<Song>): Collection<Album> = fun computeAlbumOrdering(songs: List<Song>) =
Sort(Sort.Mode.ByCount, Sort.Direction.DESCENDING).albums(songs.groupBy { it.album }.keys) songs.groupBy { it.album }.entries.sortedByDescending { it.value.size }.map { it.key }
private suspend fun openInputStream(album: Album): InputStream? = private suspend fun openInputStream(album: Album): InputStream? =
try { try {

View file

@ -28,7 +28,12 @@ import androidx.viewbinding.ViewBinding
import org.oxycblt.auxio.MainFragmentDirections import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.selection.SelectionFragment import org.oxycblt.auxio.list.selection.SelectionFragment
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.MainNavigationAction import org.oxycblt.auxio.navigation.MainNavigationAction
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD

View file

@ -22,8 +22,15 @@ import androidx.annotation.IdRes
import kotlin.math.max import kotlin.math.max
import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.Sort.Direction
import org.oxycblt.auxio.list.Sort.Mode import org.oxycblt.auxio.list.Sort.Mode
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Date import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.info.Disc import org.oxycblt.auxio.music.info.Disc

View file

@ -20,7 +20,8 @@ package org.oxycblt.auxio.list.adapter
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidx.recyclerview.widget.* import androidx.recyclerview.widget.AdapterListUpdateCallback
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import java.util.concurrent.Executor import java.util.concurrent.Executor

View file

@ -29,6 +29,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.divider.MaterialDivider import com.google.android.material.divider.MaterialDivider
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.recycler.DialogRecyclerView.ViewHolder
import org.oxycblt.auxio.util.getDimenPixels import org.oxycblt.auxio.util.getDimenPixels
/** /**

View file

@ -26,6 +26,7 @@ import androidx.core.view.isInvisible
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.recycler.MaterialDragCallback.ViewHolder
import org.oxycblt.auxio.util.getDimen import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.getInteger import org.oxycblt.auxio.util.getInteger
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD

View file

@ -31,7 +31,13 @@ import org.oxycblt.auxio.list.Divider
import org.oxycblt.auxio.list.SelectableListListener import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.areNamesTheSame
import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getPlural import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater

View file

@ -23,7 +23,14 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
/** /**
* A [ViewModel] that manages the current selection. * A [ViewModel] that manages the current selection.

View file

@ -21,12 +21,22 @@ package org.oxycblt.auxio.music
import android.content.Context import android.content.Context
import android.content.pm.PackageManager import android.content.pm.PackageManager
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import java.util.* import java.util.LinkedList
import javax.inject.Inject import javax.inject.Inject
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext import kotlin.coroutines.EmptyCoroutineContext
import kotlinx.coroutines.* import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.yield
import org.oxycblt.auxio.music.MusicRepository.IndexingListener
import org.oxycblt.auxio.music.MusicRepository.IndexingWorker
import org.oxycblt.auxio.music.MusicRepository.UpdateListener
import org.oxycblt.auxio.music.cache.CacheRepository import org.oxycblt.auxio.music.cache.CacheRepository
import org.oxycblt.auxio.music.device.DeviceLibrary import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.device.RawSong import org.oxycblt.auxio.music.device.RawSong

View file

@ -20,7 +20,7 @@ package org.oxycblt.auxio.music.cache
import javax.inject.Inject import javax.inject.Inject
import org.oxycblt.auxio.music.device.RawSong import org.oxycblt.auxio.music.device.RawSong
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.logE
/** /**
* A repository allowing access to cached metadata obtained in prior music loading operations. * A repository allowing access to cached metadata obtained in prior music loading operations.

View file

@ -23,7 +23,13 @@ import android.net.Uri
import android.provider.OpenableColumns import android.provider.OpenableColumns
import javax.inject.Inject import javax.inject.Inject
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.fs.contentResolverSafe import org.oxycblt.auxio.music.fs.contentResolverSafe
import org.oxycblt.auxio.music.fs.useQuery import org.oxycblt.auxio.music.fs.useQuery
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD

View file

@ -20,13 +20,21 @@ package org.oxycblt.auxio.music.device
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.fs.MimeType import org.oxycblt.auxio.music.fs.MimeType
import org.oxycblt.auxio.music.fs.Path import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.music.fs.toAudioUri import org.oxycblt.auxio.music.fs.toAudioUri
import org.oxycblt.auxio.music.fs.toCoverUri import org.oxycblt.auxio.music.fs.toCoverUri
import org.oxycblt.auxio.music.info.*
import org.oxycblt.auxio.music.info.Date import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.music.info.Name
import org.oxycblt.auxio.music.info.ReleaseType
import org.oxycblt.auxio.music.metadata.parseId3GenreNames import org.oxycblt.auxio.music.metadata.parseId3GenreNames
import org.oxycblt.auxio.music.metadata.parseMultiValue import org.oxycblt.auxio.music.metadata.parseMultiValue
import org.oxycblt.auxio.util.nonZeroOrNull import org.oxycblt.auxio.util.nonZeroOrNull

View file

@ -19,11 +19,12 @@
package org.oxycblt.auxio.music.device package org.oxycblt.auxio.music.device
import java.util.UUID import java.util.UUID
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.fs.Directory import org.oxycblt.auxio.music.fs.Directory
import org.oxycblt.auxio.music.info.Date import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.info.ReleaseType import org.oxycblt.auxio.music.info.ReleaseType
import org.oxycblt.auxio.music.metadata.*
/** /**
* Raw information about a [SongImpl] obtained from the filesystem/Extractor instances. * Raw information about a [SongImpl] obtained from the filesystem/Extractor instances.

View file

@ -19,6 +19,7 @@
package org.oxycblt.auxio.music.info package org.oxycblt.auxio.music.info
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.info.ReleaseType.Album
/** /**
* The type of release an [Album] is considered. This includes EPs, Singles, Compilations, etc. * The type of release an [Album] is considered. This includes EPs, Singles, Compilations, etc.

View file

@ -52,7 +52,7 @@ class RenamePlaylistDialog : ViewBindingDialogFragment<DialogPlaylistNameBinding
override fun onConfigDialog(builder: AlertDialog.Builder) { override fun onConfigDialog(builder: AlertDialog.Builder) {
builder builder
.setTitle(R.string.lbl_rename) .setTitle(R.string.lbl_rename_playlist)
.setPositiveButton(R.string.lbl_ok) { _, _ -> .setPositiveButton(R.string.lbl_ok) { _, _ ->
val playlist = unlikelyToBeNull(pickerModel.currentPlaylistToRename.value) val playlist = unlikelyToBeNull(pickerModel.currentPlaylistToRename.value)
val chosenName = pickerModel.chosenName.value as ChosenName.Valid val chosenName = pickerModel.chosenName.value as ChosenName.Valid

View file

@ -28,12 +28,17 @@ import android.os.PowerManager
import android.provider.MediaStore import android.provider.MediaStore
import coil.ImageLoader import coil.ImageLoader
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import java.lang.Runnable
import java.util.*
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.* import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.IndexingProgress
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.fs.contentResolverSafe import org.oxycblt.auxio.music.fs.contentResolverSafe
import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.service.ForegroundManager import org.oxycblt.auxio.service.ForegroundManager

View file

@ -18,7 +18,11 @@
package org.oxycblt.auxio.music.user package org.oxycblt.auxio.music.user
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.info.Name import org.oxycblt.auxio.music.info.Name

View file

@ -18,7 +18,12 @@
package org.oxycblt.auxio.music.user package org.oxycblt.auxio.music.user
import androidx.room.* import androidx.room.ColumnInfo
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.Junction
import androidx.room.PrimaryKey
import androidx.room.Relation
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
/** /**
@ -57,6 +62,6 @@ data class RawPlaylist(
@Entity @Entity
data class PlaylistSongCrossRef( data class PlaylistSongCrossRef(
@PrimaryKey(autoGenerate = true) val id: Long = 0, @PrimaryKey(autoGenerate = true) val id: Long = 0,
val playlistUid: Music.UID, @ColumnInfo(index = true) val playlistUid: Music.UID,
val songUid: Music.UID @ColumnInfo(index = true) val songUid: Music.UID
) )

View file

@ -20,7 +20,11 @@ package org.oxycblt.auxio.music.user
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary import org.oxycblt.auxio.music.device.DeviceLibrary
/** /**

View file

@ -18,7 +18,14 @@
package org.oxycblt.auxio.music.user package org.oxycblt.auxio.music.user
import androidx.room.* import androidx.room.Dao
import androidx.room.Database
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.RoomDatabase
import androidx.room.Transaction
import androidx.room.TypeConverters
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
/** /**
@ -106,7 +113,7 @@ interface PlaylistDao {
} }
/** /**
* Replace the currently-stored [Song]s of the current playlist entry. * Replace the currently stored songs of the given playlist entry.
* *
* @param playlistUid The [Music.UID] of the playlist to update. * @param playlistUid The [Music.UID] of the playlist to update.
* @param songs The [PlaylistSong] representing the new list of songs to be placed in the * @param songs The [PlaylistSong] representing the new list of songs to be placed in the

View file

@ -23,7 +23,11 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Song
/** /**
* A [ViewModel] that stores the current information required for navigation picker dialogs * A [ViewModel] that stores the current information required for navigation picker dialogs

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.playback
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import com.google.android.material.R as MR
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding
@ -95,7 +96,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
binding.playbackSecondaryAction.apply { binding.playbackSecondaryAction.apply {
setIconResource(R.drawable.ic_skip_next_24) setIconResource(R.drawable.ic_skip_next_24)
contentDescription = getString(R.string.desc_skip_next) contentDescription = getString(R.string.desc_skip_next)
iconTint = context.getAttrColorCompat(R.attr.colorOnSurfaceVariant) iconTint = context.getAttrColorCompat(MR.attr.colorOnSurfaceVariant)
setOnClickListener { playbackModel.next() } setOnClickListener { playbackModel.next() }
} }
} }

View file

@ -24,6 +24,7 @@ import android.util.AttributeSet
import android.view.MotionEvent import android.view.MotionEvent
import android.view.View import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.R as MR
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.ui.BaseBottomSheetBehavior import org.oxycblt.auxio.ui.BaseBottomSheetBehavior
@ -39,7 +40,7 @@ class PlaybackBottomSheetBehavior<V : View>(context: Context, attributeSet: Attr
BaseBottomSheetBehavior<V>(context, attributeSet) { BaseBottomSheetBehavior<V>(context, attributeSet) {
val sheetBackgroundDrawable = val sheetBackgroundDrawable =
MaterialShapeDrawable.createWithElevationOverlay(context).apply { MaterialShapeDrawable.createWithElevationOverlay(context).apply {
fillColor = context.getAttrColorCompat(R.attr.colorSurface) fillColor = context.getAttrColorCompat(MR.attr.colorSurface)
elevation = context.getDimen(R.dimen.elevation_normal) elevation = context.getDimen(R.dimen.elevation_normal)
} }

View file

@ -27,10 +27,20 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.persist.PersistenceRepository import org.oxycblt.auxio.playback.persist.PersistenceRepository
import org.oxycblt.auxio.playback.queue.Queue import org.oxycblt.auxio.playback.queue.Queue
import org.oxycblt.auxio.playback.state.* import org.oxycblt.auxio.playback.state.InternalPlayer
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.util.Event import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent import org.oxycblt.auxio.util.MutableEvent

View file

@ -126,6 +126,7 @@ interface QueueDao {
suspend fun insertMapping(mapping: List<QueueMappingItem>) suspend fun insertMapping(mapping: List<QueueMappingItem>)
} }
// TODO: Figure out how to get RepeatMode to map to an int instead of a string
@Entity(tableName = PlaybackState.TABLE_NAME) @Entity(tableName = PlaybackState.TABLE_NAME)
data class PlaybackState( data class PlaybackState(
@PrimaryKey val id: Int, @PrimaryKey val id: Int,

View file

@ -23,7 +23,10 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Song
/** /**
* A [ViewModel] that stores the choices shown in the playback picker dialogs. * A [ViewModel] that stores the choices shown in the playback picker dialogs.

View file

@ -23,6 +23,8 @@ import kotlin.random.nextInt
import org.oxycblt.auxio.list.adapter.UpdateInstructions import org.oxycblt.auxio.list.adapter.UpdateInstructions
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.queue.Queue.Change.Type
import org.oxycblt.auxio.playback.queue.Queue.SavedState
/** /**
* A heap-backed play queue. * A heap-backed play queue.

View file

@ -24,16 +24,22 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.isInvisible import androidx.core.view.isInvisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.R as MR
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.ItemEditableSongBinding import org.oxycblt.auxio.databinding.ItemEditableSongBinding
import org.oxycblt.auxio.list.EditClickListListener import org.oxycblt.auxio.list.EditClickListListener
import org.oxycblt.auxio.list.adapter.* import org.oxycblt.auxio.list.adapter.FlexibleListAdapter
import org.oxycblt.auxio.list.adapter.PlayingIndicatorAdapter
import org.oxycblt.auxio.list.recycler.MaterialDragCallback import org.oxycblt.auxio.list.recycler.MaterialDragCallback
import org.oxycblt.auxio.list.recycler.SongViewHolder import org.oxycblt.auxio.list.recycler.SongViewHolder
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.resolveNames import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.inflater
import org.oxycblt.auxio.util.logD
/** /**
* A [RecyclerView.Adapter] that shows an editable list of queue items. * A [RecyclerView.Adapter] that shows an editable list of queue items.
@ -110,7 +116,7 @@ class QueueSongViewHolder private constructor(private val binding: ItemEditableS
override val delete = binding.background override val delete = binding.background
override val background = override val background =
MaterialShapeDrawable.createWithElevationOverlay(binding.root.context).apply { MaterialShapeDrawable.createWithElevationOverlay(binding.root.context).apply {
fillColor = binding.context.getAttrColorCompat(R.attr.colorSurface) fillColor = binding.context.getAttrColorCompat(MR.attr.colorSurface)
elevation = binding.context.getDimen(R.dimen.elevation_normal) * 5 elevation = binding.context.getDimen(R.dimen.elevation_normal) * 5
alpha = 0 alpha = 0
} }
@ -128,7 +134,7 @@ class QueueSongViewHolder private constructor(private val binding: ItemEditableS
LayerDrawable( LayerDrawable(
arrayOf( arrayOf(
MaterialShapeDrawable.createWithElevationOverlay(binding.context).apply { MaterialShapeDrawable.createWithElevationOverlay(binding.context).apply {
fillColor = binding.context.getAttrColorCompat(R.attr.colorSurface) fillColor = binding.context.getAttrColorCompat(MR.attr.colorSurface)
elevation = binding.context.getDimen(R.dimen.elevation_normal) elevation = binding.context.getDimen(R.dimen.elevation_normal)
}, },
background)) background))

View file

@ -23,6 +23,7 @@ import android.util.AttributeSet
import android.view.View import android.view.View
import android.view.WindowInsets import android.view.WindowInsets
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import com.google.android.material.R as MR
import com.google.android.material.shape.MaterialShapeDrawable import com.google.android.material.shape.MaterialShapeDrawable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.ui.BaseBottomSheetBehavior import org.oxycblt.auxio.ui.BaseBottomSheetBehavior
@ -64,7 +65,7 @@ class QueueBottomSheetBehavior<V : View>(context: Context, attributeSet: Attribu
override fun createBackground(context: Context) = override fun createBackground(context: Context) =
MaterialShapeDrawable.createWithElevationOverlay(context).apply { MaterialShapeDrawable.createWithElevationOverlay(context).apply {
// The queue sheet's background is a static elevated background. // The queue sheet's background is a static elevated background.
fillColor = context.getAttrColorCompat(R.attr.colorSurface) fillColor = context.getAttrColorCompat(MR.attr.colorSurface)
elevation = context.getDimen(R.dimen.elevation_normal) elevation = context.getDimen(R.dimen.elevation_normal)
} }

View file

@ -24,6 +24,7 @@ import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.queue.EditableQueue import org.oxycblt.auxio.playback.queue.EditableQueue
import org.oxycblt.auxio.playback.queue.Queue import org.oxycblt.auxio.playback.queue.Queue
import org.oxycblt.auxio.playback.state.PlaybackStateManager.Listener
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logW import org.oxycblt.auxio.util.logW

View file

@ -26,7 +26,11 @@ import android.content.IntentFilter
import android.media.AudioManager import android.media.AudioManager
import android.media.audiofx.AudioEffect import android.media.audiofx.AudioEffect
import android.os.IBinder import android.os.IBinder
import androidx.media3.common.* import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.decoder.ffmpeg.FfmpegAudioRenderer import androidx.media3.decoder.ffmpeg.FfmpegAudioRenderer
import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.RenderersFactory import androidx.media3.exoplayer.RenderersFactory

View file

@ -20,11 +20,25 @@ package org.oxycblt.auxio.search
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.list.* import org.oxycblt.auxio.list.BasicHeader
import org.oxycblt.auxio.list.Divider
import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.SelectableListListener
import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.adapter.SimpleDiffCallback import org.oxycblt.auxio.list.adapter.SimpleDiffCallback
import org.oxycblt.auxio.list.recycler.* import org.oxycblt.auxio.list.recycler.AlbumViewHolder
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.list.recycler.ArtistViewHolder
import org.oxycblt.auxio.list.recycler.BasicHeaderViewHolder
import org.oxycblt.auxio.list.recycler.DividerViewHolder
import org.oxycblt.auxio.list.recycler.GenreViewHolder
import org.oxycblt.auxio.list.recycler.PlaylistViewHolder
import org.oxycblt.auxio.list.recycler.SongViewHolder
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
/** /**

View file

@ -39,10 +39,23 @@ import org.oxycblt.auxio.list.Header
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.ListFragment import org.oxycblt.auxio.list.ListFragment
import org.oxycblt.auxio.list.selection.SelectionViewModel import org.oxycblt.auxio.list.selection.SelectionViewModel
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.navigation.NavigationViewModel import org.oxycblt.auxio.navigation.NavigationViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.collect
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getSystemServiceCompat
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
/** /**
* The [ListFragment] providing search functionality for the music library. * The [ListFragment] providing search functionality for the music library.

View file

@ -33,7 +33,9 @@ import org.oxycblt.auxio.list.BasicHeader
import org.oxycblt.auxio.list.Divider import org.oxycblt.auxio.list.Divider
import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.Item
import org.oxycblt.auxio.list.Sort import org.oxycblt.auxio.list.Sort
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.user.UserLibrary import org.oxycblt.auxio.music.user.UserLibrary
import org.oxycblt.auxio.playback.PlaybackSettings import org.oxycblt.auxio.playback.PlaybackSettings

View file

@ -25,8 +25,8 @@ import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceGroupAdapter import androidx.preference.PreferenceGroupAdapter
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.R
import com.google.android.material.divider.BackportMaterialDividerItemDecoration import com.google.android.material.divider.BackportMaterialDividerItemDecoration
import org.oxycblt.auxio.R
/** /**
* A [BackportMaterialDividerItemDecoration] that sets up the divider configuration to correctly * A [BackportMaterialDividerItemDecoration] that sets up the divider configuration to correctly

View file

@ -21,8 +21,8 @@ package org.oxycblt.auxio.ui
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import com.google.android.material.R
import com.google.android.material.button.MaterialButton import com.google.android.material.button.MaterialButton
import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.fixDoubleRipple import org.oxycblt.auxio.util.fixDoubleRipple
/** /**

View file

@ -18,11 +18,12 @@
package org.oxycblt.auxio.ui.accent package org.oxycblt.auxio.ui.accent
import android.R as SR
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.TooltipCompat import androidx.appcompat.widget.TooltipCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R import com.google.android.material.R as MR
import org.oxycblt.auxio.databinding.ItemAccentBinding import org.oxycblt.auxio.databinding.ItemAccentBinding
import org.oxycblt.auxio.list.ClickableListListener import org.oxycblt.auxio.list.ClickableListListener
import org.oxycblt.auxio.util.getAttrColorCompat import org.oxycblt.auxio.util.getAttrColorCompat
@ -118,9 +119,9 @@ class AccentViewHolder private constructor(private val binding: ItemAccentBindin
binding.accent.apply { binding.accent.apply {
iconTint = iconTint =
if (isSelected) { if (isSelected) {
context.getAttrColorCompat(R.attr.colorSurface) context.getAttrColorCompat(MR.attr.colorSurface)
} else { } else {
context.getColorCompat(android.R.color.transparent) context.getColorCompat(SR.color.transparent)
} }
} }
} }

View file

@ -34,7 +34,9 @@ import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.playback.system.PlaybackService import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.ui.UISettings import org.oxycblt.auxio.ui.UISettings
import org.oxycblt.auxio.util.* import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logW
import org.oxycblt.auxio.util.newBroadcastPendingIntent
/** /**
* The [AppWidgetProvider] for the "Now Playing" widget. This widget shows the current playback * The [AppWidgetProvider] for the "Now Playing" widget. This widget shows the current playback

View file

@ -3,9 +3,9 @@
xmlns:aapt="http://schemas.android.com/aapt"> xmlns:aapt="http://schemas.android.com/aapt">
<!-- <!--
Yes, this whole file is all 30 frames of Spotify's equalizer animation Yes, this whole file is the material equalizer icon influenced by Spotify's
merged with the material equalizer icon, with each vector inlined using equalizer animation with each vector inlined using aapt:attr so that it does
aapt:attr so that it does not clutter the drawable folder. not clutter the drawable folder.
--> -->
<!-- Frame 1 --> <!-- Frame 1 -->

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.divider.MaterialDivider xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single"
android:id="@+id/sort_modes">
<item
android:id="@+id/option_sort_none"
android:title="@string/lbl_none" />
<item
android:id="@+id/option_sort_name"
android:title="@string/lbl_name" />
<item
android:id="@+id/option_sort_artist"
android:title="@string/lbl_artist" />
<item
android:id="@+id/option_sort_album"
android:title="@string/lbl_album" />
<item
android:id="@+id/option_sort_year"
android:title="@string/lbl_date" />
<item
android:id="@+id/option_sort_duration"
android:title="@string/lbl_duration" />
</group>
<group android:checkableBehavior="single"
android:id="@+id/sort_direction">
<item
android:id="@+id/option_sort_asc"
android:title="@string/lbl_sort_asc" />
<item
android:id="@+id/option_sort_dec"
android:title="@string/lbl_sort_dec" />
</group>
</menu>

View file

@ -274,7 +274,6 @@
<string name="desc_playlist_image">Вокладка плэйліст для %s</string> <string name="desc_playlist_image">Вокладка плэйліст для %s</string>
<string name="lbl_playlist">Плэйліст</string> <string name="lbl_playlist">Плэйліст</string>
<string name="lbl_playlists">Плэйлісты</string> <string name="lbl_playlists">Плэйлісты</string>
<string name="lbl_none">Адкл.</string>
<string name="desc_new_playlist">Стварыце новы плэйліст</string> <string name="desc_new_playlist">Стварыце новы плэйліст</string>
<string name="fmt_def_playlist">Плэйліст %d</string> <string name="fmt_def_playlist">Плэйліст %d</string>
<string name="lbl_new_playlist">Новы плэйліст</string> <string name="lbl_new_playlist">Новы плэйліст</string>

View file

@ -285,7 +285,6 @@
<string name="lbl_playlist">Seznam skladeb</string> <string name="lbl_playlist">Seznam skladeb</string>
<string name="set_intelligent_sorting">Při řazení ignorovat předložky</string> <string name="set_intelligent_sorting">Při řazení ignorovat předložky</string>
<string name="set_intelligent_sorting_desc">Ignorovat slova jako „the“ při řazení podle názvu (funguje nejlépe u hudby v angličtině)</string> <string name="set_intelligent_sorting_desc">Ignorovat slova jako „the“ při řazení podle názvu (funguje nejlépe u hudby v angličtině)</string>
<string name="lbl_none">Žádné</string>
<string name="desc_new_playlist">Vytvořit nový playlist</string> <string name="desc_new_playlist">Vytvořit nový playlist</string>
<string name="lbl_playlist_add">Přidat do seznamu skladeb</string> <string name="lbl_playlist_add">Přidat do seznamu skladeb</string>
<string name="lng_playlist_added">Přidáno do seznamu skladeb</string> <string name="lng_playlist_added">Přidáno do seznamu skladeb</string>

View file

@ -276,7 +276,6 @@
<string name="lbl_playlists">Wiedergabelisten</string> <string name="lbl_playlists">Wiedergabelisten</string>
<string name="set_intelligent_sorting">Artikel beim Sortieren ignorieren</string> <string name="set_intelligent_sorting">Artikel beim Sortieren ignorieren</string>
<string name="set_intelligent_sorting_desc">Wörter wie „the“ ignorieren (funktioniert am besten mit englischsprachiger Musik)</string> <string name="set_intelligent_sorting_desc">Wörter wie „the“ ignorieren (funktioniert am besten mit englischsprachiger Musik)</string>
<string name="lbl_none">Keine</string>
<string name="desc_new_playlist">Neue Wiedergabeliste erstellen</string> <string name="desc_new_playlist">Neue Wiedergabeliste erstellen</string>
<string name="lbl_new_playlist">Neue Wiedergabeliste</string> <string name="lbl_new_playlist">Neue Wiedergabeliste</string>
<string name="lng_playlist_added">Zur Wiedergabeliste hinzugefügt</string> <string name="lng_playlist_added">Zur Wiedergabeliste hinzugefügt</string>

View file

@ -278,7 +278,6 @@
<string name="lbl_playlists">Listas de reproducción</string> <string name="lbl_playlists">Listas de reproducción</string>
<string name="desc_playlist_image">Imagen de la lista de reproducción para %s</string> <string name="desc_playlist_image">Imagen de la lista de reproducción para %s</string>
<string name="lbl_playlist">Lista de reproducción</string> <string name="lbl_playlist">Lista de reproducción</string>
<string name="lbl_none">Ninguno</string>
<string name="set_intelligent_sorting">Ignorar artículos al ordenar</string> <string name="set_intelligent_sorting">Ignorar artículos al ordenar</string>
<string name="set_intelligent_sorting_desc">Ignorar palabras como \"the\" al ordenar por nombre (funciona mejor con música en inglés)</string> <string name="set_intelligent_sorting_desc">Ignorar palabras como \"the\" al ordenar por nombre (funciona mejor con música en inglés)</string>
<string name="desc_new_playlist">Crear una nueva lista de reproducción</string> <string name="desc_new_playlist">Crear una nueva lista de reproducción</string>

View file

@ -28,7 +28,6 @@
<string name="lbl_search">Etsi</string> <string name="lbl_search">Etsi</string>
<string name="lbl_filter">Suodata</string> <string name="lbl_filter">Suodata</string>
<string name="lbl_filter_all">Kaikki</string> <string name="lbl_filter_all">Kaikki</string>
<string name="lbl_none">Ei mitään</string>
<string name="lbl_name">Nimi</string> <string name="lbl_name">Nimi</string>
<string name="lbl_song_count">Kappalemäärä</string> <string name="lbl_song_count">Kappalemäärä</string>
<string name="lbl_disc">Levy</string> <string name="lbl_disc">Levy</string>

View file

@ -206,7 +206,6 @@
<string name="set_playback">Lecture</string> <string name="set_playback">Lecture</string>
<string name="set_state">Persistance</string> <string name="set_state">Persistance</string>
<string name="set_wipe_state">Vider l\'état de lecture</string> <string name="set_wipe_state">Vider l\'état de lecture</string>
<string name="lbl_none">Aucun</string>
<string name="set_headset_autoplay_desc">Toujours commencer la lecture lorsqu\'un périphérique audio est connecté (pourrait ne pas fonctionner sur tous les appareils)</string> <string name="set_headset_autoplay_desc">Toujours commencer la lecture lorsqu\'un périphérique audio est connecté (pourrait ne pas fonctionner sur tous les appareils)</string>
<string name="set_replay_gain_mode">Stratégie de normalisation de volume</string> <string name="set_replay_gain_mode">Stratégie de normalisation de volume</string>
<string name="set_replay_gain_mode_track">Par chanson</string> <string name="set_replay_gain_mode_track">Par chanson</string>

View file

@ -268,5 +268,4 @@
<string name="desc_playlist_image">Imaxe da lista de reprodución para %s</string> <string name="desc_playlist_image">Imaxe da lista de reprodución para %s</string>
<string name="set_separators_and">ampersand</string> <string name="set_separators_and">ampersand</string>
<string name="set_replay_gain">ganancia da repetición</string> <string name="set_replay_gain">ganancia da repetición</string>
<string name="lbl_none">Ningún</string>
</resources> </resources>

View file

@ -269,7 +269,6 @@
<string name="set_music">Glazba</string> <string name="set_music">Glazba</string>
<string name="desc_playlist_image">Slika popisa pjesama za %s</string> <string name="desc_playlist_image">Slika popisa pjesama za %s</string>
<string name="set_behavior">Ponašanje</string> <string name="set_behavior">Ponašanje</string>
<string name="lbl_none">Ništa</string>
<string name="set_intelligent_sorting">Pametno razvrstavanje</string> <string name="set_intelligent_sorting">Pametno razvrstavanje</string>
<string name="set_intelligent_sorting_desc">Ispravno razvrstaj imena koja počinju brojevima ili riječima poput „the” (najbolje radi s glazbom na engleskom jeziku)</string> <string name="set_intelligent_sorting_desc">Ispravno razvrstaj imena koja počinju brojevima ili riječima poput „the” (najbolje radi s glazbom na engleskom jeziku)</string>
<string name="desc_new_playlist">Stvori novi popis pjesama</string> <string name="desc_new_playlist">Stvori novi popis pjesama</string>

View file

@ -287,5 +287,4 @@
<string name="lng_playlist_added">Aggiunto alla playlist</string> <string name="lng_playlist_added">Aggiunto alla playlist</string>
<string name="def_song_count">Niente canzoni</string> <string name="def_song_count">Niente canzoni</string>
<string name="fmt_def_playlist">Playlist %d</string> <string name="fmt_def_playlist">Playlist %d</string>
<string name="lbl_none">Nessuno</string>
</resources> </resources>

View file

@ -265,7 +265,6 @@
<string name="lbl_playlist">プレイリスト</string> <string name="lbl_playlist">プレイリスト</string>
<string name="lbl_playlists">プレイリスト</string> <string name="lbl_playlists">プレイリスト</string>
<string name="desc_playlist_image">%s のプレイリスト イメージ</string> <string name="desc_playlist_image">%s のプレイリスト イメージ</string>
<string name="lbl_none">無し</string>
<string name="lbl_new_playlist">新規プレイリスト</string> <string name="lbl_new_playlist">新規プレイリスト</string>
<string name="lbl_playlist_add">プレイリストに追加する</string> <string name="lbl_playlist_add">プレイリストに追加する</string>
<string name="lng_playlist_created">プレイリストが作成されました</string> <string name="lng_playlist_created">プレイリストが作成されました</string>

View file

@ -276,7 +276,6 @@
<string name="desc_playlist_image">%s의 재생 목록 이미지</string> <string name="desc_playlist_image">%s의 재생 목록 이미지</string>
<string name="set_intelligent_sorting">정렬할 때 기사 무시</string> <string name="set_intelligent_sorting">정렬할 때 기사 무시</string>
<string name="set_intelligent_sorting_desc">이름으로 정렬할 때 \"the\"와 같은 단어 무시(영어 음악에서 가장 잘 작동함)</string> <string name="set_intelligent_sorting_desc">이름으로 정렬할 때 \"the\"와 같은 단어 무시(영어 음악에서 가장 잘 작동함)</string>
<string name="lbl_none">없음</string>
<string name="desc_new_playlist">새 재생 목록 만들기</string> <string name="desc_new_playlist">새 재생 목록 만들기</string>
<string name="lbl_new_playlist">새 재생목록</string> <string name="lbl_new_playlist">새 재생목록</string>
<string name="lbl_playlist_add">재생목록에 추가</string> <string name="lbl_playlist_add">재생목록에 추가</string>

View file

@ -274,6 +274,5 @@
<string name="lbl_playlist">Grojaraštis</string> <string name="lbl_playlist">Grojaraštis</string>
<string name="lbl_playlists">Grojaraščiai</string> <string name="lbl_playlists">Grojaraščiai</string>
<string name="desc_playlist_image">Grojaraščio vaizdas %s</string> <string name="desc_playlist_image">Grojaraščio vaizdas %s</string>
<string name="lbl_none">Jokios</string>
<string name="desc_new_playlist">Sukurti naują grojaraštį</string> <string name="desc_new_playlist">Sukurti naują grojaraštį</string>
</resources> </resources>

View file

@ -90,7 +90,6 @@
<string name="lbl_go_artist">കലാകാരനിലേക്ക് പോകുക</string> <string name="lbl_go_artist">കലാകാരനിലേക്ക് പോകുക</string>
<string name="lbl_song_detail">സവിശേഷതകൾ കാണുക</string> <string name="lbl_song_detail">സവിശേഷതകൾ കാണുക</string>
<string name="lbl_state_saved">സ്ഥിതി സംരക്ഷിച്ചു</string> <string name="lbl_state_saved">സ്ഥിതി സംരക്ഷിച്ചു</string>
<string name="lbl_none">ഒന്നുമില്ല</string>
<string name="lbl_sort_dec">അവരോഹണം</string> <string name="lbl_sort_dec">അവരോഹണം</string>
<string name="lbl_state_restored">സ്ഥിതി പുനഃസ്ഥാപിച്ചു</string> <string name="lbl_state_restored">സ്ഥിതി പുനഃസ്ഥാപിച്ചു</string>
<string name="lbl_wiki">വിക്കി</string> <string name="lbl_wiki">വിക്കി</string>

View file

@ -281,7 +281,6 @@
<string name="desc_playlist_image">Obraz playlisty %s</string> <string name="desc_playlist_image">Obraz playlisty %s</string>
<string name="set_intelligent_sorting">Inteligentne sortowanie</string> <string name="set_intelligent_sorting">Inteligentne sortowanie</string>
<string name="set_intelligent_sorting_desc">Ignoruj słowa takie jak „the” oraz numery w tytule podczas sortowania (działa najlepiej z utworami w języku angielskim)</string> <string name="set_intelligent_sorting_desc">Ignoruj słowa takie jak „the” oraz numery w tytule podczas sortowania (działa najlepiej z utworami w języku angielskim)</string>
<string name="lbl_none">Brak</string>
<string name="desc_new_playlist">Utwórz nową playlistę</string> <string name="desc_new_playlist">Utwórz nową playlistę</string>
<string name="lbl_new_playlist">Nowa playlista</string> <string name="lbl_new_playlist">Nowa playlista</string>
<string name="lbl_playlist_add">Dodaj do playlisty</string> <string name="lbl_playlist_add">Dodaj do playlisty</string>

View file

@ -142,7 +142,6 @@
<string name="set_action_mode_next">Treceți la următoarea</string> <string name="set_action_mode_next">Treceți la următoarea</string>
<string name="set_playback_mode_artist">Redă de la artist</string> <string name="set_playback_mode_artist">Redă de la artist</string>
<string name="set_playback_mode_genre">Redă din genul</string> <string name="set_playback_mode_genre">Redă din genul</string>
<string name="lbl_none">Nu există</string>
<string name="lbl_reset">Resetează</string> <string name="lbl_reset">Resetează</string>
<string name="lbl_wiki">Wiki</string> <string name="lbl_wiki">Wiki</string>
<string name="lng_widget">Vizualizați și controlați redarea muzicii</string> <string name="lng_widget">Vizualizați și controlați redarea muzicii</string>

View file

@ -283,7 +283,6 @@
<string name="desc_playlist_image">Обложка плейлиста для %s</string> <string name="desc_playlist_image">Обложка плейлиста для %s</string>
<string name="set_intelligent_sorting">Игнорировать артикли при сортировке</string> <string name="set_intelligent_sorting">Игнорировать артикли при сортировке</string>
<string name="set_intelligent_sorting_desc">Игнорировать такие слова, как «the», при сортировке по имени (лучше всего работает с англоязычной музыкой)</string> <string name="set_intelligent_sorting_desc">Игнорировать такие слова, как «the», при сортировке по имени (лучше всего работает с англоязычной музыкой)</string>
<string name="lbl_none">Откл.</string>
<string name="desc_new_playlist">Создать новый плейлист</string> <string name="desc_new_playlist">Создать новый плейлист</string>
<string name="lbl_new_playlist">Новый плейлист</string> <string name="lbl_new_playlist">Новый плейлист</string>
<string name="fmt_def_playlist">Плейлист %d</string> <string name="fmt_def_playlist">Плейлист %d</string>

View file

@ -274,6 +274,5 @@
<string name="lbl_playlists">çalma listeleri</string> <string name="lbl_playlists">çalma listeleri</string>
<string name="set_intelligent_sorting">Sıralama yaparken makaleleri yoksay</string> <string name="set_intelligent_sorting">Sıralama yaparken makaleleri yoksay</string>
<string name="set_intelligent_sorting_desc">Ada göre sıralarken \"the\" gibi kelimeleri yok sayın (en iyi ingilizce müzikle çalışır)</string> <string name="set_intelligent_sorting_desc">Ada göre sıralarken \"the\" gibi kelimeleri yok sayın (en iyi ingilizce müzikle çalışır)</string>
<string name="lbl_none">Hiçbiri</string>
<string name="desc_new_playlist">Yeni bir oynatma listesi oluştur</string> <string name="desc_new_playlist">Yeni bir oynatma listesi oluştur</string>
</resources> </resources>

View file

@ -278,7 +278,6 @@
<string name="desc_playlist_image">Зображення списку відтворення для %s</string> <string name="desc_playlist_image">Зображення списку відтворення для %s</string>
<string name="lbl_playlist">Список відтворення</string> <string name="lbl_playlist">Список відтворення</string>
<string name="lbl_playlists">Списки відтворення</string> <string name="lbl_playlists">Списки відтворення</string>
<string name="lbl_none">Немає</string>
<string name="set_intelligent_sorting">Інтелектуальне сортування</string> <string name="set_intelligent_sorting">Інтелектуальне сортування</string>
<string name="set_intelligent_sorting_desc">Ігнорування таких слів, як \"the\", або цифр під час сортування за назвою (найкраще працює з англомовною музикою)</string> <string name="set_intelligent_sorting_desc">Ігнорування таких слів, як \"the\", або цифр під час сортування за назвою (найкраще працює з англомовною музикою)</string>
<string name="desc_new_playlist">Створити новий список відтворення</string> <string name="desc_new_playlist">Створити новий список відтворення</string>

View file

@ -272,7 +272,6 @@
<string name="lbl_playlist">播放列表</string> <string name="lbl_playlist">播放列表</string>
<string name="lbl_playlists">播放列表</string> <string name="lbl_playlists">播放列表</string>
<string name="desc_playlist_image">%s 的播放列表图片</string> <string name="desc_playlist_image">%s 的播放列表图片</string>
<string name="lbl_none"></string>
<string name="set_intelligent_sorting">排序时忽略冠词</string> <string name="set_intelligent_sorting">排序时忽略冠词</string>
<string name="set_intelligent_sorting_desc">按名称排序时忽略类似“the”这样的冠词对英文歌曲的效果最好</string> <string name="set_intelligent_sorting_desc">按名称排序时忽略类似“the”这样的冠词对英文歌曲的效果最好</string>
<string name="desc_new_playlist">创建新的播放列表</string> <string name="desc_new_playlist">创建新的播放列表</string>

View file

@ -52,7 +52,6 @@
<string name="set_key_album_songs_sort" translatable="false">auxio_album_sort</string> <string name="set_key_album_songs_sort" translatable="false">auxio_album_sort</string>
<string name="set_key_artist_songs_sort" translatable="false">auxio_artist_sort</string> <string name="set_key_artist_songs_sort" translatable="false">auxio_artist_sort</string>
<string name="set_key_genre_songs_sort" translatable="false">auxio_genre_sort</string> <string name="set_key_genre_songs_sort" translatable="false">auxio_genre_sort</string>
<string name="set_key_playlist_songs_sort" translatable="false">auxio_playlist_sort</string>
<string-array name="entries_theme"> <string-array name="entries_theme">
<item>@string/set_theme_auto</item> <item>@string/set_theme_auto</item>

View file

@ -92,7 +92,6 @@
<!-- As in to not filter --> <!-- As in to not filter -->
<string name="lbl_filter_all">All</string> <string name="lbl_filter_all">All</string>
<string name="lbl_none">None</string>
<string name="lbl_name">Name</string> <string name="lbl_name">Name</string>
<string name="lbl_date">Date</string> <string name="lbl_date">Date</string>
<string name="lbl_duration">Duration</string> <string name="lbl_duration">Duration</string>

View file

@ -18,7 +18,7 @@
package org.oxycblt.auxio.music.device package org.oxycblt.auxio.music.device
import java.util.* import java.util.UUID
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test

View file

@ -20,7 +20,11 @@ package org.oxycblt.auxio.music.device
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import org.oxycblt.auxio.music.* import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song
open class FakeDeviceLibrary : DeviceLibrary { open class FakeDeviceLibrary : DeviceLibrary {
override val songs: List<Song> override val songs: List<Song>

View file

@ -0,0 +1,2 @@
Auxio 3.1.0 introduces playlisting functionality, with more features coming soon.
For more information, see https://github.com/OxygenCobalt/Auxio/releases/tag/v3.1.0.

View file

@ -1,4 +1,4 @@
Auxio is a local music player with a fast, reliable UI/UX without the many useless features present in other music players. Built off of Exoplayer, Auxio has superior library support and listening quality compared to other apps that use outdated android functionality. In short, <b>It plays music</b>. Auxio is a local music player with a fast, reliable UI/UX without the many useless features present in other music players. Built off of ExoPlayer, Auxio has superior library support and listening quality compared to other apps that use outdated android functionality. In short, <b>It plays music</b>.
<b>Features</b> <b>Features</b>
@ -10,7 +10,8 @@ Auxio is a local music player with a fast, reliable UI/UX without the many usele
precise/original dates, sort tags, and more precise/original dates, sort tags, and more
- Advanced artist system that unifies artists and album artists - Advanced artist system that unifies artists and album artists
- SD Card-aware folder management - SD Card-aware folder management
- Reliable playback state persistence - Reliable playlisting functionality
- Playback state persistence
- Full ReplayGain support (On MP3, FLAC, OGG, OPUS, and MP4 files) - Full ReplayGain support (On MP3, FLAC, OGG, OPUS, and MP4 files)
- External equalizer support (ex. Wavelet) - External equalizer support (ex. Wavelet)
- Edge-to-edge - Edge-to-edge
@ -19,4 +20,4 @@ precise/original dates, sort tags, and more
- Headset autoplay - Headset autoplay
- Stylish widgets that automatically adapt to their size - Stylish widgets that automatically adapt to their size
- Completely private and offline - Completely private and offline
- No rounded album covers (Unless you want them. Then you can.) - No rounded album covers (Unless you want them. Then you can.)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 189 KiB

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 145 KiB

Some files were not shown because too many files have changed in this diff Show more