Compare commits

...

23 Commits

Author SHA1 Message Date
42eaaa497f Release v0.13.4 2022-04-22 17:29:18 -04:00
96c894ce5b Revert history Compose/SQLDelight changes 2022-04-22 17:27:58 -04:00
c0214103a9 Temporarily remove chapter name cleaning
To be added back in a more consistent manner later around the app. Probably when more things are Compose-y with less repetition.
2022-04-22 14:03:43 -04:00
2b76a97989 Add advanced setting to clear WebView data 2022-04-22 14:00:42 -04:00
9d77052d9c Enable verbose logging in dev flavor by default (#6979) 2022-04-22 12:34:53 -04:00
b4981058a2 Add indexes to creational tables (#6974) 2022-04-22 08:03:07 -04:00
032aa64195 Lift Compose theme to abstract controller 2022-04-21 22:58:28 -04:00
7c8e8317a8 Simplify history item description building 2022-04-21 22:47:51 -04:00
eb1cfc4cd4 Add abstract ComposeController 2022-04-21 22:42:37 -04:00
f1e5cccee7 Add placeholder color for Compose manga covers 2022-04-21 19:02:54 -04:00
bc2ed763bd Default auto backups to 2 2022-04-21 17:13:33 -04:00
a35995b898 Fix crash on History tab when there is no next chapter (#6970) 2022-04-21 16:48:45 -04:00
b1f46ed830 Migrate History screen database calls to SQLDelight (#6933)
* Migrate History screen database call to SQLDelight

- Move all migrations to SQLDelight
- Move all tables to SQLDelight

Co-authored-by: inorichi <3521738+inorichi@users.noreply.github.com>

* Changes from review comments

* Add adapters to database

* Remove logging of database version in App

* Change query name for paging source queries

* Update migrations

* Make SQLite Callback handle migration

- To ensure it updates the database

* Use SQLDelight Schema version for Callback database version

Co-authored-by: inorichi <3521738+inorichi@users.noreply.github.com>
2022-04-21 15:45:56 -04:00
6c1565a7d4 Make links in new update dialog clickable
Co-authored-by: Jays2Kings <Jays2Kings@users.noreply.github.com>
2022-04-19 22:39:33 -04:00
2ca6b655ad Replace ignore button in new update dialog with link to GitHub page
Not enough room for 3 buttons. Users can still tap outside or back out of the dialog if they want to ignore it.
2022-04-18 22:45:58 -04:00
a83a481ac8 Update junrar 2022-04-18 17:14:47 -04:00
65a8b63b3b Move chapter name cleaning logic to holder (fixes #6955) 2022-04-18 09:26:43 -04:00
b20ca36db9 Fix AppBar not unlifting when scrolling using ComposeView (#6952) 2022-04-17 14:33:35 -04:00
189f92d7e8 Show better error message when empty backup creation is attempted (closes #6941) 2022-04-17 11:51:24 -04:00
cdd4ec6233 Increase default OkHttp call timeout to 2 minutes
Which is still stupidly high, but maybe it'll be lenient enough for certain people.
2022-04-17 11:32:47 -04:00
ef1bb4e800 Show parsed Markdown for new version info (closes #6940) 2022-04-17 11:30:05 -04:00
c475acd1ea Migrate History screen to Compose (#6922)
* Migrate History screen to Compose

- Migrate screen
- Strip logic from presenter into use cases and repository
- Setup for other screen being able to migrate to Compose with Theme

* Changes from review comments
2022-04-17 10:36:22 -04:00
7d50d7ff52 Add elevation to navigation rails (#6947)
Co-authored-by: CrepeTF <trungnguyen02@outlookcom>
2022-04-17 10:29:09 -04:00
18 changed files with 150 additions and 79 deletions

View File

@ -3,7 +3,7 @@
I acknowledge that: I acknowledge that:
- I have updated: - I have updated:
- To the latest version of the app (stable is v0.13.3) - To the latest version of the app (stable is v0.13.4)
- All extensions - All extensions
- I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/ - I have tried the troubleshooting guide: https://tachiyomi.org/help/guides/troubleshooting-problems/
- If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions - If this is an issue with an extension, that I should be opening an issue in https://github.com/tachiyomiorg/tachiyomi-extensions

View File

@ -53,7 +53,7 @@ body:
label: Tachiyomi version label: Tachiyomi version
description: You can find your Tachiyomi version in **More → About**. description: You can find your Tachiyomi version in **More → About**.
placeholder: | placeholder: |
Example: "0.13.3" Example: "0.13.4"
validations: validations:
required: true required: true
@ -98,7 +98,7 @@ body:
required: true required: true
- label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/). - label: I have tried the [troubleshooting guide](https://tachiyomi.org/help/guides/troubleshooting/).
required: true required: true
- label: I have updated the app to version **[0.13.3](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. - label: I have updated the app to version **[0.13.4](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
required: true required: true
- label: I have updated all installed extensions. - label: I have updated all installed extensions.
required: true required: true

View File

@ -33,7 +33,7 @@ body:
required: true required: true
- label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose). - label: If this is an issue with an extension, I should be opening an issue in the [extensions repository](https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose).
required: true required: true
- label: I have updated the app to version **[0.13.3](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**. - label: I have updated the app to version **[0.13.4](https://github.com/tachiyomiorg/tachiyomi/releases/latest)**.
required: true required: true
- label: I will fill out all of the requested information in this form. - label: I will fill out all of the requested information in this form.
required: true required: true

View File

@ -24,8 +24,8 @@ android {
applicationId = "eu.kanade.tachiyomi" applicationId = "eu.kanade.tachiyomi"
minSdk = AndroidConfig.minSdk minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk targetSdk = AndroidConfig.targetSdk
versionCode = 79 versionCode = 80
versionName = "0.13.3" versionName = "0.13.4"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"") buildConfigField("String", "COMMIT_SHA", "\"${getGitSha()}\"")
@ -219,6 +219,7 @@ dependencies {
exclude(group = "androidx.viewpager", module = "viewpager") exclude(group = "androidx.viewpager", module = "viewpager")
} }
implementation(libs.insetter) implementation(libs.insetter)
implementation(libs.markwon)
// Conductor // Conductor
implementation(libs.bundles.conductor) implementation(libs.bundles.conductor)

View File

@ -36,6 +36,7 @@ import eu.kanade.tachiyomi.util.preference.asImmediateFlow
import eu.kanade.tachiyomi.util.system.AuthenticatorUtil import eu.kanade.tachiyomi.util.system.AuthenticatorUtil
import eu.kanade.tachiyomi.util.system.WebViewUtil import eu.kanade.tachiyomi.util.system.WebViewUtil
import eu.kanade.tachiyomi.util.system.animatorDurationScale import eu.kanade.tachiyomi.util.system.animatorDurationScale
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.notification import eu.kanade.tachiyomi.util.system.notification
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -174,7 +175,7 @@ open class App : Application(), DefaultLifecycleObserver, ImageLoaderFactory {
} }
protected open fun setupAcra() { protected open fun setupAcra() {
if (BuildConfig.FLAVOR != "dev") { if (isDevFlavor.not()) {
initAcra { initAcra {
buildConfigClass = BuildConfig::class.java buildConfigClass = BuildConfig::class.java
excludeMatchingSharedPreferencesKeys = listOf(".*username.*", ".*password.*", ".*token.*") excludeMatchingSharedPreferencesKeys = listOf(".*username.*", ".*password.*", ".*token.*")

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.backup.full
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import com.hippo.unifile.UniFile import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.AbstractBackupManager import eu.kanade.tachiyomi.data.backup.AbstractBackupManager
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY
import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK import eu.kanade.tachiyomi.data.backup.BackupConst.BACKUP_CATEGORY_MASK
@ -90,6 +91,10 @@ class FullBackupManager(context: Context) : AbstractBackupManager(context) {
} }
val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!) val byteArray = parser.encodeToByteArray(BackupSerializer, backup!!)
if (byteArray.isEmpty()) {
throw IllegalStateException(context.getString(R.string.empty_backup_error))
}
file.openOutputStream().also { file.openOutputStream().also {
// Force overwrite old file // Force overwrite old file
(it as? FileOutputStream)?.channel?.truncate(0) (it as? FileOutputStream)?.channel?.truncate(0)

View File

@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.ui.library.setting.SortModeSetting
import eu.kanade.tachiyomi.ui.reader.setting.OrientationType import eu.kanade.tachiyomi.ui.reader.setting.OrientationType
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.widget.ExtendedNavigationView import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import java.io.File import java.io.File
import java.text.DateFormat import java.text.DateFormat
@ -207,7 +208,7 @@ class PreferencesHelper(val context: Context) {
fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false) fun folderPerManga() = prefs.getBoolean(Keys.folderPerManga, false)
fun numberOfBackups() = flowPrefs.getInt("backup_slots", 1) fun numberOfBackups() = flowPrefs.getInt("backup_slots", 2)
fun backupInterval() = flowPrefs.getInt("backup_interval", 0) fun backupInterval() = flowPrefs.getInt("backup_interval", 0)
@ -319,7 +320,7 @@ class PreferencesHelper(val context: Context) {
if (DeviceUtil.isMiui) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER, if (DeviceUtil.isMiui) Values.ExtensionInstaller.LEGACY else Values.ExtensionInstaller.PACKAGEINSTALLER,
) )
fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, false) fun verboseLogging() = prefs.getBoolean(Keys.verboseLogging, isDevFlavor)
fun autoClearChapterCache() = prefs.getBoolean(Keys.autoClearChapterCache, false) fun autoClearChapterCache() = prefs.getBoolean(Keys.autoClearChapterCache, false)

View File

@ -27,7 +27,7 @@ class NetworkHelper(context: Context) {
.cookieJar(cookieManager) .cookieJar(cookieManager)
.connectTimeout(30, TimeUnit.SECONDS) .connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.callTimeout(90, TimeUnit.SECONDS) .callTimeout(2, TimeUnit.MINUTES)
// .fastFallback(true) // TODO: re-enable when OkHttp 5 is stabler // .fastFallback(true) // TODO: re-enable when OkHttp 5 is stabler
.addInterceptor(UserAgentInterceptor()) .addInterceptor(UserAgentInterceptor())

View File

@ -901,7 +901,7 @@ class MangaController :
chaptersHeader.setNumChapters(chapters.size) chaptersHeader.setNumChapters(chapters.size)
val adapter = chaptersAdapter ?: return val adapter = chaptersAdapter ?: return
adapter.updateDataSet(presenter.cleanChapterNames(chapters)) adapter.updateDataSet(chapters)
if (selectedChapters.isNotEmpty()) { if (selectedChapters.isNotEmpty()) {
adapter.clearSelection() // we need to start from a clean state, index may have changed adapter.clearSelection() // we need to start from a clean state, index may have changed

View File

@ -431,17 +431,6 @@ class MangaPresenter(
} }
} }
fun cleanChapterNames(chapters: List<ChapterItem>): List<ChapterItem> {
chapters.forEach {
it.name = it.name
.trim()
.removePrefix(manga.title)
.trim(*CHAPTER_TRIM_CHARS)
}
return chapters
}
/** /**
* Updates the UI after applying the filters. * Updates the UI after applying the filters.
*/ */
@ -863,38 +852,3 @@ class MangaPresenter(
// Track sheet - end // Track sheet - end
} }
private val CHAPTER_TRIM_CHARS = arrayOf(
// Whitespace
' ',
'\u0009',
'\u000A',
'\u000B',
'\u000C',
'\u000D',
'\u0020',
'\u0085',
'\u00A0',
'\u1680',
'\u2000',
'\u2001',
'\u2002',
'\u2003',
'\u2004',
'\u2005',
'\u2006',
'\u2007',
'\u2008',
'\u2009',
'\u200A',
'\u2028',
'\u2029',
'\u202F',
'\u205F',
'\u3000',
// Separators
'-',
'_',
',',
':',
).toCharArray()

View File

@ -6,6 +6,7 @@ import androidx.core.text.buildSpannedString
import androidx.core.text.color import androidx.core.text.color
import androidx.core.view.isVisible import androidx.core.view.isVisible
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.databinding.ChaptersItemBinding import eu.kanade.tachiyomi.databinding.ChaptersItemBinding
import eu.kanade.tachiyomi.source.LocalSource import eu.kanade.tachiyomi.source.LocalSource
@ -35,6 +36,8 @@ class ChapterHolder(
itemView.context.getString(R.string.display_mode_chapter, number) itemView.context.getString(R.string.display_mode_chapter, number)
} }
else -> chapter.name else -> chapter.name
// TODO: show cleaned name consistently around the app
// else -> cleanChapterName(chapter, manga)
} }
// Set correct text color // Set correct text color
@ -80,4 +83,47 @@ class ChapterHolder(
binding.download.isVisible = item.manga.source != LocalSource.ID binding.download.isVisible = item.manga.source != LocalSource.ID
binding.download.setState(item.status, item.progress) binding.download.setState(item.status, item.progress)
} }
private fun cleanChapterName(chapter: Chapter, manga: Manga): String {
return chapter.name
.trim()
.removePrefix(manga.title)
.trim(*CHAPTER_TRIM_CHARS)
}
} }
private val CHAPTER_TRIM_CHARS = arrayOf(
// Whitespace
' ',
'\u0009',
'\u000A',
'\u000B',
'\u000C',
'\u000D',
'\u0020',
'\u0085',
'\u00A0',
'\u1680',
'\u2000',
'\u2001',
'\u2002',
'\u2003',
'\u2004',
'\u2005',
'\u2006',
'\u2007',
'\u2008',
'\u2009',
'\u200A',
'\u2028',
'\u2029',
'\u202F',
'\u205F',
'\u3000',
// Separators
'-',
'_',
',',
':',
).toCharArray()

View File

@ -121,6 +121,7 @@ class AboutController : SettingsController(), NoAppBarElevationController {
is AppUpdateResult.NoNewUpdate -> { is AppUpdateResult.NoNewUpdate -> {
activity?.toast(R.string.update_check_no_new_updates) activity?.toast(R.string.update_check_no_new_updates)
} }
else -> {}
} }
} catch (error: Exception) { } catch (error: Exception) {
activity?.toast(error.message) activity?.toast(error.message)

View File

@ -2,35 +2,58 @@ package eu.kanade.tachiyomi.ui.more
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.TextView
import androidx.core.os.bundleOf import androidx.core.os.bundleOf
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.updater.AppUpdateResult import eu.kanade.tachiyomi.data.updater.AppUpdateResult
import eu.kanade.tachiyomi.data.updater.AppUpdateService import eu.kanade.tachiyomi.data.updater.AppUpdateService
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.openInBrowser
import io.noties.markwon.Markwon
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) { class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
constructor(update: AppUpdateResult.NewUpdate) : this( constructor(update: AppUpdateResult.NewUpdate) : this(
bundleOf(BODY_KEY to update.release.info, URL_KEY to update.release.getDownloadLink()), bundleOf(
BODY_KEY to update.release.info,
RELEASE_URL_KEY to update.release.releaseLink,
DOWNLOAD_URL_KEY to update.release.getDownloadLink(),
),
) )
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val releaseBody = args.getString(BODY_KEY)!!
.replace("""---(\R|.)*Checksums(\R|.)*""".toRegex(), "")
val info = Markwon.create(activity!!).toMarkdown(releaseBody)
return MaterialAlertDialogBuilder(activity!!) return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.update_check_notification_update_available) .setTitle(R.string.update_check_notification_update_available)
.setMessage(args.getString(BODY_KEY) ?: "") .setMessage(info)
.setPositiveButton(R.string.update_check_confirm) { _, _ -> .setPositiveButton(R.string.update_check_confirm) { _, _ ->
val appContext = applicationContext applicationContext?.let { context ->
if (appContext != null) {
// Start download // Start download
val url = args.getString(URL_KEY) ?: "" val url = args.getString(DOWNLOAD_URL_KEY)!!
AppUpdateService.start(appContext, url) AppUpdateService.start(context, url)
} }
} }
.setNegativeButton(R.string.update_check_ignore, null) .setNeutralButton(R.string.update_check_open) { _, _ ->
openInBrowser(args.getString(RELEASE_URL_KEY)!!)
}
.create() .create()
} }
override fun onAttach(view: View) {
super.onAttach(view)
// Make links in Markdown text clickable
(dialog?.findViewById(android.R.id.message) as? TextView)?.movementMethod =
LinkMovementMethod.getInstance()
}
} }
private const val BODY_KEY = "NewUpdateDialogController.body" private const val BODY_KEY = "NewUpdateDialogController.body"
private const val URL_KEY = "NewUpdateDialogController.key" private const val RELEASE_URL_KEY = "NewUpdateDialogController.release_url"
private const val DOWNLOAD_URL_KEY = "NewUpdateDialogController.download_url"

View File

@ -4,10 +4,11 @@ import android.annotation.SuppressLint
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.provider.Settings import android.provider.Settings
import android.webkit.WebStorage
import android.webkit.WebView
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.preference.PreferenceScreen import androidx.preference.PreferenceScreen
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
@ -38,9 +39,13 @@ import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.DeviceUtil import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.isDevFlavor
import eu.kanade.tachiyomi.util.system.isPackageInstalled import eu.kanade.tachiyomi.util.system.isPackageInstalled
import eu.kanade.tachiyomi.util.system.logcat
import eu.kanade.tachiyomi.util.system.powerManager import eu.kanade.tachiyomi.util.system.powerManager
import eu.kanade.tachiyomi.util.system.setDefaultSettings
import eu.kanade.tachiyomi.util.system.toast import eu.kanade.tachiyomi.util.system.toast
import logcat.LogPriority
import rikka.sui.Sui import rikka.sui.Sui
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys import eu.kanade.tachiyomi.data.preference.PreferenceKeys as Keys
@ -55,7 +60,7 @@ class SettingsAdvancedController : SettingsController() {
override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply { override fun setupPreferenceScreen(screen: PreferenceScreen) = screen.apply {
titleRes = R.string.pref_category_advanced titleRes = R.string.pref_category_advanced
if (BuildConfig.FLAVOR != "dev") { if (isDevFlavor.not()) {
switchPreference { switchPreference {
key = "acra.enable" key = "acra.enable"
titleRes = R.string.pref_enable_acra titleRes = R.string.pref_enable_acra
@ -78,7 +83,7 @@ class SettingsAdvancedController : SettingsController() {
key = Keys.verboseLogging key = Keys.verboseLogging
titleRes = R.string.pref_verbose_logging titleRes = R.string.pref_verbose_logging
summaryRes = R.string.pref_verbose_logging_summary summaryRes = R.string.pref_verbose_logging_summary
defaultValue = false defaultValue = isDevFlavor
onChange { onChange {
activity?.toast(R.string.requires_app_restart) activity?.toast(R.string.requires_app_restart)
@ -138,6 +143,12 @@ class SettingsAdvancedController : SettingsController() {
titleRes = R.string.pref_auto_clear_chapter_cache titleRes = R.string.pref_auto_clear_chapter_cache
defaultValue = false defaultValue = false
} }
preference {
key = "pref_clear_webview_data"
titleRes = R.string.pref_clear_webview_data
onClick { clearWebViewData() }
}
preference { preference {
key = "pref_clear_database" key = "pref_clear_database"
titleRes = R.string.pref_clear_database titleRes = R.string.pref_clear_database
@ -274,10 +285,28 @@ class SettingsAdvancedController : SettingsController() {
resources?.getString(R.string.used_cache, chapterCache.readableSize) resources?.getString(R.string.used_cache, chapterCache.readableSize)
} }
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e)
withUIContext { activity?.toast(R.string.cache_delete_error) } withUIContext { activity?.toast(R.string.cache_delete_error) }
} }
} }
} }
private fun clearWebViewData() {
if (activity == null) return
try {
val webview = WebView(activity!!)
webview.setDefaultSettings()
webview.clearCache(true)
webview.clearFormData()
webview.clearHistory()
webview.clearSslPreferences()
WebStorage.getInstance().deleteAllData()
activity?.toast(R.string.webview_data_deleted)
} catch (e: Throwable) {
logcat(LogPriority.ERROR, e)
activity?.toast(R.string.cache_delete_error)
}
}
} }
private const val CLEAR_CACHE_KEY = "pref_clear_cache_key" private const val CLEAR_CACHE_KEY = "pref_clear_cache_key"

View File

@ -0,0 +1,6 @@
package eu.kanade.tachiyomi.util.system
import eu.kanade.tachiyomi.BuildConfig
val isDevFlavor: Boolean
get() = BuildConfig.FLAVOR == "dev"

View File

@ -17,7 +17,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toEndOf="@id/side_nav"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.MaterialToolbar
@ -35,7 +35,7 @@
android:background="?attr/colorTertiary" android:background="?attr/colorTertiary"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toEndOf="@id/side_nav"
app:layout_constraintTop_toBottomOf="@+id/appbar" app:layout_constraintTop_toBottomOf="@+id/appbar"
tools:visibility="visible"> tools:visibility="visible">
@ -56,7 +56,7 @@
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toEndOf="@id/side_nav"
app:layout_constraintTop_toBottomOf="@+id/downloaded_only" app:layout_constraintTop_toBottomOf="@+id/downloaded_only"
tools:visibility="visible"> tools:visibility="visible">
@ -73,11 +73,10 @@
<com.google.android.material.navigationrail.NavigationRailView <com.google.android.material.navigationrail.NavigationRailView
android:id="@+id/side_nav" android:id="@+id/side_nav"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="match_parent"
app:elevation="0dp" android:paddingTop="?attr/actionBarSize"
app:layout_constraintBottom_toBottomOf="parent" app:elevation="1dp"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/incognito_mode"
app:menu="@menu/main_nav" /> app:menu="@menu/main_nav" />
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout

View File

@ -451,6 +451,7 @@
<string name="backup_choice">What do you want to backup?</string> <string name="backup_choice">What do you want to backup?</string>
<string name="creating_backup">Creating backup</string> <string name="creating_backup">Creating backup</string>
<string name="creating_backup_error">Backup failed</string> <string name="creating_backup_error">Backup failed</string>
<string name="empty_backup_error">No library entries to back up</string>
<string name="restore_miui_warning">Backup/restore may not function properly if MIUI Optimization is disabled.</string> <string name="restore_miui_warning">Backup/restore may not function properly if MIUI Optimization is disabled.</string>
<string name="restore_in_progress">Restore is already in progress</string> <string name="restore_in_progress">Restore is already in progress</string>
<string name="restoring_backup">Restoring backup</string> <string name="restoring_backup">Restoring backup</string>
@ -468,7 +469,7 @@
<string name="pref_clear_chapter_cache">Clear chapter cache</string> <string name="pref_clear_chapter_cache">Clear chapter cache</string>
<string name="used_cache">Used: %1$s</string> <string name="used_cache">Used: %1$s</string>
<string name="cache_deleted">Cache cleared. %1$d files have been deleted</string> <string name="cache_deleted">Cache cleared. %1$d files have been deleted</string>
<string name="cache_delete_error">An error occurred while clearing cache</string> <string name="cache_delete_error">Error occurred while clearing</string>
<string name="pref_auto_clear_chapter_cache">Clear chapter cache on app close</string> <string name="pref_auto_clear_chapter_cache">Clear chapter cache on app close</string>
<string name="pref_clear_database">Clear database</string> <string name="pref_clear_database">Clear database</string>
<string name="pref_clear_database_summary">Delete history for manga that are not saved in your library</string> <string name="pref_clear_database_summary">Delete history for manga that are not saved in your library</string>
@ -476,6 +477,8 @@
<string name="clear_database_confirmation">Are you sure? Read chapters and progress of non-library manga will be lost</string> <string name="clear_database_confirmation">Are you sure? Read chapters and progress of non-library manga will be lost</string>
<string name="clear_database_completed">Entries deleted</string> <string name="clear_database_completed">Entries deleted</string>
<string name="database_clean">Database clean</string> <string name="database_clean">Database clean</string>
<string name="pref_clear_webview_data">Clear WebView data</string>
<string name="webview_data_deleted">WebView data cleared</string>
<string name="pref_refresh_library_covers">Refresh library manga covers</string> <string name="pref_refresh_library_covers">Refresh library manga covers</string>
<string name="pref_refresh_library_tracking">Refresh tracking</string> <string name="pref_refresh_library_tracking">Refresh tracking</string>
<string name="pref_refresh_library_tracking_summary">Updates status, score and last chapter read from the tracking services</string> <string name="pref_refresh_library_tracking_summary">Updates status, score and last chapter read from the tracking services</string>
@ -756,7 +759,7 @@
<!--UpdateCheck--> <!--UpdateCheck-->
<string name="update_check_confirm">Download</string> <string name="update_check_confirm">Download</string>
<string name="update_check_ignore">Ignore</string> <string name="update_check_open">Open on GitHub</string>
<string name="update_check_eol">This Android version is no longer supported</string> <string name="update_check_eol">This Android version is no longer supported</string>
<string name="update_check_no_new_updates">No new updates available</string> <string name="update_check_no_new_updates">No new updates available</string>
<string name="update_check_look_for_updates">Searching for updates…</string> <string name="update_check_look_for_updates">Searching for updates…</string>

View File

@ -34,7 +34,7 @@ jsoup = "org.jsoup:jsoup:1.14.3"
disklrucache = "com.jakewharton:disklrucache:2.0.2" disklrucache = "com.jakewharton:disklrucache:2.0.2"
unifile = "com.github.tachiyomiorg:unifile:17bec43" unifile = "com.github.tachiyomiorg:unifile:17bec43"
junrar = "com.github.junrar:junrar:7.4.0" junrar = "com.github.junrar:junrar:7.5.0"
sqlitektx = "androidx.sqlite:sqlite-ktx:2.3.0-alpha02" sqlitektx = "androidx.sqlite:sqlite-ktx:2.3.0-alpha02"
sqlite-android = "com.github.requery:sqlite-android:3.36.0" sqlite-android = "com.github.requery:sqlite-android:3.36.0"
@ -55,6 +55,8 @@ image-decoder = "com.github.tachiyomiorg:image-decoder:7481a4a"
natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1" natural-comparator = "com.github.gpanther:java-nat-sort:natural-comparator-1.1"
markwon = "io.noties.markwon:core:4.6.2"
material = "com.google.android.material:material:1.7.0-alpha01" material = "com.google.android.material:material:1.7.0-alpha01"
androidprocessbutton = "com.github.dmytrodanylyk.android-process-button:library:1.0.4" androidprocessbutton = "com.github.dmytrodanylyk.android-process-button:library:1.0.4"
flexible-adapter-core = "com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533" flexible-adapter-core = "com.github.arkon.FlexibleAdapter:flexible-adapter:c8013533"
@ -76,7 +78,7 @@ flowbinding-viewpager = { module = "io.github.reactivecircus.flowbinding:flowbin
logcat = "com.squareup.logcat:logcat:0.1" logcat = "com.squareup.logcat:logcat:0.1"
acra-http = "ch.acra:acra-http:5.9.1" acra-http = "ch.acra:acra-http:5.9.3"
firebase-analytics = "com.google.firebase:firebase-analytics-ktx:20.0.2" firebase-analytics = "com.google.firebase:firebase-analytics-ktx:20.0.2"
aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlib_version" } aboutlibraries-core = { module = "com.mikepenz:aboutlibraries-core", version.ref = "aboutlib_version" }