mirror of
https://github.com/mihonapp/mihon.git
synced 2025-06-29 12:37:50 +02:00
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:
@ -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)
|
||||
}
|
||||
}
|
||||
.launchIn(ProcessLifecycleOwner.get().lifecycleScope)
|
||||
with(TachiyomiWidgetManager) {
|
||||
init(ProcessLifecycleOwner.get().lifecycleScope, Injekt.get())
|
||||
}
|
||||
|
||||
if (!LogcatLogger.isInstalled && networkPreferences.verboseLogging().get()) {
|
||||
LogcatLogger.install(AndroidLogcatLogger(LogPriority.VERBOSE))
|
||||
|
@ -1,21 +0,0 @@
|
||||
package eu.kanade.tachiyomi.glance
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
fun GlanceModifier.appWidgetInnerRadius(): GlanceModifier {
|
||||
return this.cornerRadius(R.dimen.appwidget_inner_radius)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun stringResource(@StringRes id: Int): String {
|
||||
return LocalContext.current.getString(id)
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package eu.kanade.tachiyomi.glance
|
||||
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetReceiver
|
||||
|
||||
class UpdatesGridGlanceReceiver : GlanceAppWidgetReceiver() {
|
||||
override val glanceAppWidget: GlanceAppWidget = UpdatesGridGlanceWidget().apply { loadData() }
|
||||
}
|
@ -1,287 +0,0 @@
|
||||
package eu.kanade.tachiyomi.glance
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.glance.GlanceModifier
|
||||
import androidx.glance.Image
|
||||
import androidx.glance.ImageProvider
|
||||
import androidx.glance.LocalContext
|
||||
import androidx.glance.LocalSize
|
||||
import androidx.glance.action.clickable
|
||||
import androidx.glance.appwidget.CircularProgressIndicator
|
||||
import androidx.glance.appwidget.GlanceAppWidget
|
||||
import androidx.glance.appwidget.GlanceAppWidgetManager
|
||||
import androidx.glance.appwidget.SizeMode
|
||||
import androidx.glance.appwidget.action.actionStartActivity
|
||||
import androidx.glance.appwidget.appWidgetBackground
|
||||
import androidx.glance.appwidget.updateAll
|
||||
import androidx.glance.background
|
||||
import androidx.glance.layout.Alignment
|
||||
import androidx.glance.layout.Box
|
||||
import androidx.glance.layout.Column
|
||||
import androidx.glance.layout.ContentScale
|
||||
import androidx.glance.layout.Row
|
||||
import androidx.glance.layout.fillMaxSize
|
||||
import androidx.glance.layout.fillMaxWidth
|
||||
import androidx.glance.layout.padding
|
||||
import androidx.glance.layout.size
|
||||
import androidx.glance.text.Text
|
||||
import androidx.glance.text.TextAlign
|
||||
import androidx.glance.text.TextStyle
|
||||
import androidx.glance.unit.ColorProvider
|
||||
import coil.executeBlocking
|
||||
import coil.imageLoader
|
||||
import coil.request.CachePolicy
|
||||
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
|
||||
import tachiyomi.data.DatabaseHandler
|
||||
import tachiyomi.domain.manga.model.MangaCover
|
||||
import tachiyomi.view.UpdatesView
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
|
||||
class UpdatesGridGlanceWidget : GlanceAppWidget() {
|
||||
private val app: Application by injectLazy()
|
||||
private val preferences: SecurityPreferences by injectLazy()
|
||||
|
||||
private val coroutineScope = MainScope()
|
||||
|
||||
var data: List<Pair<Long, Bitmap?>>? = null
|
||||
|
||||
override val sizeMode = SizeMode.Exact
|
||||
|
||||
@Composable
|
||||
override fun Content() {
|
||||
// App lock enabled, don't do anything
|
||||
if (preferences.useAuthenticator().get()) {
|
||||
WidgetNotAvailable()
|
||||
} else {
|
||||
UpdatesWidget()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WidgetNotAvailable() {
|
||||
val intent = Intent(LocalContext.current, MainActivity::class.java).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}
|
||||
Box(
|
||||
modifier = GlanceModifier
|
||||
.clickable(actionStartActivity(intent))
|
||||
.then(ContainerModifier)
|
||||
.padding(8.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.appwidget_unavailable_locked),
|
||||
style = TextStyle(
|
||||
color = ColorProvider(R.color.appwidget_on_secondary_container),
|
||||
fontSize = 12.sp,
|
||||
textAlign = TextAlign.Center,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UpdatesWidget() {
|
||||
val (rowCount, columnCount) = LocalSize.current.calculateRowAndColumnCount()
|
||||
Column(
|
||||
modifier = ContainerModifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
val inData = data
|
||||
if (inData == null) {
|
||||
CircularProgressIndicator()
|
||||
} else if (inData.isEmpty()) {
|
||||
Text(text = stringResource(R.string.information_no_recent))
|
||||
} else {
|
||||
(0 until rowCount).forEach { i ->
|
||||
val coverRow = (0 until columnCount).mapNotNull { j ->
|
||||
inData.getOrNull(j + (i * columnCount))
|
||||
}
|
||||
if (coverRow.isNotEmpty()) {
|
||||
Row(
|
||||
modifier = GlanceModifier
|
||||
.padding(vertical = 4.dp)
|
||||
.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
coverRow.forEach { (mangaId, cover) ->
|
||||
Box(
|
||||
modifier = GlanceModifier
|
||||
.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)
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
|
||||
// https://issuetracker.google.com/issues/238793260
|
||||
addCategory(mangaId.toString())
|
||||
}
|
||||
Cover(
|
||||
modifier = GlanceModifier.clickable(actionStartActivity(intent)),
|
||||
cover = cover,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Cover(
|
||||
modifier: GlanceModifier = GlanceModifier,
|
||||
cover: Bitmap?,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(width = CoverWidth, height = CoverHeight)
|
||||
.appWidgetInnerRadius(),
|
||||
) {
|
||||
if (cover != null) {
|
||||
Image(
|
||||
provider = ImageProvider(cover),
|
||||
contentDescription = null,
|
||||
modifier = GlanceModifier
|
||||
.fillMaxSize()
|
||||
.appWidgetInnerRadius(),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
} else {
|
||||
// Enjoy placeholder
|
||||
Image(
|
||||
provider = ImageProvider(R.drawable.appwidget_cover_error),
|
||||
contentDescription = null,
|
||||
modifier = GlanceModifier.fillMaxSize(),
|
||||
contentScale = ContentScale.Crop,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadData(list: List<UpdatesView>? = null) {
|
||||
coroutineScope.launchIO {
|
||||
// Don't show anything when lock is active
|
||||
if (preferences.useAuthenticator().get()) {
|
||||
updateAll(app)
|
||||
return@launchIO
|
||||
}
|
||||
|
||||
val manager = GlanceAppWidgetManager(app)
|
||||
val ids = manager.getGlanceIds(this@UpdatesGridGlanceWidget::class.java)
|
||||
if (ids.isEmpty()) return@launchIO
|
||||
|
||||
val processList = list
|
||||
?: Injekt.get<DatabaseHandler>()
|
||||
.awaitList { updatesViewQueries.updates(after = DateLimit.timeInMillis) }
|
||||
val (rowCount, columnCount) = ids
|
||||
.flatMap { manager.getAppWidgetSizes(it) }
|
||||
.maxBy { it.height.value * it.width.value }
|
||||
.calculateRowAndColumnCount()
|
||||
|
||||
data = prepareList(processList, rowCount * columnCount)
|
||||
ids.forEach { update(app, it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun prepareList(processList: List<UpdatesView>, take: Int): List<Pair<Long, Bitmap?>> {
|
||||
// Resize to cover size
|
||||
val widthPx = CoverWidth.value.toInt().dpToPx
|
||||
val heightPx = CoverHeight.value.toInt().dpToPx
|
||||
val roundPx = app.resources.getDimension(R.dimen.appwidget_inner_radius)
|
||||
return processList
|
||||
.distinctBy { it.mangaId }
|
||||
.take(take)
|
||||
.map { updatesView ->
|
||||
val request = ImageRequest.Builder(app)
|
||||
.data(
|
||||
MangaCover(
|
||||
mangaId = updatesView.mangaId,
|
||||
sourceId = updatesView.source,
|
||||
isMangaFavorite = updatesView.favorite,
|
||||
url = updatesView.thumbnailUrl,
|
||||
lastModified = updatesView.coverLastModified,
|
||||
),
|
||||
)
|
||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||
.precision(Precision.EXACT)
|
||||
.size(widthPx, heightPx)
|
||||
.scale(Scale.FILL)
|
||||
.let {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
it.transformations(RoundedCornersTransformation(roundPx))
|
||||
} else {
|
||||
it // Handled by system
|
||||
}
|
||||
}
|
||||
.build()
|
||||
Pair(updatesView.mangaId, app.imageLoader.executeBlocking(request).drawable?.toBitmap())
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val DateLimit: Calendar
|
||||
get() = Calendar.getInstance().apply {
|
||||
time = Date()
|
||||
add(Calendar.MONTH, -3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val CoverWidth = 58.dp
|
||||
private val CoverHeight = 87.dp
|
||||
|
||||
private val ContainerModifier = GlanceModifier
|
||||
.fillMaxSize()
|
||||
.background(ImageProvider(R.drawable.appwidget_background))
|
||||
.appWidgetBackground()
|
||||
.appWidgetBackgroundRadius()
|
||||
|
||||
/**
|
||||
* Calculates row-column count.
|
||||
*
|
||||
* Row
|
||||
* Numerator: Container height - container vertical padding
|
||||
* Denominator: Cover height + cover vertical padding
|
||||
*
|
||||
* Column
|
||||
* Numerator: Container width - container horizontal padding
|
||||
* Denominator: Cover width + cover horizontal padding
|
||||
*
|
||||
* @return pair of row and column count
|
||||
*/
|
||||
private fun DpSize.calculateRowAndColumnCount(): Pair<Int, Int> {
|
||||
// Hack: Size provided by Glance manager is not reliable so take at least 1 row and 1 column
|
||||
// Set max to 10 children each direction because of Glance limitation
|
||||
val rowCount = (height.value / 95).toInt().coerceIn(1, 10)
|
||||
val columnCount = (width.value / 64).toInt().coerceIn(1, 10)
|
||||
return Pair(rowCount, columnCount)
|
||||
}
|
@ -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.
|
||||
*/
|
||||
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/appwidget_secondary_container" />
|
||||
<corners android:radius="@dimen/appwidget_background_radius" />
|
||||
</shape>
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/cover_placeholder" />
|
||||
<corners android:radius="@dimen/appwidget_inner_radius" />
|
||||
</shape>
|
||||
</item>
|
||||
<item
|
||||
android:top="24dp"
|
||||
android:bottom="24dp"
|
||||
android:left="24dp"
|
||||
android:right="24dp">
|
||||
<vector
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/cover_placeholder"
|
||||
android:pathData="M21,5v6.59l-2.29,-2.3c-0.39,-0.39 -1.03,-0.39 -1.42,0L14,12.59 10.71,9.3c-0.39,-0.39 -1.02,-0.39 -1.41,0L6,12.59 3,9.58L3,5c0,-1.1 0.9,-2 2,-2h14c1.1,0 2,0.9 2,2zM18,11.42l3,3.01L21,19c0,1.1 -0.9,2 -2,2L5,21c-1.1,0 -2,-0.9 -2,-2v-6.58l2.29,2.29c0.39,0.39 1.02,0.39 1.41,0l3.3,-3.3 3.29,3.29c0.39,0.39 1.02,0.39 1.41,0l3.3,-3.28z"/>
|
||||
</vector>
|
||||
</item>
|
||||
</layer-list>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/appwidget_background">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/loading"
|
||||
android:textColor="?android:attr/textColorPrimary" />
|
||||
|
||||
</FrameLayout>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="appwidget_background">@color/m3_sys_color_dynamic_dark_surface</color>
|
||||
<color name="appwidget_on_background">@color/m3_sys_color_dynamic_dark_on_surface</color>
|
||||
<color name="appwidget_surface_variant">@color/m3_sys_color_dynamic_dark_surface_variant</color>
|
||||
<color name="appwidget_on_surface_variant">@color/m3_sys_color_dynamic_dark_on_surface_variant</color>
|
||||
<color name="appwidget_secondary_container">@color/m3_sys_color_dynamic_dark_secondary_container</color>
|
||||
<color name="appwidget_on_secondary_container">@color/m3_sys_color_dynamic_dark_on_secondary_container</color>
|
||||
</resources>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="appwidget_background">@color/m3_sys_color_dynamic_light_surface</color>
|
||||
<color name="appwidget_on_background">@color/m3_sys_color_dynamic_light_on_surface</color>
|
||||
<color name="appwidget_surface_variant">@color/m3_sys_color_dynamic_light_surface_variant</color>
|
||||
<color name="appwidget_on_surface_variant">@color/m3_sys_color_dynamic_light_on_surface_variant</color>
|
||||
<color name="appwidget_secondary_container">@color/m3_sys_color_dynamic_light_secondary_container</color>
|
||||
<color name="appwidget_on_secondary_container">@color/m3_sys_color_dynamic_light_on_secondary_container</color>
|
||||
</resources>
|
@ -1,3 +0,0 @@
|
||||
<resources>
|
||||
<dimen name="appwidget_background_radius">@android:dimen/system_app_widget_background_radius</dimen>
|
||||
</resources>
|
@ -1,73 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<color name="splash">@color/accent_blue</color>
|
||||
|
||||
<color name="cover_placeholder">#1F888888</color>
|
||||
|
||||
<color name="error">#BA1B1B</color>
|
||||
<color name="errorContainer">#FFDAD4</color>
|
||||
<color name="onError">#FFFFFF</color>
|
||||
<color name="onErrorContainer">#410001</color>
|
||||
|
||||
<!-- Default Theme -->
|
||||
<color name="divider_default">@color/md_black_1000_12</color>
|
||||
|
||||
<!-- Blue Theme -->
|
||||
<color name="accent_blue">#54759E</color>
|
||||
|
||||
<!-- AMOLED Mode -->
|
||||
<color name="surface_amoled">#000001</color>
|
||||
<color name="background_amoled">#000000</color>
|
||||
|
||||
<color name="reader_background_dark">#202125</color>
|
||||
|
||||
<!-- Material Design Colors -->
|
||||
<color name="md_black_1000">#000000</color>
|
||||
<color name="md_black_1000_87">#DE000000</color>
|
||||
<color name="md_black_1000_54">#8A000000</color>
|
||||
<color name="md_black_1000_38">#61000000</color>
|
||||
<color name="md_black_1000_12">#1F000000</color>
|
||||
<color name="md_black_1000_8">#14000000</color>
|
||||
<color name="md_black_1000_6">#0F000000</color>
|
||||
|
||||
<color name="md_white_1000">#FFFFFFFF</color>
|
||||
<color name="md_white_1000_70">#B3FFFFFF</color>
|
||||
<color name="md_white_1000_54">#8AFFFFFF</color>
|
||||
<color name="md_white_1000_50">#80FFFFFF</color>
|
||||
<color name="md_white_1000_20">#33FFFFFF</color>
|
||||
<color name="md_white_1000_12">#1FFFFFFF</color>
|
||||
<color name="md_white_1000_8">#14FFFFFF</color>
|
||||
<color name="md_white_1000_6">#0FFFFFFF</color>
|
||||
|
||||
<color name="md_grey_50">#FAFAFA</color>
|
||||
<color name="md_grey_50_75">#BFFAFAFA</color>
|
||||
<color name="md_grey_100">#F5F5F5</color>
|
||||
<color name="md_grey_300">#E0E0E0</color>
|
||||
<color name="md_grey_800">#424242</color>
|
||||
<color name="md_grey_900">#212121</color>
|
||||
<color name="md_grey_900_75">#BF212121</color>
|
||||
|
||||
<color name="md_blue_A200">#448AFF</color>
|
||||
<color name="md_blue_A200_75">#BF448AFF</color>
|
||||
<color name="md_blue_A200_50">#80448AFF</color>
|
||||
|
||||
<color name="md_blue_A400">#2979FF</color>
|
||||
<color name="md_blue_A400_75">#BF2979FF</color>
|
||||
<color name="md_blue_A400_38">#612979FF</color>
|
||||
<color name="md_blue_A400_12">#1F2979FF</color>
|
||||
|
||||
<color name="md_blue_grey_900">#263238</color>
|
||||
<color name="md_blue_grey_800">#37474F</color>
|
||||
|
||||
<!-- Navigation Overlay Colors -->
|
||||
<color name="navigation_next">#CB84E296</color>
|
||||
<color name="navigation_prev">#CCFF7733</color>
|
||||
<color name="navigation_menu">#CC95818D</color>
|
||||
<color name="navigation_right">#CCA6CFD5</color>
|
||||
<color name="navigation_left">#CC7D1128</color>
|
||||
|
||||
<!-- ActionMode status bar color -->
|
||||
<color name="abc_decor_view_status_guard" tools:override="true">@android:color/transparent</color>
|
||||
<color name="abc_decor_view_status_guard_light" tools:override="true">@android:color/transparent</color>
|
||||
|
||||
</resources>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="appwidget_background">@color/tachiyomi_surface</color>
|
||||
<color name="appwidget_on_background">@color/tachiyomi_onSurface</color>
|
||||
<color name="appwidget_surface_variant">@color/tachiyomi_surfaceVariant</color>
|
||||
<color name="appwidget_on_surface_variant">@color/tachiyomi_onSurfaceVariant</color>
|
||||
<color name="appwidget_secondary_container">@color/tachiyomi_secondaryContainer</color>
|
||||
<color name="appwidget_on_secondary_container">@color/tachiyomi_onSecondaryContainer</color>
|
||||
</resources>
|
@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Green Apple theme
|
||||
~ Original color scheme by CarlosEsco, Jays2Kings and CrepeTF
|
||||
~ M3 colors generated by Material Theme Builder (https://goo.gle/material-theme-builder-web)
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #188140
|
||||
~ Secondary #188140
|
||||
~ Tertiary #D33131
|
||||
~ Neutral #5D5F5B
|
||||
-->
|
||||
<resources>
|
||||
<color name="greenapple_primary">#006D2F</color>
|
||||
<color name="greenapple_onPrimary">#FFFFFF</color>
|
||||
<color name="greenapple_primaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_onPrimaryContainer">#002109</color>
|
||||
<color name="greenapple_secondary">#006D2F</color>
|
||||
<color name="greenapple_onSecondary">#FFFFFF</color>
|
||||
<color name="greenapple_secondaryContainer">#96F8A9</color>
|
||||
<color name="greenapple_onSecondaryContainer">#002109</color>
|
||||
<color name="greenapple_tertiary">#B91D22</color>
|
||||
<color name="greenapple_onTertiary">#FFFFFF</color>
|
||||
<color name="greenapple_tertiaryContainer">#FFDAD5</color>
|
||||
<color name="greenapple_onTertiaryContainer">#410003</color>
|
||||
<color name="greenapple_background">#FBFDF7</color>
|
||||
<color name="greenapple_onBackground">#1A1C19</color>
|
||||
<color name="greenapple_surface">#FBFDF7</color>
|
||||
<color name="greenapple_onSurface">#1A1C19</color>
|
||||
<color name="greenapple_surfaceVariant">#DDE5DA</color>
|
||||
<color name="greenapple_onSurfaceVariant">#414941</color>
|
||||
<color name="greenapple_outline">#717970</color>
|
||||
<color name="greenapple_inverseOnSurface">#F0F2EC</color>
|
||||
<color name="greenapple_inverseSurface">#2F312E</color>
|
||||
<color name="greenapple_primaryInverse">#7ADB8F</color>
|
||||
</resources>
|
@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Midnight Dusk theme
|
||||
~ Original color scheme by CrepeTF
|
||||
~ M3 color scheme generated by Material Theme Builder (https://goo.gle/material-theme-builder-web)
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #F02475
|
||||
~ Secondary #F02475
|
||||
~ Tertiary #7A5733
|
||||
~ Neutral #16151D
|
||||
-->
|
||||
<resources>
|
||||
<color name="midnightdusk_primary">#BB0054</color>
|
||||
<color name="midnightdusk_onPrimary">#FFFFFF</color>
|
||||
<color name="midnightdusk_primaryContainer">#FFD9E1</color>
|
||||
<color name="midnightdusk_onPrimaryContainer">#3F0017</color>
|
||||
<color name="midnightdusk_secondary">#BB0054</color>
|
||||
<color name="midnightdusk_onSecondary">#FFFFFF</color>
|
||||
<color name="midnightdusk_secondaryContainer">#FFD9E1</color>
|
||||
<color name="midnightdusk_onSecondaryContainer">#3F0017</color>
|
||||
<color name="midnightdusk_tertiary">#006638</color>
|
||||
<color name="midnightdusk_onTertiary">#FFFFFF</color>
|
||||
<color name="midnightdusk_tertiaryContainer">#00894b</color>
|
||||
<color name="midnightdusk_onTertiaryContainer">#2D1600</color>
|
||||
<color name="midnightdusk_background">#FFFBFF</color>
|
||||
<color name="midnightdusk_onBackground">#1C1B1F</color>
|
||||
<color name="midnightdusk_surface">#FFFBFF</color>
|
||||
<color name="midnightdusk_onSurface">#1C1B1F</color>
|
||||
<color name="midnightdusk_surfaceVariant">#F3DDE0</color>
|
||||
<color name="midnightdusk_onSurfaceVariant">#524346</color>
|
||||
<color name="midnightdusk_outline">#847376</color>
|
||||
<color name="midnightdusk_inverseOnSurface">#F4F0F4</color>
|
||||
<color name="midnightdusk_inverseSurface">#313033</color>
|
||||
<color name="midnightdusk_primaryInverse">#FFB1C4</color>
|
||||
<color name="midnightdusk_elevationOverlay">@color/midnightdusk_primary</color>
|
||||
</resources>
|
@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Strawberry Daiquiri theme
|
||||
~ Original color scheme by Soitora
|
||||
~ M3 colors generated by Material Theme Builder (https://goo.gle/material-theme-builder-web)
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #ED4A65
|
||||
~ Secondary #ED4A65
|
||||
~ Tertiary #775930
|
||||
~ Neutral #655C5C
|
||||
-->
|
||||
<resources>
|
||||
<color name="strawberry_primary">#B61E40</color>
|
||||
<color name="strawberry_onPrimary">#FFFFFF</color>
|
||||
<color name="strawberry_primaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_onPrimaryContainer">#40000D</color>
|
||||
<color name="strawberry_secondary">#B61E40</color>
|
||||
<color name="strawberry_onSecondary">#FFFFFF</color>
|
||||
<color name="strawberry_secondaryContainer">#FFDADD</color>
|
||||
<color name="strawberry_onSecondaryContainer">#40000D</color>
|
||||
<color name="strawberry_tertiary">#775930</color>
|
||||
<color name="strawberry_onTertiary">#FFFFFF</color>
|
||||
<color name="strawberry_tertiaryContainer">#FFDDB1</color>
|
||||
<color name="strawberry_onTertiaryContainer">#2A1800</color>
|
||||
<color name="strawberry_background">#FCFCFC</color>
|
||||
<color name="strawberry_onBackground">#201A1A</color>
|
||||
<color name="strawberry_surface">#FCFCFC</color>
|
||||
<color name="strawberry_onSurface">#201A1A</color>
|
||||
<color name="strawberry_surfaceVariant">#F4DDDD</color>
|
||||
<color name="strawberry_onSurfaceVariant">#534344</color>
|
||||
<color name="strawberry_outline">#857374</color>
|
||||
<color name="strawberry_inverseOnSurface">#FBEDED</color>
|
||||
<color name="strawberry_inverseSurface">#362F2F</color>
|
||||
<color name="strawberry_primaryInverse">#FFB2B9</color>
|
||||
</resources>
|
@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Default theme
|
||||
~ M3 colors generated by Material Theme Builder (https://goo.gle/material-theme-builder-web)
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #2979FF
|
||||
~ Secondary #2979FF
|
||||
~ Tertiary #47A84A
|
||||
~ Neutral #5E5E62
|
||||
-->
|
||||
<resources>
|
||||
<color name="tachiyomi_primary">#0057CE</color>
|
||||
<color name="tachiyomi_onPrimary">#FFFFFF</color>
|
||||
<color name="tachiyomi_primaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_onPrimaryContainer">#001947</color>
|
||||
<color name="tachiyomi_secondary">#0057CE</color>
|
||||
<color name="tachiyomi_onSecondary">#FFFFFF</color>
|
||||
<color name="tachiyomi_secondaryContainer">#D8E2FF</color>
|
||||
<color name="tachiyomi_onSecondaryContainer">#001947</color>
|
||||
<color name="tachiyomi_tertiary">#006E17</color>
|
||||
<color name="tachiyomi_onTertiary">#FFFFFF</color>
|
||||
<color name="tachiyomi_tertiaryContainer">#95F990</color>
|
||||
<color name="tachiyomi_onTertiaryContainer">#002202</color>
|
||||
<color name="tachiyomi_background">#FDFBFF</color>
|
||||
<color name="tachiyomi_onBackground">#1B1B1E</color>
|
||||
<color name="tachiyomi_surface">#FDFBFF</color>
|
||||
<color name="tachiyomi_onSurface">#1B1B1E</color>
|
||||
<color name="tachiyomi_surfaceVariant">#E1E2EC</color>
|
||||
<color name="tachiyomi_onSurfaceVariant">#44464E</color>
|
||||
<color name="tachiyomi_outline">#757780</color>
|
||||
<color name="tachiyomi_inverseOnSurface">#F2F0F4</color>
|
||||
<color name="tachiyomi_inverseSurface">#303033</color>
|
||||
<color name="tachiyomi_primaryInverse">#AEC6FF</color>
|
||||
</resources>
|
@ -1,37 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Tako theme
|
||||
~ Original color scheme by ghostbear
|
||||
~ M3 colors generated by yours truly
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #66577E
|
||||
~ Secondary #66577E
|
||||
~ Tertiary #F3B375
|
||||
~ Neutral #F7F5FF
|
||||
-->
|
||||
<resources>
|
||||
<color name="tako_primary">#66577E</color>
|
||||
<color name="tako_onPrimary">#F3B375</color>
|
||||
<color name="tako_primaryContainer">#66577E</color>
|
||||
<color name="tako_onPrimaryContainer">#F3B375</color>
|
||||
<color name="tako_secondary">#66577E</color>
|
||||
<color name="tako_onSecondary">#F3B375</color>
|
||||
<color name="tako_secondaryContainer">#66577E</color>
|
||||
<color name="tako_onSecondaryContainer">#F3B375</color>
|
||||
<color name="tako_tertiary">#F3B375</color>
|
||||
<color name="tako_onTertiary">#574360</color>
|
||||
<color name="tako_tertiaryContainer">#FDD6B0</color>
|
||||
<color name="tako_onTertiaryContainer">#221437</color>
|
||||
<color name="tako_background">#F7F5FF</color>
|
||||
<color name="tako_onBackground">#1B1B22</color>
|
||||
<color name="tako_surface">#F7F5FF</color>
|
||||
<color name="tako_onSurface">#1B1B22</color>
|
||||
<color name="tako_surfaceVariant">#E8E0EB</color>
|
||||
<color name="tako_onSurfaceVariant">#49454E</color>
|
||||
<color name="tako_outline">#7A757E</color>
|
||||
<color name="tako_inverseOnSurface">#F3EFF4</color>
|
||||
<color name="tako_inverseSurface">#313033</color>
|
||||
<color name="tako_primaryInverse">#D6BAFF</color>
|
||||
<color name="tako_elevationOverlay">@color/tako_primary</color>
|
||||
</resources>
|
@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<resources>
|
||||
<color name="tealturquoise_primary">#008080</color>
|
||||
<color name="tealturquoise_onPrimary">#FFFFFF</color>
|
||||
<color name="tealturquoise_primaryContainer">#008080</color>
|
||||
<color name="tealturquoise_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="tealturquoise_secondary">#008080</color>
|
||||
<color name="tealturquoise_onSecondary">#FFFFFF</color>
|
||||
<color name="tealturquoise_secondaryContainer">#BFDFDF</color>
|
||||
<color name="tealturquoise_onSecondaryContainer">#008080</color>
|
||||
<color name="tealturquoise_tertiary">#FF7F7F</color>
|
||||
<color name="tealturquoise_onTertiary">#000000</color>
|
||||
<color name="tealturquoise_tertiaryContainer">#2A1616</color>
|
||||
<color name="tealturquoise_onTertiaryContainer">#FF7F7F</color>
|
||||
<color name="tealturquoise_background">#FAFAFA</color>
|
||||
<color name="tealturquoise_onBackground">#050505</color>
|
||||
<color name="tealturquoise_surface">#FAFAFA</color>
|
||||
<color name="tealturquoise_onSurface">#050505</color>
|
||||
<color name="tealturquoise_surfaceVariant">#DAE5E2</color>
|
||||
<color name="tealturquoise_onSurfaceVariant">#050505</color>
|
||||
<color name="tealturquoise_outline">#6F7977</color>
|
||||
<color name="tealturquoise_inverseOnSurface">#FAFAFA</color>
|
||||
<color name="tealturquoise_inverseSurface">#050505</color>
|
||||
<color name="tealturquoise_primaryInverse">#40E0D0</color>
|
||||
<color name="tealturquoise_elevationOverlay">#BFDFDF</color>
|
||||
</resources>
|
@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
~ Colors for Tidal Wave theme
|
||||
~ Original color scheme by NahutabDevelop
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #006780
|
||||
~ Secondary #004152
|
||||
~ Tertiary #92f7bc
|
||||
~ Neutral #b6b5b8
|
||||
-->
|
||||
<resources>
|
||||
<color name="tidalwave_primary">#006780</color>
|
||||
<color name="tidalwave_onPrimary">#ffffff</color>
|
||||
<color name="tidalwave_primaryContainer">#B4D4DF</color>
|
||||
<color name="tidalwave_onPrimaryContainer">#001f28</color>
|
||||
<color name="tidalwave_secondary">#006780</color>
|
||||
<color name="tidalwave_onSecondary">#ffffff</color>
|
||||
<color name="tidalwave_secondaryContainer">#b8eaff</color>
|
||||
<color name="tidalwave_onSecondaryContainer">#001f28</color>
|
||||
<color name="tidalwave_tertiary">#92f7bc</color>
|
||||
<color name="tidalwave_onTertiary">#001c3b</color>
|
||||
<color name="tidalwave_tertiaryContainer">#c3fada</color>
|
||||
<color name="tidalwave_onTertiaryContainer">#78ffd6</color>
|
||||
<color name="tidalwave_background">#fdfbff</color>
|
||||
<color name="tidalwave_onBackground">#001c3b</color>
|
||||
<color name="tidalwave_surface">#fdfbff</color>
|
||||
<color name="tidalwave_onSurface">#001c3b</color>
|
||||
<color name="tidalwave_surfaceVariant">#dce4e8</color>
|
||||
<color name="tidalwave_onSurfaceVariant">#40484c</color>
|
||||
<color name="tidalwave_outline">#70787c</color>
|
||||
<color name="tidalwave_inverseOnSurface">#ffe3c4</color>
|
||||
<color name="tidalwave_inverseSurface">#020400</color>
|
||||
<color name="tidalwave_primaryInverse">#ff987f</color>
|
||||
</resources>
|
@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Yin & Yang theme
|
||||
~ Original color scheme by Riztard
|
||||
~ M3 colors generated by yours truly + tweaked manually
|
||||
-->
|
||||
<resources>
|
||||
<color name="yinyang_primary">#000000</color>
|
||||
<color name="yinyang_onPrimary">#FFFFFF</color>
|
||||
<color name="yinyang_primaryContainer">#000000</color>
|
||||
<color name="yinyang_onPrimaryContainer">#FFFFFF</color>
|
||||
<color name="yinyang_secondary">#000000</color>
|
||||
<color name="yinyang_onSecondary">#FFFFFF</color>
|
||||
<color name="yinyang_secondaryContainer">#DDDDDD</color>
|
||||
<color name="yinyang_onSecondaryContainer">#0C0C0C</color>
|
||||
<color name="yinyang_tertiary">#FFFFFF</color>
|
||||
<color name="yinyang_onTertiary">#000000</color>
|
||||
<color name="yinyang_tertiaryContainer">#D8E2FF</color>
|
||||
<color name="yinyang_onTertiaryContainer">#001947</color>
|
||||
<color name="yinyang_background">#FDFDFD</color>
|
||||
<color name="yinyang_onBackground">#222222</color>
|
||||
<color name="yinyang_surface">#FDFDFD</color>
|
||||
<color name="yinyang_onSurface">#222222</color>
|
||||
<color name="yinyang_surfaceVariant">#EDEDED</color>
|
||||
<color name="yinyang_onSurfaceVariant">#515151</color>
|
||||
<color name="yinyang_outline">#838383</color>
|
||||
<color name="yinyang_inverseOnSurface">#F4F4F4</color>
|
||||
<color name="yinyang_inverseSurface">#333333</color>
|
||||
<color name="yinyang_primaryInverse">#A6A6A6</color>
|
||||
</resources>
|
@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Colors for Yotsuba theme
|
||||
~ Original color scheme by ztimms73
|
||||
~ M3 colors generated by Material Theme Builder (https://goo.gle/material-theme-builder-web)
|
||||
~
|
||||
~ Key colors:
|
||||
~ Primary #AE3200
|
||||
~ Secondary #AE3200
|
||||
~ Tertiary #6B5E2F
|
||||
~ Neutral #655C5A
|
||||
-->
|
||||
<resources>
|
||||
<color name="yotsuba_primary">#AE3200</color>
|
||||
<color name="yotsuba_onPrimary">#FFFFFF</color>
|
||||
<color name="yotsuba_primaryContainer">#FFDBCF</color>
|
||||
<color name="yotsuba_onPrimaryContainer">#3B0A00</color>
|
||||
<color name="yotsuba_secondary">#AE3200</color>
|
||||
<color name="yotsuba_onSecondary">#FFFFFF</color>
|
||||
<color name="yotsuba_secondaryContainer">#FFDBCF</color>
|
||||
<color name="yotsuba_onSecondaryContainer">#3B0A00</color>
|
||||
<color name="yotsuba_tertiary">#6B5E2F</color>
|
||||
<color name="yotsuba_onTertiary">#FFFFFF</color>
|
||||
<color name="yotsuba_tertiaryContainer">#F5E2A7</color>
|
||||
<color name="yotsuba_onTertiaryContainer">#231B00</color>
|
||||
<color name="yotsuba_background">#FCFCFC</color>
|
||||
<color name="yotsuba_onBackground">#211A18</color>
|
||||
<color name="yotsuba_surface">#FCFCFC</color>
|
||||
<color name="yotsuba_onSurface">#211A18</color>
|
||||
<color name="yotsuba_surfaceVariant">#F5DED8</color>
|
||||
<color name="yotsuba_onSurfaceVariant">#53433F</color>
|
||||
<color name="yotsuba_outline">#85736E</color>
|
||||
<color name="yotsuba_inverseOnSurface">#FBEEEB</color>
|
||||
<color name="yotsuba_inverseSurface">#362F2D</color>
|
||||
<color name="yotsuba_primaryInverse">#FFB59D</color>
|
||||
</resources>
|
Reference in New Issue
Block a user