Compare commits

...

3 Commits

Author SHA1 Message Date
Koitharu
e4e4f18066 Move read button to bottom 2024-05-18 18:20:58 +03:00
Koitharu
b1ab48e912 Option to disable connectivity check 2024-05-17 11:36:42 +03:00
Koitharu
a71e2dd289 Update settings ui and fix crash 2024-05-17 10:31:15 +03:00
16 changed files with 147 additions and 148 deletions

View File

@@ -95,9 +95,9 @@ dependencies {
implementation 'androidx.activity:activity-ktx:1.9.0'
implementation 'androidx.fragment:fragment-ktx:1.7.1'
implementation 'androidx.collection:collection-ktx:1.4.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
implementation 'androidx.lifecycle:lifecycle-service:2.7.0'
implementation 'androidx.lifecycle:lifecycle-process:2.7.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0'
implementation 'androidx.lifecycle:lifecycle-service:2.8.0'
implementation 'androidx.lifecycle:lifecycle-process:2.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.recyclerview:recyclerview:1.3.2'
@@ -105,7 +105,7 @@ dependencies {
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha05'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.7.0'
implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.0'
implementation 'androidx.webkit:webkit:1.11.0'
implementation 'androidx.work:work-runtime:2.9.0'

View File

@@ -34,6 +34,7 @@ import org.koitharu.kotatsu.core.os.NetworkState
import org.koitharu.kotatsu.core.parser.MangaLoaderContextImpl
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.favicon.FaviconFetcher
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.ui.image.CoilImageGetter
import org.koitharu.kotatsu.core.ui.util.ActivityRecreationHandle
import org.koitharu.kotatsu.core.util.AcraScreenLogger
@@ -70,8 +71,9 @@ interface AppModule {
@Provides
@Singleton
fun provideNetworkState(
@ApplicationContext context: Context
) = NetworkState(context.connectivityManager)
@ApplicationContext context: Context,
settings: AppSettings,
) = NetworkState(context.connectivityManager, settings)
@Provides
@Singleton

View File

@@ -5,13 +5,15 @@ import android.net.ConnectivityManager.NetworkCallback
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import kotlinx.coroutines.flow.first
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.util.MediatorStateFlow
import org.koitharu.kotatsu.core.util.ext.isOnline
class NetworkState(
private val connectivityManager: ConnectivityManager,
) : MediatorStateFlow<Boolean>(connectivityManager.isOnline()) {
private val settings: AppSettings,
) : MediatorStateFlow<Boolean>(connectivityManager.isOnline(settings)) {
private val callback = NetworkCallbackImpl()
@@ -22,6 +24,7 @@ class NetworkState(
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
.build()
connectivityManager.registerNetworkCallback(request, callback)
}
@@ -39,7 +42,7 @@ class NetworkState(
}
private fun invalidate() {
publishValue(connectivityManager.isOnline())
publishValue(connectivityManager.isOnline(settings))
}
private inner class NetworkCallbackImpl : NetworkCallback() {
@@ -50,4 +53,27 @@ class NetworkState(
override fun onUnavailable() = invalidate()
}
private companion object {
fun ConnectivityManager.isOnline(settings: AppSettings): Boolean {
if (settings.isOfflineCheckDisabled) {
return true
}
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activeNetwork?.let { isOnline(it) } ?: false
} else {
@Suppress("DEPRECATION")
activeNetworkInfo?.isConnected == true
}
}
private fun ConnectivityManager.isOnline(network: Network): Boolean {
val capabilities = getNetworkCapabilities(network) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
}
}
}

View File

@@ -136,6 +136,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
get() = prefs.getBoolean(KEY_TRAFFIC_WARNING, true)
set(value) = prefs.edit { putBoolean(KEY_TRAFFIC_WARNING, value) }
val isOfflineCheckDisabled: Boolean
get() = prefs.getBoolean(KEY_OFFLINE_DISABLED, false)
var isAllFavouritesVisible: Boolean
get() = prefs.getBoolean(KEY_ALL_FAVOURITES_VISIBLE, true)
set(value) = prefs.edit { putBoolean(KEY_ALL_FAVOURITES_VISIBLE, value) }
@@ -557,6 +560,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_COLOR_THEME = "color_theme"
const val KEY_THEME_AMOLED = "amoled_theme"
const val KEY_TRAFFIC_WARNING = "traffic_warning"
const val KEY_OFFLINE_DISABLED = "no_offline"
const val KEY_PAGES_CACHE_CLEAR = "pages_cache_clear"
const val KEY_HTTP_CACHE_CLEAR = "http_cache_clear"
const val KEY_COOKIES_CLEAR = "cookies_clear"

View File

@@ -92,8 +92,7 @@ abstract class BaseActivity<B : ViewBinding> :
}
override fun onSupportNavigateUp(): Boolean {
if (supportFragmentManager.backStackEntryCount > 0) {
supportFragmentManager.popBackStack()
if (supportFragmentManager.popBackStackImmediate()) {
return false
}
dispatchNavigateUp()

View File

@@ -19,6 +19,7 @@ import android.content.pm.ResolveInfo
import android.database.SQLException
import android.graphics.Bitmap
import android.graphics.Color
import android.net.ConnectivityManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
@@ -75,6 +76,9 @@ val Context.activityManager: ActivityManager?
val Context.powerManager: PowerManager?
get() = getSystemService(POWER_SERVICE) as? PowerManager
val Context.connectivityManager: ConnectivityManager
get() = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
fun String.toUriOrNull() = if (isEmpty()) null else Uri.parse(this)
suspend fun CoroutineWorker.trySetForeground(): Boolean = runCatchingCancellable {

View File

@@ -1,26 +0,0 @@
package org.koitharu.kotatsu.core.util.ext
import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.os.Build
val Context.connectivityManager: ConnectivityManager
get() = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
fun ConnectivityManager.isOnline(): Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
activeNetwork?.let { isOnline(it) } ?: false
} else {
@Suppress("DEPRECATION")
activeNetworkInfo?.isConnected == true
}
}
private fun ConnectivityManager.isOnline(network: Network): Boolean {
val capabilities = getNetworkCapabilities(network) ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
|| capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
}

View File

@@ -25,7 +25,6 @@ import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import coil.ImageLoader
import coil.request.ImageRequest
import coil.request.SuccessResult
@@ -135,7 +134,7 @@ class DetailsActivity :
viewBinding.buttonRead.setOnClickListener(this)
viewBinding.buttonRead.setOnLongClickListener(this)
viewBinding.buttonRead.setOnContextClickListenerCompat(this)
viewBinding.buttonDownload?.setOnClickListener(this)
// viewBinding.buttonDownload?.setOnClickListener(this)
viewBinding.infoLayout.chipBranch.setOnClickListener(this)
viewBinding.infoLayout.chipSize.setOnClickListener(this)
viewBinding.infoLayout.chipSource.setOnClickListener(this)
@@ -153,7 +152,7 @@ class DetailsActivity :
viewBinding.textViewDescription.movementMethod = LinkMovementMethodCompat.getInstance()
viewBinding.chipsTags.onChipClickListener = this
TitleScrollCoordinator(viewBinding.textViewTitle).attach(viewBinding.scrollView)
viewBinding.containerBottomSheet?.let { BottomSheetBehavior.from(it) }?.let { behavior ->
viewBinding.layoutBottomSheet?.let { BottomSheetBehavior.from(it) }?.let { behavior ->
onBackPressedDispatcher.addCallback(BottomSheetCollapseCallback(behavior))
}
@@ -202,7 +201,7 @@ class DetailsActivity :
when (v.id) {
R.id.button_read -> openReader(isIncognitoMode = false)
R.id.chip_branch -> showBranchPopupMenu(v)
R.id.button_download -> DownloadDialogHelper(v, viewModel).show(menuProvider)
// R.id.button_download -> DownloadDialogHelper(v, viewModel).show(menuProvider)
R.id.chip_author -> {
val manga = viewModel.manga.value ?: return
@@ -409,18 +408,18 @@ class DetailsActivity :
}
private fun onLoadingStateChanged(isLoading: Boolean) {
val button = viewBinding.buttonDownload ?: return
if (isLoading) {
button.setImageDrawable(
CircularProgressDrawable(this).also {
it.setStyle(CircularProgressDrawable.LARGE)
it.setColorSchemeColors(getThemeColor(materialR.attr.colorControlNormal))
it.start()
},
)
} else {
button.setImageResource(R.drawable.ic_download)
}
// val button = null ?: return
// if (isLoading) {
// button.setImageDrawable(
// CircularProgressDrawable(this).also {
// it.setStyle(CircularProgressDrawable.LARGE)
// it.setColorSchemeColors(getThemeColor(materialR.attr.colorControlNormal))
// it.start()
// },
// )
// } else {
// button.setImageResource(R.drawable.ic_download)
// }
}
private fun onScrobblingInfoChanged(scrobblings: List<ScrobblingInfo>) {
@@ -536,7 +535,7 @@ class DetailsActivity :
val isFirstCall = buttonRead.tag == null
buttonRead.tag = Unit
buttonRead.setProgress(info.history?.percent?.coerceIn(0f, 1f) ?: 0f, !isFirstCall)
buttonDownload?.isEnabled = info.isValid && info.canDownload
// buttonDownload?.isEnabled = info.isValid && info.canDownload
buttonRead.isEnabled = info.isValid
}

View File

@@ -49,6 +49,7 @@ class ChaptersPagesSheet : BaseAdaptiveSheet<SheetChaptersPagesBinding>(), Actio
override fun onViewBindingCreated(binding: SheetChaptersPagesBinding, savedInstanceState: Bundle?) {
super.onViewBindingCreated(binding, savedInstanceState)
disableFitToContents()
binding.headerBar.isVisible = dialog != null
val args = arguments ?: Bundle.EMPTY
var defaultTab = args.getInt(ARG_TAB, settings.defaultDetailsTab)

View File

@@ -11,7 +11,6 @@ import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.fragment.app.commit
import androidx.preference.Preference
@@ -21,9 +20,7 @@ import dagger.hilt.android.AndroidEntryPoint
import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseActivity
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.util.ext.getSerializableExtraCompat
import org.koitharu.kotatsu.core.util.ext.isScrolledToTop
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ActivitySettingsBinding
import org.koitharu.kotatsu.main.ui.owners.AppBarOwner
@@ -39,17 +36,18 @@ import org.koitharu.kotatsu.settings.userdata.UserDataSettingsFragment
class SettingsActivity :
BaseActivity<ActivitySettingsBinding>(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
AppBarOwner,
FragmentManager.OnBackStackChangedListener {
AppBarOwner {
override val appBar: AppBarLayout
get() = viewBinding.appbar
private val isMasterDetails
get() = viewBinding.containerMaster != null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(ActivitySettingsBinding.inflate(layoutInflater))
supportActionBar?.setDisplayHomeAsUpEnabled(true)
val isMasterDetails = viewBinding.containerMaster != null
val fm = supportFragmentManager
val currentFragment = fm.findFragmentById(R.id.container)
if (currentFragment == null || (isMasterDetails && currentFragment is RootSettingsFragment)) {
@@ -63,21 +61,6 @@ class SettingsActivity :
}
}
override fun onTitleChanged(title: CharSequence?, color: Int) {
super.onTitleChanged(title, color)
viewBinding.collapsingToolbarLayout?.title = title
}
override fun onStart() {
super.onStart()
supportFragmentManager.addOnBackStackChangedListener(this)
}
override fun onStop() {
supportFragmentManager.removeOnBackStackChangedListener(this)
super.onStop()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.opt_settings, menu)
@@ -110,14 +93,6 @@ class SettingsActivity :
else -> super.onOptionsItemSelected(item)
}
override fun onBackStackChanged() {
val fragment = supportFragmentManager.findFragmentById(R.id.container) as? RecyclerViewOwner ?: return
val recyclerView = fragment.recyclerView
recyclerView.post {
viewBinding.appbar.setExpanded(recyclerView.isScrolledToTop, false)
}
}
override fun onPreferenceStartFragment(
caller: PreferenceFragmentCompat,
pref: Preference,
@@ -147,19 +122,17 @@ class SettingsActivity :
fun openFragment(fragment: Fragment, isFromRoot: Boolean) {
val hasFragment = supportFragmentManager.findFragmentById(R.id.container) != null
val isMasterDetail = viewBinding.containerMaster != null
supportFragmentManager.commit {
setReorderingAllowed(true)
replace(R.id.container, fragment)
setTransition(FragmentTransaction.TRANSIT_FRAGMENT_MATCH_ACTIVITY_OPEN)
if (!isMasterDetail || (hasFragment && !isFromRoot)) {
if (!isMasterDetails || (hasFragment && !isFromRoot)) {
addToBackStack(null)
}
}
}
private fun openDefaultFragment() {
val hasMaster = viewBinding.containerMaster != null
val fragment = when (intent?.action) {
ACTION_READER -> ReaderSettingsFragment()
ACTION_SUGGESTIONS -> SuggestionsSettingsFragment()
@@ -181,7 +154,7 @@ class SettingsActivity :
}
else -> null
} ?: if (hasMaster) AppearanceSettingsFragment() else RootSettingsFragment()
} ?: if (isMasterDetails) AppearanceSettingsFragment() else RootSettingsFragment()
supportFragmentManager.commit {
setReorderingAllowed(true)
replace(R.id.container, fragment)

View File

@@ -177,44 +177,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier_header" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="@dimen/margin_normal"
android:layout_marginEnd="12dp"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toStartOf="@id/button_download"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/info_layout"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<ImageView
android:id="@+id/button_download"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="16dp"
android:background="@drawable/bg_circle_button"
android:backgroundTint="?colorSecondaryContainer"
android:contentDescription="@string/download"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="@id/button_read"
app:layout_constraintDimensionRatio="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/button_read"
app:srcCompat="@drawable/ic_download" />
<TextView
android:id="@+id/textView_description_title"
android:layout_width="0dp"
@@ -229,7 +191,7 @@
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader"
app:layout_constraintEnd_toStartOf="@id/button_description_more"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_read" />
app:layout_constraintTop_toBottomOf="@id/info_layout" />
<Button
android:id="@+id/button_description_more"
@@ -396,19 +358,78 @@
</androidx.core.widget.NestedScrollView>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container_bottom_sheet"
android:name="org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_bottom_sheet"
style="@style/Widget.Material3.BottomSheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="6dp"
android:nestedScrollingEnabled="false"
android:outlineProvider="background"
app:behavior_fitToContents="false"
app:behavior_hideable="false"
app:behavior_peekHeight="@dimen/details_bs_peek_height"
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior"
tools:layout="@layout/sheet_chapters_pages" />
app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior">
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:id="@+id/drag_handle_sheet"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/button_download"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:background="@drawable/bg_circle_button"
android:backgroundTint="?colorSecondaryContainer"
android:contentDescription="@string/download"
android:scaleType="centerInside"
app:layout_constraintBottom_toBottomOf="@id/button_read"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/button_read"
app:srcCompat="@drawable/ic_download" />
<org.koitharu.kotatsu.core.ui.widgets.ProgressButton
android:id="@+id/button_read"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="12dp"
android:layout_marginTop="@dimen/margin_normal"
android:foreground="?selectableItemBackground"
android:gravity="center"
android:minWidth="240dp"
android:paddingHorizontal="6dp"
android:paddingVertical="8dp"
app:baseColor="?colorSecondaryContainer"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_download"
app:layout_constraintTop_toBottomOf="@id/drag_handle_sheet"
app:progressColor="?colorPrimary"
app:subtitleTextAppearance="?textAppearanceBodySmall"
app:titleTextAppearance="?textAppearanceButton"
tools:max="100"
tools:progress="40"
tools:subtitle="12 chapters"
tools:title="@string/read" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/container_bottom_sheet"
android:name="org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_below="@id/drag_handle_sheet"
android:elevation="6dp"
android:visibility="gone"
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/drag_handle_sheet"
tools:layout="@layout/sheet_chapters_pages" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -11,21 +11,11 @@
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/collapsingToolbarLayout"
style="?collapsingToolbarLayoutMediumStyle"
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?collapsingToolbarLayoutMediumSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
app:toolbarId="@id/toolbar">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.AppBarLayout>

View File

@@ -42,6 +42,7 @@
</string-array>
<string-array name="sync_host_list" translatable="false">
<item>@string/sync_host_default</item>
<item>moe.shirizu.org</item>
<item>86.57.183.214:8081</item>
</string-array>
<string-array name="values_proxy_types" translatable="false">

View File

@@ -35,7 +35,7 @@
<dimen name="chapter_grid_width">80dp</dimen>
<dimen name="side_card_offset">8dp</dimen>
<dimen name="webtoon_pages_gap">24dp</dimen>
<dimen name="details_bs_peek_height">92dp</dimen>
<dimen name="details_bs_peek_height">142dp</dimen>
<dimen name="search_suggestions_manga_height">142dp</dimen>
<dimen name="search_suggestions_manga_spacing">6dp</dimen>

View File

@@ -643,4 +643,5 @@
<string name="blocked_by_server_message">You are blocked by the server. Try to use a different network connection (VPN, Proxy, etc.)</string>
<string name="disable">Disable</string>
<string name="sources_disabled">Sources disabled</string>
<string name="disable_connectivity_check">Disable connectivity check</string>
</resources>

View File

@@ -49,4 +49,8 @@
android:key="ssl_bypass"
android:title="@string/ignore_ssl_errors" />
<SwitchPreferenceCompat
android:key="no_offline"
android:title="@string/disable_connectivity_check" />
</PreferenceScreen>