all: tweak package structure

Try to tweak the package structure to be more coherent.
This commit is contained in:
Alexander Capehart 2022-09-25 20:23:31 -06:00
parent 3e73cd8080
commit f3c14b81cb
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
42 changed files with 190 additions and 201 deletions

View file

@ -96,12 +96,6 @@ dependencies {
// Preferences // Preferences
implementation "androidx.preference:preference-ktx:1.2.0" implementation "androidx.preference:preference-ktx:1.2.0"
// Room
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
// --- THIRD PARTY --- // --- THIRD PARTY ---
// Exoplayer // Exoplayer

View file

@ -21,7 +21,7 @@
#-renamesourcefileattribute SourceFile #-renamesourcefileattribute SourceFile
-keep class org.oxycblt.auxio.AuxioApp -keep class org.oxycblt.auxio.AuxioApp
-keep class org.oxycblt.auxio.settings.SettingsListFragment -keep class org.oxycblt.auxio.settings.prefs.SettingsListFragment
# Free software does not obsfucate. Also it's easier to debug stack traces. # Free software does not obsfucate. Also it's easier to debug stack traces.
-dontobfuscate -dontobfuscate

View file

@ -36,7 +36,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.queue.QueueSheetBehavior import org.oxycblt.auxio.playback.queue.QueueSheetBehavior
import org.oxycblt.auxio.playback.ui.PlaybackSheetBehavior import org.oxycblt.auxio.playback.PlaybackSheetBehavior
import org.oxycblt.auxio.ui.MainNavigationAction import org.oxycblt.auxio.ui.MainNavigationAction
import org.oxycblt.auxio.ui.NavigationViewModel import org.oxycblt.auxio.ui.NavigationViewModel
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment import org.oxycblt.auxio.ui.fragment.ViewBindingFragment

View file

@ -33,12 +33,12 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MimeType
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.ReleaseType import org.oxycblt.auxio.music.ReleaseType
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.storage.MimeType
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.recycler.Header import org.oxycblt.auxio.ui.recycler.Header
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item

View file

@ -26,7 +26,7 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogSongDetailBinding import org.oxycblt.auxio.databinding.DialogSongDetailBinding
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.fragment.ViewBindingDialogFragment import org.oxycblt.auxio.ui.fragment.ViewBindingDialogFragment
import org.oxycblt.auxio.util.androidActivityViewModels import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.collectImmediately

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.databinding.ItemDiscHeaderBinding
import org.oxycblt.auxio.detail.DiscHeader import org.oxycblt.auxio.detail.DiscHeader
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.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item
import org.oxycblt.auxio.ui.recycler.MenuItemListener import org.oxycblt.auxio.ui.recycler.MenuItemListener
@ -120,7 +120,7 @@ private class AlbumDetailViewHolder private constructor(private val binding: Ite
binding.detailInfo.apply { binding.detailInfo.apply {
val date = val date =
item.date?.let { context.getString(R.string.fmt_number, it.year) } item.date?.resolveYear(context)
?: context.getString(R.string.def_date) ?: context.getString(R.string.def_date)
val songCount = context.getPlural(R.plurals.fmt_song_count, item.songs.size) val songCount = context.getPlural(R.plurals.fmt_song_count, item.songs.size)

View file

@ -29,7 +29,6 @@ import org.oxycblt.auxio.databinding.ItemSongBinding
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.resolveYear
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item
import org.oxycblt.auxio.ui.recycler.MenuItemListener import org.oxycblt.auxio.ui.recycler.MenuItemListener
@ -158,7 +157,10 @@ private class ArtistAlbumViewHolder private constructor(private val binding: Ite
fun bind(item: Album, listener: MenuItemListener) { fun bind(item: Album, listener: MenuItemListener) {
binding.parentImage.bind(item) binding.parentImage.bind(item)
binding.parentName.text = item.resolveName(binding.context) binding.parentName.text = item.resolveName(binding.context)
binding.parentInfo.text = item.date.resolveYear(binding.context) binding.parentInfo.text =
item.date?.resolveYear(binding.context)
?: binding.context.getString(R.string.def_date)
// binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) } // binding.parentMenu.setOnClickListener { listener.onOpenMenu(item, it) }
binding.root.setOnLongClickListener { binding.root.setOnLongClickListener {
listener.onOpenMenu(item, it) listener.onOpenMenu(item, it)

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.ItemDetailBinding import org.oxycblt.auxio.databinding.ItemDetailBinding
import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item
import org.oxycblt.auxio.ui.recycler.SimpleItemCallback import org.oxycblt.auxio.ui.recycler.SimpleItemCallback
import org.oxycblt.auxio.ui.recycler.SongViewHolder import org.oxycblt.auxio.ui.recycler.SongViewHolder

View file

@ -27,8 +27,8 @@ import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.music.secsToMs import org.oxycblt.auxio.playback.secsToMs
import org.oxycblt.auxio.ui.recycler.AlbumViewHolder import org.oxycblt.auxio.ui.recycler.AlbumViewHolder
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.recycler.ArtistViewHolder import org.oxycblt.auxio.ui.recycler.ArtistViewHolder
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.recycler.GenreViewHolder import org.oxycblt.auxio.ui.recycler.GenreViewHolder
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item

View file

@ -28,9 +28,9 @@ import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.formatDurationMs
import org.oxycblt.auxio.music.picker.PickerMode import org.oxycblt.auxio.music.picker.PickerMode
import org.oxycblt.auxio.music.secsToMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.playback.secsToMs
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.MainNavigationAction import org.oxycblt.auxio.ui.MainNavigationAction
import org.oxycblt.auxio.ui.recycler.IndicatorAdapter import org.oxycblt.auxio.ui.recycler.IndicatorAdapter

View file

@ -26,7 +26,12 @@ import kotlinx.parcelize.Parcelize
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.extractor.parseId3GenreNames import org.oxycblt.auxio.music.extractor.parseId3GenreNames
import org.oxycblt.auxio.music.extractor.parseMultiValue import org.oxycblt.auxio.music.extractor.parseMultiValue
import org.oxycblt.auxio.music.extractor.parseReleaseType import org.oxycblt.auxio.music.extractor.toUuidOrNull
import org.oxycblt.auxio.music.storage.Directory
import org.oxycblt.auxio.music.storage.MimeType
import org.oxycblt.auxio.music.storage.Path
import org.oxycblt.auxio.music.storage.albumCoverUri
import org.oxycblt.auxio.music.storage.audioUri
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.recycler.Item import org.oxycblt.auxio.ui.recycler.Item
import org.oxycblt.auxio.util.nonZeroOrNull import org.oxycblt.auxio.util.nonZeroOrNull
@ -358,7 +363,7 @@ class Song constructor(raw: Raw, settings: Settings) : Music() {
musicBrainzId = raw.albumMusicBrainzId?.toUuidOrNull(), musicBrainzId = raw.albumMusicBrainzId?.toUuidOrNull(),
name = requireNotNull(raw.albumName) { "Invalid raw: No album name" }, name = requireNotNull(raw.albumName) { "Invalid raw: No album name" },
sortName = raw.albumSortName, sortName = raw.albumSortName,
releaseType = raw.albumReleaseTypes.parseReleaseType(settings), releaseType = ReleaseType.parse(raw.albumReleaseTypes.parseMultiValue(settings)),
rawArtists = rawAlbumArtists.ifEmpty { rawArtists }.ifEmpty { listOf(Artist.Raw(null, null)) } rawArtists = rawAlbumArtists.ifEmpty { rawArtists }.ifEmpty { listOf(Artist.Raw(null, null)) }
) )
@ -557,7 +562,9 @@ class Album constructor(raw: Raw, override val songs: List<Song>) : MusicParent(
*/ */
class Artist class Artist
constructor(raw: Raw, songAlbums: List<Music>) : MusicParent() { constructor(raw: Raw, songAlbums: List<Music>) : MusicParent() {
override val uid = raw.musicBrainzId?.let { UID.musicBrainz(MusicMode.ARTISTS, it) } ?: UID.auxio(MusicMode.ARTISTS) { update(raw.name) } override val uid = raw.musicBrainzId?.let { UID.musicBrainz(MusicMode.ARTISTS, it) } ?: UID.auxio(
MusicMode.ARTISTS
) { update(raw.name) }
override val rawName = raw.name override val rawName = raw.name

View file

@ -22,6 +22,7 @@ import android.net.Uri
import android.provider.OpenableColumns import android.provider.OpenableColumns
import org.oxycblt.auxio.music.MusicStore.Callback import org.oxycblt.auxio.music.MusicStore.Callback
import org.oxycblt.auxio.music.MusicStore.Library import org.oxycblt.auxio.music.MusicStore.Library
import org.oxycblt.auxio.music.storage.useQuery
import org.oxycblt.auxio.util.contentResolverSafe import org.oxycblt.auxio.util.contentResolverSafe
/** /**

View file

@ -26,13 +26,13 @@ import android.provider.MediaStore
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.core.database.getIntOrNull import androidx.core.database.getIntOrNull
import androidx.core.database.getStringOrNull import androidx.core.database.getStringOrNull
import org.oxycblt.auxio.music.Directory
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.directoryCompat import org.oxycblt.auxio.music.storage.Directory
import org.oxycblt.auxio.music.mediaStoreVolumeNameCompat import org.oxycblt.auxio.music.storage.directoryCompat
import org.oxycblt.auxio.music.queryCursor import org.oxycblt.auxio.music.storage.mediaStoreVolumeNameCompat
import org.oxycblt.auxio.music.storageVolumesCompat import org.oxycblt.auxio.music.storage.queryCursor
import org.oxycblt.auxio.music.useQuery import org.oxycblt.auxio.music.storage.storageVolumesCompat
import org.oxycblt.auxio.music.storage.useQuery
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.util.contentResolverSafe import org.oxycblt.auxio.util.contentResolverSafe
import org.oxycblt.auxio.util.getSystemServiceCompat import org.oxycblt.auxio.util.getSystemServiceCompat

View file

@ -26,7 +26,7 @@ import com.google.android.exoplayer2.metadata.id3.TextInformationFrame
import com.google.android.exoplayer2.metadata.vorbis.VorbisComment import com.google.android.exoplayer2.metadata.vorbis.VorbisComment
import org.oxycblt.auxio.music.Date import org.oxycblt.auxio.music.Date
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.audioUri import org.oxycblt.auxio.music.storage.audioUri
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logW import org.oxycblt.auxio.util.logW

View file

@ -19,9 +19,9 @@ package org.oxycblt.auxio.music.extractor
import androidx.core.text.isDigitsOnly import androidx.core.text.isDigitsOnly
import org.oxycblt.auxio.music.Date import org.oxycblt.auxio.music.Date
import org.oxycblt.auxio.music.ReleaseType
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.util.nonZeroOrNull import org.oxycblt.auxio.util.nonZeroOrNull
import java.util.UUID
/** /**
* Parse out the track number field as if the given Int is formatted as DTTT, where D Is the disc * Parse out the track number field as if the given Int is formatted as DTTT, where D Is the disc
@ -110,8 +110,11 @@ fun String.maybeParseSeparators(settings: Settings): List<String> {
return splitEscaped { separators.contains(it) } return splitEscaped { separators.contains(it) }
} }
/** Parse a multi-value tag into a [ReleaseType], handling separators in the process. */ fun String.toUuidOrNull(): UUID? = try {
fun List<String>.parseReleaseType(settings: Settings) = ReleaseType.parse(parseMultiValue(settings)) UUID.fromString(this)
} catch (e: IllegalArgumentException) {
null
}
/** /**
* Parse a multi-value genre name using ID3v2 rules. If there is one value, the ID3v2.3 rules will * Parse a multi-value genre name using ID3v2 rules. If there is one value, the ID3v2.3 rules will

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.settings package org.oxycblt.auxio.music.extractor
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater

View file

@ -15,13 +15,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.settings package org.oxycblt.auxio.music.storage
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemMusicDirBinding import org.oxycblt.auxio.databinding.ItemMusicDirBinding
import org.oxycblt.auxio.music.Directory
import org.oxycblt.auxio.ui.recycler.DialogViewHolder import org.oxycblt.auxio.ui.recycler.DialogViewHolder
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater

View file

@ -15,9 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.settings package org.oxycblt.auxio.music.storage
import org.oxycblt.auxio.music.Directory
/** Represents a the configuration for the "Folder Management" setting */ /** Represents a the configuration for the "Folder Management" setting */
data class MusicDirs(val dirs: List<Directory>, val shouldInclude: Boolean) data class MusicDirs(val dirs: List<Directory>, val shouldInclude: Boolean)

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music.settings package org.oxycblt.auxio.music.storage
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
@ -28,7 +28,6 @@ import androidx.core.view.isVisible
import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogMusicDirsBinding import org.oxycblt.auxio.databinding.DialogMusicDirsBinding
import org.oxycblt.auxio.music.Directory
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.fragment.ViewBindingDialogFragment import org.oxycblt.auxio.ui.fragment.ViewBindingDialogFragment
import org.oxycblt.auxio.util.context import org.oxycblt.auxio.util.context

View file

@ -15,10 +15,14 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music package org.oxycblt.auxio.music.storage
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.os.storage.StorageManager import android.os.storage.StorageManager
@ -91,6 +95,107 @@ class Directory private constructor(val volume: StorageVolume, val relativePath:
} }
} }
/**
* Represents a mime type as it is loaded by Auxio. [fromExtension] is based on the file extension
* should always exist, while [fromFormat] is based on the file itself and may not be available.
* @author OxygenCobalt
*/
data class MimeType(val fromExtension: String, val fromFormat: String?) {
fun resolveName(context: Context): String {
// We try our best to produce a more readable name for the common audio formats.
val formatName =
when (fromFormat) {
// We start with the extracted mime types, as they are more consistent. Note that
// we do not include container formats at all with these names. It is only the
// inner codec that we show.
MimeTypes.AUDIO_MPEG,
MimeTypes.AUDIO_MPEG_L1,
MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
MimeTypes.AUDIO_AAC -> R.string.cdc_aac
MimeTypes.AUDIO_VORBIS -> R.string.cdc_vorbis
MimeTypes.AUDIO_OPUS -> R.string.cdc_opus
MimeTypes.AUDIO_FLAC -> R.string.cdc_flac
MimeTypes.AUDIO_WAV -> R.string.cdc_wav
// We don't give a name to more unpopular formats.
else -> -1
}
if (formatName > -1) {
return context.getString(formatName)
}
// Fall back to the file extension in the case that we have no mime type or
// a useless "audio/raw" mime type. Here:
// - We return names for container formats instead of the inner format, as we
// cannot parse the file.
// - We are at the mercy of the Android OS, hence we check for every possible mime
// type for a particular format.
val extensionName =
when (fromExtension) {
"audio/mpeg",
"audio/mp3" -> R.string.cdc_mp3
"audio/mp4",
"audio/mp4a-latm",
"audio/mpeg4-generic" -> R.string.cdc_mp4
"audio/aac",
"audio/aacp",
"audio/3gpp",
"audio/3gpp2" -> R.string.cdc_aac
"audio/ogg",
"application/ogg",
"application/x-ogg" -> R.string.cdc_ogg
"audio/flac" -> R.string.cdc_flac
"audio/wav",
"audio/x-wav",
"audio/wave",
"audio/vnd.wave" -> R.string.cdc_wav
"audio/x-matroska" -> R.string.cdc_mka
else -> -1
}
return if (extensionName > -1) {
context.getString(extensionName)
} else {
// Fall back to the extension if we can't find a special name for this format.
MimeTypeMap.getSingleton().getExtensionFromMimeType(fromExtension)?.uppercase()
?: context.getString(R.string.def_codec)
}
}
}
/** Shortcut for making a [ContentResolver] query with less superfluous arguments. */
fun ContentResolver.queryCursor(
uri: Uri,
projection: Array<out String>,
selector: String? = null,
args: Array<String>? = null
) = query(uri, projection, selector, args, null)
/** Shortcut for making a [ContentResolver] query and using the particular cursor with [use]. */
inline fun <reified R> ContentResolver.useQuery(
uri: Uri,
projection: Array<out String>,
selector: String? = null,
args: Array<String>? = null,
block: (Cursor) -> R
) = queryCursor(uri, projection, selector, args)?.use(block)
/**
* For some reason the album cover URI namespace does not have a member in [MediaStore], but it
* still works since at least API 21.
*/
private val EXTERNAL_ALBUM_ART_URI = Uri.parse("content://media/external/audio/albumart")
/** Converts a [Long] Audio ID into a URI to that particular audio file. */
val Long.audioUri: Uri
get() = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, this)
/** Converts a [Long] Album ID into a URI pointing to MediaStore-cached album art. */
val Long.albumCoverUri: Uri
get() = ContentUris.withAppendedId(EXTERNAL_ALBUM_ART_URI, this)
@Suppress("NewApi") @Suppress("NewApi")
private val SM_API21_GET_VOLUME_LIST_METHOD: Method by private val SM_API21_GET_VOLUME_LIST_METHOD: Method by
lazyReflectedMethod(StorageManager::class, "getVolumeList") lazyReflectedMethod(StorageManager::class, "getVolumeList")
@ -181,73 +286,3 @@ val StorageVolume.mediaStoreVolumeNameCompat: String?
uuidCompat?.lowercase() uuidCompat?.lowercase()
} }
} }
/**
* Represents a mime type as it is loaded by Auxio. [fromExtension] is based on the file extension
* should always exist, while [fromFormat] is based on the file itself and may not be available.
* @author OxygenCobalt
*/
data class MimeType(val fromExtension: String, val fromFormat: String?) {
fun resolveName(context: Context): String {
// We try our best to produce a more readable name for the common audio formats.
val formatName =
when (fromFormat) {
// We start with the extracted mime types, as they are more consistent. Note that
// we do not include container formats at all with these names. It is only the
// inner codec that we show.
MimeTypes.AUDIO_MPEG,
MimeTypes.AUDIO_MPEG_L1,
MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
MimeTypes.AUDIO_AAC -> R.string.cdc_aac
MimeTypes.AUDIO_VORBIS -> R.string.cdc_vorbis
MimeTypes.AUDIO_OPUS -> R.string.cdc_opus
MimeTypes.AUDIO_FLAC -> R.string.cdc_flac
MimeTypes.AUDIO_WAV -> R.string.cdc_wav
// We don't give a name to more unpopular formats.
else -> -1
}
if (formatName > -1) {
return context.getString(formatName)
}
// Fall back to the file extension in the case that we have no mime type or
// a useless "audio/raw" mime type. Here:
// - We return names for container formats instead of the inner format, as we
// cannot parse the file.
// - We are at the mercy of the Android OS, hence we check for every possible mime
// type for a particular format.
val extensionName =
when (fromExtension) {
"audio/mpeg",
"audio/mp3" -> R.string.cdc_mp3
"audio/mp4",
"audio/mp4a-latm",
"audio/mpeg4-generic" -> R.string.cdc_mp4
"audio/aac",
"audio/aacp",
"audio/3gpp",
"audio/3gpp2" -> R.string.cdc_aac
"audio/ogg",
"application/ogg",
"application/x-ogg" -> R.string.cdc_ogg
"audio/flac" -> R.string.cdc_flac
"audio/wav",
"audio/x-wav",
"audio/wave",
"audio/vnd.wave" -> R.string.cdc_wav
"audio/x-matroska" -> R.string.cdc_mka
else -> -1
}
return if (extensionName > -1) {
context.getString(extensionName)
} else {
// Fall back to the extension if we can't find a special name for this format.
MimeTypeMap.getSingleton().getExtensionFromMimeType(fromExtension)?.uppercase()
?: context.getString(R.string.def_codec)
}
}
}

View file

@ -24,7 +24,6 @@ import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding import org.oxycblt.auxio.databinding.FragmentPlaybackBarBinding
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.msToDs
import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.MainNavigationAction import org.oxycblt.auxio.ui.MainNavigationAction
@ -63,6 +62,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
} }
binding.playbackSong.isSelected = true binding.playbackSong.isSelected = true
binding.playbackInfo.isSelected = true
// Load the track color in manually as it's unclear whether the track actually supports // Load the track color in manually as it's unclear whether the track actually supports
// using a ColorStateList in the resources // using a ColorStateList in the resources
@ -111,6 +111,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
override fun onDestroyBinding(binding: FragmentPlaybackBarBinding) { override fun onDestroyBinding(binding: FragmentPlaybackBarBinding) {
super.onDestroyBinding(binding) super.onDestroyBinding(binding)
binding.playbackSong.isSelected = false binding.playbackSong.isSelected = false
binding.playbackInfo.isSelected = false
} }
private fun updateSong(song: Song?) { private fun updateSong(song: Song?) {

View file

@ -32,7 +32,6 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.msToDs
import org.oxycblt.auxio.music.picker.PickerMode import org.oxycblt.auxio.music.picker.PickerMode
import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.playback.ui.StyledSeekBar import org.oxycblt.auxio.playback.ui.StyledSeekBar

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.playback.ui package org.oxycblt.auxio.playback
import android.content.Context import android.content.Context
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable

View file

@ -15,59 +15,10 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.music package org.oxycblt.auxio.playback
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
import android.text.format.DateUtils import android.text.format.DateUtils
import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import java.util.UUID
/** Shortcut for making a [ContentResolver] query with less superfluous arguments. */
fun ContentResolver.queryCursor(
uri: Uri,
projection: Array<out String>,
selector: String? = null,
args: Array<String>? = null
) = query(uri, projection, selector, args, null)
/** Shortcut for making a [ContentResolver] query and using the particular cursor with [use]. */
inline fun <reified R> ContentResolver.useQuery(
uri: Uri,
projection: Array<out String>,
selector: String? = null,
args: Array<String>? = null,
block: (Cursor) -> R
) = queryCursor(uri, projection, selector, args)?.use(block)
/**
* For some reason the album cover URI namespace does not have a member in [MediaStore], but it
* still works since at least API 21.
*/
private val EXTERNAL_ALBUM_ART_URI = Uri.parse("content://media/external/audio/albumart")
/** Converts a [Long] Audio ID into a URI to that particular audio file. */
val Long.audioUri: Uri
get() = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, this)
/** Converts a [Long] Album ID into a URI pointing to MediaStore-cached album art. */
val Long.albumCoverUri: Uri
get() = ContentUris.withAppendedId(EXTERNAL_ALBUM_ART_URI, this)
fun String.toUuidOrNull(): UUID? = try {
UUID.fromString(this)
} catch (e: IllegalArgumentException) {
null
}
/** Shortcut to resolve a year from a nullable date. Will return "No Date" if it is null. */
fun Date?.resolveYear(context: Context) =
this?.resolveYear(context) ?: context.getString(R.string.def_date)
/** Converts a long in milliseconds to a long in deci-seconds */ /** Converts a long in milliseconds to a long in deci-seconds */
fun Long.msToDs() = floorDiv(100) fun Long.msToDs() = floorDiv(100)

View file

@ -30,8 +30,6 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.dsToMs
import org.oxycblt.auxio.music.msToDs
import org.oxycblt.auxio.playback.state.InternalPlayer import org.oxycblt.auxio.playback.state.InternalPlayer
import org.oxycblt.auxio.playback.state.PlaybackStateDatabase import org.oxycblt.auxio.playback.state.PlaybackStateDatabase
import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.playback.state.PlaybackStateManager

View file

@ -21,7 +21,7 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import com.google.android.material.slider.Slider import com.google.android.material.slider.Slider
import org.oxycblt.auxio.databinding.ViewSeekBarBinding import org.oxycblt.auxio.databinding.ViewSeekBarBinding
import org.oxycblt.auxio.music.formatDurationDs import org.oxycblt.auxio.playback.formatDurationDs
import org.oxycblt.auxio.util.inflater import org.oxycblt.auxio.util.inflater
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import kotlin.math.max import kotlin.math.max

View file

@ -36,7 +36,7 @@ import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
import org.oxycblt.auxio.util.androidActivityViewModels import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.collectImmediately

View file

@ -27,10 +27,10 @@ import androidx.preference.PreferenceManager
import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.home.tabs.Tab import org.oxycblt.auxio.home.tabs.Tab
import org.oxycblt.auxio.music.Directory
import org.oxycblt.auxio.music.MusicMode import org.oxycblt.auxio.music.MusicMode
import org.oxycblt.auxio.music.Sort import org.oxycblt.auxio.music.Sort
import org.oxycblt.auxio.music.settings.MusicDirs import org.oxycblt.auxio.music.storage.Directory
import org.oxycblt.auxio.music.storage.MusicDirs
import org.oxycblt.auxio.playback.BarAction import org.oxycblt.auxio.playback.BarAction
import org.oxycblt.auxio.playback.replaygain.ReplayGainMode import org.oxycblt.auxio.playback.replaygain.ReplayGainMode
import org.oxycblt.auxio.playback.replaygain.ReplayGainPreAmp import org.oxycblt.auxio.playback.replaygain.ReplayGainPreAmp

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.settings package org.oxycblt.auxio.settings.prefs
import android.content.Context import android.content.Context
import android.content.res.TypedArray import android.content.res.TypedArray

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.settings package org.oxycblt.auxio.settings.prefs
import android.os.Bundle import android.os.Bundle
import androidx.preference.PreferenceDialogFragmentCompat import androidx.preference.PreferenceDialogFragmentCompat

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.settings package org.oxycblt.auxio.settings.prefs
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -33,6 +33,7 @@ import coil.Coil
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.MusicViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.ui.NavigationViewModel import org.oxycblt.auxio.ui.NavigationViewModel
import org.oxycblt.auxio.util.androidActivityViewModels import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.isNight import org.oxycblt.auxio.util.isNight

View file

@ -15,7 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package org.oxycblt.auxio.settings package org.oxycblt.auxio.settings.prefs
import android.content.Context import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet

View file

@ -50,14 +50,14 @@ private val Any.autoTag: String
get() = "Auxio.${this::class.simpleName ?: "Anonymous Object"}" get() = "Auxio.${this::class.simpleName ?: "Anonymous Object"}"
/** /**
* I know that this will not stop you, but consider what you are doing with your life, plagiarizers. * Note: If you are politely forking this project while keeping the source open, you can ignore
* the following passage. If not, give me a moment of your time.
* *
* Do you want to live a fulfilling existence on this planet? Or do you want to spend your life * Consider what you are doing with your life, plagiarizers. Do you want to live a fulfilling
* taking work others did and making it objectively worse so you could arbitrage a fraction of a * existence on this planet? Or do you want to spend your life taking work others did and making
* penny on every AdMob impression you get? * it objectively worse so you could arbitrage a fraction of a penny on every AdMob impression you
* * get? You could do so many great things if you simply had the courage to come up with an idea of
* You could do so many great things if you simply had the courage to come up with an idea of your * your own.
* own.
* *
* If you still want to go on, I guess the only thing I can say is this: * If you still want to go on, I guess the only thing I can say is this:
* *

View file

@ -20,7 +20,7 @@
android:id="@+id/playback_sheet" android:id="@+id/playback_sheet"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.playback.ui.PlaybackSheetBehavior"> app:layout_behavior="org.oxycblt.auxio.playback.PlaybackSheetBehavior">
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/playback_bar_fragment" android:id="@+id/playback_bar_fragment"

View file

@ -22,7 +22,7 @@
style="@style/Widget.Auxio.DisableDropShadows" style="@style/Widget.Auxio.DisableDropShadows"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="org.oxycblt.auxio.playback.ui.PlaybackSheetBehavior"> app:layout_behavior="org.oxycblt.auxio.playback.PlaybackSheetBehavior">
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/playback_bar_fragment" android:id="@+id/playback_bar_fragment"

View file

@ -36,12 +36,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/spacing_small" android:layout_marginStart="@dimen/spacing_small"
android:layout_marginEnd="@dimen/spacing_tiny" android:layout_marginEnd="@dimen/spacing_tiny"
android:ellipsize="end" android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
app:layout_constraintBottom_toBottomOf="@+id/playback_cover" app:layout_constraintBottom_toBottomOf="@+id/playback_cover"
app:layout_constraintEnd_toStartOf="@+id/playback_controls_wrapper" app:layout_constraintEnd_toStartOf="@+id/playback_controls_wrapper"
app:layout_constraintStart_toEndOf="@+id/playback_cover" app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_song" app:layout_constraintTop_toBottomOf="@+id/playback_song"
tools:text="Artist Name / Album Name" /> tools:text="Artist Name" />
<org.oxycblt.auxio.playback.ui.ForcedLTRFrameLayout <org.oxycblt.auxio.playback.ui.ForcedLTRFrameLayout
android:id="@+id/playback_controls_wrapper" android:id="@+id/playback_controls_wrapper"

View file

@ -26,7 +26,7 @@
<androidx.fragment.app.FragmentContainerView <androidx.fragment.app.FragmentContainerView
android:id="@+id/settings_list_fragment" android:id="@+id/settings_list_fragment"
android:name="org.oxycblt.auxio.settings.SettingsListFragment" android:name="org.oxycblt.auxio.settings.prefs.SettingsListFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"

View file

@ -84,12 +84,12 @@
tools:layout="@layout/dialog_pre_amp" /> tools:layout="@layout/dialog_pre_amp" />
<dialog <dialog
android:id="@+id/music_dirs_dialog" android:id="@+id/music_dirs_dialog"
android:name="org.oxycblt.auxio.music.settings.MusicDirsDialog" android:name="org.oxycblt.auxio.music.storage.MusicDirsDialog"
android:label="music_dirs_dialog" android:label="music_dirs_dialog"
tools:layout="@layout/dialog_music_dirs" /> tools:layout="@layout/dialog_music_dirs" />
<dialog <dialog
android:id="@+id/separators_dialog" android:id="@+id/separators_dialog"
android:name="org.oxycblt.auxio.music.settings.SeparatorsDialog" android:name="org.oxycblt.auxio.music.extractor.SeparatorsDialog"
android:label="music_dirs_dialog" android:label="music_dirs_dialog"
tools:layout="@layout/dialog_separators" /> tools:layout="@layout/dialog_separators" />

View file

@ -237,7 +237,7 @@
<string name="set_exclude_non_music_desc">Ignore audio files that are not music, such as podcasts</string> <string name="set_exclude_non_music_desc">Ignore audio files that are not music, such as podcasts</string>
<string name="set_separators">Multi-value separators</string> <string name="set_separators">Multi-value separators</string>
<string name="set_separators_desc">Configure characters that denote multiple tag values</string> <string name="set_separators_desc">Configure characters that denote multiple tag values</string>
<string name="set_separators_warning">Warning: Using this setting may result in some tags being incorrectly interpreted as having multiple values.</string> <string name="set_separators_warning">Warning: Using this setting may result in some tags being incorrectly interpreted as having multiple values. You can resolve this by escaping unwanted separator characters with a backslash (\\).</string>
<string name="set_separators_comma">Comma (,)</string> <string name="set_separators_comma">Comma (,)</string>
<string name="set_separators_semicolon">Semicolon (;)</string> <string name="set_separators_semicolon">Semicolon (;)</string>
<string name="set_separators_slash">Slash (/)</string> <string name="set_separators_slash">Slash (/)</string>

View file

@ -2,7 +2,7 @@
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<PreferenceCategory app:title="@string/set_ui"> <PreferenceCategory app:title="@string/set_ui">
<org.oxycblt.auxio.settings.IntListPreference <org.oxycblt.auxio.settings.prefs.IntListPreference
app:defaultValue="@integer/theme_auto" app:defaultValue="@integer/theme_auto"
app:entries="@array/entries_theme" app:entries="@array/entries_theme"
app:entryIcons="@array/icons_theme" app:entryIcons="@array/icons_theme"
@ -11,7 +11,7 @@
app:key="@string/set_key_theme" app:key="@string/set_key_theme"
app:title="@string/set_theme" /> app:title="@string/set_theme" />
<org.oxycblt.auxio.settings.WrappedDialogPreference <org.oxycblt.auxio.settings.prefs.WrappedDialogPreference
app:icon="@drawable/ic_accent_24" app:icon="@drawable/ic_accent_24"
app:key="@string/set_key_accent" app:key="@string/set_key_accent"
app:title="@string/set_accent" /> app:title="@string/set_accent" />
@ -26,7 +26,7 @@
<PreferenceCategory app:title="@string/set_display"> <PreferenceCategory app:title="@string/set_display">
<org.oxycblt.auxio.settings.WrappedDialogPreference <org.oxycblt.auxio.settings.prefs.WrappedDialogPreference
app:key="@string/set_key_lib_tabs" app:key="@string/set_key_lib_tabs"
app:summary="@string/set_lib_tabs_desc" app:summary="@string/set_lib_tabs_desc"
app:title="@string/set_lib_tabs" /> app:title="@string/set_lib_tabs" />
@ -50,7 +50,7 @@
app:summary="@string/set_round_mode_desc" app:summary="@string/set_round_mode_desc"
app:title="@string/set_round_mode" /> app:title="@string/set_round_mode" />
<org.oxycblt.auxio.settings.IntListPreference <org.oxycblt.auxio.settings.prefs.IntListPreference
app:defaultValue="@integer/bar_action_next" app:defaultValue="@integer/bar_action_next"
app:entries="@array/entries_bar_action" app:entries="@array/entries_bar_action"
app:entryValues="@array/values_bar_action" app:entryValues="@array/values_bar_action"
@ -73,14 +73,14 @@
app:summary="@string/set_headset_autoplay_desc" app:summary="@string/set_headset_autoplay_desc"
app:title="@string/set_headset_autoplay" /> app:title="@string/set_headset_autoplay" />
<org.oxycblt.auxio.settings.IntListPreference <org.oxycblt.auxio.settings.prefs.IntListPreference
app:defaultValue="@integer/replay_gain_dynamic" app:defaultValue="@integer/replay_gain_dynamic"
app:entries="@array/entries_replay_gain" app:entries="@array/entries_replay_gain"
app:entryValues="@array/values_replay_gain" app:entryValues="@array/values_replay_gain"
app:key="@string/set_key_replay_gain" app:key="@string/set_key_replay_gain"
app:title="@string/set_replay_gain" /> app:title="@string/set_replay_gain" />
<org.oxycblt.auxio.settings.WrappedDialogPreference <org.oxycblt.auxio.settings.prefs.WrappedDialogPreference
app:key="@string/set_key_pre_amp" app:key="@string/set_key_pre_amp"
app:summary="@string/set_pre_amp_desc" app:summary="@string/set_pre_amp_desc"
app:title="@string/set_pre_amp" /> app:title="@string/set_pre_amp" />
@ -89,7 +89,7 @@
<PreferenceCategory app:title="@string/set_behavior"> <PreferenceCategory app:title="@string/set_behavior">
<org.oxycblt.auxio.settings.IntListPreference <org.oxycblt.auxio.settings.prefs.IntListPreference
app:defaultValue="@integer/music_mode_songs" app:defaultValue="@integer/music_mode_songs"
app:entries="@array/entries_library_song_playback_mode" app:entries="@array/entries_library_song_playback_mode"
app:entryValues="@array/values_library_song_playback_mode" app:entryValues="@array/values_library_song_playback_mode"
@ -97,7 +97,7 @@
app:title="@string/set_library_song_playback_mode" app:title="@string/set_library_song_playback_mode"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<org.oxycblt.auxio.settings.IntListPreference <org.oxycblt.auxio.settings.prefs.IntListPreference
app:defaultValue="@integer/music_mode_none" app:defaultValue="@integer/music_mode_none"
app:entries="@array/entries_detail_song_playback_mode" app:entries="@array/entries_detail_song_playback_mode"
app:entryValues="@array/values_detail_song_playback_mode" app:entryValues="@array/values_detail_song_playback_mode"
@ -159,12 +159,12 @@
app:summary="@string/set_exclude_non_music_desc" app:summary="@string/set_exclude_non_music_desc"
app:title="@string/set_exclude_non_music" /> app:title="@string/set_exclude_non_music" />
<org.oxycblt.auxio.settings.WrappedDialogPreference <org.oxycblt.auxio.settings.prefs.WrappedDialogPreference
app:key="@string/set_key_music_dirs" app:key="@string/set_key_music_dirs"
app:summary="@string/set_dirs_desc" app:summary="@string/set_dirs_desc"
app:title="@string/set_dirs" /> app:title="@string/set_dirs" />
<org.oxycblt.auxio.settings.WrappedDialogPreference <org.oxycblt.auxio.settings.prefs.WrappedDialogPreference
app:key="@string/set_key_separators" app:key="@string/set_key_separators"
app:summary="@string/set_separators_desc" app:summary="@string/set_separators_desc"
app:title="@string/set_separators" /> app:title="@string/set_separators" />