From 85c913106172aa86b8fb9378ce450429034c14ac Mon Sep 17 00:00:00 2001 From: oxy Date: Sat, 7 Sep 2024 00:38:45 +0800 Subject: [PATCH] feat: favourite widget. --- .../m3u/androidApp/glance/FavouriteWidget.kt | 93 ++++++++++++++++ .../m3u/androidApp/glance/GlanceReceiver.kt | 5 +- .../androidApp/glance/PlayRandomlyWidget.kt | 103 ------------------ 3 files changed, 94 insertions(+), 107 deletions(-) create mode 100644 androidApp/src/main/java/com/m3u/androidApp/glance/FavouriteWidget.kt delete mode 100644 androidApp/src/main/java/com/m3u/androidApp/glance/PlayRandomlyWidget.kt diff --git a/androidApp/src/main/java/com/m3u/androidApp/glance/FavouriteWidget.kt b/androidApp/src/main/java/com/m3u/androidApp/glance/FavouriteWidget.kt new file mode 100644 index 000000000..04dcf71ee --- /dev/null +++ b/androidApp/src/main/java/com/m3u/androidApp/glance/FavouriteWidget.kt @@ -0,0 +1,93 @@ +package com.m3u.androidApp.glance + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.unit.dp +import androidx.glance.GlanceId +import androidx.glance.GlanceModifier +import androidx.glance.GlanceTheme +import androidx.glance.action.clickable +import androidx.glance.appwidget.GlanceAppWidget +import androidx.glance.appwidget.SizeMode +import androidx.glance.appwidget.action.actionStartActivity +import androidx.glance.appwidget.appWidgetBackground +import androidx.glance.appwidget.cornerRadius +import androidx.glance.appwidget.lazy.LazyColumn +import androidx.glance.appwidget.lazy.itemsIndexed +import androidx.glance.appwidget.provideContent +import androidx.glance.background +import androidx.glance.layout.Alignment +import androidx.glance.layout.Box +import androidx.glance.layout.Column +import androidx.glance.layout.Spacer +import androidx.glance.layout.fillMaxSize +import androidx.glance.layout.fillMaxWidth +import androidx.glance.layout.height +import androidx.glance.layout.padding +import androidx.glance.text.Text +import androidx.glance.text.TextStyle +import com.m3u.core.Contracts +import dagger.hilt.android.EntryPointAccessors + +class FavouriteWidget : GlanceAppWidget() { + override val sizeMode: SizeMode = SizeMode.Exact + override suspend fun provideGlance(context: Context, id: GlanceId) { + val accessor: GlanceAccessor by lazy { + EntryPointAccessors.fromApplication(context.applicationContext) + } + val favouriteFlow = accessor.channelRepository.observeAllFavourite() + provideContent { + val channels by favouriteFlow.collectAsState(initial = emptyList()) + GlanceTheme { + Box( + contentAlignment = Alignment.BottomStart, + modifier = GlanceModifier + .fillMaxSize() + .cornerRadius(16.dp) + .background(GlanceTheme.colors.background) + .appWidgetBackground() + .padding(4.dp) + ) { + LazyColumn( + modifier = GlanceModifier.fillMaxWidth() + ) { + itemsIndexed(channels) { i, channel -> + Column { + Box( + modifier = GlanceModifier + .fillMaxWidth() + .clickable( + actionStartActivity( + Intent(Intent.ACTION_VIEW).apply { + component = ComponentName.createRelative( + context, + Contracts.PLAYER_ACTIVITY + ) + putExtra(Contracts.PLAYER_SHORTCUT_CHANNEL_ID, channel.id) + } + ) + ) + .padding(16.dp) + .cornerRadius(16.dp) + .background(GlanceTheme.colors.surfaceVariant), + contentAlignment = Alignment.CenterStart + ) { + Text( + text = channel.title, + style = TextStyle(GlanceTheme.colors.onSurfaceVariant) + ) + } + if (i != channels.lastIndex) { + Spacer(GlanceModifier.height(4.dp)) + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/androidApp/src/main/java/com/m3u/androidApp/glance/GlanceReceiver.kt b/androidApp/src/main/java/com/m3u/androidApp/glance/GlanceReceiver.kt index 12515de2f..4121dbf4e 100644 --- a/androidApp/src/main/java/com/m3u/androidApp/glance/GlanceReceiver.kt +++ b/androidApp/src/main/java/com/m3u/androidApp/glance/GlanceReceiver.kt @@ -3,19 +3,16 @@ package com.m3u.androidApp.glance import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.GlanceAppWidgetReceiver import com.m3u.data.repository.channel.ChannelRepository -import com.m3u.data.repository.media.MediaRepository import dagger.hilt.EntryPoint import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent class GlanceReceiver : GlanceAppWidgetReceiver() { - override val glanceAppWidget: GlanceAppWidget = PlayRandomlyWidget() - + override val glanceAppWidget: GlanceAppWidget = FavouriteWidget() } @EntryPoint @InstallIn(SingletonComponent::class) interface GlanceAccessor { val channelRepository: ChannelRepository - val mediaRepository: MediaRepository } \ No newline at end of file diff --git a/androidApp/src/main/java/com/m3u/androidApp/glance/PlayRandomlyWidget.kt b/androidApp/src/main/java/com/m3u/androidApp/glance/PlayRandomlyWidget.kt deleted file mode 100644 index d07a27dca..000000000 --- a/androidApp/src/main/java/com/m3u/androidApp/glance/PlayRandomlyWidget.kt +++ /dev/null @@ -1,103 +0,0 @@ -package com.m3u.androidApp.glance - -import android.content.ComponentName -import android.content.Context -import android.content.Intent -import android.graphics.Bitmap -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.produceState -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.core.graphics.drawable.toBitmap -import androidx.glance.GlanceId -import androidx.glance.GlanceModifier -import androidx.glance.GlanceTheme -import androidx.glance.Image -import androidx.glance.ImageProvider -import androidx.glance.action.clickable -import androidx.glance.appwidget.GlanceAppWidget -import androidx.glance.appwidget.action.actionStartActivity -import androidx.glance.appwidget.appWidgetBackground -import androidx.glance.appwidget.cornerRadius -import androidx.glance.appwidget.provideContent -import androidx.glance.background -import androidx.glance.layout.Alignment -import androidx.glance.layout.Box -import androidx.glance.layout.ContentScale -import androidx.glance.layout.fillMaxSize -import androidx.glance.layout.padding -import androidx.glance.text.FontWeight -import androidx.glance.text.Text -import androidx.glance.text.TextDefaults -import androidx.glance.unit.ColorProvider -import com.m3u.core.Contracts -import dagger.hilt.android.EntryPointAccessors - -class PlayRandomlyWidget : GlanceAppWidget() { - override suspend fun provideGlance(context: Context, id: GlanceId) { - val accessor: GlanceAccessor by lazy { - EntryPointAccessors.fromApplication(context.applicationContext) - } - val playedRecently = accessor.channelRepository.observePlayedRecently() - provideContent { - val channel by playedRecently.collectAsState(initial = null) - GlanceTheme { - val bitmap: Bitmap? by produceState( - initialValue = null, - key1 = channel?.cover - ) { - value = accessor.mediaRepository - .loadDrawable(channel?.cover.orEmpty()) - ?.toBitmap() - } - Box( - contentAlignment = Alignment.BottomStart, - modifier = GlanceModifier - .fillMaxSize() - .cornerRadius(16.dp) - .clickable( - actionStartActivity( - Intent(Intent.ACTION_VIEW).apply { - component = ComponentName.createRelative( - context, - Contracts.PLAYER_ACTIVITY - ) - putExtra( - Contracts.PLAYER_SHORTCUT_CHANNEL_RECENTLY, - true - ) - } - ) - ) - .background(GlanceTheme.colors.background) - .appWidgetBackground() - .padding(4.dp) - ) { - val currentBitmap = bitmap - if (currentBitmap != null) { - Image( - provider = ImageProvider(currentBitmap), - contentDescription = channel?.title, - contentScale = ContentScale.Crop, - modifier = GlanceModifier - .fillMaxSize() - .cornerRadius(16.dp) - ) - } - Text( - text = channel?.title.orEmpty(), - style = TextDefaults.defaultTextStyle.copy( - fontSize = 18.sp, - fontWeight = FontWeight.Bold, - color = ColorProvider(Color.White) - ), - maxLines = 1, - modifier = GlanceModifier.padding(12.dp) - ) - } - } - } - } -} \ No newline at end of file