Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd120c5081 | |||
| 34e9d9f146 | |||
| b7f7187293 | |||
| 4abadea4f9 | |||
| 1b3d76398b | |||
| 688fdecaf8 | |||
| 0bedee1778 | |||
| bb89f9f636 | |||
| f8011981eb | |||
| 7e17e52e07 | |||
| b65990ad29 | |||
| d9560d40de | |||
| 036ab3351d | |||
| 769293355f | |||
| 850d81600e | |||
| ce96b53f10 | |||
| b98dfd65b5 | |||
| 612e0a00bc | |||
| d286cf3267 | |||
| 1a28c7fb35 | |||
| 5909f90003 | |||
| 48f7b701dc | |||
| b17530ccc3 | |||
| f844a48b67 | |||
| 66929e097c | |||
| be30814d35 | |||
| 5d56c1961d | |||
| 4aa52a2576 | |||
| f7a1869066 | |||
| 2f1d76cbac | |||
| 5c5e08b99b | |||
| cc16d53ecc | |||
| 28fa3855c2 | |||
| 5a47a58e1e | |||
| c86714ef59 | |||
| 75fe57b851 | |||
| b9fffc45cc | |||
| de6cd169d0 | |||
| 95e8a02e33 | |||
| c720f0ac5c | |||
| 76af3b59f0 | |||
| 3f8cce8a32 | |||
| 26cfb4811f | |||
| e5a6d1b456 | |||
| f0b621dfe5 |
@@ -31,7 +31,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "eu.kanade.tachiyomi.sy"
|
applicationId = "eu.kanade.tachiyomi.sy"
|
||||||
|
|
||||||
versionCode = 70
|
versionCode = 71
|
||||||
versionName = "1.11.0"
|
versionName = "1.11.0"
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.core.util
|
package eu.kanade.core.util
|
||||||
|
|
||||||
|
import androidx.compose.ui.util.fastFilter
|
||||||
import androidx.compose.ui.util.fastForEach
|
import androidx.compose.ui.util.fastForEach
|
||||||
import kotlin.contracts.ExperimentalContracts
|
import kotlin.contracts.ExperimentalContracts
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
@@ -45,21 +46,6 @@ fun <E> HashSet<E>.addOrRemove(value: E, shouldAdd: Boolean) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list containing only elements matching the given [predicate].
|
|
||||||
*
|
|
||||||
* **Do not use for collections that come from public APIs**, since they may not support random
|
|
||||||
* access in an efficient way, and this method may actually be a lot slower. Only use for
|
|
||||||
* collections that are created by code we control and are known to support random access.
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
inline fun <T> List<T>.fastFilter(predicate: (T) -> Boolean): List<T> {
|
|
||||||
contract { callsInPlace(predicate) }
|
|
||||||
val destination = ArrayList<T>()
|
|
||||||
fastForEach { if (predicate(it)) destination.add(it) }
|
|
||||||
return destination
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list containing all elements not matching the given [predicate].
|
* Returns a list containing all elements not matching the given [predicate].
|
||||||
*
|
*
|
||||||
@@ -70,27 +56,7 @@ inline fun <T> List<T>.fastFilter(predicate: (T) -> Boolean): List<T> {
|
|||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
inline fun <T> List<T>.fastFilterNot(predicate: (T) -> Boolean): List<T> {
|
inline fun <T> List<T>.fastFilterNot(predicate: (T) -> Boolean): List<T> {
|
||||||
contract { callsInPlace(predicate) }
|
contract { callsInPlace(predicate) }
|
||||||
val destination = ArrayList<T>()
|
return fastFilter { !predicate(it) }
|
||||||
fastForEach { if (!predicate(it)) destination.add(it) }
|
|
||||||
return destination
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list containing only the non-null results of applying the
|
|
||||||
* given [transform] function to each element in the original collection.
|
|
||||||
*
|
|
||||||
* **Do not use for collections that come from public APIs**, since they may not support random
|
|
||||||
* access in an efficient way, and this method may actually be a lot slower. Only use for
|
|
||||||
* collections that are created by code we control and are known to support random access.
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
inline fun <T, R> List<T>.fastMapNotNull(transform: (T) -> R?): List<R> {
|
|
||||||
contract { callsInPlace(transform) }
|
|
||||||
val destination = ArrayList<R>()
|
|
||||||
fastForEach { element ->
|
|
||||||
transform(element)?.let(destination::add)
|
|
||||||
}
|
|
||||||
return destination
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -131,26 +97,3 @@ inline fun <T> List<T>.fastCountNot(predicate: (T) -> Boolean): Int {
|
|||||||
fastForEach { if (predicate(it)) --count }
|
fastForEach { if (predicate(it)) --count }
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list containing only elements from the given collection
|
|
||||||
* having distinct keys returned by the given [selector] function.
|
|
||||||
*
|
|
||||||
* Among elements of the given collection with equal keys, only the first one will be present in the resulting list.
|
|
||||||
* The elements in the resulting list are in the same order as they were in the source collection.
|
|
||||||
*
|
|
||||||
* **Do not use for collections that come from public APIs**, since they may not support random
|
|
||||||
* access in an efficient way, and this method may actually be a lot slower. Only use for
|
|
||||||
* collections that are created by code we control and are known to support random access.
|
|
||||||
*/
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
inline fun <T, K> List<T>.fastDistinctBy(selector: (T) -> K): List<T> {
|
|
||||||
contract { callsInPlace(selector) }
|
|
||||||
val set = HashSet<K>()
|
|
||||||
val list = ArrayList<T>()
|
|
||||||
fastForEach {
|
|
||||||
val key = selector(it)
|
|
||||||
if (set.add(key)) list.add(it)
|
|
||||||
}
|
|
||||||
return list
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package eu.kanade.domain.base
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
|
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||||
import tachiyomi.core.common.preference.Preference
|
import tachiyomi.core.common.preference.Preference
|
||||||
import tachiyomi.core.common.preference.PreferenceStore
|
import tachiyomi.core.common.preference.PreferenceStore
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
@@ -31,5 +32,5 @@ class BasePreferences(
|
|||||||
|
|
||||||
fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "")
|
fun displayProfile() = preferenceStore.getString("pref_display_profile_key", "")
|
||||||
|
|
||||||
fun alwaysUseSSIVToDecode() = preferenceStore.getBoolean("pref_always_use_ssiv_to_decode", false)
|
fun hardwareBitmapThreshold() = preferenceStore.getInt("pref_hardware_bitmap_threshold", GLUtil.SAFE_TEXTURE_LIMIT)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,7 @@ internal fun LibraryTabs(
|
|||||||
getNumberOfMangaForCategory: (Category) -> Int?,
|
getNumberOfMangaForCategory: (Category) -> Int?,
|
||||||
onTabItemClick: (Int) -> Unit,
|
onTabItemClick: (Int) -> Unit,
|
||||||
) {
|
) {
|
||||||
// SY -->
|
|
||||||
val currentPageIndex = pagerState.currentPage.coerceAtMost(categories.lastIndex)
|
val currentPageIndex = pagerState.currentPage.coerceAtMost(categories.lastIndex)
|
||||||
// SY <--
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.zIndex(1f),
|
modifier = Modifier.zIndex(1f),
|
||||||
) {
|
) {
|
||||||
|
|||||||
+119
-25
@@ -15,7 +15,6 @@ import androidx.compose.ui.window.DialogProperties
|
|||||||
import exh.favorites.FavoritesSyncStatus
|
import exh.favorites.FavoritesSyncStatus
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.domain.manga.model.Manga
|
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
@@ -23,7 +22,6 @@ import kotlin.time.Duration.Companion.seconds
|
|||||||
data class SyncFavoritesProgressProperties(
|
data class SyncFavoritesProgressProperties(
|
||||||
val title: String,
|
val title: String,
|
||||||
val text: String,
|
val text: String,
|
||||||
val canDismiss: Boolean,
|
|
||||||
val positiveButtonText: String? = null,
|
val positiveButtonText: String? = null,
|
||||||
val positiveButton: (() -> Unit)? = null,
|
val positiveButton: (() -> Unit)? = null,
|
||||||
val negativeButtonText: String? = null,
|
val negativeButtonText: String? = null,
|
||||||
@@ -34,18 +32,23 @@ data class SyncFavoritesProgressProperties(
|
|||||||
fun SyncFavoritesProgressDialog(
|
fun SyncFavoritesProgressDialog(
|
||||||
status: FavoritesSyncStatus,
|
status: FavoritesSyncStatus,
|
||||||
setStatusIdle: () -> Unit,
|
setStatusIdle: () -> Unit,
|
||||||
openManga: (Manga) -> Unit,
|
openManga: (Long) -> Unit,
|
||||||
) {
|
) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val properties by produceState<SyncFavoritesProgressProperties?>(initialValue = null, status) {
|
val properties by produceState<SyncFavoritesProgressProperties?>(initialValue = null, status) {
|
||||||
when (status) {
|
when (status) {
|
||||||
is FavoritesSyncStatus.BadLibraryState.MangaInMultipleCategories -> value = SyncFavoritesProgressProperties(
|
is FavoritesSyncStatus.BadLibraryState.MangaInMultipleCategories -> value = SyncFavoritesProgressProperties(
|
||||||
title = context.stringResource(SYMR.strings.favorites_sync_error),
|
title = context.stringResource(SYMR.strings.favorites_sync_error),
|
||||||
text = context.stringResource(SYMR.strings.favorites_sync_bad_library_state, status.message),
|
text = context.stringResource(
|
||||||
canDismiss = false,
|
SYMR.strings.favorites_sync_bad_library_state,
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_gallery_in_multiple_categories, status.mangaTitle,
|
||||||
|
status.categories.joinToString(),
|
||||||
|
),
|
||||||
|
),
|
||||||
positiveButtonText = context.stringResource(SYMR.strings.show_gallery),
|
positiveButtonText = context.stringResource(SYMR.strings.show_gallery),
|
||||||
positiveButton = {
|
positiveButton = {
|
||||||
openManga(status.manga)
|
openManga(status.mangaId)
|
||||||
setStatusIdle()
|
setStatusIdle()
|
||||||
},
|
},
|
||||||
negativeButtonText = context.stringResource(MR.strings.action_ok),
|
negativeButtonText = context.stringResource(MR.strings.action_ok),
|
||||||
@@ -53,31 +56,122 @@ fun SyncFavoritesProgressDialog(
|
|||||||
)
|
)
|
||||||
is FavoritesSyncStatus.CompleteWithErrors -> value = SyncFavoritesProgressProperties(
|
is FavoritesSyncStatus.CompleteWithErrors -> value = SyncFavoritesProgressProperties(
|
||||||
title = context.stringResource(SYMR.strings.favorites_sync_done_errors),
|
title = context.stringResource(SYMR.strings.favorites_sync_done_errors),
|
||||||
text = context.stringResource(SYMR.strings.favorites_sync_done_errors_message, status.message),
|
text = context.stringResource(
|
||||||
canDismiss = false,
|
SYMR.strings.favorites_sync_done_errors_message,
|
||||||
positiveButtonText = context.stringResource(MR.strings.action_ok),
|
status.messages.joinToString(separator = "\n") {
|
||||||
positiveButton = setStatusIdle,
|
when (it) {
|
||||||
)
|
is FavoritesSyncStatus.SyncError.GallerySyncError.GalleryAddFail ->
|
||||||
is FavoritesSyncStatus.Error -> value = SyncFavoritesProgressProperties(
|
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
|
||||||
title = context.stringResource(SYMR.strings.favorites_sync_error),
|
context.stringResource(
|
||||||
text = context.stringResource(SYMR.strings.favorites_sync_error_string, status.message),
|
SYMR.strings.favorites_sync_failed_to_add_to_local_error, it.title, it.reason,
|
||||||
canDismiss = false,
|
)
|
||||||
|
is FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, it.url,
|
||||||
|
)
|
||||||
|
is FavoritesSyncStatus.SyncError.GallerySyncError.UnableToAddGalleryToRemote ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_unable_to_add_to_remote, it.title, it.gid)
|
||||||
|
FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_unable_to_delete)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
positiveButtonText = context.stringResource(MR.strings.action_ok),
|
positiveButtonText = context.stringResource(MR.strings.action_ok),
|
||||||
positiveButton = setStatusIdle,
|
positiveButton = setStatusIdle,
|
||||||
)
|
)
|
||||||
is FavoritesSyncStatus.Idle -> value = null
|
is FavoritesSyncStatus.Idle -> value = null
|
||||||
is FavoritesSyncStatus.Initializing, is FavoritesSyncStatus.Processing -> {
|
is FavoritesSyncStatus.Initializing -> {
|
||||||
value = SyncFavoritesProgressProperties(
|
value = SyncFavoritesProgressProperties(
|
||||||
title = context.stringResource(SYMR.strings.favorites_syncing),
|
title = context.stringResource(SYMR.strings.favorites_syncing),
|
||||||
text = status.message,
|
text = context.stringResource(SYMR.strings.favorites_sync_initializing),
|
||||||
canDismiss = false,
|
|
||||||
)
|
)
|
||||||
if (status is FavoritesSyncStatus.Processing && status.title != null) {
|
}
|
||||||
|
|
||||||
|
is FavoritesSyncStatus.SyncError -> value = SyncFavoritesProgressProperties(
|
||||||
|
title = context.stringResource(SYMR.strings.favorites_sync_error),
|
||||||
|
text = context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_error_string,
|
||||||
|
when (status) {
|
||||||
|
FavoritesSyncStatus.SyncError.NotLoggedInSyncError -> context.stringResource(SYMR.strings.please_login)
|
||||||
|
FavoritesSyncStatus.SyncError.FailedToFetchFavorites ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_failed_to_featch)
|
||||||
|
is FavoritesSyncStatus.SyncError.UnknownSyncError ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_unknown_error, status.message)
|
||||||
|
is FavoritesSyncStatus.SyncError.GallerySyncError.GalleryAddFail ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_failed_to_add_to_local_error, status.title, status.reason,
|
||||||
|
)
|
||||||
|
is FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, status.title, status.url,
|
||||||
|
)
|
||||||
|
is FavoritesSyncStatus.SyncError.GallerySyncError.UnableToAddGalleryToRemote ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_unable_to_add_to_remote, status.title, status.gid)
|
||||||
|
FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_unable_to_delete)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
positiveButtonText = context.stringResource(MR.strings.action_ok),
|
||||||
|
positiveButton = setStatusIdle,
|
||||||
|
)
|
||||||
|
is FavoritesSyncStatus.Processing -> {
|
||||||
|
val properties = SyncFavoritesProgressProperties(
|
||||||
|
title = context.stringResource(SYMR.strings.favorites_syncing),
|
||||||
|
text = when (status) {
|
||||||
|
FavoritesSyncStatus.Processing.VerifyingLibrary ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_verifying_library)
|
||||||
|
FavoritesSyncStatus.Processing.DownloadingFavorites ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_downloading)
|
||||||
|
FavoritesSyncStatus.Processing.CalculatingRemoteChanges ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_calculating_remote_changes)
|
||||||
|
FavoritesSyncStatus.Processing.CalculatingLocalChanges ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_calculating_local_changes)
|
||||||
|
FavoritesSyncStatus.Processing.SyncingCategoryNames ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_syncing_category_names)
|
||||||
|
is FavoritesSyncStatus.Processing.RemovingRemoteGalleries ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_removing_galleries, status.galleryCount)
|
||||||
|
is FavoritesSyncStatus.Processing.AddingGalleryToRemote ->
|
||||||
|
if (status.isThrottling) {
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_processing_throttle,
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, status.index, status.total),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, status.index, status.total)
|
||||||
|
}
|
||||||
|
is FavoritesSyncStatus.Processing.RemovingGalleryFromLocal ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_remove_from_local, status.index, status.total)
|
||||||
|
is FavoritesSyncStatus.Processing.AddingGalleryToLocal ->
|
||||||
|
if (status.isThrottling) {
|
||||||
|
context.stringResource(
|
||||||
|
SYMR.strings.favorites_sync_processing_throttle,
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_add_to_local, status.index, status.total),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_add_to_local, status.index, status.total)
|
||||||
|
}
|
||||||
|
|
||||||
|
FavoritesSyncStatus.Processing.CleaningUp ->
|
||||||
|
context.stringResource(SYMR.strings.favorites_sync_cleaning_up)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
value = properties
|
||||||
|
if (
|
||||||
|
status is FavoritesSyncStatus.Processing.AddingGalleryToRemote ||
|
||||||
|
status is FavoritesSyncStatus.Processing.AddingGalleryToLocal
|
||||||
|
) {
|
||||||
delay(5.seconds)
|
delay(5.seconds)
|
||||||
value = SyncFavoritesProgressProperties(
|
value = properties.copy(
|
||||||
title = context.stringResource(SYMR.strings.favorites_syncing),
|
text = when (status) {
|
||||||
text = status.delayedMessage ?: status.message,
|
is FavoritesSyncStatus.Processing.AddingGalleryToRemote ->
|
||||||
canDismiss = false,
|
properties.text + "\n\n" + status.title
|
||||||
|
is FavoritesSyncStatus.Processing.AddingGalleryToLocal ->
|
||||||
|
properties.text + "\n\n" + status.title
|
||||||
|
else -> properties.text
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,8 +206,8 @@ fun SyncFavoritesProgressDialog(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
properties = DialogProperties(
|
properties = DialogProperties(
|
||||||
dismissOnClickOutside = dialog.canDismiss,
|
dismissOnClickOutside = false,
|
||||||
dismissOnBackPress = dialog.canDismiss,
|
dismissOnBackPress = false,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,12 +165,12 @@ sealed class Preference {
|
|||||||
|
|
||||||
data class CustomPreference(
|
data class CustomPreference(
|
||||||
override val title: String,
|
override val title: String,
|
||||||
val content: @Composable (PreferenceItem<String>) -> Unit,
|
val content: @Composable () -> Unit,
|
||||||
) : PreferenceItem<String>() {
|
) : PreferenceItem<Unit>() {
|
||||||
override val enabled: Boolean = true
|
override val enabled: Boolean = true
|
||||||
override val subtitle: String? = null
|
override val subtitle: String? = null
|
||||||
override val icon: ImageVector? = null
|
override val icon: ImageVector? = null
|
||||||
override val onValueChanged: suspend (newValue: String) -> Boolean = { true }
|
override val onValueChanged: suspend (newValue: Unit) -> Boolean = { true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ internal fun PreferenceItem(
|
|||||||
InfoWidget(text = item.title)
|
InfoWidget(text = item.title)
|
||||||
}
|
}
|
||||||
is Preference.PreferenceItem.CustomPreference -> {
|
is Preference.PreferenceItem.CustomPreference -> {
|
||||||
item.content(item)
|
item.content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-4
@@ -59,6 +59,7 @@ import eu.kanade.tachiyomi.source.AndroidSourceManager
|
|||||||
import eu.kanade.tachiyomi.ui.more.OnboardingScreen
|
import eu.kanade.tachiyomi.ui.more.OnboardingScreen
|
||||||
import eu.kanade.tachiyomi.util.CrashLogUtil
|
import eu.kanade.tachiyomi.util.CrashLogUtil
|
||||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||||
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
import eu.kanade.tachiyomi.util.system.isDevFlavor
|
||||||
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
import eu.kanade.tachiyomi.util.system.isPreviewBuildType
|
||||||
import eu.kanade.tachiyomi.util.system.isShizukuInstalled
|
import eu.kanade.tachiyomi.util.system.isShizukuInstalled
|
||||||
@@ -83,6 +84,7 @@ import tachiyomi.core.common.i18n.pluralStringResource
|
|||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.core.common.util.lang.launchNonCancellable
|
import tachiyomi.core.common.util.lang.launchNonCancellable
|
||||||
import tachiyomi.core.common.util.lang.withUIContext
|
import tachiyomi.core.common.util.lang.withUIContext
|
||||||
|
import tachiyomi.core.common.util.system.ImageUtil
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||||
@@ -369,6 +371,26 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
return Preference.PreferenceGroup(
|
return Preference.PreferenceGroup(
|
||||||
title = stringResource(MR.strings.pref_category_reader),
|
title = stringResource(MR.strings.pref_category_reader),
|
||||||
preferenceItems = persistentListOf(
|
preferenceItems = persistentListOf(
|
||||||
|
Preference.PreferenceItem.ListPreference(
|
||||||
|
pref = basePreferences.hardwareBitmapThreshold(),
|
||||||
|
title = stringResource(MR.strings.pref_hardware_bitmap_threshold),
|
||||||
|
subtitleProvider = { value, options ->
|
||||||
|
stringResource(MR.strings.pref_hardware_bitmap_threshold_summary, options[value].orEmpty())
|
||||||
|
},
|
||||||
|
enabled = !ImageUtil.HARDWARE_BITMAP_UNSUPPORTED &&
|
||||||
|
GLUtil.DEVICE_TEXTURE_LIMIT > GLUtil.SAFE_TEXTURE_LIMIT,
|
||||||
|
entries = GLUtil.CUSTOM_TEXTURE_LIMIT_OPTIONS
|
||||||
|
.mapIndexed { index, option ->
|
||||||
|
val display = if (index == 0) {
|
||||||
|
stringResource(MR.strings.pref_hardware_bitmap_threshold_default, option)
|
||||||
|
} else {
|
||||||
|
option.toString()
|
||||||
|
}
|
||||||
|
option to display
|
||||||
|
}
|
||||||
|
.toMap()
|
||||||
|
.toImmutableMap(),
|
||||||
|
),
|
||||||
Preference.PreferenceItem.TextPreference(
|
Preference.PreferenceItem.TextPreference(
|
||||||
title = stringResource(MR.strings.pref_display_profile),
|
title = stringResource(MR.strings.pref_display_profile),
|
||||||
subtitle = basePreferences.displayProfile().get(),
|
subtitle = basePreferences.displayProfile().get(),
|
||||||
@@ -376,10 +398,6 @@ object SettingsAdvancedScreen : SearchableSettings {
|
|||||||
chooseColorProfile.launch(arrayOf("*/*"))
|
chooseColorProfile.launch(arrayOf("*/*"))
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
Preference.PreferenceItem.SwitchPreference(
|
|
||||||
pref = basePreferences.alwaysUseSSIVToDecode(),
|
|
||||||
title = stringResource(MR.strings.pref_always_use_ssiv_to_decode),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ object SettingsMangadexScreen : SearchableSettings {
|
|||||||
title = mdex.name + " Login",
|
title = mdex.name + " Login",
|
||||||
content = {
|
content = {
|
||||||
BasePreferenceWidget(
|
BasePreferenceWidget(
|
||||||
title = it.title,
|
title = mdex.name + " Login",
|
||||||
widget = {
|
widget = {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.PeopleAlt,
|
imageVector = Icons.Outlined.PeopleAlt,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import eu.kanade.tachiyomi.network.NetworkHelper
|
|||||||
import eu.kanade.tachiyomi.network.NetworkPreferences
|
import eu.kanade.tachiyomi.network.NetworkPreferences
|
||||||
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
|
import eu.kanade.tachiyomi.ui.base.delegate.SecureActivityDelegate
|
||||||
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
import eu.kanade.tachiyomi.util.system.DeviceUtil
|
||||||
|
import eu.kanade.tachiyomi.util.system.GLUtil
|
||||||
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
import eu.kanade.tachiyomi.util.system.WebViewUtil
|
||||||
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
||||||
import eu.kanade.tachiyomi.util.system.cancelNotification
|
import eu.kanade.tachiyomi.util.system.cancelNotification
|
||||||
@@ -80,6 +81,7 @@ import org.conscrypt.Conscrypt
|
|||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.core.common.preference.Preference
|
import tachiyomi.core.common.preference.Preference
|
||||||
import tachiyomi.core.common.preference.PreferenceStore
|
import tachiyomi.core.common.preference.PreferenceStore
|
||||||
|
import tachiyomi.core.common.util.system.ImageUtil
|
||||||
import tachiyomi.core.common.util.system.logcat
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.domain.storage.service.StorageManager
|
import tachiyomi.domain.storage.service.StorageManager
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
@@ -175,6 +177,14 @@ class App : Application(), DefaultLifecycleObserver, SingletonImageLoader.Factor
|
|||||||
.onEach(FirebaseConfig::setCrashlyticsEnabled)
|
.onEach(FirebaseConfig::setCrashlyticsEnabled)
|
||||||
.launchIn(scope)
|
.launchIn(scope)
|
||||||
|
|
||||||
|
basePreferences.hardwareBitmapThreshold().let { preference ->
|
||||||
|
if (!preference.isSet()) preference.set(GLUtil.DEVICE_TEXTURE_LIMIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
basePreferences.hardwareBitmapThreshold().changes()
|
||||||
|
.onEach { ImageUtil.hardwareBitmapThreshold = it }
|
||||||
|
.launchIn(scope)
|
||||||
|
|
||||||
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
|
setAppCompatDelegateThemeMode(Injekt.get<UiPreferences>().themeMode().get())
|
||||||
|
|
||||||
// Updates widget update
|
// Updates widget update
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import coil3.request.bitmapConfig
|
|||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
import eu.kanade.tachiyomi.util.storage.CbzCrypto
|
||||||
import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStream
|
import eu.kanade.tachiyomi.util.storage.CbzCrypto.getCoverStream
|
||||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
|
||||||
import mihon.core.common.archive.archiveReader
|
import mihon.core.common.archive.archiveReader
|
||||||
import okio.BufferedSource
|
import okio.BufferedSource
|
||||||
import tachiyomi.core.common.util.system.ImageUtil
|
import tachiyomi.core.common.util.system.ImageUtil
|
||||||
@@ -71,7 +70,7 @@ class TachiyomiImageDecoder(private val resources: ImageSource, private val opti
|
|||||||
if (
|
if (
|
||||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
||||||
options.bitmapConfig == Bitmap.Config.HARDWARE &&
|
options.bitmapConfig == Bitmap.Config.HARDWARE &&
|
||||||
maxOf(bitmap.width, bitmap.height) <= GLUtil.maxTextureSize
|
ImageUtil.canUseHardwareBitmap(bitmap)
|
||||||
) {
|
) {
|
||||||
val hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false)
|
val hwBitmap = bitmap.copy(Bitmap.Config.HARDWARE, false)
|
||||||
if (hwBitmap != null) {
|
if (hwBitmap != null) {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package eu.kanade.tachiyomi.data.library
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ServiceInfo
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.NetworkRequest
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.work.BackoffPolicy
|
import androidx.work.BackoffPolicy
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
@@ -135,10 +137,12 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
if (tags.contains(WORK_NAME_AUTO)) {
|
if (tags.contains(WORK_NAME_AUTO)) {
|
||||||
val preferences = Injekt.get<LibraryPreferences>()
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||||
val restrictions = preferences.autoUpdateDeviceRestrictions().get()
|
val preferences = Injekt.get<LibraryPreferences>()
|
||||||
if ((DEVICE_ONLY_ON_WIFI in restrictions) && !context.isConnectedToWifi()) {
|
val restrictions = preferences.autoUpdateDeviceRestrictions().get()
|
||||||
return Result.retry()
|
if ((DEVICE_ONLY_ON_WIFI in restrictions) && !context.isConnectedToWifi()) {
|
||||||
|
return Result.retry()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a running manual worker. If exists, try again later
|
// Find a running manual worker. If exists, try again later
|
||||||
@@ -768,15 +772,24 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
|||||||
val interval = prefInterval ?: preferences.autoUpdateInterval().get()
|
val interval = prefInterval ?: preferences.autoUpdateInterval().get()
|
||||||
if (interval > 0) {
|
if (interval > 0) {
|
||||||
val restrictions = preferences.autoUpdateDeviceRestrictions().get()
|
val restrictions = preferences.autoUpdateDeviceRestrictions().get()
|
||||||
val constraints = Constraints(
|
val networkType = if (DEVICE_NETWORK_NOT_METERED in restrictions) {
|
||||||
requiredNetworkType = if (DEVICE_NETWORK_NOT_METERED in restrictions) {
|
NetworkType.UNMETERED
|
||||||
NetworkType.UNMETERED
|
} else {
|
||||||
} else {
|
NetworkType.CONNECTED
|
||||||
NetworkType.CONNECTED
|
}
|
||||||
},
|
val networkRequestBuilder = NetworkRequest.Builder()
|
||||||
requiresCharging = DEVICE_CHARGING in restrictions,
|
if (DEVICE_ONLY_ON_WIFI in restrictions) {
|
||||||
requiresBatteryNotLow = true,
|
networkRequestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
)
|
}
|
||||||
|
if (DEVICE_NETWORK_NOT_METERED in restrictions) {
|
||||||
|
networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
|
||||||
|
}
|
||||||
|
val constraints = Constraints.Builder()
|
||||||
|
// 'networkRequest' only applies to Android 9+, otherwise 'networkType' is used
|
||||||
|
.setRequiredNetworkRequest(networkRequestBuilder.build(), networkType)
|
||||||
|
.setRequiresCharging(DEVICE_CHARGING in restrictions)
|
||||||
|
.setRequiresBatteryNotLow(true)
|
||||||
|
.build()
|
||||||
|
|
||||||
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
|
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
|
||||||
interval.toLong(),
|
interval.toLong(),
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ object Notifications {
|
|||||||
const val ID_LIBRARY_SIZE_WARNING = -103
|
const val ID_LIBRARY_SIZE_WARNING = -103
|
||||||
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
||||||
const val ID_LIBRARY_ERROR = -102
|
const val ID_LIBRARY_ERROR = -102
|
||||||
|
const val CHANNEL_LIBRARY_EHENTAI = "library_ehentai_channel"
|
||||||
|
const val ID_EHENTAI_PROGRESS = -199
|
||||||
|
const val ID_EHENTAI_ERROR = -198
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the downloader.
|
* Notification channel and ids used by the downloader.
|
||||||
@@ -71,6 +74,7 @@ object Notifications {
|
|||||||
const val CHANNEL_APP_UPDATE = "app_apk_update_channel"
|
const val CHANNEL_APP_UPDATE = "app_apk_update_channel"
|
||||||
const val ID_APP_UPDATER = 1
|
const val ID_APP_UPDATER = 1
|
||||||
const val ID_APP_UPDATE_PROMPT = 2
|
const val ID_APP_UPDATE_PROMPT = 2
|
||||||
|
const val ID_APP_UPDATE_ERROR = 3
|
||||||
const val CHANNEL_EXTENSIONS_UPDATE = "ext_apk_update_channel"
|
const val CHANNEL_EXTENSIONS_UPDATE = "ext_apk_update_channel"
|
||||||
const val ID_UPDATES_TO_EXTS = -401
|
const val ID_UPDATES_TO_EXTS = -401
|
||||||
const val ID_EXTENSION_INSTALLER = -402
|
const val ID_EXTENSION_INSTALLER = -402
|
||||||
@@ -166,6 +170,13 @@ object Notifications {
|
|||||||
setGroup(GROUP_APK_UPDATES)
|
setGroup(GROUP_APK_UPDATES)
|
||||||
setName(context.stringResource(MR.strings.channel_ext_updates))
|
setName(context.stringResource(MR.strings.channel_ext_updates))
|
||||||
},
|
},
|
||||||
|
// SY -->
|
||||||
|
buildNotificationChannel(CHANNEL_LIBRARY_EHENTAI, IMPORTANCE_LOW) {
|
||||||
|
setName("EHentai")
|
||||||
|
setGroup(GROUP_LIBRARY)
|
||||||
|
setShowBadge(false)
|
||||||
|
},
|
||||||
|
// SY <--
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import eu.kanade.domain.track.interactor.AddTracks
|
|||||||
import eu.kanade.domain.track.model.toDomainTrack
|
import eu.kanade.domain.track.model.toDomainTrack
|
||||||
import eu.kanade.domain.track.service.TrackPreferences
|
import eu.kanade.domain.track.service.TrackPreferences
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -120,6 +121,10 @@ abstract class BaseTracker(
|
|||||||
updateRemote(track)
|
updateRemote(track)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
throw NotImplementedError("Not implemented.")
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun updateRemote(track: Track): Unit = withIOContext {
|
private suspend fun updateRemote(track: Track): Unit = withIOContext {
|
||||||
try {
|
try {
|
||||||
update(track)
|
update(track)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import androidx.annotation.ColorInt
|
|||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@@ -82,4 +83,6 @@ interface Tracker {
|
|||||||
suspend fun setRemoteStartDate(track: Track, epochMillis: Long)
|
suspend fun setRemoteStartDate(track: Track, epochMillis: Long)
|
||||||
|
|
||||||
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long)
|
suspend fun setRemoteFinishDate(track: Track, epochMillis: Long)
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
|
|||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALOAuth
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALOAuth
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
@@ -232,6 +233,10 @@ class Anilist(id: Long) : BaseTracker(id, "AniList"), DeletableTracker {
|
|||||||
interceptor.setAuth(null)
|
interceptor.setAuth(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return api.getMangaMetadata(track)
|
||||||
|
}
|
||||||
|
|
||||||
fun saveOAuth(alOAuth: ALOAuth?) {
|
fun saveOAuth(alOAuth: ALOAuth?) {
|
||||||
trackPreferences.trackToken(this).set(json.encodeToString(alOAuth))
|
trackPreferences.trackToken(this).set(json.encodeToString(alOAuth))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,18 @@ import androidx.core.net.toUri
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALAddMangaResult
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALAddMangaResult
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALCurrentUserResult
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALCurrentUserResult
|
||||||
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALOAuth
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALOAuth
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALSearchResult
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALSearchResult
|
||||||
import eu.kanade.tachiyomi.data.track.anilist.dto.ALUserListMangaQueryResult
|
import eu.kanade.tachiyomi.data.track.anilist.dto.ALUserListMangaQueryResult
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||||
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
import eu.kanade.tachiyomi.network.interceptor.rateLimit
|
||||||
import eu.kanade.tachiyomi.network.jsonMime
|
import eu.kanade.tachiyomi.network.jsonMime
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
|
import eu.kanade.tachiyomi.util.lang.htmlDecode
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonNull
|
import kotlinx.serialization.json.JsonNull
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
@@ -288,6 +291,71 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata {
|
||||||
|
return withIOContext {
|
||||||
|
val query = """
|
||||||
|
|query (${'$'}mangaId: Int!) {
|
||||||
|
|Media (id: ${'$'}mangaId) {
|
||||||
|
|id
|
||||||
|
|title {
|
||||||
|
|userPreferred
|
||||||
|
|}
|
||||||
|
|coverImage {
|
||||||
|
|large
|
||||||
|
|}
|
||||||
|
|description
|
||||||
|
|staff {
|
||||||
|
|edges {
|
||||||
|
|role
|
||||||
|
|node {
|
||||||
|
|name {
|
||||||
|
|userPreferred
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|
|
||||||
|
""".trimMargin()
|
||||||
|
val payload = buildJsonObject {
|
||||||
|
put("query", query)
|
||||||
|
putJsonObject("variables") {
|
||||||
|
put("mangaId", track.remoteId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with(json) {
|
||||||
|
authClient.newCall(
|
||||||
|
POST(
|
||||||
|
API_URL,
|
||||||
|
body = payload.toString().toRequestBody(jsonMime),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<ALMangaMetadata>()
|
||||||
|
.let {
|
||||||
|
val media = it.data.media
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = media.id,
|
||||||
|
title = media.title.userPreferred,
|
||||||
|
thumbnailUrl = media.coverImage.large,
|
||||||
|
description = media.description?.htmlDecode()?.ifEmpty { null },
|
||||||
|
authors = media.staff.edges
|
||||||
|
.filter { it.role == "Story" || it.role == "Story & Art" }
|
||||||
|
.map { it.node.name.userPreferred }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
artists = media.staff.edges
|
||||||
|
.filter { it.role == "Art" || it.role == "Story & Art" }
|
||||||
|
.map { it.node.name.userPreferred }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createDate(dateValue: Long): JsonObject {
|
private fun createDate(dateValue: Long): JsonObject {
|
||||||
if (dateValue == 0L) {
|
if (dateValue == 0L) {
|
||||||
return buildJsonObject {
|
return buildJsonObject {
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.track.anilist.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALMangaMetadata(
|
||||||
|
val data: ALMangaMetadataData,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALMangaMetadataData(
|
||||||
|
@SerialName("Media")
|
||||||
|
val media: ALMangaMetadataMedia,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALMangaMetadataMedia(
|
||||||
|
val id: Long,
|
||||||
|
val title: ALItemTitle,
|
||||||
|
val coverImage: ItemCover,
|
||||||
|
val description: String?,
|
||||||
|
val staff: ALStaff,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALStaff(
|
||||||
|
val edges: List<ALStaffEdge>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALStaffEdge(
|
||||||
|
val role: String,
|
||||||
|
val node: ALStaffNode,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class ALStaffNode(
|
||||||
|
val name: ALItemTitle,
|
||||||
|
)
|
||||||
@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMOAuth
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMOAuth
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
@@ -75,6 +76,10 @@ class Bangumi(id: Long) : BaseTracker(id, "Bangumi") {
|
|||||||
return api.search(query)
|
return api.search(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return api.getMangaMetadata(track)
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun refresh(track: Track): Track {
|
override suspend fun refresh(track: Track): Track {
|
||||||
val remoteStatusTrack = api.statusLibManga(track) ?: throw Exception("Could not find manga")
|
val remoteStatusTrack = api.statusLibManga(track) ?: throw Exception("Could not find manga")
|
||||||
track.copyPersonalFrom(remoteStatusTrack)
|
track.copyPersonalFrom(remoteStatusTrack)
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMCollectionResponse
|
|||||||
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMOAuth
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMOAuth
|
||||||
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMSearchItem
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMSearchItem
|
||||||
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMSearchResult
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMSearchResult
|
||||||
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.BGMSubject
|
||||||
|
import eu.kanade.tachiyomi.data.track.bangumi.dto.Infobox
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
@@ -21,6 +24,7 @@ import tachiyomi.core.common.util.lang.withIOContext
|
|||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.net.URLEncoder
|
import java.net.URLEncoder
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
import tachiyomi.domain.track.model.Track as DomainTrack
|
||||||
|
|
||||||
class BangumiApi(
|
class BangumiApi(
|
||||||
private val trackId: Long,
|
private val trackId: Long,
|
||||||
@@ -127,6 +131,34 @@ class BangumiApi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata {
|
||||||
|
return withIOContext {
|
||||||
|
with(json) {
|
||||||
|
authClient.newCall(GET("${API_URL}/v0/subjects/${track.remoteId}"))
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<BGMSubject>()
|
||||||
|
.let {
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = it.id,
|
||||||
|
title = it.nameCn,
|
||||||
|
thumbnailUrl = it.images?.common,
|
||||||
|
description = it.summary,
|
||||||
|
authors = it.infobox
|
||||||
|
.filter { it.key == "作者" }
|
||||||
|
.filterIsInstance<Infobox.SingleValue>()
|
||||||
|
.map { it.value }
|
||||||
|
.joinToString(", "),
|
||||||
|
artists = it.infobox
|
||||||
|
.filter { it.key == "插图" }
|
||||||
|
.filterIsInstance<Infobox.SingleValue>()
|
||||||
|
.map { it.value }
|
||||||
|
.joinToString(", "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun accessToken(code: String): BGMOAuth {
|
suspend fun accessToken(code: String): BGMOAuth {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
with(json) {
|
with(json) {
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.track.bangumi.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
|
import kotlinx.serialization.json.JsonArray
|
||||||
|
import kotlinx.serialization.json.JsonContentPolymorphicSerializer
|
||||||
|
import kotlinx.serialization.json.JsonElement
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class BGMSubject(
|
||||||
|
val images: BGMSearchItemCovers?,
|
||||||
|
val summary: String,
|
||||||
|
val name: String,
|
||||||
|
@SerialName("name_cn")
|
||||||
|
val nameCn: String,
|
||||||
|
val infobox: List<Infobox>,
|
||||||
|
val id: Long,
|
||||||
|
)
|
||||||
|
|
||||||
|
// infobox deserializer and related classes courtesy of
|
||||||
|
// https://github.com/Snd-R/komf/blob/4c260a3dcd326a5e1d74ac9662eec8124ab7e461/komf-core/src/commonMain/kotlin/snd/komf/providers/bangumi/model/BangumiSubject.kt#L53-L89
|
||||||
|
object InfoBoxSerializer : JsonContentPolymorphicSerializer<Infobox>(Infobox::class) {
|
||||||
|
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<Infobox> {
|
||||||
|
if (element !is JsonObject) throw SerializationException("Expected JsonObject go ${element::class}")
|
||||||
|
val value = element["value"]
|
||||||
|
|
||||||
|
return when (value) {
|
||||||
|
is JsonArray -> Infobox.MultipleValues.serializer()
|
||||||
|
is JsonPrimitive -> Infobox.SingleValue.serializer()
|
||||||
|
else -> throw SerializationException("Unexpected element type ${element::class}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable(with = InfoBoxSerializer::class)
|
||||||
|
sealed interface Infobox {
|
||||||
|
val key: String
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class SingleValue(
|
||||||
|
override val key: String,
|
||||||
|
val value: String,
|
||||||
|
) : Infobox
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
class MultipleValues(
|
||||||
|
override val key: String,
|
||||||
|
val value: List<InfoboxNestedValue>,
|
||||||
|
) : Infobox
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class InfoboxNestedValue(
|
||||||
|
@SerialName("k")
|
||||||
|
val key: String? = null,
|
||||||
|
@SerialName("v")
|
||||||
|
val value: String,
|
||||||
|
)
|
||||||
@@ -7,6 +7,7 @@ import eu.kanade.tachiyomi.data.database.models.Track
|
|||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuOAuth
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuOAuth
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
@@ -139,6 +140,10 @@ class Kitsu(id: Long) : BaseTracker(id, "Kitsu"), DeletableTracker {
|
|||||||
interceptor.newAuth(null)
|
interceptor.newAuth(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata {
|
||||||
|
return api.getMangaMetadata(track)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getUserId(): String {
|
private fun getUserId(): String {
|
||||||
return getPassword()
|
return getPassword()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuAddMangaResult
|
|||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuAlgoliaSearchResult
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuAlgoliaSearchResult
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuCurrentUserResult
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuCurrentUserResult
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuListSearchResult
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuListSearchResult
|
||||||
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuOAuth
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuOAuth
|
||||||
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuSearchResult
|
import eu.kanade.tachiyomi.data.track.kitsu.dto.KitsuSearchResult
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.network.DELETE
|
import eu.kanade.tachiyomi.network.DELETE
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
@@ -15,6 +17,7 @@ import eu.kanade.tachiyomi.network.POST
|
|||||||
import eu.kanade.tachiyomi.network.awaitSuccess
|
import eu.kanade.tachiyomi.network.awaitSuccess
|
||||||
import eu.kanade.tachiyomi.network.jsonMime
|
import eu.kanade.tachiyomi.network.jsonMime
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
|
import eu.kanade.tachiyomi.util.lang.htmlDecode
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.buildJsonObject
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
import kotlinx.serialization.json.put
|
import kotlinx.serialization.json.put
|
||||||
@@ -240,11 +243,80 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata {
|
||||||
|
return withIOContext {
|
||||||
|
val query = """
|
||||||
|
|query(${'$'}libraryId: ID!, ${'$'}staffCount: Int) {
|
||||||
|
|findLibraryEntryById(id: ${'$'}libraryId) {
|
||||||
|
|media {
|
||||||
|
|id
|
||||||
|
|titles {
|
||||||
|
|preferred
|
||||||
|
|}
|
||||||
|
|posterImage {
|
||||||
|
|original {
|
||||||
|
|url
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|description
|
||||||
|
|staff(first: ${'$'}staffCount) {
|
||||||
|
|nodes {
|
||||||
|
|role
|
||||||
|
|person {
|
||||||
|
|name
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
""".trimMargin()
|
||||||
|
val payload = buildJsonObject {
|
||||||
|
put("query", query)
|
||||||
|
putJsonObject("variables") {
|
||||||
|
put("libraryId", track.remoteId)
|
||||||
|
put("staffCount", 25) // 25 based on nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with(json) {
|
||||||
|
authClient.newCall(
|
||||||
|
POST(
|
||||||
|
GRAPHQL_URL,
|
||||||
|
headers = headersOf("Accept-Language", "en"),
|
||||||
|
body = payload.toString().toRequestBody(jsonMime),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<KitsuMangaMetadata>()
|
||||||
|
.let {
|
||||||
|
val manga = it.data.findLibraryEntryById.media
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = manga.id.toLong(),
|
||||||
|
title = manga.titles.preferred,
|
||||||
|
thumbnailUrl = manga.posterImage.original.url,
|
||||||
|
description = manga.description.en?.htmlDecode()?.ifEmpty { null },
|
||||||
|
authors = manga.staff.nodes
|
||||||
|
.filter { it.role == "Story" || it.role == "Story & Art" }
|
||||||
|
.map { it.person.name }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
artists = manga.staff.nodes
|
||||||
|
.filter { it.role == "Art" || it.role == "Story & Art" }
|
||||||
|
.map { it.person.name }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val CLIENT_ID = "dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd"
|
private const val CLIENT_ID = "dd031b32d2f56c990b1425efe6c42ad847e7fe3ab46bf1299f05ecd856bdb7dd"
|
||||||
private const val CLIENT_SECRET = "54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151"
|
private const val CLIENT_SECRET = "54d7307928f63414defd96399fc31ba847961ceaecef3a5fd93144e960c0e151"
|
||||||
|
|
||||||
private const val BASE_URL = "https://kitsu.app/api/edge/"
|
private const val BASE_URL = "https://kitsu.app/api/edge/"
|
||||||
|
private const val GRAPHQL_URL = "https://kitsu.app/api/graphql"
|
||||||
private const val LOGIN_URL = "https://kitsu.app/api/oauth/token"
|
private const val LOGIN_URL = "https://kitsu.app/api/oauth/token"
|
||||||
private const val BASE_MANGA_URL = "https://kitsu.app/manga/"
|
private const val BASE_MANGA_URL = "https://kitsu.app/manga/"
|
||||||
private const val ALGOLIA_KEY_URL = "https://kitsu.app/api/edge/algolia-keys/media/"
|
private const val ALGOLIA_KEY_URL = "https://kitsu.app/api/edge/algolia-keys/media/"
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.track.kitsu.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaMetadata(
|
||||||
|
val data: KitsuMangaMetadataData,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaMetadataData(
|
||||||
|
val findLibraryEntryById: KitsuMangaMetadataById,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaMetadataById(
|
||||||
|
val media: KitsuMangaMetadataMedia,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaMetadataMedia(
|
||||||
|
val id: String,
|
||||||
|
val titles: KitsuMangaTitle,
|
||||||
|
val posterImage: KitsuMangaCover,
|
||||||
|
val description: KitsuMangaDescription,
|
||||||
|
val staff: KitsuMangaStaff,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaTitle(
|
||||||
|
val preferred: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaCover(
|
||||||
|
val original: KitsuMangaCoverUrl,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaCoverUrl(
|
||||||
|
val url: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaDescription(
|
||||||
|
val en: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaStaff(
|
||||||
|
val nodes: List<KitsuMangaStaffNode>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaStaffNode(
|
||||||
|
val role: String,
|
||||||
|
val person: KitsuMangaStaffPerson,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class KitsuMangaStaffPerson(
|
||||||
|
val name: String,
|
||||||
|
)
|
||||||
@@ -10,7 +10,9 @@ import eu.kanade.tachiyomi.data.track.mangaupdates.dto.MUListItem
|
|||||||
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.MURating
|
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.MURating
|
||||||
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
|
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.copyTo
|
||||||
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
|
import eu.kanade.tachiyomi.data.track.mangaupdates.dto.toTrackSearch
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
|
import eu.kanade.tachiyomi.util.lang.htmlDecode
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
@@ -117,6 +119,20 @@ class MangaUpdates(id: Long) : BaseTracker(id, "MangaUpdates"), DeletableTracker
|
|||||||
interceptor.newAuth(authenticated.sessionToken)
|
interceptor.newAuth(authenticated.sessionToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
val series = api.getSeries(track)
|
||||||
|
return series?.let {
|
||||||
|
TrackMangaMetadata(
|
||||||
|
it.seriesId,
|
||||||
|
it.title?.htmlDecode(),
|
||||||
|
it.image?.url?.original,
|
||||||
|
it.description?.htmlDecode(),
|
||||||
|
it.authors?.filter { it.type == "Author" }?.joinToString(separator = ", ") { it.name ?: "" },
|
||||||
|
it.authors?.filter { it.type == "Artist" }?.joinToString(separator = ", ") { it.name ?: "" },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun restoreSession(): String? {
|
fun restoreSession(): String? {
|
||||||
return trackPreferences.trackPassword(this).get().ifBlank { null }
|
return trackPreferences.trackPassword(this).get().ifBlank { null }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,14 @@ class MangaUpdatesApi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getSeries(track: DomainTrack): MURecord {
|
||||||
|
return with(json) {
|
||||||
|
client.newCall(GET("$BASE_URL/v1/series/${track.remoteId}"))
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<MURecord>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val BASE_URL = "https://api.mangaupdates.com"
|
private const val BASE_URL = "https://api.mangaupdates.com"
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ data class MURecord(
|
|||||||
val ratingVotes: Int? = null,
|
val ratingVotes: Int? = null,
|
||||||
@SerialName("latest_chapter")
|
@SerialName("latest_chapter")
|
||||||
val latestChapter: Int? = null,
|
val latestChapter: Int? = null,
|
||||||
|
val authors: List<MUAuthor>? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun MURecord.toTrackSearch(id: Long): TrackSearch {
|
fun MURecord.toTrackSearch(id: Long): TrackSearch {
|
||||||
@@ -36,3 +37,9 @@ fun MURecord.toTrackSearch(id: Long): TrackSearch {
|
|||||||
start_date = this@toTrackSearch.year.toString()
|
start_date = this@toTrackSearch.year.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MUAuthor(
|
||||||
|
val type: String? = null,
|
||||||
|
val name: String? = null,
|
||||||
|
)
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ package eu.kanade.tachiyomi.data.track.mdlist
|
|||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import dev.icerock.moko.resources.StringResource
|
import dev.icerock.moko.resources.StringResource
|
||||||
|
import eu.kanade.domain.track.model.toDbTrack
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.source.model.FilterList
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
@@ -168,6 +170,21 @@ class MdList(id: Long) : BaseTracker(id, "MDList") {
|
|||||||
trackPreferences.trackToken(this).delete()
|
trackPreferences.trackToken(this).delete()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return withIOContext {
|
||||||
|
val mdex = mdex ?: throw MangaDexNotFoundException()
|
||||||
|
val manga = mdex.getMangaMetadata(track.toDbTrack())
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = 0,
|
||||||
|
title = manga?.title,
|
||||||
|
thumbnailUrl = manga?.thumbnail_url, // Doesn't load the actual cover because of Refer header
|
||||||
|
description = manga?.description,
|
||||||
|
authors = manga?.author,
|
||||||
|
artists = manga?.artist,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val isLoggedIn: Boolean
|
override val isLoggedIn: Boolean
|
||||||
get() = trackPreferences.trackToken(this).get().isNotEmpty()
|
get() = trackPreferences.trackToken(this).get().isNotEmpty()
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.track.model
|
||||||
|
|
||||||
|
data class TrackMangaMetadata(
|
||||||
|
val remoteId: Long? = null,
|
||||||
|
val title: String? = null,
|
||||||
|
val thumbnailUrl: String? = null,
|
||||||
|
val description: String? = null,
|
||||||
|
val authors: String? = null,
|
||||||
|
val artists: String? = null,
|
||||||
|
)
|
||||||
@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALOAuth
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALOAuth
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
@@ -156,6 +157,10 @@ class MyAnimeList(id: Long) : BaseTracker(id, "MyAnimeList"), DeletableTracker {
|
|||||||
interceptor.setAuth(null)
|
interceptor.setAuth(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return api.getMangaMetadata(track)
|
||||||
|
}
|
||||||
|
|
||||||
fun getIfAuthExpired(): Boolean {
|
fun getIfAuthExpired(): Boolean {
|
||||||
return trackPreferences.trackAuthExpired(this).get()
|
return trackPreferences.trackAuthExpired(this).get()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package eu.kanade.tachiyomi.data.track.myanimelist
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALListItem
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALListItem
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALListItemStatus
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALListItemStatus
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALManga
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALManga
|
||||||
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALOAuth
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALOAuth
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALSearchResult
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALSearchResult
|
||||||
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALUser
|
import eu.kanade.tachiyomi.data.track.myanimelist.dto.MALUser
|
||||||
@@ -193,6 +195,41 @@ class MyAnimeListApi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return withIOContext {
|
||||||
|
val url = "$BASE_API_URL/manga".toUri().buildUpon()
|
||||||
|
.appendPath(track.remoteId.toString())
|
||||||
|
.appendQueryParameter(
|
||||||
|
"fields",
|
||||||
|
"id,title,synopsis,main_picture,authors{first_name,last_name}",
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
with(json) {
|
||||||
|
authClient.newCall(GET(url.toString()))
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<MALMangaMetadata>()
|
||||||
|
.let {
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = it.id,
|
||||||
|
title = it.title,
|
||||||
|
thumbnailUrl = it.covers.large.ifEmpty { null } ?: it.covers.medium,
|
||||||
|
description = it.synopsis,
|
||||||
|
authors = it.authors
|
||||||
|
.filter { it.role == "Story" || it.role == "Story & Art" }
|
||||||
|
.map { "${it.node.firstName} ${it.node.lastName}".trim() }
|
||||||
|
.joinToString(separator = ", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
artists = it.authors
|
||||||
|
.filter { it.role == "Art" || it.role == "Story & Art" }
|
||||||
|
.map { "${it.node.firstName} ${it.node.lastName}".trim() }
|
||||||
|
.joinToString(separator = ", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun getListPage(offset: Int): MALUserSearchResult {
|
private suspend fun getListPage(offset: Int): MALUserSearchResult {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
val urlBuilder = "$BASE_API_URL/users/@me/mangalist".toUri().buildUpon()
|
val urlBuilder = "$BASE_API_URL/users/@me/mangalist".toUri().buildUpon()
|
||||||
|
|||||||
@@ -23,4 +23,29 @@ data class MALManga(
|
|||||||
@Serializable
|
@Serializable
|
||||||
data class MALMangaCovers(
|
data class MALMangaCovers(
|
||||||
val large: String = "",
|
val large: String = "",
|
||||||
|
val medium: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MALMangaMetadata(
|
||||||
|
val id: Long,
|
||||||
|
val title: String,
|
||||||
|
val synopsis: String?,
|
||||||
|
@SerialName("main_picture")
|
||||||
|
val covers: MALMangaCovers,
|
||||||
|
val authors: List<MALAuthor>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MALAuthor(
|
||||||
|
val node: MALAuthorNode,
|
||||||
|
val role: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class MALAuthorNode(
|
||||||
|
@SerialName("first_name")
|
||||||
|
val firstName: String,
|
||||||
|
@SerialName("last_name")
|
||||||
|
val lastName: String,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.R
|
|||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.BaseTracker
|
import eu.kanade.tachiyomi.data.track.BaseTracker
|
||||||
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
import eu.kanade.tachiyomi.data.track.DeletableTracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMOAuth
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMOAuth
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
@@ -98,6 +99,10 @@ class Shikimori(id: Long) : BaseTracker(id, "Shikimori"), DeletableTracker {
|
|||||||
return track
|
return track
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata? {
|
||||||
|
return api.getMangaMetadata(track)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getLogo() = R.drawable.ic_tracker_shikimori
|
override fun getLogo() = R.drawable.ic_tracker_shikimori
|
||||||
|
|
||||||
override fun getLogoColor() = Color.rgb(40, 40, 40)
|
override fun getLogoColor() = Color.rgb(40, 40, 40)
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package eu.kanade.tachiyomi.data.track.shikimori
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
|
import eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMAddMangaResponse
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMAddMangaResponse
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMManga
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMManga
|
||||||
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMMetadata
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMOAuth
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMOAuth
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMUser
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMUser
|
||||||
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMUserListEntry
|
import eu.kanade.tachiyomi.data.track.shikimori.dto.SMUserListEntry
|
||||||
@@ -132,6 +134,65 @@ class ShikimoriApi(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: DomainTrack): TrackMangaMetadata {
|
||||||
|
return withIOContext {
|
||||||
|
val query = """
|
||||||
|
|query(${'$'}ids: String!) {
|
||||||
|
|mangas(ids: ${'$'}ids) {
|
||||||
|
|id
|
||||||
|
|name
|
||||||
|
|description
|
||||||
|
|poster {
|
||||||
|
|originalUrl
|
||||||
|
|}
|
||||||
|
|personRoles {
|
||||||
|
|person {
|
||||||
|
|name
|
||||||
|
|}
|
||||||
|
|rolesEn
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
|}
|
||||||
|
""".trimMargin()
|
||||||
|
val payload = buildJsonObject {
|
||||||
|
put("query", query)
|
||||||
|
putJsonObject("variables") {
|
||||||
|
put("ids", "${track.remoteId}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
with(json) {
|
||||||
|
authClient.newCall(
|
||||||
|
POST(
|
||||||
|
"https://shikimori.one/api/graphql",
|
||||||
|
body = payload.toString().toRequestBody(jsonMime),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.awaitSuccess()
|
||||||
|
.parseAs<SMMetadata>()
|
||||||
|
.let {
|
||||||
|
if (it.data.mangas.isEmpty()) throw Exception("Could not get metadata from Shikimori")
|
||||||
|
val manga = it.data.mangas[0]
|
||||||
|
TrackMangaMetadata(
|
||||||
|
remoteId = manga.id.toLong(),
|
||||||
|
title = manga.name,
|
||||||
|
thumbnailUrl = manga.poster.originalUrl,
|
||||||
|
description = manga.description,
|
||||||
|
authors = manga.personRoles
|
||||||
|
.filter { it.rolesEn.contains("Story") || it.rolesEn.contains("Story & Art") }
|
||||||
|
.map { it.person.name }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
artists = manga.personRoles
|
||||||
|
.filter { it.rolesEn.contains("Art") || it.rolesEn.contains("Story & Art") }
|
||||||
|
.map { it.person.name }
|
||||||
|
.joinToString(", ")
|
||||||
|
.ifEmpty { null },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun accessToken(code: String): SMOAuth {
|
suspend fun accessToken(code: String): SMOAuth {
|
||||||
return withIOContext {
|
return withIOContext {
|
||||||
with(json) {
|
with(json) {
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package eu.kanade.tachiyomi.data.track.shikimori.dto
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMMetadata(
|
||||||
|
val data: SMMetadataData,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMMetadataData(
|
||||||
|
val mangas: List<SMMetadataResult>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMMetadataResult(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val description: String,
|
||||||
|
val poster: SMMangaPoster,
|
||||||
|
val personRoles: List<SMMangaPersonRoles>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMMangaPoster(
|
||||||
|
val originalUrl: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMMangaPersonRoles(
|
||||||
|
val person: SMPerson,
|
||||||
|
val rolesEn: List<String>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SMPerson(
|
||||||
|
val name: String,
|
||||||
|
)
|
||||||
@@ -181,9 +181,9 @@ internal class AppUpdateNotifier(private val context: Context) {
|
|||||||
addAction(
|
addAction(
|
||||||
R.drawable.ic_close_24dp,
|
R.drawable.ic_close_24dp,
|
||||||
context.stringResource(MR.strings.action_cancel),
|
context.stringResource(MR.strings.action_cancel),
|
||||||
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_APP_UPDATER),
|
NotificationReceiver.dismissNotificationPendingBroadcast(context, Notifications.ID_APP_UPDATE_ERROR),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
notificationBuilder.show(Notifications.ID_APP_UPDATER)
|
notificationBuilder.show(Notifications.ID_APP_UPDATE_ERROR)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,6 +313,10 @@ class MangaDex(delegate: HttpSource, val context: Context) :
|
|||||||
return similarHandler.getRelated(manga)
|
return similarHandler.getRelated(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(track: Track): SManga? {
|
||||||
|
return mangaHandler.getMangaMetadata(track, id, coverQuality(), tryUsingFirstVolumeCover(), altTitlesInDesc())
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val dataSaverPref = "dataSaverV5"
|
private const val dataSaverPref = "dataSaverV5"
|
||||||
|
|
||||||
|
|||||||
+1
-4
@@ -5,8 +5,6 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
@@ -29,8 +27,7 @@ import tachiyomi.i18n.sy.SYMR
|
|||||||
|
|
||||||
class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen() {
|
class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen() {
|
||||||
|
|
||||||
@delegate:Transient
|
var newSelectedItem: Pair<Long, Long>? = null
|
||||||
var newSelectedItem by mutableStateOf<Pair<Long, Long>?>(null)
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
|||||||
+2
-3
@@ -8,7 +8,6 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
@@ -24,6 +23,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
|||||||
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
import eu.kanade.tachiyomi.ui.webview.WebViewScreen
|
||||||
import exh.ui.ifSourcesLoaded
|
import exh.ui.ifSourcesLoaded
|
||||||
import kotlinx.collections.immutable.persistentListOf
|
import kotlinx.collections.immutable.persistentListOf
|
||||||
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.core.common.Constants
|
import tachiyomi.core.common.Constants
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
@@ -71,7 +71,6 @@ data class SourceSearchScreen(
|
|||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
val pagingFlow by screenModel.mangaPagerFlowFlow.collectAsState()
|
|
||||||
val openMigrateDialog: (Manga) -> Unit = {
|
val openMigrateDialog: (Manga) -> Unit = {
|
||||||
// SY -->
|
// SY -->
|
||||||
navigator.items
|
navigator.items
|
||||||
@@ -83,7 +82,7 @@ data class SourceSearchScreen(
|
|||||||
}
|
}
|
||||||
BrowseSourceContent(
|
BrowseSourceContent(
|
||||||
source = screenModel.source,
|
source = screenModel.source,
|
||||||
mangaList = pagingFlow.collectAsLazyPagingItems(),
|
mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(),
|
||||||
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
// SY -->
|
// SY -->
|
||||||
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import androidx.compose.material3.Icon
|
|||||||
import androidx.compose.material3.InputChip
|
import androidx.compose.material3.InputChip
|
||||||
import androidx.compose.material3.InputChipDefaults
|
import androidx.compose.material3.InputChipDefaults
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.MenuAnchorType
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -154,7 +155,7 @@ fun AutoCompleteTextField(
|
|||||||
null
|
null
|
||||||
},
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.menuAnchor()
|
.menuAnchor(MenuAnchorType.PrimaryEditable)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.runOnEnterKeyPressed { submit() },
|
.runOnEnterKeyPressed { submit() },
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ import androidx.compose.ui.platform.LocalConfiguration
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
@@ -61,6 +60,7 @@ import exh.ui.ifSourcesLoaded
|
|||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.core.common.Constants
|
import tachiyomi.core.common.Constants
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
@@ -240,11 +240,9 @@ data class BrowseSourceScreen(
|
|||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
val pagingFlow by screenModel.mangaPagerFlowFlow.collectAsState()
|
|
||||||
|
|
||||||
BrowseSourceContent(
|
BrowseSourceContent(
|
||||||
source = screenModel.source,
|
source = screenModel.source,
|
||||||
mangaList = pagingFlow.collectAsLazyPagingItems(),
|
mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(),
|
||||||
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
// SY -->
|
// SY -->
|
||||||
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
||||||
|
|||||||
@@ -30,13 +30,13 @@ import androidx.compose.ui.Modifier
|
|||||||
import androidx.compose.ui.semantics.contentDescription
|
import androidx.compose.ui.semantics.contentDescription
|
||||||
import androidx.compose.ui.semantics.semantics
|
import androidx.compose.ui.semantics.semantics
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.util.fastFilter
|
||||||
import androidx.compose.ui.util.fastForEach
|
import androidx.compose.ui.util.fastForEach
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
import cafe.adriel.voyager.navigator.tab.LocalTabNavigator
|
||||||
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
import cafe.adriel.voyager.navigator.tab.TabNavigator
|
||||||
import eu.kanade.core.preference.asState
|
import eu.kanade.core.preference.asState
|
||||||
import eu.kanade.core.util.fastFilter
|
|
||||||
import eu.kanade.domain.source.service.SourcePreferences
|
import eu.kanade.domain.source.service.SourcePreferences
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
|
|||||||
@@ -7,16 +7,16 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.util.fastAll
|
import androidx.compose.ui.util.fastAll
|
||||||
import androidx.compose.ui.util.fastAny
|
import androidx.compose.ui.util.fastAny
|
||||||
|
import androidx.compose.ui.util.fastDistinctBy
|
||||||
|
import androidx.compose.ui.util.fastFilter
|
||||||
import androidx.compose.ui.util.fastForEach
|
import androidx.compose.ui.util.fastForEach
|
||||||
import androidx.compose.ui.util.fastMap
|
import androidx.compose.ui.util.fastMap
|
||||||
|
import androidx.compose.ui.util.fastMapNotNull
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import eu.kanade.core.preference.PreferenceMutableState
|
import eu.kanade.core.preference.PreferenceMutableState
|
||||||
import eu.kanade.core.preference.asState
|
import eu.kanade.core.preference.asState
|
||||||
import eu.kanade.core.util.fastDistinctBy
|
|
||||||
import eu.kanade.core.util.fastFilter
|
|
||||||
import eu.kanade.core.util.fastFilterNot
|
import eu.kanade.core.util.fastFilterNot
|
||||||
import eu.kanade.core.util.fastMapNotNull
|
|
||||||
import eu.kanade.core.util.fastPartition
|
import eu.kanade.core.util.fastPartition
|
||||||
import eu.kanade.domain.base.BasePreferences
|
import eu.kanade.domain.base.BasePreferences
|
||||||
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
import eu.kanade.domain.chapter.interactor.SetReadStatus
|
||||||
|
|||||||
@@ -334,8 +334,8 @@ data object LibraryTab : Tab {
|
|||||||
// SY -->
|
// SY -->
|
||||||
SyncFavoritesProgressDialog(
|
SyncFavoritesProgressDialog(
|
||||||
status = screenModel.favoritesSync.status.collectAsState().value,
|
status = screenModel.favoritesSync.status.collectAsState().value,
|
||||||
setStatusIdle = { screenModel.favoritesSync.status.value = FavoritesSyncStatus.Idle(context) },
|
setStatusIdle = { screenModel.favoritesSync.status.value = FavoritesSyncStatus.Idle },
|
||||||
openManga = { navigator.push(MangaScreen(it.id)) },
|
openManga = { navigator.push(MangaScreen(it)) },
|
||||||
)
|
)
|
||||||
// SY <--
|
// SY <--
|
||||||
|
|
||||||
|
|||||||
@@ -3,20 +3,26 @@ package eu.kanade.tachiyomi.ui.manga
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.children
|
import androidx.core.view.children
|
||||||
@@ -26,22 +32,34 @@ import coil3.transform.RoundedCornersTransformation
|
|||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.google.android.material.chip.ChipGroup
|
import com.google.android.material.chip.ChipGroup
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import eu.kanade.presentation.track.components.TrackLogoIcon
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.data.track.EnhancedTracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.Tracker
|
||||||
|
import eu.kanade.tachiyomi.data.track.TrackerManager
|
||||||
import eu.kanade.tachiyomi.databinding.EditMangaDialogBinding
|
import eu.kanade.tachiyomi.databinding.EditMangaDialogBinding
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.lang.chop
|
import eu.kanade.tachiyomi.util.lang.chop
|
||||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||||
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.widget.materialdialogs.setTextInput
|
import eu.kanade.tachiyomi.widget.materialdialogs.setTextInput
|
||||||
import exh.ui.metadata.adapters.MetadataUIUtil.getResourceColor
|
import exh.ui.metadata.adapters.MetadataUIUtil.getResourceColor
|
||||||
import exh.util.dropBlank
|
import exh.util.dropBlank
|
||||||
import exh.util.trimOrNull
|
import exh.util.trimOrNull
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import logcat.LogPriority
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
|
import tachiyomi.core.common.util.system.logcat
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.domain.track.interactor.GetTracks
|
||||||
|
import tachiyomi.domain.track.model.Track
|
||||||
import tachiyomi.i18n.MR
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.i18n.stringResource
|
import tachiyomi.presentation.core.i18n.stringResource
|
||||||
import tachiyomi.source.local.isLocal
|
import tachiyomi.source.local.isLocal
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun EditMangaDialog(
|
fun EditMangaDialog(
|
||||||
@@ -61,6 +79,10 @@ fun EditMangaDialog(
|
|||||||
var binding by remember {
|
var binding by remember {
|
||||||
mutableStateOf<EditMangaDialogBinding?>(null)
|
mutableStateOf<EditMangaDialogBinding?>(null)
|
||||||
}
|
}
|
||||||
|
val showTrackerSelectionDialogue = remember { mutableStateOf(false) }
|
||||||
|
val getTracks = remember { Injekt.get<GetTracks>() }
|
||||||
|
val trackerManager = remember { Injekt.get<TrackerManager>() }
|
||||||
|
val tracks = remember { mutableStateOf(emptyList<Pair<Track, Tracker>>()) }
|
||||||
AlertDialog(
|
AlertDialog(
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
@@ -109,7 +131,7 @@ fun EditMangaDialog(
|
|||||||
EditMangaDialogBinding.inflate(LayoutInflater.from(factoryContext))
|
EditMangaDialogBinding.inflate(LayoutInflater.from(factoryContext))
|
||||||
.also { binding = it }
|
.also { binding = it }
|
||||||
.apply {
|
.apply {
|
||||||
onViewCreated(manga, factoryContext, this, scope)
|
onViewCreated(manga, factoryContext, this, scope, getTracks, trackerManager, tracks, showTrackerSelectionDialogue)
|
||||||
}
|
}
|
||||||
.root
|
.root
|
||||||
},
|
},
|
||||||
@@ -118,9 +140,61 @@ fun EditMangaDialog(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (showTrackerSelectionDialogue.value) {
|
||||||
|
TrackerSelectDialog(
|
||||||
|
tracks = tracks.value,
|
||||||
|
onDismissRequest = { showTrackerSelectionDialogue.value = false },
|
||||||
|
onTrackerSelect = { tracker, track ->
|
||||||
|
scope.launch {
|
||||||
|
autofillFromTracker(binding!!, track, tracker)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDialogBinding, scope: CoroutineScope) {
|
@Composable
|
||||||
|
private fun TrackerSelectDialog(
|
||||||
|
tracks: List<Pair<Track, Tracker>>,
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
onTrackerSelect: (
|
||||||
|
tracker: Tracker,
|
||||||
|
track: Track,
|
||||||
|
) -> Unit,
|
||||||
|
) {
|
||||||
|
AlertDialog(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = onDismissRequest) {
|
||||||
|
Text(stringResource(MR.strings.action_cancel))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title = {
|
||||||
|
Text(stringResource(SYMR.strings.select_tracker))
|
||||||
|
},
|
||||||
|
text = {
|
||||||
|
FlowRow(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||||
|
) {
|
||||||
|
tracks.forEach { (track, tracker) ->
|
||||||
|
TrackLogoIcon(
|
||||||
|
tracker,
|
||||||
|
onClick = {
|
||||||
|
onTrackerSelect(tracker, track)
|
||||||
|
onDismissRequest()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDialogBinding, scope: CoroutineScope, getTracks: GetTracks, trackerManager: TrackerManager, tracks: MutableState<List<Pair<Track, Tracker>>>, showTrackerSelectionDialogue: MutableState<Boolean>) {
|
||||||
loadCover(manga, binding)
|
loadCover(manga, binding)
|
||||||
|
|
||||||
val statusAdapter: ArrayAdapter<String> = ArrayAdapter(
|
val statusAdapter: ArrayAdapter<String> = ArrayAdapter(
|
||||||
@@ -203,6 +277,55 @@ private fun onViewCreated(manga: Manga, context: Context, binding: EditMangaDial
|
|||||||
|
|
||||||
binding.resetTags.setOnClickListener { resetTags(manga, binding, scope) }
|
binding.resetTags.setOnClickListener { resetTags(manga, binding, scope) }
|
||||||
binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope) }
|
binding.resetInfo.setOnClickListener { resetInfo(manga, binding, scope) }
|
||||||
|
binding.autofillFromTracker.setOnClickListener {
|
||||||
|
scope.launch {
|
||||||
|
getTrackers(manga, binding, context, getTracks, trackerManager, tracks, showTrackerSelectionDialogue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun getTrackers(manga: Manga, binding: EditMangaDialogBinding, context: Context, getTracks: GetTracks, trackerManager: TrackerManager, tracks: MutableState<List<Pair<Track, Tracker>>>, showTrackerSelectionDialogue: MutableState<Boolean>) {
|
||||||
|
tracks.value = getTracks.await(manga.id).map { track ->
|
||||||
|
track to trackerManager.get(track.trackerId)!!
|
||||||
|
}
|
||||||
|
.filterNot { (_, tracker) -> tracker is EnhancedTracker }
|
||||||
|
|
||||||
|
if (tracks.value.isEmpty()) {
|
||||||
|
context.toast(context.stringResource(SYMR.strings.entry_not_tracked))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tracks.value.size > 1) {
|
||||||
|
showTrackerSelectionDialogue.value = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
autofillFromTracker(binding, tracks.value.first().first, tracks.value.first().second)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setTextIfNotBlank(field: (String) -> Unit, value: String?) {
|
||||||
|
value?.takeIf { it.isNotBlank() }?.let { field(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun autofillFromTracker(binding: EditMangaDialogBinding, track: Track, tracker: Tracker) {
|
||||||
|
try {
|
||||||
|
val trackerMangaMetadata = tracker.getMangaMetadata(track)
|
||||||
|
|
||||||
|
setTextIfNotBlank(binding.title::setText, trackerMangaMetadata?.title)
|
||||||
|
setTextIfNotBlank(binding.mangaAuthor::setText, trackerMangaMetadata?.authors)
|
||||||
|
setTextIfNotBlank(binding.mangaArtist::setText, trackerMangaMetadata?.artists)
|
||||||
|
setTextIfNotBlank(binding.thumbnailUrl::setText, trackerMangaMetadata?.thumbnailUrl)
|
||||||
|
setTextIfNotBlank(binding.mangaDescription::setText, trackerMangaMetadata?.description)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
tracker.logcat(LogPriority.ERROR, e)
|
||||||
|
binding.root.context.toast(
|
||||||
|
binding.root.context.stringResource(
|
||||||
|
MR.strings.track_error,
|
||||||
|
tracker.name,
|
||||||
|
e.message ?: "",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetTags(manga: Manga, binding: EditMangaDialogBinding, scope: CoroutineScope) {
|
private fun resetTags(manga: Manga, binding: EditMangaDialogBinding, scope: CoroutineScope) {
|
||||||
|
|||||||
@@ -33,17 +33,13 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.EASE_IN_OUT
|
|||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.EASE_OUT_QUAD
|
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.EASE_OUT_QUAD
|
||||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
|
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE
|
||||||
import com.github.chrisbanes.photoview.PhotoView
|
import com.github.chrisbanes.photoview.PhotoView
|
||||||
import eu.kanade.domain.base.BasePreferences
|
|
||||||
import eu.kanade.tachiyomi.data.coil.cropBorders
|
import eu.kanade.tachiyomi.data.coil.cropBorders
|
||||||
import eu.kanade.tachiyomi.data.coil.customDecoder
|
import eu.kanade.tachiyomi.data.coil.customDecoder
|
||||||
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonSubsamplingImageView
|
import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonSubsamplingImageView
|
||||||
import eu.kanade.tachiyomi.util.system.GLUtil
|
|
||||||
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
import eu.kanade.tachiyomi.util.system.animatorDurationScale
|
||||||
import eu.kanade.tachiyomi.util.view.isVisibleOnScreen
|
import eu.kanade.tachiyomi.util.view.isVisibleOnScreen
|
||||||
import okio.BufferedSource
|
import okio.BufferedSource
|
||||||
import tachiyomi.core.common.util.system.ImageUtil
|
import tachiyomi.core.common.util.system.ImageUtil
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper view for showing page image.
|
* A wrapper view for showing page image.
|
||||||
@@ -61,8 +57,6 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||||||
private val isWebtoon: Boolean = false,
|
private val isWebtoon: Boolean = false,
|
||||||
) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes) {
|
) : FrameLayout(context, attrs, defStyleAttrs, defStyleRes) {
|
||||||
|
|
||||||
private val alwaysUseSSIVToDecode by lazy { Injekt.get<BasePreferences>().alwaysUseSSIVToDecode().get() }
|
|
||||||
|
|
||||||
private var pageView: View? = null
|
private var pageView: View? = null
|
||||||
|
|
||||||
private var config: Config? = null
|
private var config: Config? = null
|
||||||
@@ -122,21 +116,22 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
private fun SubsamplingScaleImageView.landscapeZoom(forward: Boolean) {
|
||||||
|
val config = config
|
||||||
if (config != null &&
|
if (config != null &&
|
||||||
config!!.landscapeZoom &&
|
config.landscapeZoom &&
|
||||||
config!!.minimumScaleType == SCALE_TYPE_CENTER_INSIDE &&
|
config.minimumScaleType == SCALE_TYPE_CENTER_INSIDE &&
|
||||||
sWidth > sHeight &&
|
sWidth > sHeight &&
|
||||||
scale == minScale
|
scale == minScale
|
||||||
) {
|
) {
|
||||||
handler?.postDelayed(500) {
|
handler?.postDelayed(500) {
|
||||||
val point = when (config!!.zoomStartPosition) {
|
val point = when (config.zoomStartPosition) {
|
||||||
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
ZoomStartPosition.LEFT -> if (forward) PointF(0F, 0F) else PointF(sWidth.toFloat(), 0F)
|
||||||
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
ZoomStartPosition.RIGHT -> if (forward) PointF(sWidth.toFloat(), 0F) else PointF(0F, 0F)
|
||||||
ZoomStartPosition.CENTER -> center
|
ZoomStartPosition.CENTER -> center
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetScale = height.toFloat() / sHeight.toFloat()
|
val targetScale = height.toFloat() / sHeight.toFloat()
|
||||||
animateScaleAndCenter(targetScale, point)!!
|
(animateScaleAndCenter(targetScale, point) ?: return@postDelayed)
|
||||||
.withDuration(500)
|
.withDuration(500)
|
||||||
.withEasing(EASE_IN_OUT_QUAD)
|
.withEasing(EASE_IN_OUT_QUAD)
|
||||||
.withInterruptible(true)
|
.withInterruptible(true)
|
||||||
@@ -238,7 +233,7 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||||||
} else {
|
} else {
|
||||||
SubsamplingScaleImageView(context)
|
SubsamplingScaleImageView(context)
|
||||||
}.apply {
|
}.apply {
|
||||||
setMaxTileSize(GLUtil.maxTextureSize)
|
setMaxTileSize(ImageUtil.hardwareBitmapThreshold)
|
||||||
setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
|
setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_CENTER)
|
||||||
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
|
setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE)
|
||||||
setMinimumTileDpi(180)
|
setMinimumTileDpi(180)
|
||||||
@@ -299,32 +294,34 @@ open class ReaderPageImageView @JvmOverloads constructor(
|
|||||||
isVisible = true
|
isVisible = true
|
||||||
}
|
}
|
||||||
is BufferedSource -> {
|
is BufferedSource -> {
|
||||||
if (alwaysUseSSIVToDecode || !isWebtoon || !ImageUtil.canUseCoilToDecode(data)) {
|
if (!isWebtoon) {
|
||||||
|
setHardwareConfig(ImageUtil.canUseHardwareBitmap(data))
|
||||||
setImage(ImageSource.inputStream(data.inputStream()))
|
setImage(ImageSource.inputStream(data.inputStream()))
|
||||||
isVisible = true
|
isVisible = true
|
||||||
} else {
|
return@apply
|
||||||
val request = ImageRequest.Builder(context)
|
|
||||||
.data(data)
|
|
||||||
.memoryCachePolicy(CachePolicy.DISABLED)
|
|
||||||
.diskCachePolicy(CachePolicy.DISABLED)
|
|
||||||
.target(
|
|
||||||
onSuccess = { result ->
|
|
||||||
val image = result as BitmapImage
|
|
||||||
setImage(ImageSource.bitmap(image.bitmap))
|
|
||||||
isVisible = true
|
|
||||||
},
|
|
||||||
onError = {
|
|
||||||
this@ReaderPageImageView.onImageLoadError()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.size(ViewSizeResolver(this@ReaderPageImageView))
|
|
||||||
.precision(Precision.INEXACT)
|
|
||||||
.cropBorders(config.cropBorders)
|
|
||||||
.customDecoder(true)
|
|
||||||
.crossfade(false)
|
|
||||||
.build()
|
|
||||||
context.imageLoader.enqueue(request)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageRequest.Builder(context)
|
||||||
|
.data(data)
|
||||||
|
.memoryCachePolicy(CachePolicy.DISABLED)
|
||||||
|
.diskCachePolicy(CachePolicy.DISABLED)
|
||||||
|
.target(
|
||||||
|
onSuccess = { result ->
|
||||||
|
val image = result as BitmapImage
|
||||||
|
setImage(ImageSource.bitmap(image.bitmap))
|
||||||
|
isVisible = true
|
||||||
|
},
|
||||||
|
onError = {
|
||||||
|
onImageLoadError()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.size(ViewSizeResolver(this@ReaderPageImageView))
|
||||||
|
.precision(Precision.INEXACT)
|
||||||
|
.cropBorders(config.cropBorders)
|
||||||
|
.customDecoder(true)
|
||||||
|
.crossfade(false)
|
||||||
|
.build()
|
||||||
|
.let(context.imageLoader::enqueue)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}")
|
throw IllegalArgumentException("Not implemented for class ${data::class.simpleName}")
|
||||||
|
|||||||
@@ -353,8 +353,8 @@ class PagerViewerAdapter(private val viewer: PagerViewer) : ViewPagerAdapter() {
|
|||||||
else -> oldCurrent?.first ?: return
|
else -> oldCurrent?.first ?: return
|
||||||
}
|
}
|
||||||
|
|
||||||
val index = when (newPage) {
|
val index = when {
|
||||||
is ChapterTransition -> {
|
newPage is ChapterTransition && joinedItems.none { it.first == newPage || it.second == newPage } -> {
|
||||||
val filteredPages = joinedItems.filter {
|
val filteredPages = joinedItems.filter {
|
||||||
it.first is ReaderPage &&
|
it.first is ReaderPage &&
|
||||||
(it.first as ReaderPage).chapter == newPage.to
|
(it.first as ReaderPage).chapter == newPage.to
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package eu.kanade.tachiyomi.ui.stats
|
package eu.kanade.tachiyomi.ui.stats
|
||||||
|
|
||||||
|
import androidx.compose.ui.util.fastDistinctBy
|
||||||
|
import androidx.compose.ui.util.fastFilter
|
||||||
|
import androidx.compose.ui.util.fastMapNotNull
|
||||||
import cafe.adriel.voyager.core.model.StateScreenModel
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
||||||
import cafe.adriel.voyager.core.model.screenModelScope
|
import cafe.adriel.voyager.core.model.screenModelScope
|
||||||
import eu.kanade.core.util.fastCountNot
|
import eu.kanade.core.util.fastCountNot
|
||||||
import eu.kanade.core.util.fastDistinctBy
|
|
||||||
import eu.kanade.core.util.fastFilter
|
|
||||||
import eu.kanade.core.util.fastFilterNot
|
import eu.kanade.core.util.fastFilterNot
|
||||||
import eu.kanade.core.util.fastMapNotNull
|
|
||||||
import eu.kanade.presentation.more.stats.StatsScreenState
|
import eu.kanade.presentation.more.stats.StatsScreenState
|
||||||
import eu.kanade.presentation.more.stats.data.StatsData
|
import eu.kanade.presentation.more.stats.data.StatsData
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.core.content.getSystemService
|
|||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
import eu.kanade.domain.ui.UiPreferences
|
import eu.kanade.domain.ui.UiPreferences
|
||||||
|
import eu.kanade.domain.ui.model.ThemeMode
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
|
import eu.kanade.tachiyomi.ui.base.delegate.ThemingDelegate
|
||||||
@@ -107,9 +108,13 @@ fun Context.createFileInCacheDir(name: String): File {
|
|||||||
fun Context.createReaderThemeContext(): Context {
|
fun Context.createReaderThemeContext(): Context {
|
||||||
val preferences = Injekt.get<UiPreferences>()
|
val preferences = Injekt.get<UiPreferences>()
|
||||||
val readerPreferences = Injekt.get<ReaderPreferences>()
|
val readerPreferences = Injekt.get<ReaderPreferences>()
|
||||||
|
val themeMode = preferences.themeMode().get()
|
||||||
val isDarkBackground = when (readerPreferences.readerTheme().get()) {
|
val isDarkBackground = when (readerPreferences.readerTheme().get()) {
|
||||||
1, 2 -> true // Black, Gray
|
1, 2 -> true // Black, Gray
|
||||||
3 -> applicationContext.isNightMode() // Automatic bg uses activity background by default
|
3 -> when (themeMode) { // Automatic bg uses activity background by default
|
||||||
|
ThemeMode.SYSTEM -> applicationContext.isNightMode()
|
||||||
|
else -> themeMode == ThemeMode.DARK
|
||||||
|
}
|
||||||
else -> false // White
|
else -> false // White
|
||||||
}
|
}
|
||||||
val expected = if (isDarkBackground) Configuration.UI_MODE_NIGHT_YES else Configuration.UI_MODE_NIGHT_NO
|
val expected = if (isDarkBackground) Configuration.UI_MODE_NIGHT_YES else Configuration.UI_MODE_NIGHT_NO
|
||||||
|
|||||||
@@ -119,4 +119,10 @@ data class DummyTracker(
|
|||||||
track: eu.kanade.tachiyomi.data.database.models.Track,
|
track: eu.kanade.tachiyomi.data.database.models.Track,
|
||||||
epochMillis: Long,
|
epochMillis: Long,
|
||||||
) = Unit
|
) = Unit
|
||||||
|
|
||||||
|
override suspend fun getMangaMetadata(
|
||||||
|
track: tachiyomi.domain.track.model.Track,
|
||||||
|
): eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata = eu.kanade.tachiyomi.data.track.model.TrackMangaMetadata(
|
||||||
|
0, "test", "test", "test", "test", "test",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package exh.eh
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.core.security.SecurityPreferences
|
||||||
|
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||||
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
|
import eu.kanade.tachiyomi.util.lang.chop
|
||||||
|
import eu.kanade.tachiyomi.util.system.cancelNotification
|
||||||
|
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||||
|
import eu.kanade.tachiyomi.util.system.notify
|
||||||
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.i18n.MR
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.math.RoundingMode
|
||||||
|
import java.text.NumberFormat
|
||||||
|
|
||||||
|
class EHentaiUpdateNotifier(private val context: Context) {
|
||||||
|
|
||||||
|
private val securityPreferences: SecurityPreferences by injectLazy()
|
||||||
|
|
||||||
|
private val percentFormatter = NumberFormat.getPercentInstance().apply {
|
||||||
|
roundingMode = RoundingMode.DOWN
|
||||||
|
maximumFractionDigits = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitmap of the app for notifications.
|
||||||
|
*/
|
||||||
|
private val notificationBitmap by lazy {
|
||||||
|
BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached progress notification to avoid creating a lot.
|
||||||
|
*/
|
||||||
|
val progressNotificationBuilder by lazy {
|
||||||
|
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_EHENTAI) {
|
||||||
|
setContentTitle(context.stringResource(MR.strings.app_name))
|
||||||
|
setSmallIcon(R.drawable.ic_refresh_24dp)
|
||||||
|
setLargeIcon(notificationBitmap)
|
||||||
|
setOngoing(true)
|
||||||
|
setOnlyAlertOnce(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the notification containing the currently updating manga and the progress.
|
||||||
|
*
|
||||||
|
* @param manga the manga that are being updated.
|
||||||
|
* @param current the current progress.
|
||||||
|
* @param total the total progress.
|
||||||
|
*/
|
||||||
|
fun showProgressNotification(manga: Manga, current: Int, total: Int) {
|
||||||
|
progressNotificationBuilder
|
||||||
|
.setContentTitle(
|
||||||
|
context.stringResource(
|
||||||
|
MR.strings.notification_updating_progress,
|
||||||
|
percentFormatter.format(current.toFloat() / total),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!securityPreferences.hideNotificationContent().get()) {
|
||||||
|
val updatingText = manga.title.chop(40)
|
||||||
|
progressNotificationBuilder.setStyle(NotificationCompat.BigTextStyle().bigText(updatingText))
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notify(
|
||||||
|
Notifications.ID_EHENTAI_PROGRESS,
|
||||||
|
progressNotificationBuilder
|
||||||
|
.setProgress(total, current, false)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows notification containing update entries that failed with action to open full log.
|
||||||
|
*
|
||||||
|
* @param failed Number of entries that failed to update.
|
||||||
|
* @param uri Uri for error log file containing all titles that failed.
|
||||||
|
*/
|
||||||
|
fun showUpdateErrorNotification(failed: Int, uri: Uri) {
|
||||||
|
if (failed == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notify(
|
||||||
|
Notifications.ID_EHENTAI_ERROR,
|
||||||
|
Notifications.CHANNEL_LIBRARY_EHENTAI,
|
||||||
|
) {
|
||||||
|
setContentTitle(context.stringResource(MR.strings.notification_update_error, failed))
|
||||||
|
setContentText(context.stringResource(MR.strings.action_show_errors))
|
||||||
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
|
|
||||||
|
setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the progress notification.
|
||||||
|
*/
|
||||||
|
fun cancelProgressNotification() {
|
||||||
|
context.cancelNotification(Notifications.ID_EHENTAI_PROGRESS)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
package exh.eh
|
package exh.eh
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.os.Build
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
import androidx.work.CoroutineWorker
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.ForegroundInfo
|
||||||
import androidx.work.NetworkType
|
import androidx.work.NetworkType
|
||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
|
import androidx.work.OutOfQuotaPolicy
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.elvishew.xlog.Logger
|
import com.elvishew.xlog.Logger
|
||||||
@@ -14,8 +18,10 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
|||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.model.toSManga
|
import eu.kanade.domain.manga.model.toSManga
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
|
||||||
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||||
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
||||||
|
import eu.kanade.tachiyomi.util.system.setForegroundSafely
|
||||||
import eu.kanade.tachiyomi.util.system.workManager
|
import eu.kanade.tachiyomi.util.system.workManager
|
||||||
import exh.debug.DebugToggles
|
import exh.debug.DebugToggles
|
||||||
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
|
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
|
||||||
@@ -27,9 +33,11 @@ import kotlinx.coroutines.flow.mapNotNull
|
|||||||
import kotlinx.coroutines.flow.toList
|
import kotlinx.coroutines.flow.toList
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import tachiyomi.core.common.preference.getAndSet
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
import tachiyomi.domain.chapter.interactor.GetChaptersByMangaId
|
||||||
import tachiyomi.domain.chapter.model.Chapter
|
import tachiyomi.domain.chapter.model.Chapter
|
||||||
|
import tachiyomi.domain.library.service.LibraryPreferences
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_CHARGING
|
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_CHARGING
|
||||||
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_ONLY_ON_WIFI
|
import tachiyomi.domain.library.service.LibraryPreferences.Companion.DEVICE_ONLY_ON_WIFI
|
||||||
import tachiyomi.domain.manga.interactor.GetExhFavoriteMangaWithMetadata
|
import tachiyomi.domain.manga.interactor.GetExhFavoriteMangaWithMetadata
|
||||||
@@ -46,9 +54,10 @@ import kotlin.time.Duration.Companion.days
|
|||||||
class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerParameters) :
|
class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerParameters) :
|
||||||
CoroutineWorker(context, workerParams) {
|
CoroutineWorker(context, workerParams) {
|
||||||
private val preferences: UnsortedPreferences by injectLazy()
|
private val preferences: UnsortedPreferences by injectLazy()
|
||||||
|
private val libraryPreferences: LibraryPreferences by injectLazy()
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
||||||
private val logger: Logger = xLog()
|
private val logger: Logger by lazy { xLog() }
|
||||||
private val updateManga: UpdateManga by injectLazy()
|
private val updateManga: UpdateManga by injectLazy()
|
||||||
private val syncChaptersWithSource: SyncChaptersWithSource by injectLazy()
|
private val syncChaptersWithSource: SyncChaptersWithSource by injectLazy()
|
||||||
private val getChaptersByMangaId: GetChaptersByMangaId by injectLazy()
|
private val getChaptersByMangaId: GetChaptersByMangaId by injectLazy()
|
||||||
@@ -56,22 +65,38 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
private val insertFlatMetadata: InsertFlatMetadata by injectLazy()
|
private val insertFlatMetadata: InsertFlatMetadata by injectLazy()
|
||||||
private val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy()
|
private val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy()
|
||||||
|
|
||||||
private val updateNotifier by lazy { LibraryUpdateNotifier(context) }
|
private val updateNotifier by lazy { EHentaiUpdateNotifier(context) }
|
||||||
|
private val libraryUpdateNotifier by lazy { LibraryUpdateNotifier(context) }
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
return try {
|
return try {
|
||||||
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
|
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
|
||||||
Result.success() // retry again later
|
Result.success() // retry again later
|
||||||
} else {
|
} else {
|
||||||
|
setForegroundSafely()
|
||||||
startUpdating()
|
startUpdating()
|
||||||
logger.d("Update job completed!")
|
logger.d("Update job completed!")
|
||||||
Result.success()
|
Result.success()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Result.success() // retry again later
|
Result.success() // retry again later
|
||||||
|
} finally {
|
||||||
|
updateNotifier.cancelProgressNotification()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getForegroundInfo(): ForegroundInfo {
|
||||||
|
return ForegroundInfo(
|
||||||
|
Notifications.ID_EHENTAI_PROGRESS,
|
||||||
|
updateNotifier.progressNotificationBuilder.build(),
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun startUpdating() {
|
private suspend fun startUpdating() {
|
||||||
logger.d("Update job started!")
|
logger.d("Update job started!")
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
@@ -138,6 +163,11 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
}
|
}
|
||||||
|
|
||||||
val (new, chapters) = try {
|
val (new, chapters) = try {
|
||||||
|
updateNotifier.showProgressNotification(
|
||||||
|
manga,
|
||||||
|
updatedThisIteration + failuresThisIteration,
|
||||||
|
mangaMetaToUpdateThisIter.size,
|
||||||
|
)
|
||||||
updateEntryAndGetChapters(manga)
|
updateEntryAndGetChapters(manga)
|
||||||
} catch (e: GalleryNotUpdatedException) {
|
} catch (e: GalleryNotUpdatedException) {
|
||||||
if (e.network) {
|
if (e.network) {
|
||||||
@@ -173,8 +203,10 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
updateHelper.findAcceptedRootAndDiscardOthers(manga.source, chapters)
|
||||||
|
|
||||||
if (new.isNotEmpty() && manga.id == acceptedRoot.manga.id) {
|
if (new.isNotEmpty() && manga.id == acceptedRoot.manga.id) {
|
||||||
|
libraryPreferences.newUpdatesCount().getAndSet { it + new.size }
|
||||||
updatedManga += acceptedRoot.manga to new.toTypedArray()
|
updatedManga += acceptedRoot.manga to new.toTypedArray()
|
||||||
} else if (exhNew.isNotEmpty() && updatedManga.none { it.first.id == acceptedRoot.manga.id }) {
|
} else if (exhNew.isNotEmpty() && updatedManga.none { it.first.id == acceptedRoot.manga.id }) {
|
||||||
|
libraryPreferences.newUpdatesCount().getAndSet { it + exhNew.size }
|
||||||
updatedManga += acceptedRoot.manga to exhNew.toTypedArray()
|
updatedManga += acceptedRoot.manga to exhNew.toTypedArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,8 +225,9 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
updateNotifier.cancelProgressNotification()
|
||||||
if (updatedManga.isNotEmpty()) {
|
if (updatedManga.isNotEmpty()) {
|
||||||
updateNotifier.showUpdateNotifications(updatedManga)
|
libraryUpdateNotifier.showUpdateNotifications(updatedManga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +270,12 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
private val logger by lazy { XLog.tag("EHUpdaterScheduler") }
|
private val logger by lazy { XLog.tag("EHUpdaterScheduler") }
|
||||||
|
|
||||||
fun launchBackgroundTest(context: Context) {
|
fun launchBackgroundTest(context: Context) {
|
||||||
context.workManager.enqueue(OneTimeWorkRequestBuilder<EHentaiUpdateWorker>().build())
|
context.workManager.enqueue(
|
||||||
|
OneTimeWorkRequestBuilder<EHentaiUpdateWorker>()
|
||||||
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
|
.addTag(TAG)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) {
|
fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ class MemAutoFlushingLookupTable<T>(
|
|||||||
val size = bb.getInt(4)
|
val size = bb.getInt(4)
|
||||||
val strBArr = ByteArray(size)
|
val strBArr = ByteArray(size)
|
||||||
if (!input.requireBytes(strBArr, size)) break
|
if (!input.requireBytes(strBArr, size)) break
|
||||||
table.put(k, serializer.read(strBArr.toString(Charsets.UTF_8)))
|
table.put(k, serializer.read(strBArr.decodeToString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: FileNotFoundException) {
|
} catch (e: FileNotFoundException) {
|
||||||
@@ -131,7 +131,7 @@ class MemAutoFlushingLookupTable<T>(
|
|||||||
try {
|
try {
|
||||||
val out = fos.sink().buffer()
|
val out = fos.sink().buffer()
|
||||||
table.forEach { key, value ->
|
table.forEach { key, value ->
|
||||||
val v = serializer.write(value).toByteArray(Charsets.UTF_8)
|
val v = serializer.write(value).encodeToByteArray()
|
||||||
bb.putInt(0, key)
|
bb.putInt(0, key)
|
||||||
bb.putInt(4, v.size)
|
bb.putInt(4, v.size)
|
||||||
out.write(bb.array())
|
out.write(bb.array())
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -7,22 +7,31 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:abby dark star",
|
"cosplayer:abby dark star",
|
||||||
"cosplayer:adamae-dono",
|
"cosplayer:adamae-dono",
|
||||||
"cosplayer:ai lei jiang",
|
"cosplayer:ai lei jiang",
|
||||||
|
"cosplayer:ai xi",
|
||||||
"cosplayer:aiga mizuki",
|
"cosplayer:aiga mizuki",
|
||||||
|
"cosplayer:aimy",
|
||||||
"cosplayer:aizawa ren",
|
"cosplayer:aizawa ren",
|
||||||
"cosplayer:ajo cosplay",
|
"cosplayer:ajo cosplay",
|
||||||
"cosplayer:akane araragi",
|
"cosplayer:akane araragi",
|
||||||
|
"cosplayer:akari yamazaki",
|
||||||
"cosplayer:akemi101xoxo",
|
"cosplayer:akemi101xoxo",
|
||||||
"cosplayer:akiba cute star",
|
"cosplayer:akiba cute star",
|
||||||
"cosplayer:akitsu honoka",
|
"cosplayer:akitsu honoka",
|
||||||
"cosplayer:aleksandra bodler",
|
"cosplayer:aleksandra bodler",
|
||||||
|
"cosplayer:aleksandra lerman",
|
||||||
"cosplayer:aleksis hitc",
|
"cosplayer:aleksis hitc",
|
||||||
"cosplayer:alexis lust",
|
"cosplayer:alexis lust",
|
||||||
"cosplayer:alice bong",
|
"cosplayer:alice bong",
|
||||||
"cosplayer:alice cosplay",
|
"cosplayer:alice cosplay",
|
||||||
|
"cosplayer:alice wonder",
|
||||||
|
"cosplayer:aliceholic",
|
||||||
"cosplayer:alicekyo",
|
"cosplayer:alicekyo",
|
||||||
"cosplayer:alin ma",
|
"cosplayer:alin ma",
|
||||||
|
"cosplayer:alisa arkhangelskaya",
|
||||||
"cosplayer:alisa kiss",
|
"cosplayer:alisa kiss",
|
||||||
|
"cosplayer:alisa valeeva",
|
||||||
"cosplayer:alodia gosiengfiao",
|
"cosplayer:alodia gosiengfiao",
|
||||||
|
"cosplayer:alva velasco",
|
||||||
"cosplayer:alycia elvie",
|
"cosplayer:alycia elvie",
|
||||||
"cosplayer:amanda welp",
|
"cosplayer:amanda welp",
|
||||||
"cosplayer:amber hallibell",
|
"cosplayer:amber hallibell",
|
||||||
@@ -31,16 +40,20 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:anabelle joy",
|
"cosplayer:anabelle joy",
|
||||||
"cosplayer:anastasia komori",
|
"cosplayer:anastasia komori",
|
||||||
"cosplayer:angelina preobrazhenskaya",
|
"cosplayer:angelina preobrazhenskaya",
|
||||||
|
"cosplayer:aniela verbin",
|
||||||
"cosplayer:aninnyan",
|
"cosplayer:aninnyan",
|
||||||
"cosplayer:anizu chie",
|
"cosplayer:anizu chie",
|
||||||
"cosplayer:anna kuramoto",
|
"cosplayer:anna kuramoto",
|
||||||
"cosplayer:annie seixas",
|
"cosplayer:annie seixas",
|
||||||
|
"cosplayer:anxi",
|
||||||
"cosplayer:aokotan",
|
"cosplayer:aokotan",
|
||||||
"cosplayer:arai yomi",
|
"cosplayer:arai yomi",
|
||||||
"cosplayer:araki mai",
|
"cosplayer:araki mai",
|
||||||
|
"cosplayer:ari.anna",
|
||||||
"cosplayer:arisa mizuhara",
|
"cosplayer:arisa mizuhara",
|
||||||
"cosplayer:arty huang",
|
"cosplayer:arty huang",
|
||||||
"cosplayer:asakawa ran",
|
"cosplayer:asakawa ran",
|
||||||
|
"cosplayer:asakura kotomi",
|
||||||
"cosplayer:asakura naho",
|
"cosplayer:asakura naho",
|
||||||
"cosplayer:ashiya noriko",
|
"cosplayer:ashiya noriko",
|
||||||
"cosplayer:astasiadream",
|
"cosplayer:astasiadream",
|
||||||
@@ -48,28 +61,39 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:atina",
|
"cosplayer:atina",
|
||||||
"cosplayer:atsuki",
|
"cosplayer:atsuki",
|
||||||
"cosplayer:audalove",
|
"cosplayer:audalove",
|
||||||
|
"cosplayer:aveline tetsuya",
|
||||||
"cosplayer:ayaka matsunaga",
|
"cosplayer:ayaka matsunaga",
|
||||||
"cosplayer:bailey jay",
|
"cosplayer:bailey jay",
|
||||||
"cosplayer:banbanko",
|
"cosplayer:banbanko",
|
||||||
|
"cosplayer:beibei kappu",
|
||||||
|
"cosplayer:bella bunbun",
|
||||||
"cosplayer:bili bili",
|
"cosplayer:bili bili",
|
||||||
"cosplayer:bishoujomom",
|
"cosplayer:bishoujomom",
|
||||||
|
"cosplayer:blacqkl",
|
||||||
"cosplayer:bloodraven",
|
"cosplayer:bloodraven",
|
||||||
"cosplayer:bobbi starr",
|
"cosplayer:bobbi starr",
|
||||||
"cosplayer:bonn1ethebunny",
|
"cosplayer:bonn1ethebunny",
|
||||||
"cosplayer:bonnie bonkers",
|
"cosplayer:bonnie bonkers",
|
||||||
"cosplayer:boople snoot",
|
"cosplayer:boople snoot",
|
||||||
|
"cosplayer:breesknees",
|
||||||
|
"cosplayer:bukkitbrown",
|
||||||
"cosplayer:bunny ayumi",
|
"cosplayer:bunny ayumi",
|
||||||
"cosplayer:carry key",
|
"cosplayer:carry key",
|
||||||
"cosplayer:chadkasa",
|
"cosplayer:chadkasa",
|
||||||
|
"cosplayer:charess",
|
||||||
"cosplayer:charles dera",
|
"cosplayer:charles dera",
|
||||||
|
"cosplayer:chisai cosplay",
|
||||||
"cosplayer:chokoboll mukakoi.",
|
"cosplayer:chokoboll mukakoi.",
|
||||||
"cosplayer:christina volkova",
|
"cosplayer:christina volkova",
|
||||||
"cosplayer:chunmomo",
|
"cosplayer:chunmomo",
|
||||||
"cosplayer:cocopie",
|
"cosplayer:cocopie",
|
||||||
"cosplayer:comonun",
|
"cosplayer:comonun",
|
||||||
|
"cosplayer:cristina luise",
|
||||||
|
"cosplayer:dakko ja rrs",
|
||||||
"cosplayer:dani doe",
|
"cosplayer:dani doe",
|
||||||
"cosplayer:danielle beaulieu",
|
"cosplayer:danielle beaulieu",
|
||||||
"cosplayer:danielle vedovelli",
|
"cosplayer:danielle vedovelli",
|
||||||
|
"cosplayer:daria kravets",
|
||||||
"cosplayer:darling cute",
|
"cosplayer:darling cute",
|
||||||
"cosplayer:dessyy",
|
"cosplayer:dessyy",
|
||||||
"cosplayer:dillion harper",
|
"cosplayer:dillion harper",
|
||||||
@@ -78,39 +102,56 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:donnaloli",
|
"cosplayer:donnaloli",
|
||||||
"cosplayer:eira wang",
|
"cosplayer:eira wang",
|
||||||
"cosplayer:electricbum",
|
"cosplayer:electricbum",
|
||||||
|
"cosplayer:elena lenina",
|
||||||
|
"cosplayer:elena yuna",
|
||||||
|
"cosplayer:elisa cattabriga",
|
||||||
|
"cosplayer:elyhria",
|
||||||
"cosplayer:erin eevee",
|
"cosplayer:erin eevee",
|
||||||
|
"cosplayer:erotic doki",
|
||||||
"cosplayer:eroticneko",
|
"cosplayer:eroticneko",
|
||||||
|
"cosplayer:esther rutkovskaya-tudor",
|
||||||
"cosplayer:eunji pyo",
|
"cosplayer:eunji pyo",
|
||||||
"cosplayer:evawxsh",
|
"cosplayer:evawxsh",
|
||||||
"cosplayer:evenink",
|
"cosplayer:evenink",
|
||||||
"cosplayer:evie evangelion",
|
"cosplayer:evie evangelion",
|
||||||
"cosplayer:ezy summers",
|
"cosplayer:ezy summers",
|
||||||
|
"cosplayer:fatiaoliii",
|
||||||
|
"cosplayer:fay sg",
|
||||||
"cosplayer:fe galvao",
|
"cosplayer:fe galvao",
|
||||||
"cosplayer:felvelial",
|
"cosplayer:felvelial",
|
||||||
|
"cosplayer:feng jiang jiang",
|
||||||
"cosplayer:ferin feirn",
|
"cosplayer:ferin feirn",
|
||||||
"cosplayer:feywilde",
|
"cosplayer:feywilde",
|
||||||
|
"cosplayer:firtsbornunicorn",
|
||||||
"cosplayer:flora daria",
|
"cosplayer:flora daria",
|
||||||
"cosplayer:fluffy nemu",
|
"cosplayer:fluffy nemu",
|
||||||
"cosplayer:franxcos",
|
"cosplayer:franxcos",
|
||||||
"cosplayer:frauleinmilk",
|
"cosplayer:frauleinmilk",
|
||||||
|
"cosplayer:fubuki ami",
|
||||||
"cosplayer:fuji serika",
|
"cosplayer:fuji serika",
|
||||||
|
"cosplayer:futaba emiru",
|
||||||
"cosplayer:g44 wa kizutsukanai",
|
"cosplayer:g44 wa kizutsukanai",
|
||||||
"cosplayer:garo dazay",
|
"cosplayer:garo dazay",
|
||||||
|
"cosplayer:generic egirl",
|
||||||
"cosplayer:genthehobbit",
|
"cosplayer:genthehobbit",
|
||||||
"cosplayer:ghostly cosplay",
|
"cosplayer:ghostly cosplay",
|
||||||
|
"cosplayer:giorgia vecchini",
|
||||||
"cosplayer:giulia valeriani",
|
"cosplayer:giulia valeriani",
|
||||||
"cosplayer:goth egg",
|
"cosplayer:goth egg",
|
||||||
"cosplayer:gumiho hannya",
|
"cosplayer:gumiho hannya",
|
||||||
"cosplayer:guo chengzi",
|
"cosplayer:guo chengzi",
|
||||||
"cosplayer:hakuhi kaede",
|
"cosplayer:hakuhi kaede",
|
||||||
|
"cosplayer:hamasaki rio",
|
||||||
"cosplayer:han yeri",
|
"cosplayer:han yeri",
|
||||||
"cosplayer:hanamura misaki",
|
"cosplayer:hanamura misaki",
|
||||||
"cosplayer:hane ame",
|
"cosplayer:hane ame",
|
||||||
|
"cosplayer:harukaism",
|
||||||
"cosplayer:helly von valentine",
|
"cosplayer:helly von valentine",
|
||||||
"cosplayer:hessakai",
|
"cosplayer:hessakai",
|
||||||
"cosplayer:hey shika",
|
"cosplayer:hey shika",
|
||||||
"cosplayer:higurashi rin",
|
"cosplayer:higurashi rin",
|
||||||
"cosplayer:himeecosplay",
|
"cosplayer:himeecosplay",
|
||||||
|
"cosplayer:hinatasama",
|
||||||
"cosplayer:hinaughtya",
|
"cosplayer:hinaughtya",
|
||||||
"cosplayer:hiyo nishizuku",
|
"cosplayer:hiyo nishizuku",
|
||||||
"cosplayer:holly ava",
|
"cosplayer:holly ava",
|
||||||
@@ -121,18 +162,30 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:imokawa naoko",
|
"cosplayer:imokawa naoko",
|
||||||
"cosplayer:ino cosplay",
|
"cosplayer:ino cosplay",
|
||||||
"cosplayer:iori moe",
|
"cosplayer:iori moe",
|
||||||
|
"cosplayer:iri",
|
||||||
"cosplayer:ishikawa asami",
|
"cosplayer:ishikawa asami",
|
||||||
|
"cosplayer:jannet kat",
|
||||||
|
"cosplayer:jannet vinogradova",
|
||||||
|
"cosplayer:jasming chea",
|
||||||
"cosplayer:jaycee",
|
"cosplayer:jaycee",
|
||||||
|
"cosplayer:jenezial",
|
||||||
"cosplayer:jenna lynn meowri",
|
"cosplayer:jenna lynn meowri",
|
||||||
|
"cosplayer:jenni kaellberg",
|
||||||
"cosplayer:jessica nigri",
|
"cosplayer:jessica nigri",
|
||||||
|
"cosplayer:jessika jinx",
|
||||||
"cosplayer:jill",
|
"cosplayer:jill",
|
||||||
"cosplayer:jinxie",
|
"cosplayer:jinxie",
|
||||||
"cosplayer:jiuqujean",
|
"cosplayer:jiuqujean",
|
||||||
|
"cosplayer:jiuyan",
|
||||||
"cosplayer:jiyun choi",
|
"cosplayer:jiyun choi",
|
||||||
|
"cosplayer:joanna muller",
|
||||||
|
"cosplayer:julia larangeiras",
|
||||||
"cosplayer:julia shuenkova",
|
"cosplayer:julia shuenkova",
|
||||||
"cosplayer:jun ye tako",
|
"cosplayer:jun ye tako",
|
||||||
"cosplayer:kae kaieda",
|
"cosplayer:kae kaieda",
|
||||||
"cosplayer:kalinka fox",
|
"cosplayer:kalinka fox",
|
||||||
|
"cosplayer:kamelya chan",
|
||||||
|
"cosplayer:kamijiri ichigo",
|
||||||
"cosplayer:kamui alice",
|
"cosplayer:kamui alice",
|
||||||
"cosplayer:kanda likitsangjaroen",
|
"cosplayer:kanda likitsangjaroen",
|
||||||
"cosplayer:kanda midori",
|
"cosplayer:kanda midori",
|
||||||
@@ -141,6 +194,7 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:katiecakey",
|
"cosplayer:katiecakey",
|
||||||
"cosplayer:kay bear",
|
"cosplayer:kay bear",
|
||||||
"cosplayer:kaya huang",
|
"cosplayer:kaya huang",
|
||||||
|
"cosplayer:kei shino",
|
||||||
"cosplayer:khainsaw",
|
"cosplayer:khainsaw",
|
||||||
"cosplayer:kibashi",
|
"cosplayer:kibashi",
|
||||||
"cosplayer:kiera marie",
|
"cosplayer:kiera marie",
|
||||||
@@ -159,19 +213,27 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:kotea dali",
|
"cosplayer:kotea dali",
|
||||||
"cosplayer:koyama rikako",
|
"cosplayer:koyama rikako",
|
||||||
"cosplayer:kqueentsun",
|
"cosplayer:kqueentsun",
|
||||||
|
"cosplayer:kurasaka kururu",
|
||||||
"cosplayer:kurumi.",
|
"cosplayer:kurumi.",
|
||||||
"cosplayer:kururugi aoi",
|
"cosplayer:kururugi aoi",
|
||||||
"cosplayer:kuuko w",
|
"cosplayer:kuuko w",
|
||||||
"cosplayer:kyonatix",
|
"cosplayer:kyonatix",
|
||||||
|
"cosplayer:lagertha",
|
||||||
|
"cosplayer:lea martinez",
|
||||||
"cosplayer:lelewu",
|
"cosplayer:lelewu",
|
||||||
"cosplayer:lenfried",
|
"cosplayer:lenfried",
|
||||||
"cosplayer:lewdoart",
|
"cosplayer:lewdoart",
|
||||||
|
"cosplayer:lex kuma",
|
||||||
"cosplayer:lightz",
|
"cosplayer:lightz",
|
||||||
|
"cosplayer:lili erlih",
|
||||||
"cosplayer:lilly rose",
|
"cosplayer:lilly rose",
|
||||||
"cosplayer:lilya victorovna",
|
"cosplayer:lilya victorovna",
|
||||||
"cosplayer:lilylit",
|
"cosplayer:lilylit",
|
||||||
|
"cosplayer:lina erdel",
|
||||||
|
"cosplayer:ling li",
|
||||||
"cosplayer:linneas life",
|
"cosplayer:linneas life",
|
||||||
"cosplayer:linzi jiang",
|
"cosplayer:linzi jiang",
|
||||||
|
"cosplayer:little blue girl",
|
||||||
"cosplayer:lizyhsan",
|
"cosplayer:lizyhsan",
|
||||||
"cosplayer:lmusicl",
|
"cosplayer:lmusicl",
|
||||||
"cosplayer:lovelyspacekitten",
|
"cosplayer:lovelyspacekitten",
|
||||||
@@ -180,11 +242,16 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:mags.irl",
|
"cosplayer:mags.irl",
|
||||||
"cosplayer:mais conheyo",
|
"cosplayer:mais conheyo",
|
||||||
"cosplayer:manyu hanausagi",
|
"cosplayer:manyu hanausagi",
|
||||||
|
"cosplayer:mappy sanchez",
|
||||||
"cosplayer:marie-claude bourbonnais",
|
"cosplayer:marie-claude bourbonnais",
|
||||||
"cosplayer:mariigabii",
|
"cosplayer:mariigabii",
|
||||||
|
"cosplayer:masako yume",
|
||||||
|
"cosplayer:meagan vanburkleo",
|
||||||
|
"cosplayer:mei succubus",
|
||||||
"cosplayer:meikoui",
|
"cosplayer:meikoui",
|
||||||
"cosplayer:meriol-chan",
|
"cosplayer:meriol-chan",
|
||||||
"cosplayer:mianbing xianer",
|
"cosplayer:mianbing xianer",
|
||||||
|
"cosplayer:micro kitty",
|
||||||
"cosplayer:miih cosplay",
|
"cosplayer:miih cosplay",
|
||||||
"cosplayer:miiya",
|
"cosplayer:miiya",
|
||||||
"cosplayer:mik allen",
|
"cosplayer:mik allen",
|
||||||
@@ -192,18 +259,27 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:milena hime",
|
"cosplayer:milena hime",
|
||||||
"cosplayer:milky",
|
"cosplayer:milky",
|
||||||
"cosplayer:mimi-chan",
|
"cosplayer:mimi-chan",
|
||||||
|
"cosplayer:mimmi",
|
||||||
"cosplayer:mimo ningyo",
|
"cosplayer:mimo ningyo",
|
||||||
"cosplayer:minaduki miri",
|
"cosplayer:minaduki miri",
|
||||||
|
"cosplayer:minato riku",
|
||||||
"cosplayer:minematsu rie",
|
"cosplayer:minematsu rie",
|
||||||
|
"cosplayer:mingchudesu",
|
||||||
"cosplayer:mingming kizami",
|
"cosplayer:mingming kizami",
|
||||||
"cosplayer:mingtao",
|
"cosplayer:mingtao",
|
||||||
"cosplayer:minzy tea",
|
"cosplayer:minzy tea",
|
||||||
|
"cosplayer:miorin",
|
||||||
"cosplayer:misaco",
|
"cosplayer:misaco",
|
||||||
|
"cosplayer:mishka bear",
|
||||||
"cosplayer:missbrisolo",
|
"cosplayer:missbrisolo",
|
||||||
|
"cosplayer:misty silver",
|
||||||
|
"cosplayer:mitsuki riyu",
|
||||||
"cosplayer:miura aika",
|
"cosplayer:miura aika",
|
||||||
"cosplayer:miyoki",
|
"cosplayer:miyoki",
|
||||||
"cosplayer:mizhimaoqiu",
|
"cosplayer:mizhimaoqiu",
|
||||||
|
"cosplayer:mizuki akira",
|
||||||
"cosplayer:mochichuu",
|
"cosplayer:mochichuu",
|
||||||
|
"cosplayer:mochimochi-nn",
|
||||||
"cosplayer:mochizuki eiko",
|
"cosplayer:mochizuki eiko",
|
||||||
"cosplayer:mochizuki kanade",
|
"cosplayer:mochizuki kanade",
|
||||||
"cosplayer:moiicos",
|
"cosplayer:moiicos",
|
||||||
@@ -211,8 +287,11 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:momoiro reku",
|
"cosplayer:momoiro reku",
|
||||||
"cosplayer:momoko",
|
"cosplayer:momoko",
|
||||||
"cosplayer:momokun",
|
"cosplayer:momokun",
|
||||||
|
"cosplayer:momousagi mao",
|
||||||
"cosplayer:moody feet",
|
"cosplayer:moody feet",
|
||||||
"cosplayer:morgana cosplay",
|
"cosplayer:morgana cosplay",
|
||||||
|
"cosplayer:mowky",
|
||||||
|
"cosplayer:moyu mommy",
|
||||||
"cosplayer:mozuku kimura",
|
"cosplayer:mozuku kimura",
|
||||||
"cosplayer:mu zhi ben lan",
|
"cosplayer:mu zhi ben lan",
|
||||||
"cosplayer:murasaki",
|
"cosplayer:murasaki",
|
||||||
@@ -222,7 +301,11 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:nadyasonika",
|
"cosplayer:nadyasonika",
|
||||||
"cosplayer:nagisa",
|
"cosplayer:nagisa",
|
||||||
"cosplayer:nan tao momoko",
|
"cosplayer:nan tao momoko",
|
||||||
|
"cosplayer:natalya ditrikh",
|
||||||
"cosplayer:natasha roik",
|
"cosplayer:natasha roik",
|
||||||
|
"cosplayer:nateephan thammasilbanyad",
|
||||||
|
"cosplayer:nawo019",
|
||||||
|
"cosplayer:nayfi bardales",
|
||||||
"cosplayer:nekob0icarti",
|
"cosplayer:nekob0icarti",
|
||||||
"cosplayer:neroko kaigan",
|
"cosplayer:neroko kaigan",
|
||||||
"cosplayer:niannian d",
|
"cosplayer:niannian d",
|
||||||
@@ -235,58 +318,81 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:nonbinate",
|
"cosplayer:nonbinate",
|
||||||
"cosplayer:nora fawn",
|
"cosplayer:nora fawn",
|
||||||
"cosplayer:nuko meguro",
|
"cosplayer:nuko meguro",
|
||||||
|
"cosplayer:nuria gonzalez",
|
||||||
"cosplayer:nyako",
|
"cosplayer:nyako",
|
||||||
|
"cosplayer:nymph-princess",
|
||||||
"cosplayer:octokuro",
|
"cosplayer:octokuro",
|
||||||
"cosplayer:odoru neko ningen",
|
"cosplayer:odoru neko ningen",
|
||||||
"cosplayer:oharucosplay",
|
"cosplayer:oharucosplay",
|
||||||
"cosplayer:oichi",
|
"cosplayer:oichi",
|
||||||
"cosplayer:okada yui",
|
"cosplayer:okada yui",
|
||||||
"cosplayer:oki-cospi",
|
"cosplayer:oki-cospi",
|
||||||
|
"cosplayer:olivia metric",
|
||||||
"cosplayer:olyashaa saxon",
|
"cosplayer:olyashaa saxon",
|
||||||
"cosplayer:pattie cosplay",
|
"cosplayer:pattie cosplay",
|
||||||
"cosplayer:pattycake",
|
"cosplayer:pattycake",
|
||||||
"cosplayer:peachtot",
|
"cosplayer:peachtot",
|
||||||
"cosplayer:penkarui",
|
"cosplayer:penkarui",
|
||||||
|
"cosplayer:penny walsh",
|
||||||
|
"cosplayer:pichapu",
|
||||||
"cosplayer:pokket",
|
"cosplayer:pokket",
|
||||||
"cosplayer:poon warunya",
|
"cosplayer:poon warunya",
|
||||||
"cosplayer:punk macarroni",
|
"cosplayer:punk macarroni",
|
||||||
|
"cosplayer:purrblind",
|
||||||
"cosplayer:pushiku",
|
"cosplayer:pushiku",
|
||||||
"cosplayer:qiqi nanazi",
|
"cosplayer:qiqi nanazi",
|
||||||
"cosplayer:qiqi xiaojie",
|
"cosplayer:qiqi xiaojie",
|
||||||
"cosplayer:qiuhe keji",
|
"cosplayer:qiuhe keji",
|
||||||
"cosplayer:queenie",
|
"cosplayer:queenie",
|
||||||
|
"cosplayer:quist",
|
||||||
|
"cosplayer:rachel ravaged",
|
||||||
|
"cosplayer:rakuraku",
|
||||||
"cosplayer:ravvcoser",
|
"cosplayer:ravvcoser",
|
||||||
"cosplayer:raynearts",
|
"cosplayer:raynearts",
|
||||||
"cosplayer:rea kami",
|
"cosplayer:rea kami",
|
||||||
|
"cosplayer:renee storm",
|
||||||
"cosplayer:rhylee passfield",
|
"cosplayer:rhylee passfield",
|
||||||
"cosplayer:ri care",
|
"cosplayer:ri care",
|
||||||
|
"cosplayer:riani haratina",
|
||||||
"cosplayer:rinami",
|
"cosplayer:rinami",
|
||||||
|
"cosplayer:ringo mitsuki",
|
||||||
|
"cosplayer:rinoa",
|
||||||
"cosplayer:rio-chan",
|
"cosplayer:rio-chan",
|
||||||
"cosplayer:rioko",
|
"cosplayer:rioko",
|
||||||
|
"cosplayer:rissoft",
|
||||||
"cosplayer:rocksy light",
|
"cosplayer:rocksy light",
|
||||||
"cosplayer:rolyatistaylor",
|
"cosplayer:rolyatistaylor",
|
||||||
"cosplayer:rongrongzi",
|
"cosplayer:rongrongzi",
|
||||||
|
"cosplayer:rusuwu",
|
||||||
"cosplayer:sachi budou",
|
"cosplayer:sachi budou",
|
||||||
"cosplayer:saiwari ph",
|
"cosplayer:saiwari ph",
|
||||||
|
"cosplayer:saki kawanami",
|
||||||
"cosplayer:saku",
|
"cosplayer:saku",
|
||||||
"cosplayer:sakura ema",
|
"cosplayer:sakura ema",
|
||||||
"cosplayer:sakurai",
|
"cosplayer:sakurai",
|
||||||
"cosplayer:sakurai hinoki",
|
"cosplayer:sakurai hinoki",
|
||||||
|
"cosplayer:samantha boon",
|
||||||
"cosplayer:sandykuroneko",
|
"cosplayer:sandykuroneko",
|
||||||
"cosplayer:saotome love",
|
"cosplayer:saotome love",
|
||||||
"cosplayer:sara underwood",
|
"cosplayer:sara underwood",
|
||||||
"cosplayer:sarah quillian",
|
"cosplayer:sarah quillian",
|
||||||
|
"cosplayer:sarawrcosplay",
|
||||||
"cosplayer:sasaki remi",
|
"cosplayer:sasaki remi",
|
||||||
|
"cosplayer:sato yuri",
|
||||||
"cosplayer:savannah sixx",
|
"cosplayer:savannah sixx",
|
||||||
"cosplayer:sawaka",
|
"cosplayer:sawaka",
|
||||||
"cosplayer:scarlett afterdark",
|
"cosplayer:scarlett afterdark",
|
||||||
"cosplayer:sean lawless",
|
"cosplayer:sean lawless",
|
||||||
|
"cosplayer:sei",
|
||||||
"cosplayer:seltin sweet",
|
"cosplayer:seltin sweet",
|
||||||
|
"cosplayer:sena",
|
||||||
|
"cosplayer:sexy toys",
|
||||||
"cosplayer:sexyflowerwater",
|
"cosplayer:sexyflowerwater",
|
||||||
"cosplayer:sharkparty",
|
"cosplayer:sharkparty",
|
||||||
"cosplayer:shermie",
|
"cosplayer:shermie",
|
||||||
"cosplayer:shibuya kaho",
|
"cosplayer:shibuya kaho",
|
||||||
"cosplayer:shimizu yuno",
|
"cosplayer:shimizu yuno",
|
||||||
|
"cosplayer:shinen",
|
||||||
"cosplayer:shiro kitsune",
|
"cosplayer:shiro kitsune",
|
||||||
"cosplayer:shiroluxx",
|
"cosplayer:shiroluxx",
|
||||||
"cosplayer:siao ding",
|
"cosplayer:siao ding",
|
||||||
@@ -295,14 +401,24 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:soa lianna",
|
"cosplayer:soa lianna",
|
||||||
"cosplayer:son yeeun",
|
"cosplayer:son yeeun",
|
||||||
"cosplayer:sophie snomster",
|
"cosplayer:sophie snomster",
|
||||||
|
"cosplayer:stanislava anushkina",
|
||||||
|
"cosplayer:starfmodel",
|
||||||
"cosplayer:stelar hoshi",
|
"cosplayer:stelar hoshi",
|
||||||
|
"cosplayer:sunny lin",
|
||||||
"cosplayer:sunny ray",
|
"cosplayer:sunny ray",
|
||||||
"cosplayer:sunnyvier",
|
"cosplayer:sunnyvier",
|
||||||
"cosplayer:sunohara miki",
|
"cosplayer:sunohara miki",
|
||||||
|
"cosplayer:sushiflavoredmilk",
|
||||||
|
"cosplayer:suspira grey",
|
||||||
|
"cosplayer:tachibana remika",
|
||||||
"cosplayer:tanaka hitomi",
|
"cosplayer:tanaka hitomi",
|
||||||
|
"cosplayer:tanaka mana",
|
||||||
"cosplayer:tangtang",
|
"cosplayer:tangtang",
|
||||||
"cosplayer:tanja kensinger",
|
"cosplayer:tanja kensinger",
|
||||||
|
"cosplayer:tao liang azhai",
|
||||||
|
"cosplayer:tara nicole azarian",
|
||||||
"cosplayer:tasha leigh",
|
"cosplayer:tasha leigh",
|
||||||
|
"cosplayer:tatiana neva",
|
||||||
"cosplayer:tenleid",
|
"cosplayer:tenleid",
|
||||||
"cosplayer:tenryu-0",
|
"cosplayer:tenryu-0",
|
||||||
"cosplayer:tenshi myu.",
|
"cosplayer:tenshi myu.",
|
||||||
@@ -310,8 +426,10 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:tiffany gordon",
|
"cosplayer:tiffany gordon",
|
||||||
"cosplayer:tiny asa",
|
"cosplayer:tiny asa",
|
||||||
"cosplayer:todopokie",
|
"cosplayer:todopokie",
|
||||||
|
"cosplayer:tristan valdez",
|
||||||
"cosplayer:tsubaki zakuro",
|
"cosplayer:tsubaki zakuro",
|
||||||
"cosplayer:tsuki desu",
|
"cosplayer:tsuki desu",
|
||||||
|
"cosplayer:tsuki miko",
|
||||||
"cosplayer:tsukimiya madoka",
|
"cosplayer:tsukimiya madoka",
|
||||||
"cosplayer:tsuyato",
|
"cosplayer:tsuyato",
|
||||||
"cosplayer:turkish chi-chi",
|
"cosplayer:turkish chi-chi",
|
||||||
@@ -320,34 +438,49 @@ object Cosplayer : TagList {
|
|||||||
"cosplayer:ukyuu nako",
|
"cosplayer:ukyuu nako",
|
||||||
"cosplayer:una cosplayer",
|
"cosplayer:una cosplayer",
|
||||||
"cosplayer:uno megumi",
|
"cosplayer:uno megumi",
|
||||||
|
"cosplayer:ur senpai june",
|
||||||
"cosplayer:uru uruu",
|
"cosplayer:uru uruu",
|
||||||
|
"cosplayer:uta kohaku",
|
||||||
"cosplayer:valery himera",
|
"cosplayer:valery himera",
|
||||||
"cosplayer:velvet",
|
"cosplayer:velvet",
|
||||||
"cosplayer:veroodle",
|
"cosplayer:veroodle",
|
||||||
|
"cosplayer:vlada lutsak",
|
||||||
"cosplayer:wanco chan",
|
"cosplayer:wanco chan",
|
||||||
|
"cosplayer:whimpercat",
|
||||||
"cosplayer:wifey",
|
"cosplayer:wifey",
|
||||||
"cosplayer:wildhoney423",
|
"cosplayer:wildhoney423",
|
||||||
"cosplayer:xansoon",
|
"cosplayer:xansoon",
|
||||||
"cosplayer:xia xia zi",
|
"cosplayer:xia xia zi",
|
||||||
|
"cosplayer:xiaoyao yaoyao",
|
||||||
|
"cosplayer:xiaoying shi zhi xiaomulong",
|
||||||
"cosplayer:xidaidai",
|
"cosplayer:xidaidai",
|
||||||
"cosplayer:xue qi-sama",
|
"cosplayer:xue qi-sama",
|
||||||
"cosplayer:yaki",
|
"cosplayer:yaki",
|
||||||
"cosplayer:yaokoututu",
|
"cosplayer:yaokoututu",
|
||||||
"cosplayer:yaoyaoqwq",
|
"cosplayer:yaoyaoqwq",
|
||||||
|
"cosplayer:ying lili",
|
||||||
|
"cosplayer:yoko inui",
|
||||||
"cosplayer:yor succubus",
|
"cosplayer:yor succubus",
|
||||||
"cosplayer:yorkie w",
|
"cosplayer:yorkie w",
|
||||||
|
"cosplayer:youyou",
|
||||||
"cosplayer:yuki astra",
|
"cosplayer:yuki astra",
|
||||||
|
"cosplayer:yuki lefay",
|
||||||
"cosplayer:yuki teyi",
|
"cosplayer:yuki teyi",
|
||||||
"cosplayer:yume",
|
"cosplayer:yume",
|
||||||
|
"cosplayer:yummykimmy",
|
||||||
"cosplayer:yunie lannister",
|
"cosplayer:yunie lannister",
|
||||||
"cosplayer:yunocos69",
|
"cosplayer:yunocos69",
|
||||||
"cosplayer:yurihime",
|
"cosplayer:yurihime",
|
||||||
"cosplayer:yuumeilyn",
|
"cosplayer:yuumeilyn",
|
||||||
"cosplayer:yuyunte",
|
"cosplayer:yuyunte",
|
||||||
|
"cosplayer:yuzu chan",
|
||||||
"cosplayer:yuzuki",
|
"cosplayer:yuzuki",
|
||||||
|
"cosplayer:yuzukimiiu",
|
||||||
"cosplayer:yuzupyon",
|
"cosplayer:yuzupyon",
|
||||||
"cosplayer:zara durose",
|
"cosplayer:zara durose",
|
||||||
"cosplayer:zeico",
|
"cosplayer:zeico",
|
||||||
|
"cosplayer:zhenya zhuk",
|
||||||
|
"cosplayer:zhuimingyou",
|
||||||
"cosplayer:zyunka mukhina",
|
"cosplayer:zyunka mukhina",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,9 @@ object Female : TagList {
|
|||||||
"female:big vagina",
|
"female:big vagina",
|
||||||
"female:bike shorts",
|
"female:bike shorts",
|
||||||
"female:bikini",
|
"female:bikini",
|
||||||
|
"female:bird girl",
|
||||||
"female:bisexual",
|
"female:bisexual",
|
||||||
|
"female:bite mark",
|
||||||
"female:blackmail",
|
"female:blackmail",
|
||||||
"female:blind",
|
"female:blind",
|
||||||
"female:blindfold",
|
"female:blindfold",
|
||||||
@@ -120,8 +122,10 @@ object Female : TagList {
|
|||||||
"female:cockslapping",
|
"female:cockslapping",
|
||||||
"female:collar",
|
"female:collar",
|
||||||
"female:condom",
|
"female:condom",
|
||||||
|
"female:confinement",
|
||||||
"female:conjoined",
|
"female:conjoined",
|
||||||
"female:coprophagia",
|
"female:coprophagia",
|
||||||
|
"female:corpse",
|
||||||
"female:corruption",
|
"female:corruption",
|
||||||
"female:corset",
|
"female:corset",
|
||||||
"female:cosplaying",
|
"female:cosplaying",
|
||||||
@@ -218,6 +222,7 @@ object Female : TagList {
|
|||||||
"female:frog",
|
"female:frog",
|
||||||
"female:frog girl",
|
"female:frog girl",
|
||||||
"female:frottage",
|
"female:frottage",
|
||||||
|
"female:full tour",
|
||||||
"female:full-packaged futanari",
|
"female:full-packaged futanari",
|
||||||
"female:fundoshi",
|
"female:fundoshi",
|
||||||
"female:furry",
|
"female:furry",
|
||||||
@@ -299,6 +304,7 @@ object Female : TagList {
|
|||||||
"female:kindergarten uniform",
|
"female:kindergarten uniform",
|
||||||
"female:kissing",
|
"female:kissing",
|
||||||
"female:kneepit sex",
|
"female:kneepit sex",
|
||||||
|
"female:kodomo doushi",
|
||||||
"female:kunoichi",
|
"female:kunoichi",
|
||||||
"female:lab coat",
|
"female:lab coat",
|
||||||
"female:lactation",
|
"female:lactation",
|
||||||
@@ -319,6 +325,7 @@ object Female : TagList {
|
|||||||
"female:long tongue",
|
"female:long tongue",
|
||||||
"female:low bestiality",
|
"female:low bestiality",
|
||||||
"female:low guro",
|
"female:low guro",
|
||||||
|
"female:low incest",
|
||||||
"female:low lolicon",
|
"female:low lolicon",
|
||||||
"female:low scat",
|
"female:low scat",
|
||||||
"female:low smegma",
|
"female:low smegma",
|
||||||
@@ -369,6 +376,7 @@ object Female : TagList {
|
|||||||
"female:muscle growth",
|
"female:muscle growth",
|
||||||
"female:mute",
|
"female:mute",
|
||||||
"female:nakadashi",
|
"female:nakadashi",
|
||||||
|
"female:navel birth",
|
||||||
"female:navel fuck",
|
"female:navel fuck",
|
||||||
"female:nazi",
|
"female:nazi",
|
||||||
"female:necrophilia",
|
"female:necrophilia",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ object Group : TagList {
|
|||||||
"group:008",
|
"group:008",
|
||||||
"group:0123456789",
|
"group:0123456789",
|
||||||
"group:0909",
|
"group:0909",
|
||||||
|
"group:1 equals 1ziz",
|
||||||
"group:1 slash 0 kansokujo",
|
"group:1 slash 0 kansokujo",
|
||||||
"group:1-up",
|
"group:1-up",
|
||||||
"group:10 slash 19",
|
"group:10 slash 19",
|
||||||
@@ -336,7 +337,6 @@ object Group : TagList {
|
|||||||
"group:alice-do",
|
"group:alice-do",
|
||||||
"group:alice.blood",
|
"group:alice.blood",
|
||||||
"group:alicegarden",
|
"group:alicegarden",
|
||||||
"group:aliceholic",
|
|
||||||
"group:alicemirror",
|
"group:alicemirror",
|
||||||
"group:alices house",
|
"group:alices house",
|
||||||
"group:alicesoft",
|
"group:alicesoft",
|
||||||
@@ -359,6 +359,7 @@ object Group : TagList {
|
|||||||
"group:alz-hammer",
|
"group:alz-hammer",
|
||||||
"group:am colon tiger",
|
"group:am colon tiger",
|
||||||
"group:am400",
|
"group:am400",
|
||||||
|
"group:am644",
|
||||||
"group:amaama-tei",
|
"group:amaama-tei",
|
||||||
"group:amaembo",
|
"group:amaembo",
|
||||||
"group:amagasa cycle",
|
"group:amagasa cycle",
|
||||||
@@ -380,6 +381,7 @@ object Group : TagList {
|
|||||||
"group:amanogawa tsuushin",
|
"group:amanogawa tsuushin",
|
||||||
"group:amapoteya",
|
"group:amapoteya",
|
||||||
"group:amarini senpaku",
|
"group:amarini senpaku",
|
||||||
|
"group:amaterasu tsukikage",
|
||||||
"group:amatoro bow",
|
"group:amatoro bow",
|
||||||
"group:amatosui",
|
"group:amatosui",
|
||||||
"group:amatouenpitsukezuri",
|
"group:amatouenpitsukezuri",
|
||||||
@@ -539,6 +541,7 @@ object Group : TagList {
|
|||||||
"group:arkham products team ankoku baitai",
|
"group:arkham products team ankoku baitai",
|
||||||
"group:armadillo",
|
"group:armadillo",
|
||||||
"group:armanium",
|
"group:armanium",
|
||||||
|
"group:arnest room",
|
||||||
"group:aroimark",
|
"group:aroimark",
|
||||||
"group:aroma gaeru",
|
"group:aroma gaeru",
|
||||||
"group:arsenothelus",
|
"group:arsenothelus",
|
||||||
@@ -557,6 +560,7 @@ object Group : TagList {
|
|||||||
"group:arukomu",
|
"group:arukomu",
|
||||||
"group:aruku denpatou no kai",
|
"group:aruku denpatou no kai",
|
||||||
"group:arumike",
|
"group:arumike",
|
||||||
|
"group:arumirua",
|
||||||
"group:aruto-ya",
|
"group:aruto-ya",
|
||||||
"group:arysuivery",
|
"group:arysuivery",
|
||||||
"group:asa made go-ya",
|
"group:asa made go-ya",
|
||||||
@@ -612,6 +616,7 @@ object Group : TagList {
|
|||||||
"group:at mztm",
|
"group:at mztm",
|
||||||
"group:at no 464",
|
"group:at no 464",
|
||||||
"group:at oz",
|
"group:at oz",
|
||||||
|
"group:at szkn",
|
||||||
"group:atara shindou",
|
"group:atara shindou",
|
||||||
"group:ataraxia",
|
"group:ataraxia",
|
||||||
"group:atelier d",
|
"group:atelier d",
|
||||||
@@ -709,6 +714,7 @@ object Group : TagList {
|
|||||||
"group:bakuhatsu brs.",
|
"group:bakuhatsu brs.",
|
||||||
"group:bakunyu fullnerson",
|
"group:bakunyu fullnerson",
|
||||||
"group:bakuretsu fusen",
|
"group:bakuretsu fusen",
|
||||||
|
"group:bakushu koujou",
|
||||||
"group:bakusou special",
|
"group:bakusou special",
|
||||||
"group:balgus rec",
|
"group:balgus rec",
|
||||||
"group:balklash.",
|
"group:balklash.",
|
||||||
@@ -746,6 +752,7 @@ object Group : TagList {
|
|||||||
"group:bbb-extra",
|
"group:bbb-extra",
|
||||||
"group:bbuttondash",
|
"group:bbuttondash",
|
||||||
"group:beaf emotion",
|
"group:beaf emotion",
|
||||||
|
"group:bear valley",
|
||||||
"group:beart",
|
"group:beart",
|
||||||
"group:beat-pop",
|
"group:beat-pop",
|
||||||
"group:beauty salon b and s",
|
"group:beauty salon b and s",
|
||||||
@@ -764,6 +771,7 @@ object Group : TagList {
|
|||||||
"group:beni namazu dan",
|
"group:beni namazu dan",
|
||||||
"group:benichigaya",
|
"group:benichigaya",
|
||||||
"group:beniiro kaitenkikou",
|
"group:beniiro kaitenkikou",
|
||||||
|
"group:benimaru suisan",
|
||||||
"group:benimomo dou",
|
"group:benimomo dou",
|
||||||
"group:benisuzumedo",
|
"group:benisuzumedo",
|
||||||
"group:beniya",
|
"group:beniya",
|
||||||
@@ -804,6 +812,7 @@ object Group : TagList {
|
|||||||
"group:biroon jr.",
|
"group:biroon jr.",
|
||||||
"group:biruban",
|
"group:biruban",
|
||||||
"group:bisaid label",
|
"group:bisaid label",
|
||||||
|
"group:bishamon.",
|
||||||
"group:bishou neko",
|
"group:bishou neko",
|
||||||
"group:bishoujo production",
|
"group:bishoujo production",
|
||||||
"group:bisketty",
|
"group:bisketty",
|
||||||
@@ -1083,6 +1092,7 @@ object Group : TagList {
|
|||||||
"group:chimamire yashiki",
|
"group:chimamire yashiki",
|
||||||
"group:chimatsuriya honpo",
|
"group:chimatsuriya honpo",
|
||||||
"group:chimchimteam",
|
"group:chimchimteam",
|
||||||
|
"group:chimeishou",
|
||||||
"group:chimere marie",
|
"group:chimere marie",
|
||||||
"group:chin soft",
|
"group:chin soft",
|
||||||
"group:chinasanchi",
|
"group:chinasanchi",
|
||||||
@@ -1243,6 +1253,7 @@ object Group : TagList {
|
|||||||
"group:coonelius",
|
"group:coonelius",
|
||||||
"group:copo deluxe",
|
"group:copo deluxe",
|
||||||
"group:coppo-otome",
|
"group:coppo-otome",
|
||||||
|
"group:coscoteikoku",
|
||||||
"group:cosmic-3d-angels",
|
"group:cosmic-3d-angels",
|
||||||
"group:cosplay kissa nyan nyan",
|
"group:cosplay kissa nyan nyan",
|
||||||
"group:cosplaydeviants",
|
"group:cosplaydeviants",
|
||||||
@@ -1301,6 +1312,7 @@ object Group : TagList {
|
|||||||
"group:d-ten",
|
"group:d-ten",
|
||||||
"group:d.d.d.b.",
|
"group:d.d.d.b.",
|
||||||
"group:d.n.a.lab.",
|
"group:d.n.a.lab.",
|
||||||
|
"group:d.o.",
|
||||||
"group:d2",
|
"group:d2",
|
||||||
"group:da hootch",
|
"group:da hootch",
|
||||||
"group:da pomb no tokoro",
|
"group:da pomb no tokoro",
|
||||||
@@ -1413,6 +1425,7 @@ object Group : TagList {
|
|||||||
"group:deucesworld",
|
"group:deucesworld",
|
||||||
"group:dewdrop",
|
"group:dewdrop",
|
||||||
"group:dex plus",
|
"group:dex plus",
|
||||||
|
"group:dez climax",
|
||||||
"group:dhr-ken",
|
"group:dhr-ken",
|
||||||
"group:diablo",
|
"group:diablo",
|
||||||
"group:dicpic studio",
|
"group:dicpic studio",
|
||||||
@@ -1424,6 +1437,7 @@ object Group : TagList {
|
|||||||
"group:digital graffiti",
|
"group:digital graffiti",
|
||||||
"group:digital lover",
|
"group:digital lover",
|
||||||
"group:digital tambourine",
|
"group:digital tambourine",
|
||||||
|
"group:dingiruutoushi",
|
||||||
"group:diogenes club",
|
"group:diogenes club",
|
||||||
"group:dioxin",
|
"group:dioxin",
|
||||||
"group:dirty",
|
"group:dirty",
|
||||||
@@ -1445,12 +1459,14 @@ object Group : TagList {
|
|||||||
"group:doing crew",
|
"group:doing crew",
|
||||||
"group:doisakaken",
|
"group:doisakaken",
|
||||||
"group:dojin otome",
|
"group:dojin otome",
|
||||||
|
"group:dojiro books",
|
||||||
"group:dokkoi-tori gomoku",
|
"group:dokkoi-tori gomoku",
|
||||||
"group:doku alice",
|
"group:doku alice",
|
||||||
"group:doku doku kinoko",
|
"group:doku doku kinoko",
|
||||||
"group:doku pepper",
|
"group:doku pepper",
|
||||||
"group:doku usagi tai",
|
"group:doku usagi tai",
|
||||||
"group:dokudenpa jushintei",
|
"group:dokudenpa jushintei",
|
||||||
|
"group:dokudoku ryouki garou",
|
||||||
"group:dokugiri",
|
"group:dokugiri",
|
||||||
"group:dokukinokosha",
|
"group:dokukinokosha",
|
||||||
"group:dokupan koubou",
|
"group:dokupan koubou",
|
||||||
@@ -1461,11 +1477,13 @@ object Group : TagList {
|
|||||||
"group:donaora",
|
"group:donaora",
|
||||||
"group:donburi beya",
|
"group:donburi beya",
|
||||||
"group:dondondon",
|
"group:dondondon",
|
||||||
|
"group:dongurineko",
|
||||||
"group:dont understand",
|
"group:dont understand",
|
||||||
"group:doomcomic",
|
"group:doomcomic",
|
||||||
"group:dopyunger oukoku",
|
"group:dopyunger oukoku",
|
||||||
"group:dorepooru",
|
"group:dorepooru",
|
||||||
"group:doro-coppelia",
|
"group:doro-coppelia",
|
||||||
|
"group:dorokuma kumaya",
|
||||||
"group:doronuma bunshitsu",
|
"group:doronuma bunshitsu",
|
||||||
"group:doronuma kyoudai",
|
"group:doronuma kyoudai",
|
||||||
"group:doropanda tours",
|
"group:doropanda tours",
|
||||||
@@ -1489,8 +1507,10 @@ object Group : TagList {
|
|||||||
"group:doujin mukashibanashi",
|
"group:doujin mukashibanashi",
|
||||||
"group:douke romance",
|
"group:douke romance",
|
||||||
"group:doumo sumimasen",
|
"group:doumo sumimasen",
|
||||||
|
"group:dounimo naranai nou",
|
||||||
"group:dourakuya honpo",
|
"group:dourakuya honpo",
|
||||||
"group:doushin chaya",
|
"group:doushin chaya",
|
||||||
|
"group:doushoku",
|
||||||
"group:douwa-kensetsu",
|
"group:douwa-kensetsu",
|
||||||
"group:doyondo.",
|
"group:doyondo.",
|
||||||
"group:dr.vermilion",
|
"group:dr.vermilion",
|
||||||
@@ -1533,6 +1553,7 @@ object Group : TagList {
|
|||||||
"group:earthlyparadise",
|
"group:earthlyparadise",
|
||||||
"group:easymode",
|
"group:easymode",
|
||||||
"group:ebimayo",
|
"group:ebimayo",
|
||||||
|
"group:ebiten kaido",
|
||||||
"group:ecchi na taikendan kokuhaku toukou otoko jyuku",
|
"group:ecchi na taikendan kokuhaku toukou otoko jyuku",
|
||||||
"group:ecchuu douga honpo",
|
"group:ecchuu douga honpo",
|
||||||
"group:eclair ringo tea",
|
"group:eclair ringo tea",
|
||||||
@@ -1622,6 +1643,7 @@ object Group : TagList {
|
|||||||
"group:etopi kan",
|
"group:etopi kan",
|
||||||
"group:eucalyptus house",
|
"group:eucalyptus house",
|
||||||
"group:euereuphorie",
|
"group:euereuphorie",
|
||||||
|
"group:euglena factory",
|
||||||
"group:eunospress",
|
"group:eunospress",
|
||||||
"group:everyday milk challenge",
|
"group:everyday milk challenge",
|
||||||
"group:evil aratame baroque store",
|
"group:evil aratame baroque store",
|
||||||
@@ -1647,6 +1669,7 @@ object Group : TagList {
|
|||||||
"group:fakereal",
|
"group:fakereal",
|
||||||
"group:fakers manual",
|
"group:fakers manual",
|
||||||
"group:fakestar",
|
"group:fakestar",
|
||||||
|
"group:falcon115",
|
||||||
"group:fallinmoon",
|
"group:fallinmoon",
|
||||||
"group:famous comics",
|
"group:famous comics",
|
||||||
"group:famous toons facial",
|
"group:famous toons facial",
|
||||||
@@ -1730,6 +1753,7 @@ object Group : TagList {
|
|||||||
"group:frill frill",
|
"group:frill frill",
|
||||||
"group:frontwing",
|
"group:frontwing",
|
||||||
"group:fruitsjam",
|
"group:fruitsjam",
|
||||||
|
"group:fu rairyuu",
|
||||||
"group:fuantei",
|
"group:fuantei",
|
||||||
"group:fudeoki seisakujo",
|
"group:fudeoki seisakujo",
|
||||||
"group:fuegerstef",
|
"group:fuegerstef",
|
||||||
@@ -1778,6 +1802,7 @@ object Group : TagList {
|
|||||||
"group:fururi.",
|
"group:fururi.",
|
||||||
"group:furuya",
|
"group:furuya",
|
||||||
"group:fuseimyaku",
|
"group:fuseimyaku",
|
||||||
|
"group:fusha fusha kingdom",
|
||||||
"group:fushichou no yoake",
|
"group:fushichou no yoake",
|
||||||
"group:fushinsya guilty",
|
"group:fushinsya guilty",
|
||||||
"group:fushizen doubutsu hogodantai",
|
"group:fushizen doubutsu hogodantai",
|
||||||
@@ -1829,10 +1854,12 @@ object Group : TagList {
|
|||||||
"group:gamera 8th army",
|
"group:gamera 8th army",
|
||||||
"group:gamma menia",
|
"group:gamma menia",
|
||||||
"group:gammaedge",
|
"group:gammaedge",
|
||||||
|
"group:ganbaru dou",
|
||||||
"group:gang bang comix",
|
"group:gang bang comix",
|
||||||
"group:ganmo-no-oyatsu",
|
"group:ganmo-no-oyatsu",
|
||||||
"group:ganryuu island",
|
"group:ganryuu island",
|
||||||
"group:ganso sonodaya",
|
"group:ganso sonodaya",
|
||||||
|
"group:gaoookyouryu",
|
||||||
"group:gara ayuri nisshi",
|
"group:gara ayuri nisshi",
|
||||||
"group:garage-talk",
|
"group:garage-talk",
|
||||||
"group:garahadoh",
|
"group:garahadoh",
|
||||||
@@ -1849,6 +1876,7 @@ object Group : TagList {
|
|||||||
"group:gas ketsu jinsei",
|
"group:gas ketsu jinsei",
|
||||||
"group:gasshuukoku netamekoru",
|
"group:gasshuukoku netamekoru",
|
||||||
"group:gate of xiii",
|
"group:gate of xiii",
|
||||||
|
"group:gatekeeper",
|
||||||
"group:gaton.",
|
"group:gaton.",
|
||||||
"group:gavial no sumika",
|
"group:gavial no sumika",
|
||||||
"group:gd-mechano",
|
"group:gd-mechano",
|
||||||
@@ -1870,12 +1898,14 @@ object Group : TagList {
|
|||||||
"group:general bacchus",
|
"group:general bacchus",
|
||||||
"group:genesys",
|
"group:genesys",
|
||||||
"group:genki no mizu no wakutokoro",
|
"group:genki no mizu no wakutokoro",
|
||||||
|
"group:genkin-dou souhonpo",
|
||||||
"group:genmaiya",
|
"group:genmaiya",
|
||||||
"group:genocidekiss",
|
"group:genocidekiss",
|
||||||
"group:gensancha",
|
"group:gensancha",
|
||||||
"group:gensou graphics",
|
"group:gensou graphics",
|
||||||
"group:gensou kuukan",
|
"group:gensou kuukan",
|
||||||
"group:gensou stlavus",
|
"group:gensou stlavus",
|
||||||
|
"group:gensou yakai",
|
||||||
"group:gensyokuhakoniwa",
|
"group:gensyokuhakoniwa",
|
||||||
"group:genwakukinema",
|
"group:genwakukinema",
|
||||||
"group:geregere negro",
|
"group:geregere negro",
|
||||||
@@ -1897,12 +1927,14 @@ object Group : TagList {
|
|||||||
"group:giantessfan",
|
"group:giantessfan",
|
||||||
"group:giftbell",
|
"group:giftbell",
|
||||||
"group:giftkuchen",
|
"group:giftkuchen",
|
||||||
|
"group:giga omaru",
|
||||||
"group:gigameka",
|
"group:gigameka",
|
||||||
"group:gikogakodo",
|
"group:gikogakodo",
|
||||||
"group:gin eiji",
|
"group:gin eiji",
|
||||||
"group:gin no hoshitei",
|
"group:gin no hoshitei",
|
||||||
"group:gin penguin",
|
"group:gin penguin",
|
||||||
"group:gin-ion",
|
"group:gin-ion",
|
||||||
|
"group:ginga no arakuremon",
|
||||||
"group:ginga no himitu kichi",
|
"group:ginga no himitu kichi",
|
||||||
"group:ginga-ryusei",
|
"group:ginga-ryusei",
|
||||||
"group:giniro noel",
|
"group:giniro noel",
|
||||||
@@ -1960,6 +1992,7 @@ object Group : TagList {
|
|||||||
"group:gouhouwakan",
|
"group:gouhouwakan",
|
||||||
"group:gouriki hyakkaten",
|
"group:gouriki hyakkaten",
|
||||||
"group:gouten doujou",
|
"group:gouten doujou",
|
||||||
|
"group:gozen 4-ji one call",
|
||||||
"group:gozen niji no ushigaeru",
|
"group:gozen niji no ushigaeru",
|
||||||
"group:gpen",
|
"group:gpen",
|
||||||
"group:gpx",
|
"group:gpx",
|
||||||
@@ -1969,6 +2002,9 @@ object Group : TagList {
|
|||||||
"group:gravidan",
|
"group:gravidan",
|
||||||
"group:great acta",
|
"group:great acta",
|
||||||
"group:great canyon",
|
"group:great canyon",
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getTags2(): List<String> = listOf(
|
||||||
"group:great dadan",
|
"group:great dadan",
|
||||||
"group:greatest18club",
|
"group:greatest18club",
|
||||||
"group:greatmanjuu",
|
"group:greatmanjuu",
|
||||||
@@ -2002,9 +2038,6 @@ object Group : TagList {
|
|||||||
"group:gyara cter",
|
"group:gyara cter",
|
||||||
"group:gyaran rose",
|
"group:gyaran rose",
|
||||||
"group:gyarandou",
|
"group:gyarandou",
|
||||||
)
|
|
||||||
|
|
||||||
override fun getTags2(): List<String> = listOf(
|
|
||||||
"group:gyogyou rengou",
|
"group:gyogyou rengou",
|
||||||
"group:gyokasuisin",
|
"group:gyokasuisin",
|
||||||
"group:gyokotsu kouzou",
|
"group:gyokotsu kouzou",
|
||||||
@@ -2018,6 +2051,7 @@ object Group : TagList {
|
|||||||
"group:h na hon. ya san.",
|
"group:h na hon. ya san.",
|
||||||
"group:h plus",
|
"group:h plus",
|
||||||
"group:h senshokutai",
|
"group:h senshokutai",
|
||||||
|
"group:h sparkle",
|
||||||
"group:h-m",
|
"group:h-m",
|
||||||
"group:h-na-ojisan",
|
"group:h-na-ojisan",
|
||||||
"group:h-sys.",
|
"group:h-sys.",
|
||||||
@@ -2208,6 +2242,7 @@ object Group : TagList {
|
|||||||
"group:hellfragrance",
|
"group:hellfragrance",
|
||||||
"group:hellter skelter",
|
"group:hellter skelter",
|
||||||
"group:helmet ga naosemasen",
|
"group:helmet ga naosemasen",
|
||||||
|
"group:henachoko-domei",
|
||||||
"group:hengen monogatari",
|
"group:hengen monogatari",
|
||||||
"group:henntai-shinshi",
|
"group:henntai-shinshi",
|
||||||
"group:henreikai",
|
"group:henreikai",
|
||||||
@@ -2223,6 +2258,7 @@ object Group : TagList {
|
|||||||
"group:hero hero tei",
|
"group:hero hero tei",
|
||||||
"group:hero oukoku",
|
"group:hero oukoku",
|
||||||
"group:heroes factory",
|
"group:heroes factory",
|
||||||
|
"group:herunian zokusei",
|
||||||
"group:heshi factory",
|
"group:heshi factory",
|
||||||
"group:heta no yoko zuki",
|
"group:heta no yoko zuki",
|
||||||
"group:hetalearts",
|
"group:hetalearts",
|
||||||
@@ -2250,6 +2286,7 @@ object Group : TagList {
|
|||||||
"group:high heel syndrome",
|
"group:high heel syndrome",
|
||||||
"group:high risk revolution",
|
"group:high risk revolution",
|
||||||
"group:high-octane",
|
"group:high-octane",
|
||||||
|
"group:high-rised fossil garden",
|
||||||
"group:high-soft",
|
"group:high-soft",
|
||||||
"group:high-spirit",
|
"group:high-spirit",
|
||||||
"group:highway-senmu",
|
"group:highway-senmu",
|
||||||
@@ -2315,7 +2352,7 @@ object Group : TagList {
|
|||||||
"group:hitsuji-1ban-shibori",
|
"group:hitsuji-1ban-shibori",
|
||||||
"group:hitsujin toko",
|
"group:hitsujin toko",
|
||||||
"group:hitujinoki",
|
"group:hitujinoki",
|
||||||
"group:hiyashi chuuka hajimemashita",
|
"group:hiyashi chuuka owarimashita",
|
||||||
"group:hiyoko no gekijoh",
|
"group:hiyoko no gekijoh",
|
||||||
"group:hiyosanchi",
|
"group:hiyosanchi",
|
||||||
"group:hizadati zekkouchou",
|
"group:hizadati zekkouchou",
|
||||||
@@ -2331,6 +2368,7 @@ object Group : TagList {
|
|||||||
"group:hokoushayou shingou",
|
"group:hokoushayou shingou",
|
||||||
"group:hokuroza",
|
"group:hokuroza",
|
||||||
"group:holiday school",
|
"group:holiday school",
|
||||||
|
"group:holy up",
|
||||||
"group:home not found",
|
"group:home not found",
|
||||||
"group:homepie koubou",
|
"group:homepie koubou",
|
||||||
"group:homerun chaya",
|
"group:homerun chaya",
|
||||||
@@ -2348,6 +2386,7 @@ object Group : TagList {
|
|||||||
"group:honeypie",
|
"group:honeypie",
|
||||||
"group:hong kong dou",
|
"group:hong kong dou",
|
||||||
"group:honnokimochiya",
|
"group:honnokimochiya",
|
||||||
|
"group:honpo kes",
|
||||||
"group:hontoinu",
|
"group:hontoinu",
|
||||||
"group:hook",
|
"group:hook",
|
||||||
"group:hooliganism",
|
"group:hooliganism",
|
||||||
@@ -2379,6 +2418,7 @@ object Group : TagList {
|
|||||||
"group:hotori bocchi",
|
"group:hotori bocchi",
|
||||||
"group:hotpink",
|
"group:hotpink",
|
||||||
"group:hougakuya",
|
"group:hougakuya",
|
||||||
|
"group:houjou-kun mania",
|
||||||
"group:houkago inokorigumi",
|
"group:houkago inokorigumi",
|
||||||
"group:houkago paradise",
|
"group:houkago paradise",
|
||||||
"group:houkaiseki.",
|
"group:houkaiseki.",
|
||||||
@@ -2424,6 +2464,7 @@ object Group : TagList {
|
|||||||
"group:ice to choco",
|
"group:ice to choco",
|
||||||
"group:ice-place",
|
"group:ice-place",
|
||||||
"group:ichachi",
|
"group:ichachi",
|
||||||
|
"group:ichi dollar kouka",
|
||||||
"group:ichi-kan",
|
"group:ichi-kan",
|
||||||
"group:ichigiteishi",
|
"group:ichigiteishi",
|
||||||
"group:ichigo maririn",
|
"group:ichigo maririn",
|
||||||
@@ -2507,6 +2548,7 @@ object Group : TagList {
|
|||||||
"group:intermikan",
|
"group:intermikan",
|
||||||
"group:interracial-comics",
|
"group:interracial-comics",
|
||||||
"group:intoku.info",
|
"group:intoku.info",
|
||||||
|
"group:inuchan equals land",
|
||||||
"group:inudrill.",
|
"group:inudrill.",
|
||||||
"group:inukamedou",
|
"group:inukamedou",
|
||||||
"group:inukichi club",
|
"group:inukichi club",
|
||||||
@@ -2587,12 +2629,15 @@ object Group : TagList {
|
|||||||
"group:jet-black baselarde",
|
"group:jet-black baselarde",
|
||||||
"group:jewel box",
|
"group:jewel box",
|
||||||
"group:jhk",
|
"group:jhk",
|
||||||
|
"group:jibaku mecha",
|
||||||
"group:jibaku-system",
|
"group:jibaku-system",
|
||||||
"group:jidaraku risutorante",
|
"group:jidaraku risutorante",
|
||||||
"group:jido-hikki",
|
"group:jido-hikki",
|
||||||
"group:jigen no wataridori",
|
"group:jigen no wataridori",
|
||||||
"group:jiggly girls",
|
"group:jiggly girls",
|
||||||
"group:jigizagi",
|
"group:jigizagi",
|
||||||
|
"group:jigoku no cakeya-san",
|
||||||
|
"group:jigoku no monban",
|
||||||
"group:jigoku potion",
|
"group:jigoku potion",
|
||||||
"group:jigyaku jihen",
|
"group:jigyaku jihen",
|
||||||
"group:jikan-ya",
|
"group:jikan-ya",
|
||||||
@@ -2697,6 +2742,7 @@ object Group : TagList {
|
|||||||
"group:kairoudou",
|
"group:kairoudou",
|
||||||
"group:kairyuu",
|
"group:kairyuu",
|
||||||
"group:kaisanbou",
|
"group:kaisanbou",
|
||||||
|
"group:kaitaiya",
|
||||||
"group:kaitatuku",
|
"group:kaitatuku",
|
||||||
"group:kaiteisinden",
|
"group:kaiteisinden",
|
||||||
"group:kaiten sommelier",
|
"group:kaiten sommelier",
|
||||||
@@ -2824,6 +2870,7 @@ object Group : TagList {
|
|||||||
"group:keiyou tsudanuma juku",
|
"group:keiyou tsudanuma juku",
|
||||||
"group:kemao coopercent",
|
"group:kemao coopercent",
|
||||||
"group:kemokomoya",
|
"group:kemokomoya",
|
||||||
|
"group:kemomimi-chan ya",
|
||||||
"group:kemominnosuke",
|
"group:kemominnosuke",
|
||||||
"group:kemono ekaki no kousoku 2",
|
"group:kemono ekaki no kousoku 2",
|
||||||
"group:kemono masshigura.",
|
"group:kemono masshigura.",
|
||||||
@@ -2849,6 +2896,7 @@ object Group : TagList {
|
|||||||
"group:khaos distance",
|
"group:khaos distance",
|
||||||
"group:khaos wind",
|
"group:khaos wind",
|
||||||
"group:kharisma jati",
|
"group:kharisma jati",
|
||||||
|
"group:khpn style",
|
||||||
"group:kibawomuku",
|
"group:kibawomuku",
|
||||||
"group:kichiku bansankai",
|
"group:kichiku bansankai",
|
||||||
"group:kichiku koubou",
|
"group:kichiku koubou",
|
||||||
@@ -2959,6 +3007,7 @@ object Group : TagList {
|
|||||||
"group:koge croquette",
|
"group:koge croquette",
|
||||||
"group:kogemaru tsuushinkyoku",
|
"group:kogemaru tsuushinkyoku",
|
||||||
"group:kogitune",
|
"group:kogitune",
|
||||||
|
"group:koh no atelier",
|
||||||
"group:kohagura.",
|
"group:kohagura.",
|
||||||
"group:kohau no heya",
|
"group:kohau no heya",
|
||||||
"group:kohitsujitei",
|
"group:kohitsujitei",
|
||||||
@@ -3010,6 +3059,7 @@ object Group : TagList {
|
|||||||
"group:komorikiri.",
|
"group:komorikiri.",
|
||||||
"group:komugiko 100 percent",
|
"group:komugiko 100 percent",
|
||||||
"group:kon no pencase",
|
"group:kon no pencase",
|
||||||
|
"group:konekoconnection",
|
||||||
"group:konekopan",
|
"group:konekopan",
|
||||||
"group:konekopunch",
|
"group:konekopunch",
|
||||||
"group:kongou rikisi",
|
"group:kongou rikisi",
|
||||||
@@ -3057,6 +3107,7 @@ object Group : TagList {
|
|||||||
"group:kousaien",
|
"group:kousaien",
|
||||||
"group:kousoku gurihari-tei",
|
"group:kousoku gurihari-tei",
|
||||||
"group:kousoku purin",
|
"group:kousoku purin",
|
||||||
|
"group:koutatsu dennou koushi",
|
||||||
"group:kouzaka-san to makino jimusho",
|
"group:kouzaka-san to makino jimusho",
|
||||||
"group:kouzu shoukai",
|
"group:kouzu shoukai",
|
||||||
"group:kouzuya",
|
"group:kouzuya",
|
||||||
@@ -3087,12 +3138,14 @@ object Group : TagList {
|
|||||||
"group:kumo to koumori",
|
"group:kumo to koumori",
|
||||||
"group:kumohitode of world",
|
"group:kumohitode of world",
|
||||||
"group:kumonosu",
|
"group:kumonosu",
|
||||||
|
"group:kuni gamma",
|
||||||
"group:kunkakunka teikoku",
|
"group:kunkakunka teikoku",
|
||||||
"group:kunon",
|
"group:kunon",
|
||||||
"group:kurage kyoudai",
|
"group:kurage kyoudai",
|
||||||
"group:kurahashi shoin",
|
"group:kurahashi shoin",
|
||||||
"group:kurai mori no soko de",
|
"group:kurai mori no soko de",
|
||||||
"group:kurakura-honey",
|
"group:kurakura-honey",
|
||||||
|
"group:kurasan",
|
||||||
"group:kuraudo.",
|
"group:kuraudo.",
|
||||||
"group:kureboti ufo",
|
"group:kureboti ufo",
|
||||||
"group:kurige wagyuu",
|
"group:kurige wagyuu",
|
||||||
@@ -3162,6 +3215,7 @@ object Group : TagList {
|
|||||||
"group:kuukiisu",
|
"group:kuukiisu",
|
||||||
"group:kuuronziyou",
|
"group:kuuronziyou",
|
||||||
"group:kuusou idol labo bellberry",
|
"group:kuusou idol labo bellberry",
|
||||||
|
"group:kuusou kouko gakkai",
|
||||||
"group:kuusou switch",
|
"group:kuusou switch",
|
||||||
"group:kuzuryuu",
|
"group:kuzuryuu",
|
||||||
"group:kyakuniku kanzume",
|
"group:kyakuniku kanzume",
|
||||||
@@ -3178,6 +3232,7 @@ object Group : TagList {
|
|||||||
"group:kyouken diners",
|
"group:kyouken diners",
|
||||||
"group:kyouki na shiunten",
|
"group:kyouki na shiunten",
|
||||||
"group:kyoumo spaghe",
|
"group:kyoumo spaghe",
|
||||||
|
"group:kyourakuen",
|
||||||
"group:kyoushuugata",
|
"group:kyoushuugata",
|
||||||
"group:kyuu no mon",
|
"group:kyuu no mon",
|
||||||
"group:kyuu tekki jidai",
|
"group:kyuu tekki jidai",
|
||||||
@@ -3246,6 +3301,7 @@ object Group : TagList {
|
|||||||
"group:lily heart",
|
"group:lily heart",
|
||||||
"group:lily lily rose",
|
"group:lily lily rose",
|
||||||
"group:lily-put",
|
"group:lily-put",
|
||||||
|
"group:lime green",
|
||||||
"group:limit break",
|
"group:limit break",
|
||||||
"group:limit max",
|
"group:limit max",
|
||||||
"group:limit over",
|
"group:limit over",
|
||||||
@@ -3260,6 +3316,7 @@ object Group : TagList {
|
|||||||
"group:little mantis",
|
"group:little mantis",
|
||||||
"group:little princess",
|
"group:little princess",
|
||||||
"group:littlehopper",
|
"group:littlehopper",
|
||||||
|
"group:littlepool.",
|
||||||
"group:littletail",
|
"group:littletail",
|
||||||
"group:live house",
|
"group:live house",
|
||||||
"group:lo likyo new",
|
"group:lo likyo new",
|
||||||
@@ -3274,6 +3331,7 @@ object Group : TagList {
|
|||||||
"group:lolipop complete",
|
"group:lolipop complete",
|
||||||
"group:lolitachannel",
|
"group:lolitachannel",
|
||||||
"group:longhorntrain",
|
"group:longhorntrain",
|
||||||
|
"group:longlong de cangku",
|
||||||
"group:looptheloop",
|
"group:looptheloop",
|
||||||
"group:lopet dan",
|
"group:lopet dan",
|
||||||
"group:lostscript",
|
"group:lostscript",
|
||||||
@@ -3284,6 +3342,7 @@ object Group : TagList {
|
|||||||
"group:love kitten",
|
"group:love kitten",
|
||||||
"group:love kyun maiden",
|
"group:love kyun maiden",
|
||||||
"group:love lily",
|
"group:love lily",
|
||||||
|
"group:love love craft",
|
||||||
"group:love nyanko",
|
"group:love nyanko",
|
||||||
"group:love scythe",
|
"group:love scythe",
|
||||||
"group:love shine",
|
"group:love shine",
|
||||||
@@ -3325,6 +3384,7 @@ object Group : TagList {
|
|||||||
"group:m kichibeya",
|
"group:m kichibeya",
|
||||||
"group:m plus dilore",
|
"group:m plus dilore",
|
||||||
"group:m slash k club",
|
"group:m slash k club",
|
||||||
|
"group:m-family",
|
||||||
"group:m-i-p",
|
"group:m-i-p",
|
||||||
"group:m-keifu",
|
"group:m-keifu",
|
||||||
"group:m-koujou",
|
"group:m-koujou",
|
||||||
@@ -3364,6 +3424,7 @@ object Group : TagList {
|
|||||||
"group:magono-tei",
|
"group:magono-tei",
|
||||||
"group:magudara kaihou doumei",
|
"group:magudara kaihou doumei",
|
||||||
"group:maguro bokujo",
|
"group:maguro bokujo",
|
||||||
|
"group:maguro fiction",
|
||||||
"group:maguro koubou",
|
"group:maguro koubou",
|
||||||
"group:mahiru no tsuki",
|
"group:mahiru no tsuki",
|
||||||
"group:mahiru nosora",
|
"group:mahiru nosora",
|
||||||
@@ -3417,9 +3478,11 @@ object Group : TagList {
|
|||||||
"group:manjuu x",
|
"group:manjuu x",
|
||||||
"group:manles laboratory",
|
"group:manles laboratory",
|
||||||
"group:manshin soui",
|
"group:manshin soui",
|
||||||
|
"group:mantohihi atoz",
|
||||||
"group:many menu",
|
"group:many menu",
|
||||||
"group:maokonzu",
|
"group:maokonzu",
|
||||||
"group:maple-go",
|
"group:maple-go",
|
||||||
|
"group:mappa namatta",
|
||||||
"group:mara apocalypse",
|
"group:mara apocalypse",
|
||||||
"group:marashion",
|
"group:marashion",
|
||||||
"group:marble kid",
|
"group:marble kid",
|
||||||
@@ -3431,6 +3494,7 @@ object Group : TagList {
|
|||||||
"group:marge-loop",
|
"group:marge-loop",
|
||||||
"group:maria system00",
|
"group:maria system00",
|
||||||
"group:mariana kaikou kikaku",
|
"group:mariana kaikou kikaku",
|
||||||
|
"group:marimo-ya",
|
||||||
"group:marinesapphire",
|
"group:marinesapphire",
|
||||||
"group:marionette soukou ryouhei",
|
"group:marionette soukou ryouhei",
|
||||||
"group:marireimari inochi",
|
"group:marireimari inochi",
|
||||||
@@ -3651,6 +3715,7 @@ object Group : TagList {
|
|||||||
"group:misaki shoujokei.",
|
"group:misaki shoujokei.",
|
||||||
"group:misakix megamix",
|
"group:misakix megamix",
|
||||||
"group:misin koujou",
|
"group:misin koujou",
|
||||||
|
"group:misobolo dou",
|
||||||
"group:misonodenpatou",
|
"group:misonodenpatou",
|
||||||
"group:misoyahonpo",
|
"group:misoyahonpo",
|
||||||
"group:misssail",
|
"group:misssail",
|
||||||
@@ -3697,6 +3762,7 @@ object Group : TagList {
|
|||||||
"group:mocha plus ccc",
|
"group:mocha plus ccc",
|
||||||
"group:mocha2popcorn",
|
"group:mocha2popcorn",
|
||||||
"group:mochi hasamiuchi da",
|
"group:mochi hasamiuchi da",
|
||||||
|
"group:mochi mochi bomb",
|
||||||
"group:mochi usagi",
|
"group:mochi usagi",
|
||||||
"group:mochi-ya",
|
"group:mochi-ya",
|
||||||
"group:mochimoonya",
|
"group:mochimoonya",
|
||||||
@@ -3716,8 +3782,10 @@ object Group : TagList {
|
|||||||
"group:mogura-dou",
|
"group:mogura-dou",
|
||||||
"group:mogyutto cheesecake",
|
"group:mogyutto cheesecake",
|
||||||
"group:mojibone",
|
"group:mojibone",
|
||||||
|
"group:mokkindo",
|
||||||
"group:mokkorihan",
|
"group:mokkorihan",
|
||||||
"group:mokkoubondobu",
|
"group:mokkoubondobu",
|
||||||
|
"group:mokkuafunfun",
|
||||||
"group:mokomaru suisan",
|
"group:mokomaru suisan",
|
||||||
"group:mokugyuutan",
|
"group:mokugyuutan",
|
||||||
"group:mokusa",
|
"group:mokusa",
|
||||||
@@ -3738,6 +3806,7 @@ object Group : TagList {
|
|||||||
"group:momoiro funenmono",
|
"group:momoiro funenmono",
|
||||||
"group:momoiro mimic",
|
"group:momoiro mimic",
|
||||||
"group:momoiro tanzaku",
|
"group:momoiro tanzaku",
|
||||||
|
"group:momoiro zundoko",
|
||||||
"group:momoiro-gekijyou",
|
"group:momoiro-gekijyou",
|
||||||
"group:momoiro-rip",
|
"group:momoiro-rip",
|
||||||
"group:momokamasu",
|
"group:momokamasu",
|
||||||
@@ -3787,8 +3856,8 @@ object Group : TagList {
|
|||||||
"group:morning star",
|
"group:morning star",
|
||||||
"group:morning tea.",
|
"group:morning tea.",
|
||||||
"group:morningmoon merchandising products",
|
"group:morningmoon merchandising products",
|
||||||
"group:morohei-ya",
|
|
||||||
"group:moroheiya break",
|
"group:moroheiya break",
|
||||||
|
"group:moroheiya no agata",
|
||||||
"group:morokochiffon cake",
|
"group:morokochiffon cake",
|
||||||
"group:morokosheet",
|
"group:morokosheet",
|
||||||
"group:moromi-ya",
|
"group:moromi-ya",
|
||||||
@@ -3802,6 +3871,7 @@ object Group : TagList {
|
|||||||
"group:mosoya",
|
"group:mosoya",
|
||||||
"group:mosquitone.",
|
"group:mosquitone.",
|
||||||
"group:motchie kingdom",
|
"group:motchie kingdom",
|
||||||
|
"group:motemote life",
|
||||||
"group:mothman",
|
"group:mothman",
|
||||||
"group:mou sukoshi hidari e",
|
"group:mou sukoshi hidari e",
|
||||||
"group:mouko mouretsu hasai dan",
|
"group:mouko mouretsu hasai dan",
|
||||||
@@ -3864,6 +3934,7 @@ object Group : TagList {
|
|||||||
"group:mukokoro no kumo",
|
"group:mukokoro no kumo",
|
||||||
"group:mukousharan",
|
"group:mukousharan",
|
||||||
"group:mukuchi na hakoniwa",
|
"group:mukuchi na hakoniwa",
|
||||||
|
"group:mukyou no utopia",
|
||||||
"group:mukyuu dynamic",
|
"group:mukyuu dynamic",
|
||||||
"group:mulberry",
|
"group:mulberry",
|
||||||
"group:multi media studio l.o.e.r.",
|
"group:multi media studio l.o.e.r.",
|
||||||
@@ -3934,6 +4005,9 @@ object Group : TagList {
|
|||||||
"group:nagomi-chaya",
|
"group:nagomi-chaya",
|
||||||
"group:nagomisui",
|
"group:nagomisui",
|
||||||
"group:nagomiyasan",
|
"group:nagomiyasan",
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getTags3(): List<String> = listOf(
|
||||||
"group:nagucha.",
|
"group:nagucha.",
|
||||||
"group:nagumo curry-bu",
|
"group:nagumo curry-bu",
|
||||||
"group:nagumoya",
|
"group:nagumoya",
|
||||||
@@ -3957,9 +4031,11 @@ object Group : TagList {
|
|||||||
"group:namahage-dou",
|
"group:namahage-dou",
|
||||||
"group:namahamu sando",
|
"group:namahamu sando",
|
||||||
"group:namaikichibi",
|
"group:namaikichibi",
|
||||||
|
"group:namaitati teishoku",
|
||||||
"group:namakemono sou",
|
"group:namakemono sou",
|
||||||
"group:namakura dou",
|
"group:namakura dou",
|
||||||
"group:namanecotei",
|
"group:namanecotei",
|
||||||
|
"group:namaniku aikoukai",
|
||||||
"group:namasute koubou",
|
"group:namasute koubou",
|
||||||
"group:namazuchaya",
|
"group:namazuchaya",
|
||||||
"group:nameco-soup",
|
"group:nameco-soup",
|
||||||
@@ -4005,9 +4081,6 @@ object Group : TagList {
|
|||||||
"group:nanto wachou ken",
|
"group:nanto wachou ken",
|
||||||
"group:nantoka ikitemasu",
|
"group:nantoka ikitemasu",
|
||||||
"group:nantoka suroun",
|
"group:nantoka suroun",
|
||||||
)
|
|
||||||
|
|
||||||
override fun getTags3(): List<String> = listOf(
|
|
||||||
"group:nappy",
|
"group:nappy",
|
||||||
"group:naraduke biyori",
|
"group:naraduke biyori",
|
||||||
"group:naragyogyo kumiai",
|
"group:naragyogyo kumiai",
|
||||||
@@ -4018,6 +4091,7 @@ object Group : TagList {
|
|||||||
"group:nasi-pasuya",
|
"group:nasi-pasuya",
|
||||||
"group:nasu no mono",
|
"group:nasu no mono",
|
||||||
"group:nasuan",
|
"group:nasuan",
|
||||||
|
"group:natadecoco company",
|
||||||
"group:natakuga-yuku",
|
"group:natakuga-yuku",
|
||||||
"group:natorina dou",
|
"group:natorina dou",
|
||||||
"group:natrinium",
|
"group:natrinium",
|
||||||
@@ -4120,8 +4194,10 @@ object Group : TagList {
|
|||||||
"group:nendo ningyo",
|
"group:nendo ningyo",
|
||||||
"group:nengaranenjuu",
|
"group:nengaranenjuu",
|
||||||
"group:neo maiden",
|
"group:neo maiden",
|
||||||
|
"group:neoniro",
|
||||||
"group:neruneru",
|
"group:neruneru",
|
||||||
"group:netemo sametemo",
|
"group:netemo sametemo",
|
||||||
|
"group:netorareru tamashigi no hitoshizuku",
|
||||||
"group:netsuzukeru ishiryoku",
|
"group:netsuzukeru ishiryoku",
|
||||||
"group:nettaigyo club",
|
"group:nettaigyo club",
|
||||||
"group:neutron city",
|
"group:neutron city",
|
||||||
@@ -4152,6 +4228,7 @@ object Group : TagList {
|
|||||||
"group:nighthawk",
|
"group:nighthawk",
|
||||||
"group:nightmare software",
|
"group:nightmare software",
|
||||||
"group:nigimitama no ya",
|
"group:nigimitama no ya",
|
||||||
|
"group:nihao series",
|
||||||
"group:nihatsu shika ataranai",
|
"group:nihatsu shika ataranai",
|
||||||
"group:nihon dandy",
|
"group:nihon dandy",
|
||||||
"group:nihon denga senmon gakkou",
|
"group:nihon denga senmon gakkou",
|
||||||
@@ -4168,6 +4245,7 @@ object Group : TagList {
|
|||||||
"group:nijiiro zakura",
|
"group:nijiiro zakura",
|
||||||
"group:nijinoren",
|
"group:nijinoren",
|
||||||
"group:nijiyome",
|
"group:nijiyome",
|
||||||
|
"group:niko-chan planning",
|
||||||
"group:nikomark",
|
"group:nikomark",
|
||||||
"group:nikomi omurice",
|
"group:nikomi omurice",
|
||||||
"group:nikoniko company",
|
"group:nikoniko company",
|
||||||
@@ -4323,6 +4401,7 @@ object Group : TagList {
|
|||||||
"group:obsession.",
|
"group:obsession.",
|
||||||
"group:ochanomizu mokujinkai",
|
"group:ochanomizu mokujinkai",
|
||||||
"group:ochawan",
|
"group:ochawan",
|
||||||
|
"group:ochi mono kanzume",
|
||||||
"group:ochikochitei",
|
"group:ochikochitei",
|
||||||
"group:ochikonium",
|
"group:ochikonium",
|
||||||
"group:ochimusha.",
|
"group:ochimusha.",
|
||||||
@@ -4339,6 +4418,7 @@ object Group : TagList {
|
|||||||
"group:office amagasa",
|
"group:office amagasa",
|
||||||
"group:ofuton de suyaa",
|
"group:ofuton de suyaa",
|
||||||
"group:ogeretsu-dan",
|
"group:ogeretsu-dan",
|
||||||
|
"group:ogon shinshi club",
|
||||||
"group:ogre no heya",
|
"group:ogre no heya",
|
||||||
"group:oh-banzai studio",
|
"group:oh-banzai studio",
|
||||||
"group:ohagi.",
|
"group:ohagi.",
|
||||||
@@ -4413,6 +4493,7 @@ object Group : TagList {
|
|||||||
"group:onsen",
|
"group:onsen",
|
||||||
"group:oobari doujou",
|
"group:oobari doujou",
|
||||||
"group:ookami no o",
|
"group:ookami no o",
|
||||||
|
"group:ookina gomibako",
|
||||||
"group:ookina kodomo no omocha bako",
|
"group:ookina kodomo no omocha bako",
|
||||||
"group:operating room",
|
"group:operating room",
|
||||||
"group:oppawi shitei",
|
"group:oppawi shitei",
|
||||||
@@ -4489,8 +4570,10 @@ object Group : TagList {
|
|||||||
"group:owlpop",
|
"group:owlpop",
|
||||||
"group:oxide.lab",
|
"group:oxide.lab",
|
||||||
"group:oyako donburi tei",
|
"group:oyako donburi tei",
|
||||||
|
"group:oyasumi kobe gyuu",
|
||||||
"group:ozawa kobo",
|
"group:ozawa kobo",
|
||||||
"group:p kikaku",
|
"group:p kikaku",
|
||||||
|
"group:p shoukai",
|
||||||
"group:p-collection",
|
"group:p-collection",
|
||||||
"group:p-forest",
|
"group:p-forest",
|
||||||
"group:p-pooh",
|
"group:p-pooh",
|
||||||
@@ -4632,6 +4715,7 @@ object Group : TagList {
|
|||||||
"group:pink-noise",
|
"group:pink-noise",
|
||||||
"group:pinkbell software",
|
"group:pinkbell software",
|
||||||
"group:pinkharlem",
|
"group:pinkharlem",
|
||||||
|
"group:pinki wana",
|
||||||
"group:pinktips.info",
|
"group:pinktips.info",
|
||||||
"group:pinkysoft",
|
"group:pinkysoft",
|
||||||
"group:pinpoint",
|
"group:pinpoint",
|
||||||
@@ -4689,6 +4773,7 @@ object Group : TagList {
|
|||||||
"group:ponchees kari",
|
"group:ponchees kari",
|
||||||
"group:ponkotuna potunoya",
|
"group:ponkotuna potunoya",
|
||||||
"group:ponpon-black",
|
"group:ponpon-black",
|
||||||
|
"group:ponponponpo",
|
||||||
"group:pons lab",
|
"group:pons lab",
|
||||||
"group:pony farm",
|
"group:pony farm",
|
||||||
"group:ponyfarm",
|
"group:ponyfarm",
|
||||||
@@ -4864,6 +4949,7 @@ object Group : TagList {
|
|||||||
"group:remora works",
|
"group:remora works",
|
||||||
"group:ren-kon-an",
|
"group:ren-kon-an",
|
||||||
"group:renai mangaka",
|
"group:renai mangaka",
|
||||||
|
"group:rengaworks",
|
||||||
"group:renge-dou",
|
"group:renge-dou",
|
||||||
"group:rengeza",
|
"group:rengeza",
|
||||||
"group:renglet",
|
"group:renglet",
|
||||||
@@ -4967,6 +5053,7 @@ object Group : TagList {
|
|||||||
"group:ruku-pusyu",
|
"group:ruku-pusyu",
|
||||||
"group:running girl",
|
"group:running girl",
|
||||||
"group:runrun soft",
|
"group:runrun soft",
|
||||||
|
"group:ruri-iro special room",
|
||||||
"group:ruriiro honpo",
|
"group:ruriiro honpo",
|
||||||
"group:rurirara star",
|
"group:rurirara star",
|
||||||
"group:ruruna and nimunimu",
|
"group:ruruna and nimunimu",
|
||||||
@@ -5053,6 +5140,7 @@ object Group : TagList {
|
|||||||
"group:sakuraproject",
|
"group:sakuraproject",
|
||||||
"group:sakurasaku",
|
"group:sakurasaku",
|
||||||
"group:sakurasaku koubou",
|
"group:sakurasaku koubou",
|
||||||
|
"group:sakurayakan no hanare",
|
||||||
"group:sakuryu",
|
"group:sakuryu",
|
||||||
"group:sakusaku kangen noushuku",
|
"group:sakusaku kangen noushuku",
|
||||||
"group:sakusakusakuchan",
|
"group:sakusakusakuchan",
|
||||||
@@ -5241,6 +5329,7 @@ object Group : TagList {
|
|||||||
"group:shiina club",
|
"group:shiina club",
|
||||||
"group:shiinotomoshibitake",
|
"group:shiinotomoshibitake",
|
||||||
"group:shiitake nouen",
|
"group:shiitake nouen",
|
||||||
|
"group:shijimi wari ningyou",
|
||||||
"group:shijou misaki",
|
"group:shijou misaki",
|
||||||
"group:shikakui tori",
|
"group:shikakui tori",
|
||||||
"group:shiki be careful",
|
"group:shiki be careful",
|
||||||
@@ -5274,6 +5363,7 @@ object Group : TagList {
|
|||||||
"group:shingeki no nameko",
|
"group:shingeki no nameko",
|
||||||
"group:shining star",
|
"group:shining star",
|
||||||
"group:shining star lilys",
|
"group:shining star lilys",
|
||||||
|
"group:shinise ikedaya",
|
||||||
"group:shinkirou akatsuki",
|
"group:shinkirou akatsuki",
|
||||||
"group:shinkuraiku",
|
"group:shinkuraiku",
|
||||||
"group:shinnihon pepsitou",
|
"group:shinnihon pepsitou",
|
||||||
@@ -5338,8 +5428,11 @@ object Group : TagList {
|
|||||||
"group:short kami",
|
"group:short kami",
|
||||||
"group:shortcut koubou",
|
"group:shortcut koubou",
|
||||||
"group:shosekido",
|
"group:shosekido",
|
||||||
|
"group:shota mangaya-san",
|
||||||
|
"group:shotacon-do",
|
||||||
"group:shouchuu mac",
|
"group:shouchuu mac",
|
||||||
"group:shoudansha",
|
"group:shoudansha",
|
||||||
|
"group:shougusha",
|
||||||
"group:shoujo 2-jou",
|
"group:shoujo 2-jou",
|
||||||
"group:shoujo gesshoku",
|
"group:shoujo gesshoku",
|
||||||
"group:shoujo kousaku",
|
"group:shoujo kousaku",
|
||||||
@@ -5356,6 +5449,7 @@ object Group : TagList {
|
|||||||
"group:showa saishuu sensen",
|
"group:showa saishuu sensen",
|
||||||
"group:showa shojo",
|
"group:showa shojo",
|
||||||
"group:showano",
|
"group:showano",
|
||||||
|
"group:shubi-ryoku 4man",
|
||||||
"group:shudoushiki denki jidousha",
|
"group:shudoushiki denki jidousha",
|
||||||
"group:shumi eshi",
|
"group:shumi eshi",
|
||||||
"group:shumisen jiru",
|
"group:shumisen jiru",
|
||||||
@@ -5384,6 +5478,7 @@ object Group : TagList {
|
|||||||
"group:silky to yukai na nakama-tachi",
|
"group:silky to yukai na nakama-tachi",
|
||||||
"group:silkys plus wasabi",
|
"group:silkys plus wasabi",
|
||||||
"group:silmaril",
|
"group:silmaril",
|
||||||
|
"group:silver rice",
|
||||||
"group:silver ring",
|
"group:silver ring",
|
||||||
"group:silver-kingdom",
|
"group:silver-kingdom",
|
||||||
"group:silver-rx",
|
"group:silver-rx",
|
||||||
@@ -5407,6 +5502,7 @@ object Group : TagList {
|
|||||||
"group:sirouto plan",
|
"group:sirouto plan",
|
||||||
"group:sirubedou",
|
"group:sirubedou",
|
||||||
"group:sisinabeya",
|
"group:sisinabeya",
|
||||||
|
"group:sistny and anasis",
|
||||||
"group:sittori oblaat",
|
"group:sittori oblaat",
|
||||||
"group:sketch-book",
|
"group:sketch-book",
|
||||||
"group:skid-mark",
|
"group:skid-mark",
|
||||||
@@ -5512,6 +5608,7 @@ object Group : TagList {
|
|||||||
"group:spicia",
|
"group:spicia",
|
||||||
"group:spig at",
|
"group:spig at",
|
||||||
"group:spiral brain",
|
"group:spiral brain",
|
||||||
|
"group:spiritguide",
|
||||||
"group:spock-san",
|
"group:spock-san",
|
||||||
"group:sponge empire",
|
"group:sponge empire",
|
||||||
"group:sql",
|
"group:sql",
|
||||||
@@ -5559,6 +5656,7 @@ object Group : TagList {
|
|||||||
"group:studio c-take",
|
"group:studio c-take",
|
||||||
"group:studio cardamom",
|
"group:studio cardamom",
|
||||||
"group:studio ciao",
|
"group:studio ciao",
|
||||||
|
"group:studio diamond",
|
||||||
"group:studio dna",
|
"group:studio dna",
|
||||||
"group:studio e.go",
|
"group:studio e.go",
|
||||||
"group:studio erohouse",
|
"group:studio erohouse",
|
||||||
@@ -5602,6 +5700,7 @@ object Group : TagList {
|
|||||||
"group:studio southpaw",
|
"group:studio southpaw",
|
||||||
"group:studio sunadokei",
|
"group:studio sunadokei",
|
||||||
"group:studio sushi kui-ne",
|
"group:studio sushi kui-ne",
|
||||||
|
"group:studio t.r.c.",
|
||||||
"group:studio tapa tapa",
|
"group:studio tapa tapa",
|
||||||
"group:studio wallaby",
|
"group:studio wallaby",
|
||||||
"group:studio waltz",
|
"group:studio waltz",
|
||||||
@@ -5615,6 +5714,7 @@ object Group : TagList {
|
|||||||
"group:studio30neko",
|
"group:studio30neko",
|
||||||
"group:studiomia",
|
"group:studiomia",
|
||||||
"group:studios",
|
"group:studios",
|
||||||
|
"group:stukitora",
|
||||||
"group:stulli-yasan",
|
"group:stulli-yasan",
|
||||||
"group:sturm no shukuten",
|
"group:sturm no shukuten",
|
||||||
"group:su kanchou koubou",
|
"group:su kanchou koubou",
|
||||||
@@ -5657,6 +5757,7 @@ object Group : TagList {
|
|||||||
"group:sumomo hana koushu",
|
"group:sumomo hana koushu",
|
||||||
"group:sunadokei to enpitsu",
|
"group:sunadokei to enpitsu",
|
||||||
"group:sunatoka aoi noyama",
|
"group:sunatoka aoi noyama",
|
||||||
|
"group:sunege6",
|
||||||
"group:sunezumi fauvism",
|
"group:sunezumi fauvism",
|
||||||
"group:sunora",
|
"group:sunora",
|
||||||
"group:sunsetmoon",
|
"group:sunsetmoon",
|
||||||
@@ -5766,8 +5867,10 @@ object Group : TagList {
|
|||||||
"group:tamago no kimi",
|
"group:tamago no kimi",
|
||||||
"group:tamanegiya",
|
"group:tamanegiya",
|
||||||
"group:tamatamasanmyaku",
|
"group:tamatamasanmyaku",
|
||||||
|
"group:tamima-ya",
|
||||||
"group:tamokuteki hall",
|
"group:tamokuteki hall",
|
||||||
"group:tamokuteki kuukan",
|
"group:tamokuteki kuukan",
|
||||||
|
"group:tana kara marriage",
|
||||||
"group:tanajou",
|
"group:tanajou",
|
||||||
"group:tanaka shouten",
|
"group:tanaka shouten",
|
||||||
"group:tanaura honpo",
|
"group:tanaura honpo",
|
||||||
@@ -5778,10 +5881,13 @@ object Group : TagList {
|
|||||||
"group:tanmatsu ijou",
|
"group:tanmatsu ijou",
|
||||||
"group:tanpatsu kikaku",
|
"group:tanpatsu kikaku",
|
||||||
"group:tansanshonen",
|
"group:tansanshonen",
|
||||||
|
"group:tanu-chan chi",
|
||||||
|
"group:tanukineiri",
|
||||||
"group:tarai death",
|
"group:tarai death",
|
||||||
"group:tarako koubou",
|
"group:tarako koubou",
|
||||||
"group:tarakospa",
|
"group:tarakospa",
|
||||||
"group:tarantula",
|
"group:tarantula",
|
||||||
|
"group:tarareba naraba",
|
||||||
"group:taromarun",
|
"group:taromarun",
|
||||||
"group:tashikani",
|
"group:tashikani",
|
||||||
"group:tasogare hakubutukan",
|
"group:tasogare hakubutukan",
|
||||||
@@ -5799,6 +5905,7 @@ object Group : TagList {
|
|||||||
"group:team dai 7 youhei shidan",
|
"group:team dai 7 youhei shidan",
|
||||||
"group:team hin ga 9",
|
"group:team hin ga 9",
|
||||||
"group:team ibm",
|
"group:team ibm",
|
||||||
|
"group:team lv",
|
||||||
"group:team okays",
|
"group:team okays",
|
||||||
"group:team tanabe",
|
"group:team tanabe",
|
||||||
"group:team z and 3n",
|
"group:team z and 3n",
|
||||||
@@ -5854,6 +5961,8 @@ object Group : TagList {
|
|||||||
"group:terolin soft",
|
"group:terolin soft",
|
||||||
"group:terra drive",
|
"group:terra drive",
|
||||||
"group:testa kitchen",
|
"group:testa kitchen",
|
||||||
|
"group:testme1111",
|
||||||
|
"group:tetora star gumi",
|
||||||
"group:tetorapotto bunsitu",
|
"group:tetorapotto bunsitu",
|
||||||
"group:tetrodotoxin",
|
"group:tetrodotoxin",
|
||||||
"group:tetsubou shounen",
|
"group:tetsubou shounen",
|
||||||
@@ -5866,6 +5975,7 @@ object Group : TagList {
|
|||||||
"group:th",
|
"group:th",
|
||||||
"group:th4",
|
"group:th4",
|
||||||
"group:the block buster destruction",
|
"group:the block buster destruction",
|
||||||
|
"group:the fourth sequence",
|
||||||
"group:the fuckin toyzaras",
|
"group:the fuckin toyzaras",
|
||||||
"group:the jolly roger",
|
"group:the jolly roger",
|
||||||
"group:the knight of the pants",
|
"group:the knight of the pants",
|
||||||
@@ -5898,115 +6008,5 @@ object Group : TagList {
|
|||||||
"group:tirol bunko",
|
"group:tirol bunko",
|
||||||
"group:tissuhaco",
|
"group:tissuhaco",
|
||||||
"group:titanaluminiden",
|
"group:titanaluminiden",
|
||||||
"group:titancolor brand",
|
|
||||||
"group:titeki-kairaku",
|
|
||||||
"group:titillatio",
|
|
||||||
"group:titokara 2nd branch",
|
|
||||||
"group:tits",
|
|
||||||
"group:tiusan kingdom",
|
|
||||||
"group:tj studio",
|
|
||||||
"group:tkh soft",
|
|
||||||
"group:tkspower",
|
|
||||||
"group:tnc.",
|
|
||||||
"group:tobihizageri",
|
|
||||||
"group:todd special",
|
|
||||||
"group:toei animation",
|
|
||||||
"group:togari-nozawa",
|
|
||||||
"group:tohonifun",
|
|
||||||
"group:tojora-men",
|
|
||||||
"group:tokaeshina koubou",
|
|
||||||
"group:tokai oohashi",
|
|
||||||
"group:tokinoame",
|
|
||||||
"group:toko-ya",
|
|
||||||
"group:tokohuyu no bakansu",
|
|
||||||
"group:tokonatsu tou",
|
|
||||||
"group:tokoroniyori-tengoku",
|
|
||||||
"group:tokumori ajillo",
|
|
||||||
"group:tokutan biyori",
|
|
||||||
"group:tokyo big eros",
|
|
||||||
"group:tokyo bungeling bay yokohama",
|
|
||||||
"group:tokyo corechica",
|
|
||||||
"group:tokyo gamachannel",
|
|
||||||
"group:tokyo kumitaisougumi",
|
|
||||||
"group:tokyo note",
|
|
||||||
"group:tokyo ponpon dou",
|
|
||||||
"group:tokyo rox",
|
|
||||||
"group:tokyo tomodachi kouen",
|
|
||||||
"group:tokyo tsunamushi land",
|
|
||||||
"group:tokyo-rozewomond club",
|
|
||||||
"group:tokyoboogienight",
|
|
||||||
"group:tokyusen",
|
|
||||||
"group:toluene ittokan",
|
|
||||||
"group:tomatogohan.",
|
|
||||||
"group:tomatohouse-905s room",
|
|
||||||
"group:tomatta tokei",
|
|
||||||
"group:tomcat",
|
|
||||||
"group:tomizofu",
|
|
||||||
"group:tomoe project",
|
|
||||||
"group:tomonokai",
|
|
||||||
"group:tomoshibi-ya",
|
|
||||||
"group:tomoshibiya koubou",
|
|
||||||
"group:tonari no dagashiya-san",
|
|
||||||
"group:tonari no machi no teishokuya",
|
|
||||||
"group:tonari no yama",
|
|
||||||
"group:tondemo 8 pun",
|
|
||||||
"group:tongari gorigori",
|
|
||||||
"group:tonikakuushi",
|
|
||||||
"group:tonkotsu fuumi",
|
|
||||||
"group:tonny club",
|
|
||||||
"group:tonpuuratei",
|
|
||||||
"group:tonteki teishoku",
|
|
||||||
"group:tonton byoushi",
|
|
||||||
"group:tontoro daiyokujou",
|
|
||||||
"group:tonyu bokujo",
|
|
||||||
"group:tonzura douchuu",
|
|
||||||
"group:top hat studios",
|
|
||||||
"group:toppuu dooro",
|
|
||||||
"group:toragoyashiki",
|
|
||||||
"group:toraisix",
|
|
||||||
"group:toraiya",
|
|
||||||
"group:torajirusi",
|
|
||||||
"group:torano ori",
|
|
||||||
"group:toratepotto",
|
|
||||||
"group:toratsugumi",
|
|
||||||
"group:tori salt",
|
|
||||||
"group:toriaezu kari",
|
|
||||||
"group:toridorinori",
|
|
||||||
"group:toriha dance",
|
|
||||||
"group:toriihime",
|
|
||||||
"group:torikaeshi no tsukanai sex",
|
|
||||||
"group:torino sunakimo",
|
|
||||||
"group:torinoya",
|
|
||||||
"group:toriten software studio.",
|
|
||||||
"group:toro plus drop",
|
|
||||||
"group:toro toro resistance",
|
|
||||||
"group:toro-chin teishoku",
|
|
||||||
"group:toro2 circus",
|
|
||||||
"group:torochidan",
|
|
||||||
"group:toruneko chaya",
|
|
||||||
"group:totencop",
|
|
||||||
"group:toto max",
|
|
||||||
"group:totocetera",
|
|
||||||
"group:totontei",
|
|
||||||
"group:totoyasu no tsf lab",
|
|
||||||
"group:totsugasa",
|
|
||||||
"group:totsugeki tonarino jo-galbi",
|
|
||||||
"group:tottoko mtarou",
|
|
||||||
"group:tottori-sabaku kingdom",
|
|
||||||
"group:tottototomekichi",
|
|
||||||
"group:touch",
|
|
||||||
"group:tougall kai",
|
|
||||||
"group:touge mine",
|
|
||||||
"group:tougenkyou",
|
|
||||||
"group:tougesakuraya",
|
|
||||||
"group:touhou marupondou",
|
|
||||||
"group:touin",
|
|
||||||
"group:toukon iwashikusa",
|
|
||||||
"group:toumei kousoku",
|
|
||||||
"group:toumei tsuushin",
|
|
||||||
"group:toushi ryoku kenkyuujo",
|
|
||||||
"group:toutaku tuyagadou",
|
|
||||||
"group:touyou bujutsu gakkou",
|
|
||||||
"group:touyu okiba kari",
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,124 @@ package exh.eh.tags
|
|||||||
|
|
||||||
object Group2 : TagList {
|
object Group2 : TagList {
|
||||||
override fun getTags1(): List<String> = listOf(
|
override fun getTags1(): List<String> = listOf(
|
||||||
|
"group:titancolor brand",
|
||||||
|
"group:titeki-kairaku",
|
||||||
|
"group:titillatio",
|
||||||
|
"group:titokara 2nd branch",
|
||||||
|
"group:tits",
|
||||||
|
"group:tiusan kingdom",
|
||||||
|
"group:tj studio",
|
||||||
|
"group:tk jesus",
|
||||||
|
"group:tkh soft",
|
||||||
|
"group:tkspower",
|
||||||
|
"group:tnc.",
|
||||||
|
"group:tobihizageri",
|
||||||
|
"group:todd special",
|
||||||
|
"group:toei animation",
|
||||||
|
"group:togari-nozawa",
|
||||||
|
"group:tohonifun",
|
||||||
|
"group:tojora-men",
|
||||||
|
"group:tokaeshina koubou",
|
||||||
|
"group:tokai oohashi",
|
||||||
|
"group:tokinoame",
|
||||||
|
"group:toko-ya",
|
||||||
|
"group:tokohuyu no bakansu",
|
||||||
|
"group:tokonatsu tou",
|
||||||
|
"group:tokoroniyori-tengoku",
|
||||||
|
"group:tokumori ajillo",
|
||||||
|
"group:tokushuyokujou tondenhei",
|
||||||
|
"group:tokutan biyori",
|
||||||
|
"group:tokyo big eros",
|
||||||
|
"group:tokyo bungeling bay yokohama",
|
||||||
|
"group:tokyo corechica",
|
||||||
|
"group:tokyo gamachannel",
|
||||||
|
"group:tokyo kumitaisougumi",
|
||||||
|
"group:tokyo manga kenkyuujo",
|
||||||
|
"group:tokyo note",
|
||||||
|
"group:tokyo ponpon dou",
|
||||||
|
"group:tokyo rox",
|
||||||
|
"group:tokyo tomodachi kouen",
|
||||||
|
"group:tokyo tsunamushi land",
|
||||||
|
"group:tokyo-rozewomond club",
|
||||||
|
"group:tokyoboogienight",
|
||||||
|
"group:tokyusen",
|
||||||
|
"group:toluene ittokan",
|
||||||
|
"group:tomatogohan.",
|
||||||
|
"group:tomatohouse-905s room",
|
||||||
|
"group:tomatta tokei",
|
||||||
|
"group:tomcat",
|
||||||
|
"group:tomizofu",
|
||||||
|
"group:tomoe project",
|
||||||
|
"group:tomonokai",
|
||||||
|
"group:tomoshibi-ya",
|
||||||
|
"group:tomoshibiya koubou",
|
||||||
|
"group:tonari no dagashiya-san",
|
||||||
|
"group:tonari no machi no teishokuya",
|
||||||
|
"group:tonari no yama",
|
||||||
|
"group:tondemo 8 pun",
|
||||||
|
"group:tongari gorigori",
|
||||||
|
"group:tonikakuushi",
|
||||||
|
"group:tonkotsu fuumi",
|
||||||
|
"group:tonny club",
|
||||||
|
"group:tonpuuratei",
|
||||||
|
"group:tonteki teishoku",
|
||||||
|
"group:tonton byoushi",
|
||||||
|
"group:tontoro daiyokujou",
|
||||||
|
"group:tonyu bokujo",
|
||||||
|
"group:tonzura douchuu",
|
||||||
|
"group:top hat studios",
|
||||||
|
"group:toppuu dooro",
|
||||||
|
"group:toragoyashiki",
|
||||||
|
"group:toraisix",
|
||||||
|
"group:toraiya",
|
||||||
|
"group:torajirusi",
|
||||||
|
"group:torano ori",
|
||||||
|
"group:toratepotto",
|
||||||
|
"group:toratsugumi",
|
||||||
|
"group:tori salt",
|
||||||
|
"group:toriaezu kari",
|
||||||
|
"group:toridorinori",
|
||||||
|
"group:toriha dance",
|
||||||
|
"group:toriihime",
|
||||||
|
"group:torikaeshi no tsukanai sex",
|
||||||
|
"group:torino sunakimo",
|
||||||
|
"group:torinoya",
|
||||||
|
"group:toriten software studio.",
|
||||||
|
"group:toro plus drop",
|
||||||
|
"group:toro toro resistance",
|
||||||
|
"group:toro-chin teishoku",
|
||||||
|
"group:toro2 circus",
|
||||||
|
"group:torochidan",
|
||||||
|
"group:toruneko chaya",
|
||||||
|
"group:totencop",
|
||||||
|
"group:toto max",
|
||||||
|
"group:totocetera",
|
||||||
|
"group:totontei",
|
||||||
|
"group:totoyasu no tsf lab",
|
||||||
|
"group:totsugasa",
|
||||||
|
"group:totsugeki tonarino jo-galbi",
|
||||||
|
"group:tottoko mtarou",
|
||||||
|
"group:tottori-sabaku kingdom",
|
||||||
|
"group:tottototomekichi",
|
||||||
|
"group:touch",
|
||||||
|
"group:tougall kai",
|
||||||
|
"group:touge mine",
|
||||||
|
"group:tougenkyou",
|
||||||
|
"group:tougesakuraya",
|
||||||
|
"group:touhou marupondou",
|
||||||
|
"group:touin",
|
||||||
|
"group:toukon iwashikusa",
|
||||||
|
"group:toumei kousoku",
|
||||||
|
"group:toumei tsuushin",
|
||||||
|
"group:toushi ryoku kenkyuujo",
|
||||||
|
"group:toutaku tuyagadou",
|
||||||
|
"group:touyou bujutsu gakkou",
|
||||||
|
"group:touyu okiba kari",
|
||||||
"group:touyu stand",
|
"group:touyu stand",
|
||||||
"group:touzainanboku",
|
"group:touzainanboku",
|
||||||
"group:touzoku tachi no rakuda no mure",
|
"group:touzoku tachi no rakuda no mure",
|
||||||
"group:toxic love",
|
"group:toxic love",
|
||||||
|
"group:toyamando",
|
||||||
"group:toybox",
|
"group:toybox",
|
||||||
"group:tozan bu",
|
"group:tozan bu",
|
||||||
"group:tp",
|
"group:tp",
|
||||||
@@ -55,6 +169,7 @@ object Group2 : TagList {
|
|||||||
"group:tsuredure children",
|
"group:tsuredure children",
|
||||||
"group:tsurezurezuki",
|
"group:tsurezurezuki",
|
||||||
"group:tsurikichi doumei",
|
"group:tsurikichi doumei",
|
||||||
|
"group:tsurugashima heights",
|
||||||
"group:tsurumiku",
|
"group:tsurumiku",
|
||||||
"group:tsurupeta kenkyuusho",
|
"group:tsurupeta kenkyuusho",
|
||||||
"group:tsurutasousankai",
|
"group:tsurutasousankai",
|
||||||
@@ -70,6 +185,7 @@ object Group2 : TagList {
|
|||||||
"group:tukinon bunko",
|
"group:tukinon bunko",
|
||||||
"group:tukishitahikou",
|
"group:tukishitahikou",
|
||||||
"group:tumiribbon",
|
"group:tumiribbon",
|
||||||
|
"group:tuna ozawa",
|
||||||
"group:tunacan.",
|
"group:tunacan.",
|
||||||
"group:tunadrive",
|
"group:tunadrive",
|
||||||
"group:turuvege.",
|
"group:turuvege.",
|
||||||
@@ -141,8 +257,10 @@ object Group2 : TagList {
|
|||||||
"group:uminouie",
|
"group:uminouie",
|
||||||
"group:umon paradise",
|
"group:umon paradise",
|
||||||
"group:unagi no nedoko",
|
"group:unagi no nedoko",
|
||||||
|
"group:unagineco house",
|
||||||
"group:unaginobori",
|
"group:unaginobori",
|
||||||
"group:unceder",
|
"group:unceder",
|
||||||
|
"group:uncertain field",
|
||||||
"group:unconscious",
|
"group:unconscious",
|
||||||
"group:undamesi",
|
"group:undamesi",
|
||||||
"group:undead",
|
"group:undead",
|
||||||
@@ -201,6 +319,7 @@ object Group2 : TagList {
|
|||||||
"group:uribatakebokujou",
|
"group:uribatakebokujou",
|
||||||
"group:urondou",
|
"group:urondou",
|
||||||
"group:urusai kokuen",
|
"group:urusai kokuen",
|
||||||
|
"group:uruudoshi",
|
||||||
"group:us",
|
"group:us",
|
||||||
"group:usa daioh",
|
"group:usa daioh",
|
||||||
"group:usa.k",
|
"group:usa.k",
|
||||||
@@ -218,6 +337,7 @@ object Group2 : TagList {
|
|||||||
"group:usausa",
|
"group:usausa",
|
||||||
"group:ushi ushido",
|
"group:ushi ushido",
|
||||||
"group:ushidon-ya",
|
"group:ushidon-ya",
|
||||||
|
"group:ushikani gassen",
|
||||||
"group:uso seisakusho",
|
"group:uso seisakusho",
|
||||||
"group:uso293",
|
"group:uso293",
|
||||||
"group:usotsuki house",
|
"group:usotsuki house",
|
||||||
@@ -282,6 +402,7 @@ object Group2 : TagList {
|
|||||||
"group:wankyoku canvas",
|
"group:wankyoku canvas",
|
||||||
"group:wanwandoh",
|
"group:wanwandoh",
|
||||||
"group:warabimochi",
|
"group:warabimochi",
|
||||||
|
"group:warau kado ni wa",
|
||||||
"group:waretama",
|
"group:waretama",
|
||||||
"group:warp loop",
|
"group:warp loop",
|
||||||
"group:wasa wasa",
|
"group:wasa wasa",
|
||||||
@@ -364,6 +485,7 @@ object Group2 : TagList {
|
|||||||
"group:yakisaketeishoku",
|
"group:yakisaketeishoku",
|
||||||
"group:yakisoba pants",
|
"group:yakisoba pants",
|
||||||
"group:yakisoba rengo",
|
"group:yakisoba rengo",
|
||||||
|
"group:yakitate jamaica",
|
||||||
"group:yakiubu",
|
"group:yakiubu",
|
||||||
"group:yakousei fan club",
|
"group:yakousei fan club",
|
||||||
"group:yaku 40 man sarad",
|
"group:yaku 40 man sarad",
|
||||||
@@ -380,6 +502,7 @@ object Group2 : TagList {
|
|||||||
"group:yamakawa denenhuukei",
|
"group:yamakawa denenhuukei",
|
||||||
"group:yamami no yado",
|
"group:yamami no yado",
|
||||||
"group:yamamori gohan",
|
"group:yamamori gohan",
|
||||||
|
"group:yamamoto keiji",
|
||||||
"group:yamanaka no naka",
|
"group:yamanaka no naka",
|
||||||
"group:yamanashi musume.",
|
"group:yamanashi musume.",
|
||||||
"group:yamano murao",
|
"group:yamano murao",
|
||||||
@@ -463,10 +586,12 @@ object Group2 : TagList {
|
|||||||
"group:yoyude ikemasu",
|
"group:yoyude ikemasu",
|
||||||
"group:yozorairodrops",
|
"group:yozorairodrops",
|
||||||
"group:ys company",
|
"group:ys company",
|
||||||
|
"group:yu-chu-bu",
|
||||||
"group:yu-ta.18",
|
"group:yu-ta.18",
|
||||||
"group:yu-yu-tei",
|
"group:yu-yu-tei",
|
||||||
"group:yuasa rengou",
|
"group:yuasa rengou",
|
||||||
"group:yubidou",
|
"group:yubidou",
|
||||||
|
"group:yubunecity",
|
||||||
"group:yudenakya nama-beer",
|
"group:yudenakya nama-beer",
|
||||||
"group:yudokuya",
|
"group:yudokuya",
|
||||||
"group:yuhshiki",
|
"group:yuhshiki",
|
||||||
@@ -497,6 +622,7 @@ object Group2 : TagList {
|
|||||||
"group:yumeoikyounouta",
|
"group:yumeoikyounouta",
|
||||||
"group:yumeoukoku",
|
"group:yumeoukoku",
|
||||||
"group:yunabon",
|
"group:yunabon",
|
||||||
|
"group:yuo kurokawa",
|
||||||
"group:yurayuraseyuura",
|
"group:yurayuraseyuura",
|
||||||
"group:yurei yashiki",
|
"group:yurei yashiki",
|
||||||
"group:yureika blade",
|
"group:yureika blade",
|
||||||
@@ -564,6 +690,7 @@ object Group2 : TagList {
|
|||||||
"group:zenshuu bougyo",
|
"group:zenshuu bougyo",
|
||||||
"group:zensoku zenkai.",
|
"group:zensoku zenkai.",
|
||||||
"group:zensun habaku",
|
"group:zensun habaku",
|
||||||
|
"group:zenten ukemi tomonokai",
|
||||||
"group:zenzidou kosyubenjo",
|
"group:zenzidou kosyubenjo",
|
||||||
"group:zero byte",
|
"group:zero byte",
|
||||||
"group:zero equals mono",
|
"group:zero equals mono",
|
||||||
@@ -589,6 +716,7 @@ object Group2 : TagList {
|
|||||||
"group:zugaikotsu marudashi",
|
"group:zugaikotsu marudashi",
|
||||||
"group:zundoko sperm bank",
|
"group:zundoko sperm bank",
|
||||||
"group:zurumuke taro",
|
"group:zurumuke taro",
|
||||||
|
"group:zutto mae kara darui.",
|
||||||
"group:zvizva-dan",
|
"group:zvizva-dan",
|
||||||
"group:zydan",
|
"group:zydan",
|
||||||
"group:zyulokuya",
|
"group:zyulokuya",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ object Male : TagList {
|
|||||||
"male:balljob",
|
"male:balljob",
|
||||||
"male:balls expansion",
|
"male:balls expansion",
|
||||||
"male:bandages",
|
"male:bandages",
|
||||||
|
"male:bandaid",
|
||||||
"male:bat boy",
|
"male:bat boy",
|
||||||
"male:bbm",
|
"male:bbm",
|
||||||
"male:bdsm",
|
"male:bdsm",
|
||||||
@@ -55,7 +56,9 @@ object Male : TagList {
|
|||||||
"male:big penis",
|
"male:big penis",
|
||||||
"male:bike shorts",
|
"male:bike shorts",
|
||||||
"male:bikini",
|
"male:bikini",
|
||||||
|
"male:bird boy",
|
||||||
"male:bisexual",
|
"male:bisexual",
|
||||||
|
"male:bite mark",
|
||||||
"male:blackmail",
|
"male:blackmail",
|
||||||
"male:blind",
|
"male:blind",
|
||||||
"male:blindfold",
|
"male:blindfold",
|
||||||
@@ -111,8 +114,10 @@ object Male : TagList {
|
|||||||
"male:cockslapping",
|
"male:cockslapping",
|
||||||
"male:collar",
|
"male:collar",
|
||||||
"male:condom",
|
"male:condom",
|
||||||
|
"male:confinement",
|
||||||
"male:conjoined",
|
"male:conjoined",
|
||||||
"male:coprophagia",
|
"male:coprophagia",
|
||||||
|
"male:corpse",
|
||||||
"male:corruption",
|
"male:corruption",
|
||||||
"male:corset",
|
"male:corset",
|
||||||
"male:cosplaying",
|
"male:cosplaying",
|
||||||
@@ -157,6 +162,7 @@ object Male : TagList {
|
|||||||
"male:drill hair",
|
"male:drill hair",
|
||||||
"male:drugs",
|
"male:drugs",
|
||||||
"male:drunk",
|
"male:drunk",
|
||||||
|
"male:ear fuck",
|
||||||
"male:eel",
|
"male:eel",
|
||||||
"male:eggs",
|
"male:eggs",
|
||||||
"male:electric shocks",
|
"male:electric shocks",
|
||||||
@@ -198,6 +204,7 @@ object Male : TagList {
|
|||||||
"male:frog",
|
"male:frog",
|
||||||
"male:frog boy",
|
"male:frog boy",
|
||||||
"male:frottage",
|
"male:frottage",
|
||||||
|
"male:full tour",
|
||||||
"male:fundoshi",
|
"male:fundoshi",
|
||||||
"male:furry",
|
"male:furry",
|
||||||
"male:gag",
|
"male:gag",
|
||||||
@@ -273,6 +280,7 @@ object Male : TagList {
|
|||||||
"male:kimono",
|
"male:kimono",
|
||||||
"male:kindergarten uniform",
|
"male:kindergarten uniform",
|
||||||
"male:kissing",
|
"male:kissing",
|
||||||
|
"male:kodomo doushi",
|
||||||
"male:kunoichi",
|
"male:kunoichi",
|
||||||
"male:lab coat",
|
"male:lab coat",
|
||||||
"male:lactation",
|
"male:lactation",
|
||||||
@@ -291,6 +299,7 @@ object Male : TagList {
|
|||||||
"male:long tongue",
|
"male:long tongue",
|
||||||
"male:low bestiality",
|
"male:low bestiality",
|
||||||
"male:low guro",
|
"male:low guro",
|
||||||
|
"male:low incest",
|
||||||
"male:low scat",
|
"male:low scat",
|
||||||
"male:low shotacon",
|
"male:low shotacon",
|
||||||
"male:low smegma",
|
"male:low smegma",
|
||||||
@@ -329,6 +338,7 @@ object Male : TagList {
|
|||||||
"male:multiple assjob",
|
"male:multiple assjob",
|
||||||
"male:multiple footjob",
|
"male:multiple footjob",
|
||||||
"male:multiple handjob",
|
"male:multiple handjob",
|
||||||
|
"male:multiple nipples",
|
||||||
"male:multiple orgasms",
|
"male:multiple orgasms",
|
||||||
"male:multiple penises",
|
"male:multiple penises",
|
||||||
"male:multiple straddling",
|
"male:multiple straddling",
|
||||||
@@ -336,6 +346,7 @@ object Male : TagList {
|
|||||||
"male:muscle growth",
|
"male:muscle growth",
|
||||||
"male:mute",
|
"male:mute",
|
||||||
"male:nakadashi",
|
"male:nakadashi",
|
||||||
|
"male:navel birth",
|
||||||
"male:navel fuck",
|
"male:navel fuck",
|
||||||
"male:nazi",
|
"male:nazi",
|
||||||
"male:necrophilia",
|
"male:necrophilia",
|
||||||
@@ -496,6 +507,7 @@ object Male : TagList {
|
|||||||
"male:tracksuit",
|
"male:tracksuit",
|
||||||
"male:trampling",
|
"male:trampling",
|
||||||
"male:transformation",
|
"male:transformation",
|
||||||
|
"male:transparent clothing",
|
||||||
"male:triple anal",
|
"male:triple anal",
|
||||||
"male:triple penetration",
|
"male:triple penetration",
|
||||||
"male:tube",
|
"male:tube",
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ object Mixed : TagList {
|
|||||||
"mixed:group",
|
"mixed:group",
|
||||||
"mixed:incest",
|
"mixed:incest",
|
||||||
"mixed:inseki",
|
"mixed:inseki",
|
||||||
|
"mixed:kodomo doushi",
|
||||||
|
"mixed:low incest",
|
||||||
"mixed:mmf threesome",
|
"mixed:mmf threesome",
|
||||||
"mixed:mmt threesome",
|
"mixed:mmt threesome",
|
||||||
"mixed:mtf threesome",
|
"mixed:mtf threesome",
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ object Other : TagList {
|
|||||||
override fun getTags1(): List<String> = listOf(
|
override fun getTags1(): List<String> = listOf(
|
||||||
"other:3d",
|
"other:3d",
|
||||||
"other:3d imageset",
|
"other:3d imageset",
|
||||||
"other:ai generated",
|
|
||||||
"other:already uploaded",
|
"other:already uploaded",
|
||||||
"other:anaglyph",
|
"other:anaglyph",
|
||||||
"other:animated",
|
"other:animated",
|
||||||
@@ -20,21 +19,23 @@ object Other : TagList {
|
|||||||
"other:forbidden content",
|
"other:forbidden content",
|
||||||
"other:full censorship",
|
"other:full censorship",
|
||||||
"other:full color",
|
"other:full color",
|
||||||
"other:game manual",
|
|
||||||
"other:game sprite",
|
"other:game sprite",
|
||||||
"other:goudoushi",
|
"other:goudoushi",
|
||||||
"other:hardcore",
|
"other:hardcore",
|
||||||
"other:how to",
|
"other:how to",
|
||||||
"other:incomplete",
|
"other:incomplete",
|
||||||
|
"other:kodomo only",
|
||||||
"other:missing cover",
|
"other:missing cover",
|
||||||
"other:mosaic censorship",
|
"other:mosaic censorship",
|
||||||
"other:multi-work series",
|
"other:multi-work series",
|
||||||
"other:multipanel sequence",
|
"other:multipanel sequence",
|
||||||
"other:no penetration",
|
"other:no penetration",
|
||||||
|
"other:non-h game manual",
|
||||||
"other:non-h imageset",
|
"other:non-h imageset",
|
||||||
"other:non-nude",
|
"other:non-nude",
|
||||||
"other:novel",
|
"other:novel",
|
||||||
"other:nudity only",
|
"other:nudity only",
|
||||||
|
"other:object insertion only",
|
||||||
"other:out of order",
|
"other:out of order",
|
||||||
"other:paperchild",
|
"other:paperchild",
|
||||||
"other:realporn",
|
"other:realporn",
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ object Parody : TagList {
|
|||||||
"parody:a vampyre story",
|
"parody:a vampyre story",
|
||||||
"parody:a.d.police",
|
"parody:a.d.police",
|
||||||
"parody:a.i. ga tomaranai",
|
"parody:a.i. ga tomaranai",
|
||||||
|
"parody:abashiri ikka",
|
||||||
"parody:abenobashi mahou shoutengai",
|
"parody:abenobashi mahou shoutengai",
|
||||||
"parody:acca 13-ku kansatsu-ka",
|
"parody:acca 13-ku kansatsu-ka",
|
||||||
"parody:accel world",
|
"parody:accel world",
|
||||||
@@ -243,7 +244,6 @@ object Parody : TagList {
|
|||||||
"parody:battle royale",
|
"parody:battle royale",
|
||||||
"parody:battle spirits",
|
"parody:battle spirits",
|
||||||
"parody:beast wars",
|
"parody:beast wars",
|
||||||
"parody:beat angel escalayer",
|
|
||||||
"parody:beat blades haruka",
|
"parody:beat blades haruka",
|
||||||
"parody:beatmania",
|
"parody:beatmania",
|
||||||
"parody:beauty and the beast",
|
"parody:beauty and the beast",
|
||||||
@@ -348,6 +348,7 @@ object Parody : TagList {
|
|||||||
"parody:burst angel",
|
"parody:burst angel",
|
||||||
"parody:busou renkin",
|
"parody:busou renkin",
|
||||||
"parody:busou shoujo machiavellianism",
|
"parody:busou shoujo machiavellianism",
|
||||||
|
"parody:buta no gotoki",
|
||||||
"parody:buzz lightyear of star command",
|
"parody:buzz lightyear of star command",
|
||||||
"parody:c cube",
|
"parody:c cube",
|
||||||
"parody:c the money of soul and possibility control",
|
"parody:c the money of soul and possibility control",
|
||||||
@@ -382,18 +383,21 @@ object Parody : TagList {
|
|||||||
"parody:childs play",
|
"parody:childs play",
|
||||||
"parody:chio-chan no tsuugakuro",
|
"parody:chio-chan no tsuugakuro",
|
||||||
"parody:chip n dale rescue rangers",
|
"parody:chip n dale rescue rangers",
|
||||||
|
"parody:chiyu mahou no machigatta tsukaikata",
|
||||||
"parody:cho aniki",
|
"parody:cho aniki",
|
||||||
"parody:chobits",
|
"parody:chobits",
|
||||||
"parody:chogattai majutsu robot ginguiser",
|
"parody:chogattai majutsu robot ginguiser",
|
||||||
"parody:chokotto sister",
|
"parody:chokotto sister",
|
||||||
"parody:chou dokyuu shoujo 4946",
|
"parody:chou dokyuu shoujo 4946",
|
||||||
"parody:chou kuse ni narisou",
|
"parody:chou kuse ni narisou",
|
||||||
|
"parody:chou-tantei jikenbo rain code",
|
||||||
"parody:choudenshi bioman",
|
"parody:choudenshi bioman",
|
||||||
"parody:chouja raideen",
|
"parody:chouja raideen",
|
||||||
"parody:choujikuu kidan southern cross",
|
"parody:choujikuu kidan southern cross",
|
||||||
"parody:choujin koukousei-tachi wa isekai demo yoyuu de ikinuku you desu",
|
"parody:choujin koukousei-tachi wa isekai demo yoyuu de ikinuku you desu",
|
||||||
"parody:choujuu kishin dancougar",
|
"parody:choujuu kishin dancougar",
|
||||||
"parody:choukou shinki ixseal",
|
"parody:choukou shinki ixseal",
|
||||||
|
"parody:choukou tenshi escalayer",
|
||||||
"parody:chronicles of the going home club",
|
"parody:chronicles of the going home club",
|
||||||
"parody:chrono cross",
|
"parody:chrono cross",
|
||||||
"parody:chrono crusade",
|
"parody:chrono crusade",
|
||||||
@@ -554,6 +558,7 @@ object Parody : TagList {
|
|||||||
"parody:dororon enma-kun",
|
"parody:dororon enma-kun",
|
||||||
"parody:dosanko gal wa namaramenkoi",
|
"parody:dosanko gal wa namaramenkoi",
|
||||||
"parody:doubutsu banchou",
|
"parody:doubutsu banchou",
|
||||||
|
"parody:doubutsu nee-chan",
|
||||||
"parody:doubutsu no oishasan",
|
"parody:doubutsu no oishasan",
|
||||||
"parody:doukyuusei 2",
|
"parody:doukyuusei 2",
|
||||||
"parody:douluo continent",
|
"parody:douluo continent",
|
||||||
@@ -565,6 +570,7 @@ object Parody : TagList {
|
|||||||
"parody:dragon age",
|
"parody:dragon age",
|
||||||
"parody:dragon ball",
|
"parody:dragon ball",
|
||||||
"parody:dragon ball gt",
|
"parody:dragon ball gt",
|
||||||
|
"parody:dragon ball heroes",
|
||||||
"parody:dragon ball super",
|
"parody:dragon ball super",
|
||||||
"parody:dragon ball z",
|
"parody:dragon ball z",
|
||||||
"parody:dragon half",
|
"parody:dragon half",
|
||||||
@@ -628,6 +634,7 @@ object Parody : TagList {
|
|||||||
"parody:elemental gelade",
|
"parody:elemental gelade",
|
||||||
"parody:elf-san wa yaserarenai.",
|
"parody:elf-san wa yaserarenai.",
|
||||||
"parody:elfen lied",
|
"parody:elfen lied",
|
||||||
|
"parody:elfquest",
|
||||||
"parody:emma a victorian romance",
|
"parody:emma a victorian romance",
|
||||||
"parody:endless frontier",
|
"parody:endless frontier",
|
||||||
"parody:enen no shouboutai",
|
"parody:enen no shouboutai",
|
||||||
@@ -705,12 +712,14 @@ object Parody : TagList {
|
|||||||
"parody:final romance",
|
"parody:final romance",
|
||||||
"parody:fire emblem",
|
"parody:fire emblem",
|
||||||
"parody:fire emblem awakening",
|
"parody:fire emblem awakening",
|
||||||
|
"parody:fire emblem fates",
|
||||||
"parody:fire emblem gaiden",
|
"parody:fire emblem gaiden",
|
||||||
"parody:fire emblem if",
|
"parody:fire emblem genealogy of the holy war",
|
||||||
"parody:fire emblem mystery of the emblem",
|
"parody:fire emblem mystery of the emblem",
|
||||||
"parody:fire emblem path of radiance",
|
"parody:fire emblem path of radiance",
|
||||||
"parody:fire emblem radiant dawn",
|
"parody:fire emblem radiant dawn",
|
||||||
"parody:fire emblem rekka no ken",
|
"parody:fire emblem the binding blade",
|
||||||
|
"parody:fire emblem the blazing blade",
|
||||||
"parody:fire emblem the sacred stones",
|
"parody:fire emblem the sacred stones",
|
||||||
"parody:fire emblem three houses",
|
"parody:fire emblem three houses",
|
||||||
"parody:fist of the north star",
|
"parody:fist of the north star",
|
||||||
@@ -773,6 +782,7 @@ object Parody : TagList {
|
|||||||
"parody:gakkou gurashi",
|
"parody:gakkou gurashi",
|
||||||
"parody:gakkou no kaidan",
|
"parody:gakkou no kaidan",
|
||||||
"parody:gakuen alice",
|
"parody:gakuen alice",
|
||||||
|
"parody:gakuen babysitters",
|
||||||
"parody:gakuen heaven",
|
"parody:gakuen heaven",
|
||||||
"parody:gakusen toshi asterisk",
|
"parody:gakusen toshi asterisk",
|
||||||
"parody:galactic drifter vifam",
|
"parody:galactic drifter vifam",
|
||||||
@@ -807,6 +817,7 @@ object Parody : TagList {
|
|||||||
"parody:genroh",
|
"parody:genroh",
|
||||||
"parody:genshiken",
|
"parody:genshiken",
|
||||||
"parody:genshin impact",
|
"parody:genshin impact",
|
||||||
|
"parody:gensou suikoden",
|
||||||
"parody:getbackers",
|
"parody:getbackers",
|
||||||
"parody:getsumen to heiki mina",
|
"parody:getsumen to heiki mina",
|
||||||
"parody:getter robo",
|
"parody:getter robo",
|
||||||
@@ -830,6 +841,7 @@ object Parody : TagList {
|
|||||||
"parody:gochuumon wa usagi desu ka",
|
"parody:gochuumon wa usagi desu ka",
|
||||||
"parody:god eater",
|
"parody:god eater",
|
||||||
"parody:god of war",
|
"parody:god of war",
|
||||||
|
"parody:goddess of victory nikke",
|
||||||
"parody:gogo sentai boukenger",
|
"parody:gogo sentai boukenger",
|
||||||
"parody:gokudou-kun manyuuki",
|
"parody:gokudou-kun manyuuki",
|
||||||
"parody:gokujou seitokai",
|
"parody:gokujou seitokai",
|
||||||
@@ -839,6 +851,7 @@ object Parody : TagList {
|
|||||||
"parody:golden sun",
|
"parody:golden sun",
|
||||||
"parody:goldfish warning",
|
"parody:goldfish warning",
|
||||||
"parody:goof troop",
|
"parody:goof troop",
|
||||||
|
"parody:gormiti",
|
||||||
"parody:gosenzo san-e",
|
"parody:gosenzo san-e",
|
||||||
"parody:goshujin-sama to kemonomimi no shoujo mel",
|
"parody:goshujin-sama to kemonomimi no shoujo mel",
|
||||||
"parody:goshuushou-sama ninomiya-kun",
|
"parody:goshuushou-sama ninomiya-kun",
|
||||||
@@ -911,12 +924,14 @@ object Parody : TagList {
|
|||||||
"parody:hakushon daimaou",
|
"parody:hakushon daimaou",
|
||||||
"parody:half-life",
|
"parody:half-life",
|
||||||
"parody:halo",
|
"parody:halo",
|
||||||
|
"parody:hametsu no oukoku",
|
||||||
"parody:hamtaro",
|
"parody:hamtaro",
|
||||||
"parody:hana no joshi announcer newscaster etsuko",
|
"parody:hana no joshi announcer newscaster etsuko",
|
||||||
"parody:hanamaru youchien",
|
"parody:hanamaru youchien",
|
||||||
"parody:hanasaku iroha",
|
"parody:hanasaku iroha",
|
||||||
"parody:hanaukyo maid tai",
|
"parody:hanaukyo maid tai",
|
||||||
"parody:hand maid may",
|
"parody:hand maid may",
|
||||||
|
"parody:hantsu x trash",
|
||||||
"parody:hanzasky",
|
"parody:hanzasky",
|
||||||
"parody:happiness",
|
"parody:happiness",
|
||||||
"parody:happinesscharge precure",
|
"parody:happinesscharge precure",
|
||||||
@@ -932,11 +947,13 @@ object Parody : TagList {
|
|||||||
"parody:hataage kemono michi",
|
"parody:hataage kemono michi",
|
||||||
"parody:hataraku onii-san",
|
"parody:hataraku onii-san",
|
||||||
"parody:hataraku saibou",
|
"parody:hataraku saibou",
|
||||||
|
"parody:hatena no tou",
|
||||||
"parody:hateshinaku aoi kono sora no shita de...",
|
"parody:hateshinaku aoi kono sora no shita de...",
|
||||||
"parody:hatsukoi limited",
|
"parody:hatsukoi limited",
|
||||||
"parody:hayate no gotoku",
|
"parody:hayate no gotoku",
|
||||||
"parody:hayate x blade",
|
"parody:hayate x blade",
|
||||||
"parody:hazun de catch",
|
"parody:hazun de catch",
|
||||||
|
"parody:hazure waku",
|
||||||
"parody:he is my master",
|
"parody:he is my master",
|
||||||
"parody:he-man and the masters of the universe",
|
"parody:he-man and the masters of the universe",
|
||||||
"parody:heartcatch precure",
|
"parody:heartcatch precure",
|
||||||
@@ -969,6 +986,7 @@ object Parody : TagList {
|
|||||||
"parody:hime kishi lilia",
|
"parody:hime kishi lilia",
|
||||||
"parody:hime-chans ribbon",
|
"parody:hime-chans ribbon",
|
||||||
"parody:himegoto",
|
"parody:himegoto",
|
||||||
|
"parody:himiko-den",
|
||||||
"parody:himitsu no akko-chan",
|
"parody:himitsu no akko-chan",
|
||||||
"parody:himitsu sentai metamor v",
|
"parody:himitsu sentai metamor v",
|
||||||
"parody:hinabita",
|
"parody:hinabita",
|
||||||
@@ -1004,6 +1022,7 @@ object Parody : TagList {
|
|||||||
"parody:how the grinch stole christmas",
|
"parody:how the grinch stole christmas",
|
||||||
"parody:how to train your dragon",
|
"parody:how to train your dragon",
|
||||||
"parody:howls moving castle",
|
"parody:howls moving castle",
|
||||||
|
"parody:hp himepara",
|
||||||
"parody:hugtto precure",
|
"parody:hugtto precure",
|
||||||
"parody:hulu xiongdi",
|
"parody:hulu xiongdi",
|
||||||
"parody:hunter x hunter",
|
"parody:hunter x hunter",
|
||||||
@@ -1092,6 +1111,7 @@ object Parody : TagList {
|
|||||||
"parody:jewelpet tinkle",
|
"parody:jewelpet tinkle",
|
||||||
"parody:jibaku shounen hanako-kun",
|
"parody:jibaku shounen hanako-kun",
|
||||||
"parody:jigoku shoujo",
|
"parody:jigoku shoujo",
|
||||||
|
"parody:jiisan baasan wakagaeru",
|
||||||
"parody:jijou wo shiranai tenkousei ga guigui kuru.",
|
"parody:jijou wo shiranai tenkousei ga guigui kuru.",
|
||||||
"parody:jikkyou powerful pro yakyuu",
|
"parody:jikkyou powerful pro yakyuu",
|
||||||
"parody:jikuu senshi spielban",
|
"parody:jikuu senshi spielban",
|
||||||
@@ -1142,6 +1162,7 @@ object Parody : TagList {
|
|||||||
"parody:kageki shojo",
|
"parody:kageki shojo",
|
||||||
"parody:kagihime monogatari eikyuu alice rondo",
|
"parody:kagihime monogatari eikyuu alice rondo",
|
||||||
"parody:kagura reimeiki",
|
"parody:kagura reimeiki",
|
||||||
|
"parody:kagurabachi",
|
||||||
"parody:kaguya-sama wa kokurasetai",
|
"parody:kaguya-sama wa kokurasetai",
|
||||||
"parody:kaichou wa maid-sama",
|
"parody:kaichou wa maid-sama",
|
||||||
"parody:kaifuku jutsushi no yarinaoshi",
|
"parody:kaifuku jutsushi no yarinaoshi",
|
||||||
@@ -1187,12 +1208,15 @@ object Parody : TagList {
|
|||||||
"parody:kappa no kaikata",
|
"parody:kappa no kaikata",
|
||||||
"parody:kara no kyoukai",
|
"parody:kara no kyoukai",
|
||||||
"parody:kara no naka no kotori",
|
"parody:kara no naka no kotori",
|
||||||
|
"parody:karakai jouzu no takagi-san",
|
||||||
"parody:karakuri kiden",
|
"parody:karakuri kiden",
|
||||||
"parody:kare kano",
|
"parody:kare kano",
|
||||||
"parody:kashimashi",
|
"parody:kashimashi",
|
||||||
"parody:kasumin",
|
"parody:kasumin",
|
||||||
"parody:katawa shoujo",
|
"parody:katawa shoujo",
|
||||||
"parody:katekyo hitman reborn",
|
"parody:katekyo hitman reborn",
|
||||||
|
"parody:katri girl of the meadows",
|
||||||
|
"parody:katsute kami datta kemono-tachi e",
|
||||||
"parody:katsute mahou shoujo to aku wa tekitai shite ita.",
|
"parody:katsute mahou shoujo to aku wa tekitai shite ita.",
|
||||||
"parody:katte ni kaizou",
|
"parody:katte ni kaizou",
|
||||||
"parody:kawaii dake ja nai shikimori-san",
|
"parody:kawaii dake ja nai shikimori-san",
|
||||||
@@ -1293,6 +1317,7 @@ object Parody : TagList {
|
|||||||
"parody:kozure ookami",
|
"parody:kozure ookami",
|
||||||
"parody:kubo-san wa mob o yurusanai",
|
"parody:kubo-san wa mob o yurusanai",
|
||||||
"parody:kumo desu ga nani ka",
|
"parody:kumo desu ga nani ka",
|
||||||
|
"parody:kung fu cooking girls",
|
||||||
"parody:kung fu panda",
|
"parody:kung fu panda",
|
||||||
"parody:kunoichi",
|
"parody:kunoichi",
|
||||||
"parody:kuon no kizuna",
|
"parody:kuon no kizuna",
|
||||||
@@ -1394,6 +1419,8 @@ object Parody : TagList {
|
|||||||
"parody:lupin iii",
|
"parody:lupin iii",
|
||||||
"parody:lux-pain",
|
"parody:lux-pain",
|
||||||
"parody:lv1 maou to one room yuusha",
|
"parody:lv1 maou to one room yuusha",
|
||||||
|
"parody:lv2 kara cheat datta motoyuusha kouho no mattari isekai life",
|
||||||
|
"parody:lydie and suelle no atelier",
|
||||||
"parody:mabinogi",
|
"parody:mabinogi",
|
||||||
"parody:macademi wasshoi",
|
"parody:macademi wasshoi",
|
||||||
"parody:machikado mazoku",
|
"parody:machikado mazoku",
|
||||||
@@ -1458,10 +1485,12 @@ object Parody : TagList {
|
|||||||
"parody:makai kishi ingrid",
|
"parody:makai kishi ingrid",
|
||||||
"parody:makai tenshi jibril",
|
"parody:makai tenshi jibril",
|
||||||
"parody:makai toushi saga",
|
"parody:makai toushi saga",
|
||||||
|
"parody:make heroine ga oosugiru",
|
||||||
"parody:maken-ki",
|
"parody:maken-ki",
|
||||||
"parody:makyou gaiden le deus",
|
"parody:makyou gaiden le deus",
|
||||||
"parody:mama is a 4th grader",
|
"parody:mama is a 4th grader",
|
||||||
"parody:mama wa poyopoyo saurus ga osuki",
|
"parody:mama wa poyopoyo saurus ga osuki",
|
||||||
|
"parody:mamahaha no tsurego ga motokano datta",
|
||||||
"parody:mamono musume zukan",
|
"parody:mamono musume zukan",
|
||||||
"parody:mamoru-kun",
|
"parody:mamoru-kun",
|
||||||
"parody:mamoru-kun ni megami no shukufuku wo",
|
"parody:mamoru-kun ni megami no shukufuku wo",
|
||||||
@@ -1471,6 +1500,7 @@ object Parody : TagList {
|
|||||||
"parody:mangaka-san to assistant-san to",
|
"parody:mangaka-san to assistant-san to",
|
||||||
"parody:manyuu hikenchou",
|
"parody:manyuu hikenchou",
|
||||||
"parody:maou gakuin no futekigousha",
|
"parody:maou gakuin no futekigousha",
|
||||||
|
"parody:maou no ore ga dorei elf o yome ni shitanda ga dou medereba ii",
|
||||||
"parody:maou to ore no hangyakuki",
|
"parody:maou to ore no hangyakuki",
|
||||||
"parody:maoujou de oyasumi",
|
"parody:maoujou de oyasumi",
|
||||||
"parody:maoyuu maou yuusha",
|
"parody:maoyuu maou yuusha",
|
||||||
@@ -1520,6 +1550,7 @@ object Parody : TagList {
|
|||||||
"parody:megami paradise",
|
"parody:megami paradise",
|
||||||
"parody:megami-ryou no ryoubo-kun.",
|
"parody:megami-ryou no ryoubo-kun.",
|
||||||
"parody:megamind",
|
"parody:megamind",
|
||||||
|
"parody:mehime no toriko",
|
||||||
"parody:meiken lassie",
|
"parody:meiken lassie",
|
||||||
"parody:meili xinshijie i",
|
"parody:meili xinshijie i",
|
||||||
"parody:melon-chan no seichouki",
|
"parody:melon-chan no seichouki",
|
||||||
@@ -1611,6 +1642,7 @@ object Parody : TagList {
|
|||||||
"parody:my life as a teenage robot",
|
"parody:my life as a teenage robot",
|
||||||
"parody:my little pony friendship is magic",
|
"parody:my little pony friendship is magic",
|
||||||
"parody:my neighbor totoro",
|
"parody:my neighbor totoro",
|
||||||
|
"parody:my wife is a demon queen",
|
||||||
"parody:myriad colors phantom world",
|
"parody:myriad colors phantom world",
|
||||||
"parody:myst",
|
"parody:myst",
|
||||||
"parody:na lesnoy trope",
|
"parody:na lesnoy trope",
|
||||||
@@ -1679,6 +1711,7 @@ object Parody : TagList {
|
|||||||
"parody:nogizaka haruka no himitsu",
|
"parody:nogizaka haruka no himitsu",
|
||||||
"parody:non anonymous instruction",
|
"parody:non anonymous instruction",
|
||||||
"parody:non non biyori",
|
"parody:non non biyori",
|
||||||
|
"parody:nora to toki no koubou kiri no mori no majo",
|
||||||
"parody:nozoki ana",
|
"parody:nozoki ana",
|
||||||
"parody:nurarihyon no mago",
|
"parody:nurarihyon no mago",
|
||||||
"parody:nurse angel ririka sos",
|
"parody:nurse angel ririka sos",
|
||||||
@@ -1733,7 +1766,9 @@ object Parody : TagList {
|
|||||||
"parody:ookiku furikabutte",
|
"parody:ookiku furikabutte",
|
||||||
"parody:oounabara to wadanohara",
|
"parody:oounabara to wadanohara",
|
||||||
"parody:ooyasan wa shishunki",
|
"parody:ooyasan wa shishunki",
|
||||||
|
"parody:operators side",
|
||||||
"parody:ore dake haireru kakushi dungeon",
|
"parody:ore dake haireru kakushi dungeon",
|
||||||
|
"parody:ore ga suki nano wa imouto dakedo imouto ja nai",
|
||||||
"parody:ore monogatari",
|
"parody:ore monogatari",
|
||||||
"parody:ore no imouto ga konna ni kawaii wake ga nai",
|
"parody:ore no imouto ga konna ni kawaii wake ga nai",
|
||||||
"parody:ore no kanojo to osananajimi ga shuraba sugiru",
|
"parody:ore no kanojo to osananajimi ga shuraba sugiru",
|
||||||
@@ -1894,6 +1929,9 @@ object Parody : TagList {
|
|||||||
"parody:resident evil",
|
"parody:resident evil",
|
||||||
"parody:resonance of fate",
|
"parody:resonance of fate",
|
||||||
"parody:ressha sentai toqger",
|
"parody:ressha sentai toqger",
|
||||||
|
"parody:return to shironagasu island",
|
||||||
|
"parody:revelation online",
|
||||||
|
"parody:reverse 1999",
|
||||||
"parody:revevolution",
|
"parody:revevolution",
|
||||||
"parody:revolutionary girl utena",
|
"parody:revolutionary girl utena",
|
||||||
"parody:rewrite",
|
"parody:rewrite",
|
||||||
@@ -1941,6 +1979,7 @@ object Parody : TagList {
|
|||||||
"parody:saenai heroine no sodatekata",
|
"parody:saenai heroine no sodatekata",
|
||||||
"parody:saga frontier",
|
"parody:saga frontier",
|
||||||
"parody:saijaku muhai no bahamut",
|
"parody:saijaku muhai no bahamut",
|
||||||
|
"parody:saijaku tamer wa gomi hiroi no tabi o hajimemashita.",
|
||||||
"parody:saijou no meii",
|
"parody:saijou no meii",
|
||||||
"parody:saikano",
|
"parody:saikano",
|
||||||
"parody:saikin yatotta maid ga ayashii",
|
"parody:saikin yatotta maid ga ayashii",
|
||||||
@@ -1963,6 +2002,9 @@ object Parody : TagList {
|
|||||||
"parody:samurai 7",
|
"parody:samurai 7",
|
||||||
"parody:samurai champloo",
|
"parody:samurai champloo",
|
||||||
"parody:samurai pizza cats",
|
"parody:samurai pizza cats",
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getTags2(): List<String> = listOf(
|
||||||
"parody:samurai sentai shinkenger",
|
"parody:samurai sentai shinkenger",
|
||||||
"parody:samurai spirits",
|
"parody:samurai spirits",
|
||||||
"parody:samurai warriors",
|
"parody:samurai warriors",
|
||||||
@@ -1989,6 +2031,7 @@ object Parody : TagList {
|
|||||||
"parody:scott pilgrim",
|
"parody:scott pilgrim",
|
||||||
"parody:scp foundation",
|
"parody:scp foundation",
|
||||||
"parody:sd gundam sangokuden",
|
"parody:sd gundam sangokuden",
|
||||||
|
"parody:seer",
|
||||||
"parody:sei juushi bismark",
|
"parody:sei juushi bismark",
|
||||||
"parody:sei senshi yariman 12",
|
"parody:sei senshi yariman 12",
|
||||||
"parody:seijo no maryoku wa bannou desu",
|
"parody:seijo no maryoku wa bannou desu",
|
||||||
@@ -2002,9 +2045,6 @@ object Parody : TagList {
|
|||||||
"parody:seirei no moribito",
|
"parody:seirei no moribito",
|
||||||
"parody:seishoujo sentai lakers",
|
"parody:seishoujo sentai lakers",
|
||||||
"parody:seishun buta yarou wa bunny girl senpai no yume o minai",
|
"parody:seishun buta yarou wa bunny girl senpai no yume o minai",
|
||||||
)
|
|
||||||
|
|
||||||
override fun getTags2(): List<String> = listOf(
|
|
||||||
"parody:seito kaichou hikaru",
|
"parody:seito kaichou hikaru",
|
||||||
"parody:seitokai no ichizon",
|
"parody:seitokai no ichizon",
|
||||||
"parody:seitokai yakuindomo",
|
"parody:seitokai yakuindomo",
|
||||||
@@ -2185,6 +2225,7 @@ object Parody : TagList {
|
|||||||
"parody:star wars",
|
"parody:star wars",
|
||||||
"parody:star-myu",
|
"parody:star-myu",
|
||||||
"parody:starcraft",
|
"parody:starcraft",
|
||||||
|
"parody:stargate",
|
||||||
"parody:starry sky",
|
"parody:starry sky",
|
||||||
"parody:station memories",
|
"parody:station memories",
|
||||||
"parody:steam detectives",
|
"parody:steam detectives",
|
||||||
@@ -2199,7 +2240,6 @@ object Parody : TagList {
|
|||||||
"parody:strike witches",
|
"parody:strike witches",
|
||||||
"parody:sucker punch",
|
"parody:sucker punch",
|
||||||
"parody:suigetsu",
|
"parody:suigetsu",
|
||||||
"parody:suikoden",
|
|
||||||
"parody:suikoden v",
|
"parody:suikoden v",
|
||||||
"parody:suisei no gargantia",
|
"parody:suisei no gargantia",
|
||||||
"parody:suite precure",
|
"parody:suite precure",
|
||||||
@@ -2297,7 +2337,9 @@ object Parody : TagList {
|
|||||||
"parody:tenkuu senki shurato",
|
"parody:tenkuu senki shurato",
|
||||||
"parody:tenkuu shinpan",
|
"parody:tenkuu shinpan",
|
||||||
"parody:tensai ryouri shounen ajinosuke",
|
"parody:tensai ryouri shounen ajinosuke",
|
||||||
|
"parody:tensei kizoku kantei skill de nariagaru",
|
||||||
"parody:tensei oujo to tensai reijou no mahou kakumei",
|
"parody:tensei oujo to tensai reijou no mahou kakumei",
|
||||||
|
"parody:tensei shitara dainana ouji datta node kimama ni majutsu o kiwamemasu",
|
||||||
"parody:tensei shitara slime datta ken",
|
"parody:tensei shitara slime datta ken",
|
||||||
"parody:tenshi na konamaiki",
|
"parody:tenshi na konamaiki",
|
||||||
"parody:tenshi ni narumon",
|
"parody:tenshi ni narumon",
|
||||||
@@ -2360,6 +2402,7 @@ object Parody : TagList {
|
|||||||
"parody:the legend of heroes",
|
"parody:the legend of heroes",
|
||||||
"parody:the legend of korra",
|
"parody:the legend of korra",
|
||||||
"parody:the legend of luo xiaohei",
|
"parody:the legend of luo xiaohei",
|
||||||
|
"parody:the legend of the condor heroes",
|
||||||
"parody:the legend of the legendary heroes",
|
"parody:the legend of the legendary heroes",
|
||||||
"parody:the legend of zelda",
|
"parody:the legend of zelda",
|
||||||
"parody:the life and times of juniper lee",
|
"parody:the life and times of juniper lee",
|
||||||
@@ -2386,6 +2429,7 @@ object Parody : TagList {
|
|||||||
"parody:the princess and the frog",
|
"parody:the princess and the frog",
|
||||||
"parody:the proud family",
|
"parody:the proud family",
|
||||||
"parody:the queen of duellist",
|
"parody:the queen of duellist",
|
||||||
|
"parody:the queens gambit",
|
||||||
"parody:the ren and stimpy show",
|
"parody:the ren and stimpy show",
|
||||||
"parody:the replacements",
|
"parody:the replacements",
|
||||||
"parody:the rescuers",
|
"parody:the rescuers",
|
||||||
@@ -2435,7 +2479,7 @@ object Parody : TagList {
|
|||||||
"parody:togainu no chi",
|
"parody:togainu no chi",
|
||||||
"parody:toheart2",
|
"parody:toheart2",
|
||||||
"parody:toji no miko",
|
"parody:toji no miko",
|
||||||
"parody:tokidoki bosotto russia-go de dereru tonari no aalya-san",
|
"parody:tokidoki bosotto russia-go de dereru tonari no alya-san",
|
||||||
"parody:tokimeki memorial",
|
"parody:tokimeki memorial",
|
||||||
"parody:tokusatsu gagaga",
|
"parody:tokusatsu gagaga",
|
||||||
"parody:tokusou sentai dekaranger",
|
"parody:tokusou sentai dekaranger",
|
||||||
@@ -2453,6 +2497,7 @@ object Parody : TagList {
|
|||||||
"parody:tonagura",
|
"parody:tonagura",
|
||||||
"parody:tonari no kaibutsu-kun",
|
"parody:tonari no kaibutsu-kun",
|
||||||
"parody:tonari no kyuuketsuki-san",
|
"parody:tonari no kyuuketsuki-san",
|
||||||
|
"parody:tongari boushi",
|
||||||
"parody:tongari boushi no atelier",
|
"parody:tongari boushi no atelier",
|
||||||
"parody:tonikaku kawaii",
|
"parody:tonikaku kawaii",
|
||||||
"parody:toradora",
|
"parody:toradora",
|
||||||
@@ -2503,6 +2548,7 @@ object Parody : TagList {
|
|||||||
"parody:uchuu no kishi tekkaman",
|
"parody:uchuu no kishi tekkaman",
|
||||||
"parody:uchuu no stellvia",
|
"parody:uchuu no stellvia",
|
||||||
"parody:uchuu senshi baldios",
|
"parody:uchuu senshi baldios",
|
||||||
|
"parody:uchuu show e youkoso",
|
||||||
"parody:uchuujin tanaka tarou",
|
"parody:uchuujin tanaka tarou",
|
||||||
"parody:ufo princess valkyrie",
|
"parody:ufo princess valkyrie",
|
||||||
"parody:ukagaka",
|
"parody:ukagaka",
|
||||||
@@ -2512,6 +2558,7 @@ object Parody : TagList {
|
|||||||
"parody:uma musume pretty derby",
|
"parody:uma musume pretty derby",
|
||||||
"parody:umi ga kikoeru",
|
"parody:umi ga kikoeru",
|
||||||
"parody:umi monogatari",
|
"parody:umi monogatari",
|
||||||
|
"parody:umibe no etranger",
|
||||||
"parody:umineko no naku koro ni",
|
"parody:umineko no naku koro ni",
|
||||||
"parody:un-go",
|
"parody:un-go",
|
||||||
"parody:unbalance x unbalance",
|
"parody:unbalance x unbalance",
|
||||||
@@ -2541,6 +2588,7 @@ object Parody : TagList {
|
|||||||
"parody:vandread",
|
"parody:vandread",
|
||||||
"parody:vanitas no carte",
|
"parody:vanitas no carte",
|
||||||
"parody:variable geo",
|
"parody:variable geo",
|
||||||
|
"parody:various",
|
||||||
"parody:vatican kiseki chousakan",
|
"parody:vatican kiseki chousakan",
|
||||||
"parody:venus and braves",
|
"parody:venus and braves",
|
||||||
"parody:venus blood -ragnarok-",
|
"parody:venus blood -ragnarok-",
|
||||||
@@ -2550,7 +2598,9 @@ object Parody : TagList {
|
|||||||
"parody:video girl ai",
|
"parody:video girl ai",
|
||||||
"parody:viewtiful joe",
|
"parody:viewtiful joe",
|
||||||
"parody:vindictus",
|
"parody:vindictus",
|
||||||
|
"parody:violated heroine",
|
||||||
"parody:violinist of hameln",
|
"parody:violinist of hameln",
|
||||||
|
"parody:viorate no atelier",
|
||||||
"parody:viper",
|
"parody:viper",
|
||||||
"parody:viper ctr",
|
"parody:viper ctr",
|
||||||
"parody:viper f40",
|
"parody:viper f40",
|
||||||
@@ -2565,6 +2615,7 @@ object Parody : TagList {
|
|||||||
"parody:vocaloid",
|
"parody:vocaloid",
|
||||||
"parody:voiceroid",
|
"parody:voiceroid",
|
||||||
"parody:voltage fighter gowcaizer",
|
"parody:voltage fighter gowcaizer",
|
||||||
|
"parody:vshojo",
|
||||||
"parody:w.i.t.c.h.",
|
"parody:w.i.t.c.h.",
|
||||||
"parody:wagaya no oinari-sama",
|
"parody:wagaya no oinari-sama",
|
||||||
"parody:waka okami wa shougakusei",
|
"parody:waka okami wa shougakusei",
|
||||||
@@ -2583,6 +2634,7 @@ object Parody : TagList {
|
|||||||
"parody:warship girls",
|
"parody:warship girls",
|
||||||
"parody:warzard",
|
"parody:warzard",
|
||||||
"parody:washio sumi wa yuusha de aru",
|
"parody:washio sumi wa yuusha de aru",
|
||||||
|
"parody:watashi ga koibito ni nareru wake nai jan muri muri muri ja nakatta",
|
||||||
"parody:watashi ga motete dousunda",
|
"parody:watashi ga motete dousunda",
|
||||||
"parody:watashi ni tenshi ga maiorita",
|
"parody:watashi ni tenshi ga maiorita",
|
||||||
"parody:watashi no ashinaga ojisan",
|
"parody:watashi no ashinaga ojisan",
|
||||||
@@ -2599,6 +2651,7 @@ object Parody : TagList {
|
|||||||
"parody:white album",
|
"parody:white album",
|
||||||
"parody:wild arms",
|
"parody:wild arms",
|
||||||
"parody:wild arms 2",
|
"parody:wild arms 2",
|
||||||
|
"parody:windbreaker",
|
||||||
"parody:wingman",
|
"parody:wingman",
|
||||||
"parody:wings of honneamise",
|
"parody:wings of honneamise",
|
||||||
"parody:winnie the pooh",
|
"parody:winnie the pooh",
|
||||||
@@ -2657,15 +2710,18 @@ object Parody : TagList {
|
|||||||
"parody:yoake mae yori ruriiro na",
|
"parody:yoake mae yori ruriiro na",
|
||||||
"parody:yofukashi no uta",
|
"parody:yofukashi no uta",
|
||||||
"parody:yokohama kaidashi kikou",
|
"parody:yokohama kaidashi kikou",
|
||||||
|
"parody:yoku wakaru gendai mahou",
|
||||||
"parody:yomawari",
|
"parody:yomawari",
|
||||||
"parody:yondemasuyo azazel-san",
|
"parody:yondemasuyo azazel-san",
|
||||||
"parody:yongbi bulpae",
|
"parody:yongbi bulpae",
|
||||||
"parody:yoroiden samurai troopers",
|
"parody:yoroiden samurai troopers",
|
||||||
"parody:yoru ga kuru",
|
"parody:yoru ga kuru",
|
||||||
|
"parody:yoru no kurage wa oyogenai",
|
||||||
"parody:yoru no yatterman",
|
"parody:yoru no yatterman",
|
||||||
"parody:yoshinaga-san chi no gargoyle",
|
"parody:yoshinaga-san chi no gargoyle",
|
||||||
"parody:yosuga no sora",
|
"parody:yosuga no sora",
|
||||||
"parody:yotsubato",
|
"parody:yotsubato",
|
||||||
|
"parody:you shou yan",
|
||||||
"parody:youjo senki",
|
"parody:youjo senki",
|
||||||
"parody:youjuu senki a.d. 2048",
|
"parody:youjuu senki a.d. 2048",
|
||||||
"parody:youkai hyakkitan",
|
"parody:youkai hyakkitan",
|
||||||
@@ -2714,7 +2770,6 @@ object Parody : TagList {
|
|||||||
"parody:zettai muteki raijin-oh",
|
"parody:zettai muteki raijin-oh",
|
||||||
"parody:zettai shougeki platonic heart",
|
"parody:zettai shougeki platonic heart",
|
||||||
"parody:zettai zetsumei toshi 3",
|
"parody:zettai zetsumei toshi 3",
|
||||||
"parody:zhongfan weilai 1999",
|
|
||||||
"parody:zoids",
|
"parody:zoids",
|
||||||
"parody:zoids genesis",
|
"parody:zoids genesis",
|
||||||
"parody:zoids new century",
|
"parody:zoids new century",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import tachiyomi.core.common.i18n.stringResource
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
@@ -64,18 +65,18 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
?: EHentai(0, true, context)
|
?: EHentai(0, true, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val storage = LocalFavoritesStorage()
|
private val storage by lazy { LocalFavoritesStorage() }
|
||||||
|
|
||||||
private val galleryAdder = GalleryAdder()
|
private val galleryAdder by lazy { GalleryAdder() }
|
||||||
|
|
||||||
private val throttleManager = EHentaiThrottleManager()
|
private val throttleManager by lazy { EHentaiThrottleManager() }
|
||||||
|
|
||||||
private var wifiLock: WifiManager.WifiLock? = null
|
private var wifiLock: WifiManager.WifiLock? = null
|
||||||
private var wakeLock: PowerManager.WakeLock? = null
|
private var wakeLock: PowerManager.WakeLock? = null
|
||||||
|
|
||||||
private val logger = xLog()
|
private val logger by lazy { xLog() }
|
||||||
|
|
||||||
val status: MutableStateFlow<FavoritesSyncStatus> = MutableStateFlow(FavoritesSyncStatus.Idle(context))
|
val status: MutableStateFlow<FavoritesSyncStatus> = MutableStateFlow(FavoritesSyncStatus.Idle)
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun runSync(scope: CoroutineScope) {
|
fun runSync(scope: CoroutineScope) {
|
||||||
@@ -83,7 +84,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
status.value = FavoritesSyncStatus.Initializing(context)
|
status.value = FavoritesSyncStatus.Initializing
|
||||||
|
|
||||||
scope.launch(Dispatchers.IO) { beginSync() }
|
scope.launch(Dispatchers.IO) { beginSync() }
|
||||||
}
|
}
|
||||||
@@ -91,13 +92,12 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
private suspend fun beginSync() {
|
private suspend fun beginSync() {
|
||||||
// Check if logged in
|
// Check if logged in
|
||||||
if (!prefs.enableExhentai().get()) {
|
if (!prefs.enableExhentai().get()) {
|
||||||
status.value = FavoritesSyncStatus.Error(context.stringResource(SYMR.strings.please_login))
|
status.value = FavoritesSyncStatus.SyncError.NotLoggedInSyncError
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate library state
|
// Validate library state
|
||||||
status.value =
|
status.value = FavoritesSyncStatus.Processing.VerifyingLibrary
|
||||||
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_verifying_library))
|
|
||||||
val libraryManga = getLibraryManga.await()
|
val libraryManga = getLibraryManga.await()
|
||||||
val seenManga = HashSet<Long>(libraryManga.size)
|
val seenManga = HashSet<Long>(libraryManga.size)
|
||||||
libraryManga.forEach { (manga) ->
|
libraryManga.forEach { (manga) ->
|
||||||
@@ -106,7 +106,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
if (manga.id in seenManga) {
|
if (manga.id in seenManga) {
|
||||||
val inCategories = getCategories.await(manga.id)
|
val inCategories = getCategories.await(manga.id)
|
||||||
status.value = FavoritesSyncStatus.BadLibraryState
|
status.value = FavoritesSyncStatus.BadLibraryState
|
||||||
.MangaInMultipleCategories(manga, inCategories, context)
|
.MangaInMultipleCategories(manga.id, manga.title, inCategories.map { it.name })
|
||||||
|
|
||||||
logger.w(context.stringResource(SYMR.strings.favorites_sync_gallery_multiple_categories_error, manga.id))
|
logger.w(context.stringResource(SYMR.strings.favorites_sync_gallery_multiple_categories_error, manga.id))
|
||||||
return
|
return
|
||||||
@@ -117,17 +117,15 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
|
|
||||||
// Download remote favorites
|
// Download remote favorites
|
||||||
val favorites = try {
|
val favorites = try {
|
||||||
status.value =
|
status.value = FavoritesSyncStatus.Processing.DownloadingFavorites
|
||||||
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_downloading))
|
|
||||||
exh.fetchFavorites()
|
exh.fetchFavorites()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
status.value =
|
status.value = FavoritesSyncStatus.SyncError.FailedToFetchFavorites
|
||||||
FavoritesSyncStatus.Error(context.stringResource(SYMR.strings.favorites_sync_failed_to_featch))
|
|
||||||
logger.e(context.stringResource(SYMR.strings.favorites_sync_could_not_fetch), e)
|
logger.e(context.stringResource(SYMR.strings.favorites_sync_could_not_fetch), e)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val errorList = mutableListOf<String>()
|
val errorList = mutableListOf<FavoritesSyncStatus.SyncError.GallerySyncError>()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Take wake + wifi locks
|
// Take wake + wifi locks
|
||||||
@@ -157,23 +155,17 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
// Do not update galleries while syncing favorites
|
// Do not update galleries while syncing favorites
|
||||||
EHentaiUpdateWorker.cancelBackground(context)
|
EHentaiUpdateWorker.cancelBackground(context)
|
||||||
|
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.CalculatingRemoteChanges
|
||||||
context.stringResource(SYMR.strings.favorites_sync_calculating_remote_changes),
|
|
||||||
)
|
|
||||||
val remoteChanges = storage.getChangedRemoteEntries(favorites.first)
|
val remoteChanges = storage.getChangedRemoteEntries(favorites.first)
|
||||||
val localChanges = if (prefs.exhReadOnlySync().get()) {
|
val localChanges = if (prefs.exhReadOnlySync().get()) {
|
||||||
null // Do not build local changes if they are not going to be applied
|
null // Do not build local changes if they are not going to be applied
|
||||||
} else {
|
} else {
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.CalculatingLocalChanges
|
||||||
context.stringResource(SYMR.strings.favorites_sync_calculating_local_changes),
|
|
||||||
)
|
|
||||||
storage.getChangedDbEntries()
|
storage.getChangedDbEntries()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply remote categories
|
// Apply remote categories
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.SyncingCategoryNames
|
||||||
context.stringResource(SYMR.strings.favorites_sync_syncing_category_names),
|
|
||||||
)
|
|
||||||
applyRemoteCategories(favorites.second)
|
applyRemoteCategories(favorites.second)
|
||||||
|
|
||||||
// Apply change sets
|
// Apply change sets
|
||||||
@@ -182,8 +174,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
applyChangeSetToRemote(errorList, localChanges)
|
applyChangeSetToRemote(errorList, localChanges)
|
||||||
}
|
}
|
||||||
|
|
||||||
status.value =
|
status.value = FavoritesSyncStatus.Processing.CleaningUp
|
||||||
FavoritesSyncStatus.Processing(context.stringResource(SYMR.strings.favorites_sync_cleaning_up))
|
|
||||||
storage.snapshotEntries()
|
storage.snapshotEntries()
|
||||||
|
|
||||||
withUIContext {
|
withUIContext {
|
||||||
@@ -194,9 +185,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
logger.w(context.stringResource(SYMR.strings.favorites_sync_ignoring_exception), e)
|
logger.w(context.stringResource(SYMR.strings.favorites_sync_ignoring_exception), e)
|
||||||
return
|
return
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
status.value = FavoritesSyncStatus.Error(
|
status.value = FavoritesSyncStatus.SyncError.UnknownSyncError(e.message.orEmpty())
|
||||||
context.stringResource(SYMR.strings.favorites_sync_unknown_error, e.message.orEmpty()),
|
|
||||||
)
|
|
||||||
logger.e(context.stringResource(SYMR.strings.favorites_sync_sync_error), e)
|
logger.e(context.stringResource(SYMR.strings.favorites_sync_sync_error), e)
|
||||||
return
|
return
|
||||||
} finally {
|
} finally {
|
||||||
@@ -215,7 +204,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (errorList.isEmpty()) {
|
if (errorList.isEmpty()) {
|
||||||
status.value = FavoritesSyncStatus.Idle(context)
|
status.value = FavoritesSyncStatus.Idle
|
||||||
} else {
|
} else {
|
||||||
status.value = FavoritesSyncStatus.CompleteWithErrors(errorList)
|
status.value = FavoritesSyncStatus.CompleteWithErrors(errorList)
|
||||||
}
|
}
|
||||||
@@ -249,7 +238,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun addGalleryRemote(errorList: MutableList<String>, gallery: FavoriteEntry) {
|
private suspend fun addGalleryRemote(errorList: MutableList<FavoritesSyncStatus.SyncError.GallerySyncError>, gallery: FavoriteEntry) {
|
||||||
val url = "${exh.baseUrl}/gallerypopups.php?gid=${gallery.gid}&t=${gallery.token}&act=addfav"
|
val url = "${exh.baseUrl}/gallerypopups.php?gid=${gallery.gid}&t=${gallery.token}&act=addfav"
|
||||||
|
|
||||||
val request = POST(
|
val request = POST(
|
||||||
@@ -263,13 +252,16 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!explicitlyRetryExhRequest(10, request)) {
|
if (!explicitlyRetryExhRequest(10, request)) {
|
||||||
val errorString = "Unable to add gallery to remote server: '${gallery.title}' (GID: ${gallery.gid})!"
|
val error = FavoritesSyncStatus.SyncError.GallerySyncError.UnableToAddGalleryToRemote(
|
||||||
|
gallery.title,
|
||||||
|
gallery.gid,
|
||||||
|
)
|
||||||
|
|
||||||
if (prefs.exhLenientSync().get()) {
|
if (prefs.exhLenientSync().get()) {
|
||||||
errorList += errorString
|
errorList += error
|
||||||
} else {
|
} else {
|
||||||
status.value = FavoritesSyncStatus.Error(errorString)
|
status.value = error
|
||||||
throw IgnoredException(errorString)
|
throw IgnoredException(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,12 +285,13 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
return success
|
return success
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun applyChangeSetToRemote(errorList: MutableList<String>, changeSet: ChangeSet) {
|
private suspend fun applyChangeSetToRemote(
|
||||||
|
errorList: MutableList<FavoritesSyncStatus.SyncError.GallerySyncError>,
|
||||||
|
changeSet: ChangeSet,
|
||||||
|
) {
|
||||||
// Apply removals
|
// Apply removals
|
||||||
if (changeSet.removed.isNotEmpty()) {
|
if (changeSet.removed.isNotEmpty()) {
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.RemovingRemoteGalleries(changeSet.removed.size)
|
||||||
context.stringResource(SYMR.strings.favorites_sync_removing_galleries, changeSet.removed.size),
|
|
||||||
)
|
|
||||||
|
|
||||||
val formBody = FormBody.Builder()
|
val formBody = FormBody.Builder()
|
||||||
.add("ddact", "delete")
|
.add("ddact", "delete")
|
||||||
@@ -315,13 +308,11 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!explicitlyRetryExhRequest(10, request)) {
|
if (!explicitlyRetryExhRequest(10, request)) {
|
||||||
val errorString = context.stringResource(SYMR.strings.favorites_sync_unable_to_delete)
|
|
||||||
|
|
||||||
if (prefs.exhLenientSync().get()) {
|
if (prefs.exhLenientSync().get()) {
|
||||||
errorList += errorString
|
errorList += FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote
|
||||||
} else {
|
} else {
|
||||||
status.value = FavoritesSyncStatus.Error(errorString)
|
status.value = FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote
|
||||||
throw IgnoredException(errorString)
|
throw IgnoredException(FavoritesSyncStatus.SyncError.GallerySyncError.UnableToDeleteFromRemote)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,10 +320,10 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
// Apply additions
|
// Apply additions
|
||||||
throttleManager.resetThrottle()
|
throttleManager.resetThrottle()
|
||||||
changeSet.added.forEachIndexed { index, it ->
|
changeSet.added.forEachIndexed { index, it ->
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.AddingGalleryToRemote(
|
||||||
message = context.stringResource(SYMR.strings.favorites_sync_adding_to_remote, index + 1, changeSet.added.size),
|
index = index + 1,
|
||||||
isThrottle = needWarnThrottle(),
|
total = changeSet.added.size,
|
||||||
context = context,
|
isThrottling = needWarnThrottle(),
|
||||||
title = it.title,
|
title = it.title,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -342,14 +333,17 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun applyChangeSetToLocal(errorList: MutableList<String>, changeSet: ChangeSet) {
|
private suspend fun applyChangeSetToLocal(
|
||||||
|
errorList: MutableList<FavoritesSyncStatus.SyncError.GallerySyncError>,
|
||||||
|
changeSet: ChangeSet,
|
||||||
|
) {
|
||||||
val removedManga = mutableListOf<Manga>()
|
val removedManga = mutableListOf<Manga>()
|
||||||
|
|
||||||
// Apply removals
|
// Apply removals
|
||||||
changeSet.removed.forEachIndexed { index, it ->
|
changeSet.removed.forEachIndexed { index, it ->
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.RemovingGalleryFromLocal(
|
||||||
context.stringResource(SYMR.strings.favorites_sync_remove_from_local, index + 1, changeSet.removed.size),
|
index = index + 1,
|
||||||
title = it.title,
|
total = changeSet.removed.size,
|
||||||
)
|
)
|
||||||
val url = it.getUrl()
|
val url = it.getUrl()
|
||||||
|
|
||||||
@@ -379,10 +373,10 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
// Apply additions
|
// Apply additions
|
||||||
throttleManager.resetThrottle()
|
throttleManager.resetThrottle()
|
||||||
changeSet.added.forEachIndexed { index, it ->
|
changeSet.added.forEachIndexed { index, it ->
|
||||||
status.value = FavoritesSyncStatus.Processing(
|
status.value = FavoritesSyncStatus.Processing.AddingGalleryToLocal(
|
||||||
message = context.stringResource(SYMR.strings.favorites_sync_add_to_local, index + 1, changeSet.added.size),
|
index = index + 1,
|
||||||
isThrottle = needWarnThrottle(),
|
total = changeSet.added.size,
|
||||||
context = context,
|
isThrottling = needWarnThrottle(),
|
||||||
title = it.title,
|
title = it.title,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -405,24 +399,23 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
return@forEachIndexed
|
return@forEachIndexed
|
||||||
}
|
}
|
||||||
|
|
||||||
val errorString = context.stringResource(SYMR.strings.favorites_sync_failed_to_add_to_local) +
|
val error = when (result) {
|
||||||
when (result) {
|
is GalleryAddEvent.Fail.Error -> FavoritesSyncStatus.SyncError.GallerySyncError.GalleryAddFail(
|
||||||
is GalleryAddEvent.Fail.Error -> context.stringResource(
|
it.title, result.logMessage,
|
||||||
SYMR.strings.favorites_sync_failed_to_add_to_local_error, it.title, result.logMessage,
|
)
|
||||||
)
|
is GalleryAddEvent.Fail.UnknownType -> FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail(
|
||||||
is GalleryAddEvent.Fail.UnknownType -> context.stringResource(
|
it.title, result.galleryUrl,
|
||||||
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, result.galleryUrl,
|
)
|
||||||
)
|
is GalleryAddEvent.Fail.UnknownSource -> FavoritesSyncStatus.SyncError.GallerySyncError.InvalidGalleryFail(
|
||||||
is GalleryAddEvent.Fail.UnknownSource -> context.stringResource(
|
it.title, result.galleryUrl,
|
||||||
SYMR.strings.favorites_sync_failed_to_add_to_local_unknown_type, it.title, result.galleryUrl,
|
)
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (prefs.exhLenientSync().get()) {
|
if (prefs.exhLenientSync().get()) {
|
||||||
errorList += errorString
|
errorList += error
|
||||||
} else {
|
} else {
|
||||||
status.value = FavoritesSyncStatus.Error(errorString)
|
status.value = error
|
||||||
throw IgnoredException(errorString)
|
throw IgnoredException(error)
|
||||||
}
|
}
|
||||||
} else if (result is GalleryAddEvent.Success) {
|
} else if (result is GalleryAddEvent.Success) {
|
||||||
insertedMangaCategories += categories[it.category].id to result.manga
|
insertedMangaCategories += categories[it.category].id to result.manga
|
||||||
@@ -438,59 +431,85 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
private fun needWarnThrottle() =
|
private fun needWarnThrottle() =
|
||||||
throttleManager.throttleTime >= THROTTLE_WARN
|
throttleManager.throttleTime >= THROTTLE_WARN
|
||||||
|
|
||||||
class IgnoredException(message: String) : RuntimeException(message)
|
class IgnoredException(message: FavoritesSyncStatus.SyncError.GallerySyncError) : RuntimeException(message.toString())
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val THROTTLE_WARN = 1.seconds
|
private val THROTTLE_WARN = 1.seconds
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class FavoritesSyncStatus() {
|
@Serializable
|
||||||
abstract val message: String
|
sealed class FavoritesSyncStatus {
|
||||||
|
@Serializable
|
||||||
|
sealed class SyncError : FavoritesSyncStatus() {
|
||||||
|
@Serializable
|
||||||
|
data object NotLoggedInSyncError : SyncError()
|
||||||
|
|
||||||
data class Error(override val message: String) : FavoritesSyncStatus()
|
@Serializable
|
||||||
data class Idle(override val message: String) : FavoritesSyncStatus() {
|
data object FailedToFetchFavorites : SyncError()
|
||||||
constructor(context: Context) : this(context.stringResource(SYMR.strings.favorites_sync_waiting_for_start))
|
|
||||||
}
|
@Serializable
|
||||||
sealed class BadLibraryState : FavoritesSyncStatus() {
|
data class UnknownSyncError(val message: String) : SyncError()
|
||||||
data class MangaInMultipleCategories(
|
|
||||||
val manga: Manga,
|
@Serializable
|
||||||
val categories: List<Category>,
|
sealed class GallerySyncError : SyncError() {
|
||||||
override val message: String,
|
@Serializable
|
||||||
) : BadLibraryState() {
|
data class UnableToAddGalleryToRemote(val title: String, val gid: String) : GallerySyncError()
|
||||||
constructor(manga: Manga, categories: List<Category>, context: Context) :
|
|
||||||
this(
|
@Serializable
|
||||||
manga = manga,
|
data object UnableToDeleteFromRemote : GallerySyncError()
|
||||||
categories = categories,
|
|
||||||
message = context.stringResource(
|
@Serializable
|
||||||
SYMR.strings.favorites_sync_gallery_in_multiple_categories, manga.title,
|
data class GalleryAddFail(val title: String, val reason: String) : GallerySyncError()
|
||||||
categories.joinToString {
|
|
||||||
it.name
|
@Serializable
|
||||||
},
|
data class InvalidGalleryFail(val title: String, val url: String) : GallerySyncError()
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data class Initializing(override val message: String) : FavoritesSyncStatus() {
|
|
||||||
constructor(context: Context) : this(context.stringResource(SYMR.strings.favorites_sync_initializing))
|
|
||||||
}
|
|
||||||
data class Processing(
|
|
||||||
override val message: String,
|
|
||||||
val title: String? = null,
|
|
||||||
) : FavoritesSyncStatus() {
|
|
||||||
constructor(message: String, isThrottle: Boolean, context: Context, title: String?) :
|
|
||||||
this(
|
|
||||||
if (isThrottle) {
|
|
||||||
context.stringResource(SYMR.strings.favorites_sync_processing_throttle, message)
|
|
||||||
} else {
|
|
||||||
message
|
|
||||||
},
|
|
||||||
title,
|
|
||||||
)
|
|
||||||
|
|
||||||
val delayedMessage get() = if (title != null) this.message + "\n\n" + title else null
|
@Serializable
|
||||||
|
data object Idle : FavoritesSyncStatus()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed class BadLibraryState : FavoritesSyncStatus() {
|
||||||
|
@Serializable
|
||||||
|
data class MangaInMultipleCategories(
|
||||||
|
val mangaId: Long,
|
||||||
|
val mangaTitle: String,
|
||||||
|
val categories: List<String>,
|
||||||
|
) : BadLibraryState()
|
||||||
}
|
}
|
||||||
data class CompleteWithErrors(val messages: List<String>) : FavoritesSyncStatus() {
|
|
||||||
override val message: String = messages.joinToString("\n")
|
@Serializable
|
||||||
|
data object Initializing : FavoritesSyncStatus()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
sealed class Processing : FavoritesSyncStatus() {
|
||||||
|
data object VerifyingLibrary : Processing()
|
||||||
|
data object DownloadingFavorites : Processing()
|
||||||
|
data object CalculatingRemoteChanges : Processing()
|
||||||
|
data object CalculatingLocalChanges : Processing()
|
||||||
|
data object SyncingCategoryNames : Processing()
|
||||||
|
data class RemovingRemoteGalleries(val galleryCount: Int) : Processing()
|
||||||
|
data class AddingGalleryToRemote(
|
||||||
|
val index: Int,
|
||||||
|
val total: Int,
|
||||||
|
val isThrottling: Boolean,
|
||||||
|
val title: String,
|
||||||
|
) : Processing()
|
||||||
|
data class RemovingGalleryFromLocal(
|
||||||
|
val index: Int,
|
||||||
|
val total: Int,
|
||||||
|
) : Processing()
|
||||||
|
data class AddingGalleryToLocal(
|
||||||
|
val index: Int,
|
||||||
|
val total: Int,
|
||||||
|
val isThrottling: Boolean,
|
||||||
|
val title: String,
|
||||||
|
) : Processing()
|
||||||
|
data object CleaningUp : Processing()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CompleteWithErrors(val messages: List<SyncError.GallerySyncError>) : FavoritesSyncStatus()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
@@ -25,6 +24,7 @@ import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
|
|||||||
import eu.kanade.tachiyomi.ui.category.CategoryScreen
|
import eu.kanade.tachiyomi.ui.category.CategoryScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import exh.ui.ifSourcesLoaded
|
import exh.ui.ifSourcesLoaded
|
||||||
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.core.common.util.lang.launchIO
|
import tachiyomi.core.common.util.lang.launchIO
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
@@ -65,11 +65,9 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
|
|||||||
SnackbarHost(hostState = snackbarHostState)
|
SnackbarHost(hostState = snackbarHostState)
|
||||||
},
|
},
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
val pagingFlow by screenModel.mangaPagerFlowFlow.collectAsState()
|
|
||||||
|
|
||||||
BrowseSourceContent(
|
BrowseSourceContent(
|
||||||
source = screenModel.source,
|
source = screenModel.source,
|
||||||
mangaList = pagingFlow.collectAsLazyPagingItems(),
|
mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(),
|
||||||
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
// SY -->
|
// SY -->
|
||||||
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
ehentaiBrowseDisplayMode = screenModel.ehentaiBrowseDisplayMode,
|
||||||
|
|||||||
@@ -128,6 +128,36 @@ class MangaHandler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMangaMetadata(
|
||||||
|
track: Track,
|
||||||
|
sourceId: Long,
|
||||||
|
coverQuality: String,
|
||||||
|
tryUsingFirstVolumeCover: Boolean,
|
||||||
|
altTitlesInDesc: Boolean,
|
||||||
|
): SManga? {
|
||||||
|
return withIOContext {
|
||||||
|
val mangaId = MdUtil.getMangaId(track.tracking_url)
|
||||||
|
val response = service.viewManga(mangaId)
|
||||||
|
val coverFileName = if (tryUsingFirstVolumeCover) {
|
||||||
|
service.fetchFirstVolumeCover(response)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
apiMangaParser.parseToManga(
|
||||||
|
SManga.create().apply {
|
||||||
|
url = track.tracking_url
|
||||||
|
},
|
||||||
|
sourceId,
|
||||||
|
response,
|
||||||
|
emptyList(),
|
||||||
|
null,
|
||||||
|
coverFileName,
|
||||||
|
coverQuality,
|
||||||
|
altTitlesInDesc,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun getSimpleChapters(manga: SManga): List<String> {
|
private suspend fun getSimpleChapters(manga: SManga): List<String> {
|
||||||
return runCatching { service.aggregateChapters(MdUtil.getMangaId(manga.url), lang) }
|
return runCatching { service.aggregateChapters(MdUtil.getMangaId(manga.url), lang) }
|
||||||
.onFailure {
|
.onFailure {
|
||||||
|
|||||||
@@ -3,11 +3,8 @@ package exh.md.similar
|
|||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.currentOrThrow
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
||||||
@@ -16,6 +13,7 @@ import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
|||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
||||||
import exh.ui.ifSourcesLoaded
|
import exh.ui.ifSourcesLoaded
|
||||||
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
@@ -52,11 +50,9 @@ class MangaDexSimilarScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
|||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
val pagingFlow by screenModel.mangaPagerFlowFlow.collectAsState()
|
|
||||||
|
|
||||||
BrowseSourceContent(
|
BrowseSourceContent(
|
||||||
source = screenModel.source,
|
source = screenModel.source,
|
||||||
mangaList = pagingFlow.collectAsLazyPagingItems(),
|
mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(),
|
||||||
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
// SY -->
|
// SY -->
|
||||||
ehentaiBrowseDisplayMode = false,
|
ehentaiBrowseDisplayMode = false,
|
||||||
|
|||||||
@@ -3,11 +3,8 @@ package exh.recs
|
|||||||
import androidx.compose.material3.SnackbarHost
|
import androidx.compose.material3.SnackbarHost
|
||||||
import androidx.compose.material3.SnackbarHostState
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
import androidx.paging.compose.collectAsLazyPagingItems
|
|
||||||
import cafe.adriel.voyager.core.model.rememberScreenModel
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
||||||
import cafe.adriel.voyager.navigator.LocalNavigator
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
||||||
import cafe.adriel.voyager.navigator.Navigator
|
import cafe.adriel.voyager.navigator.Navigator
|
||||||
@@ -17,6 +14,7 @@ import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
|
|||||||
import eu.kanade.presentation.util.Screen
|
import eu.kanade.presentation.util.Screen
|
||||||
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
|
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
|
||||||
import exh.ui.ifSourcesLoaded
|
import exh.ui.ifSourcesLoaded
|
||||||
|
import mihon.presentation.core.util.collectAsLazyPagingItems
|
||||||
import tachiyomi.domain.manga.model.Manga
|
import tachiyomi.domain.manga.model.Manga
|
||||||
import tachiyomi.presentation.core.components.material.Scaffold
|
import tachiyomi.presentation.core.components.material.Scaffold
|
||||||
import tachiyomi.presentation.core.screens.LoadingScreen
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
||||||
@@ -51,11 +49,9 @@ class RecommendsScreen(val mangaId: Long, val sourceId: Long) : Screen() {
|
|||||||
},
|
},
|
||||||
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
val pagingFlow by screenModel.mangaPagerFlowFlow.collectAsState()
|
|
||||||
|
|
||||||
BrowseSourceContent(
|
BrowseSourceContent(
|
||||||
source = screenModel.source,
|
source = screenModel.source,
|
||||||
mangaList = pagingFlow.collectAsLazyPagingItems(),
|
mangaList = screenModel.mangaPagerFlowFlow.collectAsLazyPagingItems(),
|
||||||
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
columns = screenModel.getColumnsPreference(LocalConfiguration.current.orientation),
|
||||||
// SY -->
|
// SY -->
|
||||||
ehentaiBrowseDisplayMode = false,
|
ehentaiBrowseDisplayMode = false,
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class BatchAddScreen : Screen() {
|
|||||||
text = stringResource(SYMR.strings.eh_batch_add_description),
|
text = stringResource(SYMR.strings.eh_batch_add_description),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
keyboardOptions = KeyboardOptions(autoCorrect = false),
|
keyboardOptions = KeyboardOptions(autoCorrectEnabled = false),
|
||||||
textStyle = MaterialTheme.typography.bodyLarge,
|
textStyle = MaterialTheme.typography.bodyLarge,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -130,24 +130,40 @@
|
|||||||
android:layout_marginBottom="12dp" />
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/reset_tags"
|
android:id="@+id/autofill_from_tracker"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginBottom="8dp"
|
android:layout_marginBottom="8dp"
|
||||||
android:text="@string/reset_tags"
|
android:text="@string/fill_from_tracker"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
<Button
|
<LinearLayout
|
||||||
android:id="@+id/reset_info"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:orientation="horizontal">
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginBottom="8dp"
|
<Button
|
||||||
android:text="@string/reset_info"
|
android:id="@+id/reset_tags"
|
||||||
android:textAllCaps="false" />
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:text="@string/reset_tags"
|
||||||
|
android:textAllCaps="false" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/reset_info"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:text="@string/reset_info"
|
||||||
|
android:textAllCaps="false" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ object DeviceUtil {
|
|||||||
|
|
||||||
val invalidDefaultBrowsers = listOf(
|
val invalidDefaultBrowsers = listOf(
|
||||||
"android",
|
"android",
|
||||||
|
"com.hihonor.android.internal.app",
|
||||||
"com.huawei.android.internal.app",
|
"com.huawei.android.internal.app",
|
||||||
"com.zui.resolver",
|
"com.zui.resolver",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import javax.microedition.khronos.egl.EGLContext
|
|||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
object GLUtil {
|
object GLUtil {
|
||||||
val maxTextureSize: Int by lazy {
|
val DEVICE_TEXTURE_LIMIT: Int by lazy {
|
||||||
// Get EGL Display
|
// Get EGL Display
|
||||||
val egl = EGLContext.getEGL() as EGL10
|
val egl = EGLContext.getEGL() as EGL10
|
||||||
val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
|
val display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)
|
||||||
@@ -38,10 +38,23 @@ object GLUtil {
|
|||||||
// Release
|
// Release
|
||||||
egl.eglTerminate(display)
|
egl.eglTerminate(display)
|
||||||
|
|
||||||
// Return largest texture size found, or default
|
// Return largest texture size found (after making it a multiplier of [Multiplier]), or default
|
||||||
max(maximumTextureSize, IMAGE_MAX_BITMAP_DIMENSION)
|
max(maximumTextureSize, SAFE_TEXTURE_LIMIT)
|
||||||
|
}
|
||||||
|
|
||||||
|
const val SAFE_TEXTURE_LIMIT: Int = 2048
|
||||||
|
|
||||||
|
val CUSTOM_TEXTURE_LIMIT_OPTIONS: List<Int> by lazy {
|
||||||
|
val steps = DEVICE_TEXTURE_LIMIT / MULTIPLIER
|
||||||
|
buildList(steps) {
|
||||||
|
add(DEVICE_TEXTURE_LIMIT)
|
||||||
|
for (step in steps downTo 2) {
|
||||||
|
val value = step * MULTIPLIER
|
||||||
|
if (value >= DEVICE_TEXTURE_LIMIT) continue
|
||||||
|
add(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Safe minimum default size
|
private const val MULTIPLIER: Int = 1024
|
||||||
private const val IMAGE_MAX_BITMAP_DIMENSION = 2048
|
|
||||||
|
|||||||
@@ -360,9 +360,21 @@ object ImageUtil {
|
|||||||
val bottomOffset = topOffset + splitHeight
|
val bottomOffset = topOffset + splitHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
fun canUseCoilToDecode(imageSource: BufferedSource): Boolean {
|
fun canUseHardwareBitmap(bitmap: Bitmap): Boolean {
|
||||||
val options = extractImageOptions(imageSource)
|
return canUseHardwareBitmap(bitmap.width, bitmap.height)
|
||||||
return maxOf(options.outWidth, options.outHeight) <= GLUtil.maxTextureSize
|
}
|
||||||
|
|
||||||
|
fun canUseHardwareBitmap(imageSource: BufferedSource): Boolean {
|
||||||
|
return with(extractImageOptions(imageSource)) {
|
||||||
|
canUseHardwareBitmap(outWidth, outHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hardwareBitmapThreshold: Int = GLUtil.SAFE_TEXTURE_LIMIT
|
||||||
|
|
||||||
|
private fun canUseHardwareBitmap(width: Int, height: Int): Boolean {
|
||||||
|
if (HARDWARE_BITMAP_UNSUPPORTED) return false
|
||||||
|
return maxOf(width, height) <= hardwareBitmapThreshold
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -629,6 +641,121 @@ object ImageUtil {
|
|||||||
|
|
||||||
private val optimalImageHeight = getDisplayMaxHeightInPx * 2
|
private val optimalImageHeight = getDisplayMaxHeightInPx * 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken from Coil
|
||||||
|
* (https://github.com/coil-kt/coil/blob/1674d3516f061aeacbe749a435b1924f9648fd41/coil-core/src/androidMain/kotlin/coil3/util/hardwareBitmaps.kt)
|
||||||
|
* ---
|
||||||
|
* Maintains a list of devices with broken/incomplete/unstable hardware bitmap implementations.
|
||||||
|
*
|
||||||
|
* Model names are retrieved from
|
||||||
|
* [Google's official device list](https://support.google.com/googleplay/answer/1727131?hl=en).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
val HARDWARE_BITMAP_UNSUPPORTED = when (Build.VERSION.SDK_INT) {
|
||||||
|
26 -> run {
|
||||||
|
val model = Build.MODEL ?: return@run false
|
||||||
|
|
||||||
|
// Samsung Galaxy (ALL)
|
||||||
|
if (model.removePrefix("SAMSUNG-").startsWith("SM-")) return@run true
|
||||||
|
|
||||||
|
val device = Build.DEVICE ?: return@run false
|
||||||
|
|
||||||
|
return@run device in arrayOf(
|
||||||
|
"nora", "nora_8917", "nora_8917_n", // Moto E5
|
||||||
|
"james", "rjames_f", "rjames_go", "pettyl", // Moto E5 Play
|
||||||
|
"hannah", "ahannah", "rhannah", // Moto E5 Plus
|
||||||
|
|
||||||
|
"ali", "ali_n", // Moto G6
|
||||||
|
"aljeter", "aljeter_n", "jeter", // Moto G6 Play
|
||||||
|
"evert", "evert_n", "evert_nt", // Moto G6 Plus
|
||||||
|
|
||||||
|
"G3112", "G3116", "G3121", "G3123", "G3125", // Xperia XA1
|
||||||
|
"G3412", "G3416", "G3421", "G3423", "G3426", // Xperia XA1 Plus
|
||||||
|
"G3212", "G3221", "G3223", "G3226", // Xperia XA1 Ultra
|
||||||
|
|
||||||
|
"BV6800Pro", // BlackView BV6800Pro
|
||||||
|
"CatS41", // Cat S41
|
||||||
|
"Hi9Pro", // CHUWI Hi9 Pro
|
||||||
|
"manning", // Lenovo K8 Note
|
||||||
|
"N5702L", // NUU Mobile G3
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
27 -> run {
|
||||||
|
val device = Build.DEVICE ?: return@run false
|
||||||
|
|
||||||
|
return@run device in arrayOf(
|
||||||
|
"mcv1s", // LG Tribute Empire
|
||||||
|
"mcv3", // LG K11
|
||||||
|
"mcv5a", // LG Q7
|
||||||
|
"mcv7a", // LG Stylo 4
|
||||||
|
|
||||||
|
"A30ATMO", // T-Mobile REVVL 2
|
||||||
|
"A70AXLTMO", // T-Mobile REVVL 2 PLUS
|
||||||
|
|
||||||
|
"A3A_8_4G_TMO", // Alcatel 9027W
|
||||||
|
"Edison_CKT", // Alcatel ONYX
|
||||||
|
"EDISON_TF", // Alcatel TCL XL2
|
||||||
|
"FERMI_TF", // Alcatel A501DL
|
||||||
|
"U50A_ATT", // Alcatel TETRA
|
||||||
|
"U50A_PLUS_ATT", // Alcatel 5059R
|
||||||
|
"U50A_PLUS_TF", // Alcatel TCL LX
|
||||||
|
"U50APLUSTMO", // Alcatel 5059Z
|
||||||
|
"U5A_PLUS_4G", // Alcatel 1X
|
||||||
|
|
||||||
|
"RCT6513W87DK5e", // RCA Galileo Pro
|
||||||
|
"RCT6873W42BMF9A", // RCA Voyager
|
||||||
|
"RCT6A03W13", // RCA 10 Viking
|
||||||
|
"RCT6B03W12", // RCA Atlas 10 Pro
|
||||||
|
"RCT6B03W13", // RCA Atlas 10 Pro+
|
||||||
|
"RCT6T06E13", // RCA Artemis 10
|
||||||
|
|
||||||
|
"A3_Pro", // Umidigi A3 Pro
|
||||||
|
"One", // Umidigi One
|
||||||
|
"One_Max", // Umidigi One Max
|
||||||
|
"One_Pro", // Umidigi One Pro
|
||||||
|
"Z2", // Umidigi Z2
|
||||||
|
"Z2_PRO", // Umidigi Z2 Pro
|
||||||
|
|
||||||
|
"Armor_3", // Ulefone Armor 3
|
||||||
|
"Armor_6", // Ulefone Armor 6
|
||||||
|
|
||||||
|
"Blackview", // Blackview BV6000
|
||||||
|
"BV9500", // Blackview BV9500
|
||||||
|
"BV9500Pro", // Blackview BV9500Pro
|
||||||
|
|
||||||
|
"A6L-C", // Nuu A6L-C
|
||||||
|
"N5002LA", // Nuu A7L
|
||||||
|
"N5501LA", // Nuu A5L
|
||||||
|
|
||||||
|
"Power_2_Pro", // Leagoo Power 2 Pro
|
||||||
|
"Power_5", // Leagoo Power 5
|
||||||
|
"Z9", // Leagoo Z9
|
||||||
|
|
||||||
|
"V0310WW", // Blu VIVO VI+
|
||||||
|
"V0330WW", // Blu VIVO XI
|
||||||
|
|
||||||
|
"A3", // BenQ A3
|
||||||
|
"ASUS_X018_4", // Asus ZenFone Max Plus M1 (ZB570TL)
|
||||||
|
"C210AE", // Wiko Life
|
||||||
|
"fireball", // DROID Incredible 4G LTE
|
||||||
|
"ILA_X1", // iLA X1
|
||||||
|
"Infinix-X605_sprout", // Infinix NOTE 5 Stylus
|
||||||
|
"j7maxlte", // Samsung Galaxy J7 Max
|
||||||
|
"KING_KONG_3", // Cubot King Kong 3
|
||||||
|
"M10500", // Packard Bell M10500
|
||||||
|
"S70", // Altice ALTICE S70
|
||||||
|
"S80Lite", // Doogee S80Lite
|
||||||
|
"SGINO6", // SGiNO 6
|
||||||
|
"st18c10bnn", // Barnes and Noble BNTV650
|
||||||
|
"TECNO-CA8", // Tecno CAMON X Pro,
|
||||||
|
"SHIFT6m", // SHIFT 6m
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
// SY -->
|
// SY -->
|
||||||
fun mergeBitmaps(
|
fun mergeBitmaps(
|
||||||
imageBitmap: Bitmap,
|
imageBitmap: Bitmap,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
agp_version = "8.7.1"
|
agp_version = "8.7.2"
|
||||||
lifecycle_version = "2.8.7"
|
lifecycle_version = "2.8.7"
|
||||||
paging_version = "3.3.2"
|
paging_version = "3.3.4"
|
||||||
interpolator_version = "1.0.0"
|
interpolator_version = "1.0.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
@@ -11,17 +11,17 @@ annotation = "androidx.annotation:annotation:1.9.1"
|
|||||||
appcompat = "androidx.appcompat:appcompat:1.7.0"
|
appcompat = "androidx.appcompat:appcompat:1.7.0"
|
||||||
biometricktx = "androidx.biometric:biometric-ktx:1.2.0-alpha05"
|
biometricktx = "androidx.biometric:biometric-ktx:1.2.0-alpha05"
|
||||||
constraintlayout = "androidx.constraintlayout:constraintlayout:2.2.0"
|
constraintlayout = "androidx.constraintlayout:constraintlayout:2.2.0"
|
||||||
corektx = "androidx.core:core-ktx:1.13.1"
|
corektx = "androidx.core:core-ktx:1.15.0"
|
||||||
splashscreen = "androidx.core:core-splashscreen:1.0.1"
|
splashscreen = "androidx.core:core-splashscreen:1.0.1"
|
||||||
recyclerview = "androidx.recyclerview:recyclerview:1.3.2"
|
recyclerview = "androidx.recyclerview:recyclerview:1.3.2"
|
||||||
viewpager = "androidx.viewpager:viewpager:1.1.0-beta01"
|
viewpager = "androidx.viewpager:viewpager:1.1.0-rc01"
|
||||||
profileinstaller = "androidx.profileinstaller:profileinstaller:1.4.1"
|
profileinstaller = "androidx.profileinstaller:profileinstaller:1.4.1"
|
||||||
|
|
||||||
lifecycle-common = { module = "androidx.lifecycle:lifecycle-common", version.ref = "lifecycle_version" }
|
lifecycle-common = { module = "androidx.lifecycle:lifecycle-common", version.ref = "lifecycle_version" }
|
||||||
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle_version" }
|
lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle_version" }
|
||||||
lifecycle-runtimektx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle_version" }
|
lifecycle-runtimektx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle_version" }
|
||||||
|
|
||||||
workmanager = "androidx.work:work-runtime:2.9.1"
|
workmanager = "androidx.work:work-runtime:2.10.0"
|
||||||
|
|
||||||
paging-runtime = { module = "androidx.paging:paging-runtime", version.ref = "paging_version" }
|
paging-runtime = { module = "androidx.paging:paging-runtime", version.ref = "paging_version" }
|
||||||
paging-compose = { module = "androidx.paging:paging-compose", version.ref = "paging_version" }
|
paging-compose = { module = "androidx.paging:paging-compose", version.ref = "paging_version" }
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[versions]
|
[versions]
|
||||||
compose-bom = "2024.10.00"
|
compose-bom = "2024.10.01"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
activity = "androidx.activity:activity-compose:1.9.3"
|
activity = "androidx.activity:activity-compose:1.9.3"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[versions]
|
[versions]
|
||||||
kotlin_version = "2.0.21"
|
kotlin_version = "2.0.21"
|
||||||
serialization_version = "1.7.3"
|
serialization_version = "1.7.3"
|
||||||
xml_serialization_version = "0.90.2"
|
xml_serialization_version = "0.90.3"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin_version" }
|
reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin_version" }
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ sqldelight = "2.0.2"
|
|||||||
sqlite = "2.4.0"
|
sqlite = "2.4.0"
|
||||||
voyager = "1.0.0"
|
voyager = "1.0.0"
|
||||||
spotless = "7.0.0.BETA4"
|
spotless = "7.0.0.BETA4"
|
||||||
ktlint-core = "1.4.0"
|
ktlint-core = "1.4.1"
|
||||||
firebase-bom = "33.5.1"
|
firebase-bom = "33.5.1"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
desugar = "com.android.tools:desugar_jdk_libs:2.1.2"
|
desugar = "com.android.tools:desugar_jdk_libs:2.1.3"
|
||||||
android-shortcut-gradle = "com.github.zellius:android-shortcut-gradle-plugin:0.1.2"
|
android-shortcut-gradle = "com.github.zellius:android-shortcut-gradle-plugin:0.1.2"
|
||||||
|
|
||||||
rxjava = "io.reactivex:rxjava:1.3.8"
|
rxjava = "io.reactivex:rxjava:1.3.8"
|
||||||
@@ -28,7 +28,7 @@ conscrypt-android = "org.conscrypt:conscrypt-android:2.5.3"
|
|||||||
|
|
||||||
quickjs-android = "app.cash.quickjs:quickjs-android:0.9.2"
|
quickjs-android = "app.cash.quickjs:quickjs-android:0.9.2"
|
||||||
|
|
||||||
jsoup = "org.jsoup:jsoup:1.18.1"
|
jsoup = "org.jsoup:jsoup:1.18.2"
|
||||||
|
|
||||||
disklrucache = "com.jakewharton:disklrucache:2.0.2"
|
disklrucache = "com.jakewharton:disklrucache:2.0.2"
|
||||||
unifile = "com.github.tachiyomiorg:unifile:e0def6b3dc"
|
unifile = "com.github.tachiyomiorg:unifile:e0def6b3dc"
|
||||||
@@ -42,13 +42,13 @@ preferencektx = "androidx.preference:preference-ktx:1.2.1"
|
|||||||
|
|
||||||
injekt-core = "com.github.null2264:injekt-koin:ee267b2e27"
|
injekt-core = "com.github.null2264:injekt-koin:ee267b2e27"
|
||||||
|
|
||||||
coil-bom = { module = "io.coil-kt.coil3:coil-bom", version = "3.0.0-rc02" }
|
coil-bom = { module = "io.coil-kt.coil3:coil-bom", version = "3.0.4" }
|
||||||
coil-core = { module = "io.coil-kt.coil3:coil" }
|
coil-core = { module = "io.coil-kt.coil3:coil" }
|
||||||
coil-gif = { module = "io.coil-kt.coil3:coil-gif" }
|
coil-gif = { module = "io.coil-kt.coil3:coil-gif" }
|
||||||
coil-compose = { module = "io.coil-kt.coil3:coil-compose" }
|
coil-compose = { module = "io.coil-kt.coil3:coil-compose" }
|
||||||
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp" }
|
coil-network-okhttp = { module = "io.coil-kt.coil3:coil-network-okhttp" }
|
||||||
|
|
||||||
subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:b8e1b0ed2b"
|
subsamplingscaleimageview = "com.github.tachiyomiorg:subsampling-scale-image-view:66e0db195d"
|
||||||
image-decoder = "com.github.tachiyomiorg:image-decoder:41c059e540"
|
image-decoder = "com.github.tachiyomiorg:image-decoder:41c059e540"
|
||||||
|
|
||||||
natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1"
|
natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1"
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<plurals name="num_lock_times">
|
||||||
|
<item quantity="one">%d তালাবন্ধ সময়</item>
|
||||||
|
<item quantity="other">%d তালাবন্ধ সময়সমূহ</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="migrate_entry">
|
||||||
|
<item quantity="one">%1$d%2$s প্ৰৱেশ প্ৰব্ৰজন কৰা হব নেকি?</item>
|
||||||
|
<item quantity="other">%1$d%2$s প্ৰবিষ্টসমূহ প্ৰব্ৰজন কৰা হব নেকি?</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="copy_entry">
|
||||||
|
<item quantity="one">%1$d%2$s প্ৰৱেশ কপি কৰিবনে?</item>
|
||||||
|
<item quantity="other">%1$d%2$s প্ৰৱেশসমূহ কপি কৰিবনে?</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="entry_migrated">
|
||||||
|
<item quantity="one">%d প্ৰৱেশ স্থানান্তৰিত হৈছে</item>
|
||||||
|
<item quantity="other">%d প্ৰৱেশসমূহ স্থানান্তৰিত হৈছে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="num_pages">
|
||||||
|
<item quantity="one">%1$d পৃষ্ঠা</item>
|
||||||
|
<item quantity="other">%1$d পৃষ্ঠাসমূহ</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="browse_language_and_pages">
|
||||||
|
<item quantity="one">%2$s, %1$d পৃষ্ঠা</item>
|
||||||
|
<item quantity="other">%2$s, %1$d পৃষ্ঠাসমূহ</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_year">
|
||||||
|
<item quantity="one">%1$d বৰ্ষ পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d বৰ্ষৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_month">
|
||||||
|
<item quantity="one">%1$d মাহ পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d মাহৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_week">
|
||||||
|
<item quantity="one">%1$d সপ্তাহ পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d সপ্তাহৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_day">
|
||||||
|
<item quantity="one">%1$d দিন পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d দিনৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_hour">
|
||||||
|
<item quantity="one">%1$d ঘণ্টা পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d ঘণ্টাৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_minute">
|
||||||
|
<item quantity="one">%1$d মিনিট পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d মিনিটৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_second">
|
||||||
|
<item quantity="one">%1$d ছেকেণ্ড পূৰ্বে</item>
|
||||||
|
<item quantity="other">%1$d ছেকেণ্ডৰ পূৰ্বে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="row_count">
|
||||||
|
<item quantity="one">%d পংক্তি</item>
|
||||||
|
<item quantity="other">%d পংক্তিসমূহ</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="cleanup_done">
|
||||||
|
<item quantity="one">চাফাই কাম কৰা হ’ল। %d ফোল্ডাৰ আঁতৰোৱা হৈছে</item>
|
||||||
|
<item quantity="other">চাফাই কাম কৰা হ’ল। %d ফোল্ডাৰসমূহ আঁতৰোৱা হৈছে</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="eh_retry_toast">
|
||||||
|
<item quantity="one">পুনৰ চেষ্টা কৰিছে %1$d বিফল পৃষ্ঠা…</item>
|
||||||
|
<item quantity="other">পুনৰ চেষ্টা কৰিছে %1$d বিফল পৃষ্ঠাসমূহ…</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="pref_tag_sorting_desc">
|
||||||
|
<item quantity="one">%1$d টা টেগ শৃংখলাৰ সূচীত আছে। ই গ্ৰন্থাগাৰত এটা বিকল্প যোগ কৰে যাৰ সহায়ত অগ্ৰাধিকাৰ ভিত্তিত টেগ অনুসৰি শৃংখলা কৰিব পৰা যায়, অৰ্থাৎ আপুনি বিচৰা টেগৰ প্ৰাধান্য থকা বস্তুবোৰ সৰ্বপ্রথমে থাকিব।</item>
|
||||||
|
<item quantity="other">%1$d টেগ শৃংখলাৰ সূচীত আছে। ই গ্ৰন্থাগাৰত এটা বিকল্প যোগ কৰে যাৰ সহায়ত অগ্ৰাধিকাৰ ভিত্তিত টেগ অনুসৰি শৃংখলা কৰিব পৰা যায়, অৰ্থাৎ আপুনি বিচৰা টেগৰ প্ৰাধান্য থকা বস্তুবোৰ সৰ্বপ্রথমে থাকিব।</item>
|
||||||
|
</plurals>
|
||||||
|
</resources>
|
||||||
@@ -129,16 +129,7 @@
|
|||||||
<string name="gallery_updater_statistics">গ্যালাৰী আপডেটাৰ পৰিসংখ্যা</string>
|
<string name="gallery_updater_statistics">গ্যালাৰী আপডেটাৰ পৰিসংখ্যা</string>
|
||||||
<string name="gallery_updater_not_ran_yet">আপডেটাৰ এতিয়াও চলোৱা হোৱা নাই।</string>
|
<string name="gallery_updater_not_ran_yet">আপডেটাৰ এতিয়াও চলোৱা হোৱা নাই।</string>
|
||||||
<string name="gallery_updater_stats_text">আপডেটাৰ সৰ্বশেষ %1$s ত চলিছিল, আৰু %2$d গ্যালাৰীৰ ভিতৰত %3$d গ্যালাৰী পৰীক্ষা কৰিছিল যি পৰীক্ষাৰ বাবে প্রস্তুত আছিল।</string>
|
<string name="gallery_updater_stats_text">আপডেটাৰ সৰ্বশেষ %1$s ত চলিছিল, আৰু %2$d গ্যালাৰীৰ ভিতৰত %3$d গ্যালাৰী পৰীক্ষা কৰিছিল যি পৰীক্ষাৰ বাবে প্রস্তুত আছিল।</string>
|
||||||
<string name="gallery_updater_stats_time">"
|
<string name="gallery_updater_stats_time">\nশেষত পৰীক্ষা কৰা গেলেৰীসমূহ:\n- ঘন্টা: %1$d\n- ৬ ঘন্টা: %2$d\n- ১২ ঘন্টা: %3$d\n- দিন: %4$d\n- ২ দিন: %5$d\n- সপ্তাহ: %6$d\n- মাহ: %7$d\n- বছৰ: %8$d</string>
|
||||||
\nসর্বশেষ পৰীক্ষিত গ্যালাৰীৰ সংখ্যা:
|
|
||||||
\n- ১ ঘণ্টা: %1$d
|
|
||||||
\n- ৬ ঘণ্টা: %2$d
|
|
||||||
\n- ১২ ঘণ্টা: %3$d
|
|
||||||
\n- দিন: %4$d
|
|
||||||
\n- ২ দিন: %5$d
|
|
||||||
\n- সপ্তাহ: %6$d
|
|
||||||
\n- মাহ: %7$d
|
|
||||||
\n- বছৰ: %8$d"</string>
|
|
||||||
<string name="settings_profile_note">ছেটিংছ প্ৰফাইল নোট</string>
|
<string name="settings_profile_note">ছেটিংছ প্ৰফাইল নোট</string>
|
||||||
<string name="settings_profile_note_message">এপ্পে এতিয়া E-Hentai আৰু ExHentai ত নতুন ছেটিংছ প্ৰফাইল যোগ কৰিব যাতে এপ্পৰ কাৰ্যক্ষমতা উন্নত হয়। অনুগ্ৰহ কৰি নিশ্চিত কৰক যে আপোনাৰ দুইটা স্থানতে তিনিটা প্ৰফাইলৰ পৰা কম আছে।
|
<string name="settings_profile_note_message">এপ্পে এতিয়া E-Hentai আৰু ExHentai ত নতুন ছেটিংছ প্ৰফাইল যোগ কৰিব যাতে এপ্পৰ কাৰ্যক্ষমতা উন্নত হয়। অনুগ্ৰহ কৰি নিশ্চিত কৰক যে আপোনাৰ দুইটা স্থানতে তিনিটা প্ৰফাইলৰ পৰা কম আছে।
|
||||||
\n
|
\n
|
||||||
@@ -164,7 +155,7 @@
|
|||||||
<string name="enable_source_blacklist_summary">%1$s সँग অনুপযোগী এক্সটেনচনসমূহ/উৎসসমূহ লুকোৱা। পৰিবৰ্তনৰ পিছত এপ্প পুনৰ আৰম্ভ কৰক।</string>
|
<string name="enable_source_blacklist_summary">%1$s সँग অনুপযোগী এক্সটেনচনসমূহ/উৎসসমূহ লুকোৱা। পৰিবৰ্তনৰ পিছত এপ্প পুনৰ আৰম্ভ কৰক।</string>
|
||||||
<string name="open_debug_menu">ডিবাগ মেনু খোলক</string>
|
<string name="open_debug_menu">ডিবাগ মেনু খোলক</string>
|
||||||
<string name="clean_up_downloaded_chapters">ডাউনলোড কৰা অধ্যায়সমূহ পৰিস্কাৰ কৰক</string>
|
<string name="clean_up_downloaded_chapters">ডাউনলোড কৰা অধ্যায়সমূহ পৰিস্কাৰ কৰক</string>
|
||||||
<string name="open_debug_menu_summary">এই মেনুটি স্পর্শ নকৰিব যদি আপুনি কি কৰি আছে সেয়া জানেনে! <font color="red">এটি আপোনাৰ লাইব্ৰেৰী ক্ৰিয়া কৰিব পাৰে!</font></string>
|
<string name="open_debug_menu_summary"><![CDATA[এই মেনুটি স্পর্শ নকৰিব যদি আপুনি কি কৰি আছে সেয়া জানেনে! <font color=\'red\'>এটি আপোনাৰ লাইব্ৰেৰী ক্ৰিয়া কৰিব পাৰে!</font>]]></string>
|
||||||
<string name="delete_unused_chapters">অস্থিত্বৰ, আংশিকভাৱে ডাউনলোড কৰা, আৰু পঢ়া অধ্যায়ৰ ফোল্ডাৰ মচি পেলাওক</string>
|
<string name="delete_unused_chapters">অস্থিত্বৰ, আংশিকভাৱে ডাউনলোড কৰা, আৰু পঢ়া অধ্যায়ৰ ফোল্ডাৰ মচি পেলাওক</string>
|
||||||
<string name="no_folders_to_cleanup">পৰিস্কাৰ কৰিবলৈ কোনো ফোল্ডাৰ নাই</string>
|
<string name="no_folders_to_cleanup">পৰিস্কাৰ কৰিবলৈ কোনো ফোল্ডাৰ নাই</string>
|
||||||
<string name="clean_orphaned_downloads">অৰ্পিত ডাউনলোডসমূহ পৰিস্কাৰ কৰক</string>
|
<string name="clean_orphaned_downloads">অৰ্পিত ডাউনলোডসমূহ পৰিস্কাৰ কৰক</string>
|
||||||
@@ -495,10 +486,7 @@
|
|||||||
<string name="batch_add">বেটছ যোগ</string>
|
<string name="batch_add">বেটছ যোগ</string>
|
||||||
<string name="batch_add_ok">[ঠিক]</string>
|
<string name="batch_add_ok">[ঠিক]</string>
|
||||||
<string name="batch_add_error">[ভুল]</string>
|
<string name="batch_add_error">[ভুল]</string>
|
||||||
<string name="batch_add_summary">"
|
<string name="batch_add_summary">\nসাৰাংশ:\nযোগ কৰা হৈছে: %1$d গেলেৰী(সমূহ)\nব্যৰ্থ: %2$d গেলেৰী(সমূহ)</string>
|
||||||
\nসাৰাংশ:
|
|
||||||
\nযোগ কৰা হৈছে: %1$d গেছবুক
|
|
||||||
\nব্যৰ্থ: %2$d গেছবুক"</string>
|
|
||||||
<string name="batch_add_success_log_message">যোগ কৰা গেছবুক: %1$s</string>
|
<string name="batch_add_success_log_message">যোগ কৰা গেছবুক: %1$s</string>
|
||||||
<string name="batch_add_unknown_type_log_message">গেছবুকৰ বাবে অজানা প্ৰৱিষ্ট প্ৰকাৰ: %1$s</string>
|
<string name="batch_add_unknown_type_log_message">গেছবুকৰ বাবে অজানা প্ৰৱিষ্ট প্ৰকাৰ: %1$s</string>
|
||||||
<string name="batch_add_unknown_source_log_message">গেছবুকৰ বাবে অজানা উৎস: %1$s</string>
|
<string name="batch_add_unknown_source_log_message">গেছবুকৰ বাবে অজানা উৎস: %1$s</string>
|
||||||
|
|||||||
@@ -403,6 +403,9 @@
|
|||||||
<string name="artist_hint">Artist: %1$s</string>
|
<string name="artist_hint">Artist: %1$s</string>
|
||||||
<string name="thumbnail_url_hint">Thumbnail Url: %1$s</string>
|
<string name="thumbnail_url_hint">Thumbnail Url: %1$s</string>
|
||||||
<string name="multi_tags_comma_separated">Enter tag(s), seperated by commas.</string>
|
<string name="multi_tags_comma_separated">Enter tag(s), seperated by commas.</string>
|
||||||
|
<string name="select_tracker">Select a tracker</string>
|
||||||
|
<string name="entry_not_tracked">Entry is not tracked.</string>
|
||||||
|
<string name="fill_from_tracker">Fill from tracker</string>
|
||||||
|
|
||||||
<!-- Browse -->
|
<!-- Browse -->
|
||||||
<!-- Sources Tab -->
|
<!-- Sources Tab -->
|
||||||
@@ -515,6 +518,7 @@
|
|||||||
<string name="favorites_sync_removing_galleries">Removing %1$d galleries from remote server</string>
|
<string name="favorites_sync_removing_galleries">Removing %1$d galleries from remote server</string>
|
||||||
<string name="favorites_sync_unable_to_delete">Unable to delete galleries from the remote servers!</string>
|
<string name="favorites_sync_unable_to_delete">Unable to delete galleries from the remote servers!</string>
|
||||||
<string name="favorites_sync_adding_to_remote">Adding gallery %1$d of %2$d to remote server</string>
|
<string name="favorites_sync_adding_to_remote">Adding gallery %1$d of %2$d to remote server</string>
|
||||||
|
<string name="favorites_sync_unable_to_add_to_remote">Unable to add gallery to remote server: '%1$s' (GID: %2$s)!</string>
|
||||||
<string name="favorites_sync_remove_from_local">Removing gallery %1$d of %2$d from local library</string>
|
<string name="favorites_sync_remove_from_local">Removing gallery %1$d of %2$d from local library</string>
|
||||||
<string name="favorites_sync_add_to_local">Adding gallery %1$d of %2$d to local library</string>
|
<string name="favorites_sync_add_to_local">Adding gallery %1$d of %2$d to local library</string>
|
||||||
<string name="favorites_sync_remote_not_exist">Remote gallery does not exist, skipping: %1$s!</string>
|
<string name="favorites_sync_remote_not_exist">Remote gallery does not exist, skipping: %1$s!</string>
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
<string name="tag_watching_threshhold">Umbral de Monitoreo de Etiquetas</string>
|
<string name="tag_watching_threshhold">Umbral de Monitoreo de Etiquetas</string>
|
||||||
<string name="tag_watching_threshhold_summary">Las galerías recientemente subidas se incluirán en la pantalla de observación si tienen al menos una etiqueta observada con peso positivo, y la suma de los pesos de sus etiquetas observadas alcanza este valor o es mayor. Este umbral se puede establecer entre 0 y 9999. Actualmente: %1$d</string>
|
<string name="tag_watching_threshhold_summary">Las galerías recientemente subidas se incluirán en la pantalla de observación si tienen al menos una etiqueta observada con peso positivo, y la suma de los pesos de sus etiquetas observadas alcanza este valor o es mayor. Este umbral se puede establecer entre 0 y 9999. Actualmente: %1$d</string>
|
||||||
<string name="watched_list_default">Estado Predeterminado del Filtro de la Lista Observada</string>
|
<string name="watched_list_default">Estado Predeterminado del Filtro de la Lista Observada</string>
|
||||||
<string name="watched_list_state_summary">Al navegar por ExHentai/E-Hentai, ¿debería estar activado por defecto el filtro de la lista vigilada?</string>
|
<string name="watched_list_state_summary">Al navegar en ExHentai/E-Hentai, ¿debería estar habilitado el filtro de la lista de seguimiento de forma predeterminada?</string>
|
||||||
<string name="pref_enhanced_e_hentai_view_summary">Habilitar/Deshabilitar el menú de navegación mejorado hecho para E/ExHentai</string>
|
<string name="pref_enhanced_e_hentai_view_summary">Habilitar/Deshabilitar el menú de navegación mejorado hecho para E/ExHentai</string>
|
||||||
<string name="favorites_sync">Sincronización de Favoritos de E-Hentai</string>
|
<string name="favorites_sync">Sincronización de Favoritos de E-Hentai</string>
|
||||||
<string name="tag_filtering_threshhold_summary">Puedes filtrar suavemente las etiquetas añadiéndolas a la página Mis Etiquetas de E/ExHentai con un peso negativo. Si una galería tiene etiquetas que suman un peso inferior a este valor, se filtra de la vista. Este umbral se puede establecer entre -9999 y 0. Actualmente: %1$d</string>
|
<string name="tag_filtering_threshhold_summary">Puedes filtrar suavemente las etiquetas añadiéndolas a la página Mis Etiquetas de E/ExHentai con un peso negativo. Si una galería tiene etiquetas que suman un peso inferior a este valor, se filtra de la vista. Este umbral se puede establecer entre -9999 y 0. Actualmente: %1$d</string>
|
||||||
|
|||||||
@@ -268,7 +268,7 @@
|
|||||||
<string name="friday">Biyernes</string>
|
<string name="friday">Biyernes</string>
|
||||||
<string name="encrypt_database">I-encrypt ang database</string>
|
<string name="encrypt_database">I-encrypt ang database</string>
|
||||||
<string name="encrypt_database_subtitle">Kinakailangang mag-restart ng app upang magkabisa</string>
|
<string name="encrypt_database_subtitle">Kinakailangang mag-restart ng app upang magkabisa</string>
|
||||||
<string name="encrypt_database_message"><font color=\'red\'>ANG PAGPAPAGANA NITO AY GAGAWA NG BAGONG DATABASE. GAMITIN ANG MGA HAKBANG NA ITO UPANG MAPANATILI ANG IYONG DATA<br>1. MGA SETTING -> BACKUP -> GUMAWA<br>2. MGA SETTING NG SISTEMA -> I-CLEAR ANG APP DATA<br>3. BUKSAN ANG APP AT PAGANAHIN ITO<br>4. MGA SETTING NG SISTEMA -> PILITING MAG-RESTART<br>5. MGA SETTING -> BACKUP -> I-RESTORE</font></string>
|
<string name="encrypt_database_message"><![CDATA[<font color='red'>ANG PAGPAPAGANA NITO AY GAGAWA NG BAGONG DATABASE. GAMITIN ANG MGA HAKBANG NA ITO UPANG MAPANATILI ANG IYONG DATA<br>1. MGA SETTING -> BACKUP -> GUMAWA<br>2. MGA SETTING NG SISTEMA -> I-CLEAR ANG APP DATA<br>3. BUKSAN ANG APP AT PAGANAHIN ITO<br>4. MGA SETTING NG SISTEMA -> PILITING MAG-RESTART<br>5. MGA SETTING -> BACKUP -> I-RESTORE</font>]]></string>
|
||||||
<string name="set_cbz_zip_password">I-set ang archive password ng CBZ</string>
|
<string name="set_cbz_zip_password">I-set ang archive password ng CBZ</string>
|
||||||
<string name="password_protect_downloads">Protektahan ng password ang mga download</string>
|
<string name="password_protect_downloads">Protektahan ng password ang mga download</string>
|
||||||
<string name="delete_cbz_archive_password">Alisin ang password ng CBZ archive</string>
|
<string name="delete_cbz_archive_password">Alisin ang password ng CBZ archive</string>
|
||||||
@@ -498,9 +498,9 @@
|
|||||||
<string name="community_recommendations">Mga rekomendasyon ng komunidad</string>
|
<string name="community_recommendations">Mga rekomendasyon ng komunidad</string>
|
||||||
<string name="select_scanlators">Ipapakitang Scanlator group</string>
|
<string name="select_scanlators">Ipapakitang Scanlator group</string>
|
||||||
<string name="similar">Katulad sa %1$s</string>
|
<string name="similar">Katulad sa %1$s</string>
|
||||||
<string name="relation_similar">Katulad</string>
|
<string name="relation_similar">Katulad nito</string>
|
||||||
<string name="humanize_fallback">ilang sandali ang nakalipas</string>
|
<string name="humanize_fallback">ilang sandali ang nakalipas</string>
|
||||||
<string name="favorites_sync_notes_message">1. Ang mga pagbabago sa pangalan ng kategorya sa app ay <b>HINDI</b> nai-sync! Mangyaring <i>palitan ang pangalan ng kategorya sa ExHentai sa halip</i>. Ang mga pangalan ng kategorya ay kokopyahin mula sa ExHentai servers sa bawat pag-sync.<br><br>2. Ang mga paboritong kategorya sa ExHentai ay tumutukoy sa <b>unang 10 kategorya sa app</b> (hindi kasama ang \'Default\' na kategorya). <i>Ang mga gallery sa ibang mga kategorya ay <b>HINDI</b> nai-sync!</i><br><br>3. <font color=\'red\'><b>PANATALIHING MAY MALAKAS NA KONEKSYON NG INTERNET KAPAG NAGPRPROSESO NG PAG-SYNC!</b></font> Kung mawawalan ng koneksyon sa internet habang nag-sync ang app, ang iyong mga paborito ay maaaring maiwan sa isang <i>bahagyang nai-sync na estado</i>.<br><br>4. Panatilihing bukas ang app habang nag-sync ang mga paborito. Ang Android ay minsang nagsasara ng mga app na nasa background at maaaring hindi maganda kung mangyari ito habang nag-sisync ang app.<br><br>5. <b>Huwag ilagay ang mga paborito sa maraming kategorya</b> (suportado ito ng app). Maaari malilito ang algorithm ng pag-sync dahil pinapayagan lang ng ExH na ang bawat paborito ay nasa isang kategorya.<br><br> Ang dialog na ito ay lilitaw lamang ng isang beses. Maaari mong basahin muli ang mga tala na ito sa pamamagitan ng pagpunta sa \'Mga Setting > E-Hentai > Ipakita ang sync note ng mga paborito\'.</string>
|
<string name="favorites_sync_notes_message"><![CDATA[1. Ang mga pagbabago sa pangalan ng kategorya sa app ay <b>HINDI</b> nai-sync! Mangyaring <i>palitan ang pangalan ng kategorya sa ExHentai sa halip</i>. Ang mga pangalan ng kategorya ay kokopyahin mula sa ExHentai servers sa bawat pag-sync.<br><br>2. Ang mga paboritong kategorya sa ExHentai ay tumutukoy sa <b>unang 10 kategorya sa app</b> (hindi kasama ang 'Default' na kategorya). <i>Ang mga gallery sa ibang mga kategorya ay <b>HINDI</b> nai-sync!</i><br><br>3. <font color='red'><b>PANATALIHING MAY MALAKAS NA KONEKSYON NG INTERNET KAPAG NAGPRPROSESO NG PAG-SYNC!</b></font> Kung mawawalan ng koneksyon sa internet habang nag-sync ang app, ang iyong mga paborito ay maaaring maiwan sa isang <i>bahagyang nai-sync na estado</i>.<br><br>4. Panatilihing bukas ang app habang nag-sync ang mga paborito. Ang Android ay minsang nagsasara ng mga app na nasa background at maaaring hindi maganda kung mangyari ito habang nag-sisync ang app.<br><br>5. <b>Huwag ilagay ang mga paborito sa maraming kategorya</b> (suportado ito ng app). Maaari malilito ang algorithm ng pag-sync dahil pinapayagan lang ng ExH na ang bawat paborito ay nasa isang kategorya.<br><br> Ang dialog na ito ay lilitaw lamang ng isang beses. Maaari mong basahin muli ang mga tala na ito sa pamamagitan ng pagpunta sa 'Mga Setting > E-Hentai > Ipakita ang sync note ng mga paborito'.]]></string>
|
||||||
<string name="batch_add_unknown_type_log_message">Di-kilalang uri ng entry para sa gallery: %1$s</string>
|
<string name="batch_add_unknown_type_log_message">Di-kilalang uri ng entry para sa gallery: %1$s</string>
|
||||||
<string name="batch_add_summary">"
|
<string name="batch_add_summary">"
|
||||||
\nBuod:
|
\nBuod:
|
||||||
|
|||||||
@@ -1,2 +1,88 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources></resources>
|
<resources>
|
||||||
|
<plurals name="num_pages">
|
||||||
|
<item quantity="one">%1$d stranica</item>
|
||||||
|
<item quantity="few">%1$d stranice</item>
|
||||||
|
<item quantity="other">%1$d stranica</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="browse_language_and_pages">
|
||||||
|
<item quantity="one">%2$s, %1$d stranica</item>
|
||||||
|
<item quantity="few">%2$s, %1$d stranice</item>
|
||||||
|
<item quantity="other">%2$s, %1$d stranica</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="cleanup_done">
|
||||||
|
<item quantity="one">Čišćenje je gotovo. Uklonjena je %d mapa</item>
|
||||||
|
<item quantity="few">Čišćenje je gotovo. Uklonjene su %d mape</item>
|
||||||
|
<item quantity="other">Čišćenje je gotovo. Uklonjeno je %d mapa</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="num_lock_times">
|
||||||
|
<item quantity="one">%d vrijeme zaključavanja</item>
|
||||||
|
<item quantity="few">%d vremena zaključavanja</item>
|
||||||
|
<item quantity="other">%d vremena zaključavanja</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="migrate_entry">
|
||||||
|
<item quantity="one">Premjestiti %1$d%2$s unos?</item>
|
||||||
|
<item quantity="few">Premjestiti %1$d%2$s unosa?</item>
|
||||||
|
<item quantity="other">Premjestiti %1$d%2$s unosa?</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="eh_retry_toast">
|
||||||
|
<item quantity="one">Ponovni pokušaj %1$d neuspjele stranice…</item>
|
||||||
|
<item quantity="few">Ponovni pokušaj %1$d neuspjele stranice…</item>
|
||||||
|
<item quantity="other">Ponovni pokušaj %1$d neuspjelih stranica…</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="pref_tag_sorting_desc">
|
||||||
|
<item quantity="one">%1$d oznaka na popisu za razvrstavanje. Ovo dodaje opciju u biblioteci za razvrstavanje prema popisu oznaka temeljenom na prioritetu, što znači da će se unosi razvrstati na način da daju prioritet onima s oznakama koje želiš</item>
|
||||||
|
<item quantity="few">%1$d oznake na popisu za razvrstavanje. Ovo dodaje opciju u biblioteci za razvrstavanje prema popisu oznaka temeljenom na prioritetu, što znači da će se unosi razvrstati na način da daju prioritet onima s oznakama koje želiš</item>
|
||||||
|
<item quantity="other">%1$d oznaka na popisu za razvrstavanje. Ovo dodaje opciju u biblioteci za razvrstavanje prema popisu oznaka temeljenom na prioritetu, što znači da će se unosi razvrstati na način da daju prioritet onima s oznakama koje želiš</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="copy_entry">
|
||||||
|
<item quantity="one">Kopirati %1$d%2$s unos?</item>
|
||||||
|
<item quantity="few">Kopirati %1$d%2$s unosa?</item>
|
||||||
|
<item quantity="other">Kopirati %1$d%2$s unosa?</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="entry_migrated">
|
||||||
|
<item quantity="one">%d unos je premješten</item>
|
||||||
|
<item quantity="few">%d unosa su premještena</item>
|
||||||
|
<item quantity="other">%d unosa je premješteno</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_day">
|
||||||
|
<item quantity="one">Prije %1$d dan</item>
|
||||||
|
<item quantity="few">Prije %1$d dana</item>
|
||||||
|
<item quantity="other">Prije %1$d dana</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_hour">
|
||||||
|
<item quantity="one">Prije %1$d sat</item>
|
||||||
|
<item quantity="few">Prije %1$d sata</item>
|
||||||
|
<item quantity="other">Prije %1$d sati</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_minute">
|
||||||
|
<item quantity="one">Prije %1$d minute</item>
|
||||||
|
<item quantity="few">Prije %1$d minute</item>
|
||||||
|
<item quantity="other">Prije %1$d minuta</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_second">
|
||||||
|
<item quantity="one">Prije %1$d sekunde</item>
|
||||||
|
<item quantity="few">Prije %1$d sekunde</item>
|
||||||
|
<item quantity="other">Prije %1$d sekundi</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="row_count">
|
||||||
|
<item quantity="one">%d redak</item>
|
||||||
|
<item quantity="few">%d retka</item>
|
||||||
|
<item quantity="other">%d redaka</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_year">
|
||||||
|
<item quantity="one">Prije %1$d godine</item>
|
||||||
|
<item quantity="few">Prije %1$d godine</item>
|
||||||
|
<item quantity="other">Prije %1$d godina</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_month">
|
||||||
|
<item quantity="one">Prije %1$d mjesec</item>
|
||||||
|
<item quantity="few">Prije %1$d mjeseca</item>
|
||||||
|
<item quantity="other">Prije %1$d mjeseci</item>
|
||||||
|
</plurals>
|
||||||
|
<plurals name="humanize_week">
|
||||||
|
<item quantity="one">Prije %1$d tjedan</item>
|
||||||
|
<item quantity="few">Prije %1$d tjedna</item>
|
||||||
|
<item quantity="other">Prije %1$d tjedna</item>
|
||||||
|
</plurals>
|
||||||
|
</resources>
|
||||||
@@ -51,4 +51,6 @@
|
|||||||
<string name="time_between_batches_24_hours">24 sati</string>
|
<string name="time_between_batches_24_hours">24 sati</string>
|
||||||
<string name="time_between_batches_48_hours">48 sati</string>
|
<string name="time_between_batches_48_hours">48 sati</string>
|
||||||
<string name="gallery_updater_statistics_collection">Sakupljanje statisktike …</string>
|
<string name="gallery_updater_statistics_collection">Sakupljanje statisktike …</string>
|
||||||
|
<string name="all_read_entries">Svi pročitani unosi</string>
|
||||||
|
<string name="random">Nasumce</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<!-- Actions -->
|
<!-- Actions -->
|
||||||
<string name="action_skip_entry">Jangan pindahkan</string>
|
<string name="action_skip_entry">Jangan pindahkan</string>
|
||||||
<string name="action_search_manually">Cari manual</string>
|
<string name="action_search_manually">Cari secara manual</string>
|
||||||
<string name="action_migrate_now">Pindahkan</string>
|
<string name="action_migrate_now">Pindahkan sekarang</string>
|
||||||
<string name="action_copy_now">Salin</string>
|
<string name="action_copy_now">Salin</string>
|
||||||
<string name="action_clean_titles">Hapus judul</string>
|
<string name="action_clean_titles">Hapus judul</string>
|
||||||
<string name="action_start_reading">Mulai baca</string>
|
<string name="action_start_reading">Mulai baca</string>
|
||||||
@@ -33,17 +33,17 @@
|
|||||||
<string name="use_original_images">Use original images</string>
|
<string name="use_original_images">Use original images</string>
|
||||||
<string name="use_original_images_on">Currently using original images</string>
|
<string name="use_original_images_on">Currently using original images</string>
|
||||||
<string name="use_original_images_off">Currently using resampled images</string>
|
<string name="use_original_images_off">Currently using resampled images</string>
|
||||||
<string name="watched_tags">Watched Tags</string>
|
<string name="watched_tags">Tag yang telah dibaca</string>
|
||||||
<string name="watched_tags_summary">Opens a webview to your E/ExHentai watched tags page</string>
|
<string name="watched_tags_summary">Membuka tampilan web ke halaman tag yang telah Anda tonton di E/ExHentai</string>
|
||||||
<string name="watched_tags_exh">ExHentai Watched Tags</string>
|
<string name="watched_tags_exh">Tag yang Telah Ditonton di ExHentai</string>
|
||||||
<string name="tag_filtering_threshold">Tag Filtering Threshold</string>
|
<string name="tag_filtering_threshold">Batasan Pemfilteran Tag</string>
|
||||||
<string name="tag_filtering_threshhold_error">Must be between -9999 and 0!</string>
|
<string name="tag_filtering_threshhold_error">Harus diantara -9999 dan 0!</string>
|
||||||
<string name="tag_filtering_threshhold_summary">You can soft filter tags by adding them to the "My Tags" E/ExHentai page with a negative weight. If a gallery has tags that add up to weight below this value, it is filtered from view. This threshold can be set between -9999 and 0. Currently: %1$d</string>
|
<string name="tag_filtering_threshhold_summary">Anda dapat memfilter tag secara halus dengan menambahkannya ke halaman My Tags E/ExHentai dengan bobot negatif. Jika sebuah galeri memiliki tag yang jumlah bobotnya di bawah nilai ini, galeri tersebut akan disaring dari tampilan. Batasan ini dapat diatur antara -9999 dan 0. Saat ini: %1$d</string>
|
||||||
<string name="tag_watching_threshhold">Tag Watching Threshold</string>
|
<string name="tag_watching_threshhold">Batasan Pengawasan Tag</string>
|
||||||
<string name="tag_watching_threshhold_error">Must be between 0 and 9999!</string>
|
<string name="tag_watching_threshhold_error">Harus diantara 0 dan 9999!</string>
|
||||||
<string name="tag_watching_threshhold_summary">Recently uploaded galleries will be included on the watched screen if it has at least one watched tag with positive weight, and the sum of weights on its watched tags add up to this value or higher. This threshold can be set between 0 and 9999. Currently: %1$d</string>
|
<string name="tag_watching_threshhold_summary">Galeri yang baru diunggah akan ditampilkan di layar yang dilihat jika memiliki setidaknya satu tag yang dilihat dengan bobot positif, dan jumlah bobot pada tag yang dilihat mencapai nilai ini atau lebih tinggi. Batasan ini dapat diatur antara 0 dan 9999. Saat ini: %1$d</string>
|
||||||
<string name="language_filtering">Language Filtering</string>
|
<string name="language_filtering">Language Filtering</string>
|
||||||
<string name="language_filtering_summary">If you wish to hide galleries in certain languages from the gallery list and searches, select them in the dialog that will popup.\nNote that matching galleries will never appear regardless of your search query.\nTldr checkmarked = exclude</string>
|
<string name="language_filtering_summary">Jika Anda ingin menyembunyikan galeri dalam bahasa tertentu dari daftar galeri dan pencarian, pilih bahasa-bahasa tersebut dalam dialog yang akan muncul.\nPerhatikan bahwa galeri itu tidak akan pernah muncul terlepas dari kueri pencarian Anda.\nTL;DR: Centang = kecualikan.</string>
|
||||||
<string name="frong_page_categories">Front Page Categories</string>
|
<string name="frong_page_categories">Front Page Categories</string>
|
||||||
<string name="fromt_page_categories_summary">What categories would you like to show by default on the front page and in searches? They can still be enabled by enabling their filters</string>
|
<string name="fromt_page_categories_summary">What categories would you like to show by default on the front page and in searches? They can still be enabled by enabling their filters</string>
|
||||||
<string name="watched_list_default">Watched List Filter Default State</string>
|
<string name="watched_list_default">Watched List Filter Default State</string>
|
||||||
@@ -65,22 +65,22 @@
|
|||||||
<string name="show_favorite_sync_notes_summary">Show some information regarding the favorites sync feature</string>
|
<string name="show_favorite_sync_notes_summary">Show some information regarding the favorites sync feature</string>
|
||||||
<string name="please_login">Silahkan login!</string>
|
<string name="please_login">Silahkan login!</string>
|
||||||
<string name="ignore_sync_errors">Ignore sync errors when possible</string>
|
<string name="ignore_sync_errors">Ignore sync errors when possible</string>
|
||||||
<string name="ignore_sync_errors_summary">Do not abort immediately when encountering errors during the sync process. Errors will still be displayed when the sync is complete. Can cause loss of favorites in some cases. Useful when syncing large libraries.</string>
|
<string name="ignore_sync_errors_summary">Jangan langsung batalkan ketika menemui kesalahan selama proses sinkronisasi. Kesalahan tetap akan ditampilkan setelah sinkronisasi selesai. Dapat menyebabkan kehilangan favorit dalam beberapa kasus. Berguna saat menyinkronkan pustaka besar.</string>
|
||||||
<string name="force_sync_state_reset">Force sync state reset</string>
|
<string name="force_sync_state_reset">Paksa reset status sinkronisasi</string>
|
||||||
<string name="force_sync_state_reset_summary">Performs a full resynchronization on the next sync. Removals will not be synced. All favorites in the app will be re-uploaded to ExHentai and all favorites on ExHentai will be re-downloaded into the app. Useful for repairing sync after sync has been interrupted.</string>
|
<string name="force_sync_state_reset_summary">Melakukan resinkronisasi penuh pada sinkronisasi berikutnya. Penghapusan tidak akan disinkronkan. Semua favorit di aplikasi akan diunggah ulang ke ExHentai dan semua favorit di ExHentai akan diunduh ulang ke aplikasi. Berguna untuk memperbaiki sinkronisasi setelah sinkronisasi terhenti.</string>
|
||||||
<string name="sync_state_reset">Sync state reset</string>
|
<string name="sync_state_reset">Pengaturan ulang status sinkronisasi</string>
|
||||||
<string name="gallery_update_checker">Gallery update checker</string>
|
<string name="gallery_update_checker">Gallery update checker</string>
|
||||||
<string name="auto_update_restrictions">Auto update restrictions</string>
|
<string name="auto_update_restrictions">Auto update restrictions</string>
|
||||||
<string name="time_between_batches">Time between update batches</string>
|
<string name="time_between_batches">Time between update batches</string>
|
||||||
<string name="time_between_batches_never">Never update galleries</string>
|
<string name="time_between_batches_never">Never update galleries</string>
|
||||||
<string name="time_between_batches_1_hour">1 hour</string>
|
<string name="time_between_batches_1_hour">1 jam</string>
|
||||||
<string name="time_between_batches_2_hours">2 hours</string>
|
<string name="time_between_batches_2_hours">2 jam</string>
|
||||||
<string name="time_between_batches_3_hours">3 hours</string>
|
<string name="time_between_batches_3_hours">3 jam</string>
|
||||||
<string name="time_between_batches_6_hours">6 hours</string>
|
<string name="time_between_batches_6_hours">6 jam</string>
|
||||||
<string name="time_between_batches_12_hours">12 hours</string>
|
<string name="time_between_batches_12_hours">12 jam</string>
|
||||||
<string name="time_between_batches_24_hours">24 hours</string>
|
<string name="time_between_batches_24_hours">24 jam</string>
|
||||||
<string name="time_between_batches_48_hours">48 hours</string>
|
<string name="time_between_batches_48_hours">48 jam</string>
|
||||||
<string name="time_between_batches_summary_1">%1$s will currently never check galleries in your library for updates.</string>
|
<string name="time_between_batches_summary_1">%1$s saat ini tidak akan pernah memeriksa galeri di pustakamu untuk pembaruan.</string>
|
||||||
<string name="time_between_batches_summary_2">%1$s checks/updates galleries in batches. This means it will wait %2$d hour(s), check %3$d galleries, wait %2$d hour(s), check %3$d and so on…</string>
|
<string name="time_between_batches_summary_2">%1$s checks/updates galleries in batches. This means it will wait %2$d hour(s), check %3$d galleries, wait %2$d hour(s), check %3$d and so on…</string>
|
||||||
<string name="show_updater_statistics">Show updater statistics</string>
|
<string name="show_updater_statistics">Show updater statistics</string>
|
||||||
<string name="gallery_updater_statistics_collection">Collecting statistics…</string>
|
<string name="gallery_updater_statistics_collection">Collecting statistics…</string>
|
||||||
@@ -98,11 +98,11 @@
|
|||||||
<string name="eh_settings_uploading_to_server_message">Please wait, this may take some time…</string>
|
<string name="eh_settings_uploading_to_server_message">Please wait, this may take some time…</string>
|
||||||
<string name="eh_settings_out_of_slots_error">You are out of profile slots on %1$s, please delete a profile!</string>
|
<string name="eh_settings_out_of_slots_error">You are out of profile slots on %1$s, please delete a profile!</string>
|
||||||
<!-- EH Settings Login Activity -->
|
<!-- EH Settings Login Activity -->
|
||||||
<string name="recheck_login_status">Recheck login status</string>
|
<string name="recheck_login_status">Periksa ulang status login</string>
|
||||||
<string name="alternative_login_page">Alternative login page</string>
|
<string name="alternative_login_page">Halaman login alternatif</string>
|
||||||
<string name="skip_page_restyling">Skip page restyling</string>
|
<string name="skip_page_restyling">Lewati penataan ulang halaman</string>
|
||||||
<string name="custom_igneous_cookie">Custom igneous cookie</string>
|
<string name="custom_igneous_cookie">Cookie igneous kustom</string>
|
||||||
<string name="custom_igneous_cookie_message">Some users cannot access ExHentai the normal way, and have to pass in a specific igneous cookie value, this option is for those users.</string>
|
<string name="custom_igneous_cookie_message">Beberapa pengguna tidak dapat mengakses ExHentai dengan cara biasa, dan harus memasukkan nilai cookie igneous tertentu, opsi ini adalah untuk pengguna tersebut.</string>
|
||||||
<!-- Advanced Settings -->
|
<!-- Advanced Settings -->
|
||||||
<string name="developer_tools">Opsi Pengembang</string>
|
<string name="developer_tools">Opsi Pengembang</string>
|
||||||
<string name="toggle_hentai_features">Aktifkan fitur hentai terintegrasi</string>
|
<string name="toggle_hentai_features">Aktifkan fitur hentai terintegrasi</string>
|
||||||
@@ -220,7 +220,7 @@
|
|||||||
<string name="pref_force_horz_seekbar_summary">Menghapus seekbar vertikal sepenuhnya dan menggantikanya dengan seekbar horizontal</string>
|
<string name="pref_force_horz_seekbar_summary">Menghapus seekbar vertikal sepenuhnya dan menggantikanya dengan seekbar horizontal</string>
|
||||||
<!-- Reader -->
|
<!-- Reader -->
|
||||||
<!-- Reader Actions -->
|
<!-- Reader Actions -->
|
||||||
<string name="eh_autoscroll">Gulir otomatis</string>
|
<string name="eh_autoscroll">Gulir Otomatis</string>
|
||||||
<string name="eh_retry_all">Muat ulang</string>
|
<string name="eh_retry_all">Muat ulang</string>
|
||||||
<string name="eh_boost_page">Percepat halaman</string>
|
<string name="eh_boost_page">Percepat halaman</string>
|
||||||
<string name="eh_autoscroll_help">Panduan Gulir Otomatis</string>
|
<string name="eh_autoscroll_help">Panduan Gulir Otomatis</string>
|
||||||
@@ -269,8 +269,8 @@
|
|||||||
<string name="merged_already">Manga ini sudah tergabung dengan manga saat ini!</string>
|
<string name="merged_already">Manga ini sudah tergabung dengan manga saat ini!</string>
|
||||||
<string name="merge_duplicate">Manga gabungan ini adalah duplikat!</string>
|
<string name="merge_duplicate">Manga gabungan ini adalah duplikat!</string>
|
||||||
<!-- Manga Info Edit -->
|
<!-- Manga Info Edit -->
|
||||||
<string name="reset_tags">Reset Tagar</string>
|
<string name="reset_tags">Reset Tag</string>
|
||||||
<string name="add_tag">Tambah Tagar</string>
|
<string name="add_tag">Tambahkan Tag</string>
|
||||||
<string name="title_hint">Judul: %1$s</string>
|
<string name="title_hint">Judul: %1$s</string>
|
||||||
<string name="description_hint">Deskripsi: %1$s</string>
|
<string name="description_hint">Deskripsi: %1$s</string>
|
||||||
<string name="author_hint">Author: %1$s</string>
|
<string name="author_hint">Author: %1$s</string>
|
||||||
@@ -298,12 +298,12 @@
|
|||||||
<string name="no_source_categories">Tak ada kategori sumber yang tersedia</string>
|
<string name="no_source_categories">Tak ada kategori sumber yang tersedia</string>
|
||||||
<string name="invalid_category_name">Nama kategori tidak valid</string>
|
<string name="invalid_category_name">Nama kategori tidak valid</string>
|
||||||
<!-- Sort by tags -->
|
<!-- Sort by tags -->
|
||||||
<string name="pref_tag_sorting">Penyortir Tagar</string>
|
<string name="pref_tag_sorting">Penyortir Tag</string>
|
||||||
<string name="tag_sorting">Menyortir tagar</string>
|
<string name="tag_sorting">Menyortir Tag</string>
|
||||||
<string name="action_add_tags_message">Baca ini! Tagar harus sama persis,maka tidak akan berjalan semestinya!</string>
|
<string name="action_add_tags_message">Baca ini! Tag harus sama persis, tidak ada pencocokan parsial, Anda tidak dapat menggunakan netorare untuk memfilter \"female:netorare\" atau tag serupa!\nGaya untuk tag namespace adalah\n\"female: sole female\" \ntanpa tanda kutip!\nMenambahkan beberapa varian tag yang sama diperbolehkan, jadi jangan ragu untuk menggunakan \"tag: netorare\" untuk NHentai dan \"female: netorare\" untuk E-Hentai!</string>
|
||||||
<string name="action_edit_tags">Edit tagar</string>
|
<string name="action_edit_tags">Edit tag</string>
|
||||||
<string name="information_empty_tags">Kamu tidak memiliki tagar. Ketuk tombol tambah untuk membuatnya</string>
|
<string name="information_empty_tags">Kamu tidak memiliki tagar. Ketuk tombol tambah untuk membuatnya</string>
|
||||||
<string name="error_tag_exists">Tagar ini sudah ada!</string>
|
<string name="error_tag_exists">Tag ini sudah ada!</string>
|
||||||
<!-- Extension section -->
|
<!-- Extension section -->
|
||||||
<string name="ext_redundant">Duplikat</string>
|
<string name="ext_redundant">Duplikat</string>
|
||||||
<string name="redundant_extension_message">Ekstensi ini duplikat dan tak akan digunakan di dalam versi Tachiyomi ini.</string>
|
<string name="redundant_extension_message">Ekstensi ini duplikat dan tak akan digunakan di dalam versi Tachiyomi ini.</string>
|
||||||
@@ -319,13 +319,13 @@
|
|||||||
<string name="use_most_chapters">Pilih sumber dengan bab terbanyak (lambat)</string>
|
<string name="use_most_chapters">Pilih sumber dengan bab terbanyak (lambat)</string>
|
||||||
<string name="use_first_source">Pilih sumber yang pertama terdeteksi</string>
|
<string name="use_first_source">Pilih sumber yang pertama terdeteksi</string>
|
||||||
<string name="skip_this_step_next_time">Lewati langkah ini di lain waktu</string>
|
<string name="skip_this_step_next_time">Lewati langkah ini di lain waktu</string>
|
||||||
<string name="hide_not_found_entries">Sembunyikan manga yang tak ditemukan</string>
|
<string name="hide_not_found_entries">Sembunyikan komik yang tak ditemukan</string>
|
||||||
<string name="search_parameter">Parameter penelusuran (cth. language:english)</string>
|
<string name="search_parameter">Parameter penelusuran (cth. language:english)</string>
|
||||||
<string name="latest_">Terbaru: %1$s</string>
|
<string name="latest_">Terbaru: %1$s</string>
|
||||||
<string name="migrating_to">Pindahkan ke</string>
|
<string name="migrating_to">Pindahkan ke</string>
|
||||||
<string name="match_pinned_sources">Gunakan sumber yang disematkan</string>
|
<string name="match_pinned_sources">Gunakan sumber yang disematkan</string>
|
||||||
<string name="match_enabled_sources">Gunakan sumber yang diaktifkan</string>
|
<string name="match_enabled_sources">Gunakan sumber yang diaktifkan</string>
|
||||||
<string name="no_chapters_found_for_migration">Bab tak ditemukan, manga ini tak bisa dipindahkan ke sini</string>
|
<string name="no_chapters_found_for_migration">Bab tak ditemukan, komik ini tak bisa dipindahkan ke sini</string>
|
||||||
<string name="no_alternatives_found">Tidak Ditemukan</string>
|
<string name="no_alternatives_found">Tidak Ditemukan</string>
|
||||||
<string name="stop_migrating">Hentikan migrasi?</string>
|
<string name="stop_migrating">Hentikan migrasi?</string>
|
||||||
<string name="skipping_">(melewati %1$d)</string>
|
<string name="skipping_">(melewati %1$d)</string>
|
||||||
@@ -560,9 +560,9 @@
|
|||||||
<string name="google_drive_sync_data_not_found">Tidak ada data sinkronisasi yang ditemukan di Google Drive</string>
|
<string name="google_drive_sync_data_not_found">Tidak ada data sinkronisasi yang ditemukan di Google Drive</string>
|
||||||
<string name="google_drive_sync_data_purge_error">Kesalahan membersihkan data sinkronisasi dari Google Drive, Coba masuk lagi.</string>
|
<string name="google_drive_sync_data_purge_error">Kesalahan membersihkan data sinkronisasi dari Google Drive, Coba masuk lagi.</string>
|
||||||
<string name="google_drive_login_success">Masuk ke Google Drive</string>
|
<string name="google_drive_login_success">Masuk ke Google Drive</string>
|
||||||
<string name="pref_hide_feed">Sembunyikan tab Umpan</string>
|
<string name="pref_hide_feed">Sembunyikan tab Daftar Konten</string>
|
||||||
<string name="pref_feed_position">Posisi tab Umpan</string>
|
<string name="pref_feed_position">Posisi tab Daftar Konten</string>
|
||||||
<string name="pref_feed_position_summery">Apakah Anda ingin tab Umpan menjadi tab pertama dalam penjelajahan? Ini akan menjadikannya tab default saat membuka penjelajahan, tidak disarankan jika Anda menggunakan data atau jaringan terukur</string>
|
<string name="pref_feed_position_summery">Apakah Anda ingin tab Daftar Konten menjadi tab pertama dalam penjelajahan? Ini akan menjadikannya tab default saat membuka penjelajahan, tidak disarankan jika Anda menggunakan data atau jaringan terukur</string>
|
||||||
<string name="error_uploading_sync_data">Terjadi kesalahan saat mengunggah data sinkronisasi ke Google Drive</string>
|
<string name="error_uploading_sync_data">Terjadi kesalahan saat mengunggah data sinkronisasi ke Google Drive</string>
|
||||||
<string name="google_drive_login_failed">Gagal masuk ke Google Drive: %s</string>
|
<string name="google_drive_login_failed">Gagal masuk ke Google Drive: %s</string>
|
||||||
<string name="google_drive_not_signed_in">Belum masuk ke Google Drive</string>
|
<string name="google_drive_not_signed_in">Belum masuk ke Google Drive</string>
|
||||||
@@ -570,4 +570,79 @@
|
|||||||
<string name="error_deleting_google_drive_lock_file">Kesalahan saat menghapus file kunci Google Drive</string>
|
<string name="error_deleting_google_drive_lock_file">Kesalahan saat menghapus file kunci Google Drive</string>
|
||||||
<string name="error_before_sync_gdrive">Gagal sebelum sinkron: %s</string>
|
<string name="error_before_sync_gdrive">Gagal sebelum sinkron: %s</string>
|
||||||
<string name="pref_purge_confirmation_title">Konfirmasi pembersihan</string>
|
<string name="pref_purge_confirmation_title">Konfirmasi pembersihan</string>
|
||||||
|
<string name="sync_on_chapter_read">Sinkronisasi pada Bab Baca</string>
|
||||||
|
<string name="sync_on_chapter_open">Sinkronisasi pada Bab Terbuka</string>
|
||||||
|
<string name="sync_on_app_resume">Sinkronisasi pada saat Melanjutkan Aplikasi</string>
|
||||||
|
<string name="sync_library">Sinkronkan pustaka</string>
|
||||||
|
<string name="delete_time_range_confirmation">Apakah Anda ingin menghapus rentang waktu %s?</string>
|
||||||
|
<string name="encrypt_database_subtitle">Membutuhkan restart aplikasi untuk menerapkannya</string>
|
||||||
|
<string name="set_cbz_zip_password">Tetapkan kata sandi arsip CBZ</string>
|
||||||
|
<string name="pref_sync_options_summ">Dapat digunakan untuk mengatur pemicu sinkronisasi</string>
|
||||||
|
<string name="encrypt_database">Enkripsi database</string>
|
||||||
|
<string name="pref_purge_confirmation_message">Menghapus data sinkronisasi akan menghapus semua data sinkronisasi dari Google Drive. Apakah Anda yakin ingin melanjutkan?</string>
|
||||||
|
<string name="sync_on_app_start">Sinkronisasi pada saat Aplikasi Dibuka</string>
|
||||||
|
<string name="delete_time_range">Hapus rentang waktu</string>
|
||||||
|
<string name="encrypt_database_message"><![CDATA[<font color=\'red\'>MENGAKTIFKAN INI AKAN MEMBUAT DATABASE BARU. GUNAKAN LANGKAH-LANGKAH INI UNTUK MENYIMPAN DATA ANDA<br>1. PENGATURAN -> CADANGAN -> BUAT<br>2. PENGATURAN SISTEM -> HAPUS DATA APLIKASI<br>3. BUKA APLIKASI DAN AKTIFKAN INI<br>4. PENGATURAN SISTEM -> PAKSA MULAI ULANG<br>5. PENGATURAN -> CADANGAN -> PULIHKAN</font>]]></string>
|
||||||
|
<string name="favorites_sync_conformation_message">Apakah Anda yakin untuk menyinkronkan favorit Anda dengan E-Hentai?</string>
|
||||||
|
<string name="relation_similar">Mirip</string>
|
||||||
|
<string name="relation_prequel">Prekuel</string>
|
||||||
|
<string name="alt_titles">Judul-Judul Alternatif</string>
|
||||||
|
<string name="encryption_type">Tipe enkripsi</string>
|
||||||
|
<string name="aes_256">AES 256</string>
|
||||||
|
<string name="relation_adapted_from">Diadaptasi dari</string>
|
||||||
|
<string name="relation_based_on">Berdasarkan dari</string>
|
||||||
|
<string name="relation_side_story">Cerita Sampingan</string>
|
||||||
|
<string name="relation_colored">Berwarna</string>
|
||||||
|
<string name="relation_serialization">Serialisasi</string>
|
||||||
|
<string name="action_copy_second_page">Salin halaman kedua</string>
|
||||||
|
<string name="action_copy_combined_page">Salin halaman gabungan</string>
|
||||||
|
<string name="action_copy_first_page">Salin halaman pertama</string>
|
||||||
|
<string name="page_preview_page_go_to">Pergi ke</string>
|
||||||
|
<string name="aes_128">AES 128</string>
|
||||||
|
<string name="community_recommendations">Rekomendasi komunitas</string>
|
||||||
|
<string name="relation_monochrome">Monokrom</string>
|
||||||
|
<string name="relation_main_story">Cerita Utama</string>
|
||||||
|
<string name="relation_doujinshi">Doujinshi</string>
|
||||||
|
<string name="relation_alternate_version">Versi Alternatif</string>
|
||||||
|
<string name="standard_zip_encryption">Enkripsi zip standar (cepat tetapi kurang aman)</string>
|
||||||
|
<string name="center_margin_double_and_wide_page">Tambahkan ke keduanya</string>
|
||||||
|
<string name="delete_tag">Hapus tag</string>
|
||||||
|
<string name="action_stop">Berhenti</string>
|
||||||
|
<string name="relation_sequel">Sekuel</string>
|
||||||
|
<string name="relation_alternate_story">Cerita alternatif</string>
|
||||||
|
<string name="feed_tab_empty">Anda tidak memiliki sumber apapun di daftar konten Anda, navigasikan ke kanan atas untuk menambahkan satu</string>
|
||||||
|
<string name="only_show_updated_entries">Tampilkan hanyak komik dengan bab baru</string>
|
||||||
|
<string name="archive_mode_cache_to_disk">Salin ke disk penyimpanan</string>
|
||||||
|
<string name="pref_archive_reader_mode">Mode pembaca arsip</string>
|
||||||
|
<string name="add_tags">Tambahkan Tag</string>
|
||||||
|
<string name="delete_cbz_archive_password">Hapus kata sandi arsip CBZ</string>
|
||||||
|
<string name="cbz_archive_password">Kata sandi arsip CBZ</string>
|
||||||
|
<string name="center_margin_none">Tidak Ada</string>
|
||||||
|
<string name="archive_mode_load_from_file">Muat dari berkas</string>
|
||||||
|
<string name="archive_mode_load_into_memory">Muatkan ke memori</string>
|
||||||
|
<string name="password_protect_downloads">Lindungi unduhan dengan kata sandi</string>
|
||||||
|
<string name="page_previews">Pratinjau halaman</string>
|
||||||
|
<string name="multi_tags_comma_separated">Masukkan tag, dipisahkan dengan koma.</string>
|
||||||
|
<string name="include_all_read_entries">Sertakan semua komik yang telah dibaca</string>
|
||||||
|
<string name="ignore_non_library_entries">Abaikan komik yang bukan bagian dari pustaka</string>
|
||||||
|
<string name="pref_clear_page_preview_cache">Hapus data yang tersimpan untuk pratinjau halaman</string>
|
||||||
|
<string name="password_protect_downloads_summary">Mengenkripsi unduhan arsip CBZ dengan kata sandi yang diberikan.\nPERINGATAN: DATA YANG ADA DI DALAM ARSIP AKAN HILANG SELAMANYA JIKA ANDA LUPA KATA SANDI</string>
|
||||||
|
<string name="feed_add">Tambahkan %1$s ke daftar konten?</string>
|
||||||
|
<string name="more_previews">Pratinjau lebih banyak</string>
|
||||||
|
<string name="pref_smooth_scroll">Gulir Otomatis Halus</string>
|
||||||
|
<string name="eh_autoscroll_freq_invalid">Frekuensi tidak valid</string>
|
||||||
|
<string name="save_search_invalid_name">Nama pencarian yang disimpan tidak valid</string>
|
||||||
|
<string name="relation_same_franchise">Franchise yang sama</string>
|
||||||
|
<string name="wrong_cbz_archive_password">Kata sandi arsip CBZ salah</string>
|
||||||
|
<string name="delete_tag_confirmation">Apakah Anda ingin menghapus tag %s?</string>
|
||||||
|
<string name="reset_info">Atur Ulang Info</string>
|
||||||
|
<string name="pref_archive_reader_mode_summary">Cara gambar di dalam arsip, seperti CBZ atau CBR, dimuat</string>
|
||||||
|
<string name="feed_delete">Hapus sumber dari daftar konten?</string>
|
||||||
|
<string name="pref_center_margin">Tipe margin tengah</string>
|
||||||
|
<string name="center_margin">Margin Tengah</string>
|
||||||
|
<string name="pref_center_margin_summary">Tambahkan pengisi ruang untuk mengakomodasi ruang kosong pada perangkat lipat.</string>
|
||||||
|
<string name="center_margin_double_page">Tambahkan ke Halaman ganda</string>
|
||||||
|
<string name="center_margin_wide_page">Tambahkan ke Halaman lebar</string>
|
||||||
|
<string name="feed">Daftar Konten</string>
|
||||||
|
<string name="too_many_in_feed">Terlalu banyak sumber di daftar konten Anda, tidak dapat menambahkan lebih dari 10</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -4,4 +4,17 @@
|
|||||||
<string name="action_search_manually">Cerca manualmente</string>
|
<string name="action_search_manually">Cerca manualmente</string>
|
||||||
<string name="action_migrate_now">Migra ora</string>
|
<string name="action_migrate_now">Migra ora</string>
|
||||||
<string name="action_copy_now">Copia ora</string>
|
<string name="action_copy_now">Copia ora</string>
|
||||||
|
<string name="entry_type_webtoon">Webtoon</string>
|
||||||
|
<string name="entry_type_comic">Fumetto</string>
|
||||||
|
<string name="entry_type_manhua">Manhua</string>
|
||||||
|
<string name="pref_category_mangadex">MangaDex</string>
|
||||||
|
<string name="pref_category_fork">Impostazioni Fork</string>
|
||||||
|
<string name="action_start_reading">Inizia a leggere</string>
|
||||||
|
<string name="action_clean_titles">Titoli puliti</string>
|
||||||
|
<string name="changelog_version">Versione %1$s</string>
|
||||||
|
<string name="pref_mangadex_summary">Accesso MangaDex, sincronizzazione dei seguiti</string>
|
||||||
|
<string name="pref_ehentai_summary">Accesso E/ExHentai, sincronizzazione galleria</string>
|
||||||
|
<string name="action_edit_info">Modifica info</string>
|
||||||
|
<string name="pref_category_eh">E-Hentai</string>
|
||||||
|
<string name="pref_category_all_sources">Tutte le Fonti</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -277,7 +277,7 @@
|
|||||||
<string name="pref_tag_sorting">Tags de ordenação de tag</string>
|
<string name="pref_tag_sorting">Tags de ordenação de tag</string>
|
||||||
<string name="tag_sorting">Ordenação de tag</string>
|
<string name="tag_sorting">Ordenação de tag</string>
|
||||||
<string name="action_add_tags_message">Leia isto! Tags devem ser exatas, não há combinação parcial, não pode fazer netorare filtrar female:netorare ou similar!\nO estilo para tags é\n\"female: sole female\"\nsem aspas!\nAdicionar variantes da mesma tag é suportado, então pode-se fazer \"tag: netorare\" para NHentai e \"female: netorare\" para E-Hentai!</string>
|
<string name="action_add_tags_message">Leia isto! Tags devem ser exatas, não há combinação parcial, não pode fazer netorare filtrar female:netorare ou similar!\nO estilo para tags é\n\"female: sole female\"\nsem aspas!\nAdicionar variantes da mesma tag é suportado, então pode-se fazer \"tag: netorare\" para NHentai e \"female: netorare\" para E-Hentai!</string>
|
||||||
<string name="action_edit_tags">Edit\r tags</string>
|
<string name="action_edit_tags">Editar tags</string>
|
||||||
<string name="information_empty_tags">Você não tem tags. Toque no botão Adicionar para criar um e ordenar sua biblioteca por tags</string>
|
<string name="information_empty_tags">Você não tem tags. Toque no botão Adicionar para criar um e ordenar sua biblioteca por tags</string>
|
||||||
<string name="error_tag_exists">Esta tag já existe!</string>
|
<string name="error_tag_exists">Esta tag já existe!</string>
|
||||||
<!-- Extension section -->
|
<!-- Extension section -->
|
||||||
@@ -501,4 +501,138 @@
|
|||||||
<string name="update_1hour">A cada hora</string>
|
<string name="update_1hour">A cada hora</string>
|
||||||
<string name="pref_hide_feed">Ocultar a aba do feed</string>
|
<string name="pref_hide_feed">Ocultar a aba do feed</string>
|
||||||
<string name="pref_library_mark_duplicate_chapters">Marque os novos capítulos duplicados como lidos</string>
|
<string name="pref_library_mark_duplicate_chapters">Marque os novos capítulos duplicados como lidos</string>
|
||||||
|
<string name="last_synchronization">Última Sincronização: %1$s</string>
|
||||||
|
<string name="bandwidth_data_saver_server">Servidor Proxy Bandwidth Hero</string>
|
||||||
|
<string name="sync_error">Falha ao sincronizar biblioteca</string>
|
||||||
|
<string name="sync_complete">Sincronização de biblioteca completa</string>
|
||||||
|
<string name="pref_sync_host">Host</string>
|
||||||
|
<string name="pref_sync_api_key">Chave API</string>
|
||||||
|
<string name="pref_sync_api_key_summ">Coloque sua chave API para sincronizar sua biblioteca</string>
|
||||||
|
<string name="pref_choose_what_to_sync">Escolha o que sincronizar</string>
|
||||||
|
<string name="syncyomi">SyncYomi</string>
|
||||||
|
<string name="google_drive">Google Drive</string>
|
||||||
|
<string name="pref_google_drive_sign_in">Login</string>
|
||||||
|
<string name="pref_google_drive_purge_sync_data">Limpar dados sincronizados do Google Drive</string>
|
||||||
|
<string name="google_drive_sync_data_purged">Sincronizar dados purgados do Google Drive</string>
|
||||||
|
<string name="google_drive_login_success">Login no Google Drive feito com sucesso</string>
|
||||||
|
<string name="google_drive_not_signed_in">Não está logado no Google Drive</string>
|
||||||
|
<string name="error_uploading_sync_data">Erro enviando dados de sincronia para o Google Drive</string>
|
||||||
|
<string name="error_before_sync_gdrive">Erro antes de sincronia: %s</string>
|
||||||
|
<string name="pref_purge_confirmation_message">Limpar dados sincronizados irá deletar todos os seus dados de sincronia do Google Drive. Você quer continuar?</string>
|
||||||
|
<string name="google_drive_sync_data_not_found">Não foram encontrados dados para sincronia no Google Drive</string>
|
||||||
|
<string name="google_drive_login_failed">Falha ao fazer login no Google Drive: %s</string>
|
||||||
|
<string name="pref_sync_service_category">Sincronização</string>
|
||||||
|
<string name="label_sync">Sincronizar</string>
|
||||||
|
<string name="pref_sync_host_summ">Coloque o endereço de hospedagem para sincronizar sua biblioteca</string>
|
||||||
|
<string name="pref_sync_service">Serviço</string>
|
||||||
|
<string name="sync_in_progress">Sincronização está em progresso</string>
|
||||||
|
<string name="google_drive_sync_data_purge_error">Erro purgando dados de sincronia do Google Drive. Tente fazer login novamente.</string>
|
||||||
|
<string name="data_saver_downloader">Usar economia de dados no baixador</string>
|
||||||
|
<string name="bandwidth_hero">Bandwidth Hero (Requer um servidor proxy Bandwidth Hero)</string>
|
||||||
|
<string name="wsrv">wsrv.nl</string>
|
||||||
|
<string name="put_merge_in_overflow">Mesclar em transborde</string>
|
||||||
|
<string name="put_merge_in_overflow_summary">Colocar o botão de mesclar no menu de transborde ao invés da pagina inicial</string>
|
||||||
|
<string name="pref_feed_position_summery">Você quer que a aba Feed seja a primeira aba em Navegar? Isso irá fazer dela a aba principal ao abrir Navegar, não é recomendado se você estiver usando uma rede medida ou dados móveis</string>
|
||||||
|
<string name="label_triggers">Gatilhos</string>
|
||||||
|
<string name="pref_sync_now_group_title">Sincronizar Ações</string>
|
||||||
|
<string name="pref_sync_now">Sincronizar agora</string>
|
||||||
|
<string name="pref_sync_now_subtitle">Iniciar sincronização imediata de seus dados</string>
|
||||||
|
<string name="pref_sync_automatic_category">Sincronização Automática</string>
|
||||||
|
<string name="pref_sync_interval">Frequência de sincronização</string>
|
||||||
|
<string name="error_deleting_google_drive_lock_file">Error ao Deletar Ficheiro de Bloqueio no Google Drive</string>
|
||||||
|
<string name="pref_sync_options_summ">Pode ser usado para criar gatilhos de sincronização</string>
|
||||||
|
<string name="sync_on_chapter_read">Sincronizar após Leitura de Capitulo</string>
|
||||||
|
<string name="pref_purge_confirmation_title">Confirmação de Limpeza</string>
|
||||||
|
<string name="pref_sync_options">Criar gatilhos de sincronização</string>
|
||||||
|
<string name="sync_on_chapter_open">Sincronizar após Capítulo Aberto</string>
|
||||||
|
<string name="sync_on_app_start">Sincronizar na Abertura da Aplicação</string>
|
||||||
|
<string name="pref_ehentai_summary">E/ExHentai login, sincronizar galeria</string>
|
||||||
|
<string name="pref_mangadex_summary">MangaDex login, segue sincronização</string>
|
||||||
|
<string name="sync_library">Sincronizar biblioteca</string>
|
||||||
|
<string name="delete_time_range">Excluir intervalo de tempo</string>
|
||||||
|
<string name="encrypt_database">Criptografar banco de dados</string>
|
||||||
|
<string name="encrypt_database_subtitle">Requer reinicialização do aplicativo para confirmar as alterações</string>
|
||||||
|
<string name="password_protect_downloads">Proteja os downloads com senha</string>
|
||||||
|
<string name="sync_on_app_resume">Sincronizar no aplicativo ao Retomar</string>
|
||||||
|
<string name="set_cbz_zip_password">Definir senha de arquivo CBZ</string>
|
||||||
|
<string name="action_copy_first_page">Copie a primeira página</string>
|
||||||
|
<string name="center_margin">Margem central</string>
|
||||||
|
<string name="thumbnail_url_hint">URL da miniatura: %1$s</string>
|
||||||
|
<string name="dedupe_most_chapters">Mostrar fonte com mais capítulos</string>
|
||||||
|
<string name="favorites_sync_conformation_message">Tem certeza de que deseja sincronizar seus favoritos com o E-Hentai?</string>
|
||||||
|
<string name="relation_same_franchise">Mesma franquia</string>
|
||||||
|
<string name="multi_tags_comma_separated">Insira as tag(s), separadas por vírgulas.</string>
|
||||||
|
<string name="delete_time_range_confirmation">Você deseja excluir o intervalo de tempo %s?</string>
|
||||||
|
<string name="artist_hint">Artista: %1$s</string>
|
||||||
|
<string name="delete_tag_confirmation">Você deseja excluir a tag %s?</string>
|
||||||
|
<string name="page_previews">Pré-visualizações de página</string>
|
||||||
|
<string name="pref_clear_page_preview_cache">Limpar cache de visualização de página</string>
|
||||||
|
<string name="action_copy_combined_page">Copiar página combinada</string>
|
||||||
|
<string name="action_copy_second_page">Copie a segunda página</string>
|
||||||
|
<string name="add_tags">Adicionar tags</string>
|
||||||
|
<string name="alt_titles">Títulos Alternativos</string>
|
||||||
|
<string name="relation_monochrome">Monocromático</string>
|
||||||
|
<string name="relation_colored">Colorido</string>
|
||||||
|
<string name="relation_serialization">Serialização</string>
|
||||||
|
<string name="include_all_read_entries">Incluir todas as entradas lidas</string>
|
||||||
|
<string name="ignore_non_library_entries">Ignorar entradas que não sejam da biblioteca</string>
|
||||||
|
<string name="community_recommendations">Recomendações da comunidade</string>
|
||||||
|
<string name="page_preview_page_go_to">Vá para</string>
|
||||||
|
<string name="relation_based_on">Baseado em</string>
|
||||||
|
<string name="relation_similar">Semelhante</string>
|
||||||
|
<string name="relation_main_story">História principal</string>
|
||||||
|
<string name="relation_side_story">História paralela</string>
|
||||||
|
<string name="relation_doujinshi">Doujinshi</string>
|
||||||
|
<string name="relation_alternate_story">História alternativa</string>
|
||||||
|
<string name="eh_boost_page_invalid">Esta página não pode ser impulsionada (página inválida)!</string>
|
||||||
|
<string name="eh_boost_page_downloading">Esta página já está sendo baixada!</string>
|
||||||
|
<string name="eh_boost_page_downloaded">Esta página já foi baixada!</string>
|
||||||
|
<string name="center_margin_none">Nenhum</string>
|
||||||
|
<string name="center_margin_wide_page">Adicionar à página ampla</string>
|
||||||
|
<string name="pref_center_margin">Tipo de margem central</string>
|
||||||
|
<string name="merge_duplicate">Esta entrada mesclada é uma duplicata!</string>
|
||||||
|
<string name="hide_not_found_entries">Ocultar resultados não encontrados</string>
|
||||||
|
<string name="more_previews">Mais prévias</string>
|
||||||
|
<string name="dedupe_highest_chapter">Mostrar fonte com maior número de capítulo</string>
|
||||||
|
<string name="mangadex_similar">MangaDex semelhante</string>
|
||||||
|
<string name="relation_shared_universe">Universo compartilhado</string>
|
||||||
|
<string name="relation_alternate_version">Versão alternativa</string>
|
||||||
|
<string name="merge_unknown_entry">ID de entrada desconhecida: %1$d</string>
|
||||||
|
<string name="only_show_updated_entries">Mostrar apenas resultados com novos capítulos</string>
|
||||||
|
<string name="relation_preserialization">Pré-serialização</string>
|
||||||
|
<string name="entry_merged">Entrada mesclada!</string>
|
||||||
|
<string name="eh_autoscroll_freq_invalid">Frequência inválida</string>
|
||||||
|
<string name="delete_cbz_archive_password">Excluir senha do arquivo CBZ</string>
|
||||||
|
<string name="center_margin_double_page">Adicionar à página dupla</string>
|
||||||
|
<string name="eh_boost_boosted">Página atual impulsionada!</string>
|
||||||
|
<string name="wrong_cbz_archive_password">Senha de arquivo CBZ errada</string>
|
||||||
|
<string name="feed_tab_empty">Você não tem nenhuma fonte em seu feed, navegue até o canto superior direito para adicionar uma</string>
|
||||||
|
<string name="data_saver_exclude">Excluir da proteção de dados</string>
|
||||||
|
<string name="relation_spin_off">Spin off</string>
|
||||||
|
<string name="relation_adapted_from">Adaptado de</string>
|
||||||
|
<string name="automatic_search_error">Erro ao executar pesquisa automática!</string>
|
||||||
|
<string name="password_protect_downloads_summary">Criptografa downloads de arquivo CBZ com a senha fornecida.\nAVISO: OS DADOS DENTRO DOS ARQUIVOS SERÃO PERDIDOS PARA SEMPRE SE VOCÊ ESQUECER A SENHA</string>
|
||||||
|
<string name="cbz_archive_password">Senha do arquivo CBZ</string>
|
||||||
|
<string name="encryption_type">Tipo de criptografia</string>
|
||||||
|
<string name="standard_zip_encryption">Criptografia zip padrão (rápida, mas insegura)</string>
|
||||||
|
<string name="pref_smooth_scroll">Rolagem automática suave</string>
|
||||||
|
<string name="eh_boost_page_errored">A página não carregou, pressione o botão de tentar novamente!</string>
|
||||||
|
<string name="center_margin_double_and_wide_page">Adicionar a ambos</string>
|
||||||
|
<string name="archive_mode_load_into_memory">Carregar na memória</string>
|
||||||
|
<string name="archive_mode_cache_to_disk">Copiar para o disco</string>
|
||||||
|
<string name="pref_archive_reader_mode">Modo de leitor de arquivo</string>
|
||||||
|
<string name="archive_mode_load_from_file">Carregar do arquivo</string>
|
||||||
|
<string name="merged_already">Esta entrada já foi mesclada com a entrada atual!</string>
|
||||||
|
<string name="reset_info">Redefinir informações</string>
|
||||||
|
<string name="title_hint">Título: %1$s</string>
|
||||||
|
<string name="description_hint">Descrição: %1$s</string>
|
||||||
|
<string name="author_hint">Autor: %1$s</string>
|
||||||
|
<string name="could_not_find_entry">Não foi possível encontrar o resultado na fonte!</string>
|
||||||
|
<string name="save_search_invalid">Pesquisa salva inválida, filtros foram alterados</string>
|
||||||
|
<string name="save_search_invalid_name">Nome de pesquisa salva inválido</string>
|
||||||
|
<string name="feed_delete">Excluir item do feed?</string>
|
||||||
|
<string name="feed_add">Adicionar %1$s ao feed?</string>
|
||||||
|
<string name="delete_tag">Excluir tag</string>
|
||||||
|
<string name="too_many_in_feed">Muitas fontes no seu feed, não é possível adicionar mais de 10</string>
|
||||||
|
<string name="action_stop">Parar</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="action_clean_titles">Limpar Títulos</string>
|
||||||
|
<string name="action_edit_info">Editar informação</string>
|
||||||
|
<string name="entry_type_manhua">Manhua</string>
|
||||||
|
<string name="entry_type_comic">Banda Desenhada</string>
|
||||||
|
<string name="entry_type_webtoon">Webtoon</string>
|
||||||
|
<string name="pref_category_all_sources">Todas as fontes</string>
|
||||||
|
<string name="pref_category_eh">E-Hentai</string>
|
||||||
|
<string name="action_skip_entry">Não migrar</string>
|
||||||
|
<string name="action_migrate_now">Migrar agora</string>
|
||||||
|
<string name="action_search_manually">Procurar Manualmente</string>
|
||||||
|
<string name="entry_type_manga">Manga</string>
|
||||||
|
<string name="entry_type_manhwa">Manhwa</string>
|
||||||
|
<string name="action_copy_now">Copiar agora</string>
|
||||||
|
<string name="action_start_reading">Começar a ler</string>
|
||||||
|
<string name="ehentai_prefs_account_settings">Definições de Conta E-Hentai Website</string>
|
||||||
|
<string name="requires_login">Login Necessário</string>
|
||||||
|
<string name="use_hentai_at_home">Utilizar Hentai@Home Network</string>
|
||||||
|
<string name="pref_ehentai_summary">E/ExHentai login, sincronização da galeria</string>
|
||||||
|
<string name="pref_mangadex_summary">MangaDex login, sincronização de seguidores</string>
|
||||||
|
<string name="changelog_version">Versão %1$s</string>
|
||||||
|
<string name="enable_exhentai">Ativar ExHentai</string>
|
||||||
|
<string name="watched_tags_exh">ExHentai Categorias Visualizadas</string>
|
||||||
|
</resources>
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="action_search_manually">El ile ara</string>
|
<string name="action_search_manually">Manuel arama</string>
|
||||||
<string name="action_copy_now">Şimdi kopyala</string>
|
<string name="action_copy_now">Şimdi kopyala</string>
|
||||||
<string name="action_edit_info">Bilgi düzenle</string>
|
<string name="action_edit_info">Bilgileri düzenle</string>
|
||||||
<string name="entry_type_manga">Manga</string>
|
<string name="entry_type_manga">Manga</string>
|
||||||
<string name="entry_type_manhwa">Manhwa</string>
|
<string name="entry_type_manhwa">Manhwa</string>
|
||||||
<string name="entry_type_manhua">Manhua</string>
|
<string name="entry_type_manhua">Manhua</string>
|
||||||
@@ -12,7 +12,81 @@
|
|||||||
<string name="action_start_reading">Okumaya başla</string>
|
<string name="action_start_reading">Okumaya başla</string>
|
||||||
<string name="changelog_version">Versiyon %1$s</string>
|
<string name="changelog_version">Versiyon %1$s</string>
|
||||||
<string name="action_clean_titles">Başlıkları temizle</string>
|
<string name="action_clean_titles">Başlıkları temizle</string>
|
||||||
<string name="pref_category_all_sources">Bütün Kaynaklar</string>
|
<string name="pref_category_all_sources">Tüm Kaynaklar</string>
|
||||||
<string name="entry_type_webtoon">Webtoon</string>
|
<string name="entry_type_webtoon">Webtoon</string>
|
||||||
<string name="action_skip_entry">Taşıma yapma</string>
|
<string name="action_skip_entry">Taşıma</string>
|
||||||
|
<string name="use_hentai_at_home_summary">Eğer mümkünse görselleri Hentai@Home ağından yüklemek ieter misiniz? Bu ayarı kapatmak görebileceğiniz sayfa sayısını azaltacaktır.\nAyarlar:\n- Herhangi bir istemci (Önerilen)\n- Sadece varsayılan bağlantı noktası istemcileri (Daha yavaş olabilir. Standart olmayan bağlantı noktalarını engelleyen güvenlik duvarı/ara sunucu mevcutsa kullanın.)</string>
|
||||||
|
<string name="use_hentai_at_home_option_2">Sadece varsayılan bağlantı noktası istemcileri</string>
|
||||||
|
<string name="watched_tags_summary">E/ExHentai izlenilen etiketler sayfasını webview ile açar</string>
|
||||||
|
<string name="tag_filtering_threshhold_summary">E/ExHentai Etiketlerim sayfasında etiketlere negatif ağırlık ekleyerek etiketleri filtreleyebilirsiniz. Eğer bir galerinin etiketlerinin değerleri toplamı bu değerin altına düşerse gösterilmez. Bu sınır -9999 ve 0 arasında bir değer olabilir. Şu anda: %1$d</string>
|
||||||
|
<string name="show_japanese_titles">Arama sonuçlarında Japonca başlıkları göster</string>
|
||||||
|
<string name="watched_tags_exh">ExHentai İzlenilen Etiketler</string>
|
||||||
|
<string name="requires_login">Giriş yapma gerekli</string>
|
||||||
|
<string name="action_migrate_now">Şimdi taşı</string>
|
||||||
|
<string name="pref_category_fork">Kopya Ayarları</string>
|
||||||
|
<string name="pref_ehentai_summary">E/ExHentai giriş, galeri eşitleme</string>
|
||||||
|
<string name="pref_mangadex_summary">MangaDex giriş, takip edilenleri eşitleme</string>
|
||||||
|
<string name="ehentai_prefs_account_settings">E-Hentai Web Sitesi Hesap Ayarları</string>
|
||||||
|
<string name="enable_exhentai">ExHentai Aktif Et</string>
|
||||||
|
<string name="use_hentai_at_home">Hentai@Home Ağını Kullan</string>
|
||||||
|
<string name="use_hentai_at_home_option_1">Herhangi bir istemci (Önerilen)</string>
|
||||||
|
<string name="show_japanese_titles_option_1">Arama sonuçlarında Japonca başlıklar gösteriliyor. Bu ayarı değiştirdikten sonra (Gelişmiş ayarlar kısmından) bölüm önbelleğini temizleyin</string>
|
||||||
|
<string name="show_japanese_titles_option_2">Arama sonuçlarında İngilizce/Romanize başlıklar gösteriliyor. Bu ayarı değiştirdikten sonra (Gelişmiş ayarlar kısmından) bölüm önbelleğini temizleyin</string>
|
||||||
|
<string name="use_original_images">Orijinal görselleri kullan</string>
|
||||||
|
<string name="use_original_images_on">Orijinal görseller kullanılıyor</string>
|
||||||
|
<string name="use_original_images_off">Tekrar örneklenmiş görseller kullanılıyor</string>
|
||||||
|
<string name="watched_tags">İzlenilen Etiketler</string>
|
||||||
|
<string name="tag_filtering_threshold">Etiket Filtreleme Sınırı</string>
|
||||||
|
<string name="tag_filtering_threshhold_error">-9999 ve 0 arasında bir değer olmalı!</string>
|
||||||
|
<string name="tag_watching_threshhold_summary">Yeni güncellenen galeriler herhangi bir izlenen etikete sahipse ve izlenen etiketlerinin değerlerinin toplamı bu değere eşit ve daha fazlaysa izlenilenler ekranında gösterilecektir. Bu sınır 0 ve 9999 arasında bir değer olabilir. Şu anda: %1$d</string>
|
||||||
|
<string name="language_filtering_summary">Belirli dillerdeki galerileri galeri listesinde ve aramalarda gizlemek isterseniz açılacak menüden bunları seçin.\nEşleşen galeriler aramanıza bakılmaksızın gösterilmeyecektir.\nKısaca işaretli olanlar hariç tutulacaktır</string>
|
||||||
|
<string name="eh_image_quality_1280">1280x</string>
|
||||||
|
<string name="time_between_batches_3_hours">3 saat</string>
|
||||||
|
<string name="gallery_update_checker">Galeri güncelleme kontrolcüsü</string>
|
||||||
|
<string name="auto_update_restrictions">Otomatik güncelleme kısıtlamaları</string>
|
||||||
|
<string name="pref_enhanced_e_hentai_view">Gelişmiş E/ExHentai araması</string>
|
||||||
|
<string name="tag_watching_threshhold">Etiket İzleme Sınırı</string>
|
||||||
|
<string name="tag_watching_threshhold_error">0 ve 9999 arasında bir değer olmalı!</string>
|
||||||
|
<string name="language_filtering">Dil Filtreleme</string>
|
||||||
|
<string name="frong_page_categories">Ana Sayfa Kategorileri</string>
|
||||||
|
<string name="fromt_page_categories_summary">Ana sayfada ve aramalarda varsayılan olarak gösterilmesini istediğiniz kategoriler hangileri? Filtrelerini etkinleştirilerek aktif edilebilirler</string>
|
||||||
|
<string name="watched_list_default">İzlenenler Listesi Filtresi Varsayılan Durumu</string>
|
||||||
|
<string name="watched_list_state_summary">ExHentai/E-Hentai üzerinde gezinirken izlenenler listesi filtrelerinin varsayılan olarak aktif edileceğini kontrol eder</string>
|
||||||
|
<string name="eh_image_quality_summary">İndirilen görsellerin kalitesi</string>
|
||||||
|
<string name="eh_image_quality">Görsel kalitesi</string>
|
||||||
|
<string name="eh_image_quality_auto">Otomatik</string>
|
||||||
|
<string name="eh_image_quality_2400">2400x</string>
|
||||||
|
<string name="eh_image_quality_1600">1600x</string>
|
||||||
|
<string name="eh_image_quality_980">980x</string>
|
||||||
|
<string name="eh_image_quality_780">780x</string>
|
||||||
|
<string name="pref_enhanced_e_hentai_view_summary">E/ExHentai için gelişmiş arama menüsü modunu açın/kapatın</string>
|
||||||
|
<string name="favorites_sync">E-Hentai Favorileri eşitleme</string>
|
||||||
|
<string name="disable_favorites_uploading">Favorilerin gönderilmesini kapat</string>
|
||||||
|
<string name="disable_favorites_uploading_summary">Favoriler yalnızca ExHentai üzerinden indirilir. Uygulama favorilere yapılan değişiklikler gönderilmeyecektir. ExHentai üzerinde favorilerin yanlışlıkla kaybolmasını önler. Silinenlerin yine de indirileceğini unutmayın (ExHentai üzerinde bir favoriyi silersemiz uygulamada da silinecektir).</string>
|
||||||
|
<string name="show_favorite_sync_notes">Favorilerin eşitleme notlarını göster</string>
|
||||||
|
<string name="show_favorite_sync_notes_summary">Favori eşitleme özelliği ile ilgili çeşitli bilgiler gösterir</string>
|
||||||
|
<string name="please_login">Lütfen giriş yapın!</string>
|
||||||
|
<string name="ignore_sync_errors_summary">Eşitleme sırasında bir hata oluşursa işlemin hemen durdurulmasını önler. Eşitleme tamamlandığında hatalar gösterilecektir. Bazı durumlarda favorilerin kaybolmasına neden olabilir. Büyük kitaplıkların eşitlenmesinde fayda sağlar.</string>
|
||||||
|
<string name="force_sync_state_reset">Zorla eşitleme durumunu sıfırla</string>
|
||||||
|
<string name="force_sync_state_reset_summary">Gelecek eşitlemede kapsamlı bir yeniden senkronizasyon yapar. Silinenler eşitlenmeyecektir. Uygulamadaki bütün favoriler tekrar ExHentai üzerine gönderilecektir ve ExHentai üzerindeki bütün favoriler tekrar uygulamaya indirilecektir. Eşitleme kesildikten sonra düzeltimesine fayda sağlar.</string>
|
||||||
|
<string name="sync_state_reset">Eşitleme durumunu sıfırla</string>
|
||||||
|
<string name="time_between_batches">Toplu güncellemeler arasındaki süre</string>
|
||||||
|
<string name="time_between_batches_never">Galerileri asla güncelleme</string>
|
||||||
|
<string name="time_between_batches_1_hour">1 saat</string>
|
||||||
|
<string name="time_between_batches_2_hours">2 saat</string>
|
||||||
|
<string name="time_between_batches_6_hours">6 saat</string>
|
||||||
|
<string name="time_between_batches_24_hours">24 saat</string>
|
||||||
|
<string name="time_between_batches_48_hours">48 saat</string>
|
||||||
|
<string name="time_between_batches_12_hours">12 saat</string>
|
||||||
|
<string name="time_between_batches_summary_1">%1$s şu anda kitaplığınızdaki galerileri güncellemeler için asla kontrol etmeyecektir.</string>
|
||||||
|
<string name="time_between_batches_summary_2">Galeriler için toplu %1$s kontrol/güncelleme. Bu; %2$d saat beklenilip %3$d galerinin kontrol edileceği, %2$d saat beklenilip %3$d galerinin kontrol edileceği ve böyle devam edileceği anlamına gelir</string>
|
||||||
|
<string name="show_updater_statistics">Güncelleyici istatistiklerini göster</string>
|
||||||
|
<string name="gallery_updater_statistics_collection">İstatistikler toplanıyor…</string>
|
||||||
|
<string name="gallery_updater_statistics">Galeri güncelleyici istatistikleri</string>
|
||||||
|
<string name="gallery_updater_stats_text">Güncelleyici %1$s çalıştı, kontrol edilebilecek %3$d galeriden %2$d tanesini kontrol etti.</string>
|
||||||
|
<string name="gallery_updater_not_ran_yet">Güncelleyici henüz kullanılmadı.</string>
|
||||||
|
<string name="gallery_updater_stats_time">\nKontrol edilen galeriler:\n- son saat içinde: %1$d\n- son 6 saat içinde: %2$d\n- son 12 saat içinde: %3$d\n- son gün içinde: %4$d\n- son 2 gün içinde: %5$d\n- son hafta içinde: %6$d\n- son ay içinde: %7$d\n- son yıl içinde: %8$d</string>
|
||||||
|
<string name="ignore_sync_errors">Eşitleme hatalarını mümkün olduğunda görmezden gel</string>
|
||||||
|
<string name="eh_settings_successfully_uploaded">Ayarlar başarılı bir şekilde yüklendi!</string>
|
||||||
|
<string name="eh_settings_configuration_failed">Ayarlarlana başarısız!</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources></resources>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
<item quantity="other">重試 %1$d 個失敗的頁面……</item>
|
<item quantity="other">重試 %1$d 個失敗的頁面……</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="pref_tag_sorting_desc">
|
<plurals name="pref_tag_sorting_desc">
|
||||||
<item quantity="other">%1$d 個標籤在排序列表中, 這在書櫃中增加了一個選項,以基於優先級的標籤列表進行排序,這意味著作品將以你想要的標籤優先的方式進行排序</item>
|
<item quantity="other">%1$d 個標籤在排序列表中, 這在書櫃中增加了一個選項,以基於優先度的標籤列表進行排序,這意味著作品將以你想要的標籤優先的方式進行排序</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="migrate_entry">
|
<plurals name="migrate_entry">
|
||||||
<item quantity="other">遷移 %1$d%2$s 作品?</item>
|
<item quantity="other">遷移 %1$d%2$s 作品?</item>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
<string name="gallery_updater_stats_time">\n上一次檢查的畫廊:\n- 1 小時: %1$d\n- 6 小時: %2$d\n- 12 小時: %3$d\n- 1 天: %4$d\n- 2 天: %5$d\n- 1 周: %6$d\n- 1 個月: %7$d\n- 1 年: %8$d</string>
|
<string name="gallery_updater_stats_time">\n上一次檢查的畫廊:\n- 1 小時: %1$d\n- 6 小時: %2$d\n- 12 小時: %3$d\n- 1 天: %4$d\n- 2 天: %5$d\n- 1 周: %6$d\n- 1 個月: %7$d\n- 1 年: %8$d</string>
|
||||||
<!-- EH Settings Upload Dialogs -->
|
<!-- EH Settings Upload Dialogs -->
|
||||||
<string name="settings_profile_note">建立設定檔說明</string>
|
<string name="settings_profile_note">建立設定檔說明</string>
|
||||||
<string name="settings_profile_note_message">本應用程式現在將在 E-Hentai 和 ExHentai 上建立一個新的設定檔,以最佳化應用程式的性能。請確保您在這兩個網站上擁有的設定檔少於三個\n\n如果你不知道什麼是設定檔,那麼對你無影響,只需點擊「確定」</string>
|
<string name="settings_profile_note_message">本應用程式現在將在 E-Hentai 和 ExHentai 上建立一個新的設定檔,以最佳化應用程式的效能。請確保您在這兩個網站上擁有的設定檔少於三個\n\n如果你不知道什麼是設定檔,那麼對你無影響,只需點擊「確定」</string>
|
||||||
<string name="eh_settings_successfully_uploaded">設定檔上傳成功!</string>
|
<string name="eh_settings_successfully_uploaded">設定檔上傳成功!</string>
|
||||||
<string name="eh_settings_configuration_failed">設定失敗!</string>
|
<string name="eh_settings_configuration_failed">設定失敗!</string>
|
||||||
<string name="eh_settings_configuration_failed_message">在設定過程中出現錯誤:%1$s</string>
|
<string name="eh_settings_configuration_failed_message">在設定過程中出現錯誤:%1$s</string>
|
||||||
@@ -121,16 +121,16 @@
|
|||||||
<string name="clean_orphaned_downloads">清理孤立的下載</string>
|
<string name="clean_orphaned_downloads">清理孤立的下載</string>
|
||||||
<string name="clean_read_downloads">清理已讀</string>
|
<string name="clean_read_downloads">清理已讀</string>
|
||||||
<string name="clean_read_entries_not_in_library">清理不在書櫃中的作品</string>
|
<string name="clean_read_entries_not_in_library">清理不在書櫃中的作品</string>
|
||||||
<string name="data_saver">數據節省模式</string>
|
<string name="data_saver">資料節省模式</string>
|
||||||
<string name="data_saver_summary">在閱讀器下載圖片前壓縮</string>
|
<string name="data_saver_summary">在閱讀器下載圖片前壓縮</string>
|
||||||
<string name="data_saver_downloader">在下載器中使用數據節省模式</string>
|
<string name="data_saver_downloader">在下載器中使用資料節省模式</string>
|
||||||
<string name="data_saver_ignore_jpeg">忽略 JPEG 圖片</string>
|
<string name="data_saver_ignore_jpeg">忽略 JPEG 圖片</string>
|
||||||
<string name="data_saver_ignore_gif">忽略 Gif 動畫</string>
|
<string name="data_saver_ignore_gif">忽略 Gif 動畫</string>
|
||||||
<string name="data_saver_image_quality">圖片品質</string>
|
<string name="data_saver_image_quality">圖片品質</string>
|
||||||
<string name="data_saver_image_quality_summary">更高值代表更佳的儲存的圖片品質,但這代表更大的檔案大小,80% 可以很好地平衡圖片品質和檔案大小</string>
|
<string name="data_saver_image_quality_summary">更高值代表更佳的儲存的圖片品質,但這代表更大的檔案大小,80% 可以很好地平衡圖片品質和檔案大小</string>
|
||||||
<string name="data_saver_image_format">壓縮為 JPEG</string>
|
<string name="data_saver_image_format">壓縮為 JPEG</string>
|
||||||
<string name="data_saver_image_format_summary_on">JPEG 檔案的大小要比 Webp 小得多(代表節省了更多的數據),但它也會使圖片損失更多的品質。\n目前壓縮為 JPEG</string>
|
<string name="data_saver_image_format_summary_on">JPEG 檔案的大小要比 Webp 小得多(代表節省了更多的資料),但它也會使圖片損失更多的品質。\n目前壓縮為 JPEG</string>
|
||||||
<string name="data_saver_image_format_summary_off">JPEG 檔案的大小要比 Webp 小得多(代表節省了更多的數據),但它也會使圖片損失更多的品質。\n目前壓縮為 Webp</string>
|
<string name="data_saver_image_format_summary_off">JPEG 檔案的大小要比 Webp 小得多(代表節省了更多的資料),但它也會使圖片損失更多的品質。\n目前壓縮為 Webp</string>
|
||||||
<string name="data_saver_color_bw">轉換為黑白</string>
|
<string name="data_saver_color_bw">轉換為黑白</string>
|
||||||
<string name="bandwidth_hero">Bandwidth Hero(需要一個 Bandwidth Hero 代理伺服器)</string>
|
<string name="bandwidth_hero">Bandwidth Hero(需要一個 Bandwidth Hero 代理伺服器)</string>
|
||||||
<string name="bandwidth_data_saver_server">Bandwidth Hero 代理伺服器</string>
|
<string name="bandwidth_data_saver_server">Bandwidth Hero 代理伺服器</string>
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
<string name="pref_feed_position_summery">您是否希望將「動態」標籤設為瀏覽中的第一個標籤?這將使其成為預設的瀏覽標籤,但如果您使用行動數據或有限網路,則不建議這樣做</string>
|
<string name="pref_feed_position_summery">您是否希望將「動態」標籤設為瀏覽中的第一個標籤?這將使其成為預設的瀏覽標籤,但如果您使用行動數據或有限網路,則不建議這樣做</string>
|
||||||
<string name="pref_source_source_filtering">在目錄中過濾來源</string>
|
<string name="pref_source_source_filtering">在目錄中過濾來源</string>
|
||||||
<string name="pref_source_source_filtering_summery">篩選屬於類別的來源,使屬於某個類別的來源不會被放在語言下</string>
|
<string name="pref_source_source_filtering_summery">篩選屬於類別的來源,使屬於某個類別的來源不會被放在語言下</string>
|
||||||
<string name="pref_source_navigation">替換最新按鈕</string>
|
<string name="pref_source_navigation">取代最新按鈕</string>
|
||||||
<string name="pref_source_navigation_summery">用一個包括最新和瀏覽的自訂瀏覽檢視取代最新按鈕</string>
|
<string name="pref_source_navigation_summery">用一個包括最新和瀏覽的自訂瀏覽檢視取代最新按鈕</string>
|
||||||
<string name="pref_local_source_hidden_folders">本機來源隱藏資料夾</string>
|
<string name="pref_local_source_hidden_folders">本機來源隱藏資料夾</string>
|
||||||
<string name="pref_local_source_hidden_folders_summery">允許本機源讀取隱藏資料夾</string>
|
<string name="pref_local_source_hidden_folders_summery">允許本機源讀取隱藏資料夾</string>
|
||||||
@@ -211,13 +211,13 @@
|
|||||||
<string name="google_drive_login_success">成功登入 Google Drive</string>
|
<string name="google_drive_login_success">成功登入 Google Drive</string>
|
||||||
<string name="google_drive_login_failed">無法登入 Google Drive:%s</string>
|
<string name="google_drive_login_failed">無法登入 Google Drive:%s</string>
|
||||||
<string name="google_drive_not_signed_in">未登入 Google Drive</string>
|
<string name="google_drive_not_signed_in">未登入 Google Drive</string>
|
||||||
<string name="error_uploading_sync_data">上傳同步數據至 Google Drive 時出錯</string>
|
<string name="error_uploading_sync_data">上傳同步資料至 Google Drive 時出錯</string>
|
||||||
<string name="error_deleting_google_drive_lock_file">刪除 Google Drive 鎖定文件時出錯</string>
|
<string name="error_deleting_google_drive_lock_file">刪除 Google Drive 鎖定文件時出錯</string>
|
||||||
<string name="error_before_sync_gdrive">同步前出錯:%s</string>
|
<string name="error_before_sync_gdrive">同步前出錯:%s</string>
|
||||||
<string name="pref_purge_confirmation_title">清除確認</string>
|
<string name="pref_purge_confirmation_title">清除確認</string>
|
||||||
<string name="pref_purge_confirmation_message">清除同步資料將從 Google Drive 中刪除所有同步資料。您確定要繼續嗎?</string>
|
<string name="pref_purge_confirmation_message">清除同步資料將從 Google Drive 中刪除所有同步資料。您確定要繼續嗎?</string>
|
||||||
<string name="pref_sync_options">創建同步觸發條件</string>
|
<string name="pref_sync_options">建立同步觸發條件</string>
|
||||||
<string name="pref_sync_options_summ">可用於設置同步觸發條件</string>
|
<string name="pref_sync_options_summ">可用於設定同步觸發條件</string>
|
||||||
<string name="sync_on_chapter_read">閱讀章節時同步</string>
|
<string name="sync_on_chapter_read">閱讀章節時同步</string>
|
||||||
<string name="sync_on_chapter_open">打開章節時同步</string>
|
<string name="sync_on_chapter_open">打開章節時同步</string>
|
||||||
<string name="sync_on_app_start">啟動應用時同步</string>
|
<string name="sync_on_app_start">啟動應用時同步</string>
|
||||||
@@ -260,7 +260,7 @@
|
|||||||
<string name="download_threads_summary">較高的值可以明顯加快頁面載入速度,同時容易被停權。建議值為 2 或 3。現在的值為:%s</string>
|
<string name="download_threads_summary">較高的值可以明顯加快頁面載入速度,同時容易被停權。建議值為 2 或 3。現在的值為:%s</string>
|
||||||
<string name="aggressively_load_pages">積極地載入頁面</string>
|
<string name="aggressively_load_pages">積極地載入頁面</string>
|
||||||
<string name="aggressively_load_pages_summary">在閱讀時緩慢地下載整個章節,而不是只載入你正在閱讀的頁面。</string>
|
<string name="aggressively_load_pages_summary">在閱讀時緩慢地下載整個章節,而不是只載入你正在閱讀的頁面。</string>
|
||||||
<string name="skip_queue_on_retry">重試時跳過隊列</string>
|
<string name="skip_queue_on_retry">重試時跳過佇列</string>
|
||||||
<string name="skip_queue_on_retry_summary">通常情況下,在下載失敗時按下重試按鈕,將等待下載器完成最後一頁的下載,然後開始重新下載失敗的頁面。啟用此功能將迫使下載器在你按下重試按鈕後立即開始重新下載失敗的頁面。</string>
|
<string name="skip_queue_on_retry_summary">通常情況下,在下載失敗時按下重試按鈕,將等待下載器完成最後一頁的下載,然後開始重新下載失敗的頁面。啟用此功能將迫使下載器在你按下重試按鈕後立即開始重新下載失敗的頁面。</string>
|
||||||
<string name="reader_preload_amount">預載入頁面數量</string>
|
<string name="reader_preload_amount">預載入頁面數量</string>
|
||||||
<string name="reader_preload_amount_4_pages">4 頁</string>
|
<string name="reader_preload_amount_4_pages">4 頁</string>
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
<string name="reader_preload_amount_20_pages">20 頁</string>
|
<string name="reader_preload_amount_20_pages">20 頁</string>
|
||||||
<string name="reader_preload_amount_summary">閱讀時預先載入的頁數。較高的數值將提供更流暢的閱讀體驗,但會增加快取使用量。建議在使用較大數值時,增加分配給快取的容量</string>
|
<string name="reader_preload_amount_summary">閱讀時預先載入的頁數。較高的數值將提供更流暢的閱讀體驗,但會增加快取使用量。建議在使用較大數值時,增加分配給快取的容量</string>
|
||||||
<string name="reader_cache_size">閱讀器快取大小</string>
|
<string name="reader_cache_size">閱讀器快取大小</string>
|
||||||
<string name="reader_cache_size_summary">閱讀時保存於裝置上的圖片數量。較高的數值將提供更流暢的閱讀體驗,但會增加磁碟空間的使用量</string>
|
<string name="reader_cache_size_summary">閱讀時儲存於裝置上的圖片數量。較高的數值將提供更流暢的閱讀體驗,但會增加磁碟空間的使用量</string>
|
||||||
<string name="preserve_reading_position">保留已閱讀作品的閱讀位置</string>
|
<string name="preserve_reading_position">保留已閱讀作品的閱讀位置</string>
|
||||||
<string name="auto_webtoon_mode">自動 Webtoon 模式</string>
|
<string name="auto_webtoon_mode">自動 Webtoon 模式</string>
|
||||||
<string name="auto_webtoon_mode_summary">檢測到可能為長條形格式的作品時自動使用 Webtoon 模式</string>
|
<string name="auto_webtoon_mode_summary">檢測到可能為長條形格式的作品時自動使用 Webtoon 模式</string>
|
||||||
@@ -348,11 +348,11 @@
|
|||||||
<!-- Entry Info -->
|
<!-- Entry Info -->
|
||||||
<string name="az_recommends">檢視推薦</string>
|
<string name="az_recommends">檢視推薦</string>
|
||||||
<string name="merge">合併</string>
|
<string name="merge">合併</string>
|
||||||
<string name="merge_with_another_source">與其他合併</string>
|
<string name="merge_with_another_source">和另一個合併</string>
|
||||||
<string name="entry_merged">作品已合併!</string>
|
<string name="entry_merged">作品已合併!</string>
|
||||||
<string name="failed_merge">作品合併失敗:%1$s</string>
|
<string name="failed_merge">作品合併失敗:%1$s</string>
|
||||||
<string name="merge_unknown_entry">未知的作品 ID: %1$d</string>
|
<string name="merge_unknown_entry">未知的作品 ID: %1$d</string>
|
||||||
<string name="merged_already">此作品已與當前作品合併!</string>
|
<string name="merged_already">此作品已與目前作品合併!</string>
|
||||||
<string name="merge_duplicate">此已合併的作品重複了!</string>
|
<string name="merge_duplicate">此已合併的作品重複了!</string>
|
||||||
<!-- Entry Info Edit -->
|
<!-- Entry Info Edit -->
|
||||||
<string name="reset_tags">重設標籤</string>
|
<string name="reset_tags">重設標籤</string>
|
||||||
@@ -366,15 +366,15 @@
|
|||||||
<!-- Browse -->
|
<!-- Browse -->
|
||||||
<!-- Sources Tab -->
|
<!-- Sources Tab -->
|
||||||
<string name="find_in_another_source">搜尋其他來源</string>
|
<string name="find_in_another_source">搜尋其他來源</string>
|
||||||
<string name="data_saver_exclude">排除在數據節省模式之外</string>
|
<string name="data_saver_exclude">排除在資料節省模式之外</string>
|
||||||
<string name="data_saver_stop_exclude">停止排除在數據節省模式之外</string>
|
<string name="data_saver_stop_exclude">停止排除在資料節省模式之外</string>
|
||||||
<!-- Smart Search -->
|
<!-- Smart Search -->
|
||||||
<string name="searching_source">搜尋來源中……</string>
|
<string name="searching_source">搜尋來源中……</string>
|
||||||
<string name="could_not_find_entry">未能在來源中找到此作品!</string>
|
<string name="could_not_find_entry">未能在來源中找到此作品!</string>
|
||||||
<string name="automatic_search_error">進行自動搜尋過程中出現錯誤!</string>
|
<string name="automatic_search_error">進行自動搜尋過程中出現錯誤!</string>
|
||||||
<!-- Saved Searches -->
|
<!-- Saved Searches -->
|
||||||
<string name="saved_searches">儲存搜尋</string>
|
<string name="saved_searches">儲存搜尋</string>
|
||||||
<string name="save_search">儲存當前搜尋結果?</string>
|
<string name="save_search">儲存目前搜尋結果?</string>
|
||||||
<string name="save_search_hint">我的搜尋名稱</string>
|
<string name="save_search_hint">我的搜尋名稱</string>
|
||||||
<string name="save_search_failed_to_load">載入已儲存的搜尋失敗!</string>
|
<string name="save_search_failed_to_load">載入已儲存的搜尋失敗!</string>
|
||||||
<string name="save_search_failed_to_load_message">載入已儲存的搜尋過程中出現問題。</string>
|
<string name="save_search_failed_to_load_message">載入已儲存的搜尋過程中出現問題。</string>
|
||||||
@@ -409,7 +409,7 @@
|
|||||||
<string name="migration">遷移</string>
|
<string name="migration">遷移</string>
|
||||||
<string name="skip_pre_migration">跳過預遷移</string>
|
<string name="skip_pre_migration">跳過預遷移</string>
|
||||||
<string name="pre_migration_skip_toast">要重新顯示此頁面,請到設定 -> 書櫃。</string>
|
<string name="pre_migration_skip_toast">要重新顯示此頁面,請到設定 -> 書櫃。</string>
|
||||||
<string name="use_intelligent_search">搜尋標題 +標題關鍵字</string>
|
<string name="use_intelligent_search">搜尋標題 + 標題關鍵字</string>
|
||||||
<string name="data_to_include_in_migration">遷移中包含的資料</string>
|
<string name="data_to_include_in_migration">遷移中包含的資料</string>
|
||||||
<string name="include_extra_search_parameter">搜尋時包含額外的搜尋參數</string>
|
<string name="include_extra_search_parameter">搜尋時包含額外的搜尋參數</string>
|
||||||
<string name="use_most_chapters">使用章節數最多的來源(較慢)</string>
|
<string name="use_most_chapters">使用章節數最多的來源(較慢)</string>
|
||||||
@@ -578,7 +578,7 @@
|
|||||||
<string name="merge_settings">合併設定</string>
|
<string name="merge_settings">合併設定</string>
|
||||||
<string name="fetch_chapter_updates">取得章節更新</string>
|
<string name="fetch_chapter_updates">取得章節更新</string>
|
||||||
<string name="delete_merged_entry">你確定嗎?</string>
|
<string name="delete_merged_entry">你確定嗎?</string>
|
||||||
<string name="delete_merged_entry_desc">這將從合併中移除該項目,使用此功能時也會丟失對合併項目所做的任何未保存更改</string>
|
<string name="delete_merged_entry_desc">這將從合併中移除該項目,使用此功能時也會遺失對合併項目所做的任何未儲存更改</string>
|
||||||
<string name="chapter_updates_merged_entry">變更章節更新</string>
|
<string name="chapter_updates_merged_entry">變更章節更新</string>
|
||||||
<string name="chapter_updates_merged_entry_desc">變更此項將停用或啟用此已合併的漫畫的章節更新</string>
|
<string name="chapter_updates_merged_entry_desc">變更此項將停用或啟用此已合併的漫畫的章節更新</string>
|
||||||
<string name="download_merged_entry">變更新章節下載</string>
|
<string name="download_merged_entry">變更新章節下載</string>
|
||||||
|
|||||||
@@ -275,4 +275,4 @@
|
|||||||
<string name="backup_restore_missing_trackers">መከታተያዎች አልገቡም:</string>
|
<string name="backup_restore_missing_trackers">መከታተያዎች አልገቡም:</string>
|
||||||
<string name="backup_restore_missing_sources">የጠፋ ምንጮች:</string>
|
<string name="backup_restore_missing_sources">የጠፋ ምንጮች:</string>
|
||||||
<string name="invalid_backup_file_missing_manga">ምትኬ ማንኛውንም ማንጋ አልያዘም ፡፡</string>
|
<string name="invalid_backup_file_missing_manga">ምትኬ ማንኛውንም ማንጋ አልያዘም ፡፡</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -9,12 +9,12 @@
|
|||||||
<item quantity="other">%d ৰেপোসমূহ</item>
|
<item quantity="other">%d ৰেপোসমূহ</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="lock_after_mins">
|
<plurals name="lock_after_mins">
|
||||||
<item quantity="one">%1$s মিনিটৰ পিছত</item>
|
<item quantity="one">%1$s মিনিট পিছত</item>
|
||||||
<item quantity="other">%1$s মিনিটৰ পিছত</item>
|
<item quantity="other">%1$s মিনিটৰ পিছত</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="relative_time">
|
<plurals name="relative_time">
|
||||||
<item quantity="one">কালি</item>
|
<item quantity="one">কালি</item>
|
||||||
<item quantity="other">%1$d দিন আগতে</item>
|
<item quantity="other">%1$d দিনৰ আগতে</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="upcoming_relative_time">
|
<plurals name="upcoming_relative_time">
|
||||||
<item quantity="one">কাইলৈ</item>
|
<item quantity="one">কাইলৈ</item>
|
||||||
@@ -25,11 +25,11 @@
|
|||||||
<item quantity="other">%d শিতানসমূহ</item>
|
<item quantity="other">%d শিতানসমূহ</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="next_unread_chapters">
|
<plurals name="next_unread_chapters">
|
||||||
<item quantity="one">পঢ়া হোৱা পৰৱৰ্তী অধ্যায়</item>
|
<item quantity="one">পৰৱৰ্তী অপঠিত অধ্যায়</item>
|
||||||
<item quantity="other">পঢ়া হোৱা %d পৰৱৰ্তী অধ্যায়সমূহ</item>
|
<item quantity="other">পৰৱৰ্তী %d অপঠিত অধ্যায়সমূহ</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="restore_completed_message">
|
<plurals name="restore_completed_message">
|
||||||
<item quantity="one">%1$sত %2$s ত্ৰুটিৰ সৈতে সমাপ্ত</item>
|
<item quantity="one">%1$sত %2$s ত্ৰুটি সৈতে সমাপ্ত</item>
|
||||||
<item quantity="other">%1$sত %2$s ত্ৰুটিৰ সৈতে সমাপ্ত</item>
|
<item quantity="other">%1$sত %2$s ত্ৰুটিৰ সৈতে সমাপ্ত</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="download_queue_summary">
|
<plurals name="download_queue_summary">
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
<string name="action_create">সৃষ্টি কৰক</string>
|
<string name="action_create">সৃষ্টি কৰক</string>
|
||||||
<string name="invalid_backup_file_missing_manga">বেকআপত কোনো গ্ৰন্থাগাৰ প্ৰৱিষ্ট নাই।</string>
|
<string name="invalid_backup_file_missing_manga">বেকআপত কোনো গ্ৰন্থাগাৰ প্ৰৱিষ্ট নাই।</string>
|
||||||
<string name="restore_completed">পুনৰুদ্ধাৰ সম্পূৰ্ণ</string>
|
<string name="restore_completed">পুনৰুদ্ধাৰ সম্পূৰ্ণ</string>
|
||||||
<string name="restore_duration">%02d মিনিট, %02d ছেকেণ্ড</string>
|
<string name="restore_duration">%1$02d মিনিট, %2$02d ছেকেণ্ড</string>
|
||||||
<string name="missing_storage_permission">সংৰক্ষণ অনুমতি প্ৰদান কৰা হোৱা নাই</string>
|
<string name="missing_storage_permission">সংৰক্ষণ অনুমতি প্ৰদান কৰা হোৱা নাই</string>
|
||||||
<string name="in_library">লাইব্ৰেৰীত</string>
|
<string name="in_library">লাইব্ৰেৰীত</string>
|
||||||
<string name="manga_added_library">লাইব্ৰেৰীলৈ যোগ কৰা হৈছে</string>
|
<string name="manga_added_library">লাইব্ৰেৰীলৈ যোগ কৰা হৈছে</string>
|
||||||
@@ -522,7 +522,7 @@
|
|||||||
<string name="pref_reset_user_agent_string">ডিফল্ট ইউজাৰ এজেন্ট ষ্ট্ৰিং পুনৰ চমা</string>
|
<string name="pref_reset_user_agent_string">ডিফল্ট ইউজাৰ এজেন্ট ষ্ট্ৰিং পুনৰ চমা</string>
|
||||||
<string name="requires_app_restart">কাৰ্য্যকৰী হবলৈ এপ পুনৰ আৰম্ভণি প্ৰয়োজন</string>
|
<string name="requires_app_restart">কাৰ্য্যকৰী হবলৈ এপ পুনৰ আৰম্ভণি প্ৰয়োজন</string>
|
||||||
<string name="cookies_cleared">কুকি মচা হৈছে</string>
|
<string name="cookies_cleared">কুকি মচা হৈছে</string>
|
||||||
<string name="pref_invalidate_download_cache">ডাউনলোড কেচ অবৈধ কৰা</string>
|
<string name="pref_invalidate_download_cache">ডাউনলোডসমূহ পুনৰ সূচীভুক্ত কৰক</string>
|
||||||
<string name="download_cache_invalidated">ডাউনলোড কেচ অবৈধ কৰা হৈছে</string>
|
<string name="download_cache_invalidated">ডাউনলোড কেচ অবৈধ কৰা হৈছে</string>
|
||||||
<string name="pref_invalidate_download_cache_summary">ডাউনলোড কৰা অধ্যায়সমূহ পুনৰ পৰীক্ষা কৰিবলৈ এপটো বাধ্য কৰা</string>
|
<string name="pref_invalidate_download_cache_summary">ডাউনলোড কৰা অধ্যায়সমূহ পুনৰ পৰীক্ষা কৰিবলৈ এপটো বাধ্য কৰা</string>
|
||||||
<string name="pref_clear_database">ডাটাবেচ মচা</string>
|
<string name="pref_clear_database">ডাটাবেচ মচা</string>
|
||||||
@@ -835,4 +835,9 @@
|
|||||||
<string name="ext_remove">আঁতৰাওক</string>
|
<string name="ext_remove">আঁতৰাওক</string>
|
||||||
<string name="ext_confirm_remove">এক্সটেনচন আঁতৰাবনে?</string>
|
<string name="ext_confirm_remove">এক্সটেনচন আঁতৰাবনে?</string>
|
||||||
<string name="remove_private_extension_message">আপুনি কি \"%s\" এক্সটেনচনটো আঁতৰাব খুজিছে?</string>
|
<string name="remove_private_extension_message">আপুনি কি \"%s\" এক্সটেনচনটো আঁতৰাব খুজিছে?</string>
|
||||||
|
<string name="pref_auto_update_manga_on_mark_read">পঢ়া হিচাপে চিহ্নিত কৰাৰ সময়ত অগ্ৰগতি আপডেইট কৰক</string>
|
||||||
|
<string name="trackers_updated_summary">ট্ৰেকাৰসমূহ অধ্যায় %d লৈ আপডেইট কৰা হৈছে</string>
|
||||||
|
<string name="pref_hardware_bitmap_threshold">কাষ্টম হাৰ্ডৱেৰ বিটম্যাপ থ্ৰেশহোল্ড</string>
|
||||||
|
<string name="pref_hardware_bitmap_threshold_summary">যদি পাঠকে এটা খালী ছবি লোড কৰে ক্ৰমান্বয়ে থ্ৰেছহোল্ড হ্ৰাস কৰক। \nবাচনি কৰা: %s</string>
|
||||||
|
<string name="pref_hardware_bitmap_threshold_default">ডিফল্ট (%d)</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -392,7 +392,9 @@
|
|||||||
<string name="pref_show_reading_mode">Show reading mode</string>
|
<string name="pref_show_reading_mode">Show reading mode</string>
|
||||||
<string name="pref_show_reading_mode_summary">Briefly show current mode when reader is opened</string>
|
<string name="pref_show_reading_mode_summary">Briefly show current mode when reader is opened</string>
|
||||||
<string name="pref_display_profile">Custom display profile</string>
|
<string name="pref_display_profile">Custom display profile</string>
|
||||||
<string name="pref_always_use_ssiv_to_decode">Always use SSIV to decode long strip images</string>
|
<string name="pref_hardware_bitmap_threshold">Custom hardware bitmap threshold</string>
|
||||||
|
<string name="pref_hardware_bitmap_threshold_default">Default (%d)</string>
|
||||||
|
<string name="pref_hardware_bitmap_threshold_summary">If reader loads a blank image incrementally reduce the threshold.\nSelected: %s</string>
|
||||||
<string name="pref_crop_borders">Crop borders</string>
|
<string name="pref_crop_borders">Crop borders</string>
|
||||||
<string name="pref_custom_brightness">Custom brightness</string>
|
<string name="pref_custom_brightness">Custom brightness</string>
|
||||||
<string name="pref_grayscale">Grayscale</string>
|
<string name="pref_grayscale">Grayscale</string>
|
||||||
|
|||||||
@@ -642,4 +642,4 @@
|
|||||||
<string name="publishing_finished">Приключено издаване</string>
|
<string name="publishing_finished">Приключено издаване</string>
|
||||||
<string name="update_check_fdroid_migration_info">Достъпна е нова версия от официалните източници. Научете как да мигрирате от неофициалните версии на F-Droid.</string>
|
<string name="update_check_fdroid_migration_info">Достъпна е нова версия от официалните източници. Научете как да мигрирате от неофициалните версии на F-Droid.</string>
|
||||||
<string name="download_notifier_split_page_not_found">Страница %d не беше намерена при разделяне</string>
|
<string name="download_notifier_split_page_not_found">Страница %d не беше намерена при разделяне</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -443,4 +443,4 @@
|
|||||||
<string name="action_not_now">Dili karon</string>
|
<string name="action_not_now">Dili karon</string>
|
||||||
<string name="information_webview_required">Gikinahanlan ang WebView alang sa Tachiyomi</string>
|
<string name="information_webview_required">Gikinahanlan ang WebView alang sa Tachiyomi</string>
|
||||||
<string name="information_required_plain">*gikinahanlan</string>
|
<string name="information_required_plain">*gikinahanlan</string>
|
||||||
</resources>
|
</resources>
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user