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:
parent
c892c793a8
commit
12e41b6e6f
@ -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)
|
||||
|
@ -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">
|
||||
|
@ -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)
|
||||
with(TachiyomiWidgetManager) {
|
||||
init(ProcessLifecycleOwner.get().lifecycleScope, Injekt.get())
|
||||
}
|
||||
}
|
||||
.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
|
||||
|
||||
if (!LogcatLogger.isInstalled && networkPreferences.verboseLogging().get()) {
|
||||
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
1
presentation-core/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
17
presentation-core/build.gradle.kts
Normal file
17
presentation-core/build.gradle.kts
Normal 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 {
|
||||
|
||||
}
|
0
presentation-core/consumer-rules.pro
Normal file
0
presentation-core/consumer-rules.pro
Normal file
21
presentation-core/proguard-rules.pro
vendored
Normal file
21
presentation-core/proguard-rules.pro
vendored
Normal 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
|
2
presentation-core/src/main/AndroidManifest.xml
Normal file
2
presentation-core/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest />
|
1
presentation-widget/.gitignore
vendored
Normal file
1
presentation-widget/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/build
|
33
presentation-widget/build.gradle.kts
Normal file
33
presentation-widget/build.gradle.kts
Normal 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)
|
||||
|
||||
}
|
0
presentation-widget/consumer-rules.pro
Normal file
0
presentation-widget/consumer-rules.pro
Normal file
21
presentation-widget/proguard-rules.pro
vendored
Normal file
21
presentation-widget/proguard-rules.pro
vendored
Normal 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
|
2
presentation-widget/src/main/AndroidManifest.xml
Normal file
2
presentation-widget/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest />
|
@ -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)
|
@ -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)
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package eu.kanade.tachiyomi.glance
|
||||
package tachiyomi.presentation.widget
|
||||
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
@ -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)
|
||||
|
4
presentation-widget/src/main/res/values/dimens.xml
Normal file
4
presentation-widget/src/main/res/values/dimens.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<dimen name="appwidget_background_radius">16dp</dimen>
|
||||
<dimen name="appwidget_inner_radius">12dp</dimen>
|
||||
</resources>
|
@ -43,3 +43,5 @@ include(":core")
|
||||
include(":macrobenchmark")
|
||||
include(":data")
|
||||
include(":domain")
|
||||
include(":presentation-widget")
|
||||
include(":presentation-core")
|
||||
|
Loading…
Reference in New Issue
Block a user