diff --git a/app/build.gradle b/app/build.gradle index 306555035..37c28fe9f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,8 +15,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdkVersion 21 targetSdkVersion 33 - versionCode 517 - versionName '4.4.1' + versionCode 518 + versionName '4.4.2' generatedDensities = [] testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -87,7 +87,7 @@ afterEvaluate { } } dependencies { - implementation('com.github.KotatsuApp:kotatsu-parsers:f4c47b5b84') { + implementation('com.github.KotatsuApp:kotatsu-parsers:1093584202') { exclude group: 'org.json', module: 'json' } @@ -124,8 +124,8 @@ dependencies { implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl:4.3.2' implementation 'com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:4.3.2' - implementation 'com.google.dagger:hilt-android:2.44.2' - kapt 'com.google.dagger:hilt-compiler:2.44.2' + implementation 'com.google.dagger:hilt-android:2.45' + kapt 'com.google.dagger:hilt-compiler:2.45' implementation 'androidx.hilt:hilt-work:1.0.0' kapt 'androidx.hilt:hilt-compiler:1.0.0' @@ -154,6 +154,6 @@ dependencies { androidTestImplementation 'androidx.room:room-testing:2.5.0' androidTestImplementation 'com.squareup.moshi:moshi-kotlin:1.14.0' - androidTestImplementation 'com.google.dagger:hilt-android-testing:2.44.2' - kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.44.2' + androidTestImplementation 'com.google.dagger:hilt-android-testing:2.45' + kaptAndroidTest 'com.google.dagger:hilt-android-compiler:2.45' } diff --git a/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt index 565f5f653..a02e42b42 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/AppModule.kt @@ -96,6 +96,9 @@ interface AppModule { writeTimeout(20, TimeUnit.SECONDS) cookieJar(cookieJar) dns(DoHManager(cache, settings)) + if (settings.isSSLBypassEnabled) { + bypassSSLErrors() + } cache(cache) addInterceptor(GZipInterceptor()) addInterceptor(commonHeadersInterceptor) diff --git a/app/src/main/java/org/koitharu/kotatsu/core/network/SSLBypass.kt b/app/src/main/java/org/koitharu/kotatsu/core/network/SSLBypass.kt new file mode 100644 index 000000000..ed1221613 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/network/SSLBypass.kt @@ -0,0 +1,30 @@ +package org.koitharu.kotatsu.core.network + +import android.annotation.SuppressLint +import okhttp3.OkHttpClient +import org.koitharu.kotatsu.utils.ext.printStackTraceDebug +import java.security.SecureRandom +import java.security.cert.X509Certificate +import javax.net.ssl.SSLContext +import javax.net.ssl.SSLSocketFactory +import javax.net.ssl.X509TrustManager + +@SuppressLint("CustomX509TrustManager") +fun OkHttpClient.Builder.bypassSSLErrors() = also { builder -> + runCatching { + val trustAllCerts = object : X509TrustManager { + override fun checkClientTrusted(chain: Array, authType: String) = Unit + + override fun checkServerTrusted(chain: Array, authType: String) = Unit + + override fun getAcceptedIssuers(): Array = emptyArray() + } + val sslContext = SSLContext.getInstance("SSL") + sslContext.init(null, arrayOf(trustAllCerts), SecureRandom()) + val sslSocketFactory: SSLSocketFactory = sslContext.socketFactory + builder.sslSocketFactory(sslSocketFactory, trustAllCerts) + builder.hostnameVerifier { _, _ -> true } + }.onFailure { + it.printStackTraceDebug() + } +} diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index fd0518318..3faf6e5b7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -255,6 +255,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { val dnsOverHttps: DoHProvider get() = prefs.getEnumValue(KEY_DOH, DoHProvider.NONE) + val isSSLBypassEnabled: Boolean + get() = prefs.getBoolean(KEY_SSL_BYPASS, false) + var localListOrder: SortOrder get() = prefs.getEnumValue(KEY_LOCAL_LIST_ORDER, SortOrder.NEWEST) set(value) = prefs.edit { putEnumValue(KEY_LOCAL_LIST_ORDER, value) } @@ -393,6 +396,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) { const val KEY_SOURCES_GRID = "sources_grid" const val KEY_UPDATES_UNSTABLE = "updates_unstable" const val KEY_TIPS_CLOSED = "tips_closed" + const val KEY_SSL_BYPASS = "ssl_bypass" // About const val KEY_APP_UPDATE = "app_update" diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt index b93cb6f5f..5f74b3b2d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/SourceSettings.kt @@ -23,6 +23,7 @@ class SourceSettings(context: Context, source: MangaSource) : MangaSourceConfig @Suppress("UNCHECKED_CAST") override fun get(key: ConfigKey): T { return when (key) { + is ConfigKey.UserAgent -> prefs.getString(key.key, key.defaultValue).ifNullOrEmpty { key.defaultValue } is ConfigKey.Domain -> prefs.getString(key.key, key.defaultValue).ifNullOrEmpty { key.defaultValue } is ConfigKey.ShowSuspiciousContent -> prefs.getBoolean(key.key, key.defaultValue) } as T diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/ContentSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/ContentSettingsFragment.kt index 61da14d36..872caac79 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/ContentSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/ContentSettingsFragment.kt @@ -5,6 +5,7 @@ import android.os.Bundle import android.view.View import androidx.preference.ListPreference import androidx.preference.Preference +import com.google.android.material.snackbar.Snackbar import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.koitharu.kotatsu.R @@ -85,6 +86,10 @@ class ContentSettingsFragment : AppSettings.KEY_SOURCES_HIDDEN -> { bindRemoteSourcesSummary() } + + AppSettings.KEY_SSL_BYPASS -> { + Snackbar.make(listView, R.string.settings_apply_restart_required, Snackbar.LENGTH_INDEFINITE).show() + } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsExt.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsExt.kt index 41a2639a9..5137fe95e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsExt.kt @@ -37,6 +37,21 @@ fun PreferenceFragmentCompat.addPreferencesFromRepository(repository: RemoteMang } } + is ConfigKey.UserAgent -> { + EditTextPreference(requireContext()).apply { + summaryProvider = EditTextDefaultSummaryProvider(key.defaultValue) + setOnBindEditTextListener( + EditTextBindListener( + inputType = EditorInfo.TYPE_CLASS_TEXT, + hint = key.defaultValue, + validator = null, + ), + ) + setTitle(R.string.user_agent) + setDialogTitle(R.string.user_agent) + } + } + is ConfigKey.ShowSuspiciousContent -> { SwitchPreferenceCompat(requireContext()).apply { setDefaultValue(key.defaultValue) diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/utils/ThemeChooserPreference.kt b/app/src/main/java/org/koitharu/kotatsu/settings/utils/ThemeChooserPreference.kt index 2775014b0..d2ef58f50 100644 --- a/app/src/main/java/org/koitharu/kotatsu/settings/utils/ThemeChooserPreference.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/utils/ThemeChooserPreference.kt @@ -19,6 +19,7 @@ import androidx.preference.PreferenceViewHolder import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.ColorScheme import org.koitharu.kotatsu.databinding.ItemColorSchemeBinding +import java.lang.ref.WeakReference class ThemeChooserPreference @JvmOverloads constructor( context: Context, @@ -68,7 +69,7 @@ class ThemeChooserPreference @JvmOverloads constructor( } scrollView.viewTreeObserver.run { scrollPersistListener?.let { removeOnScrollChangedListener(it) } - scrollPersistListener = ScrollPersistListener(scrollView, lastScrollPosition) + scrollPersistListener = ScrollPersistListener(WeakReference(scrollView), lastScrollPosition) addOnScrollChangedListener(scrollPersistListener) } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { @@ -106,7 +107,6 @@ class ThemeChooserPreference @JvmOverloads constructor( } super.onRestoreInstanceState(state.superState) lastScrollPosition[0] = state.scrollPosition - // notifyChanged() } private fun setValueInternal(enumName: String, notifyChanged: Boolean) { @@ -152,11 +152,12 @@ class ThemeChooserPreference @JvmOverloads constructor( } private class ScrollPersistListener( - private val scrollView: HorizontalScrollView, + private val scrollViewRef: WeakReference, private val lastScrollPosition: IntArray, ) : ViewTreeObserver.OnScrollChangedListener { override fun onScrollChanged() { + val scrollView = scrollViewRef.get() ?: return lastScrollPosition[0] = scrollView.scrollX } } diff --git a/app/src/main/res/values-fil/plurals.xml b/app/src/main/res/values-fil/plurals.xml index 64bc20070..b7a6d36c8 100644 --- a/app/src/main/res/values-fil/plurals.xml +++ b/app/src/main/res/values-fil/plurals.xml @@ -1,12 +1,12 @@ - %1$d (na) aytem - %1$d (na mga) aytem + %1$d aytem + %1$d (na) aytem - Kabuuang %1$d (na) pahina - Kabuuang %1$d (na) mga pahina + "Kabuuang %1$d pahina" + Kabuuang %1$d (na) pahina %1$d minutong nakakalipas @@ -14,15 +14,15 @@ %1$d bagong kabanata - %1$d bagong (mga) kabanata + %1$d mga bagong kabanata - %1$d (na) kabanata - %1$d (na mga) kabanata + "%1$d kabanata" + %1$d (na) kabanata - %1$d (na) kabanata mula sa %2$d - %1$d (na) mga kabanata mula sa %2$d + %1$d kabanata mula sa %2$d + %1$d (na) kabanata mula sa %2$d %1$d oras ang nakalipas diff --git a/app/src/main/res/values-fil/strings.xml b/app/src/main/res/values-fil/strings.xml index c34ef549f..4f2580543 100644 --- a/app/src/main/res/values-fil/strings.xml +++ b/app/src/main/res/values-fil/strings.xml @@ -8,7 +8,7 @@ Tema Madilim Sundan ang sistema - May naganap na error + May nangyaring error Error sa network Mga detalye Mga kabanata @@ -49,8 +49,8 @@ Subukang i-reformulate ang query. Ang iyong nabasa ay ipapakita dito Ang iyong manga ay ipapakita dito - Mag-save muna - I save ito mula sa mga online na mapagkukunan o mag import ng mga file. + Mag-save muna ng isang bagay + I-save ito mula sa mga online na source o mag import ng mga file. Istante Animasyon ng pahina Hindi magagamit @@ -137,7 +137,7 @@ Detalyadong listahan Grid Mga setting - Mga remote na mapagkukunan + Mga remote na source Naglo-load… Isara Walang nahanap @@ -169,7 +169,7 @@ I-clear ang mga cookie I-clear ang page cache I-save - Ipakita ang notification kung may available na bagong bersyon + Ipakita ang abiso kung may available na bagong bersyon I-download Mga setting ng abiso Tunog ng abiso @@ -214,7 +214,7 @@ Ang ilang device ay may iba\'t ibang gawi ng system, na maaaring masira ang mga gawain sa background. Nakapila na I-download o basahin ang nawawalang kabanata online. - Mala-log out ka mula sa lahat ng mapagkukunan + Mala-log out ka mula sa lahat ng source Tapos na Alisin ang lahat ng kamakailang query sa paghahanap nang permanente\? Pagsasalin @@ -237,7 +237,175 @@ Nagco-compute… Kabanata %1$d ng %2$d Subukan ulit - Pagkakasunud-sunod ng pag-uuri + Pag-aayos ng order I-clear Natanggal ang \"%s\" sa kasaysayan + Mga taps ng gilid + Mga ginamit na source + Magagamit na mga source + Lagi na lang + I-preload ang mga pahina + Naka-log in bilang %s + Iba\'t ibang wika + Maghanap ng kabanata + %1$s%% + Hitsura + Hindi isali ang mga genre + Tukuyin ang mga genre na hindi mo nais na makita sa mga mungkahi + Nakumpleto na ang pagtanggal + Tumutulong na maiwasan ang pag-block ng iyong IP address + Naka-save na pagproseso ng manga + Mayroon nang account + Bumalik + Pag-synchronize + Ilagay ang iyong email upang magpatuloy + Itago + May mga bagong source ng manga + Hindi ka makakatanggap ng mga abiso ngunit ang mga bagong kabanata ay iha-highlight sa mga listahan + Paganahin ang mga abiso + Ayusin ang kategorya + Tina-track + Walang mga paboritong kategorya + Mag-log out + Magdagdag ng bookmark + Tinanggal ang bookmark + Inalis sa kasaysayan + DNS sa HTTPS + Default na mode + Automatikong matukoy ang reader mode + May nangyaring mali. Mangyaring magsumite ng isang bug report sa mga developer upang matulungan kaming ayusin ito. + Ipadala + Muling pagbabasa + Binitawan + Manga mula sa iyong mga paborito + Ang iyong kamakailang nabasa na manga + Pagtanggal ng data + Ipakita ang porsyento na nabasa sa kasaysayan at mga paborito + Ipakita lahat + Pumili ng saklaw + I-clear ang lahat ng kasaysayan + Maaari kang lumikha ng bookmark habang nagbabasa ng manga + Tinanggal ang mga bookmark + Random + Walang mga source ng manga + Paganahin ang mga source ng manga upang basahin ang manga online + Ayusin muli + Walang laman + Changelog + Pindutin muli ang Bumalik upang lumabas + Pindutin ang Bumalik nang dalawang beses upang lumabas sa app + Pagkumpirma ng paglabas + Na-save na manga + Mag-Explore + Iba pang cache + Paggamit ng storage + Magagamit na + %s - %s + Inalis sa mga paborito + Inalis mula sa \"%s\" + Mga pagpipilian + Nagda-download ng manga + Incognito mode + Magagamit ang pag update ng application: %s + Walang mga kabanata + Awtomatikong pag-scroll + Ch. %1$d/%2$d Pg. %3$d/%4$d + Ipakita ang information bar sa pagbasa + Archive ng mga comics + Folder na may mga larawan + Nakumpleto na ang pag-import + Magsisimula na ang pag-import + Feed + Gawing magagamit ang kamakailang manga sa pamamagitan ng mahabang pagpindot sa icon ng application + Ipakita ang mga kamakailang manga shortcut + Ergonomic na kontrol sa mambabasa + Pagwawasto ng kulay + Liwanag + Kaibahan + I-save o kalimutan ang mga hindi na-save na pagbabago\? + Kalimutan + Walang natitirang espasyo sa device + Pag-zoom sa webtoon + Iba\'t ibang wika + Server side error (%1$d). Subukang muli mamaya + I-clear din ang impormasyon tungkol sa mga bagong kabanata + Preloading ng nilalaman + Markahan bilang kasalukuyan + Wika + Ibahagi ang mga log + Magpakita ng kahina-hinalang nilalaman + Dynamic + Ipakita sa grid view + Asuka + Mion + Rikka + Sakura + Mamimi + Kanade + Wala naman dito + Mga serbisyo + Payagan ang mga hindi stable na update + Ipakita ang mga tagapagpahiwatig ng progress ng pagbabasa + Manga na minarkahan bilang NSFW ay hindi kailanman idadagdag sa kasaysayan at ang iyong progress ay hindi mase-save + Maaaring makatulong sa kaso ng ilang mga isyu. Ang lahat ng pahintulot ay mawawalan ng bisa + Imbalidong domain + Huling 2 oras + Nabura ang kasaysayan + Pamahalaan + Wala pang bookmark + 18+ + Hindi natagpuan o inalis ang nilalaman + Magtala ng ilang pagkilos para sa mga layunin ng pag-debug + Permanenteng tanggalin ang mga napiling item sa device\? + Walang mga kabanata sa manga na ito + Nag-a-update ang mga mungkahi + Nilalaman + I-download ang lahat ng napiling manga at ang mga kabanata nito\? Maaari itong kumonsumo ng maraming trapiko at storage. + Mga parallel na pag-download + Pagbagal ng pag-download + Tatanggalin ang mga chapters sa background. Maaari itong tumagal ng ilang oras + Kinansela + I-sync ang iyong data + Tingnan ang mga bagong kabanata at ipaalam ang tungkol dito + Pangalan + I-edit + Tanggalin ang bookmark + Makakatanggap ka ng mga abiso tungkol sa mga update ng manga na iyong binabasa + Mag-undo + Nagbabasa + Cache ng mga pahina + Mga bookmark + Sigurado ka bang gusto mong tanggalin ang mga napiling paboritong kategorya\? +\nAng lahat ng manga sa loob nito ay mawawala at hindi na ito mababawi. + Idinagdag ang bookmark + Awtomatikong matukoy kung ang manga ay webtoon + Huwag paganahin ang pag-optimize ng baterya + Tumutulong sa mga pagsusuri sa mga update sa background + Nakaplano + Nakumpleto na + Naka-hold + Huwag paganahin ang lahat + Gumamit ng fingerprint kung magagamit + Ulat + Ilagay ang iyong email upang magpatuloy + I-reset + Magmungkahi ng mga update sa mga beta na bersyon ng app + Hindi magagamit ang network + I-on ang Wi-Fi o mobile network para magbasa ng manga online + Naka-off + %ss + Mag-tap sa kanang gilid o ang pagpindot sa kanang key ay palaging lilipat sa susunod na pahina + Ipakita ang slider ng paglipat ng pahina + Mga detalye ng error:<br><tt>%1$s</tt><br><br>1. Subukang <a href=%2$s>buksan ang manga sa isang web browser</a> upang matiyak na magagamit ito sa source<br>nito 2. Kung magagamit ito, magpadala ng isang ulat ng error sa mga developer. + Paganahin ang pag-log + Hindi pinagana ang source + Pag-import ng manga + Maaari mong tanggalin ang orihinal na file mula sa storage upang makatipid ng espasyo + Ang napiling mga setting ng kulay ay matatandaan para sa manga na ito + Payagan ang pag-zoom in/zoom out na galaw sa webtoon mode (beta) + Compact + Upang subaybayan ang pag unlad ng pagbabasa, piliin ang Menu → Track sa screen ng mga detalye ng manga. + Nagsimula na ang pag-download + Scheme ng kulay + Miku \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f5bca9af9..7eb7b4ecb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -426,4 +426,6 @@ Download started Got it Tap and hold on an item to reorder them + UserAgent header + Please restart the application to apply these changes diff --git a/app/src/main/res/xml/pref_content.xml b/app/src/main/res/xml/pref_content.xml index bf617ab66..cc679251b 100644 --- a/app/src/main/res/xml/pref_content.xml +++ b/app/src/main/res/xml/pref_content.xml @@ -20,12 +20,6 @@ android:title="@string/suggestions" app:allowDividerAbove="true" /> - - + + + +