diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt index 110e1c1dc..5961f0046 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -18,7 +18,6 @@ import org.koitharu.kotatsu.core.util.ext.configureForParser import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug import javax.inject.Inject -import com.google.android.material.R as materialR @AndroidEntryPoint class BrowserActivity : BaseBrowserActivity() { @@ -28,10 +27,7 @@ class BrowserActivity : BaseBrowserActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) val mangaSource = MangaSource(intent?.getStringExtra(AppRouter.KEY_SOURCE)) val repository = mangaRepositoryFactory.create(mangaSource) as? ParserMangaRepository val userAgent = repository?.getRequestHeaders()?.get(CommonHeaders.USER_AGENT) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt index c97a94548..b21479a2d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/browser/cloudflare/CloudFlareActivity.kt @@ -26,7 +26,6 @@ import org.koitharu.kotatsu.core.util.ext.configureForParser import org.koitharu.kotatsu.core.util.ext.getDisplayMessage import org.koitharu.kotatsu.parsers.network.CloudFlareHelper import javax.inject.Inject -import com.google.android.material.R as materialR @AndroidEntryPoint class CloudFlareActivity : BaseBrowserActivity(), CloudFlareCallback { @@ -40,10 +39,7 @@ class CloudFlareActivity : BaseBrowserActivity(), CloudFlareCallback { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) val url = intent?.dataString if (url.isNullOrEmpty()) { finishAfterTransition() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt index 750682a84..922711717 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/ExpiringLruCache.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.core.cache -import androidx.collection.LruCache +import androidx.collection.SieveCache +import org.koitharu.kotatsu.parsers.model.MangaSource import java.util.concurrent.TimeUnit import org.koitharu.kotatsu.core.cache.MemoryContentCache.Key as CacheKey @@ -8,11 +9,9 @@ class ExpiringLruCache( val maxSize: Int, private val lifetime: Long, private val timeUnit: TimeUnit, -) : Iterable { +) { - private val cache = LruCache>(maxSize) - - override fun iterator(): Iterator = cache.snapshot().keys.iterator() + private val cache = SieveCache>(maxSize) operator fun get(key: CacheKey): T? { val value = cache[key] ?: return null @@ -37,4 +36,8 @@ class ExpiringLruCache( fun remove(key: CacheKey) { cache.remove(key) } + + fun removeAll(source: MangaSource) { + cache.removeIf { key, _ -> key.source == source } + } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt index c76d7f317..cf78bcb6b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/cache/MemoryContentCache.kt @@ -81,11 +81,7 @@ class MemoryContentCache @Inject constructor(application: Application) : Compone } private fun clearCache(cache: ExpiringLruCache<*>, source: MangaSource) { - cache.forEach { key -> - if (key.source == source) { - cache.remove(key) - } - } + cache.removeAll(source) } data class Key( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/nav/AppRouter.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/nav/AppRouter.kt index 3f565b863..0e6919c20 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/nav/AppRouter.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/nav/AppRouter.kt @@ -749,6 +749,12 @@ class AppRouter private constructor( .putExtra(KEY_SOURCE, source.name) } + fun isShareSupported(manga: Manga): Boolean = when { + manga.isBroken -> false + manga.isLocal -> manga.url.toUri().toFileOrNull() != null + else -> true + } + const val KEY_DATA = "data" const val KEY_ENTRIES = "entries" const val KEY_ERROR = "error" diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt index 82d0148d5..2fc0a1204 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/network/CommonHeadersInterceptor.kt @@ -65,7 +65,7 @@ class CommonHeadersInterceptor @Inject constructor( private fun Interceptor.interceptSafe(chain: Chain): Response = runCatchingCancellable { intercept(chain) }.getOrElse { e -> - if (e is IOException) { + if (e is IOException || e is Error) { throw e } else { // only IOException can be safely thrown from an Interceptor diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/os/AppShortcutManager.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/os/AppShortcutManager.kt index 075102e05..df7e2ba57 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/os/AppShortcutManager.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/os/AppShortcutManager.kt @@ -133,7 +133,7 @@ class AppShortcutManager @Inject constructor( } } - private suspend fun buildShortcutInfo(manga: Manga): ShortcutInfoCompat { + private suspend fun buildShortcutInfo(manga: Manga): ShortcutInfoCompat = withContext(Dispatchers.Default) { val icon = runCatchingCancellable { coil.execute( ImageRequest.Builder(context) @@ -149,7 +149,7 @@ class AppShortcutManager @Inject constructor( onFailure = { IconCompat.createWithResource(context, R.drawable.ic_shortcut_default) }, ) mangaRepository.storeManga(manga) - return ShortcutInfoCompat.Builder(context, manga.id.toString()) + ShortcutInfoCompat.Builder(context, manga.id.toString()) .setShortLabel(manga.title) .setLongLabel(manga.title) .setIcon(icon) @@ -159,8 +159,7 @@ class AppShortcutManager @Inject constructor( .mangaId(manga.id) .build() .intent, - ) - .build() + ).build() } private suspend fun buildShortcutInfo(source: MangaSource): ShortcutInfoCompat = withContext(Dispatchers.Default) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/ParserMangaRepository.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/ParserMangaRepository.kt index 3b0e99738..67a9d1967 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/ParserMangaRepository.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/parser/ParserMangaRepository.kt @@ -18,7 +18,6 @@ import org.koitharu.kotatsu.parsers.model.MangaListFilterOptions import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.model.SortOrder -import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.runCatchingCancellable import org.koitharu.kotatsu.parsers.util.suspendlazy.suspendLazy @@ -58,13 +57,7 @@ class ParserMangaRepository( val domains: Array get() = parser.configKeyDomain.presetValues - override fun intercept(chain: Interceptor.Chain): Response { - return if (parser is Interceptor) { - parser.intercept(chain) - } else { - chain.proceed(chain.request()) - } - } + override fun intercept(chain: Interceptor.Chain): Response = parser.intercept(chain) override suspend fun getList(offset: Int, order: SortOrder?, filter: MangaListFilter?): List { return mirrorSwitchInterceptor.withMirrorSwitching { @@ -96,7 +89,7 @@ class ParserMangaRepository( parser.getDetails(manga) } - fun getAuthProvider(): MangaParserAuthProvider? = parser as? MangaParserAuthProvider + fun getAuthProvider(): MangaParserAuthProvider? = parser.authorizationProvider fun getRequestHeaders() = parser.getRequestHeaders() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt index d1f88b863..2d1c647d9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -741,6 +741,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_BACKUP_TG_TEST = "backup_periodic_tg_test" const val KEY_CLEAR_MANGA_DATA = "manga_data_clear" const val KEY_STORAGE_USAGE = "storage_usage" + const val KEY_WEBVIEW_CLEAR = "webview_clear" // old keys are for migration only private const val KEY_IMAGES_PROXY_OLD = "images_proxy" diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt index ec2598d7e..883afdc0b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/BaseActivity.kt @@ -29,6 +29,7 @@ import org.koitharu.kotatsu.core.nav.AppRouter import org.koitharu.kotatsu.core.ui.util.ActionModeDelegate import org.koitharu.kotatsu.core.util.ext.isWebViewUnavailable import org.koitharu.kotatsu.main.ui.protect.ScreenshotPolicyHelper +import com.google.android.material.R as materialR abstract class BaseActivity : AppCompatActivity(), @@ -98,6 +99,15 @@ abstract class BaseActivity : toolbar?.let(this::setSupportActionBar) } + protected fun setDisplayHomeAsUp(isEnabled: Boolean, showUpAsClose: Boolean) { + supportActionBar?.run { + setDisplayHomeAsUpEnabled(isEnabled) + if (showUpAsClose) { + setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) + } + } + } + override fun onSupportNavigateUp(): Boolean { val fm = supportFragmentManager if (fm.isStateSaved) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt index ef9c96fa0..6f9d6a543 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/core/ui/FragmentContainerActivity.kt @@ -30,7 +30,7 @@ abstract class FragmentContainerActivity(private val fragmentClass: Class { - activity.router.showShareDialog(manga) + router.showShareDialog(manga) } R.id.action_delete -> { @@ -56,31 +61,31 @@ class DetailsMenuProvider( } R.id.action_save -> { - activity.router.showDownloadDialog(manga, snackbarHost) + router.showDownloadDialog(manga, snackbarHost) } R.id.action_browser -> { - activity.router.openBrowser(url = manga.publicUrl, source = manga.source, title = manga.title) + router.openBrowser(url = manga.publicUrl, source = manga.source, title = manga.title) } R.id.action_online -> { - activity.router.openDetails(manga) + router.openDetails(manga) } R.id.action_related -> { - activity.router.openSearch(manga.title) + router.openSearch(manga.title) } R.id.action_alternatives -> { - activity.router.openAlternatives(manga) + router.openAlternatives(manga) } R.id.action_stats -> { - activity.router.showStatisticSheet(manga) + router.showStatisticSheet(manga) } R.id.action_scrobbling -> { - activity.router.showScrobblingSelectorSheet(manga, null) + router.showScrobblingSelectorSheet(manga, null) } R.id.action_shortcut -> { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt index e07ecb3f5..87dd34145 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/download/ui/list/DownloadsActivity.kt @@ -43,7 +43,7 @@ class DownloadsActivity : BaseActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityDownloadsBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val downloadsAdapter = DownloadsAdapter(this, coil, this) val decoration = TypedListSpacingDecoration(this, false) selectionController = ListSelectionController( diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt index 46d620aff..88413354d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/FavouriteCategoriesActivity.kt @@ -49,7 +49,7 @@ class FavouriteCategoriesActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityCategoriesBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) adapter = CategoriesAdapter(coil, this, this, this) selectionController = ListSelectionController( appCompatDelegate = delegate, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt index fffe0afa8..1b6b101f2 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/favourites/ui/categories/edit/FavouritesCategoryEditActivity.kt @@ -25,7 +25,6 @@ import org.koitharu.kotatsu.core.util.ext.sortedByOrdinal import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityCategoryEditBinding import org.koitharu.kotatsu.list.domain.ListSortOrder -import com.google.android.material.R as materialR @AndroidEntryPoint class FavouritesCategoryEditActivity : @@ -41,10 +40,7 @@ class FavouritesCategoryEditActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityCategoryEditBinding.inflate(layoutInflater)) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) initSortSpinner() viewBinding.buttonDone.setOnClickListener(this) viewBinding.editName.addTextChangedListener(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/EdgeDetector.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/EdgeDetector.kt index 5b4f9cb5b..76cb60e57 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/EdgeDetector.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/domain/EdgeDetector.kt @@ -6,7 +6,7 @@ import android.graphics.Color import android.graphics.Point import android.graphics.Rect import androidx.annotation.ColorInt -import androidx.collection.LruCache +import androidx.collection.SieveCache import androidx.core.graphics.alpha import androidx.core.graphics.blue import androidx.core.graphics.get @@ -29,7 +29,7 @@ import kotlin.math.abs class EdgeDetector(private val context: Context) { private val mutex = Mutex() - private val cache = LruCache(CACHE_SIZE) + private val cache = SieveCache(CACHE_SIZE) suspend fun getBounds(imageSource: ImageSource): Rect? { cache[imageSource]?.let { rect -> diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index 8aa79ce09..798b5ca02 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -105,7 +105,7 @@ class ReaderActivity : super.onCreate(savedInstanceState) setContentView(ActivityReaderBinding.inflate(layoutInflater)) readerManager = ReaderManager(supportFragmentManager, viewBinding.container, settings) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) touchHelper = TapGridDispatcher(this, this) scrollTimer = scrollTimerFactory.create(this, this) pageSaveHelper = pageSaveHelperFactory.create(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt index a3f5e2b72..ad45d14bb 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/reader/ui/colorfilter/ColorFilterConfigActivity.kt @@ -35,7 +35,6 @@ import org.koitharu.kotatsu.parsers.util.format import org.koitharu.kotatsu.parsers.util.nullIfEmpty import org.koitharu.kotatsu.reader.domain.ReaderColorFilter import javax.inject.Inject -import com.google.android.material.R as materialR @AndroidEntryPoint class ColorFilterConfigActivity : @@ -51,10 +50,7 @@ class ColorFilterConfigActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityColorFilterBinding.inflate(layoutInflater)) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) viewBinding.sliderBrightness.addOnChangeListener(this) viewBinding.sliderContrast.addOnChangeListener(this) val formatter = PercentLabelFormatter(resources) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt index d3606aeba..647828d32 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/scrobbling/common/ui/config/ScrobblerConfigActivity.kt @@ -46,7 +46,7 @@ class ScrobblerConfigActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivityScrobblerConfigBinding.inflate(layoutInflater)) setTitle(viewModel.titleResId) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val listAdapter = ScrobblingMangaAdapter(this, coil, this) with(viewBinding.recyclerView) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt index 3e720f917..00c100ca0 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/MangaListActivity.kt @@ -76,7 +76,7 @@ class MangaListActivity : val filter = intent.getParcelableExtraCompat(AppRouter.KEY_FILTER)?.filter val sortOrder = intent.getSerializableExtraCompat(AppRouter.KEY_SORT_ORDER) source = MangaSource(intent.getStringExtra(AppRouter.KEY_SOURCE)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) if (viewBinding.containerFilterHeader != null) { viewBinding.appbar.addOnOffsetChangedListener(this) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt index de404b168..c7e2c6a71 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/search/ui/multi/SearchActivity.kt @@ -96,10 +96,8 @@ class SearchActivity : viewBinding.recyclerView.setHasFixedSize(true) viewBinding.recyclerView.addItemDecoration(TypedListSpacingDecoration(this, true)) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setSubtitle(R.string.search_results) - } + setDisplayHomeAsUp(true, false) + supportActionBar?.setSubtitle(R.string.search_results) addMenuProvider(SearchKindMenuProvider(this, viewModel.query, viewModel.kind)) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/ProxySettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/ProxySettingsFragment.kt index cd630618b..513e33f5f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/ProxySettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/ProxySettingsFragment.kt @@ -122,8 +122,9 @@ class ProxySettingsFragment : BasePreferenceFragment(R.string.proxy), .get() .url("http://neverssl.com") .build() - val response = okHttpClient.newCall(request).await() - check(response.isSuccessful) { response.message } + okHttpClient.newCall(request).await().use { response -> + check(response.isSuccessful) { response.message } + } } showTestResult(null) } catch (e: CancellationException) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index f8409a3bd..93b8c6b53 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -57,7 +57,7 @@ class SettingsActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivitySettingsBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val fm = supportFragmentManager val currentFragment = fm.findFragmentById(R.id.container) if (currentFragment == null || (isMasterDetails && currentFragment is RootSettingsFragment)) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt index aaea17e62..75f13524d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/reader/ReaderTapGridConfigActivity.kt @@ -40,7 +40,7 @@ class ReaderTapGridConfigActivity : BaseActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivitySourcesCatalogBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val sourcesAdapter = SourcesCatalogAdapter(this, coil, this) with(viewBinding.recyclerView) { setHasFixedSize(true) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt index f77f54da5..f66697fd4 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/storage/directories/MangaDirectoriesActivity.kt @@ -62,7 +62,7 @@ class MangaDirectoriesActivity : BaseActivity() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityMangaDirectoriesBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val adapter = AsyncListDifferDelegationAdapter(DirectoryDiffCallback(), directoryConfigAD(this)) viewBinding.recyclerView.adapter = adapter viewBinding.fabAdd.setOnClickListener(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsFragment.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsFragment.kt index 59b30d50a..6b29bb9a5 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsFragment.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsFragment.kt @@ -55,6 +55,7 @@ class StorageManageSettingsFragment : BasePreferenceFragment(R.string.storage_us findPreference(AppSettings.KEY_STORAGE_USAGE)?.let { pref -> viewModel.storageUsage.observe(viewLifecycleOwner, pref) } + findPreference(AppSettings.KEY_WEBVIEW_CLEAR)?.isVisible = viewModel.isBrowserDataCleanupEnabled viewModel.loadingKeys.observe(viewLifecycleOwner) { keys -> loadingPrefs.addAll(keys) @@ -98,6 +99,10 @@ class StorageManageSettingsFragment : BasePreferenceFragment(R.string.storage_us true } + AppSettings.KEY_WEBVIEW_CLEAR -> { + viewModel.clearBrowserData() + true + } AppSettings.KEY_CLEAR_MANGA_DATA -> { viewModel.clearMangaData() diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsViewModel.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsViewModel.kt index db5f2b87c..c57be32ee 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsViewModel.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/userdata/storage/StorageManageSettingsViewModel.kt @@ -1,5 +1,9 @@ package org.koitharu.kotatsu.settings.userdata.storage +import android.annotation.SuppressLint +import android.webkit.WebStorage +import androidx.webkit.WebStorageCompat +import androidx.webkit.WebViewFeature import coil3.ImageLoader import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -26,6 +30,8 @@ import org.koitharu.kotatsu.tracker.domain.TrackingRepository import java.util.EnumMap import javax.inject.Inject import javax.inject.Provider +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine @HiltViewModel class StorageManageSettingsViewModel @Inject constructor( @@ -50,6 +56,9 @@ class StorageManageSettingsViewModel @Inject constructor( val onChaptersCleanedUp = MutableEventFlow>() + val isBrowserDataCleanupEnabled: Boolean + get() = WebViewFeature.isFeatureSupported(WebViewFeature.DELETE_BROWSING_DATA) + private var storageUsageJob: Job? = null init { @@ -120,11 +129,34 @@ class StorageManageSettingsViewModel @Inject constructor( } } + @SuppressLint("RequiresFeature") + fun clearBrowserData() { + launchJob { + try { + loadingKeys.update { it + AppSettings.KEY_WEBVIEW_CLEAR } + val storage = WebStorage.getInstance() + suspendCoroutine { cont -> + WebStorageCompat.deleteBrowsingData(storage) { + cont.resume(Unit) + } + } + onActionDone.call(ReversibleAction(R.string.updates_feed_cleared, null)) + } finally { + loadingKeys.update { it - AppSettings.KEY_WEBVIEW_CLEAR } + } + } + } + fun clearUpdatesFeed() { launchJob(Dispatchers.Default) { - trackingRepository.clearLogs() - feedItemsCount.value = trackingRepository.getLogsCount() - onActionDone.call(ReversibleAction(R.string.updates_feed_cleared, null)) + try { + loadingKeys.update { it + AppSettings.KEY_UPDATES_FEED_CLEAR } + trackingRepository.clearLogs() + feedItemsCount.value = trackingRepository.getLogsCount() + onActionDone.call(ReversibleAction(R.string.updates_feed_cleared, null)) + } finally { + loadingKeys.update { it - AppSettings.KEY_UPDATES_FEED_CLEAR } + } } } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt index 964bb3333..3e5bc104d 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/stats/ui/StatsActivity.kt @@ -63,7 +63,7 @@ class StatsActivity : BaseActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityStatsBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val adapter = BaseListAdapter() .addDelegate(ListItemType.FEED, statsAD(this)) .addListListener(this) diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt index 8cb875558..70eabceb9 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt @@ -30,7 +30,7 @@ class TrackerDebugActivity : BaseActivity(), OnList override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityTrackerDebugBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + setDisplayHomeAsUp(true, false) val tracksAdapter = BaseListAdapter() .addDelegate(ListItemType.FEED, trackDebugAD(this, coil, this)) with(viewBinding.recyclerView) { diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt index 32d9394a1..f5a42535f 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/recent/RecentWidgetConfigActivity.kt @@ -12,7 +12,6 @@ import org.koitharu.kotatsu.core.ui.BaseActivity import org.koitharu.kotatsu.core.util.ext.consumeAllSystemBarsInsets import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityAppwidgetRecentBinding -import com.google.android.material.R as materialR @AndroidEntryPoint class RecentWidgetConfigActivity : @@ -24,10 +23,7 @@ class RecentWidgetConfigActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityAppwidgetRecentBinding.inflate(layoutInflater)) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) viewBinding.buttonDone.setOnClickListener(this) val appWidgetId = intent?.getIntExtra( AppWidgetManager.EXTRA_APPWIDGET_ID, diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt index afa3aec44..4c2ee770e 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/widget/shelf/ShelfWidgetConfigActivity.kt @@ -20,7 +20,6 @@ import org.koitharu.kotatsu.core.util.ext.systemBarsInsets import org.koitharu.kotatsu.databinding.ActivityAppwidgetShelfBinding import org.koitharu.kotatsu.widget.shelf.adapter.CategorySelectAdapter import org.koitharu.kotatsu.widget.shelf.model.CategoryItem -import com.google.android.material.R as materialR @AndroidEntryPoint class ShelfWidgetConfigActivity : @@ -36,10 +35,7 @@ class ShelfWidgetConfigActivity : override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityAppwidgetShelfBinding.inflate(layoutInflater)) - supportActionBar?.run { - setDisplayHomeAsUpEnabled(true) - setHomeAsUpIndicator(materialR.drawable.abc_ic_clear_material) - } + setDisplayHomeAsUp(true, true) adapter = CategorySelectAdapter(this) viewBinding.recyclerView.adapter = adapter viewBinding.buttonDone.setOnClickListener(this) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c9a32a03..b0b254ffe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -816,4 +816,6 @@ You can submit a bug report to the developers. This will help us investigate and fix the issue. Link to manga on %s Link to manga in Kotatsu + Clear browser data + Clear browser data such as cache and cookies. Warning: Authorization in manga sources may become invalid diff --git a/app/src/main/res/xml/pref_storage.xml b/app/src/main/res/xml/pref_storage.xml index 87fb9bf24..7ff1291e9 100644 --- a/app/src/main/res/xml/pref_storage.xml +++ b/app/src/main/res/xml/pref_storage.xml @@ -49,6 +49,12 @@ android:summary="@string/clear_cookies_summary" android:title="@string/clear_cookies" /> + +