diff --git a/CHANGELOG.md b/CHANGELOG.md index cd5f1be53..d1844357a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ #### What's New - Added a shuffle shortcut +- Reworked the button appearance on widgets - You can now customize what occurs when a song is played from an album/artist/genre [#164] #### What's Improved diff --git a/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt b/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt index 1a9b66568..b4efcaf3c 100644 --- a/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt +++ b/app/src/main/java/org/oxycblt/auxio/image/StyledImageView.kt @@ -61,7 +61,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr set(value) { field = value (background as? MaterialShapeDrawable)?.let { bg -> - if (settings.roundCovers) { + if (settings.roundMode) { bg.setCornerSize(value) } else { bg.setCornerSize(0f) diff --git a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt index 97fed10a1..e951c7d20 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt @@ -160,7 +160,7 @@ private class IndexerNotification(private val context: Context) : notificationManager.createNotificationChannel(channel) } - setSmallIcon(R.drawable.ic_indexer_32) + setSmallIcon(R.drawable.ic_indexer_24) setCategory(NotificationCompat.CATEGORY_PROGRESS) setShowWhen(false) setSilent(true) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt index 8044946ec..71eca08de 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/NotificationComponent.kt @@ -27,6 +27,7 @@ import android.support.v4.media.session.MediaSessionCompat import androidx.annotation.DrawableRes import androidx.core.app.NotificationCompat import androidx.media.app.NotificationCompat.MediaStyle +import okhttp3.internal.notify import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R @@ -35,6 +36,7 @@ import org.oxycblt.auxio.music.MusicParent import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.util.getSystemServiceSafe +import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.newBroadcastPendingIntent import org.oxycblt.auxio.util.newMainPendingIntent @@ -94,24 +96,26 @@ class NotificationComponent( /** Set the metadata of the notification using [song]. */ fun updateMetadata(song: Song, parent: MusicParent?) { - setContentTitle(song.resolveName(context)) - setContentText(song.resolveIndividualArtistName(context)) - - // Starting in API 24, the subtext field changed semantics from being below the content - // text to being above the title. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - setSubText(parent?.resolveName(context) ?: context.getString(R.string.lbl_all_songs)) - } else { - setSubText(song.album.resolveName(context)) - } - provider.load( song, object : BitmapProvider.Target { override fun onCompleted(bitmap: Bitmap?) { + logD("writing ${song.rawName} to notif") setLargeIcon(bitmap) - build() - callback.onNotificationChanged(this@NotificationComponent) + setContentTitle(song.resolveName(context)) + setContentText(song.resolveIndividualArtistName(context)) + + // Starting in API 24, the subtext field changed semantics from being below the + // content text to being above the title. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + setSubText( + parent?.resolveName(context) + ?: context.getString(R.string.lbl_all_songs)) + } else { + setSubText(song.album.resolveName(context)) + } + + callback.onNotificationChanged(song, this@NotificationComponent) } }) } @@ -120,7 +124,7 @@ class NotificationComponent( fun updatePlaying(isPlaying: Boolean) { mActions[2] = buildPlayPauseAction(context, isPlaying) if (!provider.isBusy) { - callback.onNotificationChanged(this) + callback.onNotificationChanged(null, this) } } @@ -128,7 +132,7 @@ class NotificationComponent( fun updateRepeatMode(repeatMode: RepeatMode) { mActions[0] = buildRepeatAction(context, repeatMode) if (!provider.isBusy) { - callback.onNotificationChanged(this) + callback.onNotificationChanged(null, this) } } @@ -136,7 +140,7 @@ class NotificationComponent( fun updateShuffled(isShuffled: Boolean) { mActions[0] = buildShuffleAction(context, isShuffled) if (!provider.isBusy) { - callback.onNotificationChanged(this) + callback.onNotificationChanged(null, this) } } @@ -188,7 +192,7 @@ class NotificationComponent( } interface Callback { - fun onNotificationChanged(component: NotificationComponent) + fun onNotificationChanged(song: Song?, component: NotificationComponent) } companion object { 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 86fe8d29c..961dec995 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 @@ -24,6 +24,7 @@ import android.content.Intent import android.content.IntentFilter import android.media.AudioManager import android.os.IBinder +import androidx.core.app.NotificationCompat import androidx.core.app.ServiceCompat import com.google.android.exoplayer2.C import com.google.android.exoplayer2.ExoPlayer @@ -310,9 +311,10 @@ class PlaybackService : // --- NOTIFICATION CALLBACKS --- - override fun onNotificationChanged(component: NotificationComponent) { + override fun onNotificationChanged(song: Song?, component: NotificationComponent) { if (hasPlayed && playbackManager.song != null) { - logD("Starting foreground/notifying") + logD("Starting foreground/notifying: ${song?.rawName}") + logD(NotificationCompat.getContentTitle(component.build())) if (!isForeground) { startForeground(IntegerTable.PLAYBACK_NOTIFICATION_CODE, component.build()) diff --git a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt index 466329072..741d48fc3 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/Settings.kt @@ -123,9 +123,9 @@ class Settings(private val context: Context, private val callback: Callback? = n val useQualityCovers: Boolean get() = inner.getBoolean(context.getString(R.string.set_key_quality_covers), false) - /** Whether to round album covers */ - val roundCovers: Boolean - get() = inner.getBoolean(context.getString(R.string.set_key_round_covers), false) + /** Whether to round additional UI elements (including album covers) */ + val roundMode: Boolean + get() = inner.getBoolean(context.getString(R.string.set_key_round_mode), false) /** Whether to resume playback when a headset is connected (may not work well in all cases) */ val headsetAutoplay: Boolean diff --git a/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetLayout.kt b/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetLayout.kt index bb3f39004..e81032cd0 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/BottomSheetLayout.kt @@ -102,7 +102,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) : private val elevationNormal = context.getDimenSafe(R.dimen.elevation_normal) private val cornersLarge = - if (Settings(context).roundCovers) { + if (Settings(context).roundMode) { // Since album covers are rounded, we can also round the bar too. context.getDimenSizeSafe(R.dimen.size_corners_large) } else { 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 944039e5c..1d7c126db 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt @@ -18,12 +18,14 @@ package org.oxycblt.auxio.widgets import android.content.Context +import android.os.Build import android.view.View import android.widget.RemoteViews import androidx.annotation.LayoutRes import org.oxycblt.auxio.R import org.oxycblt.auxio.playback.state.RepeatMode import org.oxycblt.auxio.playback.system.PlaybackService +import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.util.newBroadcastPendingIntent import org.oxycblt.auxio.util.newMainPendingIntent @@ -39,6 +41,7 @@ fun createDefaultWidget(context: Context) = createViews(context, R.layout.widget */ fun createThinWidget(context: Context, state: WidgetComponent.WidgetState) = createViews(context, R.layout.widget_thin) + .applyRoundingToBackground(context) .applyMeta(context, state) .applyBasicControls(context, state) /** @@ -48,6 +51,7 @@ fun createThinWidget(context: Context, state: WidgetComponent.WidgetState) = */ fun createSmallWidget(context: Context, state: WidgetComponent.WidgetState) = createViews(context, R.layout.widget_small) + .applyRoundingToBar(context) .applyCover(context, state) .applyBasicControls(context, state) @@ -57,18 +61,21 @@ fun createSmallWidget(context: Context, state: WidgetComponent.WidgetState) = */ fun createMediumWidget(context: Context, state: WidgetComponent.WidgetState) = createViews(context, R.layout.widget_medium) + .applyRoundingToBackground(context) .applyMeta(context, state) .applyBasicControls(context, state) /** The wide widget is for Nx2 widgets and is like the small widget but with more controls. */ fun createWideWidget(context: Context, state: WidgetComponent.WidgetState) = createViews(context, R.layout.widget_wide) + .applyRoundingToBar(context) .applyCover(context, state) .applyFullControls(context, state) /** The large widget is for 3x4 widgets and shows all metadata and controls. */ fun createLargeWidget(context: Context, state: WidgetComponent.WidgetState): RemoteViews = createViews(context, R.layout.widget_large) + .applyRoundingToBackground(context) .applyMeta(context, state) .applyFullControls(context, state) @@ -78,6 +85,26 @@ private fun createViews(context: Context, @LayoutRes layout: Int): RemoteViews { return views } +private fun RemoteViews.applyRoundingToBackground(context: Context): RemoteViews { + if (Settings(context).roundMode && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + setInt(android.R.id.background, "setBackgroundResource", R.drawable.ui_widget_bg_round) + } else { + setInt(android.R.id.background, "setBackgroundResource", R.drawable.ui_widget_bg) + } + + return this +} + +private fun RemoteViews.applyRoundingToBar(context: Context): RemoteViews { + if (Settings(context).roundMode && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + setInt(R.id.widget_controls, "setBackgroundResource", R.drawable.ui_widget_bg_round) + } else { + setInt(R.id.widget_controls, "setBackgroundResource", R.drawable.ui_widget_bar) + } + + return this +} + private fun RemoteViews.applyMeta( context: Context, state: WidgetComponent.WidgetState 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 f6e4dd1fa..286ccc896 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetComponent.kt @@ -84,14 +84,23 @@ class WidgetComponent(private val context: Context) : song, object : BitmapProvider.Target { override fun onConfigRequest(builder: ImageRequest.Builder): ImageRequest.Builder { + val cornerRadius = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + context.getDimenSizeSafe(android.R.dimen.system_app_widget_inner_radius) + } else if (settings.roundMode) { + context.getDimenSizeSafe(R.dimen.size_corners_large) + } else { + 0 + } + // 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 // out the album art. // - After Android 12, the widget has round edges, so we need to round out // the album art. I dislike this, but it's mainly for stylistic cohesion. - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - this@WidgetComponent.logD("Doing API 31 cover load") + return if (cornerRadius > 0) { + this@WidgetComponent.logD("Loading round covers: $cornerRadius") val metrics = context.resources.displayMetrics @@ -101,11 +110,7 @@ class WidgetComponent(private val context: Context) : builder .transformations( SquareFrameTransform.INSTANCE, - RoundedCornersTransformation( - context - .getDimenSizeSafe( - android.R.dimen.system_app_widget_inner_radius) - .toFloat())) + RoundedCornersTransformation(cornerRadius.toFloat())) // The output of RoundedCornersTransformation is dimension-dependent, // so scale up the image to the screen size to ensure consistent radii. // Make sure we stop at 1024, so we don't accidentally make a massive @@ -145,7 +150,8 @@ class WidgetComponent(private val context: Context) : override fun onRepeatChanged(repeatMode: RepeatMode) = update() override fun onSettingChanged(key: String) { if (key == context.getString(R.string.set_key_show_covers) || - key == context.getString(R.string.set_key_quality_covers)) { + key == context.getString(R.string.set_key_quality_covers) || + key == context.getString(R.string.set_key_round_mode)) { update() } } diff --git a/app/src/main/res/drawable-nodpi/ui_widget_preview.png b/app/src/main/res/drawable-nodpi/ui_widget_preview.png index 76b505c6f..d4ff028fb 100644 Binary files a/app/src/main/res/drawable-nodpi/ui_widget_preview.png and b/app/src/main/res/drawable-nodpi/ui_widget_preview.png differ diff --git a/app/src/main/res/drawable-v31/ui_widget_panel.xml b/app/src/main/res/drawable-v31/ui_widget_bar.xml similarity index 100% rename from app/src/main/res/drawable-v31/ui_widget_panel.xml rename to app/src/main/res/drawable-v31/ui_widget_bar.xml diff --git a/app/src/main/res/drawable/ic_indexer_32.xml b/app/src/main/res/drawable/ic_indexer_24.xml similarity index 100% rename from app/src/main/res/drawable/ic_indexer_32.xml rename to app/src/main/res/drawable/ic_indexer_24.xml diff --git a/app/src/main/res/drawable/ui_widget_panel.xml b/app/src/main/res/drawable/ui_widget_bar.xml similarity index 100% rename from app/src/main/res/drawable/ui_widget_panel.xml rename to app/src/main/res/drawable/ui_widget_bar.xml diff --git a/app/src/main/res/drawable/ui_widget_bg.xml b/app/src/main/res/drawable/ui_widget_bg.xml new file mode 100644 index 000000000..9d33d5912 --- /dev/null +++ b/app/src/main/res/drawable/ui_widget_bg.xml @@ -0,0 +1,5 @@ + + + + diff --git a/app/src/main/res/drawable/ui_widget_bg_round.xml b/app/src/main/res/drawable/ui_widget_bg_round.xml new file mode 100644 index 000000000..203f3e83c --- /dev/null +++ b/app/src/main/res/drawable/ui_widget_bg_round.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/widget_large.xml b/app/src/main/res/layout/widget_large.xml index 5a37c53e9..bf2bcd09e 100644 --- a/app/src/main/res/layout/widget_large.xml +++ b/app/src/main/res/layout/widget_large.xml @@ -4,7 +4,8 @@ android:id="@android:id/background" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="?attr/colorSurface" + android:backgroundTint="?attr/colorSurface" + android:background="@drawable/ui_widget_bg" android:theme="@style/Theme.Widget"> + @@ -79,13 +79,14 @@ android:layout_height="match_parent" android:layout_weight="1" /> - + + أطفاء لتقليل استخدام الذاكرة تجاهل اغلفة وسائط التخزين يزيد من جودة غلاف الالبوم، لكن يؤذي إلى زيادة وقت التحميل واستخدام اعلى للذاكرة - اغلفة البوم مدورة - جعل اغلفة الابومات ذات زوايا مدورة + اغلفة البوم مدورة + جعل اغلفة الابومات ذات زوايا مدورة استخدام نشاط بديل للإشعار تفضيل نشاط وضع التكرار تفضيل نشاط الخلط diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 1cb26f3af..c41b29229 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -84,8 +84,8 @@ Vypněte pro ušetření paměti Ignorovat obaly MediaStore Zvýší kvalitu obalů alb, ale znamená také delší časy načítání a vyšší využití paměti - Zakulacené obaly alb - Použít obaly alb se zakulacenými rohy + Zakulacené obaly alb + Použít obaly alb se zakulacenými rohy Použít alternativní akci oznámení Preferovat akci režimu opakování Preferovat akci náhodného přehrávání diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 3a7187dd3..aed6d6f26 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -66,8 +66,8 @@ Ausschalten um Speicherplatz zu sparen MediaStore Cover ignorieren Verbesst die Albumcoverqualität, führt jedoch zu längeren Ladezeiten und höherem Speicherverbrauch - Abgerundete Cover - Rundet Ecken der Cover ab + Abgerundete Cover + Rundet Ecken der Cover ab Alternative Aktionstaste verwenden Wiederholen-Aktionstaste bevorzugen Zufällig-Aktionstaste bevorzugen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 905c581dd..e7bec7ae7 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -74,8 +74,8 @@ Desactive para ahorrar memoria Ignorar carátulas de MediaStore Incrementa la calidad de las carátulas, pero deriva en mayores tiempos de carga y uso de memoria - Carátulas redondeadas - Usar carátulas redondeadas para los álbumes + Carátulas redondeadas + Usar carátulas redondeadas para los álbumes Usar acciones de notificación alternativas Preferir acción de bucle Preferir acción de mezcla diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 27808a255..5de2c1349 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -74,8 +74,8 @@ Disattiva per ridurre il consumo di memoria Ignora copertine MediaStore Migliora la qualità delle copertine, ma comporta maggiori tempi di caricamento e consumo di memoria - Copertine dischi arrotondate - Usa copertine dischi con angoli arrotondati + Copertine dischi arrotondate + Usa copertine dischi con angoli arrotondati Usa azioni notifica alternative Preferisci azione modalità ripetizione Preferisci azione mescola diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 9529ec390..b5a4e5f5e 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -82,8 +82,8 @@ 이 옵션을 끄면 메모리 사용량을 줄일 수 있습니다. MediaStore 커버 무시 앨범 커버의 품질을 높일 수 있지만 메모리 사용량이 늘어나고 불러오는 시간이 더 오래 걸립니다. - 둥근 앨범 커버 사용 - 앨범 커버의 가장자리를 둥글게 표시 + 둥근 앨범 커버 사용 + 앨범 커버의 가장자리를 둥글게 표시 다른 방식의 알림 동작 사용 반복 모드 동작 선호 무작위 동작 선호 diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 99c4ab424..1fa8df516 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -74,8 +74,8 @@ Отключите для экономии памяти Игнорировать хранилище обложек Улучшает качество обложек, но увеличивает время загрузки и использование памяти - Скруглённые обложки - Показывать обложки со скруглёнными краями + Скруглённые обложки + Показывать обложки со скруглёнными краями Кнопка в уведомлении Режим повтора Режим перемешивания diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 18c3e5d21..3f332874d 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -73,8 +73,8 @@ 关闭以节省内存使用 忽略 MediaStore 封面 提升专辑封面质量,但需要更长的加载时间并消耗更多内存 - 专辑封面圆角 - 使用圆角设计的专辑封面 + 专辑封面圆角 + 使用圆角设计的专辑封面 使用替代通知操作方案 偏好重复播放操作 偏好随机播放操作 diff --git a/app/src/main/res/values/settings.xml b/app/src/main/res/values/settings.xml index 2efb09335..232851842 100644 --- a/app/src/main/res/values/settings.xml +++ b/app/src/main/res/values/settings.xml @@ -8,7 +8,7 @@ auxio_lib_tabs KEY_SHOW_COVERS KEY_QUALITY_COVERS - auxio_round_covers + auxio_round_covers KEY_ALT_NOTIF_ACTION auxio_headset_autoplay diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 044a07584..cdd84ef19 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -94,8 +94,8 @@ Turn off to save memory usage Ignore MediaStore covers Increases album cover quality, but results in longer loading times and higher memory usage - Rounded album covers - Use album covers with rounded corners + Round mode + Enable rounded corners on additional UI elements (Requires album covers to be rounded) Use alternate notification action Prefer repeat mode action Prefer shuffle action diff --git a/app/src/main/res/xml/prefs_main.xml b/app/src/main/res/xml/prefs_main.xml index 197513c10..dc1c9c0f2 100644 --- a/app/src/main/res/xml/prefs_main.xml +++ b/app/src/main/res/xml/prefs_main.xml @@ -58,9 +58,9 @@ + app:key="@string/set_key_round_mode" + app:summary="@string/set_round_mode_desc" + app:title="@string/set_round_mode" />