all: minor cleanup

Do some minor housecleaning across the app.
This commit is contained in:
OxygenCobalt 2022-06-12 21:02:15 -06:00
parent ad87c72cd6
commit cb8c3306eb
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
12 changed files with 58 additions and 129 deletions

View file

@ -17,6 +17,7 @@
- Genre parsing now handles multiple integer values and cover/remix indicators (May wipe playback state) - Genre parsing now handles multiple integer values and cover/remix indicators (May wipe playback state)
- "Rounded album covers" option is no longer dependent on "Show album covers" option - "Rounded album covers" option is no longer dependent on "Show album covers" option
- Added song actions to the playback panel - Added song actions to the playback panel
- Playback controls are now easier to reach when gesture navigation is enabled
#### What's Fixed #### What's Fixed
- Playback bar now picks the larger inset in case that gesture inset is missing [#149] - Playback bar now picks the larger inset in case that gesture inset is missing [#149]

View file

@ -20,7 +20,6 @@ package org.oxycblt.auxio.detail
import android.os.Bundle import android.os.Bundle
import android.text.format.Formatter import android.text.format.Formatter
import android.view.LayoutInflater import android.view.LayoutInflater
import android.webkit.MimeTypeMap
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@ -34,7 +33,6 @@ import org.oxycblt.auxio.util.launch
class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() { class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
private val detailModel: DetailViewModel by activityViewModels() private val detailModel: DetailViewModel by activityViewModels()
private val mimeTypes = MimeTypeMap.getSingleton()
override fun onCreateBinding(inflater: LayoutInflater) = override fun onCreateBinding(inflater: LayoutInflater) =
DialogSongDetailBinding.inflate(inflater) DialogSongDetailBinding.inflate(inflater)
@ -83,41 +81,6 @@ class SongDetailDialog : ViewBindingDialogFragment<DialogSongDetailBinding>() {
} }
} }
private fun getMimeName(mime: String): String? {
return when (mime) {
// Since Auxio only feasibly loads music, we can match for general mime types
// and assume that they are audio-based.
// Classic formats
"audio/mpeg",
"audio/mp3" -> "MPEG-1 Layer 3"
"audio/ogg",
"application/ogg" -> "OGG"
"audio/vorbis" -> "OGG Vorbis"
"audio/opus" -> "OGG Opus"
"audio/flac" -> "(OGG) FLAC"
// Modern formats
"audio/mp4",
"audio/mp4a-latm",
"audio/mpeg4-generic",
"audio/aac",
"audio/3gpp",
"audio/3gpp2", -> "Advanced Audio Coding (AAC)"
"audio/x-matroska" -> "Matroska Audio (MKA)"
// Windows formats
"audio/wav",
"audio/x-wav",
"audio/wave",
"audio/vnd.wave" -> "Microsoft WAV"
"audio/x-ms-wma" -> "Windows Media Audio (WMA)"
// Don't know, fall back to an extension
else -> mimeTypes.getExtensionFromMimeType(mime)?.uppercase()
}
}
companion object { companion object {
fun from(song: Song): SongDetailDialog { fun from(song: Song): SongDetailDialog {
val instance = SongDetailDialog() val instance = SongDetailDialog()

View file

@ -89,15 +89,15 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
} }
binding.homeAppbar.apply { binding.homeAppbar.apply {
addOnOffsetChangedListener( addOnOffsetChangedListener { _, offset ->
AppBarLayout.OnOffsetChangedListener { _, offset ->
val range = binding.homeAppbar.totalScrollRange val range = binding.homeAppbar.totalScrollRange
binding.homeToolbar.alpha = 1f - (abs(offset.toFloat()) / (range.toFloat() / 2)) binding.homeToolbar.alpha = 1f - (abs(offset.toFloat()) / (range.toFloat() / 2))
binding.homeContent.updatePadding( binding.homeContent.updatePadding(
bottom = binding.homeAppbar.totalScrollRange + offset) bottom = binding.homeAppbar.totalScrollRange + offset
}) )
}
} }
binding.homeToolbar.apply { binding.homeToolbar.apply {

View file

@ -19,6 +19,7 @@ package org.oxycblt.auxio.music
import android.content.Context import android.content.Context
import android.webkit.MimeTypeMap import android.webkit.MimeTypeMap
import com.google.android.exoplayer2.util.MimeTypes
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
/** /**
@ -74,52 +75,34 @@ sealed class Dir {
*/ */
data class MimeType(val fromExtension: String, val fromFormat: String?) { data class MimeType(val fromExtension: String, val fromFormat: String?) {
fun resolveName(context: Context): String { fun resolveName(context: Context): String {
// Prefer the format mime type first, as it actually is derived from the file // While it would be nice to have more refined mime type names (Layer I/II/III, containers,
// and not the extension. Just make sure to ignore audio/raw, as that could feasibly // etc.), it's not exactly practical with ExoPlayer. So, we go for the next best thing
// correspond to multiple formats. // and try to find a good enough readable name to use.
val readableMime =
if (fromFormat != null && fromFormat != "audio/raw") {
fromFormat
} else {
fromExtension
}
// We have special names for the most common formats.
val readableStringRes = val readableStringRes =
when (readableMime) { if (fromFormat != null && fromFormat != MimeTypes.AUDIO_RAW) {
// MPEG formats // Prefer the extracted mime type, as it properly handles container formats and
// While MP4 is AAC, it's considered separate given how common it is. // is agnostic to the file extension
"audio/mpeg", when (fromFormat) {
"audio/mp3" -> R.string.cdc_mp3 MimeTypes.AUDIO_MPEG,
"audio/mp4", MimeTypes.AUDIO_MPEG_L1,
"audio/mp4a-latm", MimeTypes.AUDIO_MPEG_L2 -> R.string.cdc_mp3
"audio/mpeg4-generic" -> R.string.cdc_mp4 MimeTypes.AUDIO_AAC -> R.string.cdc_mp4
MimeTypes.AUDIO_VORBIS -> R.string.cdc_ogg_vorbis
// Free formats MimeTypes.AUDIO_OPUS -> R.string.cdc_ogg_opus
// Generic Ogg is included here as it's actually formatted as "Ogg", not "OGG" MimeTypes.AUDIO_WAV -> R.string.cdc_wav
"audio/ogg",
"application/ogg" -> R.string.cdc_ogg
"audio/vorbis" -> R.string.cdc_ogg_vorbis
"audio/opus" -> R.string.cdc_ogg_opus
"audio/flac" -> R.string.cdc_flac
// The other AAC containers have a generic name
"audio/aac",
"audio/aacp",
"audio/aac-adts",
"audio/3gpp",
"audio/3gpp2", -> R.string.cdc_aac
// Windows formats
"audio/wav",
"audio/x-wav",
"audio/wave",
"audio/vnd.wave" -> R.string.cdc_wav
"audio/x-ms-wma" -> R.string.cdc_wma
// Don't know
else -> -1 else -> -1
} }
} else {
// Fall back to the file extension in the case that we have a useless
when (fromExtension) {
"audio/mpeg" -> R.string.cdc_mp3
"audio/mp4" -> R.string.cdc_mp4
"audio/ogg" -> R.string.cdc_ogg
"audio/x-wav" -> R.string.cdc_wav
"audio/x-matroska" -> R.string.cdc_mka
else -> -1
}
}
return if (readableStringRes > -1) { return if (readableStringRes > -1) {
context.getString(readableStringRes) context.getString(readableStringRes)

View file

@ -24,6 +24,7 @@ import androidx.appcompat.widget.Toolbar
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import kotlin.math.max
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding import org.oxycblt.auxio.databinding.FragmentPlaybackPanelBinding
import org.oxycblt.auxio.detail.SongDetailDialog import org.oxycblt.auxio.detail.SongDetailDialog
@ -35,6 +36,7 @@ import org.oxycblt.auxio.ui.NavigationViewModel
import org.oxycblt.auxio.ui.ViewBindingFragment import org.oxycblt.auxio.ui.ViewBindingFragment
import org.oxycblt.auxio.util.getDrawableSafe import org.oxycblt.auxio.util.getDrawableSafe
import org.oxycblt.auxio.util.getSystemBarInsetsCompat import org.oxycblt.auxio.util.getSystemBarInsetsCompat
import org.oxycblt.auxio.util.getSystemGestureInsetsCompat
import org.oxycblt.auxio.util.launch import org.oxycblt.auxio.util.launch
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.textSafe import org.oxycblt.auxio.util.textSafe
@ -67,8 +69,13 @@ class PlaybackPanelFragment :
// --- UI SETUP --- // --- UI SETUP ---
binding.root.setOnApplyWindowInsetsListener { view, insets -> binding.root.setOnApplyWindowInsetsListener { view, insets ->
// The playback controls should be inset upwards at least a little bit more than usual,
// just for quality of life. While the old 3-button navigation does this for us, when
// bar navigation is used, we use the gesture padding to add that extra portion of
// space.
val bars = insets.getSystemBarInsetsCompat(view) val bars = insets.getSystemBarInsetsCompat(view)
view.updatePadding(top = bars.top, bottom = bars.bottom) val gestures = insets.getSystemGestureInsetsCompat(view)
view.updatePadding(top = bars.top, bottom = max(gestures.bottom, bars.bottom))
insets insets
} }

View file

@ -38,10 +38,7 @@ import org.oxycblt.auxio.util.logD
* hot garbage. This shouldn't have *too many* UI bugs. I hope. * hot garbage. This shouldn't have *too many* UI bugs. I hope.
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class QueueDragCallback( class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouchHelper.Callback() {
private val playbackModel: PlaybackViewModel,
private val queueAdapter: QueueAdapter
) : ItemTouchHelper.Callback() {
private var shouldLift = true private var shouldLift = true
override fun getMovementFlags( override fun getMovementFlags(

View file

@ -82,7 +82,7 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), QueueItemList
if (instance != null) { if (instance != null) {
return instance return instance
} }
val newCallback = QueueDragCallback(playbackModel, queueAdapter) val newCallback = QueueDragCallback(playbackModel)
val newInstance = ItemTouchHelper(newCallback) val newInstance = ItemTouchHelper(newCallback)
callback = newCallback callback = newCallback
touchHelper = newInstance touchHelper = newInstance

View file

@ -131,28 +131,6 @@ fun Context.getAttrColorSafe(@AttrRes attr: Int): Int {
return getColorSafe(color) return getColorSafe(color)
} }
/**
* Convenience method for getting a color attribute safely.
* @param attr The color attribute
* @return The attribute requested, or black if an error occurred.
*/
@ColorInt
fun Context.getAttrStateListSafe(@AttrRes attr: Int): ColorStateList {
// First resolve the attribute into its ID
val resolvedAttr = TypedValue()
theme.resolveAttribute(attr, resolvedAttr, true)
// Then convert it to a proper color
val color =
if (resolvedAttr.resourceId != 0) {
resolvedAttr.resourceId
} else {
resolvedAttr.data
}
return getColorStateListSafe(color)
}
/** /**
* Convenience method for getting a [Drawable] safely. * Convenience method for getting a [Drawable] safely.
* @param drawable The drawable resource * @param drawable The drawable resource

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Dialog style that properly impelments dividers in a NestedScrollView --> <!-- Dialog style that properly implements dividers in a NestedScrollView -->
<style name="Widget.Auxio.Dialog.NestedScrollView" parent=""> <style name="Widget.Auxio.Dialog.NestedScrollView" parent="">
<item name="android:overScrollMode">never</item> <item name="android:overScrollMode">never</item>
<item name="android:scrollIndicators">top|bottom</item> <item name="android:scrollIndicators">top|bottom</item>

View file

@ -8,7 +8,12 @@
<string name="fmt_three" translatable="false">%1$s • %2$s • %3$s</string> <string name="fmt_three" translatable="false">%1$s • %2$s • %3$s</string>
<string name="fmt_number" translatable="false">%d</string> <string name="fmt_number" translatable="false">%d</string>
<!-- Note: These are stopgap measures until we make the path code rely on android components! --> <!-- Codec Namespace | Format names -->
<string name="cdc_ogg_vorbis">Ogg Vorbis</string>
<string name="cdc_ogg_opus">Ogg Opus</string>
<string name="cdc_wav">Microsoft WAVE</string>
<!-- Note: These are stopgap measures until we make the path code rely on components! -->
<string name="fmt_primary_path">Internal:%s</string> <string name="fmt_primary_path">Internal:%s</string>
<string name="fmt_secondary_path">SDCARD:%s</string> <string name="fmt_secondary_path">SDCARD:%s</string>
</resources> </resources>

View file

@ -51,7 +51,7 @@
<string name="lbl_props">Song properties</string> <string name="lbl_props">Song properties</string>
<string name="lbl_file_name">File name</string> <string name="lbl_file_name">File name</string>
<string name="lbl_relative_path">Relative path</string> <string name="lbl_relative_path">Parent path</string>
<string name="lbl_format">Format</string> <string name="lbl_format">Format</string>
<string name="lbl_size">Size</string> <string name="lbl_size">Size</string>
<string name="lbl_bitrate">Bitrate</string> <string name="lbl_bitrate">Bitrate</string>
@ -181,15 +181,10 @@
<string name="def_widget_artist">Artist Name</string> <string name="def_widget_artist">Artist Name</string>
<!-- Codec Namespace | Format names --> <!-- Codec Namespace | Format names -->
<string name="cdc_mp3">MPEG-1 Layer 3 </string> <string name="cdc_mp3">MPEG-1 Audio</string>
<string name="cdc_mp4">MPEG-4 Audio (AAC)</string> <string name="cdc_mp4">MPEG-4 Audio</string>
<string name="cdc_ogg">Ogg</string> <string name="cdc_ogg">Ogg Audio</string>
<string name="cdc_ogg_vorbis">Ogg Vorbis</string> <string name="cdc_mka">Matroska Audio</string>
<string name="cdc_ogg_opus">Ogg Opus</string>
<string name="cdc_flac">Free Lossless Audio Codec (FLAC)</string>
<string name="cdc_aac">Advanced Audio Coding (AAC)</string>
<string name="cdc_wav">Microsoft WAVE</string>
<string name="cdc_wma">Windows Media Audio (WMA)</string>
<!-- Color Label namespace | Accent names --> <!-- Color Label namespace | Accent names -->
<string name="clr_red">Red</string> <string name="clr_red">Red</string>

View file

@ -33,7 +33,7 @@
<item name="android:layout_marginStart">0dp</item> <item name="android:layout_marginStart">0dp</item>
</style> </style>
<!-- Dialog style that properly impelments dividers in a NestedScrollView --> <!-- Dialog style that properly implements dividers in a NestedScrollView -->
<style name="Widget.Auxio.Dialog.NestedScrollView" parent=""> <style name="Widget.Auxio.Dialog.NestedScrollView" parent="">
<item name="android:overScrollMode">never</item> <item name="android:overScrollMode">never</item>
<item name="android:paddingTop">@dimen/spacing_medium</item> <item name="android:paddingTop">@dimen/spacing_medium</item>