From 5bf1d4e13d3c4401f8532f4f872344664a2556a5 Mon Sep 17 00:00:00 2001 From: nift4 Date: Sat, 26 Oct 2024 00:18:55 +0200 Subject: [PATCH] stuff --- app/lint.xml | 6 +- app/src/main/AndroidManifest.xml | 13 ++ .../logic/GramophonePlaybackService.kt | 89 +++++--- .../gramophone/logic/ui/ViewCompatInflater.kt | 36 ++-- .../logic/utils/GramophoneShuffleOrder.kt | 1 + .../org/akanework/gramophone/ui/Widget.kt | 202 ++++++++++++++++++ app/src/main/res/color/sl_lyric_active.xml | 4 + app/src/main/res/color/sl_lyric_text.xml | 4 + .../res/drawable/ic_gramophone_monochrome.xml | 23 +- app/src/main/res/layout-land/full_player.xml | 28 +-- .../res/layout/activity_audio_preview.xml | 6 +- .../layout/adapter_blacklist_folder_card.xml | 2 +- .../main/res/layout/adapter_folder_card.xml | 4 +- app/src/main/res/layout/adapter_grid_card.xml | 4 +- app/src/main/res/layout/adapter_list_card.xml | 6 +- .../res/layout/adapter_list_card_larger.xml | 6 +- .../res/layout/adapter_list_card_playlist.xml | 8 +- app/src/main/res/layout/bottom_sheet.xml | 4 +- .../main/res/layout/fragment_info_song.xml | 48 ++--- app/src/main/res/layout/full_player.xml | 28 +-- app/src/main/res/layout/general_decor.xml | 12 +- app/src/main/res/layout/lyric_widget.xml | 22 ++ .../main/res/layout/lyric_widget_txt_bgli.xml | 9 + .../main/res/layout/lyric_widget_txt_nnli.xml | 9 + .../main/res/layout/lyric_widget_txt_nnri.xml | 9 + .../main/res/layout/lyric_widget_txt_tbli.xml | 9 + .../main/res/layout/lyric_widget_txt_tlli.xml | 9 + .../main/res/layout/lyric_widget_txt_tlri.xml | 9 + .../main/res/layout/playlist_bottom_sheet.xml | 4 +- .../res/layout/preference_category_md.xml | 3 +- .../main/res/layout/tab_order_seperator.xml | 4 +- app/src/main/res/values-v31/themes.xml | 5 +- app/src/main/res/values/dimens.xml | 3 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/values/styleables.xml | 6 +- app/src/main/res/values/themes.xml | 3 + app/src/main/res/xml/lyric_widget.xml | 9 + 37 files changed, 501 insertions(+), 147 deletions(-) create mode 100644 app/src/main/kotlin/org/akanework/gramophone/ui/Widget.kt create mode 100644 app/src/main/res/color/sl_lyric_active.xml create mode 100644 app/src/main/res/color/sl_lyric_text.xml create mode 100644 app/src/main/res/layout/lyric_widget.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_bgli.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_nnli.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_nnri.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_tbli.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_tlli.xml create mode 100644 app/src/main/res/layout/lyric_widget_txt_tlri.xml create mode 100644 app/src/main/res/xml/lyric_widget.xml diff --git a/app/lint.xml b/app/lint.xml index bf8d1b3bd..e84efd437 100644 --- a/app/lint.xml +++ b/app/lint.xml @@ -1,7 +1,9 @@ + - + - - backported in ViewCompatInflater - - + - - backported in ViewCompatInflater - - + --> \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7feca710f..a22216abf 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -118,6 +118,19 @@ android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> + + + + + + + + + + diff --git a/app/src/main/kotlin/org/akanework/gramophone/logic/GramophonePlaybackService.kt b/app/src/main/kotlin/org/akanework/gramophone/logic/GramophonePlaybackService.kt index 018eca3ea..1f0f50471 100644 --- a/app/src/main/kotlin/org/akanework/gramophone/logic/GramophonePlaybackService.kt +++ b/app/src/main/kotlin/org/akanework/gramophone/logic/GramophonePlaybackService.kt @@ -18,8 +18,6 @@ package org.akanework.gramophone.logic import android.annotation.SuppressLint -import android.app.NotificationChannel -import android.app.NotificationManager import android.app.PendingIntent import android.content.BroadcastReceiver import android.content.Context @@ -30,7 +28,6 @@ import android.graphics.Bitmap import android.media.AudioManager import android.media.audiofx.AudioEffect import android.net.Uri -import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper @@ -58,7 +55,6 @@ import androidx.media3.exoplayer.ExoPlayer import androidx.media3.exoplayer.util.EventLogger import androidx.media3.session.CacheBitmapLoader import androidx.media3.session.CommandButton -import androidx.media3.session.DefaultMediaNotificationProvider import androidx.media3.session.MediaController import androidx.media3.session.MediaLibraryService import androidx.media3.session.MediaSession @@ -96,6 +92,7 @@ import org.akanework.gramophone.logic.utils.SemanticLyrics import org.akanework.gramophone.logic.utils.exoplayer.EndedWorkaroundPlayer import org.akanework.gramophone.logic.utils.exoplayer.GramophoneMediaSourceFactory import org.akanework.gramophone.logic.utils.exoplayer.GramophoneRenderFactory +import org.akanework.gramophone.ui.LyricWidgetProvider import org.akanework.gramophone.ui.MainActivity import kotlin.random.Random @@ -114,6 +111,7 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis private const val NOTIFY_ID = 1 private const val PENDING_INTENT_SESSION_ID = 0 private const val PENDING_INTENT_NOTIFY_ID = 1 + const val PENDING_INTENT_WIDGET_ID = 2 private const val PLAYBACK_SHUFFLE_ACTION_ON = "shuffle_on" private const val PLAYBACK_SHUFFLE_ACTION_OFF = "shuffle_off" private const val PLAYBACK_REPEAT_OFF = "repeat_off" @@ -125,13 +123,17 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis const val SERVICE_GET_LYRICS_LEGACY = "get_lyrics_legacy" const val SERVICE_GET_SESSION = "get_session" const val SERVICE_TIMER_CHANGED = "changed_timer" + var instanceForWidgetAndOnlyWidget: GramophonePlaybackService? = null } private var lastSessionId = 0 private var mediaSession: MediaLibrarySession? = null - private var controller: MediaController? = null - private val sendLyrics = Runnable { sendLyricNow() } - private var lyrics: SemanticLyrics? = null - private var lyricsLegacy: MutableList? = null + var controller: MediaController? = null + private set + private val sendLyrics = Runnable { scheduleSendingLyrics() } + var lyrics: SemanticLyrics? = null + private set + var lyricsLegacy: MutableList? = null + private set private var shuffleFactory: ((Int) -> ((CircularShuffleOrder) -> Unit) -> CircularShuffleOrder)? = null private lateinit var customCommands: List @@ -183,7 +185,16 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis } } + private val seekReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val to = intent.extras?.getLong("seekTo", C.INDEX_UNSET.toLong()) ?: C.INDEX_UNSET.toLong() + if (to != C.INDEX_UNSET.toLong()) + controller?.seekTo(to) + } + } + override fun onCreate() { + instanceForWidgetAndOnlyWidget = this handler = Handler(Looper.getMainLooper()) super.onCreate() nm = NotificationManagerCompat.from(this) @@ -379,11 +390,18 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis headSetReceiver, IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY) ) + ContextCompat.registerReceiver( + this, + seekReceiver, + IntentFilter("$packageName.SEEK_TO"), + ContextCompat.RECEIVER_NOT_EXPORTED + ) } // When destroying, we should release server side player // alongside with the mediaSession. override fun onDestroy() { + instanceForWidgetAndOnlyWidget = null // Important: this must happen before sending stop() as that changes state ENDED -> IDLE lastPlayedManager.save() mediaSession!!.player.stop() @@ -393,9 +411,8 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis mediaSession!!.release() mediaSession!!.player.release() mediaSession = null - lyrics = null - lyricsLegacy = null unregisterReceiver(headSetReceiver) + unregisterReceiver(seekReceiver) super.onDestroy() } @@ -681,37 +698,33 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis private fun scheduleSendingLyrics() { handler.removeCallbacks(sendLyrics) sendLyricNow() - if (controller?.isPlaying != true) return - val controllerPos = (controller?.currentPosition ?: 0).toULong() + val isStatusBarLyricsEnabled = prefs.getBooleanStrict("status_bar_lyrics", false) + val hnw = !LyricWidgetProvider.hasWidget(this) + if (controller?.isPlaying != true || (!isStatusBarLyricsEnabled && hnw)) return + val cPos = (controller?.contentPosition ?: 0).toULong() val nextUpdate = if (lyrics != null && lyrics is SemanticLyrics.SyncedLyrics) { val syncedLyrics = lyrics as SemanticLyrics.SyncedLyrics - syncedLyrics.text.filterIndexed { _, lyric -> - lyric.lyric.start > controllerPos - }.minByOrNull { it.lyric.start }?.lyric?.start + syncedLyrics.text.flatMap { + if (hnw) listOf(it.lyric.start) else + (it.lyric.words?.map { it.timeRange.start }?.filter { it > cPos } ?: listOf()) + .let { i -> if (it.lyric.start > cPos) i + it.lyric.start else i } + }.minOrNull() } else if (lyricsLegacy != null) { - lyricsLegacy!!.filterIndexed { _, lyric -> - (lyric.timeStamp ?: -2) > controllerPos.toLong() - }.minByOrNull { it.timeStamp!! }?.timeStamp?.toULong() + lyricsLegacy!!.find { + (it.timeStamp ?: -2) > cPos.toLong() + }?.timeStamp?.toULong() } else null - nextUpdate?.let { handler.postDelayed(sendLyrics, (it - controllerPos).toLong()) } + nextUpdate?.let { handler.postDelayed(sendLyrics, (it - cPos).toLong()) } } private fun sendLyricNow() { + LyricWidgetProvider.adapterUpdate(this) val isStatusBarLyricsEnabled = prefs.getBooleanStrict("status_bar_lyrics", false) val highlightedLyric = if (isStatusBarLyricsEnabled) - if (lyrics != null && lyrics is SemanticLyrics.SyncedLyrics) { - val syncedLyrics = lyrics as SemanticLyrics.SyncedLyrics - syncedLyrics.text.find { - it.lyric.start > (controller?.currentPosition ?: 0).toULong() - }?.lyric?.text - } else if (lyricsLegacy != null) { - val filteredList = lyricsLegacy?.filterIndexed { _, lyric -> - (lyric.timeStamp ?: Long.MAX_VALUE) <= (controller?.currentPosition ?: 0) - } - if (filteredList?.isNotEmpty() == true) { - filteredList.maxByOrNull { it.timeStamp ?: -2 }?.content - } else null - } else null + getCurrentLyricIndex()?.let { + (lyrics as? SemanticLyrics.SyncedLyrics)?.text?.get(it)?.lyric?.text ?: + lyricsLegacy?.get(it)?.content + } else null if (lastSentHighlightedLyric != highlightedLyric) { lastSentHighlightedLyric = highlightedLyric @@ -719,6 +732,18 @@ class GramophonePlaybackService : MediaLibraryService(), MediaSessionService.Lis } } + fun getCurrentLyricIndex() = + if (lyrics != null && lyrics is SemanticLyrics.SyncedLyrics) { + val syncedLyrics = lyrics as SemanticLyrics.SyncedLyrics + syncedLyrics.text.indexOfFirst { + it.lyric.start > (controller?.currentPosition ?: 0).toULong() + } + } else if (lyricsLegacy != null) { + lyricsLegacy?.indexOfLast { + (it.timeStamp ?: Long.MAX_VALUE) <= (controller?.currentPosition ?: 0) + } + } else null + override fun onForegroundServiceStartNotAllowedException() { Log.w(TAG, "Failed to resume playback :/") if (mayThrowForegroundServiceStartNotAllowed() diff --git a/app/src/main/kotlin/org/akanework/gramophone/logic/ui/ViewCompatInflater.kt b/app/src/main/kotlin/org/akanework/gramophone/logic/ui/ViewCompatInflater.kt index 457574585..77ccb3681 100644 --- a/app/src/main/kotlin/org/akanework/gramophone/logic/ui/ViewCompatInflater.kt +++ b/app/src/main/kotlin/org/akanework/gramophone/logic/ui/ViewCompatInflater.kt @@ -1,5 +1,6 @@ package org.akanework.gramophone.logic.ui +import android.annotation.SuppressLint import android.content.Context import android.content.res.TypedArray import android.os.Build @@ -20,10 +21,7 @@ class ViewCompatInflater class ViewCompatInflaterImpl : MaterialComponentsViewInflater(), Callback { override fun createTextView(context: Context, attrs: AttributeSet?): AppCompatTextView { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { - return TypefaceCompatTextView(context, attrs) - } - return super.createTextView(context, attrs) + return TypefaceCompatTextView(context, attrs) } class TypefaceCompatTextView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : @@ -72,7 +70,7 @@ class ViewCompatInflater attrs: AttributeSet, result: View? ) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P && result is TextView) { + if (result is TextView) { // perhaps some descendant, not just TypefaceCompatTextView var fontWeight = -1 val theme = context.theme @@ -91,20 +89,20 @@ class ViewCompatInflater if (ap != -1) { appearance = theme.obtainStyledAttributes(ap, R.styleable.MyTextAppearance) } - if (appearance != null) { + if (appearance != null && appearance.hasValue(R.styleable.MyTextAppearance_textFontWeight)) { fontWeight = appearance.getInt(R.styleable.MyTextAppearance_textFontWeight, -1) appearance.recycle() } a = theme.obtainStyledAttributes( attrs, - androidx.appcompat.R.styleable.TextAppearance, + R.styleable.MyTextAppearance, 0, 0 ) - if (a.hasValue(androidx.appcompat.R.styleable.TextAppearance_android_textFontWeight)) { + if (a.hasValue(R.styleable.MyTextAppearance_textFontWeight)) { fontWeight = a.getInt( - androidx.appcompat.R.styleable.TextAppearance_android_textFontWeight, + R.styleable.MyTextAppearance_textFontWeight, -1 ) } @@ -119,17 +117,15 @@ class ViewCompatInflater result.setTypeface(tf) } } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { - val a = context.theme.obtainStyledAttributes( - attrs, - R.styleable.MyTooltipCompat, - 0, - 0 - ) - val tooltip = a.getText(R.styleable.MyTooltipCompat_android_tooltipText) - if (tooltip != null) { - result?.let { TooltipCompat.setTooltipText(it, tooltip) } - } + val a = context.theme.obtainStyledAttributes( + attrs, + R.styleable.MyTooltipCompat, + 0, + 0 + ) + val tooltip = a.getText(R.styleable.MyTooltipCompat_tooltipText) + if (tooltip != null) { + result?.let { TooltipCompat.setTooltipText(it, tooltip) } } } } diff --git a/app/src/main/kotlin/org/akanework/gramophone/logic/utils/GramophoneShuffleOrder.kt b/app/src/main/kotlin/org/akanework/gramophone/logic/utils/GramophoneShuffleOrder.kt index fc763075c..c51d1417a 100644 --- a/app/src/main/kotlin/org/akanework/gramophone/logic/utils/GramophoneShuffleOrder.kt +++ b/app/src/main/kotlin/org/akanework/gramophone/logic/utils/GramophoneShuffleOrder.kt @@ -137,6 +137,7 @@ class CircularShuffleOrder private constructor( fun deserialize(data: String?): Persistent { if (data == null || data.length < 2) return Persistent(Random.nextLong(), null) val split = data.split(';') + if (split.isEmpty()) return Persistent(Random.nextLong(), null) return Persistent(split[0].toLong(), if (split.size > 1) split[1] .split(',').map(String::toInt).toIntArray() else null) } diff --git a/app/src/main/kotlin/org/akanework/gramophone/ui/Widget.kt b/app/src/main/kotlin/org/akanework/gramophone/ui/Widget.kt new file mode 100644 index 000000000..cce2c4d89 --- /dev/null +++ b/app/src/main/kotlin/org/akanework/gramophone/ui/Widget.kt @@ -0,0 +1,202 @@ +package org.akanework.gramophone.ui + +import android.app.PendingIntent +import android.appwidget.AppWidgetManager +import android.appwidget.AppWidgetProvider +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.text.SpannableString +import android.text.Spanned +import android.text.style.ForegroundColorSpan +import android.widget.RemoteViews +import android.widget.RemoteViewsService +import androidx.core.content.ContextCompat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.withContext +import org.akanework.gramophone.R +import org.akanework.gramophone.logic.GramophonePlaybackService +import org.akanework.gramophone.logic.utils.SemanticLyrics +import org.akanework.gramophone.logic.utils.SpeakerEntity + +// TODO test on a5 +class LyricWidgetProvider : AppWidgetProvider() { + override fun onUpdate( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetIds: IntArray + ) { + val seekPi = PendingIntent.getBroadcast( + context, + GramophonePlaybackService.PENDING_INTENT_WIDGET_ID, + Intent(context.packageName + ".SEEK_TO").setPackage(context.packageName), + PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_MUTABLE + ) + for (appWidgetId in appWidgetIds) { + val views = RemoteViews(context.packageName, R.layout.lyric_widget) + lastViewForIdCache[appWidgetId] = views + views.setPendingIntentTemplate(R.id.list_view, seekPi) + views.setRemoteAdapter( + R.id.list_view, + Intent(context, LyricWidgetService::class.java).apply { + putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + data = Uri.parse(toUri(Intent.URI_INTENT_SCHEME)) + }) + views.setEmptyView(R.id.list_view, R.id.empty_view) + appWidgetManager.updateAppWidget(appWidgetId, views) + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) + } + } + + override fun onAppWidgetOptionsChanged( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int, + newOptions: Bundle? + ) { + onUpdate(context, appWidgetManager, intArrayOf(appWidgetId)) + } + + companion object { + private val lastViewForIdCache = hashMapOf() + fun update(context: Context) { + val awm = AppWidgetManager.getInstance(context) + LyricWidgetProvider().onUpdate(context, awm, awm.appWidgetIds(context)) + } + fun adapterUpdate(context: Context) { + val awm = AppWidgetManager.getInstance(context) + for (appWidgetId in awm.appWidgetIds(context)) { + awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) + Handler(Looper.getMainLooper()).postDelayed({ + GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.getCurrentLyricIndex() + ?.let { + lastViewForIdCache[appWidgetId]?.setScrollPosition(R.id.lyric_view, it) + awm.partiallyUpdateAppWidget(appWidgetId, lastViewForIdCache[appWidgetId]) + } // TODO fix scroll + }, 1000) + } + } + fun hasWidget(context: Context): Boolean { + val awm = AppWidgetManager.getInstance(context) + return awm.getAppWidgetIds(ComponentName(context, + LyricWidgetProvider::class.java)).isNotEmpty() + } + private fun AppWidgetManager.appWidgetIds(context: Context) = + getAppWidgetIds(ComponentName(context, LyricWidgetProvider::class.java)) + } +} + +class LyricWidgetService : RemoteViewsService() { + override fun onGetViewFactory(intent: Intent): RemoteViewsFactory? { + if (!intent.hasExtra(AppWidgetManager.EXTRA_APPWIDGET_ID)) + throw IllegalStateException("where is EXTRA_APPWIDGET_ID?") + return LyricRemoteViewsFactory(this, + intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0)) + } +} + +private class LyricRemoteViewsFactory(private val context: Context, private val widgetId: Int) + : RemoteViewsService.RemoteViewsFactory { + override fun onCreate() { + // do nothing + } + + override fun onDataSetChanged() { + // do nothing + } + + override fun onDestroy() { + // do nothing + } + + override fun getCount(): Int { + return (GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyrics as? SemanticLyrics.SyncedLyrics?) + ?.text?.size + ?: GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyricsLegacy?.size ?: 0 + } + + private val span = ForegroundColorSpan(ContextCompat.getColor(context, R.color.sl_lyric_active)) // TODO why is it pink? + + override fun getViewAt(position: Int): RemoteViews? { + val cPos = runBlocking { + withContext(Dispatchers.Main) { + GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.controller?.contentPosition + } + } + val item = + (GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyrics as? SemanticLyrics.SyncedLyrics?)?.text?.getOrNull( + position + ) + val itemLegacy = + GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyricsLegacy?.getOrNull( + position + ) + if (item == null && itemLegacy == null) return null + val isTranslation = item?.isTranslated ?: itemLegacy!!.isTranslation + val isBackground = item?.lyric?.speaker == SpeakerEntity.Background + val isVoice2 = item?.lyric?.speaker == SpeakerEntity.Voice2 + val startTs = item?.lyric?.start?.toLong() ?: itemLegacy!!.timeStamp ?: 0L + val endTs = item?.lyric?.words?.lastOrNull()?.timeRange?.last?.toLong() + ?: (GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyrics as? SemanticLyrics.SyncedLyrics?)?.text?.getOrNull( + position + 1 + )?.lyric?.start?.toLong() + ?: GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyricsLegacy?.getOrNull( + position + 1 + )?.timeStamp + ?: Long.MAX_VALUE + val isActive = cPos != null && cPos >= startTs && cPos <= endTs + return RemoteViews( + context.packageName, when { + isVoice2 && isTranslation -> R.layout.lyric_widget_txt_tlri + isVoice2 -> R.layout.lyric_widget_txt_nnri + isTranslation && isBackground -> R.layout.lyric_widget_txt_tbli + isTranslation -> R.layout.lyric_widget_txt_tlli + isBackground -> R.layout.lyric_widget_txt_bgli + else -> R.layout.lyric_widget_txt_nnli + } + ).apply { + val sb = SpannableString(item?.lyric?.text ?: itemLegacy!!.content) + if (isActive) { + val hlChar = item?.lyric?.words?.findLast { it.timeRange.start <= cPos.toULong() } + ?.charRange?.last?.plus(1) ?: sb.length + sb.setSpan(span, 0, hlChar, Spanned.SPAN_INCLUSIVE_INCLUSIVE) + } + setTextViewText(R.id.lyric_widget_item, sb) + setOnClickFillInIntent(R.id.lyric_widget_item, Intent().apply { + putExtras(Bundle().apply { + putLong("seekTo", startTs) + }) + }) + } + return null + } + + override fun getLoadingView(): RemoteViews? { + return null // TODO + } + + override fun getViewTypeCount(): Int { + return 6 + } + + override fun getItemId(position: Int): Long { + val item = + (GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyrics as? SemanticLyrics.SyncedLyrics?)?.text?.get( + position + ) + val itemLegacy = + GramophonePlaybackService.instanceForWidgetAndOnlyWidget?.lyricsLegacy?.get(position) + return (item?.lyric?.text?.hashCode() ?: itemLegacy!!.content.hashCode()).toLong() + .shl(32) or + (item?.lyric?.start?.hashCode() ?: itemLegacy!!.timeStamp.hashCode()).toLong() + } + + override fun hasStableIds(): Boolean { + return true + } +} \ No newline at end of file diff --git a/app/src/main/res/color/sl_lyric_active.xml b/app/src/main/res/color/sl_lyric_active.xml new file mode 100644 index 000000000..38868c25b --- /dev/null +++ b/app/src/main/res/color/sl_lyric_active.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/color/sl_lyric_text.xml b/app/src/main/res/color/sl_lyric_text.xml new file mode 100644 index 000000000..6029e6746 --- /dev/null +++ b/app/src/main/res/color/sl_lyric_text.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_gramophone_monochrome.xml b/app/src/main/res/drawable/ic_gramophone_monochrome.xml index 6bfdb1ab9..224ad2f79 100644 --- a/app/src/main/res/drawable/ic_gramophone_monochrome.xml +++ b/app/src/main/res/drawable/ic_gramophone_monochrome.xml @@ -1,9 +1,14 @@ - - - - - - - - - \ No newline at end of file + + + + + + diff --git a/app/src/main/res/layout-land/full_player.xml b/app/src/main/res/layout-land/full_player.xml index 64b70de69..ee506ef89 100644 --- a/app/src/main/res/layout-land/full_player.xml +++ b/app/src/main/res/layout-land/full_player.xml @@ -18,7 +18,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="16dp" android:background="@drawable/rp_buttons" - android:tooltipText="@string/expand_less" + app:tooltipText="@string/expand_less" android:contentDescription="@string/expand_less" app:icon="@drawable/ic_expand_more" app:iconGravity="textStart" @@ -89,7 +89,7 @@ android:gravity="center" android:scrollbars="none" android:textColor="?attr/colorOnSurface" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="22sp" tools:text="Artifiction" /> @@ -102,7 +102,7 @@ android:gravity="center" android:scrollbars="none" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Artifiction" /> @@ -172,7 +172,7 @@ android:layout_gravity="start" android:text="@string/default_time" android:textColor="?attr/colorAccent" - android:textFontWeight="600" + app:textFontWeight="600" android:fontFamily="sans-serif" /> @@ -198,7 +198,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/play" + app:tooltipText="@string/play" android:contentDescription="@string/play" app:backgroundTint="?attr/colorSecondaryContainer" app:icon="@drawable/play_anim" @@ -223,7 +223,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/skip_previous" + app:tooltipText="@string/skip_previous" android:contentDescription="@string/skip_previous" app:icon="@drawable/ic_skip_previous" app:iconGravity="textStart" @@ -248,7 +248,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/skip_next" + app:tooltipText="@string/skip_next" android:contentDescription="@string/skip_next" app:icon="@drawable/ic_skip_next" app:iconGravity="textStart" @@ -288,7 +288,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/dialog_lyrics" + app:tooltipText="@string/dialog_lyrics" android:contentDescription="@string/dialog_lyrics" app:icon="@drawable/ic_article" app:iconGravity="textStart" @@ -308,7 +308,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/repeat_mode" + app:tooltipText="@string/repeat_mode" android:contentDescription="@string/repeat_mode" app:icon="@drawable/ic_repeat" app:iconGravity="textStart" @@ -328,7 +328,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/shuffle" + app:tooltipText="@string/shuffle" android:contentDescription="@string/shuffle" app:icon="@drawable/ic_shuffle" app:iconGravity="textStart" @@ -349,7 +349,7 @@ android:insetBottom="0dp" android:saveEnabled="false" android:visibility="gone" - android:tooltipText="@string/playlist_favourite" + app:tooltipText="@string/playlist_favourite" android:contentDescription="@string/playlist_favourite" app:icon="@drawable/sl_check_fav" app:iconGravity="textStart" @@ -369,7 +369,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/timer" + app:tooltipText="@string/timer" android:contentDescription="@string/timer" app:toggleCheckedStateOnClick="false" app:icon="@drawable/sl_check_timer" @@ -388,7 +388,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/current_playlist" + app:tooltipText="@string/current_playlist" android:contentDescription="@string/current_playlist" app:icon="@drawable/ic_playlist_play" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/activity_audio_preview.xml b/app/src/main/res/layout/activity_audio_preview.xml index b86fa0c65..45c0664d5 100644 --- a/app/src/main/res/layout/activity_audio_preview.xml +++ b/app/src/main/res/layout/activity_audio_preview.xml @@ -41,7 +41,7 @@ android:ellipsize="end" android:fontFamily="sans-serif" android:textColor="?attr/colorOnSurface" - android:textFontWeight="400" + app:textFontWeight="400" android:textSize="15sp" app:layout_constraintBottom_toTopOf="@id/artist_text_view" app:layout_constraintEnd_toStartOf="@id/play_pause_replay_button" @@ -57,7 +57,7 @@ android:ellipsize="end" android:fontFamily="sans-serif" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="400" + app:textFontWeight="400" android:textSize="12sp" app:layout_constraintBottom_toBottomOf="@id/coverCardView" app:layout_constraintEnd_toStartOf="@id/play_pause_replay_button" @@ -78,7 +78,7 @@ android:insetBottom="0dp" android:padding="4dp" android:src="@drawable/ic_play_arrow" - android:tooltipText="@string/play" + app:tooltipText="@string/play" android:contentDescription="@string/play" app:icon="@drawable/play_anim" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/adapter_blacklist_folder_card.xml b/app/src/main/res/layout/adapter_blacklist_folder_card.xml index 00e1bf780..b24f66234 100644 --- a/app/src/main/res/layout/adapter_blacklist_folder_card.xml +++ b/app/src/main/res/layout/adapter_blacklist_folder_card.xml @@ -24,7 +24,7 @@ android:paddingTop="12dp" android:paddingBottom="12dp" android:textColor="?attr/colorOnSurface" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:layout_gravity="center_vertical" android:textSize="16sp" diff --git a/app/src/main/res/layout/adapter_folder_card.xml b/app/src/main/res/layout/adapter_folder_card.xml index dc29b0370..e1209cd92 100644 --- a/app/src/main/res/layout/adapter_folder_card.xml +++ b/app/src/main/res/layout/adapter_folder_card.xml @@ -45,7 +45,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurface" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Example Title" /> @@ -56,7 +56,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="14sp" tools:text="Example Artist" /> diff --git a/app/src/main/res/layout/adapter_grid_card.xml b/app/src/main/res/layout/adapter_grid_card.xml index e39379a41..56d7c4a51 100644 --- a/app/src/main/res/layout/adapter_grid_card.xml +++ b/app/src/main/res/layout/adapter_grid_card.xml @@ -55,7 +55,7 @@ android:gravity="start" android:singleLine="true" android:textColor="?attr/colorOnSurface" - android:textFontWeight="500" + app:textFontWeight="500" android:textSize="15sp" tools:text="Example Title" /> @@ -67,7 +67,7 @@ android:gravity="start" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="500" + app:textFontWeight="500" android:textSize="15sp" tools:text="Example Artist" /> diff --git a/app/src/main/res/layout/adapter_list_card.xml b/app/src/main/res/layout/adapter_list_card.xml index 01c67a7c1..5f8b81f39 100644 --- a/app/src/main/res/layout/adapter_list_card.xml +++ b/app/src/main/res/layout/adapter_list_card.xml @@ -51,7 +51,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurface" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Example Title" /> @@ -62,7 +62,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="14sp" tools:text="Example Artist" /> @@ -92,7 +92,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/more" + app:tooltipText="@string/more" android:contentDescription="@string/more" app:icon="@drawable/ic_more_vert_alt" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/adapter_list_card_larger.xml b/app/src/main/res/layout/adapter_list_card_larger.xml index 08d21b88e..9bda2a820 100644 --- a/app/src/main/res/layout/adapter_list_card_larger.xml +++ b/app/src/main/res/layout/adapter_list_card_larger.xml @@ -49,7 +49,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurface" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Example Title" /> @@ -60,7 +60,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="15sp" tools:text="Example Artist" /> @@ -90,7 +90,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/more" + app:tooltipText="@string/more" android:contentDescription="@string/more" app:icon="@drawable/ic_more_vert_alt" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/adapter_list_card_playlist.xml b/app/src/main/res/layout/adapter_list_card_playlist.xml index 5dc940b53..a2bb2634e 100644 --- a/app/src/main/res/layout/adapter_list_card_playlist.xml +++ b/app/src/main/res/layout/adapter_list_card_playlist.xml @@ -50,7 +50,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurface" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Example Title" /> @@ -61,7 +61,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="400" + app:textFontWeight="400" android:fontFamily="sans-serif" android:textSize="15sp" tools:text="Example Artist" /> @@ -74,7 +74,7 @@ android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" tools:text="3 | Disc 1" /> @@ -90,7 +90,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/remove" + app:tooltipText="@string/remove" android:contentDescription="@string/remove" app:icon="@drawable/ic_close" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/bottom_sheet.xml b/app/src/main/res/layout/bottom_sheet.xml index 56c706389..3fb039051 100644 --- a/app/src/main/res/layout/bottom_sheet.xml +++ b/app/src/main/res/layout/bottom_sheet.xml @@ -76,7 +76,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/play" + app:tooltipText="@string/play" android:contentDescription="@string/play" app:icon="@drawable/play_anim" app:iconGravity="textStart" @@ -98,7 +98,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/skip_next" + app:tooltipText="@string/skip_next" android:contentDescription="@string/skip_next" app:icon="@drawable/ic_skip_next" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/fragment_info_song.xml b/app/src/main/res/layout/fragment_info_song.xml index bf67ce4b6..54c64d158 100644 --- a/app/src/main/res/layout/fragment_info_song.xml +++ b/app/src/main/res/layout/fragment_info_song.xml @@ -59,7 +59,7 @@ android:text="@string/album_cover" android:textColor="?colorPrimary" android:fontFamily="sans-serif" - android:textFontWeight="500" + app:textFontWeight="500" android:textSize="17sp" android:layout_marginTop="24dp" android:layout_marginStart="24dp" /> @@ -109,7 +109,7 @@ android:text="@string/dialog_title" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -122,7 +122,7 @@ android:textColor="?colorOnSurface" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:layout_marginStart="50dp" android:fontFamily="sans-serif" android:gravity="end" /> @@ -144,7 +144,7 @@ android:text="@string/dialog_artist" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -156,7 +156,7 @@ android:text="@string/unknown_artist" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -179,7 +179,7 @@ android:text="@string/dialog_album" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -191,7 +191,7 @@ android:text="@string/unknown_album" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -214,7 +214,7 @@ android:text="@string/dialog_album_artist" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -226,7 +226,7 @@ android:text="@string/unknown_artist" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -249,7 +249,7 @@ android:text="@string/dialog_disc_number" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -260,7 +260,7 @@ android:layout_gravity="center_vertical" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" tools:text="0" android:layout_marginStart="50dp" @@ -284,7 +284,7 @@ android:text="@string/dialog_track_number" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -295,7 +295,7 @@ android:layout_gravity="center_vertical" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" tools:text="0" android:layout_marginStart="50dp" @@ -319,7 +319,7 @@ android:text="@string/dialog_genre" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -331,7 +331,7 @@ android:text="@string/unknown_genre" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -354,7 +354,7 @@ android:text="@string/dialog_year" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -366,7 +366,7 @@ android:text="@string/unknown_year" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -397,7 +397,7 @@ android:text="@string/dialog_duration" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -409,7 +409,7 @@ android:textColor="?colorOnSurface" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:layout_marginStart="50dp" android:fontFamily="sans-serif" android:gravity="end" /> @@ -431,7 +431,7 @@ android:text="@string/dialog_mime" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -442,7 +442,7 @@ android:layout_gravity="center_vertical" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -465,7 +465,7 @@ android:text="@string/dialog_path" android:layout_gravity="center_vertical" android:textColor="?colorPrimary" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" /> @@ -476,7 +476,7 @@ android:layout_gravity="center_vertical" android:textIsSelectable="true" android:textSize="16sp" - android:textFontWeight="500" + app:textFontWeight="500" android:textColor="?colorOnSurface" android:layout_marginStart="50dp" android:fontFamily="sans-serif" @@ -497,7 +497,7 @@ android:text="@string/dialog_lyrics" android:textColor="?colorPrimary" android:fontFamily="sans-serif" - android:textFontWeight="600" + app:textFontWeight="600" android:textSize="16sp" android:layout_marginTop="28dp" android:layout_marginStart="24dp" /> diff --git a/app/src/main/res/layout/full_player.xml b/app/src/main/res/layout/full_player.xml index 8ff5f56c4..50b70cf2a 100644 --- a/app/src/main/res/layout/full_player.xml +++ b/app/src/main/res/layout/full_player.xml @@ -18,7 +18,7 @@ android:layout_marginStart="24dp" android:layout_marginTop="16dp" android:background="@drawable/rp_buttons" - android:tooltipText="@string/expand_less" + app:tooltipText="@string/expand_less" android:contentDescription="@string/expand_less" app:icon="@drawable/ic_expand_more" app:iconGravity="textStart" @@ -90,7 +90,7 @@ android:gravity="center" android:scrollbars="none" android:textColor="?attr/colorOnSurface" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="22sp" tools:text="Artifiction" /> @@ -103,7 +103,7 @@ android:gravity="center" android:scrollbars="none" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Artifiction" /> @@ -173,7 +173,7 @@ android:layout_gravity="start" android:text="@string/default_time" android:textColor="?attr/colorAccent" - android:textFontWeight="600" + app:textFontWeight="600" android:fontFamily="sans-serif" /> @@ -199,7 +199,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/play" + app:tooltipText="@string/play" android:contentDescription="@string/play" app:backgroundTint="?attr/colorSecondaryContainer" app:icon="@drawable/play_anim" @@ -224,7 +224,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/skip_previous" + app:tooltipText="@string/skip_previous" android:contentDescription="@string/skip_previous" app:icon="@drawable/ic_skip_previous" app:iconGravity="textStart" @@ -249,7 +249,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/skip_next" + app:tooltipText="@string/skip_next" android:contentDescription="@string/skip_next" app:icon="@drawable/ic_skip_next" app:iconGravity="textStart" @@ -289,7 +289,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/dialog_lyrics" + app:tooltipText="@string/dialog_lyrics" android:contentDescription="@string/dialog_lyrics" app:icon="@drawable/ic_article" app:iconGravity="textStart" @@ -309,7 +309,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/repeat_mode" + app:tooltipText="@string/repeat_mode" android:contentDescription="@string/repeat_mode" app:icon="@drawable/ic_repeat" app:iconGravity="textStart" @@ -329,7 +329,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/shuffle" + app:tooltipText="@string/shuffle" android:contentDescription="@string/shuffle" app:icon="@drawable/ic_shuffle" app:iconGravity="textStart" @@ -350,7 +350,7 @@ android:insetBottom="0dp" android:saveEnabled="false" android:visibility="gone" - android:tooltipText="@string/playlist_favourite" + app:tooltipText="@string/playlist_favourite" android:contentDescription="@string/playlist_favourite" app:icon="@drawable/sl_check_fav" app:iconGravity="textStart" @@ -370,7 +370,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:saveEnabled="false" - android:tooltipText="@string/timer" + app:tooltipText="@string/timer" android:contentDescription="@string/timer" app:toggleCheckedStateOnClick="false" app:icon="@drawable/sl_check_timer" @@ -389,7 +389,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/current_playlist" + app:tooltipText="@string/current_playlist" android:contentDescription="@string/current_playlist" app:icon="@drawable/ic_playlist_play" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/general_decor.xml b/app/src/main/res/layout/general_decor.xml index 210b39d79..1876bb5ae 100644 --- a/app/src/main/res/layout/general_decor.xml +++ b/app/src/main/res/layout/general_decor.xml @@ -12,7 +12,7 @@ android:layout_gravity="start|center_vertical" android:layout_marginStart="24dp" android:textColor="?attr/colorOnSurface" - android:textFontWeight="600" + app:textFontWeight="600" android:fontFamily="sans-serif" android:textSize="15sp" tools:text="0 Song" /> @@ -34,7 +34,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:visibility="gone" - android:tooltipText="@string/play_all" + app:tooltipText="@string/play_all" android:contentDescription="@string/play_all" app:icon="@drawable/ic_play_arrow" app:iconGravity="textStart" @@ -53,7 +53,7 @@ android:insetRight="0dp" android:insetBottom="0dp" android:visibility="gone" - android:tooltipText="@string/shuffle_all" + app:tooltipText="@string/shuffle_all" android:contentDescription="@string/shuffle_all" app:icon="@drawable/ic_shuffle" app:iconGravity="textStart" @@ -71,7 +71,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/sort" + app:tooltipText="@string/sort" android:contentDescription="@string/sort" app:icon="@drawable/ic_sort" app:iconGravity="textStart" @@ -89,7 +89,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/scroll_to_albums" + app:tooltipText="@string/scroll_to_albums" android:contentDescription="@string/scroll_to_albums" app:icon="@drawable/baseline_arrow_upward_24" app:iconGravity="textStart" @@ -108,7 +108,7 @@ android:insetTop="0dp" android:insetRight="0dp" android:insetBottom="0dp" - android:tooltipText="@string/scroll_to_songs" + app:tooltipText="@string/scroll_to_songs" android:contentDescription="@string/scroll_to_songs" app:icon="@drawable/baseline_arrow_downward_24" app:iconGravity="textStart" diff --git a/app/src/main/res/layout/lyric_widget.xml b/app/src/main/res/layout/lyric_widget.xml new file mode 100644 index 000000000..6eed27e74 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_bgli.xml b/app/src/main/res/layout/lyric_widget_txt_bgli.xml new file mode 100644 index 000000000..b227a3cb6 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_bgli.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_nnli.xml b/app/src/main/res/layout/lyric_widget_txt_nnli.xml new file mode 100644 index 000000000..369afc582 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_nnli.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_nnri.xml b/app/src/main/res/layout/lyric_widget_txt_nnri.xml new file mode 100644 index 000000000..fb0aea172 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_nnri.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_tbli.xml b/app/src/main/res/layout/lyric_widget_txt_tbli.xml new file mode 100644 index 000000000..2c867f583 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_tbli.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_tlli.xml b/app/src/main/res/layout/lyric_widget_txt_tlli.xml new file mode 100644 index 000000000..b227a3cb6 --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_tlli.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/lyric_widget_txt_tlri.xml b/app/src/main/res/layout/lyric_widget_txt_tlri.xml new file mode 100644 index 000000000..e29499b8e --- /dev/null +++ b/app/src/main/res/layout/lyric_widget_txt_tlri.xml @@ -0,0 +1,9 @@ + + \ No newline at end of file diff --git a/app/src/main/res/layout/playlist_bottom_sheet.xml b/app/src/main/res/layout/playlist_bottom_sheet.xml index e9eadb48c..7b239c852 100644 --- a/app/src/main/res/layout/playlist_bottom_sheet.xml +++ b/app/src/main/res/layout/playlist_bottom_sheet.xml @@ -49,7 +49,7 @@ android:singleLine="true" android:text="@string/now_playing" android:textColor="?attr/colorOnSurface" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="17sp" tools:text="Now playing" /> @@ -60,7 +60,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textColor="?attr/colorOnSurfaceVariant" - android:textFontWeight="500" + app:textFontWeight="500" android:fontFamily="sans-serif" android:textSize="15sp" tools:text="Artifact" /> diff --git a/app/src/main/res/layout/preference_category_md.xml b/app/src/main/res/layout/preference_category_md.xml index 63ab258a0..11b6393d4 100644 --- a/app/src/main/res/layout/preference_category_md.xml +++ b/app/src/main/res/layout/preference_category_md.xml @@ -16,6 +16,7 @@ --> \ No newline at end of file diff --git a/app/src/main/res/layout/tab_order_seperator.xml b/app/src/main/res/layout/tab_order_seperator.xml index 05bf463e8..e23478a11 100644 --- a/app/src/main/res/layout/tab_order_seperator.xml +++ b/app/src/main/res/layout/tab_order_seperator.xml @@ -10,10 +10,12 @@ android:background="?attr/selectableItemBackground" tools:ignore="Overdraw"> + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 10376b38b..35165f1e9 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -24,4 +24,7 @@ 20sp 14sp 50dp + 20sp + 15sp + 12sp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 227e0a604..1be873cae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -200,4 +200,5 @@ Experimental UI to display word-by-word lyric with advanced features Status bar lyrics Enable MeiZu method of displaying lyrics in status bar (only available on some devices) + Widget that shows lyrics of currently playing media diff --git a/app/src/main/res/values/styleables.xml b/app/src/main/res/values/styleables.xml index cf487628a..96e481968 100644 --- a/app/src/main/res/values/styleables.xml +++ b/app/src/main/res/values/styleables.xml @@ -4,6 +4,10 @@ - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 7e77c6a78..076861cef 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -14,6 +14,8 @@ @style/CollapsingToolbarLarge @drawable/popup_background @style/AppTheme.AlertDialog + 28dp + 20dp