diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt index 8ec8cef82..df2ccc292 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt @@ -39,7 +39,8 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat /** * The single [AppCompatActivity] for Auxio. * - * TODO: Add a new view for crashes with a stack trace + * TODO: Add crash reporting and error screens. This likely has to be an external activity, so it is + * blocked by eliminating exitProcess from the app. * * TODO: Custom language support * diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 29e76ce7f..bb1b2da37 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -44,8 +44,6 @@ import org.oxycblt.auxio.util.logD * A wrapper around the home fragment that shows the playback fragment and controls the more * high-level navigation features. * @author OxygenCobalt - * - * TODO: Add a new view with a stack trace whenever the music loading process fails. */ class MainFragment : ViewBindingFragment() { private val playbackModel: PlaybackViewModel by activityViewModels() diff --git a/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt b/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt index 52b794a74..ad8be8224 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/BitmapProvider.kt @@ -41,6 +41,7 @@ import org.oxycblt.auxio.music.Song class BitmapProvider(private val context: Context) { private var currentRequest: Request? = null + /* If this provider is currently attempting to load something. */ val isBusy: Boolean get() = currentRequest?.run { !disposable.isDisposed } ?: false @@ -53,7 +54,7 @@ class BitmapProvider(private val context: Context) { currentRequest = null val request = - target.setupRequest( + target.onConfigRequest( ImageRequest.Builder(context) .data(song) .size(Size.ORIGINAL) @@ -76,8 +77,15 @@ class BitmapProvider(private val context: Context) { private data class Request(val disposable: Disposable, val callback: Target) + /** Represents the target for a request. */ interface Target { - fun setupRequest(builder: ImageRequest.Builder): ImageRequest.Builder = builder + /** Modify the default request with custom attributes. */ + fun onConfigRequest(builder: ImageRequest.Builder): ImageRequest.Builder = builder + + /** + * Called when the loading process is completed. [bitmap] will be null if there was an + * error. + */ fun onCompleted(bitmap: Bitmap?) } } diff --git a/app/src/main/java/org/oxycblt/auxio/image/Components.kt b/app/src/main/java/org/oxycblt/auxio/image/Components.kt index 8d5e5613a..0184a203e 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/Components.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/Components.kt @@ -71,9 +71,8 @@ class AlbumArtFetcher private constructor(private val context: Context, private } class AlbumFactory : Fetcher.Factory { - override fun create(data: Album, options: Options, imageLoader: ImageLoader): Fetcher { - return AlbumArtFetcher(options.context, data) - } + override fun create(data: Album, options: Options, imageLoader: ImageLoader) = + AlbumArtFetcher(options.context, data) } } @@ -90,14 +89,12 @@ private constructor( override suspend fun fetch(): FetchResult? { val albums = Sort.ByName(true).albums(artist.albums) val results = albums.mapAtMost(4) { album -> fetchArt(context, album) } - return createMosaic(context, results, size) } class Factory : Fetcher.Factory { - override fun create(data: Artist, options: Options, imageLoader: ImageLoader): Fetcher { - return ArtistImageFetcher(options.context, options.size, data) - } + override fun create(data: Artist, options: Options, imageLoader: ImageLoader) = + ArtistImageFetcher(options.context, options.size, data) } } @@ -115,14 +112,12 @@ private constructor( // Don't sort here to preserve compatibility with previous versions of this image. val albums = genre.songs.groupBy { it.album }.keys val results = albums.mapAtMost(4) { album -> fetchArt(context, album) } - return createMosaic(context, results, size) } class Factory : Fetcher.Factory { - override fun create(data: Genre, options: Options, imageLoader: ImageLoader): Fetcher { - return GenreImageFetcher(options.context, options.size, data) - } + override fun create(data: Genre, options: Options, imageLoader: ImageLoader) = + GenreImageFetcher(options.context, options.size, data) } } 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 cbcbd1f4b..6fee2dcd1 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/Sort.kt @@ -119,9 +119,7 @@ sealed class Sort(open val isAscending: Boolean) { genres.sortWith(compareByDynamic(NameComparator()) { it }) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByName(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByName(newIsAscending) } /** Sort by the album of an item, only supported by [Song] */ @@ -140,9 +138,7 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByAlbum(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByAlbum(newIsAscending) } /** Sort by the artist of an item, only supported by [Album] and [Song] */ @@ -171,9 +167,7 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByArtist(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByArtist(newIsAscending) } /** Sort by the year of an item, only supported by [Album] and [Song] */ @@ -200,9 +194,7 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByYear(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByYear(newIsAscending) } /** Sort by the duration of the item. Supports all items. */ @@ -237,9 +229,7 @@ sealed class Sort(open val isAscending: Boolean) { compareByDynamic { it.durationSecs }, compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByDuration(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByDuration(newIsAscending) } /** Sort by the amount of songs. Only applicable to music parents. */ @@ -268,9 +258,7 @@ sealed class Sort(open val isAscending: Boolean) { compareByDynamic { it.songs.size }, compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByCount(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByCount(newIsAscending) } /** @@ -293,9 +281,7 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByDisc(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByDisc(newIsAscending) } /** @@ -317,9 +303,7 @@ sealed class Sort(open val isAscending: Boolean) { compareBy(NameComparator()) { it })) } - override fun ascending(newIsAscending: Boolean): Sort { - return ByTrack(newIsAscending) - } + override fun ascending(newIsAscending: Boolean) = ByTrack(newIsAscending) } val intCode: Int diff --git a/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt index d9f7234f0..2349271bd 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/StyledImageView.kt @@ -41,7 +41,6 @@ import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.settings.SettingsManager import org.oxycblt.auxio.util.getColorStateListSafe import org.oxycblt.auxio.util.getDrawableSafe -import org.oxycblt.auxio.util.logD /** * An [AppCompatImageView] that applies many of the stylistic choices that Auxio uses regarding @@ -130,7 +129,6 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr } override fun draw(canvas: Canvas) { - logD(src.alpha) src.bounds.set(canvas.clipBounds) val adjustWidth = src.bounds.width() / 4 val adjustHeight = src.bounds.height() / 4 diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt index bf18449fc..9f11ad3ca 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt @@ -35,13 +35,13 @@ fun createDefaultWidget(context: Context): RemoteViews { } /** - * The tiny widget is for an edge-case situation where a 2xN widget happens to be smaller than - * 100dp. It just shows the cover, titles, and a button. + * The tiny widget is for an edge-case situation where a widget falls under the size class of the + * small widget, either via landscape mode or exceptionally small screens. */ fun createTinyWidget(context: Context, state: WidgetComponent.WidgetState): RemoteViews { return createViews(context, R.layout.widget_tiny) .applyMeta(context, state) - .applyPlayControls(context, state) + .applyBasicControls(context, state) } /** diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt index 8641c581d..8119943b9 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt @@ -50,6 +50,10 @@ class WidgetComponent(private val context: Context) : init { playbackManager.addCallback(this) settingsManager.addCallback(this) + + if (playbackManager.isInitialized) { + update() + } } /* @@ -76,7 +80,7 @@ class WidgetComponent(private val context: Context) : provider.load( song, object : BitmapProvider.Target { - override fun setupRequest(builder: ImageRequest.Builder): ImageRequest.Builder { + override fun onConfigRequest(builder: ImageRequest.Builder): ImageRequest.Builder { // The widget has two distinct styles that we must transform the album art to // accommodate: // - Before Android 12, the widget has hard edges, so we don't need to round diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt index 16978b8dc..8658d5a42 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt @@ -122,6 +122,13 @@ class WidgetProvider : AppWidgetProvider() { val name = ComponentName(context, WidgetProvider::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + for (id in getAppWidgetIds(name)) { + val options = getAppWidgetOptions(id) + logD( + options.getParcelableArrayList(AppWidgetManager.OPTION_APPWIDGET_SIZES) + ?: "no sizes") + } + // Widgets are automatically responsive on Android 12, no need to do anything. updateAppWidget(name, RemoteViews(views)) } else { diff --git a/app/src/main/res/drawable/ic_down.xml b/app/src/main/res/drawable/ic_down.xml index fed95d407..8b9b17aeb 100644 --- a/app/src/main/res/drawable/ic_down.xml +++ b/app/src/main/res/drawable/ic_down.xml @@ -7,5 +7,5 @@ android:viewportHeight="24"> + android:pathData="M 18.119999,7.0600006 12,13.166666 5.8800004,7.0600006 4.0000006,8.9400004 12,16.939999 19.999999,8.9400004 Z" /> diff --git a/app/src/main/res/drawable/ic_remote_default_cover.xml b/app/src/main/res/drawable/ic_remote_default_cover.xml index a97938c73..02ad5acc2 100644 --- a/app/src/main/res/drawable/ic_remote_default_cover.xml +++ b/app/src/main/res/drawable/ic_remote_default_cover.xml @@ -13,7 +13,7 @@ a terrible API. --> - - + + + + + + + + + - - - diff --git a/app/src/main/res/layout/widget_wide.xml b/app/src/main/res/layout/widget_wide.xml index 4a2242ca3..8f64ab103 100644 --- a/app/src/main/res/layout/widget_wide.xml +++ b/app/src/main/res/layout/widget_wide.xml @@ -8,14 +8,7 @@ android:theme="@style/Theme.Widget"> Orange Brown Grey + Dynamic Disc %d