Merge branch 'dev' into feature/share
This commit is contained in:
commit
a5e01be34b
106 changed files with 392 additions and 183 deletions
|
@ -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
|
||||||
|
|
11
README.md
11
README.md
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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].
|
||||||
|
|
|
@ -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].
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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].
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>> {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 -->
|
||||||
|
|
|
@ -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" />
|
|
|
@ -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>
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
2
fastlane/metadata/android/en-US/changelogs/30.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/30.txt
Normal 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.
|
|
@ -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
Loading…
Reference in a new issue