From 608112a7ac89360290d0b179eca0b66b1ae7d81b Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sat, 19 Mar 2022 19:57:57 -0600 Subject: [PATCH] all: migrate to centralized constant table Migrate to a centralized constant table for easier management. Previously, Auxio would tie constants to the class itself, which led to a largely disjointed system that relied on an internal table so that it would stay sane. This commit moves all of those constants to a single table for easier usage and management. --- .../main/java/org/oxycblt/auxio/AuxioApp.kt | 3 - .../java/org/oxycblt/auxio/IntegerTable.kt | 101 ++++++++++++++++++ .../detail/recycler/AlbumDetailAdapter.kt | 18 ++-- .../detail/recycler/ArtistDetailAdapter.kt | 27 ++--- .../detail/recycler/GenreDetailAdapter.kt | 18 ++-- .../home/fastscroll/FastScrollPopupView.kt | 2 +- .../auxio/playback/queue/QueueAdapter.kt | 17 ++- .../oxycblt/auxio/playback/state/LoopMode.kt | 28 +++-- .../auxio/playback/state/PlaybackMode.kt | 32 +++--- .../playback/state/PlaybackStateDatabase.kt | 8 +- .../playback/system/PlaybackNotification.kt | 2 - .../auxio/playback/system/PlaybackService.kt | 10 +- .../auxio/playback/system/ReplayGainMode.kt | 28 ++--- .../org/oxycblt/auxio/search/SearchAdapter.kt | 21 ++-- .../oxycblt/auxio/settings/SettingsManager.kt | 41 ++++--- .../java/org/oxycblt/auxio/ui/DisplayMode.kt | 39 +++---- .../main/java/org/oxycblt/auxio/ui/Sort.kt | 101 ++++++++++-------- .../java/org/oxycblt/auxio/ui/ViewHolders.kt | 12 --- .../org/oxycblt/auxio/util/ContextUtil.kt | 7 +- .../java/org/oxycblt/auxio/util/ViewUtil.kt | 3 +- app/src/main/res/values-zh-rCN/strings.xml | 2 - app/src/main/res/values/integers.xml | 1 + info/ARCHITECTURE.md | 54 +--------- 23 files changed, 293 insertions(+), 282 deletions(-) create mode 100644 app/src/main/java/org/oxycblt/auxio/IntegerTable.kt diff --git a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt index 09fabdcfd..e69342276 100644 --- a/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt +++ b/app/src/main/java/org/oxycblt/auxio/AuxioApp.kt @@ -36,9 +36,6 @@ import org.oxycblt.auxio.settings.SettingsManager * - Rework RecyclerView management and item dragging * - Rework sealed classes to minimize whens and maximize overrides * ``` - * - * TODO: Dumpster int-codes for a 4-byte identifier (can still be in the form of an int) For - * example, instead of 0xA111 for ReplayGainMode.TRACK, you would instead have RTCK */ @Suppress("UNUSED") class AuxioApp : Application(), ImageLoaderFactory { diff --git a/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt new file mode 100644 index 000000000..7ea9406cf --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/IntegerTable.kt @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022 Auxio Project + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.oxycblt.auxio + +object IntegerTable { + /** SongViewHolder */ + const val ITEM_TYPE_SONG = 0xA000 + /** AlbumViewHolder */ + const val ITEM_TYPE_ALBUM = 0xA001 + /** ArtistViewHolder */ + const val ITEM_TYPE_ARTIST = 0xA002 + /** GenreViewHolder */ + const val ITEM_TYPE_GENRE = 0xA003 + /** HeaderViewHolder */ + const val ITEM_TYPE_HEADER = 0xA004 + /** ActionHeaderViewHolder */ + const val ITEM_TYPE_ACTION_HEADER = 0xA005 + + /** AlbumDetailViewHolder */ + const val ITEM_TYPE_ALBUM_DETAIL = 0xA006 + /** AlbumSongViewHolder */ + const val ITEM_TYPE_ALBUM_SONG = 0xA007 + /** ArtistDetailViewHolder */ + const val ITEM_TYPE_ARTIST_DETAIL = 0xA008 + /** ArtistAlbumViewHolder */ + const val ITEM_TYPE_ARTIST_ALBUM = 0xA009 + /** ArtistSongViewHolder */ + const val ITEM_TYPE_ARTIST_SONG = 0xA00A + /** GenreDetailViewHolder */ + const val ITEM_TYPE_GENRE_DETAIL = 0xA00B + /** GenreSongViewHolder */ + const val ITEM_TYPE_GENRE_SONG = 0xA00C + + /** QueueSongViewHolder */ + const val ITEM_TYPE_QUEUE_SONG = 0xA00D + + /** "Music playback" Notification channel */ + const val NOTIFICATION_CODE = 0xA0A0 + /** Intent request code */ + const val REQUEST_CODE = 0xA0C0 + + /** LoopMode.NONE */ + const val LOOP_MODE_NONE = 0xA100 + /** LoopMode.ALL */ + const val LOOP_MODE_ALL = 0xA101 + /** LoopMode.TRACK */ + const val LOOP_MODE_TRACK = 0xA102 + + /** PlaybackMode.IN_GENRE */ + const val PLAYBACK_MODE_IN_GENRE = 0xA103 + /** PlaybackMode.IN_ARTIST */ + const val PLAYBACK_MODE_IN_ARTIST = 0xA104 + /** PlaybackMode.IN_ALBUM */ + const val PLAYBACK_MODE_IN_ALBUM = 0xA105 + /** PlaybackMode.ALL_SONGS */ + const val PLAYBACK_MODE_ALL_SONGS = 0xA106 + + /** DisplayMode.NONE (No Longer used but still reserved) */ + // const val DISPLAY_MODE_NONE = 0xA107 + /** DisplayMode.SHOW_GENRES */ + const val DISPLAY_MODE_SHOW_GENRES = 0xA108 + /** DisplayMode.SHOW_ARTISTS */ + const val DISPLAY_MODE_SHOW_ARTISTS = 0xA109 + /** DisplayMode.SHOW_ALBUMS */ + const val DISPLAY_MODE_SHOW_ALBUMS = 0xA10A + /** DisplayMode.SHOW_SONGS */ + const val DISPLAY_MODE_SHOW_SONGS = 0xA10B + + /** Sort.ByName */ + const val SORT_BY_NAME = 0xA10C + /** Sort.ByArtist */ + const val SORT_BY_ARTIST = 0xA10D + /** Sort.ByAlbum */ + const val SORT_BY_ALBUM = 0xA10E + /** Sort.ByYear */ + const val SORT_BY_YEAR = 0xA10F + + /** ReplayGainMode.Off */ + const val REPLAY_GAIN_MODE_OFF = 0xA110 + /** ReplayGainMode.Track */ + const val REPLAY_GAIN_MODE_TRACK = 0xA111 + /** ReplayGainMode.Album */ + const val REPLAY_GAIN_MODE_ALBUM = 0xA112 + /** ReplayGainMode.Dynamic */ + const val REPLAY_GAIN_MODE_DYNAMIC = 0xA113 +} diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt index 29e362868..851e433b7 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/AlbumDetailAdapter.kt @@ -22,6 +22,7 @@ import android.view.ViewGroup import androidx.core.view.isInvisible import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R import org.oxycblt.auxio.coil.bindAlbumArt import org.oxycblt.auxio.databinding.ItemAlbumSongBinding @@ -53,20 +54,20 @@ class AlbumDetailAdapter( override fun getItemViewType(position: Int): Int { return when (getItem(position)) { - is Album -> ALBUM_DETAIL_ITEM_TYPE - is ActionHeader -> ActionHeaderViewHolder.ITEM_TYPE - is Song -> ALBUM_SONG_ITEM_TYPE + is Album -> IntegerTable.ITEM_TYPE_ALBUM_DETAIL + is ActionHeader -> IntegerTable.ITEM_TYPE_ACTION_HEADER + is Song -> IntegerTable.ITEM_TYPE_ALBUM_SONG else -> -1 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - ALBUM_DETAIL_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ALBUM_DETAIL -> AlbumDetailViewHolder(ItemDetailBinding.inflate(parent.context.inflater)) - ALBUM_SONG_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ACTION_HEADER -> ActionHeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_ALBUM_SONG -> AlbumSongViewHolder(ItemAlbumSongBinding.inflate(parent.context.inflater)) - ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) else -> error("Invalid ViewHolder item type $viewType") } } @@ -172,9 +173,4 @@ class AlbumDetailAdapter( binding.songTrackPlaceholder.isActivated = isHighlighted } } - - companion object { - const val ALBUM_DETAIL_ITEM_TYPE = 0xA006 - const val ALBUM_SONG_ITEM_TYPE = 0xA007 - } } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt index 499114da3..556f8657c 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/ArtistDetailAdapter.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R import org.oxycblt.auxio.coil.bindArtistImage import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding @@ -58,25 +59,25 @@ class ArtistDetailAdapter( override fun getItemViewType(position: Int): Int { return when (getItem(position)) { - is Artist -> ARTIST_DETAIL_ITEM_TYPE - is Album -> ARTIST_ALBUM_ITEM_TYPE - is Song -> ARTIST_SONG_ITEM_TYPE - is Header -> HeaderViewHolder.ITEM_TYPE - is ActionHeader -> ActionHeaderViewHolder.ITEM_TYPE + is Artist -> IntegerTable.ITEM_TYPE_ARTIST_DETAIL + is Album -> IntegerTable.ITEM_TYPE_ARTIST_ALBUM + is Song -> IntegerTable.ITEM_TYPE_ARTIST_SONG + is Header -> IntegerTable.ITEM_TYPE_HEADER + is ActionHeader -> IntegerTable.ITEM_TYPE_ACTION_HEADER else -> -1 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - ARTIST_DETAIL_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ARTIST_DETAIL -> ArtistDetailViewHolder(ItemDetailBinding.inflate(parent.context.inflater)) - ARTIST_ALBUM_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ARTIST_ALBUM -> ArtistAlbumViewHolder(ItemArtistAlbumBinding.inflate(parent.context.inflater)) - ARTIST_SONG_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ARTIST_SONG -> ArtistSongViewHolder(ItemArtistSongBinding.inflate(parent.context.inflater)) - HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context) - ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_HEADER -> HeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_ACTION_HEADER -> ActionHeaderViewHolder.from(parent.context) else -> error("Invalid ViewHolder item type $viewType") } } @@ -222,10 +223,4 @@ class ArtistDetailAdapter( binding.songName.isActivated = isHighlighted } } - - companion object { - const val ARTIST_DETAIL_ITEM_TYPE = 0xA008 - const val ARTIST_ALBUM_ITEM_TYPE = 0xA009 - const val ARTIST_SONG_ITEM_TYPE = 0xA00A - } } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt index 8704bf4c8..f8932023b 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R import org.oxycblt.auxio.coil.bindGenreImage import org.oxycblt.auxio.databinding.ItemDetailBinding @@ -50,22 +51,22 @@ class GenreDetailAdapter( override fun getItemViewType(position: Int): Int { return when (getItem(position)) { - is Genre -> GENRE_DETAIL_ITEM_TYPE - is ActionHeader -> ActionHeaderViewHolder.ITEM_TYPE - is Song -> GENRE_SONG_ITEM_TYPE + is Genre -> IntegerTable.ITEM_TYPE_GENRE_DETAIL + is ActionHeader -> IntegerTable.ITEM_TYPE_ACTION_HEADER + is Song -> IntegerTable.ITEM_TYPE_GENRE_SONG else -> -1 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - GENRE_DETAIL_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_GENRE_DETAIL -> GenreDetailViewHolder(ItemDetailBinding.inflate(parent.context.inflater)) - GENRE_SONG_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ACTION_HEADER -> ActionHeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_GENRE_SONG -> GenreSongViewHolder( ItemGenreSongBinding.inflate(parent.context.inflater), ) - ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) else -> error("Bad ViewHolder item type $viewType") } } @@ -154,9 +155,4 @@ class GenreDetailAdapter( binding.songName.isActivated = isHighlighted } } - - companion object { - const val GENRE_DETAIL_ITEM_TYPE = 0xA00B - const val GENRE_SONG_ITEM_TYPE = 0xA00C - } } diff --git a/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollPopupView.kt b/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollPopupView.kt index 9619016e5..aec9460d7 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollPopupView.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/fastscroll/FastScrollPopupView.kt @@ -156,7 +156,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleRes: Int = 0) startAngle: Float, sweepAngle: Float ) { - path.arcTo( + arcTo( centerX - radius, centerY - radius, centerX + radius, diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt index 6e9e5a8fd..19703d5b9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt @@ -27,6 +27,7 @@ import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.google.android.material.shape.MaterialShapeDrawable +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.databinding.ItemQueueSongBinding import org.oxycblt.auxio.music.ActionHeader import org.oxycblt.auxio.music.Header @@ -55,19 +56,19 @@ class QueueAdapter(private val touchHelper: ItemTouchHelper) : override fun getItemViewType(position: Int): Int { return when (data[position]) { - is Song -> QUEUE_SONG_ITEM_TYPE - is Header -> HeaderViewHolder.ITEM_TYPE - is ActionHeader -> ActionHeaderViewHolder.ITEM_TYPE + is Song -> IntegerTable.ITEM_TYPE_QUEUE_SONG + is Header -> IntegerTable.ITEM_TYPE_HEADER + is ActionHeader -> IntegerTable.ITEM_TYPE_ACTION_HEADER else -> -1 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - QUEUE_SONG_ITEM_TYPE -> + IntegerTable.ITEM_TYPE_QUEUE_SONG -> QueueSongViewHolder(ItemQueueSongBinding.inflate(parent.context.inflater)) - HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context) - ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_HEADER -> HeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_ACTION_HEADER -> ActionHeaderViewHolder.from(parent.context) else -> error("Invalid ViewHolder item type $viewType") } } @@ -146,8 +147,4 @@ class QueueAdapter(private val touchHelper: ItemTouchHelper) : } } } - - companion object { - const val QUEUE_SONG_ITEM_TYPE = 0xA00D - } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt index a7ca40828..4a8e9f92f 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt @@ -17,6 +17,8 @@ package org.oxycblt.auxio.playback.state +import org.oxycblt.auxio.IntegerTable + /** * Enum that determines the playback repeat mode. * @author OxygenCobalt @@ -39,25 +41,21 @@ enum class LoopMode { * Convert the LoopMode to an int constant that is saved in PlaybackStateDatabase * @return The int constant for this mode */ - fun toInt(): Int { - return when (this) { - NONE -> INT_NONE - ALL -> INT_ALL - TRACK -> INT_TRACK - } - } + val intCode: Int + get() = + when (this) { + NONE -> IntegerTable.LOOP_MODE_NONE + ALL -> IntegerTable.LOOP_MODE_ALL + TRACK -> IntegerTable.LOOP_MODE_TRACK + } companion object { - private const val INT_NONE = 0xA100 - private const val INT_ALL = 0xA101 - private const val INT_TRACK = 0xA102 - /** Convert an int [constant] into a LoopMode, or null if it isn't valid. */ - fun fromInt(constant: Int): LoopMode? { + fun fromIntCode(constant: Int): LoopMode? { return when (constant) { - INT_NONE -> NONE - INT_ALL -> ALL - INT_TRACK -> TRACK + IntegerTable.LOOP_MODE_NONE -> NONE + IntegerTable.LOOP_MODE_ALL -> ALL + IntegerTable.LOOP_MODE_TRACK -> TRACK else -> null } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackMode.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackMode.kt index 2c49d25de..194f32e23 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackMode.kt @@ -17,6 +17,8 @@ package org.oxycblt.auxio.playback.state +import org.oxycblt.auxio.IntegerTable + /** * Enum that indicates how the queue should be constructed. * @author OxygenCobalt @@ -35,32 +37,26 @@ enum class PlaybackMode { * Convert the mode into an int constant, to be saved in PlaybackStateDatabase * @return The constant for this mode, */ - fun toInt(): Int { - return when (this) { - ALL_SONGS -> INT_ALL_SONGS - IN_ALBUM -> INT_IN_ALBUM - IN_ARTIST -> INT_IN_ARTIST - IN_GENRE -> INT_IN_GENRE - } - } + val intCode: Int + get() = + when (this) { + ALL_SONGS -> IntegerTable.PLAYBACK_MODE_ALL_SONGS + IN_ALBUM -> IntegerTable.PLAYBACK_MODE_IN_ALBUM + IN_ARTIST -> IntegerTable.PLAYBACK_MODE_IN_ARTIST + IN_GENRE -> IntegerTable.PLAYBACK_MODE_IN_GENRE + } companion object { - // Kept in reverse order because of backwards compat, do not re-order these - private const val INT_ALL_SONGS = 0xA106 - private const val INT_IN_ALBUM = 0xA105 - private const val INT_IN_ARTIST = 0xA104 - private const val INT_IN_GENRE = 0xA103 - /** * Get a [PlaybackMode] for an int [constant] * @return The mode, null if there isn't one for this. */ fun fromInt(constant: Int): PlaybackMode? { return when (constant) { - INT_ALL_SONGS -> ALL_SONGS - INT_IN_ALBUM -> IN_ALBUM - INT_IN_ARTIST -> IN_ARTIST - INT_IN_GENRE -> IN_GENRE + IntegerTable.PLAYBACK_MODE_ALL_SONGS -> ALL_SONGS + IntegerTable.PLAYBACK_MODE_IN_ALBUM -> IN_ALBUM + IntegerTable.PLAYBACK_MODE_IN_ARTIST -> IN_ARTIST + IntegerTable.PLAYBACK_MODE_IN_GENRE -> IN_GENRE else -> null } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt index c899c8be3..12116f21c 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateDatabase.kt @@ -34,6 +34,8 @@ import org.oxycblt.auxio.util.queryAll * A SQLite database for managing the persistent playback state and queue. Yes. I know Room exists. * But that would needlessly bloat my app and has crippling bugs. * @author OxygenCobalt + * + * TODO: Rework to rely on queue indices more and only use specific items as fallbacks */ class PlaybackStateDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) { @@ -144,7 +146,7 @@ class PlaybackStateDatabase(context: Context) : queueIndex = cursor.getInt(indexIndex), playbackMode = mode, isShuffling = cursor.getInt(shuffleIndex) == 1, - loopMode = LoopMode.fromInt(cursor.getInt(loopModeIndex)) ?: LoopMode.NONE, + loopMode = LoopMode.fromIntCode(cursor.getInt(loopModeIndex)) ?: LoopMode.NONE, ) logD("Successfully read playback state: $state") @@ -169,9 +171,9 @@ class PlaybackStateDatabase(context: Context) : put(StateColumns.COLUMN_POSITION, state.position) put(StateColumns.COLUMN_PARENT_HASH, state.parent?.id) put(StateColumns.COLUMN_QUEUE_INDEX, state.queueIndex) - put(StateColumns.COLUMN_PLAYBACK_MODE, state.playbackMode.toInt()) + put(StateColumns.COLUMN_PLAYBACK_MODE, state.playbackMode.intCode) put(StateColumns.COLUMN_IS_SHUFFLING, state.isShuffling) - put(StateColumns.COLUMN_LOOP_MODE, state.loopMode.toInt()) + put(StateColumns.COLUMN_LOOP_MODE, state.loopMode.intCode) } insert(TABLE_NAME_STATE, null, stateData) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt index de315b24f..a3955c84b 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt @@ -49,7 +49,6 @@ private constructor(private val context: Context, mediaToken: MediaSessionCompat setCategory(NotificationCompat.CATEGORY_SERVICE) setShowWhen(false) setSilent(true) - setBadgeIconType(NotificationCompat.BADGE_ICON_NONE) setContentIntent(context.newMainIntent()) setVisibility(NotificationCompat.VISIBILITY_PUBLIC) @@ -159,7 +158,6 @@ private constructor(private val context: Context, mediaToken: MediaSessionCompat companion object { const val CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel.PLAYBACK" - const val NOTIFICATION_ID = 0xA0A0 /** Build a new instance of [PlaybackNotification]. */ fun from( diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index 3e4662d21..c6c92c35c 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -51,6 +51,7 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.launch import org.oxycblt.auxio.BuildConfig +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.state.LoopMode @@ -407,18 +408,17 @@ class PlaybackService : // Specify that this is a media service, if supported. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { startForeground( - PlaybackNotification.NOTIFICATION_ID, + IntegerTable.NOTIFICATION_CODE, notification.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK) } else { - startForeground(PlaybackNotification.NOTIFICATION_ID, notification.build()) + startForeground(IntegerTable.NOTIFICATION_CODE, notification.build()) } isForeground = true } else { // If we are already in foreground just update the notification - notificationManager.notify( - PlaybackNotification.NOTIFICATION_ID, notification.build()) + notificationManager.notify(IntegerTable.NOTIFICATION_CODE, notification.build()) } } } @@ -426,7 +426,7 @@ class PlaybackService : /** Stop the foreground state and hide the notification */ private fun stopForegroundAndNotification() { stopForeground(true) - notificationManager.cancel(PlaybackNotification.NOTIFICATION_ID) + notificationManager.cancel(IntegerTable.NOTIFICATION_CODE) isForeground = false } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/ReplayGainMode.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/ReplayGainMode.kt index fba56c0f9..d9269de48 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/ReplayGainMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/ReplayGainMode.kt @@ -17,6 +17,8 @@ package org.oxycblt.auxio.playback.system +import org.oxycblt.auxio.IntegerTable + /** Represents the current setting for ReplayGain. */ enum class ReplayGainMode { /** Do not apply ReplayGain. */ @@ -28,29 +30,13 @@ enum class ReplayGainMode { /** Apply the album gain only when playing from an album, defaulting to track gain otherwise. */ DYNAMIC; - /** Converts this type to an integer constant. */ - fun toInt(): Int { - return when (this) { - OFF -> INT_OFF - TRACK -> INT_TRACK - ALBUM -> INT_ALBUM - DYNAMIC -> INT_DYNAMIC - } - } - companion object { - private const val INT_OFF = 0xA110 - private const val INT_TRACK = 0xA111 - private const val INT_ALBUM = 0xA112 - private const val INT_DYNAMIC = 0xA113 - - /** Converts an integer constant to this type. */ - fun fromInt(value: Int): ReplayGainMode? { + fun fromIntCode(value: Int): ReplayGainMode? { return when (value) { - INT_OFF -> OFF - INT_TRACK -> TRACK - INT_ALBUM -> ALBUM - INT_DYNAMIC -> DYNAMIC + IntegerTable.REPLAY_GAIN_MODE_OFF -> OFF + IntegerTable.REPLAY_GAIN_MODE_TRACK -> TRACK + IntegerTable.REPLAY_GAIN_MODE_ALBUM -> ALBUM + IntegerTable.REPLAY_GAIN_MODE_DYNAMIC -> DYNAMIC else -> null } } diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt index 4b3d6f7ae..b57a43e02 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt @@ -21,6 +21,7 @@ import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre @@ -46,26 +47,26 @@ class SearchAdapter( override fun getItemViewType(position: Int): Int { return when (getItem(position)) { - is Genre -> GenreViewHolder.ITEM_TYPE - is Artist -> ArtistViewHolder.ITEM_TYPE - is Album -> AlbumViewHolder.ITEM_TYPE - is Song -> SongViewHolder.ITEM_TYPE - is Header -> HeaderViewHolder.ITEM_TYPE + is Genre -> IntegerTable.ITEM_TYPE_GENRE + is Artist -> IntegerTable.ITEM_TYPE_ARTIST + is Album -> IntegerTable.ITEM_TYPE_ALBUM + is Song -> IntegerTable.ITEM_TYPE_SONG + is Header -> IntegerTable.ITEM_TYPE_HEADER else -> -1 } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { return when (viewType) { - GenreViewHolder.ITEM_TYPE -> + IntegerTable.ITEM_TYPE_GENRE -> GenreViewHolder.from(parent.context, doOnClick, doOnLongClick) - ArtistViewHolder.ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ARTIST -> ArtistViewHolder.from(parent.context, doOnClick, doOnLongClick) - AlbumViewHolder.ITEM_TYPE -> + IntegerTable.ITEM_TYPE_ALBUM -> AlbumViewHolder.from(parent.context, doOnClick, doOnLongClick) - SongViewHolder.ITEM_TYPE -> + IntegerTable.ITEM_TYPE_SONG -> SongViewHolder.from(parent.context, doOnClick, doOnLongClick) - HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context) + IntegerTable.ITEM_TYPE_HEADER -> HeaderViewHolder.from(parent.context) else -> error("Invalid ViewHolder item type") } } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 70267a1df..21038a85c 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -104,7 +104,7 @@ class SettingsManager private constructor(context: Context) : /** The current ReplayGain configuration */ val replayGainMode: ReplayGainMode get() = - ReplayGainMode.fromInt(prefs.getInt(KEY_REPLAY_GAIN, Int.MIN_VALUE)) + ReplayGainMode.fromIntCode(prefs.getInt(KEY_REPLAY_GAIN, Int.MIN_VALUE)) ?: ReplayGainMode.OFF /** What queue to create when a song is selected (ex. From All Songs or Search) */ @@ -129,50 +129,54 @@ class SettingsManager private constructor(context: Context) : /** The current filter mode of the search tab */ var searchFilterMode: DisplayMode? - get() = DisplayMode.fromFilterInt(prefs.getInt(KEY_SEARCH_FILTER_MODE, Int.MIN_VALUE)) + get() = DisplayMode.fromInt(prefs.getInt(KEY_SEARCH_FILTER_MODE, Int.MIN_VALUE)) set(value) { prefs.edit { - putInt(KEY_SEARCH_FILTER_MODE, DisplayMode.toFilterInt(value)) + putInt(KEY_SEARCH_FILTER_MODE, value?.intCode ?: Int.MIN_VALUE) apply() } } /** The song sort mode on HomeFragment */ var libSongSort: Sort - get() = Sort.fromInt(prefs.getInt(KEY_LIB_SONGS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + get() = + Sort.fromIntCode(prefs.getInt(KEY_LIB_SONGS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_LIB_SONGS_SORT, value.toInt()) + putInt(KEY_LIB_SONGS_SORT, value.intCode) apply() } } /** The album sort mode on HomeFragment */ var libAlbumSort: Sort - get() = Sort.fromInt(prefs.getInt(KEY_LIB_ALBUMS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + get() = + Sort.fromIntCode(prefs.getInt(KEY_LIB_ALBUMS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_LIB_ALBUMS_SORT, value.toInt()) + putInt(KEY_LIB_ALBUMS_SORT, value.intCode) apply() } } /** The artist sort mode on HomeFragment */ var libArtistSort: Sort - get() = Sort.fromInt(prefs.getInt(KEY_LIB_ARTISTS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + get() = + Sort.fromIntCode(prefs.getInt(KEY_LIB_ARTISTS_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_LIB_ARTISTS_SORT, value.toInt()) + putInt(KEY_LIB_ARTISTS_SORT, value.intCode) apply() } } /** The genre sort mode on HomeFragment */ var libGenreSort: Sort - get() = Sort.fromInt(prefs.getInt(KEY_LIB_GENRES_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + get() = + Sort.fromIntCode(prefs.getInt(KEY_LIB_GENRES_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_LIB_GENRES_SORT, value.toInt()) + putInt(KEY_LIB_GENRES_SORT, value.intCode) apply() } } @@ -180,10 +184,11 @@ class SettingsManager private constructor(context: Context) : /** The detail album sort mode */ var detailAlbumSort: Sort get() = - Sort.fromInt(prefs.getInt(KEY_DETAIL_ALBUM_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + Sort.fromIntCode(prefs.getInt(KEY_DETAIL_ALBUM_SORT, Int.MIN_VALUE)) + ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_DETAIL_ALBUM_SORT, value.toInt()) + putInt(KEY_DETAIL_ALBUM_SORT, value.intCode) apply() } } @@ -191,10 +196,11 @@ class SettingsManager private constructor(context: Context) : /** The detail artist sort mode */ var detailArtistSort: Sort get() = - Sort.fromInt(prefs.getInt(KEY_DETAIL_ARTIST_SORT, Int.MIN_VALUE)) ?: Sort.ByYear(false) + Sort.fromIntCode(prefs.getInt(KEY_DETAIL_ARTIST_SORT, Int.MIN_VALUE)) + ?: Sort.ByYear(false) set(value) { prefs.edit { - putInt(KEY_DETAIL_ARTIST_SORT, value.toInt()) + putInt(KEY_DETAIL_ARTIST_SORT, value.intCode) apply() } } @@ -202,10 +208,11 @@ class SettingsManager private constructor(context: Context) : /** The detail genre sort mode */ var detailGenreSort: Sort get() = - Sort.fromInt(prefs.getInt(KEY_DETAIL_GENRE_SORT, Int.MIN_VALUE)) ?: Sort.ByName(true) + Sort.fromIntCode(prefs.getInt(KEY_DETAIL_GENRE_SORT, Int.MIN_VALUE)) + ?: Sort.ByName(true) set(value) { prefs.edit { - putInt(KEY_DETAIL_GENRE_SORT, value.toInt()) + putInt(KEY_DETAIL_GENRE_SORT, value.intCode) apply() } } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/DisplayMode.kt b/app/src/main/java/org/oxycblt/auxio/ui/DisplayMode.kt index 58fb9b8df..33608f8d9 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/DisplayMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/DisplayMode.kt @@ -17,6 +17,7 @@ package org.oxycblt.auxio.ui +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R /** @@ -49,39 +50,27 @@ enum class DisplayMode { SHOW_GENRES -> R.drawable.ic_genre } - companion object { - private const val INT_NULL = 0xA107 - private const val INT_SHOW_GENRES = 0xA108 - private const val INT_SHOW_ARTISTS = 0xA109 - private const val INT_SHOW_ALBUMS = 0xA10A - private const val INT_SHOW_SONGS = 0xA10B - - /** - * Convert this enum into an integer for filtering. In this context, a null value means to - * filter nothing. - * @return An integer constant for that display mode, or a constant for a null [DisplayMode] - */ - fun toFilterInt(value: DisplayMode?): Int { - return when (value) { - SHOW_SONGS -> INT_SHOW_SONGS - SHOW_ALBUMS -> INT_SHOW_ALBUMS - SHOW_ARTISTS -> INT_SHOW_ARTISTS - SHOW_GENRES -> INT_SHOW_GENRES - null -> INT_NULL + val intCode: Int + get() = + when (this) { + SHOW_SONGS -> IntegerTable.DISPLAY_MODE_SHOW_SONGS + SHOW_ALBUMS -> IntegerTable.DISPLAY_MODE_SHOW_ALBUMS + SHOW_ARTISTS -> IntegerTable.DISPLAY_MODE_SHOW_ARTISTS + SHOW_GENRES -> IntegerTable.DISPLAY_MODE_SHOW_GENRES } - } + companion object { /** * Convert a filtering integer to a [DisplayMode]. In this context, a null value means to * filter nothing. * @return A [DisplayMode] for this constant (including null) */ - fun fromFilterInt(value: Int): DisplayMode? { + fun fromInt(value: Int): DisplayMode? { return when (value) { - INT_SHOW_SONGS -> SHOW_SONGS - INT_SHOW_ALBUMS -> SHOW_ALBUMS - INT_SHOW_ARTISTS -> SHOW_ARTISTS - INT_SHOW_GENRES -> SHOW_GENRES + IntegerTable.DISPLAY_MODE_SHOW_SONGS -> SHOW_SONGS + IntegerTable.DISPLAY_MODE_SHOW_ALBUMS -> SHOW_ALBUMS + IntegerTable.DISPLAY_MODE_SHOW_ARTISTS -> SHOW_ARTISTS + IntegerTable.DISPLAY_MODE_SHOW_GENRES -> SHOW_GENRES else -> null } } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt b/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt index 2a6a04d4b..9825a3b2d 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt @@ -18,6 +18,7 @@ package org.oxycblt.auxio.ui import androidx.annotation.IdRes +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist @@ -43,6 +44,9 @@ import org.oxycblt.auxio.util.logW * @author OxygenCobalt */ sealed class Sort(open val isAscending: Boolean) { + protected abstract val sortIntCode: Int + abstract val itemId: Int + open fun songs(songs: Collection): List { logW("This sort is not supported for songs") return songs.toList() @@ -63,8 +67,20 @@ sealed class Sort(open val isAscending: Boolean) { return genres.toList() } + /** + * Apply [newIsAscending] to the status of this sort. + * @return A new [Sort] with the value of [newIsAscending] applied. + */ + abstract fun ascending(newIsAscending: Boolean): Sort + /** Sort by the names of an item */ class ByName(override val isAscending: Boolean) : Sort(isAscending) { + override val sortIntCode: Int + get() = IntegerTable.SORT_BY_NAME + + override val itemId: Int + get() = R.id.option_sort_name + override fun songs(songs: Collection): List { return songs.sortedWith(compareByDynamic(NameComparator()) { it }) } @@ -80,10 +96,20 @@ sealed class Sort(open val isAscending: Boolean) { override fun genres(genres: Collection): List { return genres.sortedWith(compareByDynamic(NameComparator()) { it }) } + + override fun ascending(newIsAscending: Boolean): Sort { + return ByName(isAscending) + } } /** Sort by the album of an item, only supported by [Song] */ class ByAlbum(override val isAscending: Boolean) : Sort(isAscending) { + override val sortIntCode: Int + get() = IntegerTable.SORT_BY_ALBUM + + override val itemId: Int + get() = R.id.option_sort_album + override fun songs(songs: Collection): List { return songs.sortedWith( MultiComparator( @@ -91,10 +117,20 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NullableComparator()) { it.track }, compareBy(NameComparator()) { it })) } + + override fun ascending(newIsAscending: Boolean): Sort { + return ByAlbum(newIsAscending) + } } /** Sort by the artist of an item, only supported by [Album] and [Song] */ class ByArtist(override val isAscending: Boolean) : Sort(isAscending) { + override val sortIntCode: Int + get() = IntegerTable.SORT_BY_ARTIST + + override val itemId: Int + get() = R.id.option_sort_artist + override fun songs(songs: Collection): List { return songs.sortedWith( MultiComparator( @@ -112,10 +148,20 @@ sealed class Sort(open val isAscending: Boolean) { compareByDescending(NullableComparator()) { it.year }, compareBy(NameComparator()) { it })) } + + override fun ascending(newIsAscending: Boolean): Sort { + return ByArtist(newIsAscending) + } } /** Sort by the year of an item, only supported by [Album] and [Song] */ class ByYear(override val isAscending: Boolean) : Sort(isAscending) { + override val sortIntCode: Int + get() = IntegerTable.SORT_BY_YEAR + + override val itemId: Int + get() = R.id.option_sort_year + override fun songs(songs: Collection): List { return songs.sortedWith( MultiComparator( @@ -131,31 +177,15 @@ sealed class Sort(open val isAscending: Boolean) { compareByDynamic(NullableComparator()) { it.year }, compareBy(NameComparator()) { it })) } - } - /** Get the corresponding item id for this sort. */ - val itemId: Int - get() = - when (this) { - is ByName -> R.id.option_sort_name - is ByArtist -> R.id.option_sort_artist - is ByAlbum -> R.id.option_sort_album - is ByYear -> R.id.option_sort_year - } - - /** - * Apply [ascending] to the status of this sort. - * @return A new [Sort] with the value of [ascending] applied. - */ - fun ascending(ascending: Boolean): Sort { - return when (this) { - is ByName -> ByName(ascending) - is ByArtist -> ByArtist(ascending) - is ByAlbum -> ByAlbum(ascending) - is ByYear -> ByYear(ascending) + override fun ascending(newIsAscending: Boolean): Sort { + return ByYear(newIsAscending) } } + val intCode: Int + get() = sortIntCode.shl(1) or if (isAscending) 1 else 0 + /** * Assign a new [id] to this sort * @return A new [Sort] corresponding to the [id] given, null if the ID has no analogue. @@ -197,16 +227,6 @@ sealed class Sort(open val isAscending: Boolean) { return songs(genre.songs) } - /** Convert this sort to it's integer representation. */ - fun toInt(): Int { - return when (this) { - is ByName -> INT_NAME - is ByArtist -> INT_ARTIST - is ByAlbum -> INT_ALBUM - is ByYear -> INT_YEAR - }.shl(1) or if (isAscending) 1 else 0 - } - protected inline fun compareByDynamic( comparator: Comparator, crossinline selector: (T) -> K @@ -244,8 +264,8 @@ sealed class Sort(open val isAscending: Boolean) { * * Sorts often need to compare multiple things at once across several hierarchies, with this * class doing such in a more efficient manner than resorting at multiple intervals or grouping - * items up. Comparators are checked from first to last, with the first comparator that returns a - * non-equal result being propagated upwards. + * items up. Comparators are checked from first to last, with the first comparator that returns + * a non-equal result being propagated upwards. */ class MultiComparator(vararg comparators: Comparator) : Comparator { private val mComparators = comparators @@ -263,24 +283,19 @@ sealed class Sort(open val isAscending: Boolean) { } companion object { - private const val INT_NAME = 0xA10C - private const val INT_ARTIST = 0xA10D - private const val INT_ALBUM = 0xA10E - private const val INT_YEAR = 0xA10F - /** * Convert a sort's integer representation into a [Sort] instance. * * @return A [Sort] instance, null if the data is malformed. */ - fun fromInt(value: Int): Sort? { + fun fromIntCode(value: Int): Sort? { val ascending = (value and 1) == 1 return when (value.shr(1)) { - INT_NAME -> ByName(ascending) - INT_ARTIST -> ByArtist(ascending) - INT_ALBUM -> ByAlbum(ascending) - INT_YEAR -> ByYear(ascending) + IntegerTable.SORT_BY_NAME -> ByName(ascending) + IntegerTable.SORT_BY_ARTIST -> ByArtist(ascending) + IntegerTable.SORT_BY_ALBUM -> ByAlbum(ascending) + IntegerTable.SORT_BY_YEAR -> ByYear(ascending) else -> null } } diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt b/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt index 4480905b5..02caff360 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/ViewHolders.kt @@ -100,8 +100,6 @@ private constructor( } companion object { - const val ITEM_TYPE = 0xA000 - /** Create an instance of [SongViewHolder] */ fun from( context: Context, @@ -128,8 +126,6 @@ private constructor( } companion object { - const val ITEM_TYPE = 0xA001 - /** Create an instance of [AlbumViewHolder] */ fun from( context: Context, @@ -156,8 +152,6 @@ private constructor( } companion object { - const val ITEM_TYPE = 0xA002 - /** Create an instance of [ArtistViewHolder] */ fun from( context: Context, @@ -184,8 +178,6 @@ private constructor( } companion object { - const val ITEM_TYPE = 0xA003 - /** Create an instance of [GenreViewHolder] */ fun from( context: Context, @@ -207,8 +199,6 @@ class HeaderViewHolder private constructor(private val binding: ItemHeaderBindin } companion object { - const val ITEM_TYPE = 0xA004 - /** Create an instance of [HeaderViewHolder] */ fun from(context: Context): HeaderViewHolder { return HeaderViewHolder(ItemHeaderBinding.inflate(context.inflater)) @@ -233,8 +223,6 @@ class ActionHeaderViewHolder private constructor(private val binding: ItemAction } companion object { - const val ITEM_TYPE = 0xA005 - /** Create an instance of [ActionHeaderViewHolder] */ fun from(context: Context): ActionHeaderViewHolder { return ActionHeaderViewHolder(ItemActionHeaderBinding.inflate(context.inflater)) diff --git a/app/src/main/java/org/oxycblt/auxio/util/ContextUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ContextUtil.kt index 043d2fd63..0f42730f8 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/ContextUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/ContextUtil.kt @@ -40,10 +40,9 @@ import androidx.annotation.StringRes import androidx.core.content.ContextCompat import kotlin.reflect.KClass import kotlin.system.exitProcess +import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.MainActivity -const val INTENT_REQUEST_CODE = 0xA0A0 - /** Shortcut to get a [LayoutInflater] from a [Context] */ val Context.inflater: LayoutInflater get() = LayoutInflater.from(this) @@ -213,7 +212,7 @@ fun Context.showToast(@StringRes str: Int) { fun Context.newMainIntent(): PendingIntent { return PendingIntent.getActivity( this, - INTENT_REQUEST_CODE, + IntegerTable.REQUEST_CODE, Intent(this, MainActivity::class.java), if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0) } @@ -222,7 +221,7 @@ fun Context.newMainIntent(): PendingIntent { fun Context.newBroadcastIntent(what: String): PendingIntent { return PendingIntent.getBroadcast( this, - INTENT_REQUEST_CODE, + IntegerTable.REQUEST_CODE, Intent(what), if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0) } diff --git a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt index 834e62e63..f1c722445 100644 --- a/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt +++ b/app/src/main/java/org/oxycblt/auxio/util/ViewUtil.kt @@ -26,6 +26,7 @@ import android.util.Log import android.view.View import android.view.WindowInsets import androidx.annotation.ColorRes +import androidx.core.graphics.drawable.DrawableCompat import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.R @@ -117,7 +118,7 @@ private fun isUnderImpl( val View.isRtl: Boolean get() = layoutDirection == View.LAYOUT_DIRECTION_RTL val Drawable.isRtl: Boolean - get() = layoutDirection == View.LAYOUT_DIRECTION_RTL + get() = DrawableCompat.getLayoutDirection(this) == View.LAYOUT_DIRECTION_RTL /** * Resolve system bar insets in a version-aware manner. This can be used to apply padding to a view diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 21ea64fab..1c61b1558 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -172,12 +172,10 @@ 已加载 %d 首曲目 - %d 首歌曲 "%d 首歌曲" - %d 张专辑 "%d 张专辑" diff --git a/app/src/main/res/values/integers.xml b/app/src/main/res/values/integers.xml index e89cba798..3038da668 100644 --- a/app/src/main/res/values/integers.xml +++ b/app/src/main/res/values/integers.xml @@ -2,6 +2,7 @@ 150 + @string/set_theme_auto diff --git a/info/ARCHITECTURE.md b/info/ARCHITECTURE.md index 1be331ff0..40afdeee0 100644 --- a/info/ARCHITECTURE.md +++ b/info/ARCHITECTURE.md @@ -150,58 +150,8 @@ system events, such as when a button is pressed on a headset. It should **never* #### Data Integers Integer representations of data/UI elements are used heavily in Auxio, primarily for efficiency. -To prevent any strange bugs, all integer representations must be unique. A table of all current integers used are shown below: - -``` -0xA0XX | UI Integer Space [Required by android] - -0xA000 | SongViewHolder -0xA001 | AlbumViewHolder -0xA002 | ArtistViewHolder -0xA003 | GenreViewHolder -0xA004 | HeaderViewHolder -0xA005 | ActionHeaderViewHolder - -0xA006 | AlbumDetailViewHolder -0xA007 | AlbumSongViewHolder -0xA008 | ArtistDetailViewHolder -0xA009 | ArtistAlbumViewHolder -0xA00A | ArtistSongViewHolder -0xA00B | GenreDetailViewHolder -0xA00C | GenreSongViewHolder - -0xA00D | QueueSongViewHolder - -0xA0A0 | Auxio notification code -0xA0C0 | Auxio request code - -0xA1XX | Data Integer Space [Stored for IO efficency] - -0xA100 | LoopMode.NONE -0xA101 | LoopMode.ALL -0xA102 | LoopMode.TRACK - -0xA103 | PlaybackMode.IN_GENRE -0xA104 | PlaybackMode.IN_ARTIST -0xA105 | PlaybackMode.IN_ALBUM -0xA106 | PlaybackMode.ALL_SONGS - -0xA107 | Null DisplayMode [Filter Nothing] -0xA108 | DisplayMode.SHOW_GENRES -0xA109 | DisplayMode.SHOW_ARTISTS -0xA10A | DisplayMode.SHOW_ALBUMS -0xA10B | DisplayMode.SHOW_SONGS - -0xA10C | Sort.Name -0xA10D | Sort.Artist -0xA10E | Sort.Album -0xA10F | Sort.Year - -0xA110 | ReplayGainMode.OFF -0xA111 | ReplayGainMode.TRACK -0xA112 | ReplayGainMode.ALBUM -0xA113 | ReplayGainMode.DYNAMIC -``` +To prevent any strange bugs, all integer representations must be unique. To see a table of all current integers, see the `C` class within +the project. Some datatypes [like `Tab` and `Sort`] have even more fine-grained integer representations for other data. More information can be found in the documentation for those datatypes.