From ff999a6dda4468f4fc74e978b0d2ced1bc46f36a Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 10:11:30 -0500 Subject: [PATCH 01/24] Show selected preference for "Library update order" --- .../ui/setting/SettingsLibraryController.kt | 35 ++++++++++++------- app/src/main/res/values/strings.xml | 1 - 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt index eb63229387..59b170e60a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsLibraryController.kt @@ -114,33 +114,42 @@ class SettingsLibraryController : SettingsController() { selectedCategories.joinToString { it.name } } } - intListPreference{ + intListPreference { key = Keys.libraryUpdatePrioritization titleRes = R.string.pref_library_update_prioritization - // The following arrays are to be lined up with the list rankingScheme in: + + // The following array lines up with the list rankingScheme in: // ../../data/library/LibraryUpdateRanker.kt - entriesRes = arrayOf( - R.string.action_sort_alpha, - R.string.action_sort_last_updated + val priorities = arrayOf( + Pair("0", R.string.action_sort_alpha), + Pair("1", R.string.action_sort_last_updated) ) - entryValues = arrayOf( - "0", - "1" - ) - defaultValue = "0" - summaryRes = R.string.pref_library_update_prioritization_summary + val defaultPriority = priorities[0] + + entriesRes = priorities.map { it.second }.toTypedArray() + entryValues = priorities.map { it.first }.toTypedArray() + defaultValue = defaultPriority.first + + val selectedPriority = priorities.find { it.first.toInt() == preferences.libraryUpdatePrioritization().getOrDefault() } + summaryRes = selectedPriority?.second ?: defaultPriority.second + onChange { newValue -> + summaryRes = priorities.find { + it.first == (newValue as String) + }?.second ?: defaultPriority.second + true + } } intListPreference { key = Keys.defaultCategory titleRes = R.string.default_category - val selectedCategory = categories.find { it.id == preferences.defaultCategory() } entries = arrayOf(context.getString(R.string.default_category_summary)) + categories.map { it.name }.toTypedArray() entryValues = arrayOf("-1") + categories.map { it.id.toString() }.toTypedArray() defaultValue = "-1" - summary = selectedCategory?.name ?: context.getString(R.string.default_category_summary) + val selectedCategory = categories.find { it.id == preferences.defaultCategory() } + summary = selectedCategory?.name ?: context.getString(R.string.default_category_summary) onChange { newValue -> summary = categories.find { it.id == (newValue as String).toInt() diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fba4d407fa..fd046af0a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -147,7 +147,6 @@ Categories to include in global update All Library update order - Select the order in which Tachiyomi checks for update Library update restrictions Update only when the conditions are met Wi-Fi From 012b1b56aa843af5d58e00404c8b70197fc779dd Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 10:11:39 -0500 Subject: [PATCH 02/24] Minor grammar fixes --- .../eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt | 2 +- .../eu/kanade/tachiyomi/data/updater/github/GithubService.kt | 2 +- .../eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt | 2 +- app/src/main/res/values/strings.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt index f65bf39ba6..4e4d7feca2 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubRelease.kt @@ -5,7 +5,7 @@ import eu.kanade.tachiyomi.data.updater.Release /** * Release object. - * Contains information about the latest release from Github. + * Contains information about the latest release from GitHub. * * @param version version of latest release. * @param info log of latest release. diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt index e19e3528d5..b2ccaff3f4 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/updater/github/GithubService.kt @@ -10,7 +10,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get /** - * Used to connect with the Github API. + * Used to connect with the GitHub API. */ interface GithubService { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt index 2331dfea51..863c5794c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAboutController.kt @@ -79,7 +79,7 @@ class SettingsAboutController : SettingsController() { } } preference { - title = "Github" + title = "GitHub" val url = "https://github.com/inorichi/tachiyomi" summary = url onClick { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fd046af0a9..7318d62f8e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -273,7 +273,7 @@ Restore completed Could not open log Restore took %1$s.\n%2$s errors found. - Restore uses source to fetch data, carrier costs may apply.\n\nMake sure you have installed all necessary extensions and are logged in to sources and tracking services before restoring. + Restore uses sources to fetch data, carrier costs may apply.\n\nMake sure you have installed all necessary extensions and are logged in to sources and tracking services before restoring. File saved at %1$s What do you want to backup? Restoring backup From cd90702fe5bf6069867c0825bd5b18ca565cd0c1 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 10:41:16 -0500 Subject: [PATCH 03/24] Fix splash screen status bar color --- app/src/main/res/drawable/splash_background.xml | 2 +- app/src/main/res/values/colors.xml | 2 ++ app/src/main/res/values/themes.xml | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/drawable/splash_background.xml b/app/src/main/res/drawable/splash_background.xml index 8572bd2460..b8286740c5 100644 --- a/app/src/main/res/drawable/splash_background.xml +++ b/app/src/main/res/drawable/splash_background.xml @@ -1,7 +1,7 @@ - + #1C1C1D @color/md_black_1000 + @color/colorPrimary + @color/md_blue_A400 @color/md_black_1000_87 diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 4f2f48b969..135af42819 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -158,7 +158,8 @@ From 262ad45b792dc2480fdabeb2854c708e35dc28a6 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 11 Jan 2020 02:11:06 -0800 Subject: [PATCH 04/24] Update BackupTest.kt (cherry picked from commit 00b1b097a7ae744f69f47436f4d764ce8cf4b111) --- app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt index 481ae4fe76..ddf5f7e05f 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt +++ b/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt @@ -389,7 +389,6 @@ class BackupTest { val track = TrackImpl() track.title = manga.title track.manga_id = manga.id!! - track.remote_id = 1 track.sync_id = 1 return track } From 62d3fc65e0a73645439a9632838197a58c2a9f8c Mon Sep 17 00:00:00 2001 From: MCAxiaz Date: Sat, 11 Jan 2020 12:06:54 -0800 Subject: [PATCH 05/24] Filter Extensions By Language (#2275) * add options menu item to filer extensions by languages * resolve merge conflicts changes per pr comments Co-authored-by: arkon --- .../data/preference/PreferencesHelper.kt | 3 +- .../ui/extension/ExtensionController.kt | 25 +++++++++ .../ui/extension/ExtensionPresenter.kt | 11 ++-- .../extension/SettingsExtensionsController.kt | 52 +++++++++++++++++++ app/src/main/res/menu/extension_main.xml | 6 +++ app/src/main/res/values/strings.xml | 1 + 6 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 68e6371ee7..c988225817 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt @@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.source.Source import java.io.File +import java.util.Locale import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys fun Preference.getOrDefault(): T = get() ?: defaultValue()!! @@ -95,7 +96,7 @@ class PreferencesHelper(val context: Context) { fun catalogueAsList() = rxPrefs.getBoolean(Keys.catalogueAsList, false) - fun enabledLanguages() = rxPrefs.getStringSet(Keys.enabledLanguages, setOf("en")) + fun enabledLanguages() = rxPrefs.getStringSet(Keys.enabledLanguages, setOf("en", Locale.getDefault().language)) fun sourceUsername(source: Source) = prefs.getString(Keys.sourceUsername(source.id), "") diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt index 823cd77873..33a9085ab5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt @@ -5,8 +5,13 @@ import androidx.appcompat.widget.SearchView import android.view.LayoutInflater import android.view.Menu import android.view.MenuInflater +import android.view.MenuItem import android.view.View import android.view.ViewGroup +import com.bluelinelabs.conductor.ControllerChangeHandler +import com.bluelinelabs.conductor.ControllerChangeType +import com.bluelinelabs.conductor.RouterTransaction +import com.bluelinelabs.conductor.changehandler.FadeChangeHandler import com.jakewharton.rxbinding.support.v4.widget.refreshes import com.jakewharton.rxbinding.support.v7.widget.queryTextChanges import eu.davidea.flexibleadapter.FlexibleAdapter @@ -73,6 +78,25 @@ open class ExtensionController : NucleusController(), super.onDestroyView(view) } + override fun onOptionsItemSelected(item: MenuItem): Boolean { + when (item.itemId) { + R.id.action_settings -> { + router.pushController((RouterTransaction.with(SettingsExtensionsController())) + .popChangeHandler(SettingsExtensionsFadeChangeHandler()) + .pushChangeHandler(FadeChangeHandler())) + } + else -> return super.onOptionsItemSelected(item) + } + return true + } + + override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { + super.onChangeStarted(handler, type) + if (!type.isPush && handler is SettingsExtensionsFadeChangeHandler) { + presenter.findAvailableExtensions() + } + } + override fun onButtonClick(position: Int) { val extension = (adapter?.getItem(position) as? ExtensionItem)?.extension ?: return when (extension) { @@ -173,4 +197,5 @@ open class ExtensionController : NucleusController(), presenter.uninstallExtension(pkgName) } + class SettingsExtensionsFadeChangeHandler : FadeChangeHandler() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt index 04ff5f3ce7..fda29d66e8 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt @@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.ui.extension import android.app.Application import android.os.Bundle import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.InstallStep @@ -22,7 +24,8 @@ private typealias ExtensionTuple * Presenter of [ExtensionController]. */ open class ExtensionPresenter( - private val extensionManager: ExtensionManager = Injekt.get() + private val extensionManager: ExtensionManager = Injekt.get(), + private val preferences: PreferencesHelper = Injekt.get() ) : BasePresenter() { private var extensions = emptyList() @@ -53,6 +56,7 @@ open class ExtensionPresenter( @Synchronized private fun toItems(tuple: ExtensionTuple): List { val context = Injekt.get() + val activeLangs = preferences.enabledLanguages().getOrDefault() val (installed, untrusted, available) = tuple @@ -61,9 +65,10 @@ open class ExtensionPresenter( val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { it.pkgName })) val untrustedSorted = untrusted.sortedBy { it.pkgName } val availableSorted = available - // Filter out already installed extensions + // Filter out already installed extensions and disabled languages .filter { avail -> installed.none { it.pkgName == avail.pkgName } - && untrusted.none { it.pkgName == avail.pkgName } } + && untrusted.none { it.pkgName == avail.pkgName } + && (avail.lang in activeLangs || avail.lang == "all")} .sortedBy { it.pkgName } if (installedSorted.isNotEmpty() || untrustedSorted.isNotEmpty()) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt new file mode 100644 index 0000000000..df9817dc06 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt @@ -0,0 +1,52 @@ +package eu.kanade.tachiyomi.ui.extension + +import android.support.v7.preference.PreferenceScreen +import android.support.v7.preference.SwitchPreference +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.data.preference.getOrDefault +import eu.kanade.tachiyomi.extension.ExtensionManager +import eu.kanade.tachiyomi.ui.setting.SettingsController +import eu.kanade.tachiyomi.ui.setting.onChange +import eu.kanade.tachiyomi.ui.setting.titleRes +import eu.kanade.tachiyomi.util.LocaleHelper +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +class SettingsExtensionsController: SettingsController() { + + override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) { + titleRes = R.string.ext_settings + + val activeLangs = preferences.enabledLanguages().getOrDefault() + + val availableLangs = + Injekt.get().availableExtensions.groupBy { + it.lang + }.keys.minus("all").partition { + it in activeLangs + }.let { + it.first + it.second + } + + availableLangs.forEach { + SwitchPreference(context).apply { + preferenceScreen.addPreference(this) + title = LocaleHelper.getDisplayName(it, context) + isPersistent = false + isChecked = it in activeLangs + + onChange { newValue -> + val checked = newValue as Boolean + val currentActiveLangs = preferences.enabledLanguages().getOrDefault() + + if (checked) { + preferences.enabledLanguages().set(currentActiveLangs + it) + } else { + preferences.enabledLanguages().set(currentActiveLangs - it) + } + true + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/menu/extension_main.xml b/app/src/main/res/menu/extension_main.xml index 994ae2fbc2..2d88c505fc 100644 --- a/app/src/main/res/menu/extension_main.xml +++ b/app/src/main/res/menu/extension_main.xml @@ -8,4 +8,10 @@ app:showAsAction="collapseActionView|ifRoom" app:actionViewClass="androidx.appcompat.widget.SearchView"/> + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7318d62f8e..9065a407dd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -176,6 +176,7 @@ Version: %1$s Language: %1$s No preferences to edit for this extension + Settings Fullscreen From e414b9edf18bc16d63beaed6dc483c07cb44d166 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 15:13:51 -0500 Subject: [PATCH 06/24] Minor extension filter cleanup --- .../tachiyomi/ui/extension/ExtensionController.kt | 2 +- ...onsController.kt => ExtensionFilterController.kt} | 10 +++++----- app/src/main/res/menu/extension_main.xml | 12 ++++++------ app/src/main/res/values/strings.xml | 1 - 4 files changed, 12 insertions(+), 13 deletions(-) rename app/src/main/java/eu/kanade/tachiyomi/ui/extension/{SettingsExtensionsController.kt => ExtensionFilterController.kt} (89%) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt index 33a9085ab5..ff83e48efa 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionController.kt @@ -81,7 +81,7 @@ open class ExtensionController : NucleusController(), override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.action_settings -> { - router.pushController((RouterTransaction.with(SettingsExtensionsController())) + router.pushController((RouterTransaction.with(ExtensionFilterController())) .popChangeHandler(SettingsExtensionsFadeChangeHandler()) .pushChangeHandler(FadeChangeHandler())) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt similarity index 89% rename from app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt rename to app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt index df9817dc06..7c2be136f3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/SettingsExtensionsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionFilterController.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.ui.extension -import android.support.v7.preference.PreferenceScreen -import android.support.v7.preference.SwitchPreference +import androidx.preference.PreferenceScreen +import androidx.preference.SwitchPreference import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.extension.ExtensionManager @@ -12,10 +12,10 @@ import eu.kanade.tachiyomi.util.LocaleHelper import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -class SettingsExtensionsController: SettingsController() { +class ExtensionFilterController: SettingsController() { override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) { - titleRes = R.string.ext_settings + titleRes = R.string.action_filter val activeLangs = preferences.enabledLanguages().getOrDefault() @@ -49,4 +49,4 @@ class SettingsExtensionsController: SettingsController() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/res/menu/extension_main.xml b/app/src/main/res/menu/extension_main.xml index 2d88c505fc..520be80b3a 100644 --- a/app/src/main/res/menu/extension_main.xml +++ b/app/src/main/res/menu/extension_main.xml @@ -3,15 +3,15 @@ + android:title="@string/action_search" + app:actionViewClass="androidx.appcompat.widget.SearchView" + app:showAsAction="collapseActionView|ifRoom" /> + android:icon="@drawable/ic_filter_list_white_24dp" + android:title="@string/action_filter" + app:showAsAction="ifRoom" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9065a407dd..7318d62f8e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -176,7 +176,6 @@ Version: %1$s Language: %1$s No preferences to edit for this extension - Settings Fullscreen From 2d3bfa9a89e08bb7318a39ba73620ae2820d6181 Mon Sep 17 00:00:00 2001 From: Jay Date: Thu, 5 Dec 2019 21:50:36 -0800 Subject: [PATCH 07/24] Implement long hold selection for Manga Chapters and library Co-Authored-By: zhuoyang Co-Authored-By: Jays2Kings --- .../ui/library/LibraryCategoryView.kt | 38 ++++++++++++++++--- .../ui/manga/chapter/ChaptersController.kt | 32 ++++++++++++++-- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt index d0208027c4..5293d8c18d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryCategoryView.kt @@ -1,11 +1,11 @@ package eu.kanade.tachiyomi.ui.library import android.content.Context -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView import android.util.AttributeSet import android.view.View import android.widget.FrameLayout +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.SelectableAdapter import eu.kanade.tachiyomi.R @@ -18,8 +18,8 @@ import eu.kanade.tachiyomi.util.inflate import eu.kanade.tachiyomi.util.plusAssign import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.widget.AutofitRecyclerView -import kotlinx.android.synthetic.main.chapters_controller.fast_scroller -import kotlinx.android.synthetic.main.library_category.view.* +import kotlinx.android.synthetic.main.library_category.view.fast_scroller +import kotlinx.android.synthetic.main.library_category.view.swipe_refresh import rx.subscriptions.CompositeSubscription import uy.kohesive.injekt.injectLazy @@ -62,6 +62,8 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att */ private var subscriptions = CompositeSubscription() + private var lastClickPosition = -1 + fun onCreate(controller: LibraryController) { this.controller = controller @@ -174,6 +176,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att } is LibrarySelectionEvent.Unselected -> { findAndToggleSelection(event.manga) + if (adapter.indexOf(event.manga) != -1) lastClickPosition = -1 if (controller.selectedMangas.isEmpty()) { adapter.mode = SelectableAdapter.Mode.SINGLE } @@ -181,6 +184,7 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att is LibrarySelectionEvent.Cleared -> { adapter.mode = SelectableAdapter.Mode.SINGLE adapter.clearSelection() + lastClickPosition = -1 } } } @@ -204,10 +208,11 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att * @param position the position of the element clicked. * @return true if the item should be selected, false otherwise. */ - override fun onItemClick(view: View, position: Int): Boolean { + override fun onItemClick(view: View?, position: Int): Boolean { // If the action mode is created and the position is valid, toggle the selection. val item = adapter.getItem(position) ?: return false if (adapter.mode == SelectableAdapter.Mode.MULTI) { + lastClickPosition = position toggleSelection(position) return true } else { @@ -223,7 +228,15 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att */ override fun onItemLongClick(position: Int) { controller.createActionModeIfNeeded() - toggleSelection(position) + when { + lastClickPosition == -1 -> setSelection(position) + lastClickPosition > position -> for (i in position until lastClickPosition) + setSelection(i) + lastClickPosition < position -> for (i in lastClickPosition + 1..position) + setSelection(i) + else -> setSelection(position) + } + lastClickPosition = position } /** @@ -247,4 +260,17 @@ class LibraryCategoryView @JvmOverloads constructor(context: Context, attrs: Att controller.invalidateActionMode() } + + /** + * Tells the presenter to set the selection for the given position. + * + * @param position the position to toggle. + */ + private fun setSelection(position: Int) { + val item = adapter.getItem(position) ?: return + + controller.setSelection(item.manga, true) + controller.invalidateActionMode() + } + } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt index a6fe7cddfd..d7c57826a7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/chapter/ChaptersController.kt @@ -55,6 +55,8 @@ class ChaptersController : NucleusController(), */ private val selectedItems = mutableSetOf() + private var lastClickPosition = -1 + init { setHasOptionsMenu(true) setOptionsMenuHidden(true) @@ -184,8 +186,9 @@ class ChaptersController : NucleusController(), fun onNextChapters(chapters: List) { // If the list is empty, fetch chapters from source if the conditions are met // We use presenter chapters instead because they are always unfiltered - if (presenter.chapters.isEmpty()) + if (presenter.chapters.isEmpty()) { initialFetchChapters() + } val adapter = adapter ?: return adapter.updateDataSet(chapters) @@ -242,10 +245,11 @@ class ChaptersController : NucleusController(), startActivity(intent) } - override fun onItemClick(view: View, position: Int): Boolean { + override fun onItemClick(view: View?, position: Int): Boolean { val adapter = adapter ?: return false val item = adapter.getItem(position) ?: return false if (actionMode != null && adapter.mode == SelectableAdapter.Mode.MULTI) { + lastClickPosition = position toggleSelection(position) return true } else { @@ -256,7 +260,16 @@ class ChaptersController : NucleusController(), override fun onItemLongClick(position: Int) { createActionModeIfNeeded() - toggleSelection(position) + when { + lastClickPosition == -1 -> setSelection(position) + lastClickPosition > position -> for (i in position until lastClickPosition) + setSelection(i) + lastClickPosition < position -> for (i in lastClickPosition + 1..position) + setSelection(i) + else -> setSelection(position) + } + lastClickPosition = position + adapter?.notifyDataSetChanged() } // SELECTIONS & ACTION MODE @@ -265,6 +278,7 @@ class ChaptersController : NucleusController(), val adapter = adapter ?: return val item = adapter.getItem(position) ?: return adapter.toggleSelection(position) + adapter.notifyDataSetChanged() if (adapter.isSelected(position)) { selectedItems.add(item) } else { @@ -273,6 +287,16 @@ class ChaptersController : NucleusController(), actionMode?.invalidate() } + private fun setSelection(position: Int) { + val adapter = adapter ?: return + val item = adapter.getItem(position) ?: return + if (!adapter.isSelected(position)) { + adapter.toggleSelection(position) + selectedItems.add(item) + actionMode?.invalidate() + } + } + private fun getSelectedChapters(): List { val adapter = adapter ?: return emptyList() return adapter.selectedPositions.mapNotNull { adapter.getItem(it) } @@ -285,6 +309,7 @@ class ChaptersController : NucleusController(), } private fun destroyActionModeIfNeeded() { + lastClickPosition = -1 actionMode?.finish() } @@ -373,7 +398,6 @@ class ChaptersController : NucleusController(), } } - private fun showDeleteChaptersConfirmationDialog() { DeleteChaptersDialog(this).showDialog(router) } From 1b37c61b5a21043ab2bdcab3ed7fe83eb42a387c Mon Sep 17 00:00:00 2001 From: Chris Allan Date: Sat, 11 Jan 2020 12:59:43 -0800 Subject: [PATCH 08/24] JSON metadata for local manga (#1658) * JSON metadata for local manga * Simplification * Lazy load local data --- .../eu/kanade/tachiyomi/source/LocalSource.kt | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt index 1630e723d7..b02c79ae1e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/LocalSource.kt @@ -1,6 +1,8 @@ package eu.kanade.tachiyomi.source import android.content.Context +import com.google.gson.Gson +import com.google.gson.JsonObject import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.FilterList @@ -21,6 +23,7 @@ import java.io.File import java.io.FileInputStream import java.io.InputStream import java.util.Locale +import java.util.Scanner import java.util.concurrent.TimeUnit import java.util.zip.ZipEntry import java.util.zip.ZipFile @@ -117,8 +120,6 @@ class LocalSource(private val context: Context) : CatalogueSource { } } } - - initialized = true } } return Observable.just(MangasPage(mangas, false)) @@ -126,7 +127,26 @@ class LocalSource(private val context: Context) : CatalogueSource { override fun fetchLatestUpdates(page: Int) = fetchSearchManga(page, "", LATEST_FILTERS) - override fun fetchMangaDetails(manga: SManga) = Observable.just(manga) + override fun fetchMangaDetails(manga: SManga): Observable { + getBaseDirectories(context) + .mapNotNull { File(it, manga.url).listFiles()?.toList() } + .flatten() + .filter { it.extension.equals("json") } + .firstOrNull() + ?.apply { + val json = Gson().fromJson(Scanner(this).useDelimiter("\\Z").next(), JsonObject::class.java) + manga.title = json["title"]?.asString ?: manga.title + manga.author = json["author"]?.asString ?: manga.author + manga.artist = json["artist"]?.asString ?: manga.artist + manga.description = json["description"]?.asString ?: manga.description + manga.genre = json["genre"]?.asJsonArray + ?.map { it.asString } + ?.joinToString(", ") + ?: manga.genre + manga.status = json["status"]?.asInt ?: manga.status + } + return Observable.just(manga) + } override fun fetchChapterList(manga: SManga): Observable> { val chapters = getBaseDirectories(context) From e11c28915029d7139d45f5d4ea3ce7317e3ca69d Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 16:06:16 -0500 Subject: [PATCH 09/24] Renormalize files --- gradle/wrapper/gradle-wrapper.jar | Bin 49896 -> 49895 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 8c0fb64a8698b08ecc4158d828ca593c4928e9dd..7b43c0845fa7fbe240850375ebed5e844f3f5948 100644 GIT binary patch delta 14 VcmaFS%KW^QdBXvx%?F*-8vr*z2JZj> delta 16 XcmaFf%KW00dBXuGM&8W_oYWftK(Yq> From f9225981270b8f3910e4433298681377fcea620e Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 16:12:12 -0500 Subject: [PATCH 10/24] Revert "Renormalize files" This reverts commit e11c28915029d7139d45f5d4ea3ce7317e3ca69d. --- gradle/wrapper/gradle-wrapper.jar | Bin 49895 -> 49896 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7b43c0845fa7fbe240850375ebed5e844f3f5948..8c0fb64a8698b08ecc4158d828ca593c4928e9dd 100644 GIT binary patch delta 16 XcmaFf%KW00dBXuGM&8W_oYWftK(Yq> delta 14 VcmaFS%KW^QdBXvx%?F*-8vr*z2JZj> From a61e3cd68928bed5ae748a591042660e41623d3d Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 16:13:08 -0500 Subject: [PATCH 11/24] Mark JAR as binary too --- .gitattributes | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.gitattributes b/.gitattributes index 7b9779ee53..1ca443da48 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,18 +4,16 @@ # Windows forced line-endings /.idea/* text eol=crlf +# Gradle wrapper +*.jar binary + +# Images *.webp binary *.png binary *.jpg binary *.jpeg binary *.gif binary *.ico binary -*.mov binary -*.mp4 binary -*.mp3 binary -*.flv binary -*.fla binary -*.swf binary *.gz binary *.zip binary *.7z binary @@ -23,7 +21,4 @@ *.eot binary *.woff binary *.pyc binary -*.pdf binary -*.ez binary -*.bz2 binary *.swp binary From 32b7cc68b92c0afd3fe2714973ecc62ae5247b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jozef=20Holl=C3=BD?= Date: Sat, 11 Jan 2020 22:39:27 +0100 Subject: [PATCH 12/24] Translations (Continuous) (#2484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update translation files Updated by "Cleanup translation files" hook in Weblate. Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ * Translated using Weblate (Catalan) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/ * Translated using Weblate (Malay) Currently translated at 99.5% (437 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/ * Translated using Weblate (Chinese (Simplified)) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hans/ * Translated using Weblate (Romanian) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ro/ * Translated using Weblate (Japanese) Currently translated at 44.2% (194 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ja/ * Translated using Weblate (Hindi) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/ * Translated using Weblate (Arabic) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ar/ * Translated using Weblate (French) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/ * Translated using Weblate (Thai) Currently translated at 22.1% (97 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/ * Translated using Weblate (German) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/ * Translated using Weblate (Chinese (Traditional)) Currently translated at 89.1% (391 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/ * Translated using Weblate (Spanish) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/ * Translated using Weblate (Sardinian) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 98.6% (433 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/ * Translated using Weblate (Bengali) Currently translated at 100.0% (439 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/bn/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 99.8% (438 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/ * Translated using Weblate (Hungarian) Currently translated at 41.7% (183 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hu/ * Translated using Weblate (Chinese (Traditional)) Currently translated at 98.6% (433 of 439 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/zh_Hant/ * Added translation using Weblate (Slovak) * Translated using Weblate (Hindi) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/hi/ * Translated using Weblate (Slovak) Currently translated at 34.9% (155 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sk/ * Translated using Weblate (Slovak) Currently translated at 36.3% (161 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sk/ * Translated using Weblate (Polish) Currently translated at 99.3% (441 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/pl/ * Translated using Weblate (Finnish) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fi/ * Translated using Weblate (Slovak) Currently translated at 54.5% (242 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sk/ * Translated using Weblate (Catalan) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ca/ * Translated using Weblate (Dutch) Currently translated at 98.6% (438 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nl/ * Translated using Weblate (Sardinian) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/sc/ * Translated using Weblate (German) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/de/ * Translated using Weblate (Italian) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/it/ * Translated using Weblate (Spanish) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/ * Translated using Weblate (French) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/ * Translated using Weblate (French) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/fr/ * Translated using Weblate (Turkish) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/tr/ * Translated using Weblate (Vietnamese) Currently translated at 98.6% (438 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/vi/ * Translated using Weblate (Indonesian) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/id/ * Translated using Weblate (Spanish) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/es/ * Translated using Weblate (Malay) Currently translated at 99.5% (442 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/ms/ * Translated using Weblate (Thai) Currently translated at 78.8% (350 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/ * Translated using Weblate (Thai) Currently translated at 100.0% (444 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/th/ * Translated using Weblate (Norwegian Bokmål) Currently translated at 99.3% (441 of 444 strings) Translation: Tachiyomi/Strings Translate-URL: https://hosted.weblate.org/projects/tachiyomi/strings/nb_NO/ Co-authored-by: Weblate (bot) Co-authored-by: Eduard Ereza Martínez Co-authored-by: DarKCroX Co-authored-by: sr093906 Co-authored-by: f0roots <41129381+f0roots@users.noreply.github.com> Co-authored-by: Mark Acosta Co-authored-by: darkbeast13 <32981566+darkbeast13@users.noreply.github.com> Co-authored-by: petetae Co-authored-by: Lzmxya Co-authored-by: Credits125 <48494748+Credits125@users.noreply.github.com> Co-authored-by: asereze Co-authored-by: Allan Nordhøy Co-authored-by: Rezaul Rabbi Co-authored-by: Rolf Vidar Hoksaas <32819373+mazunki@users.noreply.github.com> Co-authored-by: Tóth Béla Co-authored-by: KaHsun <58354107+KaHsun@users.noreply.github.com> Co-authored-by: roguesoulboss Co-authored-by: Jendrej Co-authored-by: Topi Harjunpää Co-authored-by: mirfire <1897695+mirfire@users.noreply.github.com> Co-authored-by: Luigi Gandossi Co-authored-by: monolifed <6624464+monolifed@users.noreply.github.com> Co-authored-by: Le Cong Hau Co-authored-by: muhajaya <36522453+Muhajaya@users.noreply.github.com> Co-authored-by: Tanpahol --- app/src/main/res/values-ar/strings.xml | 10 +- app/src/main/res/values-bn/strings.xml | 6 +- app/src/main/res/values-ca/strings.xml | 10 +- app/src/main/res/values-de/strings.xml | 6 +- app/src/main/res/values-es/strings.xml | 6 +- app/src/main/res/values-fi/strings.xml | 10 +- app/src/main/res/values-fr/strings.xml | 30 +- app/src/main/res/values-hi/strings.xml | 8 +- app/src/main/res/values-hu/strings.xml | 18 +- app/src/main/res/values-in/strings.xml | 16 +- app/src/main/res/values-it/strings.xml | 4 + app/src/main/res/values-ja/strings.xml | 17 +- app/src/main/res/values-ms/strings.xml | 8 +- app/src/main/res/values-nb-rNO/strings.xml | 20 +- app/src/main/res/values-nl/strings.xml | 11 + app/src/main/res/values-pl/strings.xml | 2 + app/src/main/res/values-ro/strings.xml | 48 +-- app/src/main/res/values-sc/strings.xml | 6 +- app/src/main/res/values-sk/strings.xml | 251 ++++++++++++++ app/src/main/res/values-th/strings.xml | 360 ++++++++++++++++++++- app/src/main/res/values-tr/strings.xml | 4 + app/src/main/res/values-vi/strings.xml | 54 ++-- app/src/main/res/values-zh-rCN/strings.xml | 15 +- app/src/main/res/values-zh-rTW/strings.xml | 60 +++- 24 files changed, 863 insertions(+), 117 deletions(-) create mode 100644 app/src/main/res/values-sk/strings.xml diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 62a445a59c..07785ea26a 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -433,15 +433,19 @@ لا يوجدُ فصل سابق جار تحميل الصّفحات… فشل تحميل الصّفحات: %1$s - ضغطة طويلة - فتح في المتصفح + معلومات بضغطة مستمرة + فتح في web view الوان 32bit تخطي الفصول المقروءة أساسي - غطاء + غطاءالغطاء مضاعفة الشاشة المساعدة طلبات تحديث المكتبة إختر طريقة (Tachiyomi) لطلب التحديثات + "سحب لمزيد من الخيارات" + فلتر الألوان ”وضع الألوان الممزوجة“ + مراوغة / تفتيح + حرق / تغميق \ No newline at end of file diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index 14e86b5c54..0c25a3abb7 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -440,6 +440,10 @@ ডিফল্ট ওভারলে স্ক্রীন - ডজ/হালকা + এড়িয়ে / হালকা বার্ন/অন্ধকার + গুণ + সাহায্য + মাঙ্গা লাইব্রেরী আপডেটের প্রক্রিয়া + যে ক্রমে তাচিয়োমি হালনাগাদ করবে তা নির্বাচন করুন \ No newline at end of file diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index c14566d570..c72d88b606 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -20,7 +20,7 @@ Extensions Informació de l\'extensió Configuració - Filtre + Filtra Descarregats Marcats No llegits @@ -434,7 +434,7 @@ Descarregador Finestra de toc llarg Estireu cap amunt per a altres opcions - Visualitza en web + Obre en una visualització web Color de 32 bits Omet els capítols marcats com a llegits Mode de mescla del filtre de color @@ -446,5 +446,9 @@ Crema / Enfosqueix Ajuda Ordre d\'actualització de la biblioteca - Selecciona l\'ordre amb el qual Tachiyomi busca actualitzacions + Seleccioneu l\'ordre amb què el Tachiyomi comprova si hi ha actualitzacions + Endavant + Actualitza + No s\'ha trobat cap resultat + Seleccioneu un origen del qual vulgueu migrar \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 74b4fe94e1..58ef9306cb 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -13,7 +13,7 @@ Neueste Updates Kategorien Ausgewählt: %1$d - Backup + Sicherung Einstellungen Filter Heruntergeladen @@ -445,4 +445,8 @@ Hilfe Reihenfolge der Bibliotheksaktualisierung Bestimme die Reihenfolge in der Tachiyomi nach Updates sucht + Vorwärts + Aktualisierung + Keine Ergebnisse gefunden + Suche eine Quelle zum migrieren aus \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d48b5eea8d..ebb2cfbd21 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -103,7 +103,7 @@ Izquierda a derecha Derecha a izquierda Vertical - Webtoons + Webtoon Decodificador de imagen Tipo de escalado Ajustar a la pantalla @@ -476,4 +476,8 @@ También asegúrese de haber iniciado sesión en las fuentes que lo requieren an Ayuda Orden de actualización de la biblioteca Selecciona el orden en el que Tachiyomi buscará actualizaciones + Adelantar + Refrescar + No se han encontrado resultados + Selecciona una fuente para migrar \ No newline at end of file diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 4056982a4e..a16c8d9bdf 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -18,7 +18,7 @@ Seuranta Seuranta Luvut - Kirjasto päivitykset + Kirjastopäivitykset Katalokit Valittu: %1$d Lukuja yhteensä @@ -56,7 +56,7 @@ Ladataan sivuja… Sivujen lataus epäonnistui: %1$s Vedä ylös saadaksesi lisää asetuksia - "%1$s - Luku %2$s" + %1$s - Luku %2$s Kosketa valitaksesi lähde josta vaihdetaan Valitse sisällytettävä tieto Valitse @@ -85,7 +85,7 @@ Lataa päivitys Lataus kesken Lataus valmis - Lataus virhe + Latausvirhe Päivitys saatavilla Sarjan taustakuva Sarjan kansikuva @@ -447,4 +447,8 @@ Apu Kirjaston päivitys järjestys Valitse järjestys jossa päivitykset tarkistetaan + Seuraava + Päivitä + Ei tuloksia + Valitse lähde josta vaihdetaan \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index c4acaf8764..36ad70b5a9 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -342,7 +342,7 @@ Déplacer Exporter Créer - Raccourcis + Application indisponible Chaque semaine Chaque mois Thème AMOLED @@ -352,7 +352,7 @@ Ce manga a été ajouté à votre bibliothèque Dernier chapitre En pause - Ouvre le fichier journal + Ouvrir le fichier journal Restaurer Dossier de sauvegarde Service @@ -366,7 +366,7 @@ Pour %1$s chapitres Suivi Nombre de chapitres - Actualisations + Mises à jour Catégories à inclure dans le téléchargement Créer une sauvegarde Peut être utilisé pour restaurer la bibliothèque actuelle @@ -375,7 +375,7 @@ Fréquence de sauvegarde Nombre maximal de sauvegardes automatiques Restauration de sauvegarde en cours -%1$s ajouté à la bibliothèque +\n%1$s ajouté à la bibliothèque Restauration de sauvegarde en cours %1$s source introuvable Sauvegarde créée @@ -417,10 +417,10 @@ Assurez-vous que vous êtes connecté à des sources qui le demande avant de com Préférences Disponible Extension non reconnue - Cette extension a été signé avec un certificat non reconnu et n\'a pas été activée. -\n -\nUne extension malveillante peut lire les certificats de connections sauvegardés sur Tachiyomi ou exécuter du code arbitraire. -\n + Cette extension a été signé avec un certificat non reconnu et n\'a pas été activée. +\n +\nUne extension malveillante peut lire les identifiants de connexion sauvegardés sur Tachiyomi ou exécuter du code arbitraire. +\n \nEn faisant confiance à ce certificat vous acceptez ces risques. Version : %1$s Langue : %1$s @@ -474,9 +474,15 @@ Assurez-vous que vous êtes connecté à des sources qui le demande avant de com Par défaut Multiplier Écran - Mode de mélange des filtres de couleur - Couche + Mode de filtrage via couleurs mélangées + Interface Aide - Ordre de mise à jour de la librairie - Sélectionnez l\'ordre auquel Tachiyomi doit vérifier les mises à jour + Ordre de mise à jour de la bibliothèque + Sélectionnez l\'ordre dans lequel Tachiyomi doit vérifier si des mises à jour sont disponibles + Densité/Éclaircir + Brûlé / Assombri + Suivant + Actualiser + Aucun résultats trouvés + Sélectionner une source depuis laquelle migrer \ No newline at end of file diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 1465306024..cdcd145f5a 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -145,7 +145,7 @@ बाएं से दाएं दाएं से बाएं शीर्ष से असंतत - शीर्ष से निरंतर + वेबटून छवि कूटवाचक मापन प्ररूप उपयुक्त स्क्रीन @@ -367,7 +367,7 @@ एक पृष्ठ लोड नहीं हुआ है कोई वाई-फ़ाई कनेक्शन उपलब्ध नहीं है कोई नेटवर्क कनेक्शन उपलब्ध नहीं है - डाउनलोड रोक दिया गया + डाउनलोड रोक दिया है सामान्य पुस्तकालय डाउनलोडर @@ -445,4 +445,8 @@ मदद लाइब्रेरी अद्यतन क्रम उस क्रम का चयन करें जिसमें टचियोमी अद्यतन की जांच करे + आगे + पुनश्चर्या + कोई परिणाम नहीं मिला + से माइग्रेट करने के लिए एक स्रोत का चयन करें \ No newline at end of file diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 0d2823aa92..faab456b99 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -100,9 +100,9 @@ %1$d kiválasztva Szűrők Letöltve - Könyvjelzőzött + Könyvjelzőzve Olvasatlan - Aktuális + Olvasott Szűrők eltávolítása Betűrendben Összes fejezet @@ -169,7 +169,19 @@ Bővítmények Nem megbízható Eltávolítás - Beállítások + Preferenciák Sötétkék Összes + Bővítmény információ + Részletek + Frissítés + Telepítés + Függőben + Letöltés + Telepítés + Telepítve + Elérhető + Webnézet + Segítség + Könyvtár frissítési sorrend \ No newline at end of file diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 23bcb0a103..6664231aa8 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -317,7 +317,7 @@ Gambar tidak bisa diterjemahkan Perbaharui bab terakhir baca di layanan yang diaktifkan ke %1$d? Apakah anda ingin menggunakan gambar ini sebagai sampul\? - Pembaca untuk seri ini + Jumlah pembaca untuk seri ini %1$s - Ch.%2$s Terjadi kesalahan saat mengunduh bab. Anda bisa mencoba lagi di halaman sedang diunduh Proses pembaruan sedang berlangsung: %1$d/%2$d @@ -435,14 +435,18 @@ Lewati bab yang sudah dibaca Tarik ke atas untuk opsi lainnya Dialog ketuk dan tahan - Mode filter warna campuran - Bawaan - Hamparan + Mode saringan warna campur + Standar + Lapisan Gandakan Layar - Terangkan - Gelapkan + Dodge / Cerahkan + Burn / Gelapkan Bantuan Urutan perbarui perpustakaan Pilih urutan perpustakaan yang akan Tachiyomi perbarui terlebih dahulu + Teruskan + Muat ulang + Hasil tidak ditemukan + Pilih sumber untuk migrasi dari \ No newline at end of file diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 8b8f395ebd..72c9fcd54f 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -480,4 +480,8 @@ Aiuto Ordine di aggiornamento della libreria Seleziona l\'ordine in cui vuoi che Tachiyomi controlli gli aggiornamenti + Avanti + Ricarica + Nessun risultato trovato + Seleziona una sorgente da cui migrare \ No newline at end of file diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index ce02b5613b..50f64f2a6f 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -1,10 +1,10 @@ - + + カテゴリ 漫画 履歴 - 設定 ダウンロードキュー ライブラリ @@ -15,8 +15,6 @@ カテゴリ 選択: %1$d バックアップ - - 設定 フィルター ダウンロードした @@ -209,4 +207,15 @@ パスワードを表示 ログイン ログイン成功 + 追加 + カテゴリー名を変更 + カテゴリーに移動 + 昇順に並べ替え + 降順に並べ替え + ダウンロード終了 + 停止 + 削除 + インストール + 取り消し + ヘルプ \ No newline at end of file diff --git a/app/src/main/res/values-ms/strings.xml b/app/src/main/res/values-ms/strings.xml index 5f21d2cf18..0c5053d44d 100644 --- a/app/src/main/res/values-ms/strings.xml +++ b/app/src/main/res/values-ms/strings.xml @@ -15,7 +15,7 @@ Perubahan terkini Kategori %1$d dipilih - Salinan + Sandaran Tetapan Tapis Telah dimuat turun @@ -399,7 +399,7 @@ Tiada apa untuk disunting di sambungan ini Kelajuan animasi ketik dua kali 32-bit warna - Langkau bab-bab yang bertanda dibaca + Langkau bab yang sudah dibaca Menahan ketik buka dialog Halaman muka surat Tiada animasi @@ -447,4 +447,8 @@ Skrin Dodge / Lighten Burn / Darken + Ke Depan + Segar Semula + Tiada hasil dijumpai + Pilih sumber untuk ditukar \ No newline at end of file diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index 9f35fae59e..b430b35db8 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -349,7 +349,7 @@ Kategorier slettet Lesningsdato for dette kapittelet vil bli fjernet. Er du sikker\? Tilbakestill alle kapittel for denne mangaen - Legg manga til i bibliotek + Legg manga til i bibliotek\? Bilde lagret Lagrer bilde Valg @@ -392,17 +392,17 @@ Hjelp Last ned merker Bibliotekmanga per rad - Denne utvidelsen ble signert med et usikkert sertifikat og ble ikke aktivert + Denne utvidelsen ble signert med et usikkert sertifikat, og ble dermed ikke aktivert \n -\nEn skadelig utvidelse kan lese innloggingsdetaljer lagret i Tachiyomi eller kjøre ukjent kode +\nEn skadelig utvidelse kan lese innloggingsdetaljer lagret i Tachiyomi, eller kjøre ukjent kode. \n -\nVed å godta dette sertifikatet aksepterer du overstående risiko. +\nVed å godta dette sertifikatet aksepterer du overstående risikoer. Det er ingen preferanser å redigere for denne utvidelsen - Animasjonshastighet for Dobbelklikk + Animasjonshastighet ved dobbelklikk Sideleser Gjenoppretting bruker kilde for å hente data, mobilkostnader kan forekomme \nHusk å logge inn på kilder som krever dette før gjennoppretting. - Oppdater siste leste kapittel er skrudd på for %1$d\? + Oppdater siste leste kapittel i eksterne tjenester for %1$d\? Vil du bruke dette bildet som omslag\? Leser for denne serien Trykk for å velge kilde å migrere fra @@ -435,16 +435,20 @@ Nedlaster Feil En uventet feil oppstod mens kapittelet ble lastet ned - En side mangler i katalogen + En side ble ikke funnet En side er ikke lastet Ingen trådløst tilkobling tilgjengelig Ingen nettverkstilkobling tilgjengelig Nedlasting pauset - Fargefilter-blandingsmodus + Blandingsmodus for fargefilter Overlegg Multiplisere Unngå / lysne Brenn / mørkere Rekkefølge for biblioteksoppdatering Velg rekkefølgen Tachiyomi ser etter oppdateringer + Frem + Gjenoppfrisk + Resultatløst + Velg en kilde å migrere fra \ No newline at end of file diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index d0a9e48672..ad33cdc68a 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -435,4 +435,15 @@ Zorg ook dat je ingelogd bent voor bronnen die dit vereisen alvorens je het teru Kopiëren Aan het migreren… Standaard + Openen in webview + 32-bit kleuren + Hoofdstukken die gemarkeerd zijn als gelezen overslaan + Overlapping + Vermenigvuldigen + + Help + Updatevolgorde bibliotheken + Selecteer de volgorde waarop Tachiyomi zoekt naar updates + Volgende + Herladen \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index b4edcbf623..794d9e211e 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -446,4 +446,6 @@ Nie znaleziono źródła %1$s Pomoc Kolejność aktualizacji biblioteki Ustaw kolejność, w jakiej Tachiyomi ma sprawdzać aktualizacje + Dalej + Odśwież \ No newline at end of file diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 12d630f40f..6b623ce115 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -15,7 +15,7 @@ Actualizări recente Categorii Selectate: %1$d - Backup + Copie de rezervă Migrare între surse Extensii Info extensie @@ -27,7 +27,7 @@ Citite Șterge filtre Alfabetic - Total capitole + Capitole totale Citite recent Actualizate recent Caută @@ -122,7 +122,7 @@ Ecran principal Limbă Prestabilită de sistem - Categoria principală + Categorie implicită Întreabă mereu Toate Detalii @@ -172,7 +172,7 @@ De la stânga la dreapta De la dreapta la stânga Vertical - Bandă desenată + Benzi desenate web Setări pagini Decodor de imagine Tip de mărime @@ -181,7 +181,7 @@ Potrivire lățime Potrivire înălțime Marime originală - Potrivire smart + Potrivire inteligentă Poziție inițială de mărire Automat Stânga @@ -229,7 +229,7 @@ \n%1$s sursa nu a fost găsită Copie de rezervă creată Restaurare completă - Nu s-a putut deschide log + Nu s-a putut deschide jurnalul Restaurarea a durat %1$s. \n%2$s erori găsite. Restaurare folosește sursa pentru a aduce datele, cost suplimentar aplicabil. De asemenea verificați dacă sunteți autentificați în sursele ce au nevoie înainte de a incepe restaurarea. @@ -244,7 +244,7 @@ Curățare cookies Cookies curățate Resetare optiuni de dialog - Curățare bază de date + Curățați baza de date Șterge manga și capitolele care nu sunt în bibliotecă Ești sigur\? Capitolele citite si progresul mangaurilor ce nu sunt în bibliotecă vor fi pierdute Înregistrări șterse @@ -256,7 +256,7 @@ Data versiunii Verifică pentru actualizări "Verifică automat pentru actualizări " - Trimite rapoarte pt eșuări + Trimite rapoarte pt. eșuări Ajută la rezolvarea bug-urilor. Informații sensibile nu vor fi trimise Autentificare pentru %1$s Nume de utilizator @@ -264,10 +264,10 @@ Arată parola Autentificare Autentificare reușită - Eroare autentificare + Eroare de conectare Eroare necunoscută Titlul sau autorul… - Actualizand categoria + Actualizând categoria Local Ești sigur ca vrei să elimini manga selectat\? Șterge și capitolele descărcate @@ -301,13 +301,13 @@ Status Sursă Genuri - Icoană circulară - Icoană rotunjita - Icoană pătrată - Icoană stea + Pictogramă circulară + Pictogramă rotunjită + Pictogramă pătrată + Pictograma stelei Scurtătură titlu Scurtătura a fost adăugată ecranului principal. - Forma icoanei + Forma pictogramei Creere scurtătură eșuată! Ștergeți capitolele descărcate\? %1$s copiat in clipboard @@ -320,7 +320,7 @@ Se descarcă Se descarcă (%1$d/%2$d) Eroare - Inrerupt + Întrerupt Eroare în aducerea capitolelor Arată titlul Arată numărul capitolului @@ -343,7 +343,7 @@ Abandonat Pe pauză Planificat pentru citit - Recitire + Recitind Scor Titlu Status @@ -364,7 +364,7 @@ Stabilește o copertă Copertă actualizată Pagină copiată în %1$s - Descărcare… + Descărcând… Descărcat %1$d%% Pagina: %1$d Capitolul %1$s @@ -401,11 +401,11 @@ Conexiune indisponibilă Selectează imagine copertă Selectează fișier de copie de rezervă - Selectează icoană scurtătură - Actualizare nouă valabilă! + Selectează pictogramă scurtătură + Nouă actualizare disponibilă! Descarcă Ignoră - Nici o actualizare nouă valabilă + Nu sunt disponibile actualizări noi Descărcare pornită În căutare de actualizări Descarcă actualizare @@ -415,8 +415,8 @@ Actualizare valabilă Imagine în findal la manga Coperta la manga - Nici o descărcare - Nici un capitol recent + Fără descărcări + Nu există capitole recente Nici un manga citi recent Biblioteca dumneavoastră este goală, puteți adaugă serii la bibliotecă de la Categorii. Nu aveți categorii. Apăsați butonul plus pentru a crea una pentru a vă organiza biblioteca. @@ -444,4 +444,6 @@ Dialog prin apasare lunga Trage în sus pentru mai multe opțiuni Ajutor + Ordinea actualizării bibliotecii + Selectați ordinea în care Tachiyomi verifică actualizarea \ No newline at end of file diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml index f59117ece2..1383908be8 100644 --- a/app/src/main/res/values-sc/strings.xml +++ b/app/src/main/res/values-sc/strings.xml @@ -183,7 +183,7 @@ Adata a s\'artària Mannària originale Adatamentu intelligente - Positzione de incumintzu de s\'ismanniamentu + Positzione incumintzu ismanniamentu Automàtica A manca A destra @@ -447,4 +447,8 @@ Agiudu Òrdine de agiornamentu de sa biblioteca Ischerta s\'òrdine chi Tachiyomi at a impreare pro sos agiornamentos + Sighi + Annoa + Perunu resultadu agadadu + Ischerta una mitza dae sa cale tramudare \ No newline at end of file diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml new file mode 100644 index 0000000000..8e431f9f6c --- /dev/null +++ b/app/src/main/res/values-sk/strings.xml @@ -0,0 +1,251 @@ + + + Meno + Kategórie + Manga + Kapitoly + Sledovanie + História + Nastavenia + Sťahujúce sa + Knižnica + Nedávno čítané + Katalógy + Updaty + Nedávno aktualizované + Kategórie + Vybraté: %1$d + Záloha + Presun zdrojov + Rozšírenia + Info o rozšíreniach + Pomoc + Nastavenia + Filter + Stiahnuté + Uložené + Neprečítané + Prečítané + Zrušiť filter + Abecedne + Všetky kapitoly + Naposledy čítané + Naposledy aktualizované + Hľadať + Hľadať všade + Vybrať všetko + Označiť ako prečítané + Označiť ako neprečítané + Označiť predošlé ako prečítané + Stiahnuť + Uložiť + Odstrániť z uložených + Vymazať + Aktualizovať + Aktualizovať knižnicu + Upraviť + Pridať + Pridať kategóriu + Upraviť kategórie + Premenovať kategóriu + Presunúť do kategórie + Nahrať vlastný obal + Zatriediť hore + Zatriediť dole + Stiahnuté + Nasledujúce nečítané + Začať + Zastaviť + Pauza + Zmazať + Zatvoriť + Predošlá kapitola + Nasledujúca kapitola + Skúsiť znovu + Odstrániť + Pokračovať + Presunúť + Otvoriť v browseri + Otvoriť vo web view + Pridať na plochu + Zmeniť zobrazenie + Zobraziť + Mriežka + List + Symbol stiahnutia + Nastaviť filter + Zrušiť + Triediť + Nainštalovať + Zdieľať + Uložiť + Reset + Krok späť + Exportovať + Otvoriť log + Vytvoriť + Obnoviť + Otvoriť + Prihlásiť sa + Maže sa… + Načítava sa… + Aplikácia nedostupná + Updaty + Všeobecné + Prehliadač + Sťahovanie + Zdroje + Sledovanie + Rozšírené + O Aplikácii + Knižnica: Manga na riadok + Na výšku + Na šírku + Predvolené + Frekvencia aktualizácie knižnice + Manuálne + Raz za hodinu + Každé 2 hodiny + Každé 3 hodiny + Každých 6 hodín + Každých 12 hodín + Raz za deň + Každé 2 dni + Každý týždeň + Každý mesiac + Kategórie, ktoré sa majú zahrnúť do globálnej aktualizácie + Všetko + Poradie aktualizácie knižnice + Vyberte poradie, v ktorom Tachiyomi kontroluje aktualizácie + Obmedzenia aktualizácii knižnice + Aktualizovať len vtedy, keď sú splnené podmienky + Wi-Fi + Nabíjanie + Aktualizovať iba nedokončenú Mangu + Synchronizovať kapitoly po prečítaní + Motív aplikácie + Hlavná téma + Tmavý motív + AMOLED téma + Tmavomodrá téma + Úvodná obrazovka + Jazyk + Predvolené nastavenie systému + Predvolená kategória + Vždy sa opýtať + Všetky + Podrobnosti + aktualizovať + Nainštalovať + Čakajúce + Sťahujem + Inštalujem + Nainštalovaný + Dôverovať + Odobrať dôveru + Odinštalovať + Preferencie + K dispozícii + Nedôveryhodné rozšírenie + Toto rozšírenie bolo podpísané nedôveryhodným certifikátom a nebolo aktivované. +\n +\nŠkodlivé rozšírenie môže čítať všetky prihlasovacie údaje uložené v Tachiyomi alebo spúšťať ľubovoľný kód. +\n +\nDôverovaním tohto certifikátu akceptujete tieto riziká. + Verzia: %1$s + Jazyk: %1$s + Nie sú k dispozícii žiadne preferencie na úpravu pre toto rozšírenie + Na celú obrazovku + Dopredu + Obnoviť + Zamknúť orientáciu + Prechod stránok + Rýchlosť animácie pre dvojité ťuknutie + Zobraziť číslo strany + 32-bitová farba + Orezať okraje + Použiť vlastný jas + Použiť vlastný farebný filter + Farebný filter: režim splynutia + Predvolený + Prekrytie + Znásobiť + Obrazovka + Dodge / Zosvetliť + Spáliť / Stmaviť + Nechať obrazovku zapnutú + Preskočiť kapitoly označené ako prečítané + Navigácia + Tlačidlá hlasitosti + Invertovať tlačidlá hlasitosti + Ťukanie + Rozšírene možnosti po dlhšiom podržaní + Farba pozadia + Biela + Čierna + Predvolený prehliadač + Predvolené + Zľava doprava + Sprava doľava + Vertikálne + Ako Webtoon - Zhora dole a strany sa spájajú do jednej dlhej + pager + Dekodér obrázkov + Mód škálovania + Prispôsobiť obrazovke + natiahnuť + Prispôsobiť šírke + Prispôsobiť výške + Pôvodná veľkosť + Inteligentne prispôsobiť + Začiatočná poloha priblíženia + Automatická + Vľavo + Vpravo + Stred + Žiadna animácia + Normálne + Rýchlo + Rotácia + Voľná + Zamknúť + Iba na výšku + Iba na šírku + R + G + B + A + Kam stahovať + Sťahovať, iba pri pripojení na Wi-Fi + Odstrániť keď označené ako prečítané + Odstrániť po prečítaní + Vlastný adresár + Vypnuté + Naposledy čítaná kapitola + Predposledná kapitola + Predpred posledná kapitola + Štvrtá kapitola od konca + Piata kapitola od konca + Stiahnuť nové kapitoly + Kategórie, ktoré sa majú zahrnúť do sťahovania + Služby + Zálohovanie + Vytvoriť zálohu + Možno použiť na obnovenie aktuálnej knižnice + Obnoviť zálohu + Obnoviť knižnicu zo záložného súboru + Adresár na zálohy + Služby + Frekvencia zálohovania + Max. počet automatických záloh + Obnovujem zálohu +\n%1$s pridaná do knižnice + Zdroj sa nenašiel + Obnovujem zálohu +\n%1$s zdroj sa nenašiel + Záloha bola vytvorená + Obnovenie dokončené + Log sa nedá otvoriť + Obnova trvala %1$s. +\n%2$s nájdených chýb. + \ No newline at end of file diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 3fc6aa1939..24213f6021 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -58,7 +58,7 @@ เปิด เข้าสู่ระบบ กำลังลบ… - กำลังโหลด… + กำลังดำเนินการ… อัพเดท ทั่วไป ตัวอ่าน @@ -93,4 +93,362 @@ สีพื้นหลัง ขาว ดำ + อ่านล่าสุด + ค้นหา + อ่านแล้ว + ช่วยเหลือ + เปลี่ยนแหล่งข้อมูล + บุ๊คมาร์ค + บุ๊คมาร์ค + ลบบุ๊คมาร์ค + ย้ายไปที่ประเภท + เรียงขึ้น + เรียงลง + อ่านเรื่องที่ยังไม่ได้อ่าน + เริ่มต้น + จุดจบ + หยุดพัก + ล้าง + ลบออก + เล่นต่อ + เพิ่มไปที่หน้าหลัก + เปลี่ยนรูปแบบการแสดงผล + การแสดงผล + ดาวน์โหลดป้าย + ตั้งตัวกรอง + การจัดเรียง + แชร์ + ย้อนกลับ + นำออก + ประวัติ + ย้อนค่ากลับ + โปรแกรมไม่พร้อม + ที่ดาวน์โหลด + การติดตาม + จำนวนการ์ตูนแต่ละแถวแนวนอน + แนวตั้ง + แนวนอน + ความถี่การปรับปรุงข้อมูลห้องสมุด + คู่มือ + หมวดหมู่ที่จะปรับปรุงข้อมูลทั้งหมด + จำกัดการปรับปรุงห้องสมุด + ปรับปรุงตามเงื่อนไข + Wi-Fi + ปรับปรุงเฉพาะมังงะที่ดำเนินต่อ + ซิงค์ตอนหลังการอ่าน + รูปแบบโปรแกรม + รูปแบบหน้าจอหลัก + รูปแบบสีดำ + รูปแบบ AMOLED + รูปแบบสีน้ำเงิน + เปิดหน้าแรก + ค่าเรื่มต้นประเภท + ทั้งหมด + เชื่อถือ + ไม่น่าเชื่อถือ + ลบการติดตั้ง + การตั้งค่า + ที่มี + ส่วนขยายที่ไม่น่าเชื่อถือ + ส่วนต่อขยายนี้ถูกรับรองจากใบรับรองที่ไม่น่าเชื่อถือ และมันไม่ทำงาน +\n +\nส่วนต่อขยายที่ประสงค์ร้าย สามารถข้อมูลหนังสือรับรองทั้งหมดใน Tachiyomi หรือโปรแกรมอันตราย +\n +\nคุณยอมต้องยอมรับความเสี่ยง กรณีเชื่อถือใบรับรองนี้ + เวอร์ชัน: %1$s + ไม่มีการตั้งค่าสำหรับส่วนต่อขยายนี้ + เต็มจอ + ล๊อคหมุนจอ + เล่นเปลี่ยนแปลงหน้า + เพื่อความเร็วภาพเคลื่อนไหว + แสดงเลขหน้า + ตัดขอบ + ใช้ความสว่างแบบกำหนดเอง + ใช้ฟิลเตอร์สีแบบกำหนดเอง + เปิดหน้าจอไว้ + ปุ่มปรับระดับเสียง + สลับด้าน ปุ่มปรับระดับเสียง + แตะ + ตัวแสดงเริ่มต้น + ค่าเริ่มต้น + จากซ้ายไปขวา + จากขวาไปซ้าย + แนวตั้ง + เว็บตูน + การแสดงหน้า + ตัวถอดรหัสภาพ + ชนิดของมาตราส่วน + หน้าจอพอดี + ยืด + พอดีกับความกว้าง + พอดีกับความสูง + ขนาดดั้งเดิม + พอดีอย่างชาญฉลาด + ตำแหน่งเริ่มซูม + อัตโนมัติ + ซ้าย + ขวา + ตรงกลาง + ไม่ใช้ภาพเคลื่อนไหว + ปกติ + เร็ว + การหมุน + ว่าง + ล็อค + บังคับแนวตั้ง + บังคับแนวนอน + R + กรัม + B + A + ไดเรกทอรีดาวน์โหลด + ดาวน์โหลดผ่าน Wi-fi เท่านั้น + ลบเครื่องหมายว่าอ่านแล้ว + ลบออกหลังจากอ่านแล้ว + ไดเรกทอรีที่กำหนดเอง + ปิดการใช้งาน + บทที่อ่านล่าสุด + 2 บท ถึง บทสุดท้าย + 3 บท ถึง บทสุดท้าย + 4 บท ถึง บทสุดท้าย + 5 บท ถึง บทสุดท้าย + ดาวน์โหลดบทใหม่ + ประเภทที่จะรวมในการดาวน์โหลด + บริการ + การสำรองข้อมูล + สร้างการสำรองข้อมูล + สามารถใช้ในการเรียกคืนค่าห้องสมุดปัจจุบัน + เรียกคืนการสำรองข้อมูล + เรียกคืนค่าห้องสมุดจากแฟ้มสำรองข้อมูล + ไดเรกทอรีการสำรองข้อมูล + บริการ + ความถี่ในการสำรองข้อมูล + จำนวนการสำรองข้อมูลอัตโนมัติสูงสุด + กำลังกู้คืนข้อมูลสำรอง +\nเพิ่ม %1$s ไปยังห้องสมุดแล้ว + ไม่พบแหล่งที่มา + การคืนค่าการสำรองข้อมูล +\nไม่พบแหล่งที่มาของ %1$s + การสำรองข้อมูลที่สร้างขึ้น + การคืนค่าเสร็จสมบูรณ์ + ไม่สามารถเปิดแฟ้มบันทึก + การคืนค่าเอา %1$s +\nพบข้อผิดพลาด %2$s + แฟ้มที่บันทึกไว้ที่ %1$s + คุณต้องการสำรองข้อมูลอะไร\? + กำลังคืนค่าการสำรองข้อมูล + กำลังสร้างการสำรองข้อมูล + ล้างแคชของบท + ใช้แล้ว: %1$s + ล้างแคชแล้ว %1$d ไฟล์ถูกลบแล้ว + เกิดข้อผิดพลาดขณะล้างแคช + ล้างคุกกี้ + ล้างคุกกี้แล้ว + รีเซ็ตตัวเลือกกล่องโต้ตอบ + ล้างฐานข้อมูล + ลบมังงะและบทที่ไม่ได้อยู่ในห้องสมุดของคุณ + คุณแน่ใจไหม\? อ่านบทและความคืบหน้าของมังงะที่ไม่ใช่ห้องสมุดจะหายไป + รายการที่ลบแล้ว + รีเฟรชข้อมูลเมตาของไลบรารี + การปรับปรุงครอบคลุมประเภทคำอธิบายและข้อมูลสถานะมังงะ + รีเฟรชข้อมูลเมตาของการติดตาม + อัพเดตสถานะคะแนนและบทสุดท้ายที่อ่านจากบริการติดตาม + เวอร์ชัน + สร้างเวลา + ตรวจหาโปรแกรมปรับปรุง + ตรวจหาการปรับปรุงโปรแกรมประยุกต์โดยอัตโนมัติ + ส่งรายงานความผิดพลาด + ช่วยแก้ไขข้อบกพร่องใดๆ ไม่มีข้อมูลที่สำคัญจะถูกส่ง + เข้าสู่ระบบสำหรับ %1$s + ชื่อผู้ใช้ + รหัส ผ่าน + แสดงรหัสผ่าน + ลงชื่อเข้าใช้ + เข้าสู่ระบบสำเร็จ + ข้อผิดพลาดในการเข้าสู่ระบบ + ข้อผิดพลาดที่ไม่รู้จัก + ชื่อเรื่องหรือผู้เขียน … + กำลังอัพเดตประเภท + ท้องถิ่น + คุณแน่ใจหรือไม่ว่าคุณต้องการเอามังงะที่เลือกออก\? + ลบบทที่ดาวน์โหลดด้วย + ตัวกรองค้นหา + แหล่งที่มานี้ต้องการให้คุณเข้าสู่ระบบ + เลือกแหล่งที่มา + กรุณาเปิดใช้งานอย่างน้อยหนึ่งแหล่งที่ถูกต้อง + ไม่มีผลลัพธ์เพิ่มเติม + มังงะภายในเครื่อง + อื่น ๆ + ไม่สามารถเลือกค่าเริ่มต้นพร้อมกับหมวดหมู่อื่น ๆ ได้ + เพิ่มมังงะในห้องสมุดของคุณแล้ว + ค้นหาทั้งหมด… + ล่าสุด + เปิดดู + มังงะนี้ถูกลบออกจากฐานข้อมูล! + ข้อมูล + คำอธิบาย + ยังดำเนินการอยู่ + ไม่ทราบ + ลิขสิทธิ์ + ลบออกจากห้องสมุด + ชื่อเรื่อง + เพิ่มไปยังห้องสมุด + ลบออกจากห้องสมุด + ผู้เขียน + ศิลปิน + บท + บทสุดท้าย + ปรับปรุงแล้ว + สถานะ + แหล่ง + ชนิด + ไอคอนวงกลม + ไอคอนโค้งมน + ไอคอนสี่เหลี่ยม + ไอคอนดาว + ชื่อทางลัด + เพิ่มทางลัดไปยังหน้าจอหลักแล้ว + รูปร่างไอคอน + ไม่สามารถสร้างทางลัดได้! + ลบบทที่ดาวน์โหลดมาหรือไม่\? + %1$s ถูกคัดลอกไปยังคลิปบอร์ด + ไม่ได้ติดตั้ง: %1$s + บท + ไม่มีชื่อเรื่อง + บทที่ %1$s + ดาวน์โหลดแล้ว + อยู่ในคิวแล้ว + กำลังดาวน์โหลด + กำลังดาวน์โหลด (%1$d/%2$d) + เกิดข้อผิดพลาด + หยุดเล่นชั่วคราว + เกิดข้อผิดพลาดขณะตรวจสอบจำนวนบท + แสดงชื่อเรื่อง + แสดงหมายเลขบท + โหมดการเรียงลำดับ + ตามแหล่งที่มา + ตามหมายเลขบท + ดาวน์โหลด + จำนวนดาวน์โหลดที่กำหนดเอง + จำนวน + ดาวน์โหลดบทถัดไป + ดาวน์โหลด 5 บทถัดไป + ดาวน์โหลด 10 บทถัดไป + ดาวน์โหลดแบบกำหนดเอง + ดาวน์โหลดทั้งหมด + ดาวน์โหลดที่ยังไม่ได้อ่าน + คุณแน่ใจหรือไม่ว่าคุณต้องการลบบทที่เลือก\? + การติดตาม + การอ่าน + เสร็จสมบูรณ์ + ทิ้ง + รอสาย + วางแผนที่จะอ่าน + อ่านอีกครั้ง + คะแนน + แตะนาน + เปิดในมุมมองเว็บ + สี 32บิต + ข้ามตอนที่อ่านแล้ว + แสดงตัวอักษรชัดเจน + วางซ้อน + หน้าจอ + ดอดจ์ / แบ่งเบา + ลำดับการปรับปรุงห้องสมุด + เลือกลำดับที่ให้ Tachiyomi ตรวจสอบการปรับปรุง + เดินหน้า + โหลดใหม่ + ไม่พบผลลัพธ์ + คืนค่าใช้แหล่งที่มาเพื่อดึงข้อมูลอาจมีค่าใช้จ่ายของผู้ให้บริการ +\nตรวจสอบให้แน่ใจว่าคุณได้เข้าสู่ระบบอย่างถูกต้องในแหล่งที่ต้องใช้ก่อนที่จะกู้ + ชื่อเรื่อง + สถานะ + สถานะ + เริ่มต้นแล้ว + ชนิด + ผู้เขียน + ไม่ได้ตั้งค่า URL ของมังงะ โปรดคลิกที่ชื่อและเลือกมังงะอีกครั้ง + หมวดหมู่ที่มีชื่อนี้มีอยู่แล้ว! + หมวดหมู่ถูกลบ + สิ่งนี้จะลบวันที่อ่านของบทนี้ คุณแน่ใจไหม\? + รีเซ็ตบททั้งหมดสำหรับมังงะนี้ + เพิ่มมังงะในห้องสมุด\? + บันทึกรูปภาพแล้ว + กำลังบันทึกรูปภาพ + ตัวเลือก + ตัวกรองที่กำหนดเอง + ตั้งเป็นปก + อัปเดตปกแล้ว + คัดลอกหน้าไปยัง %1$s + กำลังดาวน์โหลด… + ดาวน์โหลด %1$d%% + หน้า: %1$d + บทที่ %1$s + ไม่พบบทถัดไป + ไม่พบบทก่อนหน้านี้ + ไม่สามารถถอดรหัสรูปภาพได้ + เปิดบริการอัปเดตบทที่อ่านล่าสุด %1$d หรือไม่\? + คุณต้องการที่จะตั้งค่าภาพเป็นภาพที่ปกใช่มั้ย\? + ตัวแสดงสำหรับชุดนี้ + เสร็จแล้ว: + ปัจจุบัน: + ต่อไป: + ก่อนหน้า: + ไม่มีบทต่อไป + ไม่มีบทก่อนหน้านี้ + กำลังโหลดหน้า … + ไม่สามารถโหลดหน้าได้: %1$s + %1$s - Ch.%2$s + เลือกแหล่งที่มา + เลือกข้อมูลที่จะรวม + เลือก + โยกย้าย + คัดลอก + การโอนย้าย … + เกิดข้อผิดพลาดขณะดาวน์โหลดบท คุณสามารถลองอีกครั้งในส่วนการดาวน์โหลด + ความคืบหน้าในการอัพเดต: %1$d/%2$d + พบบทใหม่ + สำหรับชื่อ %1$d + ไม่สามารถอัปเดตหน้าปก + กรุณาเพิ่มมังงะในห้องสมุดของคุณก่อนที่จะทำเช่นนี้ + การซิงค์ถูกยกเลิก + ไม่ได้เชื่อมต่อกับแหล่งจ่ายไฟ + การซิงค์ถูกยกเลิก + การเชื่อมต่อไม่พร้อม + เลือกภาพหน้าปก + เลือกไฟล์สำรองข้อมูล + เลือกไอคอนทางลัด + มีการอัปเดตใหม่! + ดาวน์โหลด + ไม่สนใจ + ไม่มีการอัปเดตใหม่ + เริ่มต้นการดาวน์โหลดแล้ว + กำลังมองหาการปรับปรุง + ดาวน์โหลดการปรับปรุง + กำลังดาวน์โหลด + ดาวน์โหลดเสร็จสิ้น + ดาวน์โหลดเกิดข้อผิดพลาด + อัปเดตที่มีอยู่ + ภาพฉากหลังของมังงะ + ปกของมังงะ + ไม่มีการดาวน์โหลด + ไม่มีบทล่าสุด + ไม่มีมังงะที่เพิ่งอ่าน + ห้องสมุดของคุณว่างเปล่า คุณสามารถเพิ่มชุดข้อมูลลงในคลังของคุณจากประเภท + คุณไม่มีหมวดหมู่ กดปุ่มเพิ่ม เพื่อเพิ่มหมวดหมู่สำหรับการจัดระเบียบห้องสมุดของคุณ + การดาวน์โหลด + เกิดข้อผิดพลาด + เกิดข้อผิดพลาดที่ไม่คาดคิดขณะดาวน์โหลดบท + หน้าหายไปในไดเรกทอรี + ไม่มีการโหลดหน้า + ไม่มีการเชื่อมต่อ wifi + ไม่มีการเชื่อมต่อเครือข่าย + ดาวน์โหลดหยุดชั่วคราว + ร่วมกัน + ห้องสมุด + การดาวน์โหลด + ดึงขึ้นเพื่อดูตัวเลือกเพิ่มเติม + หลากหลาย + มืดมิด + เลือกแหล่งที่มา \ No newline at end of file diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a5bf5ccb3c..e669e04117 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -447,4 +447,8 @@ Yardım Kitaplık güncelleme sırası Tachiyomi\'nin güncelleme denetleme sırasını seçin + İleri + Yenile + Sonuç bulunmadı + Taşınılacak bir kaynak seçin \ No newline at end of file diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index e545080103..c3bc38b9b3 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -1,7 +1,6 @@ Tên - Cài đặt Hàng chờ tải xuống @@ -13,7 +12,6 @@ Hạng mục Đã chọn: %1$d Sao lưu - Cài đặt Bộ lọc @@ -70,11 +68,9 @@ Lưu lại Cài lại Quay lại - Đang xóa… Đang tải… - Chung @@ -84,7 +80,6 @@ Theo dõi Nâng cao Giới thiệu - Số truyện hiển thị trong thư viện trên cùng một dòng Dọc @@ -113,7 +108,6 @@ Màn hình khởi động Ngôn ngữ Mặc định hệ thống - Toàn màn hình Khóa xoay @@ -124,7 +118,7 @@ Giữ màn hình bật Điều hướng Phím âm lượng - Nhấn giữ + Nhấn Màu nền Trắng Đen @@ -156,8 +150,6 @@ G B A - - Thư mục tải xuống Chỉ tải trên Wi-Fi @@ -171,10 +163,8 @@ Bốn chương gần nhất Năm chương gần nhất Tải chương mới - Dịch vụ - Dọn dẹp bộ nhớ đệm Đã sử dụng: %1$s @@ -189,7 +179,6 @@ Các mục đã bị xóa Làm mới siêu dữ liệu của thư viện Cập nhật ảnh bìa, thể loại, thông tin trạng thái của các bộ truyện - Phiên bản Thời gian tạo @@ -198,8 +187,6 @@ Gửi báo cáo lỗi Giúp đỡ sửa lỗi. Sẽ không có thông tin nhạy cảm nào được gửi đi - - Đăng nhập vào %1$s Tên đăng nhập @@ -209,21 +196,17 @@ Đăng nhập thành công Lỗi đăng nhập Lỗi không xác định - Tiêu đề truyện hoặc tên tác giả… Cập nhật danh mục Bạn có chắc là muốn xóa truyện đã chọn không\? - Nguồn truyện này yêu cầu đăng nhập Chọn một nguồn truyện Vui lòng chọn ít nhất một nguồn truyện hợp lệ Không có thêm kết quả nào - Truyện này đã bị xóa khỏi cơ sở dữ liệu! - Thông tin Mô tả @@ -244,7 +227,6 @@ Tiêu đề của lối tắt Kiểu biểu tượng Tạo lối tắt thất bại! - Danh sách chương Không có tiêu đề @@ -268,7 +250,6 @@ Tải về toàn bộ Tải các chương chưa đọc Bạn có chắc muốn xóa các chương đã chọn? - Theo dõi Đang đọc @@ -280,23 +261,18 @@ Tiêu đề Trạng thái Các chương - Tên danh mục này đã tồn tại! Danh mục đã bị xóa - Sẽ xóa ngày đọc các chương. Bạn chắc chứ? Làm mới mọi chương của truyện này - Thêm truyện vào thư viện? - Đã lưu ảnh Đang lưu ảnh Tùy chọn - Bộ lọc tùy chỉnh Đặt làm ảnh bìa @@ -312,16 +288,12 @@ Cập nhật chương mới nhất của dịch vụ đang bật đến %1$d\? Bạn có chắc muốn đặt ảnh này làm ảnh bìa? Kiểu đọc cho series này - Sao lưu - %1$s - Ch.%2$s - Có lỗi đã xảy ra khi đang tải chương. Bạn có thể thử lại trong phần tải xuống - Tiến độ cập nhật: %1$d/%2$d "Đã tìm thấy chương mới " @@ -331,12 +303,10 @@ Chưa được kết nối đến nguồn điện Đã hủy đồng bộ Không có kết nối - Chọn ảnh bìa Chọn file sao lưu Chọn biểu tượng phím tắt - Có bản cập nhật mới! Tải xuống @@ -344,24 +314,20 @@ Không có cập nhật mới Đã bắt đầu tải xuống Đang tìm bản cập nhật mới - Tải xuống cập nhật Đang trong quá trình tải xuống Đã tải xong Lỗi khi tải xuống Có cập nhật mới - Ảnh nền của truyện Ảnh bìa của truyện - Không có tải xuống Không có các chương gần đây Không có truyện đã đọc gần đây Thư viện trống, bạn có thể thêm truyện vào thư viện từ Danh mục. - Trình tải xuống Lỗi @@ -447,7 +413,7 @@ \n%2$s lỗi đã được tìm thấy. Khôi phục sử dụng nguồn để lấy dữ liệu, yêu cầu sử dụng mạng \nHãy đảm bảo rằng bạn đã đăng nhập đúng cách vào các nguồn trước khi khôi phục. - Tập tin được lưu tới %1$s + Tập tin được lưu được %1$s Bạn có muốn sao lưu không\? Khôi phục sao lưu Đang tạo bản sao lưu @@ -500,4 +466,20 @@ Thường gặp Thư viện Trình tải xuống + Nhấn giữ mở hộp thoại + Kéo xuống có nhiều tuỳ chọn + Mở bằng webview + Màu 32-bit + Bỏ qua chap đã đọc + Chế độ hòa trộn bộ lọc màu + Mặc định + Phủ lên + Nhân + Trợ giúp + Thứ tự ưu tiên cập nhật + Chọn thứ tự để Tachiyomi kiểm tra cập nhật + Chuyển tiếp + Làm mới + Không tìm thấy kết quả nào + Chọn 1 nguồn để di chuyển từ \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 015fa2d2e9..36ff80f467 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -128,7 +128,7 @@ 系统默认 默认标签 每次询问 - All + 全部 详细 更新 安装 @@ -306,7 +306,7 @@ 方形图标 星形图标 快捷方式标题 - 已创建快捷方式 + 已添加快捷方式至主屏幕 图标形状 创建快捷方式失败! 删除已下载的章节? @@ -419,8 +419,8 @@ 没有下载中的任务 无最近章节 无最近阅读 - 你的书架是空的哦,请去发现栏寻找漫画进行收藏吧 - 你还没有标签。你可以点击加号按钮创建一个标签以管理书架 + 你的书架为空,您可从发现添加漫画至书架 + 你还没有漫画类别。点击右下方的加号按钮创建一个类别以管理书架 下载 错误 下载时发生不可预期的错误 @@ -438,9 +438,14 @@ 用外部浏览器打开 32位色彩 跳过已读章节 - 滤镜颜色模式 + 滤镜调和模式 默认 帮助 书架更新顺序 选择Tachiyomi检查书架更新的顺序 + 悬浮窗 + 正片叠底 + 屏幕 + 减淡/变亮 + 颜色加深/变暗 \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 2c598f74c8..52aa48cf63 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -3,7 +3,7 @@ 分類 漫畫 章節 - 記錄 + 歷史記錄 設定 下載佇列 我的書櫃 @@ -367,7 +367,7 @@ 尚未收藏任何作品,請至書目檢索挖掘您的愛書。 更新書封、類型、描述和連載狀態等漫畫簡介 重設此漫畫所有章節 - 自訂篩選器 + 濾鏡 已下載 %1$d% % 第 %1$s 章 遷移 @@ -385,4 +385,60 @@ 已閱畢: 下一章: 發現新章節 + 略過已讀的章節 + 閱畢後刪除 + 已複製頁面至「%1$s」 + 沒有下一章 + 沒有前一章 + 第 %1$s 頁載入失敗 + 沒有新章節 + 部分頁面遺失 + 未載入部分頁面 + 名稱 + 追隨中 + 移至下個未讀 + 打開記錄檔 + 跟隨中 + 閱讀完後同步章節 + 信任 + 不信任 + 不信任的擴充元件 + 這個插件的憑證是未經認證的,並且它沒有被啟用。 +\n +\n惡意插件可能讀取或儲存在Tachiyomi中的任何登錄憑證或是會執行任意程式碼。 +\n +\n信任這個憑證,即代表你願意承擔上述的風險。 + 最後閱讀的章節 + 最大自動備份數 + 無法打開記錄檔 + 已恢復 %1$s。 +\n%2$s 出現錯誤。 + 你確定嗎?將刪除未在書櫃的漫畫章節與閱讀進度的數據 + 更新同步數據 + 更新同步服務的狀態、評分以及已讀章節 + 標題或作者… + 選擇一個來源 + 請至少啟用一個有效的來源 + 最近更新 + 漫畫已被移出資料庫! + 跟隨中 + 閱讀中 + 加入閱讀清單 + 重新讀取中 + 已開始 + 類型 + 作者 + 漫畫網址未設置,請點擊標題再選擇一次漫畫 + 這將會清除此章節的閱讀日期,確定嗎? + 要從伺服器上同步上次已讀的最新章節到%1$d嗎? + 當前章節: + 上一章: + %1$s - 第%2$s章 + 選擇需要遷移的來源 + 選擇需要移動的數據 + 下載時發生錯誤。請再試一次 + %1$d + 連接不可用 + 漫畫背景 + 下載時發生不可預期的錯誤 \ No newline at end of file From 83c2e907c7dbf923bfab18fe0de56c639d27ea8b Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 11 Jan 2020 18:27:39 -0800 Subject: [PATCH 13/24] Fixed file permissions for Android 10 (cherry picked from commit 4e1952ffafa5b64988b0cff533fe497fabce86a6) --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b3558ec507..7ad671ffed 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -21,6 +21,7 @@ android:hardwareAccelerated="true" android:usesCleartextTraffic="true" android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:label="@string/app_name" android:largeHeap="true" From 3892b93bcada9926fae291b18a72d6e5089237ca Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:01:26 -0500 Subject: [PATCH 14/24] Rename tracker icon images --- .../kanade/tachiyomi/data/track/anilist/Anilist.kt | 2 +- .../kanade/tachiyomi/data/track/bangumi/Bangumi.kt | 2 +- .../eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt | 2 +- .../tachiyomi/data/track/myanimelist/MyAnimeList.kt | 2 +- .../tachiyomi/data/track/shikimori/Shikimori.kt | 3 +-- .../{anilist.webp => tracker_anilist.webp} | Bin .../{bangumi.webp => tracker_bangumi.webp} | Bin .../{kitsu.webp => tracker_kitsu.webp} | Bin .../drawable-xxxhdpi/{mal.webp => tracker_mal.webp} | Bin .../{shikimori.webp => tracker_shikimori.webp} | Bin app/src/main/res/layout/track_item.xml | 2 +- 11 files changed, 6 insertions(+), 7 deletions(-) rename app/src/main/res/drawable-xxxhdpi/{anilist.webp => tracker_anilist.webp} (100%) rename app/src/main/res/drawable-xxxhdpi/{bangumi.webp => tracker_bangumi.webp} (100%) rename app/src/main/res/drawable-xxxhdpi/{kitsu.webp => tracker_kitsu.webp} (100%) rename app/src/main/res/drawable-xxxhdpi/{mal.webp => tracker_mal.webp} (100%) rename app/src/main/res/drawable-xxxhdpi/{shikimori.webp => tracker_shikimori.webp} (100%) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt index fde18a22d6..043d2653fe 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt @@ -52,7 +52,7 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) { } } - override fun getLogo() = R.drawable.anilist + override fun getLogo() = R.drawable.tracker_anilist override fun getLogoColor() = Color.rgb(18, 25, 35) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 0d93e1fb73..9638d40d15 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -91,7 +91,7 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) { private val api by lazy { BangumiApi(client, interceptor) } - override fun getLogo() = R.drawable.bangumi + override fun getLogo() = R.drawable.tracker_bangumi override fun getLogoColor() = Color.rgb(0xF0, 0x91, 0x99) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt index 97741fd54e..a6f49c401e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/Kitsu.kt @@ -34,7 +34,7 @@ class Kitsu(private val context: Context, id: Int) : TrackService(id) { private val api by lazy { KitsuApi(client, interceptor) } override fun getLogo(): Int { - return R.drawable.kitsu + return R.drawable.tracker_kitsu } override fun getLogoColor(): Int { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt index 1cdb341085..24fb80128c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeList.kt @@ -34,7 +34,7 @@ class Myanimelist(private val context: Context, id: Int) : TrackService(id) { override val name: String get() = "MyAnimeList" - override fun getLogo() = R.drawable.mal + override fun getLogo() = R.drawable.tracker_mal override fun getLogoColor() = Color.rgb(46, 81, 162) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index 4c818d5fce..00f7a517ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -2,7 +2,6 @@ package eu.kanade.tachiyomi.data.track.shikimori import android.content.Context import android.graphics.Color -import android.util.Log import com.google.gson.Gson import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.models.Track @@ -84,7 +83,7 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { private val api by lazy { ShikimoriApi(client, interceptor) } - override fun getLogo() = R.drawable.shikimori + override fun getLogo() = R.drawable.tracker_shikimori override fun getLogoColor() = Color.rgb(40, 40, 40) diff --git a/app/src/main/res/drawable-xxxhdpi/anilist.webp b/app/src/main/res/drawable-xxxhdpi/tracker_anilist.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/anilist.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_anilist.webp diff --git a/app/src/main/res/drawable-xxxhdpi/bangumi.webp b/app/src/main/res/drawable-xxxhdpi/tracker_bangumi.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/bangumi.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_bangumi.webp diff --git a/app/src/main/res/drawable-xxxhdpi/kitsu.webp b/app/src/main/res/drawable-xxxhdpi/tracker_kitsu.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/kitsu.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_kitsu.webp diff --git a/app/src/main/res/drawable-xxxhdpi/mal.webp b/app/src/main/res/drawable-xxxhdpi/tracker_mal.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/mal.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_mal.webp diff --git a/app/src/main/res/drawable-xxxhdpi/shikimori.webp b/app/src/main/res/drawable-xxxhdpi/tracker_shikimori.webp similarity index 100% rename from app/src/main/res/drawable-xxxhdpi/shikimori.webp rename to app/src/main/res/drawable-xxxhdpi/tracker_shikimori.webp diff --git a/app/src/main/res/layout/track_item.xml b/app/src/main/res/layout/track_item.xml index b15dcb88e3..029ca35fd3 100644 --- a/app/src/main/res/layout/track_item.xml +++ b/app/src/main/res/layout/track_item.xml @@ -25,7 +25,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - tools:src="@drawable/mal" /> + tools:src="@drawable/tracker_mal" /> From ab2bdfc508fb87367c59fb52839c89e700e2f4ac Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:03:39 -0500 Subject: [PATCH 15/24] Remove unused FAB animations --- app/src/main/res/anim/fab_hide_to_bottom.xml | 6 ------ app/src/main/res/anim/fab_show_from_bottom.xml | 6 ------ 2 files changed, 12 deletions(-) delete mode 100644 app/src/main/res/anim/fab_hide_to_bottom.xml delete mode 100644 app/src/main/res/anim/fab_show_from_bottom.xml diff --git a/app/src/main/res/anim/fab_hide_to_bottom.xml b/app/src/main/res/anim/fab_hide_to_bottom.xml deleted file mode 100644 index b5f8d63bd2..0000000000 --- a/app/src/main/res/anim/fab_hide_to_bottom.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/anim/fab_show_from_bottom.xml b/app/src/main/res/anim/fab_show_from_bottom.xml deleted file mode 100644 index eea12e8c42..0000000000 --- a/app/src/main/res/anim/fab_show_from_bottom.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file From 51d454cded0f6de6b4c14c8baf721c92374a754f Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:04:23 -0500 Subject: [PATCH 16/24] Run formatting on test package --- .../tachiyomi/data/backup/BackupTest.kt | 12 +-- .../data/database/ChapterRecognitionTest.kt | 99 ++++++++++++------- .../data/library/LibraryUpdateServiceTest.kt | 2 +- 3 files changed, 73 insertions(+), 40 deletions(-) diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt index ddf5f7e05f..748dc30daf 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt +++ b/app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt @@ -166,7 +166,7 @@ class BackupTest { assertThat(favoriteManga[0].viewer).isEqualTo(3) // Update json with all options enabled - mangaEntries.add(backupManager.backupMangaObject(manga,1)) + mangaEntries.add(backupManager.backupMangaObject(manga, 1)) // Change manga in database to default values val dbManga = getSingleManga("One Piece") @@ -178,7 +178,7 @@ class BackupTest { assertThat(favoriteManga[0].viewer).isEqualTo(0) // Restore local manga - backupManager.restoreMangaNoFetch(manga,dbManga) + backupManager.restoreMangaNoFetch(manga, dbManga) // Test if restore successful favoriteManga = backupManager.databaseHelper.getFavoriteMangas().executeAsBlocking() @@ -231,7 +231,7 @@ class BackupTest { // Create restore list val chapters = ArrayList() - for (i in 1..8){ + for (i in 1..8) { val chapter = getSingleChapter("Chapter $i") chapter.read = true chapters.add(chapter) @@ -263,7 +263,7 @@ class BackupTest { * Test to check if history restore works */ @Test - fun restoreHistoryForManga(){ + fun restoreHistoryForManga() { // Initialize json with version 2 initializeJsonTest(2) @@ -376,7 +376,7 @@ class BackupTest { return category } - fun clearDatabase(){ + fun clearDatabase() { db.deleteMangas().executeAsBlocking() db.deleteHistory().executeAsBlocking() } @@ -408,4 +408,4 @@ class BackupTest { chapter.url = "/read-online/$name-page-1.html" return chapter } -} \ No newline at end of file +} diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt index ee8c1f33a4..452da9b303 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt +++ b/app/src/test/java/eu/kanade/tachiyomi/data/database/ChapterRecognitionTest.kt @@ -42,7 +42,8 @@ class ChapterRecognitionTest { /** * Called before test */ - @Before fun setup() { + @Before + fun setup() { manga = Manga.create(0).apply { title = "random" } chapter = Chapter.create() } @@ -50,7 +51,8 @@ class ChapterRecognitionTest { /** * Ch.xx base case */ - @Test fun ChCaseBase() { + @Test + fun ChCaseBase() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch.4: Misrepresentation") @@ -61,7 +63,8 @@ class ChapterRecognitionTest { /** * Ch. xx base case but space after period */ - @Test fun ChCaseBase2() { + @Test + fun ChCaseBase2() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol. 1 Ch. 4: Misrepresentation") @@ -72,7 +75,8 @@ class ChapterRecognitionTest { /** * Ch.xx.x base case */ - @Test fun ChCaseDecimal() { + @Test + fun ChCaseDecimal() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch.4.1: Misrepresentation") @@ -87,7 +91,8 @@ class ChapterRecognitionTest { /** * Ch.xx.a base case */ - @Test fun ChCaseAlpha() { + @Test + fun ChCaseAlpha() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch.4.a: Misrepresentation") @@ -106,7 +111,8 @@ class ChapterRecognitionTest { /** * Name containing one number base case */ - @Test fun OneNumberCaseBase() { + @Test + fun OneNumberCaseBase() { createManga("Bleach") createChapter("Bleach 567 Down With Snowwhite") @@ -117,7 +123,8 @@ class ChapterRecognitionTest { /** * Name containing one number and decimal case */ - @Test fun OneNumberCaseDecimal() { + @Test + fun OneNumberCaseDecimal() { createManga("Bleach") createChapter("Bleach 567.1 Down With Snowwhite") @@ -132,7 +139,8 @@ class ChapterRecognitionTest { /** * Name containing one number and alpha case */ - @Test fun OneNumberCaseAlpha() { + @Test + fun OneNumberCaseAlpha() { createManga("Bleach") createChapter("Bleach 567.a Down With Snowwhite") @@ -151,7 +159,8 @@ class ChapterRecognitionTest { /** * Chapter containing manga title and number base case */ - @Test fun MangaTitleCaseBase() { + @Test + fun MangaTitleCaseBase() { createManga("Solanin") createChapter("Solanin 028 Vol. 2") @@ -162,7 +171,8 @@ class ChapterRecognitionTest { /** * Chapter containing manga title and number decimal case */ - @Test fun MangaTitleCaseDecimal() { + @Test + fun MangaTitleCaseDecimal() { createManga("Solanin") createChapter("Solanin 028.1 Vol. 2") @@ -177,7 +187,8 @@ class ChapterRecognitionTest { /** * Chapter containing manga title and number alpha case */ - @Test fun MangaTitleCaseAlpha() { + @Test + fun MangaTitleCaseAlpha() { createManga("Solanin") createChapter("Solanin 028.a Vol. 2") @@ -196,7 +207,8 @@ class ChapterRecognitionTest { /** * Extreme base case */ - @Test fun ExtremeCaseBase() { + @Test + fun ExtremeCaseBase() { createManga("Onepunch-Man") createChapter("Onepunch-Man Punch Ver002 028") @@ -207,7 +219,8 @@ class ChapterRecognitionTest { /** * Extreme base case decimal */ - @Test fun ExtremeCaseDecimal() { + @Test + fun ExtremeCaseDecimal() { createManga("Onepunch-Man") createChapter("Onepunch-Man Punch Ver002 028.1") @@ -222,7 +235,8 @@ class ChapterRecognitionTest { /** * Extreme base case alpha */ - @Test fun ExtremeCaseAlpha() { + @Test + fun ExtremeCaseAlpha() { createManga("Onepunch-Man") createChapter("Onepunch-Man Punch Ver002 028.a") @@ -241,7 +255,8 @@ class ChapterRecognitionTest { /** * Chapter containing .v2 */ - @Test fun dotV2Case() { + @Test + fun dotV2Case() { createChapter("Vol.1 Ch.5v.2: Alones") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(5f) @@ -250,7 +265,8 @@ class ChapterRecognitionTest { /** * Check for case with number in manga title */ - @Test fun numberInMangaTitleCase() { + @Test + fun numberInMangaTitleCase() { createManga("Ayame 14") createChapter("Ayame 14 1 - The summer of 14") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -260,7 +276,8 @@ class ChapterRecognitionTest { /** * Case with space between ch. x */ - @Test fun spaceAfterChapterCase() { + @Test + fun spaceAfterChapterCase() { createManga("Mokushiroku Alice") createChapter("Mokushiroku Alice Vol.1 Ch. 4: Misrepresentation") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -270,7 +287,8 @@ class ChapterRecognitionTest { /** * Chapter containing mar(ch) */ - @Test fun marchInChapterCase() { + @Test + fun marchInChapterCase() { createManga("Ayame 14") createChapter("Vol.1 Ch.1: March 25 (First Day Cohabiting)") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -280,7 +298,8 @@ class ChapterRecognitionTest { /** * Chapter containing range */ - @Test fun rangeInChapterCase() { + @Test + fun rangeInChapterCase() { createChapter("Ch.191-200 Read Online") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(191f) @@ -289,7 +308,8 @@ class ChapterRecognitionTest { /** * Chapter containing multiple zeros */ - @Test fun multipleZerosCase() { + @Test + fun multipleZerosCase() { createChapter("Vol.001 Ch.003: Kaguya Doesn't Know Much") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(3f) @@ -298,7 +318,8 @@ class ChapterRecognitionTest { /** * Chapter with version before number */ - @Test fun chapterBeforeNumberCase() { + @Test + fun chapterBeforeNumberCase() { createManga("Onepunch-Man") createChapter("Onepunch-Man Punch Ver002 086 : Creeping Darkness [3]") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -308,7 +329,8 @@ class ChapterRecognitionTest { /** * Case with version attached to chapter number */ - @Test fun vAttachedToChapterCase() { + @Test + fun vAttachedToChapterCase() { createManga("Ansatsu Kyoushitsu") createChapter("Ansatsu Kyoushitsu 011v002: Assembly Time") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -319,7 +341,8 @@ class ChapterRecognitionTest { * Case where the chapter title contains the chapter * But wait it's not actual the chapter number. */ - @Test fun NumberAfterMangaTitleWithChapterInChapterTitleCase() { + @Test + fun NumberAfterMangaTitleWithChapterInChapterTitleCase() { createChapter("Tokyo ESP 027: Part 002: Chapter 001") createManga("Tokyo ESP") ChapterRecognition.parseChapterNumber(chapter, manga) @@ -329,7 +352,8 @@ class ChapterRecognitionTest { /** * unParsable chapter */ - @Test fun unParsableCase() { + @Test + fun unParsableCase() { createChapter("Foo") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(-1f) @@ -338,7 +362,8 @@ class ChapterRecognitionTest { /** * chapter with time in title */ - @Test fun timeChapterCase() { + @Test + fun timeChapterCase() { createChapter("Fairy Tail 404: 00:00") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(404f) @@ -347,7 +372,8 @@ class ChapterRecognitionTest { /** * chapter with alpha without dot */ - @Test fun alphaWithoutDotCase() { + @Test + fun alphaWithoutDotCase() { createChapter("Asu No Yoichi 19a") ChapterRecognition.parseChapterNumber(chapter, manga) assertThat(chapter.chapter_number).isEqualTo(19.1f) @@ -356,7 +382,8 @@ class ChapterRecognitionTest { /** * Chapter title containing extra and vol */ - @Test fun chapterContainingExtraCase() { + @Test + fun chapterContainingExtraCase() { createManga("Fairy Tail") createChapter("Fairy Tail 404.extravol002") @@ -375,7 +402,8 @@ class ChapterRecognitionTest { /** * Chapter title containing omake (japanese extra) and vol */ - @Test fun chapterContainingOmakeCase() { + @Test + fun chapterContainingOmakeCase() { createManga("Fairy Tail") createChapter("Fairy Tail 404.omakevol002") @@ -394,7 +422,8 @@ class ChapterRecognitionTest { /** * Chapter title containing special and vol */ - @Test fun chapterContainingSpecialCase() { + @Test + fun chapterContainingSpecialCase() { createManga("Fairy Tail") createChapter("Fairy Tail 404.specialvol002") @@ -413,7 +442,8 @@ class ChapterRecognitionTest { /** * Chapter title containing comma's */ - @Test fun chapterContainingCommasCase() { + @Test + fun chapterContainingCommasCase() { createManga("One Piece") createChapter("One Piece 300,a") @@ -432,7 +462,8 @@ class ChapterRecognitionTest { /** * Test for chapters containing season */ - @Test fun chapterContainingSeasonCase() { + @Test + fun chapterContainingSeasonCase() { createManga("D.I.C.E") createChapter("D.I.C.E[Season 001] Ep. 007") @@ -444,7 +475,8 @@ class ChapterRecognitionTest { /** * Test for chapters in format sx - chapter xx */ - @Test fun chapterContainingSeasonCase2() { + @Test + fun chapterContainingSeasonCase2() { createManga("The Gamer") createChapter("S3 - Chapter 20") @@ -455,7 +487,8 @@ class ChapterRecognitionTest { /** * Test for chapters ending with s */ - @Test fun chaptersEndingWithS() { + @Test + fun chaptersEndingWithS() { createManga("One Outs") createChapter("One Outs 001") diff --git a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt b/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt index a86e1f6446..bfd87f5af0 100644 --- a/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt +++ b/app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateServiceTest.kt @@ -26,7 +26,7 @@ import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.InjektModule import uy.kohesive.injekt.api.InjektRegistrar import uy.kohesive.injekt.api.addSingleton -import java.util.* +import java.util.ArrayList @Config(constants = BuildConfig::class, sdk = intArrayOf(Build.VERSION_CODES.LOLLIPOP)) @RunWith(CustomRobolectricGradleTestRunner::class) From 427d2fed8cced3be89a2d0c1520f4fc12fb6452a Mon Sep 17 00:00:00 2001 From: mutsumi <4182301+mutsumi63@users.noreply.github.com> Date: Sun, 12 Jan 2020 11:05:03 +0800 Subject: [PATCH 17/24] fix bangumi track will override record to 0 after every track search(bind) (#2486) * fix bangumi track : the update status api must be called before update chapter api * fix bangumi track will override record to 0 after every track search(bind) --- .../java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt | 2 +- .../java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 9638d40d15..39c204c8e9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -41,7 +41,7 @@ class Bangumi(private val context: Context, id: Int) : TrackService(id) { track.library_id = remoteTrack.library_id track.status = remoteTrack.status track.last_chapter_read = remoteTrack.last_chapter_read - update(track) + refresh(track) } else { // Set default fields if it's not found in the list track.score = DEFAULT_SCORE.toFloat() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt index 7180156aa3..ef8314e118 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt @@ -59,12 +59,12 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept .url("$apiUrl/collection/${track.media_id}/update") .post(sbody) .build() - return authClient.newCall(request) + return authClient.newCall(srequest) .asObservableSuccess() .map { track }.flatMap { - authClient.newCall(srequest) + authClient.newCall(request) .asObservableSuccess() .map { track From 44f406b4b9f46a0f5dfce69aec9d883ce7b1bee3 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:06:23 -0500 Subject: [PATCH 18/24] Fix Bangumi class formatting --- .../tachiyomi/data/track/bangumi/Avatar.kt | 8 +- .../tachiyomi/data/track/bangumi/Bangumi.kt | 230 ++++++------ .../data/track/bangumi/BangumiApi.kt | 354 +++++++++--------- .../data/track/bangumi/BangumiInterceptor.kt | 90 ++--- .../data/track/bangumi/BangumiModels.kt | 24 +- .../data/track/bangumi/Collection.kt | 20 +- .../tachiyomi/data/track/bangumi/OAuth.kt | 16 +- .../tachiyomi/data/track/bangumi/Status.kt | 8 +- .../tachiyomi/data/track/bangumi/User.kt | 16 +- 9 files changed, 383 insertions(+), 383 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt index 02e0b2efbb..d058a85f59 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Avatar.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Avatar( - val large: String? = "", - val medium: String? = "", - val small: String? = "" -) \ No newline at end of file + val large: String? = "", + val medium: String? = "", + val small: String? = "" +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt index 39c204c8e9..147dde6de6 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Bangumi.kt @@ -13,132 +13,132 @@ import uy.kohesive.injekt.injectLazy class Bangumi(private val context: Context, id: Int) : TrackService(id) { - override fun getScoreList(): List { - return IntRange(0, 10).map(Int::toString) - } + override val name = "Bangumi" - override fun displayScore(track: Track): String { - return track.score.toInt().toString() - } + private val gson: Gson by injectLazy() - override fun add(track: Track): Observable { - return api.addLibManga(track) - } + private val interceptor by lazy { BangumiInterceptor(this, gson) } - override fun update(track: Track): Observable { - if (track.total_chapters != 0 && track.last_chapter_read == track.total_chapters) { - track.status = COMPLETED + private val api by lazy { BangumiApi(client, interceptor) } + + override fun getScoreList(): List { + return IntRange(0, 10).map(Int::toString) } - return api.updateLibManga(track) - } - override fun bind(track: Track): Observable { - return api.statusLibManga(track) - .flatMap { - api.findLibManga(track).flatMap { remoteTrack -> - if (remoteTrack != null && it != null) { - track.copyPersonalFrom(remoteTrack) - track.library_id = remoteTrack.library_id - track.status = remoteTrack.status - track.last_chapter_read = remoteTrack.last_chapter_read - refresh(track) - } else { - // Set default fields if it's not found in the list - track.score = DEFAULT_SCORE.toFloat() - track.status = DEFAULT_STATUS - add(track) - update(track) - } + override fun displayScore(track: Track): String { + return track.score.toInt().toString() + } + + override fun add(track: Track): Observable { + return api.addLibManga(track) + } + + override fun update(track: Track): Observable { + if (track.total_chapters != 0 && track.last_chapter_read == track.total_chapters) { + track.status = COMPLETED } - } - } + return api.updateLibManga(track) + } - override fun search(query: String): Observable> { - return api.search(query) - } + override fun bind(track: Track): Observable { + return api.statusLibManga(track) + .flatMap { + api.findLibManga(track).flatMap { remoteTrack -> + if (remoteTrack != null && it != null) { + track.copyPersonalFrom(remoteTrack) + track.library_id = remoteTrack.library_id + track.status = remoteTrack.status + track.last_chapter_read = remoteTrack.last_chapter_read + refresh(track) + } else { + // Set default fields if it's not found in the list + track.score = DEFAULT_SCORE.toFloat() + track.status = DEFAULT_STATUS + add(track) + update(track) + } + } + } + } - override fun refresh(track: Track): Observable { - return api.statusLibManga(track) - .flatMap { - track.copyPersonalFrom(it!!) - api.findLibManga(track) - .map { remoteTrack -> - if (remoteTrack != null) { - track.total_chapters = remoteTrack.total_chapters - track.status = remoteTrack.status + override fun search(query: String): Observable> { + return api.search(query) + } + + override fun refresh(track: Track): Observable { + return api.statusLibManga(track) + .flatMap { + track.copyPersonalFrom(it!!) + api.findLibManga(track) + .map { remoteTrack -> + if (remoteTrack != null) { + track.total_chapters = remoteTrack.total_chapters + track.status = remoteTrack.status + } + track + } + } + } + + override fun getLogo() = R.drawable.tracker_bangumi + + override fun getLogoColor() = Color.rgb(0xF0, 0x91, 0x99) + + override fun getStatusList(): List { + return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLANNING) + } + + override fun getStatus(status: Int): String = with(context) { + when (status) { + READING -> getString(R.string.reading) + COMPLETED -> getString(R.string.completed) + ON_HOLD -> getString(R.string.on_hold) + DROPPED -> getString(R.string.dropped) + PLANNING -> getString(R.string.plan_to_read) + else -> "" + } + } + + override fun login(username: String, password: String) = login(password) + + fun login(code: String): Completable { + return api.accessToken(code).map { oauth: OAuth? -> + interceptor.newAuth(oauth) + if (oauth != null) { + saveCredentials(oauth.user_id.toString(), oauth.access_token) } - track - } - } - } - - companion object { - const val READING = 3 - const val COMPLETED = 2 - const val ON_HOLD = 4 - const val DROPPED = 5 - const val PLANNING = 1 - - const val DEFAULT_STATUS = READING - const val DEFAULT_SCORE = 0 - } - - override val name = "Bangumi" - - private val gson: Gson by injectLazy() - - private val interceptor by lazy { BangumiInterceptor(this, gson) } - - private val api by lazy { BangumiApi(client, interceptor) } - - override fun getLogo() = R.drawable.tracker_bangumi - - override fun getLogoColor() = Color.rgb(0xF0, 0x91, 0x99) - - override fun getStatusList(): List { - return listOf(READING, COMPLETED, ON_HOLD, DROPPED, PLANNING) - } - - override fun getStatus(status: Int): String = with(context) { - when (status) { - READING -> getString(R.string.reading) - COMPLETED -> getString(R.string.completed) - ON_HOLD -> getString(R.string.on_hold) - DROPPED -> getString(R.string.dropped) - PLANNING -> getString(R.string.plan_to_read) - else -> "" + }.doOnError { + logout() + }.toCompletable() } - } - override fun login(username: String, password: String) = login(password) - - fun login(code: String): Completable { - return api.accessToken(code).map { oauth: OAuth? -> - interceptor.newAuth(oauth) - if (oauth != null) { - saveCredentials(oauth.user_id.toString(), oauth.access_token) - } - }.doOnError { - logout() - }.toCompletable() - } - - fun saveToken(oauth: OAuth?) { - val json = gson.toJson(oauth) - preferences.trackToken(this).set(json) - } - - fun restoreToken(): OAuth? { - return try { - gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) - } catch (e: Exception) { - null + fun saveToken(oauth: OAuth?) { + val json = gson.toJson(oauth) + preferences.trackToken(this).set(json) } - } - override fun logout() { - super.logout() - preferences.trackToken(this).set(null) - interceptor.newAuth(null) - } + fun restoreToken(): OAuth? { + return try { + gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) + } catch (e: Exception) { + null + } + } + + override fun logout() { + super.logout() + preferences.trackToken(this).set(null) + interceptor.newAuth(null) + } + + companion object { + const val READING = 3 + const val COMPLETED = 2 + const val ON_HOLD = 4 + const val DROPPED = 5 + const val PLANNING = 1 + + const val DEFAULT_STATUS = READING + const val DEFAULT_SCORE = 0 + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt index ef8314e118..3b356f6533 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt @@ -21,191 +21,191 @@ import java.net.URLEncoder class BangumiApi(private val client: OkHttpClient, interceptor: BangumiInterceptor) { - private val gson: Gson by injectLazy() - private val parser = JsonParser() - private val authClient = client.newBuilder().addInterceptor(interceptor).build() + private val gson: Gson by injectLazy() + private val parser = JsonParser() + private val authClient = client.newBuilder().addInterceptor(interceptor).build() - fun addLibManga(track: Track): Observable { - val body = FormBody.Builder() - .add("rating", track.score.toInt().toString()) - .add("status", track.toBangumiStatus()) - .build() - val request = Request.Builder() - .url("$apiUrl/collection/${track.media_id}/update") - .post(body) - .build() - return authClient.newCall(request) - .asObservableSuccess() - .map { - track - } - } + fun addLibManga(track: Track): Observable { + val body = FormBody.Builder() + .add("rating", track.score.toInt().toString()) + .add("status", track.toBangumiStatus()) + .build() + val request = Request.Builder() + .url("$apiUrl/collection/${track.media_id}/update") + .post(body) + .build() + return authClient.newCall(request) + .asObservableSuccess() + .map { + track + } + } - fun updateLibManga(track: Track): Observable { - // chapter update - val body = FormBody.Builder() - .add("watched_eps", track.last_chapter_read.toString()) - .build() - val request = Request.Builder() - .url("$apiUrl/subject/${track.media_id}/update/watched_eps") - .post(body) - .build() + fun updateLibManga(track: Track): Observable { + // chapter update + val body = FormBody.Builder() + .add("watched_eps", track.last_chapter_read.toString()) + .build() + val request = Request.Builder() + .url("$apiUrl/subject/${track.media_id}/update/watched_eps") + .post(body) + .build() - // read status update - val sbody = FormBody.Builder() - .add("status", track.toBangumiStatus()) - .build() - val srequest = Request.Builder() - .url("$apiUrl/collection/${track.media_id}/update") - .post(sbody) - .build() - return authClient.newCall(srequest) - .asObservableSuccess() - .map { - track - }.flatMap { - authClient.newCall(request) - .asObservableSuccess() - .map { - track - } - } - } + // read status update + val sbody = FormBody.Builder() + .add("status", track.toBangumiStatus()) + .build() + val srequest = Request.Builder() + .url("$apiUrl/collection/${track.media_id}/update") + .post(sbody) + .build() + return authClient.newCall(srequest) + .asObservableSuccess() + .map { + track + }.flatMap { + authClient.newCall(request) + .asObservableSuccess() + .map { + track + } + } + } - fun search(search: String): Observable> { - val url = Uri.parse( - "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}").buildUpon() - .appendQueryParameter("max_results", "20") - .build() - val request = Request.Builder() - .url(url.toString()) - .get() - .build() - return authClient.newCall(request) - .asObservableSuccess() - .map { netResponse -> - var responseBody = netResponse.body?.string().orEmpty() - if (responseBody.isEmpty()) { - throw Exception("Null Response") + fun search(search: String): Observable> { + val url = Uri.parse( + "$apiUrl/search/subject/${URLEncoder.encode(search, Charsets.UTF_8.name())}").buildUpon() + .appendQueryParameter("max_results", "20") + .build() + val request = Request.Builder() + .url(url.toString()) + .get() + .build() + return authClient.newCall(request) + .asObservableSuccess() + .map { netResponse -> + var responseBody = netResponse.body?.string().orEmpty() + if (responseBody.isEmpty()) { + throw Exception("Null Response") + } + if (responseBody.contains("\"code\":404")) { + responseBody = "{\"results\":0,\"list\":[]}" + } + val response = parser.parse(responseBody).obj["list"]?.array + response?.filter { it.obj["type"].asInt == 1 }?.map { jsonToSearch(it.obj) } + } + + } + + private fun jsonToSearch(obj: JsonObject): TrackSearch { + return TrackSearch.create(TrackManager.BANGUMI).apply { + media_id = obj["id"].asInt + title = obj["name_cn"].asString + cover_url = obj["images"].obj["common"].asString + summary = obj["name"].asString + tracking_url = obj["url"].asString } - if(responseBody.contains("\"code\":404")){ - responseBody = "{\"results\":0,\"list\":[]}" + } + + private fun jsonToTrack(mangas: JsonObject): Track { + return Track.create(TrackManager.BANGUMI).apply { + title = mangas["name"].asString + media_id = mangas["id"].asInt + score = if (mangas["rating"] != null) + (if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f) + else 0f + status = Bangumi.DEFAULT_STATUS + tracking_url = mangas["url"].asString } - val response = parser.parse(responseBody).obj["list"]?.array - response?.filter { it.obj["type"].asInt == 1 }?.map { jsonToSearch(it.obj) } - } - - } - - private fun jsonToSearch(obj: JsonObject): TrackSearch { - return TrackSearch.create(TrackManager.BANGUMI).apply { - media_id = obj["id"].asInt - title = obj["name_cn"].asString - cover_url = obj["images"].obj["common"].asString - summary = obj["name"].asString - tracking_url = obj["url"].asString - } - } - - private fun jsonToTrack(mangas: JsonObject): Track { - return Track.create(TrackManager.BANGUMI).apply { - title = mangas["name"].asString - media_id = mangas["id"].asInt - score = if (mangas["rating"] != null) - (if (mangas["rating"].isJsonObject) mangas["rating"].obj["score"].asFloat else 0f) - else 0f - status = Bangumi.DEFAULT_STATUS - tracking_url = mangas["url"].asString - } - } - - fun findLibManga(track: Track): Observable { - val urlMangas = "$apiUrl/subject/${track.media_id}" - val requestMangas = Request.Builder() - .url(urlMangas) - .get() - .build() - - return authClient.newCall(requestMangas) - .asObservableSuccess() - .map { netResponse -> - // get comic info - val responseBody = netResponse.body?.string().orEmpty() - jsonToTrack(parser.parse(responseBody).obj) - } - } - - fun statusLibManga(track: Track): Observable { - val urlUserRead = "$apiUrl/collection/${track.media_id}" - val requestUserRead = Request.Builder() - .url(urlUserRead) - .cacheControl(CacheControl.FORCE_NETWORK) - .get() - .build() - - // todo get user readed chapter here - return authClient.newCall(requestUserRead) - .asObservableSuccess() - .map { netResponse -> - val resp = netResponse.body?.string() - val coll = gson.fromJson(resp, Collection::class.java) - track.status = coll.status?.id!! - track.last_chapter_read = coll.ep_status!! - track - } - } - - fun accessToken(code: String): Observable { - return client.newCall(accessTokenRequest(code)).asObservableSuccess().map { netResponse -> - val responseBody = netResponse.body?.string().orEmpty() - if (responseBody.isEmpty()) { - throw Exception("Null Response") - } - gson.fromJson(responseBody, OAuth::class.java) - } - } - - private fun accessTokenRequest(code: String) = POST(oauthUrl, - body = FormBody.Builder() - .add("grant_type", "authorization_code") - .add("client_id", clientId) - .add("client_secret", clientSecret) - .add("code", code) - .add("redirect_uri", redirectUrl) - .build() - ) - - companion object { - private const val clientId = "bgm10555cda0762e80ca" - private const val clientSecret = "8fff394a8627b4c388cbf349ec865775" - - private const val baseUrl = "https://bangumi.org" - private const val apiUrl = "https://api.bgm.tv" - private const val oauthUrl = "https://bgm.tv/oauth/access_token" - private const val loginUrl = "https://bgm.tv/oauth/authorize" - - private const val redirectUrl = "tachiyomi://bangumi-auth" - private const val baseMangaUrl = "$apiUrl/mangas" - - fun mangaUrl(remoteId: Int): String { - return "$baseMangaUrl/$remoteId" } - fun authUrl() = - Uri.parse(loginUrl).buildUpon() - .appendQueryParameter("client_id", clientId) - .appendQueryParameter("response_type", "code") - .appendQueryParameter("redirect_uri", redirectUrl) - .build() + fun findLibManga(track: Track): Observable { + val urlMangas = "$apiUrl/subject/${track.media_id}" + val requestMangas = Request.Builder() + .url(urlMangas) + .get() + .build() - fun refreshTokenRequest(token: String) = POST(oauthUrl, - body = FormBody.Builder() - .add("grant_type", "refresh_token") - .add("client_id", clientId) - .add("client_secret", clientSecret) - .add("refresh_token", token) - .add("redirect_uri", redirectUrl) - .build()) - } + return authClient.newCall(requestMangas) + .asObservableSuccess() + .map { netResponse -> + // get comic info + val responseBody = netResponse.body?.string().orEmpty() + jsonToTrack(parser.parse(responseBody).obj) + } + } + + fun statusLibManga(track: Track): Observable { + val urlUserRead = "$apiUrl/collection/${track.media_id}" + val requestUserRead = Request.Builder() + .url(urlUserRead) + .cacheControl(CacheControl.FORCE_NETWORK) + .get() + .build() + + // todo get user readed chapter here + return authClient.newCall(requestUserRead) + .asObservableSuccess() + .map { netResponse -> + val resp = netResponse.body?.string() + val coll = gson.fromJson(resp, Collection::class.java) + track.status = coll.status?.id!! + track.last_chapter_read = coll.ep_status!! + track + } + } + + fun accessToken(code: String): Observable { + return client.newCall(accessTokenRequest(code)).asObservableSuccess().map { netResponse -> + val responseBody = netResponse.body?.string().orEmpty() + if (responseBody.isEmpty()) { + throw Exception("Null Response") + } + gson.fromJson(responseBody, OAuth::class.java) + } + } + + private fun accessTokenRequest(code: String) = POST(oauthUrl, + body = FormBody.Builder() + .add("grant_type", "authorization_code") + .add("client_id", clientId) + .add("client_secret", clientSecret) + .add("code", code) + .add("redirect_uri", redirectUrl) + .build() + ) + + companion object { + private const val clientId = "bgm10555cda0762e80ca" + private const val clientSecret = "8fff394a8627b4c388cbf349ec865775" + + private const val baseUrl = "https://bangumi.org" + private const val apiUrl = "https://api.bgm.tv" + private const val oauthUrl = "https://bgm.tv/oauth/access_token" + private const val loginUrl = "https://bgm.tv/oauth/authorize" + + private const val redirectUrl = "tachiyomi://bangumi-auth" + private const val baseMangaUrl = "$apiUrl/mangas" + + fun mangaUrl(remoteId: Int): String { + return "$baseMangaUrl/$remoteId" + } + + fun authUrl() = + Uri.parse(loginUrl).buildUpon() + .appendQueryParameter("client_id", clientId) + .appendQueryParameter("response_type", "code") + .appendQueryParameter("redirect_uri", redirectUrl) + .build() + + fun refreshTokenRequest(token: String) = POST(oauthUrl, + body = FormBody.Builder() + .add("grant_type", "refresh_token") + .add("client_id", clientId) + .add("client_secret", clientSecret) + .add("refresh_token", token) + .add("redirect_uri", redirectUrl) + .build()) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt index d51c6d7862..add168201e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiInterceptor.kt @@ -7,55 +7,55 @@ import okhttp3.Response class BangumiInterceptor(val bangumi: Bangumi, val gson: Gson) : Interceptor { - /** - * OAuth object used for authenticated requests. - */ - private var oauth: OAuth? = bangumi.restoreToken() + /** + * OAuth object used for authenticated requests. + */ + private var oauth: OAuth? = bangumi.restoreToken() - fun addTocken(tocken: String, oidFormBody: FormBody): FormBody { - val newFormBody = FormBody.Builder() - for (i in 0 until oidFormBody.size) { - newFormBody.add(oidFormBody.name(i), oidFormBody.value(i)) - } - newFormBody.add("access_token", tocken) - return newFormBody.build() - } - - override fun intercept(chain: Interceptor.Chain): Response { - val originalRequest = chain.request() - - val currAuth = oauth ?: throw Exception("Not authenticated with Bangumi") - - if (currAuth.isExpired()) { - val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!)) - if (response.isSuccessful) { - newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java)) - } else { - response.close() - } + fun addTocken(tocken: String, oidFormBody: FormBody): FormBody { + val newFormBody = FormBody.Builder() + for (i in 0 until oidFormBody.size) { + newFormBody.add(oidFormBody.name(i), oidFormBody.value(i)) + } + newFormBody.add("access_token", tocken) + return newFormBody.build() } - val authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder() - .header("User-Agent", "Tachiyomi") - .url(originalRequest.url.newBuilder() - .addQueryParameter("access_token", currAuth.access_token).build()) - .build() else originalRequest.newBuilder() - .post(addTocken(currAuth.access_token, originalRequest.body as FormBody)) - .header("User-Agent", "Tachiyomi") - .build() + override fun intercept(chain: Interceptor.Chain): Response { + val originalRequest = chain.request() - return chain.proceed(authRequest) - } + val currAuth = oauth ?: throw Exception("Not authenticated with Bangumi") - fun newAuth(oauth: OAuth?) { - this.oauth = if (oauth == null) null else OAuth( - oauth.access_token, - oauth.token_type, - System.currentTimeMillis() / 1000, - oauth.expires_in, - oauth.refresh_token, - this.oauth?.user_id) + if (currAuth.isExpired()) { + val response = chain.proceed(BangumiApi.refreshTokenRequest(currAuth.refresh_token!!)) + if (response.isSuccessful) { + newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java)) + } else { + response.close() + } + } - bangumi.saveToken(oauth) - } + val authRequest = if (originalRequest.method == "GET") originalRequest.newBuilder() + .header("User-Agent", "Tachiyomi") + .url(originalRequest.url.newBuilder() + .addQueryParameter("access_token", currAuth.access_token).build()) + .build() else originalRequest.newBuilder() + .post(addTocken(currAuth.access_token, originalRequest.body as FormBody)) + .header("User-Agent", "Tachiyomi") + .build() + + return chain.proceed(authRequest) + } + + fun newAuth(oauth: OAuth?) { + this.oauth = if (oauth == null) null else OAuth( + oauth.access_token, + oauth.token_type, + System.currentTimeMillis() / 1000, + oauth.expires_in, + oauth.refresh_token, + this.oauth?.user_id) + + bangumi.saveToken(oauth) + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt index 83b9ce3054..0b02f2b2ff 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiModels.kt @@ -3,20 +3,20 @@ package eu.kanade.tachiyomi.data.track.bangumi import eu.kanade.tachiyomi.data.database.models.Track fun Track.toBangumiStatus() = when (status) { - Bangumi.READING -> "do" - Bangumi.COMPLETED -> "collect" - Bangumi.ON_HOLD -> "on_hold" - Bangumi.DROPPED -> "dropped" - Bangumi.PLANNING -> "wish" - else -> throw NotImplementedError("Unknown status") + Bangumi.READING -> "do" + Bangumi.COMPLETED -> "collect" + Bangumi.ON_HOLD -> "on_hold" + Bangumi.DROPPED -> "dropped" + Bangumi.PLANNING -> "wish" + else -> throw NotImplementedError("Unknown status") } fun toTrackStatus(status: String) = when (status) { - "do" -> Bangumi.READING - "collect" -> Bangumi.COMPLETED - "on_hold" -> Bangumi.ON_HOLD - "dropped" -> Bangumi.DROPPED - "wish" -> Bangumi.PLANNING + "do" -> Bangumi.READING + "collect" -> Bangumi.COMPLETED + "on_hold" -> Bangumi.ON_HOLD + "dropped" -> Bangumi.DROPPED + "wish" -> Bangumi.PLANNING - else -> throw Exception("Unknown status") + else -> throw Exception("Unknown status") } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt index 732676bf31..03143d19f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Collection.kt @@ -1,13 +1,13 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Collection( - val `private`: Int? = 0, - val comment: String? = "", - val ep_status: Int? = 0, - val lasttouch: Int? = 0, - val rating: Int? = 0, - val status: Status? = Status(), - val tag: List? = listOf(), - val user: User? = User(), - val vol_status: Int? = 0 -) \ No newline at end of file + val `private`: Int? = 0, + val comment: String? = "", + val ep_status: Int? = 0, + val lasttouch: Int? = 0, + val rating: Int? = 0, + val status: Status? = Status(), + val tag: List? = listOf(), + val user: User? = User(), + val vol_status: Int? = 0 +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt index b46276d167..811d0fd459 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/OAuth.kt @@ -1,16 +1,16 @@ package eu.kanade.tachiyomi.data.track.bangumi data class OAuth( - val access_token: String, - val token_type: String, - val created_at: Long, - val expires_in: Long, - val refresh_token: String?, - val user_id: Long? + val access_token: String, + val token_type: String, + val created_at: Long, + val expires_in: Long, + val refresh_token: String?, + val user_id: Long? ) { - // Access token refresh before expired - fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600) + // Access token refresh before expired + fun isExpired() = (System.currentTimeMillis() / 1000) > (created_at + expires_in - 3600) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt index 78e22e882c..3d2ea3c14b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/Status.kt @@ -1,7 +1,7 @@ package eu.kanade.tachiyomi.data.track.bangumi data class Status( - val id: Int? = 0, - val name: String? = "", - val type: String? = "" -) \ No newline at end of file + val id: Int? = 0, + val name: String? = "", + val type: String? = "" +) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt index 808e4860a6..9e82f533e3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/User.kt @@ -1,11 +1,11 @@ package eu.kanade.tachiyomi.data.track.bangumi data class User( - val avatar: Avatar? = Avatar(), - val id: Int? = 0, - val nickname: String? = "", - val sign: String? = "", - val url: String? = "", - val usergroup: Int? = 0, - val username: String? = "" -) \ No newline at end of file + val avatar: Avatar? = Avatar(), + val id: Int? = 0, + val nickname: String? = "", + val sign: String? = "", + val url: String? = "", + val usergroup: Int? = 0, + val username: String? = "" +) From d4c25359bda6b081d1c8d185a8b4a886cab92d74 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:13:46 -0500 Subject: [PATCH 19/24] Remove clickable attributes from unclickable text in reader --- app/src/main/res/layout/reader_activity.xml | 31 ++++++++++----------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index 2a1ea590d1..b2af47123b 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -1,8 +1,8 @@ - + android:layout_height="match_parent" /> + tools:visibility="visible" /> + android:descendantFocusability="blocksDescendants" + android:gravity="center" + android:orientation="horizontal"> + android:padding="@dimen/material_layout_keylines_screen_edge_margin" + app:srcCompat="@drawable/ic_skip_previous_white_24dp" /> + tools:text="1" /> + tools:text="15" /> + android:padding="@dimen/material_layout_keylines_screen_edge_margin" + app:srcCompat="@drawable/ic_skip_next_white_24dp" /> @@ -109,12 +106,12 @@ android:id="@+id/brightness_overlay" android:layout_width="match_parent" android:layout_height="match_parent" - android:visibility="gone"/> + android:visibility="gone" /> + android:visibility="gone" /> From 885c7bbb103dde6ca6b1b47cfefc6b9ea5ea231c Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:14:02 -0500 Subject: [PATCH 20/24] Add descriptions to reader prev/next buttons for a11y --- app/src/main/res/layout/reader_activity.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index b2af47123b..54933da704 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -65,6 +65,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="?selectableItemBackgroundBorderless" + android:contentDescription="@string/action_previous_chapter" android:padding="@dimen/material_layout_keylines_screen_edge_margin" app:srcCompat="@drawable/ic_skip_previous_white_24dp" /> @@ -95,6 +96,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="?selectableItemBackgroundBorderless" + android:contentDescription="@string/action_next_chapter" android:padding="@dimen/material_layout_keylines_screen_edge_margin" app:srcCompat="@drawable/ic_skip_next_white_24dp" /> From 81418a7712a4261b2b1cb68d0af2a5c20a361be2 Mon Sep 17 00:00:00 2001 From: arkon Date: Sat, 11 Jan 2020 22:29:31 -0500 Subject: [PATCH 21/24] Tweak reader seekbar height for Android 5 UI bug (closes #2487) --- app/src/main/res/layout/reader_activity.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/reader_activity.xml b/app/src/main/res/layout/reader_activity.xml index 54933da704..aa0968f54f 100644 --- a/app/src/main/res/layout/reader_activity.xml +++ b/app/src/main/res/layout/reader_activity.xml @@ -77,10 +77,16 @@ android:textSize="15sp" tools:text="1" /> + Date: Sun, 12 Jan 2020 11:47:26 -0500 Subject: [PATCH 22/24] Restore transparent status bars, allow WebView app bar to scroll away --- .../tachiyomi/ui/webview/WebViewActivity.kt | 5 +++++ app/src/main/res/layout/webview_activity.xml | 20 +++++++++++++------ app/src/main/res/values/themes.xml | 6 +++--- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt index c3f394e1c9..9ea7cfb375 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/webview/WebViewActivity.kt @@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.ui.base.activity.BaseActivity import eu.kanade.tachiyomi.util.WebViewClientCompat +import eu.kanade.tachiyomi.util.getResourceColor import kotlinx.android.synthetic.main.webview_activity.toolbar import kotlinx.android.synthetic.main.webview_activity.webview import uy.kohesive.injekt.injectLazy @@ -29,6 +30,10 @@ class WebViewActivity : BaseActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.webview_activity) + // Manually override status bar color since it's normally transparent with the app themes + // This is needed to hide the app bar when it scrolls up + window.statusBarColor = getResourceColor(R.attr.colorPrimaryDark) + title = intent.extras?.getString(TITLE_KEY) setSupportActionBar(toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) diff --git a/app/src/main/res/layout/webview_activity.xml b/app/src/main/res/layout/webview_activity.xml index 2144da73e6..972db4d692 100644 --- a/app/src/main/res/layout/webview_activity.xml +++ b/app/src/main/res/layout/webview_activity.xml @@ -1,5 +1,5 @@ - + app:navigationIcon="@drawable/ic_close_white_24dp" + app:layout_scrollFlags="scroll|enterAlways|snap" /> - + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - + + + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 135af42819..3f3c35a4be 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -44,7 +44,7 @@ @@ -67,7 +67,7 @@ @drawable/line_divider_dark true - @color/colorDarkPrimaryDark + @android:color/transparent @color/colorDarkPrimaryDark @@ -97,7 +97,7 @@ @color/colorPrimaryDark true - @color/colorPrimaryDark + @android:color/transparent @color/colorDarkPrimaryDark From 6b5742c1ffabcce6251e3b452b638758d2e747e0 Mon Sep 17 00:00:00 2001 From: MCAxiaz Date: Sun, 12 Jan 2020 12:02:21 -0800 Subject: [PATCH 23/24] Fix catalogue search focus automatically being removed (#2396) Fix catalogue search focus automatically being removed --- .../tachiyomi/ui/base/controller/BaseController.kt | 7 ++++--- .../catalogue/browse/BrowseCatalogueController.kt | 14 +++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt index 292bf2e326..860c4d5908 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/controller/BaseController.kt @@ -89,15 +89,16 @@ abstract class BaseController(bundle: Bundle? = null) : RestoreViewOnCreateContr * This method should be removed when fixed upstream. * Issue link: https://issuetracker.google.com/issues/37657375 */ - fun MenuItem.fixExpand() { + fun MenuItem.fixExpand(onExpand: ((MenuItem) -> Boolean)? = null, onCollapse: ((MenuItem) -> Boolean)? = null) { setOnActionExpandListener(object : MenuItem.OnActionExpandListener { override fun onMenuItemActionExpand(item: MenuItem): Boolean { - return true + return onExpand?.invoke(item) ?: true } override fun onMenuItemActionCollapse(item: MenuItem): Boolean { activity?.invalidateOptionsMenu() - return true + + return onCollapse?.invoke(item) ?: true } }) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt index 3ea5eb68fe..f73bb09380 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/catalogue/browse/BrowseCatalogueController.kt @@ -36,7 +36,6 @@ import kotlinx.android.synthetic.main.main_activity.* import rx.Observable import rx.Subscription import rx.android.schedulers.AndroidSchedulers -import rx.subscriptions.Subscriptions import timber.log.Timber import uy.kohesive.injekt.injectLazy import java.util.concurrent.TimeUnit @@ -228,6 +227,7 @@ open class BrowseCatalogueController(bundle: Bundle) : val searchEventsObservable = searchView.queryTextChangeEvents() .skip(1) + .filter { router.backstack.lastOrNull()?.controller() == this@BrowseCatalogueController } .share() val writingObservable = searchEventsObservable .filter { !it.isSubmitted } @@ -238,11 +238,12 @@ open class BrowseCatalogueController(bundle: Bundle) : searchViewSubscription?.unsubscribe() searchViewSubscription = Observable.merge(writingObservable, submitObservable) .map { it.queryText().toString() } - .distinctUntilChanged() .subscribeUntilDestroy { searchWithQuery(it) } - untilDestroySubscriptions.add( - Subscriptions.create { if (isActionViewExpanded) collapseActionView() }) + fixExpand(onCollapse = { + searchWithQuery("") + true + }) } // Setup filters button @@ -310,11 +311,6 @@ open class BrowseCatalogueController(bundle: Bundle) : if (presenter.query == newQuery) return - // FIXME dirty fix to restore the toolbar buttons after closing search mode. - if (newQuery == "") { - activity?.invalidateOptionsMenu() - } - showProgressBar() adapter?.clear() From f3e228e8a4be324220124676d9ad122a1bdcd397 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 12 Jan 2020 18:27:04 -0500 Subject: [PATCH 24/24] Indicate obsolete extensions (#2494) * Indicate obsolete extensions * Make obsolete indicators red * Move obsolete extensions up the list * Add base button theme for holder * Use red button color state instead of explicit text color --- .../tachiyomi/extension/ExtensionManager.kt | 21 ++++++++++----- .../tachiyomi/extension/model/Extension.kt | 3 ++- .../extension/ExtensionDetailsController.kt | 4 +++ .../tachiyomi/ui/extension/ExtensionHolder.kt | 26 +++++++++++++++---- .../ui/extension/ExtensionPresenter.kt | 2 +- app/src/main/res/drawable/button_bg_error.xml | 26 +++++++++++++++++++ .../layout/extension_detail_controller.xml | 18 ++++++++++++- app/src/main/res/values/strings.xml | 2 ++ 8 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 app/src/main/res/drawable/button_bg_error.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt index 8dfcb27a40..bfb3381fa0 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/ExtensionManager.kt @@ -71,7 +71,7 @@ class ExtensionManager( private set(value) { field = value availableExtensionsRelay.call(value) - setUpdateFieldOfInstalledExtensions(value) + updatedInstalledExtensionsStatuses(value) } /** @@ -158,18 +158,25 @@ class ExtensionManager( * * @param availableExtensions The list of extensions given by the [api]. */ - private fun setUpdateFieldOfInstalledExtensions(availableExtensions: List) { + private fun updatedInstalledExtensionsStatuses(availableExtensions: List) { val mutInstalledExtensions = installedExtensions.toMutableList() var changed = false for ((index, installedExt) in mutInstalledExtensions.withIndex()) { val pkgName = installedExt.pkgName - val availableExt = availableExtensions.find { it.pkgName == pkgName } ?: continue + val availableExt = availableExtensions.find { it.pkgName == pkgName } - val hasUpdate = availableExt.versionCode > installedExt.versionCode - if (installedExt.hasUpdate != hasUpdate) { - mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate) - changed = true + if (availableExt == null) { + if (!installedExt.isObsolete) { + mutInstalledExtensions[index] = installedExt.copy(isObsolete = true) + changed = true + } + } else { + val hasUpdate = availableExt.versionCode > installedExt.versionCode + if (installedExt.hasUpdate != hasUpdate) { + mutInstalledExtensions[index] = installedExt.copy(hasUpdate = hasUpdate) + changed = true + } } } if (changed) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt index ef4c245684..f0a53690f5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt @@ -16,7 +16,8 @@ sealed class Extension { override val versionCode: Int, val sources: List, override val lang: String, - val hasUpdate: Boolean = false) : Extension() + val hasUpdate: Boolean = false, + val isObsolete: Boolean = false) : Extension() data class Available(override val name: String, override val pkgName: String, diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt index 9d020e278a..73afc46810 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionDetailsController.kt @@ -69,6 +69,10 @@ class ExtensionDetailsController(bundle: Bundle? = null) : presenter.uninstallExtension() } + if (extension.isObsolete) { + extension_obsolete.visibility = View.VISIBLE + } + val themedContext by lazy { getPreferenceThemeContext() } val manager = PreferenceManager(themedContext) manager.preferenceDataStore = EmptyPreferenceDataStore() diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt index bcf6b3a131..a1425da46b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionHolder.kt @@ -1,6 +1,8 @@ package eu.kanade.tachiyomi.ui.extension import android.view.View +import androidx.core.content.ContextCompat +import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.extension.model.Extension @@ -52,11 +54,15 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) : bindButton(item) } + @Suppress("ResourceType") fun bindButton(item: ExtensionItem) = with(ext_button) { isEnabled = true isClickable = true isActivated = false + background = VectorDrawableCompat.create(resources!!, R.drawable.button_bg_transparent, null) + setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_transparent)) + val extension = item.extension val installStep = item.installStep @@ -73,11 +79,21 @@ class ExtensionHolder(view: View, override val adapter: ExtensionAdapter) : isClickable = false } } else if (extension is Extension.Installed) { - if (extension.hasUpdate) { - isActivated = true - setText(R.string.ext_update) - } else { - setText(R.string.ext_details) + when { + extension.hasUpdate -> { + isActivated = true + setText(R.string.ext_update) + } + extension.isObsolete -> { + // Red outline + background = VectorDrawableCompat.create(resources, R.drawable.button_bg_error, null) + setTextColor(ContextCompat.getColorStateList(context, R.drawable.button_bg_error)) + + setText(R.string.ext_obsolete) + } + else -> { + setText(R.string.ext_details) + } } } else if (extension is Extension.Untrusted) { setText(R.string.ext_trust) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt index fda29d66e8..97997b55f1 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/extension/ExtensionPresenter.kt @@ -62,7 +62,7 @@ open class ExtensionPresenter( val items = mutableListOf() - val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { it.pkgName })) + val installedSorted = installed.sortedWith(compareBy({ !it.hasUpdate }, { !it.isObsolete }, { it.pkgName })) val untrustedSorted = untrusted.sortedBy { it.pkgName } val availableSorted = available // Filter out already installed extensions and disabled languages diff --git a/app/src/main/res/drawable/button_bg_error.xml b/app/src/main/res/drawable/button_bg_error.xml new file mode 100644 index 0000000000..3edb3611bb --- /dev/null +++ b/app/src/main/res/drawable/button_bg_error.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/extension_detail_controller.xml b/app/src/main/res/layout/extension_detail_controller.xml index 137b81f853..d91b5a84eb 100644 --- a/app/src/main/res/layout/extension_detail_controller.xml +++ b/app/src/main/res/layout/extension_detail_controller.xml @@ -60,6 +60,22 @@ app:layout_constraintEnd_toEndOf="parent" tools:text="eu.kanade.tachiyomi.extension.en.myext"/> + +