Made almost all the strings SY uses translatable! If people would like to help translate, feel free to join the Tachiyomi discord server (https://discord.gg/tachiyomi), and jump in the tachiyomi-az-sy channel and I can give you a rundown on how to do it

This commit is contained in:
Jobobby04
2020-07-15 19:16:21 -04:00
parent 0ca87a3763
commit 362f0a6671
42 changed files with 668 additions and 485 deletions
@@ -286,7 +286,7 @@ class BackupRestoreService : Service() {
backupManager.restoreSavedSearches(savedSearchesJson)
restoreProgress += 1
showRestoreProgress(restoreProgress, restoreAmount, getString(R.string.eh_saved_searches))
showRestoreProgress(restoreProgress, restoreAmount, getString(R.string.saved_searches))
}
// SY <--
@@ -98,7 +98,7 @@ open class SourceManager(private val context: Context) {
XLog.d("[EXH] Delegating source: %s -> %s!", sourceQName, delegate.newSourceClass.qualifiedName)
val enhancedSource = EnhancedHttpSource(
source,
delegate.newSourceClass.constructors.find { it.parameters.size == 1 }!!.call(source)
delegate.newSourceClass.constructors.find { it.parameters.size == 2 }!!.call(source, context)
)
val map = listOf(DelegatedSource(enhancedSource.originalSource.name, enhancedSource.originalSource.id, enhancedSource.originalSource::class.qualifiedName ?: delegate.originalSourceQualifiedClassName, (enhancedSource.enhancedSource as DelegatedHttpSource)::class, delegate.factory)).associateBy { it.originalSourceQualifiedClassName }
currentDelegatedSources.plusAssign(map)
@@ -132,12 +132,12 @@ open class SourceManager(private val context: Context) {
if (prefs.enableExhentai().get()) {
exSrcs += EHentai(EXH_SOURCE_ID, true, context)
}
exSrcs += PervEden(PERV_EDEN_EN_SOURCE_ID, PervEdenLang.en)
exSrcs += PervEden(PERV_EDEN_IT_SOURCE_ID, PervEdenLang.it)
exSrcs += PervEden(PERV_EDEN_EN_SOURCE_ID, PervEdenLang.en, context)
exSrcs += PervEden(PERV_EDEN_IT_SOURCE_ID, PervEdenLang.it, context)
exSrcs += NHentai(context)
exSrcs += Hitomi()
exSrcs += EightMuses()
exSrcs += HBrowse()
exSrcs += Hitomi(context)
exSrcs += EightMuses(context)
exSrcs += HBrowse(context)
return exSrcs
}
// SY <--
@@ -271,7 +271,7 @@ class EHentai(
// Support direct URL importing
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
urlImportFetchSearchManga(query) {
urlImportFetchSearchManga(context, query) {
searchMangaRequestObservable(page, query, filters).flatMap {
client.newCall(it).asObservableSuccess()
}.map { response ->
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.all
import android.content.Context
import android.net.Uri
import android.os.Build
import com.github.salomonbrys.kotson.array
@@ -41,7 +42,7 @@ import uy.kohesive.injekt.injectLazy
/**
* Man, I hate this source :(
*/
class Hitomi : HttpSource(), LewdSource<HitomiSearchMetadata, Document>, UrlImportableSource {
class Hitomi(val context: Context) : HttpSource(), LewdSource<HitomiSearchMetadata, Document>, UrlImportableSource {
private val prefs: PreferencesHelper by injectLazy()
override val id = HITOMI_SOURCE_ID
@@ -185,7 +186,7 @@ class Hitomi : HttpSource(), LewdSource<HitomiSearchMetadata, Document>, UrlImpo
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw UnsupportedOperationException()
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return urlImportFetchSearchManga(query) {
return urlImportFetchSearchManga(context, query) {
val splitQuery = query.split(" ")
val positive = splitQuery.filter { !it.startsWith('-') }.toMutableList()
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.all
import android.content.Context
import android.net.Uri
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.source.ConfigurableSource
@@ -11,7 +12,7 @@ import exh.source.DelegatedHttpSource
import exh.util.urlImportFetchSearchManga
import rx.Observable
class MangaDex(delegate: HttpSource) :
class MangaDex(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
ConfigurableSource,
UrlImportableSource {
@@ -19,7 +20,7 @@ class MangaDex(delegate: HttpSource) :
override val matchingHosts: List<String> = listOf("mangadex.org", "www.mangadex.org")
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> =
urlImportFetchSearchManga(query) {
urlImportFetchSearchManga(context, query) {
super.fetchSearchManga(page, query, filters)
}
@@ -37,7 +37,7 @@ import rx.Observable
* NHentai source
*/
class NHentai(context: Context) : HttpSource(), LewdSource<NHentaiSearchMetadata, Response>, UrlImportableSource {
class NHentai(val context: Context) : HttpSource(), LewdSource<NHentaiSearchMetadata, Response>, UrlImportableSource {
override val metaClass = NHentaiSearchMetadata::class
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
@@ -57,7 +57,7 @@ class NHentai(context: Context) : HttpSource(), LewdSource<NHentaiSearchMetadata
"$baseUrl/g/$trimmedIdQuery/"
} else query
return urlImportFetchSearchManga(newQuery) {
return urlImportFetchSearchManga(context, newQuery) {
searchMangaRequestObservable(page, query, filters).flatMap {
client.newCall(it).asObservableSuccess()
}.map { response ->
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.all
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
@@ -33,7 +34,7 @@ import org.jsoup.nodes.TextNode
import rx.Observable
// TODO Transform into delegated source
class PervEden(override val id: Long, val pvLang: PervEdenLang) :
class PervEden(override val id: Long, val pvLang: PervEdenLang, val context: Context) :
ParsedHttpSource(),
LewdSource<PervEdenSearchMetadata, Document>,
UrlImportableSource {
@@ -64,7 +65,7 @@ class PervEden(override val id: Long, val pvLang: PervEdenLang) :
// Support direct URL importing
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
urlImportFetchSearchManga(query) {
urlImportFetchSearchManga(context, query) {
super.fetchSearchManga(page, query, filters)
}
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import com.kizitonwose.time.hours
import eu.kanade.tachiyomi.network.GET
@@ -41,7 +42,7 @@ import rx.schedulers.Schedulers
typealias SiteMap = NakedTrie<Unit>
class EightMuses :
class EightMuses(val context: Context) :
HttpSource(),
LewdSource<EightMusesSearchMetadata, Document>,
UrlImportableSource {
@@ -177,7 +178,7 @@ class EightMuses :
override fun fetchPopularManga(page: Int) = fetchListing(popularMangaRequest(page), false) // TODO Dig
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return urlImportFetchSearchManga(query) {
return urlImportFetchSearchManga(context, query) {
fetchListing(searchMangaRequest(page, query, filters), false)
}
}
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.string
@@ -43,7 +44,7 @@ import org.jsoup.nodes.Element
import rx.Observable
import rx.schedulers.Schedulers
class HBrowse : HttpSource(), LewdSource<HBrowseSearchMetadata, Document>, UrlImportableSource {
class HBrowse(val context: Context) : HttpSource(), LewdSource<HBrowseSearchMetadata, Document>, UrlImportableSource {
/**
* An ISO 639-1 compliant language code (two letters in lower case).
*/
@@ -110,7 +111,7 @@ class HBrowse : HttpSource(), LewdSource<HBrowseSearchMetadata, Document>, UrlIm
* @param filters the list of filters to apply.
*/
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
return urlImportFetchSearchManga(query) {
return urlImportFetchSearchManga(context, query) {
fetchSearchMangaInternal(page, query, filters)
}
}
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList
@@ -19,7 +20,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import org.jsoup.nodes.Document
import rx.Observable
class HentaiCafe(delegate: HttpSource) :
class HentaiCafe(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
LewdSource<HentaiCafeSearchMetadata, Document>,
UrlImportableSource {
@@ -34,7 +35,7 @@ class HentaiCafe(delegate: HttpSource) :
// Support direct URL importing
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
urlImportFetchSearchManga(query) {
urlImportFetchSearchManga(context, query) {
super.fetchSearchManga(page, query, filters)
}
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList
@@ -18,7 +19,7 @@ import exh.util.urlImportFetchSearchManga
import org.jsoup.nodes.Document
import rx.Observable
class Pururin(delegate: HttpSource) :
class Pururin(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
LewdSource<PururinSearchMetadata, Document>,
UrlImportableSource {
@@ -38,7 +39,7 @@ class Pururin(delegate: HttpSource) :
"$baseUrl/gallery/$trimmedIdQuery/-"
} else query
return urlImportFetchSearchManga(newQuery) {
return urlImportFetchSearchManga(context, newQuery) {
super.fetchSearchManga(page, query, filters)
}
}
@@ -1,5 +1,6 @@
package eu.kanade.tachiyomi.source.online.english
import android.content.Context
import android.net.Uri
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList
@@ -19,7 +20,7 @@ import java.util.Locale
import org.jsoup.nodes.Document
import rx.Observable
class Tsumino(delegate: HttpSource) :
class Tsumino(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
LewdSource<TsuminoSearchMetadata, Document>,
UrlImportableSource {
@@ -28,7 +29,7 @@ class Tsumino(delegate: HttpSource) :
// Support direct URL importing
override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
urlImportFetchSearchManga(query) {
urlImportFetchSearchManga(context, query) {
super.fetchSearchManga(page, query, filters)
}
@@ -64,7 +64,6 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.appcompat.QueryTextEvent
import reactivecircus.flowbinding.appcompat.queryTextEvents
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
/**
@@ -193,7 +192,7 @@ open class BrowseSourceController(bundle: Bundle) :
if (presenter.sourceFilters.isEmpty()) {
// SY -->
actionFab?.text = activity!!.getString(R.string.eh_saved_searches)
actionFab?.text = activity!!.getString(R.string.saved_searches)
// SY <--
}
@@ -218,8 +217,8 @@ open class BrowseSourceController(bundle: Bundle) :
onSaveClicked = {
filterSheet?.context?.let {
MaterialDialog(it)
.title(text = "Save current search query?")
.input("My search name", hintRes = null) { _, searchName ->
.title(R.string.save_search)
.input(hintRes = R.string.save_search_hint) { _, searchName ->
val oldSavedSearches = presenter.loadSearches()
if (searchName.isNotBlank() &&
oldSavedSearches.size < MAX_SAVED_SEARCHES
@@ -248,8 +247,8 @@ open class BrowseSourceController(bundle: Bundle) :
if (search == null) {
filterSheet?.context?.let {
MaterialDialog(it)
.title(text = "Failed to load saved searches!")
.message(text = "An error occurred while loading your saved searches.")
.title(R.string.save_search_failed_to_load)
.message(R.string.save_search_failed_to_load_message)
.cancelable(true)
.cancelOnTouchOutside(true)
.show()
@@ -275,8 +274,8 @@ open class BrowseSourceController(bundle: Bundle) :
if (search == null || search.name != name) {
filterSheet?.context?.let {
MaterialDialog(it)
.title(text = "Failed to delete saved search!")
.message(text = "An error occurred while deleting the search.")
.title(R.string.save_search_failed_to_delete)
.message(R.string.save_search_failed_to_delete_message)
.cancelable(true)
.cancelOnTouchOutside(true)
.show()
@@ -286,10 +285,10 @@ open class BrowseSourceController(bundle: Bundle) :
filterSheet?.context?.let {
MaterialDialog(it)
.title(text = "Delete saved search query?")
.message(text = "Are you sure you wish to delete your saved search query: '${search.name}'?")
.title(R.string.save_search_delete)
.message(text = it.getString(R.string.save_search_delete_message, search.name))
.positiveButton(R.string.action_cancel)
.negativeButton(text = "Confirm") {
.negativeButton(android.R.string.yes) {
val newSearches = savedSearches.filterIndexed { index, _ ->
index != indexToDelete
}
@@ -696,7 +696,7 @@ class LibraryController(
private fun showSyncProgressDialog() {
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title(text = "Favorites syncing")
?.title(R.string.favorites_syncing)
?.cancelable(false)
// ?.progress(true, 0)
favSyncDialog?.show()
@@ -723,15 +723,15 @@ class LibraryController(
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title(text = "Favorites sync error")
?.message(text = status.message + " Sync will not start until the gallery is in only one category.")
?.title(R.string.favorites_sync_error)
?.message(text = activity!!.getString(R.string.favorites_sync_bad_library_state, status.message))
?.cancelable(false)
?.positiveButton(text = "Show gallery") {
?.positiveButton(R.string.show_gallery) {
openManga(status.manga)
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle(activity!!))
}
?.negativeButton(android.R.string.ok) {
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle(activity!!))
}
favSyncDialog?.show()
}
@@ -740,11 +740,11 @@ class LibraryController(
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title(text = "Favorites sync error")
?.message(text = "An error occurred during the sync process: ${status.message}")
?.title(R.string.favorites_sync_error)
?.message(text = activity!!.getString(R.string.favorites_sync_error_string, status.message))
?.cancelable(false)
?.positiveButton(android.R.string.ok) {
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle(activity!!))
}
favSyncDialog?.show()
}
@@ -753,11 +753,11 @@ class LibraryController(
favSyncDialog?.dismiss()
favSyncDialog = buildDialog()
?.title(text = "Favorites sync complete with errors")
?.message(text = "Errors occurred during the sync process that were ignored:\n${status.message}")
?.title(R.string.favorites_sync_done_errors)
?.message(text = activity!!.getString(R.string.favorites_sync_done_errors_message, status.message))
?.cancelable(false)
?.positiveButton(android.R.string.ok) {
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle())
presenter.favoritesSync.status.onNext(FavoritesSyncStatus.Idle(activity!!))
}
favSyncDialog?.show()
}
@@ -548,7 +548,7 @@ class MangaController :
startActivityForResult(
Intent.createChooser(
intent,
resources?.getString(R.string.select_cover_image)
resources?.getString(R.string.action_edit_cover)
),
REQUEST_EDIT_MANGA_COVER
)
@@ -750,7 +750,7 @@ class MangaController :
presenter.editCoverWithStream(uri)
}
} catch (error: IOException) {
activity.toast(R.string.failed_to_update_cover)
activity.toast(R.string.notification_cover_update_failed)
Timber.e(error)
}
}
@@ -133,7 +133,7 @@ class MangaInfoHeaderAdapter(
binding.btnSmartSearch.clicks()
.onEach { controller.openSmartSearch() }
.launchIn(scope)
binding.btnSmartSearch.setTooltip(R.string.eh_merge_with_another_source)
binding.btnSmartSearch.setTooltip(R.string.merge_with_another_source)
}
// SY <--
@@ -146,12 +146,12 @@ class SettingsAdvancedController : SettingsController() {
// --> EXH
preferenceCategory {
title = "Developer tools"
titleRes = R.string.developer_tools
isPersistent = false
switchPreference {
title = "Enable integrated hentai features"
summary = "This is a experimental feature that will disable all hentai features if toggled off"
titleRes = R.string.toggle_hentai_features
summaryRes = R.string.toggle_hentai_features_summary
key = Keys.eh_is_hentai_enabled
defaultValue = true
@@ -212,35 +212,35 @@ class SettingsAdvancedController : SettingsController() {
}
switchPreference {
title = "Enable delegated sources"
titleRes = R.string.toggle_delegated_sources
key = Keys.eh_delegateSources
defaultValue = true
summary = "Apply ${context.getString(R.string.app_name)} enhancements to the following sources if they are installed: ${DELEGATED_SOURCES.values.map { it.sourceName }.distinct().joinToString()}"
summary = context.getString(R.string.toggle_delegated_sources_summary, context.getString(R.string.app_name), DELEGATED_SOURCES.values.map { it.sourceName }.distinct().joinToString())
}
intListPreference {
key = Keys.eh_logLevel
title = "Log level"
titleRes = R.string.log_level
entries = EHLogLevel.values().map {
"${it.name.toLowerCase().capitalize()} (${it.description})"
"${context.getString(it.nameRes)} (${context.getString(it.description)})"
}.toTypedArray()
entryValues = EHLogLevel.values().mapIndexed { index, _ -> "$index" }.toTypedArray()
defaultValue = "0"
summary = "Changing this can impact app performance. Force-restart app after changing. Current value: %s"
summaryRes = R.string.log_level_summary
}
switchPreference {
title = "Enable source blacklist"
titleRes = R.string.enable_source_blacklist
key = Keys.eh_enableSourceBlacklist
defaultValue = true
summary = "Hide extensions/sources that are incompatible with ${context.getString(R.string.app_name)}. Force-restart app after changing."
summary = context.getString(R.string.enable_source_blacklist_summary, context.getString(R.string.app_name))
}
preference {
title = "Open debug menu"
summary = HtmlCompat.fromHtml("DO NOT TOUCH THIS MENU UNLESS YOU KNOW WHAT YOU ARE DOING! <font color='red'>IT CAN CORRUPT YOUR LIBRARY!</font>", HtmlCompat.FROM_HTML_MODE_LEGACY)
titleRes = R.string.open_debug_menu
summary = HtmlCompat.fromHtml(context.getString(R.string.open_debug_menu_summary), HtmlCompat.FROM_HTML_MODE_LEGACY)
onClick { router.pushController(SettingsDebugController().withFadeTransaction()) }
}
}
@@ -33,6 +33,7 @@ import eu.kanade.tachiyomi.util.preference.preference
import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.toast
import exh.EH_SOURCE_ID
import exh.EXH_SOURCE_ID
@@ -143,14 +144,14 @@ class SettingsEhController : SettingsController() {
}
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
title = "E-Hentai"
titleRes = R.string.pref_category_eh
preferenceCategory {
title = "E-Hentai Website Account Settings"
titleRes = R.string.ehentai_prefs_account_settings
switchPreference {
title = "Enable ExHentai"
summaryOff = "Requires login"
titleRes = R.string.enable_exhentai
summaryOff = context.getString(R.string.requires_login)
key = PreferenceKeys.eh_enableExHentai
isPersistent = false
defaultValue = false
@@ -178,33 +179,23 @@ class SettingsEhController : SettingsController() {
}
intListPreference {
title = "Use Hentai@Home Network"
titleRes = R.string.use_hentai_at_home
key = PreferenceKeys.eh_enable_hah
if (preferences.eh_hathPerksCookies().get().isBlank()) {
summary = "Do you wish to load images through the Hentai@Home Network, if available? Disabling this option will reduce the amount of pages you are able to view\nOptions:\n - Any client (Recommended)\n - Default port clients only (Can be slower. Enable if behind firewall/proxy that blocks outgoing non-standard ports.)"
entries = arrayOf(
"Any client (Recommended)",
"Default port clients only"
)
entryValues = arrayOf("0", "1")
} else {
summary = "Do you wish to load images through the Hentai@Home Network, if available? Disabling this option will reduce the amount of pages you are able to view\nOptions:\n - Any client (Recommended)\n - Default port clients only (Can be slower. Enable if behind firewall/proxy that blocks outgoing non-standard ports.)\n - No (Donator only. You will not be able to browse as many pages, enable only if having severe problems.)"
entries = arrayOf(
"Any client (Recommended)",
"Default port clients only",
"No(will select Default port clients only if you are not a donator)"
)
entryValues = arrayOf("0", "1", "2")
}
summaryRes = R.string.use_hentai_at_home_summary
entriesRes = arrayOf(
R.string.use_hentai_at_home_option_1,
R.string.use_hentai_at_home_option_2
)
entryValues = arrayOf("0", "1")
onChange { preferences.useHentaiAtHome().reconfigure() }
}.dependency = PreferenceKeys.eh_enableExHentai
switchPreference {
title = "Show Japanese titles in search results"
summaryOn = "Currently showing Japanese titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
summaryOff = "Currently showing English/Romanized titles in search results. Clear the chapter cache after changing this (in the Advanced section)"
titleRes = R.string.show_japanese_titles
summaryOn = context.getString(R.string.show_japanese_titles_option_1)
summaryOff = context.getString(R.string.show_japanese_titles_option_2)
key = "use_jp_title"
defaultValue = false
@@ -212,9 +203,9 @@ class SettingsEhController : SettingsController() {
}.dependency = PreferenceKeys.eh_enableExHentai
switchPreference {
title = "Use original images"
summaryOn = "Currently using original images"
summaryOff = "Currently using resampled images"
titleRes = R.string.use_original_images
summaryOn = context.getString(R.string.use_original_images_on)
summaryOff = context.getString(R.string.use_original_images_off)
key = PreferenceKeys.eh_useOrigImages
defaultValue = false
@@ -222,28 +213,28 @@ class SettingsEhController : SettingsController() {
}.dependency = PreferenceKeys.eh_enableExHentai
preference {
title = "Watched Tags"
summary = "Opens a webview to your E/ExHentai watched tags page"
titleRes = R.string.watched_tags
summaryRes = R.string.watched_tags_summary
onClick {
val intent = if (preferences.enableExhentai().get()) {
WebViewActivity.newIntent(activity!!, url = "https://exhentai.org/mytags", title = "ExHentai Watched Tags")
WebViewActivity.newIntent(activity!!, url = "https://exhentai.org/mytags", title = context.getString(R.string.watched_tags_exh))
} else {
WebViewActivity.newIntent(activity!!, url = "https://e-hentai.org/mytags", title = "E-Hentai Watched Tags")
WebViewActivity.newIntent(activity!!, url = "https://e-hentai.org/mytags", title = context.getString(R.string.watched_tags_eh))
}
startActivity(intent)
}
}.dependency = PreferenceKeys.eh_enableExHentai
preference {
title = "Tag Filtering Threshold"
titleRes = R.string.tag_filtering_threshold
key = PreferenceKeys.eh_tag_filtering_value
defaultValue = 0
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: ${preferences.ehTagFilterValue().get()}"
summaryRes = R.string.tag_filtering_threshhold_summary
onClick {
MaterialDialog(activity!!)
.title(text = "Tag Filtering Threshold")
.title(R.string.tag_filtering_threshold)
.input(
inputType = InputType.TYPE_NUMBER_FLAG_SIGNED,
waitForPositiveButton = false,
@@ -255,14 +246,13 @@ class SettingsEhController : SettingsController() {
if (value != null && value in -9999..0) {
inputField.error = null
} else {
inputField.error = "Must be between -9999 and 0!"
inputField.error = context.getString(R.string.tag_filtering_threshhold_error)
}
dialog.setActionButtonEnabled(WhichButton.POSITIVE, value != null && value in -9999..0)
}
.positiveButton(android.R.string.ok) {
val value = it.getInputField().text.toString().toInt()
preferences.ehTagFilterValue().set(value)
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 0 and -9999. Currently: $value"
preferences.ehTagFilterValue().reconfigure()
}
.show()
@@ -270,15 +260,15 @@ class SettingsEhController : SettingsController() {
}.dependency = PreferenceKeys.eh_enableExHentai
preference {
title = "Tag Watching Threshold"
titleRes = R.string.tag_watching_threshhold
key = PreferenceKeys.eh_tag_watching_value
defaultValue = 0
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: ${preferences.ehTagWatchingValue().get()}"
summaryRes = R.string.tag_watching_threshhold_summary
onClick {
MaterialDialog(activity!!)
.title(text = "Tag Watching Threshold")
.title(R.string.tag_watching_threshhold)
.input(
inputType = InputType.TYPE_NUMBER_FLAG_SIGNED,
maxLength = 4,
@@ -291,14 +281,13 @@ class SettingsEhController : SettingsController() {
if (value != null && value in 0..9999) {
inputField.error = null
} else {
inputField.error = "Must be between 0 and 9999!"
inputField.error = context.getString(R.string.tag_watching_threshhold_error)
}
dialog.setActionButtonEnabled(WhichButton.POSITIVE, value != null && value in 0..9999)
}
.positiveButton(android.R.string.ok) {
val value = it.getInputField().text.toString().toInt()
preferences.ehTagWatchingValue().set(value)
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: $value"
preferences.ehTagWatchingValue().reconfigure()
}
.show()
@@ -306,13 +295,13 @@ class SettingsEhController : SettingsController() {
}.dependency = PreferenceKeys.eh_enableExHentai
preference {
title = "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"
titleRes = R.string.language_filtering
summaryRes = R.string.language_filtering_summary
onClick {
MaterialDialog(activity!!)
.title(text = "Language Filtering")
.message(text = "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")
.title(R.string.language_filtering)
.message(R.string.language_filtering_summary)
.customView(R.layout.eh_dialog_languages, scrollable = true)
.positiveButton(android.R.string.ok) {
val customView = it.view.contentLayout.customView!!
@@ -444,13 +433,13 @@ class SettingsEhController : SettingsController() {
}.dependency = PreferenceKeys.eh_enableExHentai
preference {
title = "Front 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"
titleRes = R.string.frong_page_categories
summaryRes = R.string.fromt_page_categories_summary
onClick {
MaterialDialog(activity!!)
.title(text = "Front Page Categories")
.message(text = "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")
.title(R.string.frong_page_categories)
.message(R.string.fromt_page_categories_summary)
.customView(R.layout.eh_dialog_categories, scrollable = true)
.positiveButton {
val customView = it.view.contentLayout.customView!!
@@ -497,22 +486,22 @@ class SettingsEhController : SettingsController() {
switchPreference {
defaultValue = false
key = PreferenceKeys.eh_watched_list_default_state
title = "Watched List Filter Default State"
summary = "When browsing ExHentai/E-Hentai should the watched list filter be enabled by default"
}
titleRes = R.string.watched_list_default
summaryRes = R.string.watched_list_state_summary
}.dependency = PreferenceKeys.eh_enableExHentai
listPreference {
defaultValue = "auto"
key = PreferenceKeys.eh_ehentai_quality
summary = "The quality of the downloaded images"
title = "Image quality"
entries = arrayOf(
"Auto",
"2400x",
"1600x",
"1280x",
"980x",
"780x"
summaryRes = R.string.eh_image_quality_summary
titleRes = R.string.eh_image_quality
entriesRes = arrayOf(
R.string.eh_image_quality_auto,
R.string.eh_image_quality_2400,
R.string.eh_image_quality_1600,
R.string.eh_image_quality_1280,
R.string.eh_image_quality_980,
R.string.eh_image_quality_780
)
entryValues = arrayOf(
"auto",
@@ -528,18 +517,18 @@ class SettingsEhController : SettingsController() {
}
preferenceCategory {
title = "Favorites sync"
titleRes = R.string.favorites_sync
switchPreference {
title = "Disable favorites uploading"
summary = "Favorites are only downloaded from ExHentai. Any changes to favorites in the app will not be uploaded. Prevents accidental loss of favorites on ExHentai. Note that removals will still be downloaded (if you remove a favorites on ExHentai, it will be removed in the app as well)."
titleRes = R.string.disable_favorites_uploading
summaryRes = R.string.disable_favorites_uploading_summary
key = PreferenceKeys.eh_readOnlySync
defaultValue = false
}
preference {
title = "Show favorites sync notes"
summary = "Show some information regarding the favorites sync feature"
titleRes = R.string.show_favorite_sync_notes
summaryRes = R.string.show_favorite_sync_notes_summary
onClick {
activity?.let {
@@ -549,21 +538,21 @@ class SettingsEhController : SettingsController() {
}
switchPreference {
title = "Ignore sync errors when possible"
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."
titleRes = R.string.ignore_sync_errors
summaryRes = R.string.ignore_sync_errors_summary
key = PreferenceKeys.eh_lenientSync
defaultValue = false
}
preference {
title = "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."
titleRes = R.string.force_sync_state_reset
summaryRes = R.string.force_sync_state_reset_summary
onClick {
activity?.let { activity ->
MaterialDialog(activity)
.title(R.string.eh_force_sync_reset_title)
.message(R.string.eh_force_sync_reset_message)
.title(R.string.favorites_sync_reset)
.message(R.string.favorites_sync_reset_message)
.positiveButton(android.R.string.yes) {
LocalFavoritesStorage().apply {
getRealm().use {
@@ -572,7 +561,7 @@ class SettingsEhController : SettingsController() {
}
}
}
activity.toast("Sync state reset", Toast.LENGTH_LONG)
activity.toast(context.getString(R.string.sync_state_reset), Toast.LENGTH_LONG)
}
.negativeButton(android.R.string.no)
.cancelable(false)
@@ -583,20 +572,20 @@ class SettingsEhController : SettingsController() {
}
preferenceCategory {
title = "Gallery update checker"
titleRes = R.string.gallery_update_checker
intListPreference {
key = PreferenceKeys.eh_autoUpdateFrequency
title = "Time between update batches"
entries = arrayOf(
"Never update galleries",
"1 hour",
"2 hours",
"3 hours",
"6 hours",
"12 hours",
"24 hours",
"48 hours"
titleRes = R.string.time_between_batches
entriesRes = arrayOf(
R.string.time_between_batches_never,
R.string.time_between_batches_1_hour,
R.string.time_between_batches_2_hours,
R.string.time_between_batches_3_hours,
R.string.time_between_batches_6_hours,
R.string.time_between_batches_12_hours,
R.string.time_between_batches_24_hours,
R.string.time_between_batches_48_hours
)
entryValues = arrayOf("0", "1", "2", "3", "6", "12", "24", "48")
defaultValue = "0"
@@ -604,11 +593,9 @@ class SettingsEhController : SettingsController() {
preferences.eh_autoUpdateFrequency().asFlow()
.onEach { newVal ->
summary = if (newVal == 0) {
"${context.getString(R.string.app_name)} will currently never check galleries in your library for updates."
context.getString(R.string.time_between_batches_summary_1, context.getString(R.string.app_name))
} else {
"${context.getString(R.string.app_name)} checks/updates galleries in batches. " +
"This means it will wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} galleries," +
" wait $newVal hour(s), check ${EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION} and so on..."
context.getString(R.string.time_between_batches_summary_2, context.getString(R.string.app_name), newVal, EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION)
}
}
.launchIn(scope)
@@ -622,7 +609,7 @@ class SettingsEhController : SettingsController() {
multiSelectListPreference {
key = PreferenceKeys.eh_autoUpdateRestrictions
title = "Auto update restrictions"
titleRes = R.string.auto_update_restrictions
entriesRes = arrayOf(R.string.wifi, R.string.charging)
entryValues = arrayOf("wifi", "ac")
summaryRes = R.string.pref_library_update_restriction_summary
@@ -639,11 +626,11 @@ class SettingsEhController : SettingsController() {
}
preference {
title = "Show updater statistics"
titleRes = R.string.show_updater_statistics
onClick {
val progress = MaterialDialog(context)
.message(R.string.eh_show_update_statistics_dialog)
.message(R.string.gallery_updater_statistics_collection)
.cancelable(false)
progress.show()
@@ -655,8 +642,8 @@ class SettingsEhController : SettingsController() {
}
val statsText = if (stats != null) {
"The updater last ran ${Humanize.naturalTime(Date(stats.startTime))}, and checked ${stats.updateCount} out of the ${stats.possibleUpdates} galleries that were ready for checking."
} else "The updater has not ran yet."
context.getString(R.string.gallery_updater_stats_text, Humanize.naturalTime(Date(stats.startTime)), stats.updateCount, stats.possibleUpdates)
} else context.getString(R.string.gallery_updater_not_ran_yet)
val allMeta = db.getFavoriteMangaWithMetadata().await().filter {
it.source == EH_SOURCE_ID || it.source == EXH_SOURCE_ID
@@ -672,26 +659,24 @@ class SettingsEhController : SettingsController() {
}.count()
}
"""
$statsText
Galleries that were checked in the last:
- hour: ${metaInRelativeDuration(1.hours)}
- 6 hours: ${metaInRelativeDuration(6.hours)}
- 12 hours: ${metaInRelativeDuration(12.hours)}
- day: ${metaInRelativeDuration(1.days)}
- 2 days: ${metaInRelativeDuration(2.days)}
- week: ${metaInRelativeDuration(7.days)}
- month: ${metaInRelativeDuration(30.days)}
- year: ${metaInRelativeDuration(365.days)}
""".trimIndent()
statsText + "\n\n" + context.getString(
R.string.gallery_updater_stats_time,
metaInRelativeDuration(1.hours),
metaInRelativeDuration(6.hours),
metaInRelativeDuration(12.hours),
metaInRelativeDuration(1.days),
metaInRelativeDuration(2.days),
metaInRelativeDuration(7.days),
metaInRelativeDuration(30.days),
metaInRelativeDuration(365.days)
)
} finally {
progress.dismiss()
}
withContext(Dispatchers.Main) {
MaterialDialog(context)
.title(text = "Gallery updater statistics")
.title(R.string.gallery_updater_statistics)
.message(text = updateInfo)
.positiveButton(android.R.string.ok)
.show()
@@ -16,6 +16,7 @@ import eu.kanade.tachiyomi.util.preference.onChange
import eu.kanade.tachiyomi.util.preference.onClick
import eu.kanade.tachiyomi.util.preference.preference
import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.LocaleHelper
@@ -252,19 +253,18 @@ class SettingsGeneralController : SettingsController() {
}
// --> EXH
preferenceCategory {
titleRes = R.string.eh_settings_category
titleRes = R.string.pref_category_fork
switchPreference {
key = Keys.eh_expandFilters
title = "Expand all search filters by default"
titleRes = R.string.toggle_expand_search_filters
defaultValue = false
}
switchPreference {
key = Keys.eh_autoSolveCaptchas
title = "Automatically solve captcha"
summary =
"Use HIGHLY EXPERIMENTAL automatic ReCAPTCHA solver. Will be grayed out if unsupported by your device."
titleRes = R.string.auto_solve_captchas
summaryRes = R.string.auto_solve_captchas_summary
defaultValue = false
}
}
@@ -1,9 +1,12 @@
package eu.kanade.tachiyomi.ui.setting
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
import eu.kanade.tachiyomi.util.preference.defaultValue
import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
/**
* hitomi.la Settings fragment
@@ -11,11 +14,11 @@ import eu.kanade.tachiyomi.util.preference.switchPreference
class SettingsHlController : SettingsController() {
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
title = "hitomi.la"
titleRes = R.string.pref_category_hl
switchPreference {
title = "Use high-quality thumbnails"
summary = "May slow down search results"
titleRes = R.string.high_quality_thumbnails
summaryRes = R.string.high_quality_thumbnails_summary
key = PreferenceKeys.eh_hl_useHighQualityThumbs
defaultValue = false
}
@@ -219,11 +219,11 @@ class SettingsLibraryController : SettingsController() {
.isNotEmpty()
) {
preferenceCategory {
title = "Migration"
titleRes = R.string.migration
switchPreference {
key = Keys.skipPreMigration
titleRes = R.string.pref_skip_pre_migration
titleRes = R.string.skip_pre_migration
summaryRes = R.string.pref_skip_pre_migration_summary
defaultValue = false
}
@@ -1,9 +1,12 @@
package eu.kanade.tachiyomi.ui.setting
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
import eu.kanade.tachiyomi.util.preference.defaultValue
import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
/**
* nhentai Settings fragment
@@ -11,11 +14,11 @@ import eu.kanade.tachiyomi.util.preference.switchPreference
class SettingsNhController : SettingsController() {
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
title = "nhentai"
titleRes = R.string.pref_category_nh
switchPreference {
title = "Use high-quality thumbnails"
summary = "May slow down search results"
titleRes = R.string.high_quality_thumbnails
summaryRes = R.string.high_quality_thumbnails_summary
key = PreferenceKeys.eh_nh_useHighQualityThumbs
defaultValue = false
}
@@ -140,34 +140,31 @@ class SettingsReaderController : SettingsController() {
// EXH -->
preferenceCategory {
titleRes = R.string.eh_settings_category
titleRes = R.string.pref_category_fork
intListPreference {
key = Keys.eh_readerThreads
title = "Download threads"
titleRes = R.string.download_threads
entries = arrayOf("1", "2", "3", "4", "5")
entryValues = entries
defaultValue = "2"
summary =
"Higher values can speed up image downloading significantly, but can also trigger bans. Recommended value is 2 or 3. Current value is: %s"
summaryRes = R.string.download_threads_summary
}
switchPreference {
key = Keys.eh_aggressivePageLoading
title = "Aggressively load pages"
summary =
"Slowly download the entire gallery while reading instead of just loading the pages you are viewing."
titleRes = R.string.aggressively_load_pages
summaryRes = R.string.aggressively_load_pages_summary
defaultValue = false
}
switchPreference {
key = Keys.eh_readerInstantRetry
title = "Skip queue on retry"
summary =
"Normally, pressing the retry button on a failed download will wait until the downloader has finished downloading the last page before beginning to re-download the failed page. Enabling this will force the downloader to begin re-downloading the failed page as soon as you press the retry button."
titleRes = R.string.skip_queue_on_retry
summaryRes = R.string.skip_queue_on_retry_summary
defaultValue = true
}
intListPreference {
key = Keys.eh_preload_size
title = "Reader Preload amount"
titleRes = R.string.reader_preload_amount
entryValues = arrayOf(
"1",
"2",
@@ -180,25 +177,24 @@ class SettingsReaderController : SettingsController() {
"14",
"16"
)
entries = arrayOf(
"1 Page",
"2 Pages",
"3 Pages",
"4 Pages",
"6 Pages",
"8 Pages",
"10 Pages",
"12 Pages",
"14 Pages",
"16 Pages"
entriesRes = arrayOf(
R.string.reader_preload_amount_1_page,
R.string.reader_preload_amount_2_pages,
R.string.reader_preload_amount_3_pages,
R.string.reader_preload_amount_4_pages,
R.string.reader_preload_amount_6_pages,
R.string.reader_preload_amount_8_pages,
R.string.reader_preload_amount_10_pages,
R.string.reader_preload_amount_12_pages,
R.string.reader_preload_amount_14_pages,
R.string.reader_preload_amount_16_pages
)
defaultValue = "4"
summary =
"The amount of pages to preload when reading. Higher values will result in a smoother reading experience, at the cost of higher cache usage, it is recommended to increase the amount of cache you allocate when using larger values"
summaryRes = R.string.reader_preload_amount_summary
}
listPreference {
key = Keys.eh_cacheSize
title = "Reader cache size"
titleRes = R.string.reader_cache_size
entryValues = arrayOf(
"50",
"75",
@@ -236,18 +232,17 @@ class SettingsReaderController : SettingsController() {
"5 GB"
)
defaultValue = "75"
summary =
"The amount of images to save on device while reading. Higher values will result in a smoother reading experience, at the cost of higher disk space usage"
summaryRes = R.string.reader_cache_size_summary
}
switchPreference {
key = Keys.eh_preserveReadingPosition
title = "Preserve reading position on read manga"
titleRes = R.string.preserve_reading_position
defaultValue = false
}
switchPreference {
key = Keys.eh_use_auto_webtoon
title = "Auto Webtoon Mode"
summary = "Use auto webtoon mode for manga that are detected to likely use the long strip format"
titleRes = R.string.auto_webtoon_mode
summaryRes = R.string.auto_webtoon_mode_summary
defaultValue = true
}
}
@@ -4,7 +4,6 @@ import android.content.Context
import android.widget.ArrayAdapter
import android.widget.Filter
import android.widget.Filterable
import timber.log.Timber
class AutoCompleteAdapter(context: Context, resource: Int, var objects: List<String>, val excludePrefix: String?) :
ArrayAdapter<String>(context, resource, objects),
@@ -35,8 +34,6 @@ class AutoCompleteAdapter(context: Context, resource: Int, var objects: List<Str
mOriginalValues = objects
}
Timber.d("$prefix ")
if (prefix == null || prefix.isEmpty()) {
val list = mOriginalValues!!
results.values = list
@@ -44,7 +41,6 @@ class AutoCompleteAdapter(context: Context, resource: Int, var objects: List<Str
} else {
val prefixString = prefix.toString()
val containsPrefix: Boolean = excludePrefix?.let { prefixString.startsWith(it) } ?: false
Timber.d(prefixString)
val filterResults = mOriginalValues!!.filter { it.contains(if (excludePrefix != null) prefixString.removePrefix(excludePrefix) else prefixString, true) }
results.values = if (containsPrefix) filterResults.map { excludePrefix + it } else filterResults
results.count = filterResults.size
+26 -22
View File
@@ -1,7 +1,9 @@
package exh
import android.content.Context
import android.net.Uri
import com.elvishew.xlog.XLog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.SourceManager
@@ -18,12 +20,13 @@ class GalleryAdder {
private val sourceManager: SourceManager by injectLazy()
fun addGallery(
context: Context,
url: String,
fav: Boolean = false,
forceSource: UrlImportableSource? = null,
throttleFunc: () -> Unit = {}
): GalleryAddEvent {
XLog.d("Importing gallery (url: %s, fav: %s, forceSource: %s)...", url, fav, forceSource)
XLog.d(context.getString(R.string.gallery_adder_importing_gallery, url, fav.toString(), forceSource))
try {
val uri = Uri.parse(url)
@@ -31,10 +34,10 @@ class GalleryAdder {
val source = if (forceSource != null) {
try {
if (forceSource.matchesUri(uri)) forceSource
else return GalleryAddEvent.Fail.UnknownType(url)
else return GalleryAddEvent.Fail.UnknownType(url, context)
} catch (e: Exception) {
XLog.e("Source URI match check error!", e)
return GalleryAddEvent.Fail.UnknownType(url)
XLog.e(context.getString(R.string.gallery_adder_source_uri_must_match), e)
return GalleryAddEvent.Fail.UnknownType(url, context)
}
} else {
sourceManager.getVisibleCatalogueSources()
@@ -43,7 +46,7 @@ class GalleryAdder {
try {
it.matchesUri(uri)
} catch (e: Exception) {
XLog.e("Source URI match check error!", e)
XLog.e(context.getString(R.string.gallery_adder_source_uri_must_match), e)
false
}
} ?: sourceManager.getDelegatedCatalogueSources()
@@ -52,27 +55,27 @@ class GalleryAdder {
try {
it.matchesUri(uri)
} catch (e: Exception) {
XLog.e("Source URI match check error!", e)
XLog.e(context.getString(R.string.gallery_adder_source_uri_must_match), e)
false
}
} ?: return GalleryAddEvent.Fail.UnknownType(url)
} ?: return GalleryAddEvent.Fail.UnknownType(url, context)
}
// Map URL to manga URL
val realUrl = try {
source.mapUrlToMangaUrl(uri)
} catch (e: Exception) {
XLog.e("Source URI map-to-manga error!", e)
XLog.e(context.getString(R.string.gallery_adder_uri_map_to_manga_error), e)
null
} ?: return GalleryAddEvent.Fail.UnknownType(url)
} ?: return GalleryAddEvent.Fail.UnknownType(url, context)
// Clean URL
val cleanedUrl = try {
source.cleanMangaUrl(realUrl)
} catch (e: Exception) {
XLog.e("Source URI clean error!", e)
XLog.e(context.getString(R.string.gallery_adder_uri_clean_error), e)
null
} ?: return GalleryAddEvent.Fail.UnknownType(url)
} ?: return GalleryAddEvent.Fail.UnknownType(url, context)
// Use manga in DB if possible, otherwise, make a new manga
val manga = db.getManga(cleanedUrl, source.id).executeAsBlocking()
@@ -112,16 +115,16 @@ class GalleryAdder {
syncChaptersWithSource(db, it, manga, source)
}.toBlocking().first()
} catch (e: Exception) {
XLog.w("Failed to update chapters for gallery: ${manga.title}!", e)
return GalleryAddEvent.Fail.Error(url, "Failed to update chapters for gallery: $url")
XLog.w(context.getString(R.string.gallery_adder_chapter_fetch_error, manga.title), e)
return GalleryAddEvent.Fail.Error(url, context.getString(R.string.gallery_adder_chapter_fetch_error, url))
}
return GalleryAddEvent.Success(url, manga)
return GalleryAddEvent.Success(url, manga, context)
} catch (e: Exception) {
XLog.w("Could not add gallery (url: $url)!", e)
XLog.w(context.getString(R.string.gallery_adder_could_not_add_gallery, url), e)
if (e is EHentai.GalleryNotFoundException) {
return GalleryAddEvent.Fail.NotFound(url)
return GalleryAddEvent.Fail.NotFound(url, context)
}
return GalleryAddEvent.Fail.Error(
@@ -139,15 +142,16 @@ sealed class GalleryAddEvent {
class Success(
override val galleryUrl: String,
val manga: Manga
val manga: Manga,
val context: Context
) : GalleryAddEvent() {
override val galleryTitle = manga.title
override val logMessage = "Added gallery: $galleryTitle"
override val logMessage = context.getString(R.string.batch_add_success_log_message, galleryTitle)
}
sealed class Fail : GalleryAddEvent() {
class UnknownType(override val galleryUrl: String) : Fail() {
override val logMessage = "Unknown gallery type for gallery: $galleryUrl"
class UnknownType(override val galleryUrl: String, val context: Context) : Fail() {
override val logMessage = context.getString(R.string.batch_add_unknown_type_log_message, galleryUrl)
}
open class Error(
@@ -155,7 +159,7 @@ sealed class GalleryAddEvent {
override val logMessage: String
) : Fail()
class NotFound(galleryUrl: String) :
Error(galleryUrl, "Gallery does not exist: $galleryUrl")
class NotFound(galleryUrl: String, context: Context) :
Error(galleryUrl, context.getString(R.string.batch_add_not_exist_log_message, galleryUrl))
}
}
@@ -3,6 +3,7 @@ package exh.favorites
import android.content.Context
import androidx.core.text.HtmlCompat
import com.afollestad.materialdialogs.MaterialDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import uy.kohesive.injekt.injectLazy
@@ -10,26 +11,11 @@ class FavoritesIntroDialog {
private val prefs: PreferencesHelper by injectLazy()
fun show(context: Context) = MaterialDialog(context)
.title(text = "IMPORTANT FAVORITES SYNC NOTES")
.message(text = HtmlCompat.fromHtml(FAVORITES_INTRO_TEXT, HtmlCompat.FROM_HTML_MODE_LEGACY))
.title(R.string.favorites_sync_notes)
.message(text = HtmlCompat.fromHtml(context.getString(R.string.favorites_sync_notes_message), HtmlCompat.FROM_HTML_MODE_LEGACY))
.positiveButton(android.R.string.ok) {
prefs.eh_showSyncIntro().set(false)
}
.cancelable(false)
.show()
private val FAVORITES_INTRO_TEXT =
"""
1. Changes to category names in the app are <b>NOT</b> synced! Please <i>change the category names on ExHentai instead</i>. The category names will be copied from the ExHentai servers every sync.
<br><br>
2. The favorite categories on ExHentai correspond to the <b>first 10 categories in the app</b> (excluding the 'Default' category). <i>Galleries in other categories will <b>NOT</b> be synced!</i>
<br><br>
3. <font color='red'><b>ENSURE YOU HAVE A STABLE INTERNET CONNECTION WHEN SYNC IS IN PROGRESS!</b></font> If the internet disconnects while the app is syncing, your favorites may be left in a <i>partially-synced state</i>.
<br><br>
4. Keep the app open while favorites are syncing. Android will close apps that are in the background sometimes and that could be bad if it happens while the app is syncing.
<br><br>
5. <b>Do NOT put favorites in multiple categories</b> (the app supports this). This can confuse the sync algorithm as ExHentai only allows each favorite to be in one category.
<br><br>
This dialog will only popup once. You can read these notes again by going to 'Settings > E-Hentai > Show favorites sync notes'.
""".trimIndent()
}
@@ -4,6 +4,7 @@ import android.content.Context
import android.net.wifi.WifiManager
import android.os.PowerManager
import com.elvishew.xlog.XLog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Manga
@@ -52,7 +53,7 @@ class FavoritesSyncHelper(val context: Context) {
private val logger = XLog.tag("EHFavSync").build()
val status = BehaviorSubject.create<FavoritesSyncStatus>(FavoritesSyncStatus.Idle())
val status = BehaviorSubject.create<FavoritesSyncStatus>(FavoritesSyncStatus.Idle(context))
@Synchronized
fun runSync() {
@@ -60,7 +61,7 @@ class FavoritesSyncHelper(val context: Context) {
return
}
status.onNext(FavoritesSyncStatus.Initializing())
status.onNext(FavoritesSyncStatus.Initializing(context))
thread { beginSync() }
}
@@ -68,12 +69,12 @@ class FavoritesSyncHelper(val context: Context) {
private fun beginSync() {
// Check if logged in
if (!prefs.enableExhentai().get()) {
status.onNext(FavoritesSyncStatus.Error("Please log in!"))
status.onNext(FavoritesSyncStatus.Error(context.getString(R.string.please_login)))
return
}
// Validate library state
status.onNext(FavoritesSyncStatus.Processing("Verifying local library"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_verifying_library), context = context))
val libraryManga = db.getLibraryMangas().executeAsBlocking()
val seenManga = HashSet<Long>(libraryManga.size)
libraryManga.forEach {
@@ -83,9 +84,9 @@ class FavoritesSyncHelper(val context: Context) {
val inCategories = db.getCategoriesForManga(it).executeAsBlocking()
status.onNext(
FavoritesSyncStatus.BadLibraryState
.MangaInMultipleCategories(it, inCategories)
.MangaInMultipleCategories(it, inCategories, context)
)
logger.w("Manga %s is in multiple categories!", it.id)
logger.w(context.getString(R.string.favorites_sync_manga_multiple_categories_error, it.id))
return
} else {
seenManga += it.id!!
@@ -94,11 +95,11 @@ class FavoritesSyncHelper(val context: Context) {
// Download remote favorites
val favorites = try {
status.onNext(FavoritesSyncStatus.Processing("Downloading favorites from remote server"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_downloading), context = context))
exh.fetchFavorites()
} catch (e: Exception) {
status.onNext(FavoritesSyncStatus.Error("Failed to fetch favorites from remote server!"))
logger.e("Could not fetch favorites!", e)
status.onNext(FavoritesSyncStatus.Error(context.getString(R.string.favorites_sync_failed_to_featch)))
logger.e(context.getString(R.string.favorites_sync_could_not_fetch), e)
return
}
@@ -127,17 +128,17 @@ class FavoritesSyncHelper(val context: Context) {
storage.getRealm().use { realm ->
realm.trans {
db.inTransaction {
status.onNext(FavoritesSyncStatus.Processing("Calculating remote changes"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_calculating_remote_changes), context = context))
val remoteChanges = storage.getChangedRemoteEntries(realm, favorites.first)
val localChanges = if (prefs.eh_readOnlySync().get()) {
null // Do not build local changes if they are not going to be applied
} else {
status.onNext(FavoritesSyncStatus.Processing("Calculating local changes"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_calculating_local_changes), context = context))
storage.getChangedDbEntries(realm)
}
// Apply remote categories
status.onNext(FavoritesSyncStatus.Processing("Updating category names"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_syncing_category_names), context = context))
applyRemoteCategories(favorites.second)
// Apply change sets
@@ -146,7 +147,7 @@ class FavoritesSyncHelper(val context: Context) {
applyChangeSetToRemote(errorList, localChanges)
}
status.onNext(FavoritesSyncStatus.Processing("Cleaning up"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_cleaning_up), context = context))
storage.snapshotEntries(realm)
}
}
@@ -154,15 +155,15 @@ class FavoritesSyncHelper(val context: Context) {
val theContext = context
launchUI {
theContext.toast("Sync complete!")
theContext.toast(context.getString(R.string.favorites_sync_complete))
}
} catch (e: IgnoredException) {
// Do not display error as this error has already been reported
logger.w("Ignoring exception!", e)
logger.w(context.getString(R.string.favorites_sync_ignoring_exception), e)
return
} catch (e: Exception) {
status.onNext(FavoritesSyncStatus.Error("Unknown error: ${e.message}"))
logger.e("Sync error!", e)
status.onNext(FavoritesSyncStatus.Error(context.getString(R.string.favorites_sync_unknown_error, e.message)))
logger.e(context.getString(R.string.favorites_sync_sync_error), e)
return
} finally {
// Release wake + wifi locks
@@ -180,7 +181,7 @@ class FavoritesSyncHelper(val context: Context) {
}
if (errorList.isEmpty()) {
status.onNext(FavoritesSyncStatus.Idle())
status.onNext(FavoritesSyncStatus.Idle(context))
} else {
status.onNext(FavoritesSyncStatus.CompleteWithErrors(errorList))
}
@@ -268,7 +269,7 @@ class FavoritesSyncHelper(val context: Context) {
break
}
} catch (e: Exception) {
logger.w("Sync network error!", e)
logger.w(context.getString(R.string.favorites_sync_network_error), e)
}
}
@@ -278,7 +279,7 @@ class FavoritesSyncHelper(val context: Context) {
private fun applyChangeSetToRemote(errorList: MutableList<String>, changeSet: ChangeSet) {
// Apply removals
if (changeSet.removed.isNotEmpty()) {
status.onNext(FavoritesSyncStatus.Processing("Removing ${changeSet.removed.size} galleries from remote server"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_removing_galleries, changeSet.removed.size), context = context))
val formBody = FormBody.Builder()
.add("ddact", "delete")
@@ -295,7 +296,7 @@ class FavoritesSyncHelper(val context: Context) {
.build()
if (!explicitlyRetryExhRequest(10, request)) {
val errorString = "Unable to delete galleries from the remote servers!"
val errorString = context.getString(R.string.favorites_sync_unable_to_delete)
if (prefs.eh_lenientSync().get()) {
errorList += errorString
@@ -311,8 +312,9 @@ class FavoritesSyncHelper(val context: Context) {
changeSet.added.forEachIndexed { index, it ->
status.onNext(
FavoritesSyncStatus.Processing(
"Adding gallery ${index + 1} of ${changeSet.added.size} to remote server",
needWarnThrottle()
context.getString(R.string.favorites_sync_adding_to_remote, index + 1, changeSet.added.size),
needWarnThrottle(),
context
)
)
@@ -327,7 +329,7 @@ class FavoritesSyncHelper(val context: Context) {
// Apply removals
changeSet.removed.forEachIndexed { index, it ->
status.onNext(FavoritesSyncStatus.Processing("Removing gallery ${index + 1} of ${changeSet.removed.size} from local library"))
status.onNext(FavoritesSyncStatus.Processing(context.getString(R.string.favorites_sync_remove_from_local, index + 1, changeSet.removed.size), context = context))
val url = it.getUrl()
// Consider both EX and EH sources
@@ -359,8 +361,9 @@ class FavoritesSyncHelper(val context: Context) {
changeSet.added.forEachIndexed { index, it ->
status.onNext(
FavoritesSyncStatus.Processing(
"Adding gallery ${index + 1} of ${changeSet.added.size} to local library",
needWarnThrottle()
context.getString(R.string.favorites_sync_add_to_local, index + 1, changeSet.added.size),
needWarnThrottle(),
context
)
)
@@ -368,6 +371,7 @@ class FavoritesSyncHelper(val context: Context) {
// Import using gallery adder
val result = galleryAdder.addGallery(
context,
"${exh.baseUrl}${it.getUrl()}",
true,
exh,
@@ -376,14 +380,14 @@ class FavoritesSyncHelper(val context: Context) {
if (result is GalleryAddEvent.Fail) {
if (result is GalleryAddEvent.Fail.NotFound) {
XLog.e("Remote gallery does not exist, skipping: %s!", it.getUrl())
XLog.e(context.getString(R.string.favorites_sync_remote_not_exist, it.getUrl()))
// Skip this gallery, it no longer exists
return@forEachIndexed
}
val errorString = "Failed to add gallery to local database: " + when (result) {
is GalleryAddEvent.Fail.Error -> "'${it.title}' ${result.logMessage}"
is GalleryAddEvent.Fail.UnknownType -> "'${it.title}' (${result.galleryUrl}) is not a valid gallery!"
val errorString = context.getString(R.string.favorites_sync_failed_to_add_to_local) + when (result) {
is GalleryAddEvent.Fail.Error -> context.getString(R.string.favorites_sync_failed_to_add_to_local_error, it.title, result.logMessage)
is GalleryAddEvent.Fail.UnknownType -> context.getString(R.string.favorites_sync_failed_to_add_to_local_unknown_type, it.title, result.galleryUrl)
}
if (prefs.eh_lenientSync().get()) {
@@ -418,20 +422,22 @@ class FavoritesSyncHelper(val context: Context) {
}
}
// TODO String resources
sealed class FavoritesSyncStatus(val message: String) {
class Error(message: String) : FavoritesSyncStatus(message)
class Idle : FavoritesSyncStatus("Waiting for sync to start")
class Idle(context: Context) : FavoritesSyncStatus(context.getString(R.string.favorites_sync_waiting_for_start))
sealed class BadLibraryState(message: String) : FavoritesSyncStatus(message) {
class MangaInMultipleCategories(
val manga: Manga,
val categories: List<Category>
val categories: List<Category>,
context: Context
) :
BadLibraryState("The gallery: ${manga.title} is in more than one category (${categories.joinToString { it.name }})!")
BadLibraryState(context.getString(R.string.favorites_sync_manga_in_multiple_categories, manga.title, categories.joinToString { it.name }))
}
class Initializing : FavoritesSyncStatus("Initializing sync")
class Processing(message: String, isThrottle: Boolean = false) : FavoritesSyncStatus(
class Initializing(context: Context) : FavoritesSyncStatus(context.getString(R.string.favorites_sync_initializing))
class Processing(message: String, isThrottle: Boolean = false, context: Context) : FavoritesSyncStatus(
if (isThrottle) {
"$message\n\nSync is currently throttling (to avoid being banned from ExHentai) and may take a long time to complete."
context.getString(R.string.favorites_sync_processing_throttle, message)
} else {
message
}
+6 -4
View File
@@ -1,13 +1,15 @@
package exh.log
import android.content.Context
import androidx.annotation.StringRes
import androidx.preference.PreferenceManager
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferenceKeys
enum class EHLogLevel(val description: String) {
MINIMAL("critical errors only"),
EXTRA("log everything"),
EXTREME("network inspection mode");
enum class EHLogLevel(@StringRes val nameRes: Int, @StringRes val description: Int) {
MINIMAL(R.string.log_minimal, R.string.log_minimal_desc),
EXTRA(R.string.log_extra, R.string.log_extra_desc),
EXTREME(R.string.log_extreme, R.string.log_extreme_desc);
companion object {
private var curLogLevel: Int? = null
@@ -4,6 +4,7 @@ import android.app.Dialog
import android.os.Bundle
import android.view.View
import com.afollestad.materialdialogs.MaterialDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.lang.launchUI
import eu.kanade.tachiyomi.util.system.toast
@@ -17,16 +18,16 @@ class ConfiguringDialogController : DialogController() {
if (savedViewState == null) {
thread {
try {
EHConfigurator().configureAll()
EHConfigurator(activity!!).configureAll()
launchUI {
activity?.toast("Settings successfully uploaded!")
activity?.toast(activity?.getString(R.string.eh_settings_successfully_uploaded))
}
} catch (e: Exception) {
activity?.let {
it.runOnUiThread {
MaterialDialog(it)
.title(text = "Configuration failed!")
.message(text = "An error occurred during the configuration process: " + e.message)
.title(R.string.eh_settings_configuration_failed)
.message(text = it.getString(R.string.eh_settings_configuration_failed_message, e.message))
.positiveButton(android.R.string.ok)
.show()
}
@@ -40,8 +41,8 @@ class ConfiguringDialogController : DialogController() {
}
return MaterialDialog(activity!!)
.title(text = "Uploading settings to server")
.message(text = "Please wait, this may take some time...")
.title(R.string.eh_settings_uploading_to_server)
.message(R.string.eh_settings_uploading_to_server_message)
.cancelable(false)
.also {
materialDialog = it
@@ -1,5 +1,7 @@
package exh.uconfig
import android.content.Context
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.online.all.EHentai
@@ -13,7 +15,7 @@ import okhttp3.Request
import timber.log.Timber
import uy.kohesive.injekt.injectLazy
class EHConfigurator {
class EHConfigurator(val context: Context) {
private val prefs: PreferencesHelper by injectLazy()
private val sources: SourceManager by injectLazy()
@@ -104,7 +106,7 @@ class EHConfigurator {
// No profile slots left :(
if (availableProfiles.isEmpty()) {
throw IllegalStateException("You are out of profile slots on ${source.name}, please delete a profile!")
throw IllegalStateException(context.getString(R.string.eh_settings_out_of_slots_error, source.name))
}
// Create profile in available slot
@@ -4,6 +4,7 @@ import android.app.Dialog
import android.os.Bundle
import com.afollestad.materialdialogs.MaterialDialog
import com.bluelinelabs.conductor.Router
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import uy.kohesive.injekt.Injekt
@@ -14,15 +15,8 @@ class WarnConfigureDialogController : DialogController() {
private val prefs: PreferencesHelper by injectLazy()
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog(activity!!)
.title(text = "Settings profile note")
.message(
text =
"""
The app will now add a new settings profile on E-Hentai and ExHentai to optimize app performance. Please ensure that you have less than three profiles on both sites.
If you have no idea what settings profiles are, then it probably doesn't matter, just hit 'OK'.
""".trimIndent()
)
.title(R.string.settings_profile_note)
.message(R.string.settings_profile_note_message)
.positiveButton(android.R.string.ok) {
prefs.eh_showSettingsUploadWarning().set(false)
ConfiguringDialogController().showDialog(router)
@@ -5,6 +5,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import com.afollestad.materialdialogs.MaterialDialog
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.databinding.EhFragmentBatchAddBinding
import eu.kanade.tachiyomi.ui.base.controller.NucleusController
import eu.kanade.tachiyomi.util.lang.combineLatest
@@ -26,7 +27,7 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
return binding.root
}
override fun getTitle() = "Batch add"
override fun getTitle() = activity!!.getString(R.string.batch_add)
override fun createPresenter() = BatchAddPresenter()
@@ -145,14 +146,14 @@ class BatchAddController : NucleusController<EhFragmentBatchAddBinding, BatchAdd
return
}
presenter.addGalleries(galleries)
presenter.addGalleries(activity!!, galleries)
}
private fun noGalleriesSpecified() {
activity?.let {
MaterialDialog(it)
.title(text = "No galleries to add!")
.message(text = "You must specify at least one gallery to add!")
.title(R.string.batch_add_no_valid_galleries)
.message(R.string.batch_add_no_valid_galleries_message)
.positiveButton(android.R.string.ok) { materialDialog -> materialDialog.dismiss() }
.cancelable(true)
.cancelOnTouchOutside(true)
@@ -1,7 +1,9 @@
package exh.ui.batchadd
import android.content.Context
import com.jakewharton.rxrelay.BehaviorRelay
import com.jakewharton.rxrelay.ReplayRelay
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter
import exh.GalleryAddEvent
@@ -20,7 +22,7 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
var eventRelay: ReplayRelay<String>? = null
val currentlyAddingRelay = BehaviorRelay.create(STATE_IDLE)!!
fun addGalleries(galleries: String) {
fun addGalleries(context: Context, galleries: String) {
eventRelay = ReplayRelay.create()
val regex =
"""[0-9]*?\.[a-z0-9]*?:""".toRegex()
@@ -53,7 +55,7 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
val failed = mutableListOf<String>()
splitGalleries.forEachIndexed { i, s ->
val result = galleryAdder.addGallery(s, true)
val result = galleryAdder.addGallery(context, s, true)
if (result is GalleryAddEvent.Success) {
succeeded.add(s)
} else {
@@ -63,15 +65,15 @@ class BatchAddPresenter : BasePresenter<BatchAddController>() {
eventRelay?.call(
(
when (result) {
is GalleryAddEvent.Success -> "[OK]"
is GalleryAddEvent.Fail -> "[ERROR]"
is GalleryAddEvent.Success -> context.getString(R.string.batch_add_ok)
is GalleryAddEvent.Fail -> context.getString(R.string.batch_add_error)
}
) + " " + result.logMessage
)
}
// Show report
val summary = "\nSummary:\nAdded: ${succeeded.size} gallerie(s)\nFailed: ${failed.size} gallerie(s)"
val summary = context.getString(R.string.batch_add_summary, succeeded.size, failed.size)
eventRelay?.call(summary)
}
}
@@ -15,6 +15,7 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.string
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.asObservableSuccess
@@ -180,8 +181,8 @@ class BrowserActionActivity : AppCompatActivity() {
runOnUiThread {
webview.evaluateJavascript(SOLVE_UI_SCRIPT_HIDE, null)
MaterialDialog(this)
.title(text = "Captcha solve failure")
.message(text = "Failed to auto-solve the captcha!")
.title(R.string.captcha_solve_failure)
.message(R.string.captcha_solve_failure_message)
.cancelable(true)
.cancelOnTouchOutside(true)
.positiveButton(android.R.string.ok)
@@ -61,7 +61,7 @@ class InterceptActivity : BaseActivity<EhActivityInterceptBinding>() {
when (it) {
is InterceptResult.Success -> {
binding.interceptProgress.gone()
binding.interceptStatus.text = "Launching app..."
binding.interceptStatus.setText(R.string.launching_app)
onBackPressed()
startActivity(
Intent(this, MainActivity::class.java)
@@ -72,10 +72,10 @@ class InterceptActivity : BaseActivity<EhActivityInterceptBinding>() {
}
is InterceptResult.Failure -> {
binding.interceptProgress.gone()
binding.interceptStatus.text = "Error: ${it.reason}"
binding.interceptStatus.text = this.getString(R.string.error_with_reason, it.reason)
MaterialDialog(this)
.title(text = "Error")
.message(text = "Could not open this gallery:\n\n${it.reason}")
.title(R.string.chapter_error)
.message(text = this.getString(R.string.could_not_open_gallery, it.reason))
.cancelable(true)
.cancelOnTouchOutside(true)
.positiveButton(android.R.string.ok)
@@ -104,13 +104,13 @@ class InterceptActivity : BaseActivity<EhActivityInterceptBinding>() {
// Load gallery async
thread {
val result = galleryAdder.addGallery(gallery)
val result = galleryAdder.addGallery(this, gallery)
status.onNext(
when (result) {
is GalleryAddEvent.Success -> result.manga.id?.let {
InterceptResult.Success(it)
} ?: InterceptResult.Failure("Manga ID is null!")
} ?: InterceptResult.Failure(this.getString(R.string.manga_id_is_null))
is GalleryAddEvent.Fail -> InterceptResult.Failure(result.logMessage)
}
)
+3 -2
View File
@@ -1,5 +1,6 @@
package exh.util
import android.content.Context
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.online.UrlImportableSource
import exh.GalleryAddEvent
@@ -13,11 +14,11 @@ private val galleryAdder by lazy {
/**
* A version of fetchSearchManga that supports URL importing
*/
fun UrlImportableSource.urlImportFetchSearchManga(query: String, fail: () -> Observable<MangasPage>) =
fun UrlImportableSource.urlImportFetchSearchManga(context: Context, query: String, fail: () -> Observable<MangasPage>) =
when {
query.startsWith("http://") || query.startsWith("https://") -> {
Observable.fromCallable {
val res = galleryAdder.addGallery(query, false, this)
val res = galleryAdder.addGallery(context, query, false, this)
MangasPage(
(
if (res is GalleryAddEvent.Success) {