Move Glance Widget to seperate module (#8989)

Move Widget to seperate module

- Create a core module for presentation. Widget and App will share some resources and hopefully composables
This commit is contained in:
Andreas 2023-01-26 23:53:24 +01:00 committed by GitHub
parent c892c793a8
commit 12e41b6e6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 154 additions and 35 deletions

View file

@ -143,6 +143,8 @@ dependencies {
implementation(project(":source-api"))
implementation(project(":data"))
implementation(project(":domain"))
implementation(project(":presentation-core"))
implementation(project(":presentation-widget"))
// Compose
implementation(platform(compose.bom))
@ -181,7 +183,6 @@ dependencies {
implementation(androidx.splashscreen)
implementation(androidx.recyclerview)
implementation(androidx.viewpager)
implementation(androidx.glance)
implementation(androidx.profileinstaller)
implementation(androidx.bundles.lifecycle)

View file

@ -188,7 +188,7 @@
android:exported="false" />
<receiver
android:name=".glance.UpdatesGridGlanceReceiver"
android:name="tachiyomi.presentation.widget.UpdatesGridGlanceReceiver"
android:enabled="@bool/glance_appwidget_available"
android:exported="false"
android:label="@string/label_recent_updates">

View file

@ -13,7 +13,6 @@ import android.os.Looper
import android.webkit.WebView
import androidx.core.app.NotificationManagerCompat
import androidx.core.content.getSystemService
import androidx.glance.appwidget.GlanceAppWidgetManager
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
@ -36,7 +35,6 @@ import eu.kanade.tachiyomi.data.coil.MangaCoverKeyer
import eu.kanade.tachiyomi.data.coil.MangaKeyer
import eu.kanade.tachiyomi.data.coil.TachiyomiImageDecoder
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.glance.UpdatesGridGlanceWidget
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.NetworkPreferences
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
@ -47,8 +45,6 @@ import eu.kanade.tachiyomi.util.system.isReleaseBuildType
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notification
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import logcat.AndroidLogcatLogger
@ -58,7 +54,7 @@ import org.acra.config.httpSender
import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
import org.conscrypt.Conscrypt
import tachiyomi.data.DatabaseHandler
import tachiyomi.presentation.widget.TachiyomiWidgetManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@ -128,17 +124,9 @@ class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
// Updates widget update
Injekt.get<DatabaseHandler>()
.subscribeToList { updatesViewQueries.updates(after = UpdatesGridGlanceWidget.DateLimit.timeInMillis) }
.drop(1)
.distinctUntilChanged()
.onEach {
val manager = GlanceAppWidgetManager(this)
if (manager.getGlanceIds(UpdatesGridGlanceWidget::class.java).isNotEmpty()) {
UpdatesGridGlanceWidget().loadData(it)
}
}
.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
with(TachiyomiWidgetManager) {
init(ProcessLifecycleOwner.get().lifecycleScope, Injekt.get())
}
if (!LogcatLogger.isInstalled && networkPreferences.verboseLogging().get()) {
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))

View file

@ -115,12 +115,6 @@ fun Context.hasPermission(permission: String) = ContextCompat.checkSelfPermissio
val getDisplayMaxHeightInPx: Int
get() = Resources.getSystem().displayMetrics.let { max(it.heightPixels, it.widthPixels) }
/**
* Converts to px.
*/
val Int.dpToPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
/**
* Converts to px and takes into account LTR/RTL layout.
*/

View file

@ -0,0 +1,9 @@
package eu.kanade.tachiyomi.util.system
import android.content.res.Resources
/**
* Converts to px.
*/
val Int.dpToPx: Int
get() = (this * Resources.getSystem().displayMetrics.density).toInt()

1
presentation-core/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,17 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "tachiyomi.presentation.core"
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
}
dependencies {
}

View file

21
presentation-core/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

1
presentation-widget/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,33 @@
plugins {
id("com.android.library")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "tachiyomi.presentation.widget"
defaultConfig {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = compose.versions.compiler.get()
}
}
dependencies {
implementation(project(":core"))
implementation(project(":data"))
implementation(project(":domain"))
implementation(project(":presentation-core"))
implementation(androidx.glance)
implementation(libs.coil.core)
}

View file

21
presentation-widget/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View file

@ -1,11 +1,10 @@
package eu.kanade.tachiyomi.glance
package tachiyomi.presentation.widget
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.glance.GlanceModifier
import androidx.glance.LocalContext
import androidx.glance.appwidget.cornerRadius
import eu.kanade.tachiyomi.R
fun GlanceModifier.appWidgetBackgroundRadius(): GlanceModifier {
return this.cornerRadius(R.dimen.appwidget_background_radius)

View file

@ -0,0 +1,26 @@
package tachiyomi.presentation.widget
import android.content.Context
import androidx.glance.appwidget.GlanceAppWidgetManager
import androidx.lifecycle.LifecycleCoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import tachiyomi.data.DatabaseHandler
object TachiyomiWidgetManager {
fun Context.init(scope: LifecycleCoroutineScope, database: DatabaseHandler) {
database.subscribeToList { updatesViewQueries.updates(after = UpdatesGridGlanceWidget.DateLimit.timeInMillis) }
.drop(1)
.distinctUntilChanged()
.onEach {
val manager = GlanceAppWidgetManager(this)
if (manager.getGlanceIds(UpdatesGridGlanceWidget::class.java).isNotEmpty()) {
UpdatesGridGlanceWidget().loadData(it)
}
}
.launchIn(scope)
}
}

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.glance
package tachiyomi.presentation.widget
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver

View file

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.glance
package tachiyomi.presentation.widget
import android.app.Application
import android.content.Intent
@ -43,10 +43,7 @@ import coil.request.ImageRequest
import coil.size.Precision
import coil.size.Scale
import coil.transform.RoundedCornersTransformation
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.core.security.SecurityPreferences
import eu.kanade.tachiyomi.ui.main.MainActivity
import eu.kanade.tachiyomi.util.Constants
import eu.kanade.tachiyomi.util.lang.launchIO
import eu.kanade.tachiyomi.util.system.dpToPx
import kotlinx.coroutines.MainScope
@ -81,7 +78,8 @@ class UpdatesGridGlanceWidget : GlanceAppWidget() {
@Composable
private fun WidgetNotAvailable() {
val intent = Intent(LocalContext.current, MainActivity::class.java).apply {
val clazz = Class.forName("eu.kanade.tachiyomi.ui.main.MainActivity")
val intent = Intent(LocalContext.current, clazz).apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
Box(
@ -134,9 +132,9 @@ class UpdatesGridGlanceWidget : GlanceAppWidget() {
.padding(horizontal = 3.dp),
contentAlignment = Alignment.Center,
) {
val intent = Intent(LocalContext.current, MainActivity::class.java).apply {
action = MainActivity.SHORTCUT_MANGA
putExtra(Constants.MANGA_EXTRA, mangaId)
val intent = Intent(LocalContext.current, Class.forName("eu.kanade.tachiyomi.ui.main.MainActivity")).apply {
action = "eu.kanade.tachiyomi.SHOW_MANGA"
putExtra("manga", mangaId)
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)

View file

@ -0,0 +1,4 @@
<resources>
<dimen name="appwidget_background_radius">16dp</dimen>
<dimen name="appwidget_inner_radius">12dp</dimen>
</resources>

View file

@ -43,3 +43,5 @@ include(":core")
include(":macrobenchmark")
include(":data")
include(":domain")
include(":presentation-widget")
include(":presentation-core")