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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user