Address some build warnings
Cette révision appartient à :
Parent
80d6d412f3
révision
2d7650537d
33 fichiers modifiés avec 102 ajouts et 144 suppressions
|
@ -2,7 +2,6 @@
|
|||
|-------|----------|---------|------------|---------|
|
||||
| [![CI](https://github.com/tachiyomiorg/tachiyomi/actions/workflows/build_push.yml/badge.svg)](https://github.com/tachiyomiorg/tachiyomi/actions/workflows/build_push.yml) | [![stable release](https://img.shields.io/github/release/tachiyomiorg/tachiyomi.svg?maxAge=3600&label=download)](https://github.com/tachiyomiorg/tachiyomi/releases) | [![latest preview build](https://img.shields.io/github/v/release/tachiyomiorg/tachiyomi-preview.svg?maxAge=3600&label=download)](https://github.com/tachiyomiorg/tachiyomi-preview/releases) | [![Translation status](https://hosted.weblate.org/widgets/tachiyomi/-/svg-badge.svg)](https://hosted.weblate.org/engage/tachiyomi/?utm_source=widget) | [![Discord](https://img.shields.io/discord/349436576037732353.svg?label=discord&labelColor=7289da&color=2c2f33&style=flat)](https://discord.gg/tachiyomi) |
|
||||
|
||||
|
||||
# ![app icon](./.github/readme-images/app-icon.png)Tachiyomi
|
||||
Tachiyomi is a free and open source manga reader for Android 6.0 and above.
|
||||
|
||||
|
|
2
app/proguard-rules.pro
externe
2
app/proguard-rules.pro
externe
|
@ -45,7 +45,7 @@
|
|||
|
||||
##---------------Begin: proguard configuration for kotlinx.serialization ----------
|
||||
-keepattributes *Annotation*, InnerClasses
|
||||
-dontnote kotlinx.serialization.AnnotationsKt # core serialization annotations
|
||||
-dontnote kotlinx.serialization.** # core serialization annotations
|
||||
|
||||
# kotlinx-serialization-json specific. Add this if you have java.lang.NoClassDefFoundError kotlinx.serialization.json.JsonObjectSerializer
|
||||
-keepclassmembers class kotlinx.serialization.json.** {
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
|
||||
<!-- Storage -->
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
tools:ignore="ScopedStorage" />
|
||||
|
||||
<!-- For background jobs -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
|
@ -20,10 +21,12 @@
|
|||
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION" />
|
||||
<!-- To view extension packages in API 30+ -->
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.READ_APP_SPECIFIC_LOCALES" />
|
||||
<uses-permission android:name="android.permission.READ_APP_SPECIFIC_LOCALES"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import androidx.compose.ui.focus.FocusRequester
|
|||
import androidx.compose.ui.focus.focusRequester
|
||||
import eu.kanade.core.preference.asToggleableState
|
||||
import eu.kanade.presentation.category.visualName
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.delay
|
||||
import tachiyomi.core.preference.CheckboxState
|
||||
import tachiyomi.domain.category.model.Category
|
||||
|
@ -39,7 +40,7 @@ import kotlin.time.Duration.Companion.seconds
|
|||
fun CategoryCreateDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onCreate: (String) -> Unit,
|
||||
categories: List<Category>,
|
||||
categories: ImmutableList<Category>,
|
||||
) {
|
||||
var name by remember { mutableStateOf("") }
|
||||
|
||||
|
@ -98,7 +99,7 @@ fun CategoryCreateDialog(
|
|||
fun CategoryRenameDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
onRename: (String) -> Unit,
|
||||
categories: List<Category>,
|
||||
categories: ImmutableList<Category>,
|
||||
category: Category,
|
||||
) {
|
||||
var name by remember { mutableStateOf(category.name) }
|
||||
|
|
|
@ -6,6 +6,7 @@ import androidx.compose.material.icons.outlined.Add
|
|||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.components.material.ExtendedFloatingActionButton
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
@ -16,11 +17,13 @@ import tachiyomi.presentation.core.util.isScrollingUp
|
|||
fun CategoryFloatingActionButton(
|
||||
lazyListState: LazyListState,
|
||||
onCreate: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ExtendedFloatingActionButton(
|
||||
text = { Text(text = stringResource(MR.strings.action_add)) },
|
||||
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = null) },
|
||||
onClick = onCreate,
|
||||
expanded = lazyListState.isScrollingUp() || lazyListState.isScrolledToEnd(),
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ package eu.kanade.presentation.components
|
|||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import eu.kanade.presentation.manga.DownloadAction
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import tachiyomi.i18n.MR
|
||||
import tachiyomi.presentation.core.i18n.pluralStringResource
|
||||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
|
@ -13,18 +15,22 @@ fun DownloadDropdownMenu(
|
|||
expanded: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
onDownloadClicked: (DownloadAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val options = persistentListOf(
|
||||
DownloadAction.NEXT_1_CHAPTER to pluralStringResource(MR.plurals.download_amount, 1, 1),
|
||||
DownloadAction.NEXT_5_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 5, 5),
|
||||
DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 10, 10),
|
||||
DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 25, 25),
|
||||
DownloadAction.UNREAD_CHAPTERS to stringResource(MR.strings.download_unread),
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = onDismissRequest,
|
||||
modifier = modifier,
|
||||
) {
|
||||
listOfNotNull(
|
||||
DownloadAction.NEXT_1_CHAPTER to pluralStringResource(MR.plurals.download_amount, 1, 1),
|
||||
DownloadAction.NEXT_5_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 5, 5),
|
||||
DownloadAction.NEXT_10_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 10, 10),
|
||||
DownloadAction.NEXT_25_CHAPTERS to pluralStringResource(MR.plurals.download_amount, 25, 25),
|
||||
DownloadAction.UNREAD_CHAPTERS to stringResource(MR.strings.download_unread),
|
||||
).map { (downloadAction, string) ->
|
||||
options.map { (downloadAction, string) ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = string) },
|
||||
onClick = {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package eu.kanade.presentation.components
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.sizeIn
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.outlined.ArrowRight
|
||||
import androidx.compose.material.icons.outlined.RadioButtonChecked
|
||||
|
@ -22,12 +25,17 @@ import tachiyomi.i18n.MR
|
|||
import tachiyomi.presentation.core.i18n.stringResource
|
||||
import androidx.compose.material3.DropdownMenu as ComposeDropdownMenu
|
||||
|
||||
/**
|
||||
* DropdownMenu but overlaps anchor and has width constraints to better
|
||||
* match non-Compose implementation.
|
||||
*/
|
||||
@Composable
|
||||
fun DropdownMenu(
|
||||
expanded: Boolean,
|
||||
onDismissRequest: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
offset: DpOffset = DpOffset(8.dp, (-56).dp),
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
properties: PopupProperties = PopupProperties(focusable = true),
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
|
@ -36,6 +44,7 @@ fun DropdownMenu(
|
|||
onDismissRequest = onDismissRequest,
|
||||
modifier = modifier.sizeIn(minWidth = 196.dp, maxWidth = 196.dp),
|
||||
offset = offset,
|
||||
scrollState = scrollState,
|
||||
properties = properties,
|
||||
content = content,
|
||||
)
|
||||
|
@ -45,6 +54,7 @@ fun DropdownMenu(
|
|||
fun RadioMenuItem(
|
||||
text: @Composable () -> Unit,
|
||||
isChecked: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
|
@ -64,6 +74,7 @@ fun RadioMenuItem(
|
|||
)
|
||||
}
|
||||
},
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -71,25 +82,29 @@ fun RadioMenuItem(
|
|||
fun NestedMenuItem(
|
||||
text: @Composable () -> Unit,
|
||||
children: @Composable ColumnScope.(() -> Unit) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var nestedExpanded by remember { mutableStateOf(false) }
|
||||
val closeMenu = { nestedExpanded = false }
|
||||
|
||||
DropdownMenuItem(
|
||||
text = text,
|
||||
onClick = { nestedExpanded = true },
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Outlined.ArrowRight,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
)
|
||||
Box {
|
||||
DropdownMenuItem(
|
||||
text = text,
|
||||
onClick = { nestedExpanded = true },
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Outlined.ArrowRight,
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = nestedExpanded,
|
||||
onDismissRequest = closeMenu,
|
||||
) {
|
||||
children(closeMenu)
|
||||
DropdownMenu(
|
||||
expanded = nestedExpanded,
|
||||
onDismissRequest = closeMenu,
|
||||
modifier = modifier,
|
||||
) {
|
||||
children(closeMenu)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,10 +49,10 @@ enum class ChapterDownloadAction {
|
|||
@Composable
|
||||
fun ChapterDownloadIndicator(
|
||||
enabled: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
downloadStateProvider: () -> Download.State,
|
||||
downloadProgressProvider: () -> Int,
|
||||
onClick: (ChapterDownloadAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
when (val downloadState = downloadStateProvider()) {
|
||||
Download.State.NOT_DOWNLOADED -> NotDownloadedIndicator(
|
||||
|
@ -109,10 +109,10 @@ private fun NotDownloadedIndicator(
|
|||
@Composable
|
||||
private fun DownloadingIndicator(
|
||||
enabled: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
downloadState: Download.State,
|
||||
downloadProgressProvider: () -> Int,
|
||||
onClick: (ChapterDownloadAction) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
var isMenuExpanded by remember { mutableStateOf(false) }
|
||||
Box(
|
||||
|
|
|
@ -182,7 +182,10 @@ private fun RowScope.Button(
|
|||
onClick: () -> Unit,
|
||||
content: (@Composable () -> Unit)? = null,
|
||||
) {
|
||||
val animatedWeight by animateFloatAsState(if (toConfirm) 2f else 1f)
|
||||
val animatedWeight by animateFloatAsState(
|
||||
targetValue = if (toConfirm) 2f else 1f,
|
||||
label = "weight",
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
|
|
|
@ -20,7 +20,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import eu.kanade.presentation.components.AppBar
|
||||
|
|
|
@ -11,7 +11,6 @@ import tachiyomi.presentation.core.i18n.stringResource
|
|||
/**
|
||||
* Returns a string of categories name for settings subtitle
|
||||
*/
|
||||
|
||||
@ReadOnlyComposable
|
||||
@Composable
|
||||
fun getCategoriesLabel(
|
||||
|
|
|
@ -65,7 +65,6 @@ object SettingsLibraryScreen : SearchableSettings {
|
|||
allCategories: List<Category>,
|
||||
libraryPreferences: LibraryPreferences,
|
||||
): Preference.PreferenceGroup {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val userCategoriesCount = allCategories.filterNot(Category::isSystemCategory).size
|
||||
|
||||
|
@ -76,7 +75,7 @@ object SettingsLibraryScreen : SearchableSettings {
|
|||
val ids = listOf(libraryPreferences.defaultCategory().defaultValue()) +
|
||||
allCategories.fastMap { it.id.toInt() }
|
||||
val labels = listOf(stringResource(MR.strings.default_category_summary)) +
|
||||
allCategories.fastMap { it.visualName(context) }
|
||||
allCategories.fastMap { it.visualName }
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(MR.strings.categories),
|
||||
|
|
|
@ -114,6 +114,7 @@ internal fun Modifier.highlightBackground(highlighted: Boolean): Modifier = comp
|
|||
} else {
|
||||
tween(200)
|
||||
},
|
||||
label = "highlight",
|
||||
)
|
||||
Modifier.background(color = highlight)
|
||||
}
|
||||
|
|
|
@ -20,17 +20,20 @@ class BackupDecoder(
|
|||
* Decode a potentially-gzipped backup.
|
||||
*/
|
||||
fun decode(uri: Uri): Backup {
|
||||
val backupStringSource = context.contentResolver.openInputStream(uri)!!.source().buffer()
|
||||
return context.contentResolver.openInputStream(uri)!!.use { inputStream ->
|
||||
val source = inputStream.source().buffer()
|
||||
|
||||
val peeked = backupStringSource.peek()
|
||||
peeked.require(2)
|
||||
val id1id2 = peeked.readShort()
|
||||
val backupString = if (id1id2.toInt() == 0x1f8b) { // 0x1f8b is gzip magic bytes
|
||||
backupStringSource.gzip().buffer()
|
||||
} else {
|
||||
backupStringSource
|
||||
}.use { it.readByteArray() }
|
||||
val peeked = source.peek().apply {
|
||||
require(2)
|
||||
}
|
||||
val id1id2 = peeked.readShort()
|
||||
val backupString = if (id1id2.toInt() == 0x1f8b) { // 0x1f8b is gzip magic bytes
|
||||
source.gzip().buffer()
|
||||
} else {
|
||||
source
|
||||
}.use { it.readByteArray() }
|
||||
|
||||
return parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
parser.decodeFromByteArray(BackupSerializer, backupString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ class BackupCreator(
|
|||
.forEach { it.delete() }
|
||||
|
||||
// Create new file to place backup
|
||||
dir?.createFile(BackupCreator.getFilename())
|
||||
dir?.createFile(getFilename())
|
||||
} else {
|
||||
UniFile.fromUri(context, uri)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ class DownloadProvider(
|
|||
private val storageManager: StorageManager = Injekt.get(),
|
||||
) {
|
||||
|
||||
val downloadsDir: UniFile?
|
||||
private val downloadsDir: UniFile?
|
||||
get() = storageManager.getDownloadsDirectory()
|
||||
|
||||
/**
|
||||
|
|
|
@ -246,7 +246,7 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||
|
||||
// Mark chapters as read action
|
||||
addAction(
|
||||
R.drawable.ic_glasses_24dp,
|
||||
R.drawable.ic_done_24dp,
|
||||
context.stringResource(MR.strings.action_mark_as_read),
|
||||
NotificationReceiver.markAsReadPendingBroadcast(
|
||||
context,
|
||||
|
|
|
@ -235,7 +235,6 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
private const val NAME = "NotificationReceiver"
|
||||
|
||||
private const val ACTION_SHARE_IMAGE = "$ID.$NAME.SHARE_IMAGE"
|
||||
private const val ACTION_DELETE_IMAGE = "$ID.$NAME.DELETE_IMAGE"
|
||||
|
||||
private const val ACTION_SHARE_BACKUP = "$ID.$NAME.SEND_BACKUP"
|
||||
|
||||
|
@ -256,7 +255,6 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
|
||||
private const val ACTION_DISMISS_NOTIFICATION = "$ID.$NAME.ACTION_DISMISS_NOTIFICATION"
|
||||
|
||||
private const val EXTRA_FILE_LOCATION = "$ID.$NAME.FILE_LOCATION"
|
||||
private const val EXTRA_URI = "$ID.$NAME.URI"
|
||||
private const val EXTRA_NOTIFICATION_ID = "$ID.$NAME.NOTIFICATION_ID"
|
||||
private const val EXTRA_GROUP_ID = "$ID.$NAME.EXTRA_GROUP_ID"
|
||||
|
@ -361,7 +359,7 @@ class NotificationReceiver : BroadcastReceiver() {
|
|||
it.id == notificationId
|
||||
}?.groupKey
|
||||
|
||||
if (groupId != null && groupId != 0 && groupKey != null && groupKey.isNotEmpty()) {
|
||||
if (groupId != null && groupId != 0 && !groupKey.isNullOrEmpty()) {
|
||||
val notifications = context.notificationManager.activeNotifications.filter {
|
||||
it.groupKey == groupKey
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import okhttp3.Interceptor
|
|||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class BangumiInterceptor(val bangumi: Bangumi) : Interceptor {
|
||||
class BangumiInterceptor(private val bangumi: Bangumi) : Interceptor {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
|
|
|
@ -62,12 +62,3 @@ fun Track.toBangumiStatus() = when (status) {
|
|||
Bangumi.PLAN_TO_READ -> "wish"
|
||||
else -> throw NotImplementedError("Unknown status: $status")
|
||||
}
|
||||
|
||||
fun toTrackStatus(status: String) = when (status) {
|
||||
"do" -> Bangumi.READING
|
||||
"collect" -> Bangumi.COMPLETED
|
||||
"on_hold" -> Bangumi.ON_HOLD
|
||||
"dropped" -> Bangumi.DROPPED
|
||||
"wish" -> Bangumi.PLAN_TO_READ
|
||||
else -> throw NotImplementedError("Unknown status: $status")
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import okhttp3.Interceptor
|
|||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class KitsuInterceptor(val kitsu: Kitsu) : Interceptor {
|
||||
class KitsuInterceptor(private val kitsu: Kitsu) : Interceptor {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import okhttp3.Interceptor
|
|||
import okhttp3.Response
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class ShikimoriInterceptor(val shikimori: Shikimori) : Interceptor {
|
||||
class ShikimoriInterceptor(private val shikimori: Shikimori) : Interceptor {
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
|
|
|
@ -2,9 +2,6 @@ package eu.kanade.tachiyomi.util.system
|
|||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import android.view.ViewPropertyAnimator
|
||||
import android.view.animation.Animation
|
||||
import androidx.constraintlayout.motion.widget.MotionScene.Transition
|
||||
|
||||
/**
|
||||
* Gets the duration multiplier for general animations on the device
|
||||
|
@ -12,19 +9,3 @@ import androidx.constraintlayout.motion.widget.MotionScene.Transition
|
|||
*/
|
||||
val Context.animatorDurationScale: Float
|
||||
get() = Settings.Global.getFloat(this.contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1f)
|
||||
|
||||
/** Scale the duration of this [Animation] by [Context.animatorDurationScale] */
|
||||
fun Animation.applySystemAnimatorScale(context: Context) {
|
||||
this.duration = (this.duration * context.animatorDurationScale).toLong()
|
||||
}
|
||||
|
||||
/** Scale the duration of this [Transition] by [Context.animatorDurationScale] */
|
||||
fun Transition.applySystemAnimatorScale(context: Context) {
|
||||
// End layout of cover expanding animation tends to break when the transition is less than ~25ms
|
||||
this.duration = (this.duration * context.animatorDurationScale).toInt().coerceAtLeast(25)
|
||||
}
|
||||
|
||||
/** Scale the duration of this [ViewPropertyAnimator] by [Context.animatorDurationScale] */
|
||||
fun ViewPropertyAnimator.applySystemAnimatorScale(context: Context): ViewPropertyAnimator = apply {
|
||||
this.duration = (this.duration * context.animatorDurationScale).toLong()
|
||||
}
|
||||
|
|
|
@ -17,18 +17,10 @@ private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700
|
|||
// make sure icons on the nav rail fit
|
||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600
|
||||
|
||||
fun Context.isTabletUi(): Boolean {
|
||||
return resources.configuration.isTabletUi()
|
||||
}
|
||||
|
||||
fun Configuration.isTabletUi(): Boolean {
|
||||
return smallestScreenWidthDp >= TABLET_UI_REQUIRED_SCREEN_WIDTH_DP
|
||||
}
|
||||
|
||||
fun Configuration.isAutoTabletUiAvailable(): Boolean {
|
||||
return smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
||||
}
|
||||
|
||||
// TODO: move the logic to `isTabletUi()` when main activity is rewritten in Compose
|
||||
fun Context.prepareTabletUiContext(): Context {
|
||||
val configuration = resources.configuration
|
||||
|
|
9
app/src/main/res/drawable/ic_done_24dp.xml
Fichier normal
9
app/src/main/res/drawable/ic_done_24dp.xml
Fichier normal
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFF"
|
||||
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z" />
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/recycler"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
|
@ -51,6 +51,7 @@ fun OkHttpClient.Builder.rateLimitHost(
|
|||
* @param permits [Int] Number of requests allowed within a period of units.
|
||||
* @param period [Duration] The limiting duration. Defaults to 1.seconds.
|
||||
*/
|
||||
@Suppress("UNUSED")
|
||||
fun OkHttpClient.Builder.rateLimitHost(
|
||||
httpUrl: HttpUrl,
|
||||
permits: Int,
|
||||
|
@ -71,5 +72,6 @@ fun OkHttpClient.Builder.rateLimitHost(
|
|||
* @param permits [Int] Number of requests allowed within a period of units.
|
||||
* @param period [Duration] The limiting duration. Defaults to 1.seconds.
|
||||
*/
|
||||
@Suppress("UNUSED")
|
||||
fun OkHttpClient.Builder.rateLimitHost(url: String, permits: Int, period: Duration = 1.seconds) =
|
||||
addInterceptor(RateLimitInterceptor(url.toHttpUrlOrNull()?.host, permits, period))
|
||||
|
|
|
@ -51,6 +51,7 @@ class InMemoryPreferenceStore(
|
|||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T> getObject(
|
||||
key: String,
|
||||
defaultValue: T,
|
||||
|
@ -59,7 +60,7 @@ class InMemoryPreferenceStore(
|
|||
): Preference<T> {
|
||||
val default = InMemoryPreference(key, null, defaultValue)
|
||||
val data: T? = preferences[key]?.get() as? T
|
||||
return if (data == null) default else InMemoryPreference<T>(key, data, defaultValue)
|
||||
return if (data == null) default else InMemoryPreference(key, data, defaultValue)
|
||||
}
|
||||
|
||||
override fun getAll(): Map<String, *> {
|
||||
|
|
|
@ -11,7 +11,6 @@ import androidx.compose.foundation.gestures.anchoredDraggable
|
|||
import androidx.compose.foundation.gestures.animateTo
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxWithConstraints
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
@ -78,7 +77,7 @@ fun AdaptiveSheet(
|
|||
onDismissRequest()
|
||||
}
|
||||
}
|
||||
BoxWithConstraints(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.clickable(
|
||||
enabled = true,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<resources>
|
||||
<color name="splash">@color/accent_blue</color>
|
||||
|
||||
<color name="cover_placeholder">#1F888888</color>
|
||||
|
@ -20,21 +20,7 @@
|
|||
<color name="background_amoled">#000000</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>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package tachiyomi.presentation.widget
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.glance.ImageProvider
|
||||
import androidx.glance.unit.ColorProvider
|
||||
|
||||
class UpdatesGridGlanceWidget : BaseUpdatesGridGlanceWidget() {
|
||||
@SuppressLint("RestrictedApi")
|
||||
override val foreground = ColorProvider(R.color.appwidget_on_secondary_container)
|
||||
override val background = ImageProvider(R.drawable.appwidget_background)
|
||||
override val topPadding = 0.dp
|
||||
|
|
|
@ -29,36 +29,6 @@ interface SManga : Serializable {
|
|||
return genre?.split(", ")?.map { it.trim() }?.filterNot { it.isBlank() }?.distinct()
|
||||
}
|
||||
|
||||
fun copyFrom(other: SManga) {
|
||||
if (other.author != null) {
|
||||
author = other.author
|
||||
}
|
||||
|
||||
if (other.artist != null) {
|
||||
artist = other.artist
|
||||
}
|
||||
|
||||
if (other.description != null) {
|
||||
description = other.description
|
||||
}
|
||||
|
||||
if (other.genre != null) {
|
||||
genre = other.genre
|
||||
}
|
||||
|
||||
if (other.thumbnail_url != null) {
|
||||
thumbnail_url = other.thumbnail_url
|
||||
}
|
||||
|
||||
status = other.status
|
||||
|
||||
update_strategy = other.update_strategy
|
||||
|
||||
if (!initialized) {
|
||||
initialized = other.initialized
|
||||
}
|
||||
}
|
||||
|
||||
fun copy() = create().also {
|
||||
it.url = url
|
||||
it.title = title
|
||||
|
|
|
@ -6,6 +6,7 @@ package eu.kanade.tachiyomi.source.model
|
|||
*
|
||||
* @since extensions-lib 1.4
|
||||
*/
|
||||
@Suppress("UNUSED")
|
||||
enum class UpdateStrategy {
|
||||
/**
|
||||
* Series marked as always update will be included in the library
|
||||
|
|
Référencer dans un nouveau ticket