diff --git a/app/src/main/java/eu/kanade/tachiyomi/App.kt b/app/src/main/java/eu/kanade/tachiyomi/App.kt index e8fe7d98e4..dbb6ed6a5e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/App.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/App.kt @@ -128,7 +128,7 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory { setAppCompatDelegateThemeMode(Injekt.get().themeMode().get()) // Updates widget update - with(TachiyomiWidgetManager(Injekt.get())) { + with(TachiyomiWidgetManager(Injekt.get(), Injekt.get())) { init(ProcessLifecycleOwner.get().lifecycleScope) } diff --git a/gradle/androidx.versions.toml b/gradle/androidx.versions.toml index 16d8796ee2..25f1798d36 100644 --- a/gradle/androidx.versions.toml +++ b/gradle/androidx.versions.toml @@ -13,7 +13,7 @@ corektx = "androidx.core:core-ktx:1.11.0-beta01" splashscreen = "androidx.core:core-splashscreen:1.0.0-alpha02" recyclerview = "androidx.recyclerview:recyclerview:1.3.1-rc01" viewpager = "androidx.viewpager:viewpager:1.1.0-alpha01" -glance = "androidx.glance:glance-appwidget:1.0.0-alpha03" +glance = "androidx.glance:glance-appwidget:1.0.0-beta01" profileinstaller = "androidx.profileinstaller:profileinstaller:1.3.1" lifecycle-common = { module = "androidx.lifecycle:lifecycle-common", version.ref = "lifecycle_version" } diff --git a/presentation-widget/src/main/java/tachiyomi/presentation/widget/TachiyomiWidgetManager.kt b/presentation-widget/src/main/java/tachiyomi/presentation/widget/TachiyomiWidgetManager.kt index 89a8a7fcd1..e51b0337dc 100644 --- a/presentation-widget/src/main/java/tachiyomi/presentation/widget/TachiyomiWidgetManager.kt +++ b/presentation-widget/src/main/java/tachiyomi/presentation/widget/TachiyomiWidgetManager.kt @@ -1,29 +1,34 @@ package tachiyomi.presentation.widget import android.content.Context -import androidx.glance.appwidget.GlanceAppWidgetManager +import androidx.glance.appwidget.updateAll import androidx.lifecycle.LifecycleCoroutineScope +import eu.kanade.tachiyomi.core.security.SecurityPreferences +import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.drop import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import logcat.LogPriority +import tachiyomi.core.util.system.logcat import tachiyomi.domain.updates.interactor.GetUpdates class TachiyomiWidgetManager( private val getUpdates: GetUpdates, + private val securityPreferences: SecurityPreferences, ) { fun Context.init(scope: LifecycleCoroutineScope) { - getUpdates.subscribe( - read = false, - after = UpdatesGridGlanceWidget.DateLimit.timeInMillis, + combine( + getUpdates.subscribe(read = false, after = UpdatesGridGlanceWidget.DateLimit.timeInMillis), + securityPreferences.useAuthenticator().changes(), + transform = { a, _ -> a }, ) - .drop(1) .distinctUntilChanged() .onEach { - val manager = GlanceAppWidgetManager(this) - if (manager.getGlanceIds(UpdatesGridGlanceWidget::class.java).isNotEmpty()) { - UpdatesGridGlanceWidget().loadData(it) + try { + UpdatesGridGlanceWidget().updateAll(this) + } catch (e: Exception) { + logcat(LogPriority.ERROR, e) { "Failed to update widget" } } } .launchIn(scope) diff --git a/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceReceiver.kt b/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceReceiver.kt index 2318b31fc6..93a4cf7358 100644 --- a/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceReceiver.kt +++ b/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceReceiver.kt @@ -4,5 +4,5 @@ import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.GlanceAppWidgetReceiver class UpdatesGridGlanceReceiver : GlanceAppWidgetReceiver() { - override val glanceAppWidget: GlanceAppWidget = UpdatesGridGlanceWidget().apply { loadData() } + override val glanceAppWidget: GlanceAppWidget = UpdatesGridGlanceWidget() } diff --git a/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceWidget.kt b/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceWidget.kt index b467651d84..9d7794b56f 100644 --- a/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceWidget.kt +++ b/presentation-widget/src/main/java/tachiyomi/presentation/widget/UpdatesGridGlanceWidget.kt @@ -1,17 +1,18 @@ package tachiyomi.presentation.widget import android.app.Application +import android.content.Context import android.graphics.Bitmap import android.os.Build -import androidx.compose.runtime.Composable import androidx.core.graphics.drawable.toBitmap +import androidx.glance.GlanceId import androidx.glance.GlanceModifier import androidx.glance.ImageProvider import androidx.glance.appwidget.GlanceAppWidget import androidx.glance.appwidget.GlanceAppWidgetManager import androidx.glance.appwidget.SizeMode import androidx.glance.appwidget.appWidgetBackground -import androidx.glance.appwidget.updateAll +import androidx.glance.appwidget.provideContent import androidx.glance.background import androidx.glance.layout.fillMaxSize import coil.executeBlocking @@ -23,8 +24,7 @@ import coil.size.Scale import coil.transform.RoundedCornersTransformation import eu.kanade.tachiyomi.core.security.SecurityPreferences import eu.kanade.tachiyomi.util.system.dpToPx -import kotlinx.coroutines.MainScope -import tachiyomi.core.util.lang.launchIO +import tachiyomi.core.util.lang.withIOContext import tachiyomi.domain.manga.model.MangaCover import tachiyomi.domain.updates.interactor.GetUpdates import tachiyomi.domain.updates.model.UpdatesWithRelations @@ -45,33 +45,29 @@ class UpdatesGridGlanceWidget : GlanceAppWidget() { private val app: Application by injectLazy() private val preferences: SecurityPreferences by injectLazy() - private val coroutineScope = MainScope() - private var data: List>? = null override val sizeMode = SizeMode.Exact - @Composable - override fun Content() { - // If app lock enabled, don't do anything - if (preferences.useAuthenticator().get()) { - LockedWidget() - return + override suspend fun provideGlance(context: Context, id: GlanceId) { + val locked = preferences.useAuthenticator().get() + if (!locked) loadData() + + provideContent { + // If app lock enabled, don't do anything + if (locked) { + LockedWidget() + return@provideContent + } + UpdatesWidget(data) } - UpdatesWidget(data) } - fun loadData(list: List? = null) { - coroutineScope.launchIO { - // Don't show anything when lock is active - if (preferences.useAuthenticator().get()) { - updateAll(app) - return@launchIO - } - + private suspend fun loadData(list: List? = null) { + withIOContext { val manager = GlanceAppWidgetManager(app) val ids = manager.getGlanceIds(this@UpdatesGridGlanceWidget::class.java) - if (ids.isEmpty()) return@launchIO + if (ids.isEmpty()) return@withIOContext val processList = list ?: Injekt.get().await( @@ -84,7 +80,6 @@ class UpdatesGridGlanceWidget : GlanceAppWidget() { .calculateRowAndColumnCount() data = prepareList(processList, rowCount * columnCount) - ids.forEach { update(app, it) } } }