mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-21 15:31:49 +01:00
Tweak tablet UI mode setting (#8262)
This commit is contained in:
parent
b3557e844c
commit
d558f9e1d6
@ -166,7 +166,6 @@ dependencies {
|
||||
implementation(compose.activity)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material3.core)
|
||||
implementation(compose.material3.windowsizeclass)
|
||||
implementation(compose.material3.adapter)
|
||||
implementation(compose.material.icons)
|
||||
implementation(compose.animation)
|
||||
@ -324,7 +323,6 @@ tasks {
|
||||
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
|
||||
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
|
||||
"-opt-in=androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi",
|
||||
"-opt-in=androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi",
|
||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"-opt-in=kotlinx.coroutines.FlowPreview",
|
||||
"-opt-in=kotlinx.coroutines.InternalCoroutinesApi",
|
||||
|
@ -30,7 +30,6 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -72,7 +71,7 @@ import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
||||
fun MangaScreen(
|
||||
state: MangaScreenState.Success,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
windowWidthSizeClass: WindowWidthSizeClass,
|
||||
isTabletUi: Boolean,
|
||||
onBackClicked: () -> Unit,
|
||||
onChapterClicked: (Chapter) -> Unit,
|
||||
onDownloadChapter: ((List<ChapterItem>, ChapterDownloadAction) -> Unit)?,
|
||||
@ -105,7 +104,7 @@ fun MangaScreen(
|
||||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
) {
|
||||
if (windowWidthSizeClass == WindowWidthSizeClass.Compact) {
|
||||
if (!isTabletUi) {
|
||||
MangaScreenSmallImpl(
|
||||
state = state,
|
||||
snackbarHostState = snackbarHostState,
|
||||
@ -136,7 +135,6 @@ fun MangaScreen(
|
||||
} else {
|
||||
MangaScreenLargeImpl(
|
||||
state = state,
|
||||
windowWidthSizeClass = windowWidthSizeClass,
|
||||
snackbarHostState = snackbarHostState,
|
||||
onBackClicked = onBackClicked,
|
||||
onChapterClicked = onChapterClicked,
|
||||
@ -308,7 +306,7 @@ private fun MangaScreenSmallImpl(
|
||||
contentType = MangaScreenItem.INFO_BOX,
|
||||
) {
|
||||
MangaInfoBox(
|
||||
windowWidthSizeClass = WindowWidthSizeClass.Compact,
|
||||
isTabletUi = false,
|
||||
appBarPadding = topPadding,
|
||||
title = state.manga.title,
|
||||
author = state.manga.author,
|
||||
@ -373,7 +371,6 @@ private fun MangaScreenSmallImpl(
|
||||
@Composable
|
||||
fun MangaScreenLargeImpl(
|
||||
state: MangaScreenState.Success,
|
||||
windowWidthSizeClass: WindowWidthSizeClass,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
onBackClicked: () -> Unit,
|
||||
onChapterClicked: (Chapter) -> Unit,
|
||||
@ -505,7 +502,7 @@ fun MangaScreenLargeImpl(
|
||||
.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
MangaInfoBox(
|
||||
windowWidthSizeClass = windowWidthSizeClass,
|
||||
isTabletUi = true,
|
||||
appBarPadding = contentPadding.calculateTopPadding(),
|
||||
title = state.manga.title,
|
||||
author = state.manga.author,
|
||||
|
@ -43,7 +43,6 @@ import androidx.compose.material3.ProvideTextStyle
|
||||
import androidx.compose.material3.SuggestionChip
|
||||
import androidx.compose.material3.SuggestionChipDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -88,7 +87,7 @@ private val whitespaceLineRegex = Regex("[\\r\\n]{2,}", setOf(RegexOption.MULTIL
|
||||
@Composable
|
||||
fun MangaInfoBox(
|
||||
modifier: Modifier = Modifier,
|
||||
windowWidthSizeClass: WindowWidthSizeClass,
|
||||
isTabletUi: Boolean,
|
||||
appBarPadding: Dp,
|
||||
title: String,
|
||||
author: String?,
|
||||
@ -123,7 +122,7 @@ fun MangaInfoBox(
|
||||
|
||||
// Manga & source info
|
||||
CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
|
||||
if (windowWidthSizeClass == WindowWidthSizeClass.Compact) {
|
||||
if (!isTabletUi) {
|
||||
MangaAndSourceTitlesSmall(
|
||||
appBarPadding = appBarPadding,
|
||||
coverDataProvider = coverDataProvider,
|
||||
|
@ -27,8 +27,6 @@ import cafe.adriel.voyager.navigator.currentOrThrow
|
||||
import eu.kanade.domain.base.BasePreferences
|
||||
import eu.kanade.domain.library.service.LibraryPreferences
|
||||
import eu.kanade.domain.manga.repository.MangaRepository
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.domain.ui.model.TabletUiMode
|
||||
import eu.kanade.presentation.more.settings.Preference
|
||||
import eu.kanade.presentation.util.collectAsState
|
||||
import eu.kanade.tachiyomi.R
|
||||
@ -110,7 +108,6 @@ class SettingsAdvancedScreen : SearchableSettings {
|
||||
getNetworkGroup(networkPreferences = networkPreferences),
|
||||
getLibraryGroup(),
|
||||
getExtensionsGroup(basePreferences = basePreferences),
|
||||
getDisplayGroup(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -390,24 +387,4 @@ class SettingsAdvancedScreen : SearchableSettings {
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getDisplayGroup(): Preference.PreferenceGroup {
|
||||
val context = LocalContext.current
|
||||
val uiPreferences = remember { Injekt.get<UiPreferences>() }
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(R.string.pref_category_display),
|
||||
preferenceItems = listOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = uiPreferences.tabletUiMode(),
|
||||
title = stringResource(R.string.pref_tablet_ui_mode),
|
||||
entries = TabletUiMode.values().associateWith { stringResource(it.titleResId) },
|
||||
onValueChanged = {
|
||||
context.toast(R.string.requires_app_restart)
|
||||
true
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,14 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.app.ActivityCompat
|
||||
import eu.kanade.domain.ui.UiPreferences
|
||||
import eu.kanade.domain.ui.model.TabletUiMode
|
||||
import eu.kanade.domain.ui.model.ThemeMode
|
||||
import eu.kanade.domain.ui.model.setAppCompatDelegateThemeMode
|
||||
import eu.kanade.presentation.more.settings.Preference
|
||||
import eu.kanade.presentation.util.collectAsState
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.isAutoTabletUiAvailable
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.merge
|
||||
@ -40,7 +42,7 @@ class SettingsAppearanceScreen : SearchableSettings {
|
||||
|
||||
return listOf(
|
||||
getThemeGroup(context = context, uiPreferences = uiPreferences),
|
||||
getNavigationGroup(context = context, uiPreferences = uiPreferences),
|
||||
getDisplayGroup(context = context, uiPreferences = uiPreferences),
|
||||
getTimestampGroup(uiPreferences = uiPreferences),
|
||||
)
|
||||
}
|
||||
@ -99,18 +101,38 @@ class SettingsAppearanceScreen : SearchableSettings {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getNavigationGroup(
|
||||
private fun getDisplayGroup(
|
||||
context: Context,
|
||||
uiPreferences: UiPreferences,
|
||||
): Preference.PreferenceGroup {
|
||||
val tabletUiModePref = uiPreferences.tabletUiMode()
|
||||
val tabletUiMode by tabletUiModePref.collectAsState()
|
||||
|
||||
val isTabletUiAvailable = remember(tabletUiMode) { // won't survive config change
|
||||
when (tabletUiMode) {
|
||||
TabletUiMode.AUTOMATIC -> context.resources.configuration.isAutoTabletUiAvailable()
|
||||
TabletUiMode.NEVER -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
return Preference.PreferenceGroup(
|
||||
title = stringResource(R.string.pref_category_navigation),
|
||||
enabled = remember(context) { context.isTablet() },
|
||||
title = stringResource(R.string.pref_category_display),
|
||||
preferenceItems = listOf(
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = tabletUiModePref,
|
||||
title = stringResource(R.string.pref_tablet_ui_mode),
|
||||
entries = TabletUiMode.values().associateWith { stringResource(it.titleResId) },
|
||||
onValueChanged = {
|
||||
context.toast(R.string.requires_app_restart)
|
||||
true
|
||||
},
|
||||
),
|
||||
Preference.PreferenceItem.ListPreference(
|
||||
pref = uiPreferences.sideNavIconAlignment(),
|
||||
title = stringResource(R.string.pref_side_nav_icon_alignment),
|
||||
subtitle = "%s",
|
||||
enabled = isTabletUiAvailable,
|
||||
entries = mapOf(
|
||||
0 to stringResource(R.string.alignment_top),
|
||||
1 to stringResource(R.string.alignment_center),
|
||||
|
@ -1,24 +0,0 @@
|
||||
package eu.kanade.presentation.util
|
||||
|
||||
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
fun calculateWindowWidthSizeClass(): WindowWidthSizeClass {
|
||||
val configuration = LocalConfiguration.current
|
||||
return fromWidth(configuration.smallestScreenWidthDp.dp)
|
||||
}
|
||||
|
||||
private fun fromWidth(width: Dp): WindowWidthSizeClass {
|
||||
require(width >= 0.dp) { "Width must not be negative" }
|
||||
return when {
|
||||
width < 720.dp -> WindowWidthSizeClass.Compact // Was 600
|
||||
width < 840.dp -> WindowWidthSizeClass.Medium
|
||||
else -> WindowWidthSizeClass.Expanded
|
||||
}
|
||||
}
|
@ -65,7 +65,7 @@ import eu.kanade.tachiyomi.util.lang.launchUI
|
||||
import eu.kanade.tachiyomi.util.preference.asHotFlow
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getThemeColor
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.isTabletUi
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
||||
@ -610,7 +610,7 @@ class MainActivity : BaseActivity() {
|
||||
binding.appbar.isVisible = !isComposeController
|
||||
binding.controllerContainer.enableScrollingBehavior(!isComposeController)
|
||||
|
||||
if (!isTablet()) {
|
||||
if (!isTabletUi()) {
|
||||
// Save lift state
|
||||
if (isPush) {
|
||||
if (router.backstackSize > 1) {
|
||||
|
@ -13,6 +13,7 @@ import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.core.os.bundleOf
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
@ -25,7 +26,6 @@ import eu.kanade.presentation.manga.DownloadAction
|
||||
import eu.kanade.presentation.manga.MangaScreen
|
||||
import eu.kanade.presentation.manga.components.DeleteChaptersDialog
|
||||
import eu.kanade.presentation.manga.components.DownloadCustomAmountDialog
|
||||
import eu.kanade.presentation.util.calculateWindowWidthSizeClass
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||
import eu.kanade.tachiyomi.data.download.model.Download
|
||||
@ -52,6 +52,7 @@ import eu.kanade.tachiyomi.ui.reader.ReaderActivity
|
||||
import eu.kanade.tachiyomi.ui.recent.history.HistoryController
|
||||
import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController
|
||||
import eu.kanade.tachiyomi.ui.webview.WebViewActivity
|
||||
import eu.kanade.tachiyomi.util.system.isTabletUi
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import kotlinx.coroutines.launch
|
||||
@ -112,10 +113,13 @@ class MangaController : FullComposeController<MangaPresenter> {
|
||||
val isHttpSource = remember { successState.source is HttpSource }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val configuration = LocalConfiguration.current
|
||||
val isTabletUi = remember { configuration.isTabletUi() } // won't survive config change
|
||||
|
||||
MangaScreen(
|
||||
state = successState,
|
||||
snackbarHostState = snackbarHostState,
|
||||
windowWidthSizeClass = calculateWindowWidthSizeClass(),
|
||||
isTabletUi = isTabletUi,
|
||||
onBackClicked = router::popCurrentController,
|
||||
onChapterClicked = this::openChapter,
|
||||
onDownloadChapter = this::onDownloadChapters.takeIf { !successState.source.isLocalOrStub() },
|
||||
|
@ -6,9 +6,10 @@ import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalConfiguration
|
||||
import androidx.core.os.bundleOf
|
||||
import cafe.adriel.voyager.navigator.Navigator
|
||||
import cafe.adriel.voyager.transitions.ScreenTransition
|
||||
@ -19,8 +20,8 @@ import eu.kanade.presentation.more.settings.screen.SettingsGeneralScreen
|
||||
import eu.kanade.presentation.more.settings.screen.SettingsMainScreen
|
||||
import eu.kanade.presentation.util.LocalBackPress
|
||||
import eu.kanade.presentation.util.LocalRouter
|
||||
import eu.kanade.presentation.util.calculateWindowWidthSizeClass
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BasicFullComposeController
|
||||
import eu.kanade.tachiyomi.util.system.isTabletUi
|
||||
|
||||
class SettingsMainController(bundle: Bundle = bundleOf()) : BasicFullComposeController(bundle) {
|
||||
|
||||
@ -39,8 +40,9 @@ class SettingsMainController(bundle: Bundle = bundleOf()) : BasicFullComposeCont
|
||||
@Composable
|
||||
override fun ComposeContent() {
|
||||
CompositionLocalProvider(LocalRouter provides router) {
|
||||
val widthSizeClass = calculateWindowWidthSizeClass()
|
||||
if (widthSizeClass == WindowWidthSizeClass.Compact) {
|
||||
val configuration = LocalConfiguration.current
|
||||
val isTabletUi = remember { configuration.isTabletUi() } // won't survive config change
|
||||
if (!isTabletUi) {
|
||||
Navigator(
|
||||
screen = if (toBackupScreen) {
|
||||
SettingsBackupScreen()
|
||||
|
@ -50,8 +50,6 @@ import java.io.File
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_DP = 720
|
||||
|
||||
/**
|
||||
* Copies a string to clipboard
|
||||
*
|
||||
@ -263,28 +261,46 @@ fun Context.createFileInCacheDir(name: String): File {
|
||||
return file
|
||||
}
|
||||
|
||||
/**
|
||||
* We consider anything with a width of >= 720dp as a tablet, i.e. with layouts in layout-sw720dp.
|
||||
*/
|
||||
fun Context.isTablet(): Boolean {
|
||||
return resources.configuration.smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP
|
||||
private const val TABLET_UI_REQUIRED_SCREEN_WIDTH_DP = 720
|
||||
|
||||
// some tablets have screen width like 711dp = 1600px / 2.25
|
||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP = 700
|
||||
|
||||
// make sure icons on the nav rail fit
|
||||
private const val TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP = 600
|
||||
|
||||
fun Context.isTabletUi(): Boolean {
|
||||
return resources.configuration.isTabletUi()
|
||||
}
|
||||
|
||||
fun Configuration.isTabletUi(): Boolean {
|
||||
return smallestScreenWidthDp >= TABLET_UI_REQUIRED_SCREEN_WIDTH_DP
|
||||
}
|
||||
|
||||
fun Configuration.isAutoTabletUiAvailable(): Boolean {
|
||||
return smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
||||
}
|
||||
|
||||
// TODO: move the logic to `isTabletUi()` when main activity is rewritten in Compose
|
||||
fun Context.prepareTabletUiContext(): Context {
|
||||
val configuration = resources.configuration
|
||||
val expected = when (Injekt.get<UiPreferences>().tabletUiMode().get()) {
|
||||
TabletUiMode.AUTOMATIC -> isTablet()
|
||||
TabletUiMode.AUTOMATIC ->
|
||||
configuration.smallestScreenWidthDp >= when (configuration.orientation) {
|
||||
Configuration.ORIENTATION_PORTRAIT -> TABLET_UI_MIN_SCREEN_WIDTH_PORTRAIT_DP
|
||||
else -> TABLET_UI_MIN_SCREEN_WIDTH_LANDSCAPE_DP
|
||||
}
|
||||
TabletUiMode.ALWAYS -> true
|
||||
TabletUiMode.LANDSCAPE -> configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
TabletUiMode.NEVER -> false
|
||||
}
|
||||
if (configuration.smallestScreenWidthDp >= TABLET_UI_MIN_SCREEN_WIDTH_DP != expected) {
|
||||
if (configuration.isTabletUi() != expected) {
|
||||
val overrideConf = Configuration()
|
||||
overrideConf.setTo(configuration)
|
||||
overrideConf.smallestScreenWidthDp = if (expected) {
|
||||
overrideConf.smallestScreenWidthDp.coerceAtLeast(TABLET_UI_MIN_SCREEN_WIDTH_DP)
|
||||
overrideConf.smallestScreenWidthDp.coerceAtLeast(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP)
|
||||
} else {
|
||||
overrideConf.smallestScreenWidthDp.coerceAtMost(TABLET_UI_MIN_SCREEN_WIDTH_DP - 1)
|
||||
overrideConf.smallestScreenWidthDp.coerceAtMost(TABLET_UI_REQUIRED_SCREEN_WIDTH_DP - 1)
|
||||
}
|
||||
return createConfigurationContext(overrideConf)
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import androidx.core.view.isVisible
|
||||
import androidx.customview.view.AbsSavedState
|
||||
import com.google.android.material.appbar.AppBarLayout
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.isTabletUi
|
||||
import eu.kanade.tachiyomi.util.view.findChild
|
||||
|
||||
/**
|
||||
@ -48,7 +48,7 @@ class TachiyomiCoordinatorLayout @JvmOverloads constructor(
|
||||
) {
|
||||
super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed)
|
||||
// Disable elevation overlay when tabs are visible
|
||||
if (context.isTablet().not()) {
|
||||
if (context.isTabletUi().not()) {
|
||||
if (target is ComposeView) {
|
||||
val scrollCondition = if (type == ViewCompat.TYPE_NON_TOUCH) {
|
||||
dyUnconsumed >= 0
|
||||
|
@ -13,7 +13,6 @@ ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose
|
||||
ui-util = { module = "androidx.compose.ui:ui-util", version.ref = "compose" }
|
||||
|
||||
material3-core = { module = "androidx.compose.material3:material3", version.ref = "material3" }
|
||||
material3-windowsizeclass = { module = "androidx.compose.material3:material3-window-size-class", version.ref = "material3" }
|
||||
material3-adapter = "com.google.android.material:compose-theme-adapter-3:1.0.20"
|
||||
material-icons = { module = "androidx.compose.material:material-icons-extended", version.ref = "compose" }
|
||||
|
||||
|
@ -187,7 +187,6 @@
|
||||
<string name="theme_yotsuba">Yotsuba</string>
|
||||
<string name="theme_tidalwave">Tidal Wave</string>
|
||||
<string name="pref_dark_theme_pure_black">Pure black dark mode</string>
|
||||
<string name="pref_category_navigation">Navigation</string>
|
||||
<string name="pref_side_nav_icon_alignment">Side navigation icon alignment</string>
|
||||
<string name="alignment_top">Top</string>
|
||||
<string name="alignment_center">Center</string>
|
||||
|
Loading…
Reference in New Issue
Block a user