feat: move color and fonts to separate screen (#485)

This commit is contained in:
Diego Beraldin 2024-01-25 22:54:51 +01:00 committed by GitHub
parent 30152548d9
commit 4bdd0e61bc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
40 changed files with 630 additions and 497 deletions

View File

@ -0,0 +1,37 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors
import androidx.compose.ui.graphics.Color
import cafe.adriel.voyager.core.model.ScreenModel
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.CommentBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
interface SettingsColorAndFontMviModel :
MviModel<SettingsColorAndFontMviModel.Intent, SettingsColorAndFontMviModel.UiState, SettingsColorAndFontMviModel.Effect>,
ScreenModel {
sealed interface Intent {
data class ChangeDynamicColors(val value: Boolean) : Intent
}
data class UiState(
val isLogged: Boolean = false,
val supportsDynamicColors: Boolean = false,
val uiTheme: UiTheme? = null,
val dynamicColors: Boolean = false,
val customSeedColor: Color? = null,
val upVoteColor: Color? = null,
val downVoteColor: Color? = null,
val replyColor: Color? = null,
val saveColor: Color? = null,
val commentBarTheme: CommentBarTheme = CommentBarTheme.Blue,
val uiFontScale: FontScale = FontScale.Normal,
val uiFontFamily: UiFontFamily = UiFontFamily.Poppins,
val contentFontScale: FontScale = FontScale.Normal,
val contentFontFamily: UiFontFamily = UiFontFamily.Poppins,
)
sealed interface Effect
}

View File

@ -0,0 +1,263 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.input.nestedscroll.nestedScroll
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.scaleFactor
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getColorSchemeProvider
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.SettingsRow
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.SettingsSwitchRow
import com.github.diegoberaldin.raccoonforlemmy.core.navigation.di.getNavigationCoordinator
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.onClick
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallback
import com.github.diegoberaldin.raccoonforlemmy.core.utils.compose.rememberCallbackArgs
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components.SettingsColorRow
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components.SettingsMultiColorRow
import com.github.diegoberaldin.raccoonforlemmy.resources.MR
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.ColorBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.CommentBarThemeBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.VoteThemeBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosefont.FontFamilyBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosefont.FontScaleBottomSheet
import dev.icerock.moko.resources.compose.stringResource
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class SettingsColorAndFontScreen : Screen {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
override fun Content() {
val model = getScreenModel<SettingsColorAndFontMviModel>()
model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState()
val navigationCoordinator = remember { getNavigationCoordinator() }
val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
val themeRepository = remember { getThemeRepository() }
val scrollState = rememberScrollState()
val colorSchemeProvider = remember { getColorSchemeProvider() }
val defaultTheme = if (isSystemInDarkTheme()) {
UiTheme.Dark
} else {
UiTheme.Light
}
var uiFontSizeWorkaround by remember { mutableStateOf(true) }
LaunchedEffect(themeRepository) {
themeRepository.uiFontScale.drop(1).onEach {
uiFontSizeWorkaround = false
delay(50)
uiFontSizeWorkaround = true
}.launchIn(this)
}
if (!uiFontSizeWorkaround) {
return
}
Scaffold(
modifier = Modifier
.background(MaterialTheme.colorScheme.background)
.padding(Spacing.xs),
topBar = {
TopAppBar(
scrollBehavior = scrollBehavior,
title = {
Text(
modifier = Modifier.padding(horizontal = Spacing.s),
text = stringResource(MR.strings.settings_colors_and_fonts),
)
},
navigationIcon = {
if (navigationCoordinator.canPop.value) {
Image(
modifier = Modifier.onClick(
onClick = rememberCallback {
navigationCoordinator.popScreen()
},
),
imageVector = Icons.Default.ArrowBack,
contentDescription = null,
colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.onBackground),
)
}
},
)
},
) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection),
) {
Column(
modifier = Modifier.fillMaxSize().verticalScroll(scrollState),
verticalArrangement = Arrangement.spacedBy(Spacing.xs),
) {
// dynamic colors
if (uiState.supportsDynamicColors) {
SettingsSwitchRow(
title = stringResource(MR.strings.settings_dynamic_colors),
value = uiState.dynamicColors,
onValueChanged = rememberCallbackArgs(model) { value ->
model.reduce(
SettingsColorAndFontMviModel.Intent.ChangeDynamicColors(value)
)
},
)
}
// custom scheme seed color
SettingsColorRow(
title = stringResource(MR.strings.settings_custom_seed_color),
value = uiState.customSeedColor ?: colorSchemeProvider.getColorScheme(
theme = uiState.uiTheme ?: defaultTheme,
dynamic = uiState.dynamicColors,
).primary,
onTap = rememberCallback {
val sheet = ColorBottomSheet()
navigationCoordinator.showBottomSheet(sheet)
},
)
if (uiState.isLogged) {
// action colors
SettingsColorRow(
title = stringResource(MR.strings.settings_upvote_color),
value = uiState.upVoteColor ?: MaterialTheme.colorScheme.primary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 0,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_downvote_color),
value = uiState.downVoteColor ?: MaterialTheme.colorScheme.tertiary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 1,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_reply_color),
value = uiState.replyColor ?: MaterialTheme.colorScheme.secondary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 2,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_save_color),
value = uiState.saveColor
?: MaterialTheme.colorScheme.secondaryContainer,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 3,
)
navigationCoordinator.showBottomSheet(screen)
},
)
}
// comment bar theme
val commentBarColors =
themeRepository.getCommentBarColors(uiState.commentBarTheme)
SettingsMultiColorRow(
title = stringResource(MR.strings.settings_comment_bar_theme),
values = commentBarColors,
onTap = rememberCallback {
val screen = CommentBarThemeBottomSheet()
navigationCoordinator.showBottomSheet(screen)
}
)
// font family
SettingsRow(
title = stringResource(MR.strings.settings_ui_font_family),
value = uiState.uiFontFamily.toReadableName(),
onTap = rememberCallback {
val sheet = FontFamilyBottomSheet()
navigationCoordinator.showBottomSheet(sheet)
},
)
SettingsRow(
title = stringResource(MR.strings.settings_content_font_family),
value = uiState.contentFontFamily.toReadableName(),
onTap = rememberCallback {
val sheet = FontFamilyBottomSheet(content = true)
navigationCoordinator.showBottomSheet(sheet)
},
)
// font scale
SettingsRow(
title = stringResource(MR.strings.settings_ui_font_scale),
value = uiState.uiFontScale.toReadableName(),
onTap = rememberCallback {
val sheet = FontScaleBottomSheet(
values = listOf(
FontScale.Large,
FontScale.Normal,
FontScale.Small,
).map { it.scaleFactor },
content = false,
)
navigationCoordinator.showBottomSheet(sheet)
},
)
SettingsRow(
title = stringResource(MR.strings.settings_content_font_scale),
value = uiState.contentFontScale.toReadableName(),
onTap = rememberCallback {
val sheet = FontScaleBottomSheet(content = true)
navigationCoordinator.showBottomSheet(sheet)
},
)
}
}
}
}
}

View File

@ -0,0 +1,243 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.CommentBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toFontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toInt
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ColorSchemeProvider
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenter
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.NotificationCenterEvent
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.data.SettingsModel
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.AccountRepository
import com.github.diegoberaldin.raccoonforlemmy.core.persistence.repository.SettingsRepository
import com.github.diegoberaldin.raccoonforlemmy.domain.identity.repository.IdentityRepository
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
class SettingsColorAndFontViewModel(
private val mvi: DefaultMviModel<SettingsColorAndFontMviModel.Intent, SettingsColorAndFontMviModel.UiState, SettingsColorAndFontMviModel.Effect>,
private val themeRepository: ThemeRepository,
private val colorSchemeProvider: ColorSchemeProvider,
private val identityRepository: IdentityRepository,
private val settingsRepository: SettingsRepository,
private val accountRepository: AccountRepository,
private val notificationCenter: NotificationCenter,
) : SettingsColorAndFontMviModel,
MviModel<SettingsColorAndFontMviModel.Intent, SettingsColorAndFontMviModel.UiState, SettingsColorAndFontMviModel.Effect> by mvi {
override fun onStarted() {
mvi.onStarted()
mvi.scope?.launch {
themeRepository.uiTheme.onEach { value ->
mvi.updateState { it.copy(uiTheme = value) }
}.launchIn(this)
themeRepository.uiFontFamily.onEach { value ->
mvi.updateState { it.copy(uiFontFamily = value) }
}.launchIn(this)
themeRepository.contentFontScale.onEach { value ->
mvi.updateState { it.copy(contentFontScale = value.toFontScale()) }
}.launchIn(this)
themeRepository.contentFontFamily.onEach { value ->
mvi.updateState { it.copy(contentFontFamily = value) }
}.launchIn(this)
themeRepository.uiFontScale.onEach { value ->
mvi.updateState { it.copy(uiFontScale = value.toFontScale()) }
}.launchIn(this)
themeRepository.dynamicColors.onEach { value ->
mvi.updateState { it.copy(dynamicColors = value) }
}.launchIn(this)
themeRepository.customSeedColor.onEach { value ->
mvi.updateState { it.copy(customSeedColor = value) }
}.launchIn(this)
themeRepository.upVoteColor.onEach { value ->
mvi.updateState { it.copy(upVoteColor = value) }
}.launchIn(this)
themeRepository.downVoteColor.onEach { value ->
mvi.updateState { it.copy(downVoteColor = value) }
}.launchIn(this)
themeRepository.replyColor.onEach { value ->
mvi.updateState { it.copy(replyColor = value) }
}.launchIn(this)
themeRepository.saveColor.onEach { value ->
mvi.updateState { it.copy(saveColor = value) }
}.launchIn(this)
themeRepository.commentBarTheme.onEach { value ->
mvi.updateState { it.copy(commentBarTheme = value) }
}.launchIn(this)
identityRepository.isLogged.onEach { logged ->
mvi.updateState { it.copy(isLogged = logged ?: false) }
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeFontFamily::class)
.onEach { evt ->
changeFontFamily(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeContentFontSize::class)
.onEach { evt ->
changeContentFontScale(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeContentFontFamily::class)
.onEach { evt ->
changeContentFontFamily(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeUiFontSize::class)
.onEach { evt ->
changeUiFontScale(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeColor::class).onEach { evt ->
changeCustomSeedColor(evt.color)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeCommentBarTheme::class)
.onEach { evt ->
changeCommentBarTheme(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeActionColor::class)
.onEach { evt ->
when (evt.actionType) {
3 -> changeSaveColor(evt.color)
2 -> changeReplyColor(evt.color)
1 -> changeDownVoteColor(evt.color)
else -> changeUpVoteColor(evt.color)
}
}.launchIn(this)
mvi.updateState {
it.copy(
supportsDynamicColors = colorSchemeProvider.supportsDynamicColors,
)
}
}
}
override fun reduce(intent: SettingsColorAndFontMviModel.Intent) {
when (intent) {
is SettingsColorAndFontMviModel.Intent.ChangeDynamicColors -> {
changeDynamicColors(intent.value)
}
}
}
private fun changeFontFamily(value: UiFontFamily) {
themeRepository.changeUiFontFamily(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
uiFontFamily = value.toInt()
)
saveSettings(settings)
}
}
private fun changeUiFontScale(value: Float) {
themeRepository.changeUiFontScale(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
uiFontScale = value
)
saveSettings(settings)
}
}
private fun changeContentFontScale(value: Float) {
themeRepository.changeContentFontScale(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
contentFontScale = value
)
saveSettings(settings)
}
}
private fun changeContentFontFamily(value: UiFontFamily) {
themeRepository.changeContentFontFamily(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
contentFontFamily = value.toInt()
)
saveSettings(settings)
}
}
private fun changeDynamicColors(value: Boolean) {
themeRepository.changeDynamicColors(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
dynamicColors = value
)
saveSettings(settings)
}
}
private fun changeCustomSeedColor(value: Color?) {
themeRepository.changeCustomSeedColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
customSeedColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeUpVoteColor(value: Color?) {
themeRepository.changeUpvoteColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
upVoteColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeDownVoteColor(value: Color?) {
themeRepository.changeDownvoteColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
downVoteColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeReplyColor(value: Color?) {
themeRepository.changeReplyColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
replyColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeSaveColor(value: Color?) {
themeRepository.changeSaveColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
saveColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeCommentBarTheme(value: CommentBarTheme) {
themeRepository.changeCommentBarTheme(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
commentBarTheme = value.toInt()
)
saveSettings(settings)
}
}
private suspend fun saveSettings(settings: SettingsModel) {
val accountId = accountRepository.getActive()?.id
settingsRepository.updateSettings(settings, accountId)
settingsRepository.changeCurrentSettings(settings)
}
}

View File

@ -1,6 +1,8 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.di package com.github.diegoberaldin.raccoonforlemmy.feature.settings.di
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors.SettingsColorAndFontMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors.SettingsColorAndFontViewModel
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.main.SettingsMviModel import com.github.diegoberaldin.raccoonforlemmy.feature.settings.main.SettingsMviModel
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.main.SettingsViewModel import com.github.diegoberaldin.raccoonforlemmy.feature.settings.main.SettingsViewModel
import com.github.diegoberaldin.raccoonforlemmy.unit.about.di.aboutModule import com.github.diegoberaldin.raccoonforlemmy.unit.about.di.aboutModule
@ -16,7 +18,6 @@ val settingsTabModule = module {
themeRepository = get(), themeRepository = get(),
languageRepository = get(), languageRepository = get(),
identityRepository = get(), identityRepository = get(),
colorSchemeProvider = get(),
notificationCenter = get(), notificationCenter = get(),
crashReportConfiguration = get(), crashReportConfiguration = get(),
crashReportSender = get(), crashReportSender = get(),
@ -24,4 +25,15 @@ val settingsTabModule = module {
getSortTypesUseCase = get(), getSortTypesUseCase = get(),
) )
} }
factory<SettingsColorAndFontMviModel> {
SettingsColorAndFontViewModel(
mvi = DefaultMviModel(SettingsColorAndFontMviModel.UiState()),
settingsRepository = get(),
accountRepository = get(),
themeRepository = get(),
identityRepository = get(),
colorSchemeProvider = get(),
notificationCenter = get(),
)
}
} }

View File

@ -1,11 +1,7 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main
import androidx.compose.ui.graphics.Color
import cafe.adriel.voyager.core.model.ScreenModel import cafe.adriel.voyager.core.model.ScreenModel
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.CommentBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
@ -20,26 +16,17 @@ interface SettingsMviModel :
sealed interface Intent { sealed interface Intent {
data class ChangeUiTheme(val value: UiTheme?) : Intent data class ChangeUiTheme(val value: UiTheme?) : Intent
data class ChangeUiFontSize(val value: Float) : Intent
data class ChangeUiFontFamily(val value: UiFontFamily) : Intent
data class ChangeContentFontSize(val value: Float) : Intent
data class ChangeContentFontFamily(val value: UiFontFamily) : Intent
data class ChangeLanguage(val value: String) : Intent data class ChangeLanguage(val value: String) : Intent
data class ChangeDefaultListingType(val value: ListingType) : Intent data class ChangeDefaultListingType(val value: ListingType) : Intent
data class ChangePostLayout(val value: PostLayout) : Intent data class ChangePostLayout(val value: PostLayout) : Intent
data class ChangeDefaultPostSortType(val value: SortType) : Intent data class ChangeDefaultPostSortType(val value: SortType) : Intent
data class ChangeDefaultCommentSortType(val value: SortType) : Intent data class ChangeDefaultCommentSortType(val value: SortType) : Intent
data class ChangeNavBarTitlesVisible(val value: Boolean) : Intent data class ChangeNavBarTitlesVisible(val value: Boolean) : Intent
data class ChangeDynamicColors(val value: Boolean) : Intent
data class ChangeIncludeNsfw(val value: Boolean) : Intent data class ChangeIncludeNsfw(val value: Boolean) : Intent
data class ChangeBlurNsfw(val value: Boolean) : Intent data class ChangeBlurNsfw(val value: Boolean) : Intent
data class ChangeOpenUrlsInExternalBrowser(val value: Boolean) : Intent data class ChangeOpenUrlsInExternalBrowser(val value: Boolean) : Intent
data class ChangeEnableSwipeActions(val value: Boolean) : Intent data class ChangeEnableSwipeActions(val value: Boolean) : Intent
data class ChangeEnableDoubleTapAction(val value: Boolean) : Intent data class ChangeEnableDoubleTapAction(val value: Boolean) : Intent
data class ChangeCustomSeedColor(val value: Color?) : Intent
data class ChangeUpvoteColor(val value: Color?) : Intent
data class ChangeDownvoteColor(val value: Color?) : Intent
data class ChangeReplyColor(val value: Color?) : Intent
data class ChangeCrashReportEnabled(val value: Boolean) : Intent data class ChangeCrashReportEnabled(val value: Boolean) : Intent
data class ChangeVoteFormat(val value: VoteFormat) : Intent data class ChangeVoteFormat(val value: VoteFormat) : Intent
data class ChangeAutoLoadImages(val value: Boolean) : Intent data class ChangeAutoLoadImages(val value: Boolean) : Intent
@ -59,15 +46,6 @@ interface SettingsMviModel :
data class UiState( data class UiState(
val isLogged: Boolean = false, val isLogged: Boolean = false,
val uiTheme: UiTheme? = null, val uiTheme: UiTheme? = null,
val uiFontFamily: UiFontFamily = UiFontFamily.Poppins,
val customSeedColor: Color? = null,
val upVoteColor: Color? = null,
val downVoteColor: Color? = null,
val replyColor: Color? = null,
val saveColor: Color? = null,
val uiFontScale: FontScale = FontScale.Normal,
val contentFontScale: FontScale = FontScale.Normal,
val contentFontFamily: UiFontFamily = UiFontFamily.Poppins,
val lang: String = "", val lang: String = "",
val postLayout: PostLayout = PostLayout.Card, val postLayout: PostLayout = PostLayout.Card,
val defaultListingType: ListingType = ListingType.Local, val defaultListingType: ListingType = ListingType.Local,
@ -75,8 +53,6 @@ interface SettingsMviModel :
val defaultCommentSortType: SortType = SortType.New, val defaultCommentSortType: SortType = SortType.New,
val defaultInboxUnreadOnly: Boolean = true, val defaultInboxUnreadOnly: Boolean = true,
val navBarTitlesVisible: Boolean = false, val navBarTitlesVisible: Boolean = false,
val supportsDynamicColors: Boolean = false,
val dynamicColors: Boolean = false,
val includeNsfw: Boolean = true, val includeNsfw: Boolean = true,
val blurNsfw: Boolean = true, val blurNsfw: Boolean = true,
val openUrlsInExternalBrowser: Boolean = false, val openUrlsInExternalBrowser: Boolean = false,
@ -93,7 +69,6 @@ interface SettingsMviModel :
val markAsReadWhileScrolling: Boolean = true, val markAsReadWhileScrolling: Boolean = true,
val availableSortTypesForPosts: List<SortType> = emptyList(), val availableSortTypesForPosts: List<SortType> = emptyList(),
val availableSortTypesForComments: List<SortType> = emptyList(), val availableSortTypesForComments: List<SortType> = emptyList(),
val commentBarTheme: CommentBarTheme = CommentBarTheme.Blue,
val searchPostTitleOnly: Boolean = false, val searchPostTitleOnly: Boolean = false,
val edgeToEdge: Boolean = true, val edgeToEdge: Boolean = true,
val postBodyMaxLines: Int? = null, val postBodyMaxLines: Int? = null,

View File

@ -1,7 +1,6 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -42,14 +41,9 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.unit.toSize import androidx.compose.ui.unit.toSize
import cafe.adriel.voyager.core.screen.Screen import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel import cafe.adriel.voyager.koin.getScreenModel
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.FontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiBarTheme import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.scaleFactor
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toReadableName
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getColorSchemeProvider
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.di.getThemeRepository
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.Spacing
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle import com.github.diegoberaldin.raccoonforlemmy.core.architecture.bindToLifecycle
import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.SettingsHeader import com.github.diegoberaldin.raccoonforlemmy.core.commonui.lemmyui.SettingsHeader
@ -80,25 +74,16 @@ import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLanguageName
import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp import com.github.diegoberaldin.raccoonforlemmy.core.utils.toLocalDp
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toInt import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toInt
import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toReadableName import com.github.diegoberaldin.raccoonforlemmy.domain.lemmy.data.toReadableName
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.SettingsTab import com.github.diegoberaldin.raccoonforlemmy.feature.settings.colors.SettingsColorAndFontScreen
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components.SettingsColorRow
import com.github.diegoberaldin.raccoonforlemmy.feature.settings.ui.components.SettingsMultiColorRow
import com.github.diegoberaldin.raccoonforlemmy.resources.MR import com.github.diegoberaldin.raccoonforlemmy.resources.MR
import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository import com.github.diegoberaldin.raccoonforlemmy.resources.di.getLanguageRepository
import com.github.diegoberaldin.raccoonforlemmy.resources.di.staticString import com.github.diegoberaldin.raccoonforlemmy.resources.di.staticString
import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutDialog import com.github.diegoberaldin.raccoonforlemmy.unit.about.AboutDialog
import com.github.diegoberaldin.raccoonforlemmy.unit.accountsettings.AccountSettingsScreen import com.github.diegoberaldin.raccoonforlemmy.unit.accountsettings.AccountSettingsScreen
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.ColorBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.CommentBarThemeBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosecolor.VoteThemeBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosefont.FontFamilyBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.choosefont.FontScaleBottomSheet
import com.github.diegoberaldin.raccoonforlemmy.unit.configureswipeactions.ConfigureSwipeActionsScreen import com.github.diegoberaldin.raccoonforlemmy.unit.configureswipeactions.ConfigureSwipeActionsScreen
import com.github.diegoberaldin.raccoonforlemmy.unit.manageban.ManageBanScreen import com.github.diegoberaldin.raccoonforlemmy.unit.manageban.ManageBanScreen
import dev.icerock.moko.resources.compose.stringResource import dev.icerock.moko.resources.compose.stringResource
import dev.icerock.moko.resources.desc.desc import dev.icerock.moko.resources.desc.desc
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -110,7 +95,7 @@ class SettingsScreen : Screen {
@Composable @Composable
override fun Content() { override fun Content() {
val model = getScreenModel<SettingsMviModel>() val model = getScreenModel<SettingsMviModel>()
model.bindToLifecycle(SettingsTab.key) model.bindToLifecycle(key)
val uiState by model.uiState.collectAsState() val uiState by model.uiState.collectAsState()
val topAppBarState = rememberTopAppBarState() val topAppBarState = rememberTopAppBarState()
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState) val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarState)
@ -120,24 +105,9 @@ class SettingsScreen : Screen {
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
val languageRepository = remember { getLanguageRepository() } val languageRepository = remember { getLanguageRepository() }
val lang by languageRepository.currentLanguage.collectAsState() val lang by languageRepository.currentLanguage.collectAsState()
var uiFontSizeWorkaround by remember { mutableStateOf(true) }
val themeRepository = remember { getThemeRepository() }
val colorSchemeProvider = remember { getColorSchemeProvider() }
val defaultTheme = if (isSystemInDarkTheme()) {
UiTheme.Dark
} else {
UiTheme.Light
}
var infoDialogOpened by remember { mutableStateOf(false) } var infoDialogOpened by remember { mutableStateOf(false) }
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
LaunchedEffect(themeRepository) {
themeRepository.uiFontScale.drop(1).onEach {
uiFontSizeWorkaround = false
delay(50)
uiFontSizeWorkaround = true
}.launchIn(this)
}
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
navigationCoordinator.onDoubleTabSelection.onEach { section -> navigationCoordinator.onDoubleTabSelection.onEach { section ->
if (section == TabNavigationSection.Settings) { if (section == TabNavigationSection.Settings) {
@ -153,10 +123,6 @@ class SettingsScreen : Screen {
}.launchIn(this) }.launchIn(this)
} }
if (!uiFontSizeWorkaround) {
return
}
var screenWidth by remember { mutableStateOf(0f) } var screenWidth by remember { mutableStateOf(0f) }
Scaffold( Scaffold(
modifier = Modifier.onGloballyPositioned { modifier = Modifier.onGloballyPositioned {
@ -193,7 +159,8 @@ class SettingsScreen : Screen {
}, },
) { paddingValues -> ) { paddingValues ->
Box( Box(
modifier = Modifier.padding(paddingValues) modifier = Modifier
.padding(paddingValues)
.nestedScroll(scrollBehavior.nestedScrollConnection), .nestedScroll(scrollBehavior.nestedScrollConnection),
) { ) {
Column( Column(
@ -231,132 +198,6 @@ class SettingsScreen : Screen {
}, },
) )
// dynamic colors
if (uiState.supportsDynamicColors) {
SettingsSwitchRow(
title = stringResource(MR.strings.settings_dynamic_colors),
value = uiState.dynamicColors,
onValueChanged = rememberCallbackArgs(model) { value ->
model.reduce(
SettingsMviModel.Intent.ChangeDynamicColors(value)
)
},
)
}
// custom scheme seed color
SettingsColorRow(
title = stringResource(MR.strings.settings_custom_seed_color),
value = uiState.customSeedColor ?: colorSchemeProvider.getColorScheme(
theme = uiState.uiTheme ?: defaultTheme,
dynamic = uiState.dynamicColors,
).primary,
onTap = rememberCallback {
val sheet = ColorBottomSheet()
navigationCoordinator.showBottomSheet(sheet)
},
)
if (uiState.isLogged) {
// action colors
SettingsColorRow(
title = stringResource(MR.strings.settings_upvote_color),
value = uiState.upVoteColor ?: MaterialTheme.colorScheme.primary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 0,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_downvote_color),
value = uiState.downVoteColor ?: MaterialTheme.colorScheme.tertiary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 1,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_reply_color),
value = uiState.replyColor ?: MaterialTheme.colorScheme.secondary,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 2,
)
navigationCoordinator.showBottomSheet(screen)
},
)
SettingsColorRow(
title = stringResource(MR.strings.settings_save_color),
value = uiState.saveColor
?: MaterialTheme.colorScheme.secondaryContainer,
onTap = rememberCallback {
val screen = VoteThemeBottomSheet(
actionType = 3,
)
navigationCoordinator.showBottomSheet(screen)
},
)
}
// comment bar theme
val commentBarColors =
themeRepository.getCommentBarColors(uiState.commentBarTheme)
SettingsMultiColorRow(
title = stringResource(MR.strings.settings_comment_bar_theme),
values = commentBarColors,
onTap = rememberCallback {
val screen = CommentBarThemeBottomSheet()
navigationCoordinator.showBottomSheet(screen)
}
)
// font family
SettingsRow(
title = stringResource(MR.strings.settings_ui_font_family),
value = uiState.uiFontFamily.toReadableName(),
onTap = rememberCallback {
val sheet = FontFamilyBottomSheet()
navigationCoordinator.showBottomSheet(sheet)
},
)
SettingsRow(
title = stringResource(MR.strings.settings_content_font_family),
value = uiState.contentFontFamily.toReadableName(),
onTap = rememberCallback {
val sheet = FontFamilyBottomSheet(content = true)
navigationCoordinator.showBottomSheet(sheet)
},
)
// font scale
SettingsRow(
title = stringResource(MR.strings.settings_ui_font_scale),
value = uiState.uiFontScale.toReadableName(),
onTap = rememberCallback {
val sheet = FontScaleBottomSheet(
values = listOf(
FontScale.Large,
FontScale.Normal,
FontScale.Small,
).map { it.scaleFactor },
content = false,
)
navigationCoordinator.showBottomSheet(sheet)
},
)
SettingsRow(
title = stringResource(MR.strings.settings_content_font_scale),
value = uiState.contentFontScale.toReadableName(),
onTap = rememberCallback {
val sheet = FontScaleBottomSheet(content = true)
navigationCoordinator.showBottomSheet(sheet)
},
)
// navigation bar titles // navigation bar titles
SettingsSwitchRow( SettingsSwitchRow(
title = stringResource(MR.strings.settings_navigation_bar_titles_visible), title = stringResource(MR.strings.settings_navigation_bar_titles_visible),
@ -407,6 +248,15 @@ class SettingsScreen : Screen {
}, },
) )
// colors and fonts
SettingsRow(
title = stringResource(MR.strings.settings_colors_and_fonts),
disclosureIndicator = true,
onTap = rememberCallback {
navigationCoordinator.pushScreen(SettingsColorAndFontScreen())
}
)
SettingsHeader( SettingsHeader(
icon = Icons.Default.Dashboard, icon = Icons.Default.Dashboard,
title = stringResource(MR.strings.settings_section_feed), title = stringResource(MR.strings.settings_section_feed),

View File

@ -1,17 +1,11 @@
package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main package com.github.diegoberaldin.raccoonforlemmy.feature.settings.main
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.CommentBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.PostLayout
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiBarTheme import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiBarTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiFontFamily
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.UiTheme
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.VoteFormat
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toFontScale
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toInt import com.github.diegoberaldin.raccoonforlemmy.core.appearance.data.toInt
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository import com.github.diegoberaldin.raccoonforlemmy.core.appearance.repository.ThemeRepository
import com.github.diegoberaldin.raccoonforlemmy.core.appearance.theme.ColorSchemeProvider
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel import com.github.diegoberaldin.raccoonforlemmy.core.architecture.DefaultMviModel
import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel import com.github.diegoberaldin.raccoonforlemmy.core.architecture.MviModel
import com.github.diegoberaldin.raccoonforlemmy.core.notifications.ContentResetCoordinator import com.github.diegoberaldin.raccoonforlemmy.core.notifications.ContentResetCoordinator
@ -42,7 +36,6 @@ import kotlin.time.Duration
class SettingsViewModel( class SettingsViewModel(
private val mvi: DefaultMviModel<SettingsMviModel.Intent, SettingsMviModel.UiState, SettingsMviModel.Effect>, private val mvi: DefaultMviModel<SettingsMviModel.Intent, SettingsMviModel.UiState, SettingsMviModel.Effect>,
private val themeRepository: ThemeRepository, private val themeRepository: ThemeRepository,
private val colorSchemeProvider: ColorSchemeProvider,
private val languageRepository: LanguageRepository, private val languageRepository: LanguageRepository,
private val identityRepository: IdentityRepository, private val identityRepository: IdentityRepository,
private val settingsRepository: SettingsRepository, private val settingsRepository: SettingsRepository,
@ -61,45 +54,12 @@ class SettingsViewModel(
themeRepository.uiTheme.onEach { value -> themeRepository.uiTheme.onEach { value ->
mvi.updateState { it.copy(uiTheme = value) } mvi.updateState { it.copy(uiTheme = value) }
}.launchIn(this) }.launchIn(this)
themeRepository.uiFontFamily.onEach { value ->
mvi.updateState { it.copy(uiFontFamily = value) }
}.launchIn(this)
themeRepository.contentFontScale.onEach { value ->
mvi.updateState { it.copy(contentFontScale = value.toFontScale()) }
}.launchIn(this)
themeRepository.contentFontFamily.onEach { value ->
mvi.updateState { it.copy(contentFontFamily = value) }
}.launchIn(this)
themeRepository.uiFontScale.onEach { value ->
mvi.updateState { it.copy(uiFontScale = value.toFontScale()) }
}.launchIn(this)
themeRepository.navItemTitles.onEach { value -> themeRepository.navItemTitles.onEach { value ->
mvi.updateState { it.copy(navBarTitlesVisible = value) } mvi.updateState { it.copy(navBarTitlesVisible = value) }
}.launchIn(this) }.launchIn(this)
themeRepository.dynamicColors.onEach { value ->
mvi.updateState { it.copy(dynamicColors = value) }
}.launchIn(this)
themeRepository.customSeedColor.onEach { value ->
mvi.updateState { it.copy(customSeedColor = value) }
}.launchIn(this)
themeRepository.postLayout.onEach { value -> themeRepository.postLayout.onEach { value ->
mvi.updateState { it.copy(postLayout = value) } mvi.updateState { it.copy(postLayout = value) }
}.launchIn(this) }.launchIn(this)
themeRepository.upVoteColor.onEach { value ->
mvi.updateState { it.copy(upVoteColor = value) }
}.launchIn(this)
themeRepository.downVoteColor.onEach { value ->
mvi.updateState { it.copy(downVoteColor = value) }
}.launchIn(this)
themeRepository.replyColor.onEach { value ->
mvi.updateState { it.copy(replyColor = value) }
}.launchIn(this)
themeRepository.saveColor.onEach { value ->
mvi.updateState { it.copy(saveColor = value) }
}.launchIn(this)
themeRepository.commentBarTheme.onEach { value ->
mvi.updateState { it.copy(commentBarTheme = value) }
}.launchIn(this)
languageRepository.currentLanguage.onEach { lang -> languageRepository.currentLanguage.onEach { lang ->
mvi.updateState { it.copy(lang = lang) } mvi.updateState { it.copy(lang = lang) }
@ -119,25 +79,6 @@ class SettingsViewModel(
notificationCenter.subscribe(NotificationCenterEvent.ChangeTheme::class).onEach { evt -> notificationCenter.subscribe(NotificationCenterEvent.ChangeTheme::class).onEach { evt ->
changeTheme(evt.value) changeTheme(evt.value)
}.launchIn(this) }.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeColor::class).onEach { evt ->
changeCustomSeedColor(evt.color)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeFontFamily::class)
.onEach { evt ->
changeFontFamily(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeContentFontSize::class)
.onEach { evt ->
changeContentFontScale(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeContentFontFamily::class)
.onEach { evt ->
changeContentFontFamily(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeUiFontSize::class)
.onEach { evt ->
changeUiFontScale(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangePostLayout::class) notificationCenter.subscribe(NotificationCenterEvent.ChangePostLayout::class)
.onEach { evt -> .onEach { evt ->
changePostLayout(evt.value) changePostLayout(evt.value)
@ -170,19 +111,6 @@ class SettingsViewModel(
.onEach { evt -> .onEach { evt ->
changeVoteFormat(evt.value) changeVoteFormat(evt.value)
}.launchIn(this) }.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeCommentBarTheme::class)
.onEach { evt ->
changeCommentBarTheme(evt.value)
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangeActionColor::class)
.onEach { evt ->
when (evt.actionType) {
3 -> changeSaveColor(evt.color)
2 -> changeReplyColor(evt.color)
1 -> changeDownvoteColor(evt.color)
else -> changeUpvoteColor(evt.color)
}
}.launchIn(this)
notificationCenter.subscribe(NotificationCenterEvent.ChangePostBodyMaxLines::class) notificationCenter.subscribe(NotificationCenterEvent.ChangePostBodyMaxLines::class)
.onEach { evt -> .onEach { evt ->
changePostBodyMaxLines(evt.value) changePostBodyMaxLines(evt.value)
@ -211,7 +139,6 @@ class SettingsViewModel(
defaultInboxUnreadOnly = settings.defaultInboxType.toInboxUnreadOnly(), defaultInboxUnreadOnly = settings.defaultInboxType.toInboxUnreadOnly(),
includeNsfw = settings.includeNsfw, includeNsfw = settings.includeNsfw,
blurNsfw = settings.blurNsfw, blurNsfw = settings.blurNsfw,
supportsDynamicColors = colorSchemeProvider.supportsDynamicColors,
openUrlsInExternalBrowser = settings.openUrlsInExternalBrowser, openUrlsInExternalBrowser = settings.openUrlsInExternalBrowser,
enableSwipeActions = settings.enableSwipeActions, enableSwipeActions = settings.enableSwipeActions,
enableDoubleTapAction = settings.enableDoubleTapAction, enableDoubleTapAction = settings.enableDoubleTapAction,
@ -235,145 +162,47 @@ class SettingsViewModel(
override fun reduce(intent: SettingsMviModel.Intent) { override fun reduce(intent: SettingsMviModel.Intent) {
when (intent) { when (intent) {
is SettingsMviModel.Intent.ChangeUiTheme -> { is SettingsMviModel.Intent.ChangeUiTheme -> changeTheme(intent.value)
changeTheme(intent.value) is SettingsMviModel.Intent.ChangeLanguage -> changeLanguage(intent.value)
} is SettingsMviModel.Intent.ChangeDefaultCommentSortType ->
is SettingsMviModel.Intent.ChangeUiFontFamily -> {
changeFontFamily(intent.value)
}
is SettingsMviModel.Intent.ChangeContentFontSize -> {
changeContentFontScale(intent.value)
}
is SettingsMviModel.Intent.ChangeContentFontFamily -> {
changeContentFontFamily(intent.value)
}
is SettingsMviModel.Intent.ChangeUiFontSize -> {
changeUiFontScale(intent.value)
}
is SettingsMviModel.Intent.ChangeLanguage -> {
changeLanguage(intent.value)
}
is SettingsMviModel.Intent.ChangeDefaultCommentSortType -> {
changeDefaultCommentSortType(intent.value) changeDefaultCommentSortType(intent.value)
}
is SettingsMviModel.Intent.ChangeDefaultListingType -> { is SettingsMviModel.Intent.ChangeDefaultListingType -> changeDefaultListingType(intent.value)
changeDefaultListingType(intent.value) is SettingsMviModel.Intent.ChangeDefaultPostSortType -> changeDefaultPostSortType(intent.value)
} is SettingsMviModel.Intent.ChangeBlurNsfw -> changeBlurNsfw(intent.value)
is SettingsMviModel.Intent.ChangeIncludeNsfw -> changeIncludeNsfw(intent.value)
is SettingsMviModel.Intent.ChangeDefaultPostSortType -> { is SettingsMviModel.Intent.ChangeNavBarTitlesVisible -> changeNavBarTitlesVisible(intent.value)
changeDefaultPostSortType(intent.value) is SettingsMviModel.Intent.ChangeOpenUrlsInExternalBrowser ->
}
is SettingsMviModel.Intent.ChangeBlurNsfw -> {
changeBlurNsfw(intent.value)
}
is SettingsMviModel.Intent.ChangeIncludeNsfw -> {
changeIncludeNsfw(intent.value)
}
is SettingsMviModel.Intent.ChangeNavBarTitlesVisible -> {
changeNavBarTitlesVisible(intent.value)
}
is SettingsMviModel.Intent.ChangeDynamicColors -> {
changeDynamicColors(intent.value)
}
is SettingsMviModel.Intent.ChangeOpenUrlsInExternalBrowser -> {
changeOpenUrlsInExternalBrowser(intent.value) changeOpenUrlsInExternalBrowser(intent.value)
}
is SettingsMviModel.Intent.ChangeEnableSwipeActions -> { is SettingsMviModel.Intent.ChangeEnableSwipeActions -> changeEnableSwipeActions(intent.value)
changeEnableSwipeActions(intent.value) is SettingsMviModel.Intent.ChangeEnableDoubleTapAction ->
}
is SettingsMviModel.Intent.ChangeEnableDoubleTapAction -> {
changeEnableDoubleTapAction(intent.value) changeEnableDoubleTapAction(intent.value)
}
is SettingsMviModel.Intent.ChangeCustomSeedColor -> { is SettingsMviModel.Intent.ChangePostLayout -> changePostLayout(intent.value)
changeCustomSeedColor(intent.value) is SettingsMviModel.Intent.ChangeCrashReportEnabled -> changeCrashReportEnabled(intent.value)
} is SettingsMviModel.Intent.ChangeVoteFormat -> changeVoteFormat(intent.value)
is SettingsMviModel.Intent.ChangeAutoLoadImages -> changeAutoLoadImages(intent.value)
is SettingsMviModel.Intent.ChangePostLayout -> { is SettingsMviModel.Intent.ChangeAutoExpandComments -> changeAutoExpandComments(intent.value)
changePostLayout(intent.value) is SettingsMviModel.Intent.ChangeFullHeightImages -> changeFullHeightImages(intent.value)
} is SettingsMviModel.Intent.ChangeHideNavigationBarWhileScrolling ->
is SettingsMviModel.Intent.ChangeCrashReportEnabled -> {
changeCrashReportEnabled(intent.value)
}
is SettingsMviModel.Intent.ChangeVoteFormat -> {
changeVoteFormat(intent.value)
}
is SettingsMviModel.Intent.ChangeAutoLoadImages -> {
changeAutoLoadImages(intent.value)
}
is SettingsMviModel.Intent.ChangeAutoExpandComments -> {
changeAutoExpandComments(intent.value)
}
is SettingsMviModel.Intent.ChangeFullHeightImages -> {
changeFullHeightImages(intent.value)
}
is SettingsMviModel.Intent.ChangeUpvoteColor -> {
changeUpvoteColor(intent.value)
}
is SettingsMviModel.Intent.ChangeDownvoteColor -> {
changeDownvoteColor(intent.value)
}
is SettingsMviModel.Intent.ChangeReplyColor -> {
changeReplyColor(intent.value)
}
is SettingsMviModel.Intent.ChangeHideNavigationBarWhileScrolling -> {
changeHideNavigationBarWhileScrolling(intent.value) changeHideNavigationBarWhileScrolling(intent.value)
}
is SettingsMviModel.Intent.ChangeZombieModeInterval -> { is SettingsMviModel.Intent.ChangeZombieModeInterval -> changeZombieModeInterval(intent.value)
changeZombieModeInterval(intent.value) is SettingsMviModel.Intent.ChangeZombieModeScrollAmount ->
}
is SettingsMviModel.Intent.ChangeZombieModeScrollAmount -> {
changeZombieModeScrollAmount(intent.value) changeZombieModeScrollAmount(intent.value)
}
is SettingsMviModel.Intent.ChangeMarkAsReadWhileScrolling -> { is SettingsMviModel.Intent.ChangeMarkAsReadWhileScrolling ->
changeMarkAsReadWhileScrolling(intent.value) changeMarkAsReadWhileScrolling(intent.value)
}
is SettingsMviModel.Intent.ChangeDefaultInboxUnreadOnly -> { is SettingsMviModel.Intent.ChangeDefaultInboxUnreadOnly ->
changeDefaultInboxUnreadOnly(intent.value) changeDefaultInboxUnreadOnly(intent.value)
}
is SettingsMviModel.Intent.ChangeSearchPostTitleOnly -> { is SettingsMviModel.Intent.ChangeSearchPostTitleOnly -> changeSearchPostTitleOnly(intent.value)
changeSearchPostTitleOnly(intent.value) is SettingsMviModel.Intent.ChangeEdgeToEdge -> changeEdgeToEdge(intent.value)
} is SettingsMviModel.Intent.ChangePostBodyMaxLines -> changePostBodyMaxLines(intent.value)
is SettingsMviModel.Intent.ChangeInfiniteScrollDisabled ->
is SettingsMviModel.Intent.ChangeEdgeToEdge -> {
changeEdgeToEdge(intent.value)
}
is SettingsMviModel.Intent.ChangePostBodyMaxLines -> {
changePostBodyMaxLines(intent.value)
}
is SettingsMviModel.Intent.ChangeInfiniteScrollDisabled -> {
changeInfiniteScrollDisabled(intent.value) changeInfiniteScrollDisabled(intent.value)
}
} }
} }
@ -387,46 +216,6 @@ class SettingsViewModel(
} }
} }
private fun changeFontFamily(value: UiFontFamily) {
themeRepository.changeUiFontFamily(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
uiFontFamily = value.toInt()
)
saveSettings(settings)
}
}
private fun changeUiFontScale(value: Float) {
themeRepository.changeUiFontScale(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
uiFontScale = value
)
saveSettings(settings)
}
}
private fun changeContentFontScale(value: Float) {
themeRepository.changeContentFontScale(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
contentFontScale = value
)
saveSettings(settings)
}
}
private fun changeContentFontFamily(value: UiFontFamily) {
themeRepository.changeContentFontFamily(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
contentFontFamily = value.toInt()
)
saveSettings(settings)
}
}
private fun changeLanguage(value: String) { private fun changeLanguage(value: String) {
languageRepository.changeLanguage(value) languageRepository.changeLanguage(value)
mvi.scope?.launch(Dispatchers.IO) { mvi.scope?.launch(Dispatchers.IO) {
@ -501,66 +290,6 @@ class SettingsViewModel(
} }
} }
private fun changeDynamicColors(value: Boolean) {
themeRepository.changeDynamicColors(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
dynamicColors = value
)
saveSettings(settings)
}
}
private fun changeCustomSeedColor(value: Color?) {
themeRepository.changeCustomSeedColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
customSeedColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeUpvoteColor(value: Color?) {
themeRepository.changeUpvoteColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
upVoteColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeDownvoteColor(value: Color?) {
themeRepository.changeDownvoteColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
downVoteColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeReplyColor(value: Color?) {
themeRepository.changeReplyColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
replyColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeSaveColor(value: Color?) {
themeRepository.changeSaveColor(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
saveColor = value?.toArgb()
)
saveSettings(settings)
}
}
private fun changeOpenUrlsInExternalBrowser(value: Boolean) { private fun changeOpenUrlsInExternalBrowser(value: Boolean) {
mvi.updateState { it.copy(openUrlsInExternalBrowser = value) } mvi.updateState { it.copy(openUrlsInExternalBrowser = value) }
mvi.scope?.launch(Dispatchers.IO) { mvi.scope?.launch(Dispatchers.IO) {
@ -698,16 +427,6 @@ class SettingsViewModel(
} }
} }
private fun changeCommentBarTheme(value: CommentBarTheme) {
themeRepository.changeCommentBarTheme(value)
mvi.scope?.launch(Dispatchers.IO) {
val settings = settingsRepository.currentSettings.value.copy(
commentBarTheme = value.toInt()
)
saveSettings(settings)
}
}
private fun changeSearchPostTitleOnly(value: Boolean) { private fun changeSearchPostTitleOnly(value: Boolean) {
mvi.updateState { it.copy(searchPostTitleOnly = value) } mvi.updateState { it.copy(searchPostTitleOnly = value) }
mvi.scope?.launch(Dispatchers.IO) { mvi.scope?.launch(Dispatchers.IO) {

View File

@ -323,4 +323,5 @@
<string name="bar_theme_opaque">مبهمة</string> <string name="bar_theme_opaque">مبهمة</string>
<string name="bar_theme_transparent">شفاف</string> <string name="bar_theme_transparent">شفاف</string>
<string name="settings_bar_theme">موضوع الحالة وشريط التنقل</string> <string name="settings_bar_theme">موضوع الحالة وشريط التنقل</string>
<string name="settings_colors_and_fonts">الألوان والخطوط</string>
</resources> </resources>

View File

@ -356,4 +356,5 @@
<string name="bar_theme_opaque">Opaque</string> <string name="bar_theme_opaque">Opaque</string>
<string name="bar_theme_transparent">Transparent</string> <string name="bar_theme_transparent">Transparent</string>
<string name="settings_bar_theme">System notification and navigation bar theme</string> <string name="settings_bar_theme">System notification and navigation bar theme</string>
<string name="settings_colors_and_fonts">Colors and fonts</string>
</resources> </resources>

View File

@ -333,4 +333,5 @@
<string name="bar_theme_opaque">Непрозрачен</string> <string name="bar_theme_opaque">Непрозрачен</string>
<string name="bar_theme_transparent">Прозрачен</string> <string name="bar_theme_transparent">Прозрачен</string>
<string name="settings_bar_theme">Тема на лентата за състояние и навигация</string> <string name="settings_bar_theme">Тема на лентата за състояние и навигация</string>
<string name="settings_colors_and_fonts">Цветове и шрифтове</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Neprůhledný</string> <string name="bar_theme_opaque">Neprůhledný</string>
<string name="bar_theme_transparent">Průhledný</string> <string name="bar_theme_transparent">Průhledný</string>
<string name="settings_bar_theme">Téma stavové a navigační lišty</string> <string name="settings_bar_theme">Téma stavové a navigační lišty</string>
<string name="settings_colors_and_fonts">Barvy a písma</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Uigennemsigtig</string> <string name="bar_theme_opaque">Uigennemsigtig</string>
<string name="bar_theme_transparent">Gennemsigtig</string> <string name="bar_theme_transparent">Gennemsigtig</string>
<string name="settings_bar_theme">Tema for status- og navigationslinjen</string> <string name="settings_bar_theme">Tema for status- og navigationslinjen</string>
<string name="settings_colors_and_fonts">Farver og skrifttyper</string>
</resources> </resources>

View File

@ -333,4 +333,5 @@
<string name="bar_theme_opaque">Undurchsichtig</string> <string name="bar_theme_opaque">Undurchsichtig</string>
<string name="bar_theme_transparent">Transparent</string> <string name="bar_theme_transparent">Transparent</string>
<string name="settings_bar_theme">Thema der Status- und Navigationsleiste</string> <string name="settings_bar_theme">Thema der Status- und Navigationsleiste</string>
<string name="settings_colors_and_fonts">Farben und Schriftarten</string>
</resources> </resources>

View File

@ -336,4 +336,5 @@
<string name="bar_theme_opaque">Αδιαφανής</string> <string name="bar_theme_opaque">Αδιαφανής</string>
<string name="bar_theme_transparent">Διαφανής</string> <string name="bar_theme_transparent">Διαφανής</string>
<string name="settings_bar_theme">Θέμα της γραμμής κατάστασης και πλοήγησης</string> <string name="settings_bar_theme">Θέμα της γραμμής κατάστασης και πλοήγησης</string>
<string name="settings_colors_and_fonts">Χρώματα και γραμματοσειρές</string>
</resources> </resources>

View File

@ -324,4 +324,5 @@
<string name="bar_theme_opaque">Opaka</string> <string name="bar_theme_opaque">Opaka</string>
<string name="bar_theme_transparent">Travidebla</string> <string name="bar_theme_transparent">Travidebla</string>
<string name="settings_bar_theme">Temo de la statuso kaj navigadbreto</string> <string name="settings_bar_theme">Temo de la statuso kaj navigadbreto</string>
<string name="settings_colors_and_fonts">Koloroj kaj tiparoj</string>
</resources> </resources>

View File

@ -326,4 +326,5 @@
<string name="bar_theme_opaque">Opaco</string> <string name="bar_theme_opaque">Opaco</string>
<string name="bar_theme_transparent">Transparente</string> <string name="bar_theme_transparent">Transparente</string>
<string name="settings_bar_theme">Tema barra de estado y navegación</string> <string name="settings_bar_theme">Tema barra de estado y navegación</string>
<string name="settings_colors_and_fonts">Colores y fuentes</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Läbipaistmatu</string> <string name="bar_theme_opaque">Läbipaistmatu</string>
<string name="bar_theme_transparent">Läbipaistev</string> <string name="bar_theme_transparent">Läbipaistev</string>
<string name="settings_bar_theme">Oleku- ja navigeerimisriba teema</string> <string name="settings_bar_theme">Oleku- ja navigeerimisriba teema</string>
<string name="settings_colors_and_fonts">Värvid ja fondid</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Läpinäkymätön</string> <string name="bar_theme_opaque">Läpinäkymätön</string>
<string name="bar_theme_transparent">Läpinäkyvä</string> <string name="bar_theme_transparent">Läpinäkyvä</string>
<string name="settings_bar_theme">Tila- ja navigointipalkin teema</string> <string name="settings_bar_theme">Tila- ja navigointipalkin teema</string>
<string name="settings_colors_and_fonts">Värit ja fontit</string>
</resources> </resources>

View File

@ -330,4 +330,5 @@
<string name="bar_theme_opaque">Opaque</string> <string name="bar_theme_opaque">Opaque</string>
<string name="bar_theme_transparent">Transparent</string> <string name="bar_theme_transparent">Transparent</string>
<string name="settings_bar_theme">Thème barre d\'état et de navigation</string> <string name="settings_bar_theme">Thème barre d\'état et de navigation</string>
<string name="settings_colors_and_fonts">Couleurs et polices</string>
</resources> </resources>

View File

@ -334,4 +334,5 @@
<string name="bar_theme_opaque">Teimhneach</string> <string name="bar_theme_opaque">Teimhneach</string>
<string name="bar_theme_transparent">Trédhearcach</string> <string name="bar_theme_transparent">Trédhearcach</string>
<string name="settings_bar_theme">Téama an bharra stádais agus nascleanúna</string> <string name="settings_bar_theme">Téama an bharra stádais agus nascleanúna</string>
<string name="settings_colors_and_fonts">Dathanna agus clónna</string>
</resources> </resources>

View File

@ -330,4 +330,5 @@
<string name="bar_theme_opaque">Neproziran</string> <string name="bar_theme_opaque">Neproziran</string>
<string name="bar_theme_transparent">Transparentan</string> <string name="bar_theme_transparent">Transparentan</string>
<string name="settings_bar_theme">Tema statusne i navigacijske trake</string> <string name="settings_bar_theme">Tema statusne i navigacijske trake</string>
<string name="settings_colors_and_fonts">Boje i fontovi</string>
</resources> </resources>

View File

@ -329,4 +329,5 @@
<string name="bar_theme_opaque">Áttetsző</string> <string name="bar_theme_opaque">Áttetsző</string>
<string name="bar_theme_transparent">Átlátszó</string> <string name="bar_theme_transparent">Átlátszó</string>
<string name="settings_bar_theme">Az állapot és a navigációs sáv témája</string> <string name="settings_bar_theme">Az állapot és a navigációs sáv témája</string>
<string name="settings_colors_and_fonts">Színek és betűtípusok</string>
</resources> </resources>

View File

@ -329,4 +329,5 @@
<string name="bar_theme_opaque">Opaco</string> <string name="bar_theme_opaque">Opaco</string>
<string name="bar_theme_transparent">Trasparente</string> <string name="bar_theme_transparent">Trasparente</string>
<string name="settings_bar_theme">Tema barra notifiche di sistema e navigazione</string> <string name="settings_bar_theme">Tema barra notifiche di sistema e navigazione</string>
<string name="settings_colors_and_fonts">Colori e font</string>
</resources> </resources>

View File

@ -327,4 +327,5 @@
<string name="bar_theme_opaque">Nepermatomas</string> <string name="bar_theme_opaque">Nepermatomas</string>
<string name="bar_theme_transparent">Skaidrus</string> <string name="bar_theme_transparent">Skaidrus</string>
<string name="settings_bar_theme">Būsenos ir naršymo juostos tema</string> <string name="settings_bar_theme">Būsenos ir naršymo juostos tema</string>
<string name="settings_colors_and_fonts">Spalvos ir šriftai</string>
</resources> </resources>

View File

@ -329,4 +329,5 @@
<string name="bar_theme_opaque">Necaurspīdīgs</string> <string name="bar_theme_opaque">Necaurspīdīgs</string>
<string name="bar_theme_transparent">Caurspīdīgs</string> <string name="bar_theme_transparent">Caurspīdīgs</string>
<string name="settings_bar_theme">Statusa un navigācijas joslas motīvs</string> <string name="settings_bar_theme">Statusa un navigācijas joslas motīvs</string>
<string name="settings_colors_and_fonts">Krāsas un fonti</string>
</resources> </resources>

View File

@ -330,4 +330,5 @@
<string name="bar_theme_opaque">Opaki</string> <string name="bar_theme_opaque">Opaki</string>
<string name="bar_theme_transparent">Trasparenti</string> <string name="bar_theme_transparent">Trasparenti</string>
<string name="settings_bar_theme">Tema tal-istatus u l-bar tan-navigazzjoni</string> <string name="settings_bar_theme">Tema tal-istatus u l-bar tan-navigazzjoni</string>
<string name="settings_colors_and_fonts">Kuluri u fonts</string>
</resources> </resources>

View File

@ -328,4 +328,5 @@
<string name="bar_theme_opaque">Ondoorzichtig</string> <string name="bar_theme_opaque">Ondoorzichtig</string>
<string name="bar_theme_transparent">Transparant</string> <string name="bar_theme_transparent">Transparant</string>
<string name="settings_bar_theme">Thema van de status- en navigatiebalk</string> <string name="settings_bar_theme">Thema van de status- en navigatiebalk</string>
<string name="settings_colors_and_fonts">Kleuren en lettertypen</string>
</resources> </resources>

View File

@ -327,4 +327,5 @@
<string name="bar_theme_opaque">Ugjennomsiktig</string> <string name="bar_theme_opaque">Ugjennomsiktig</string>
<string name="bar_theme_transparent">Gjennomsiktig</string> <string name="bar_theme_transparent">Gjennomsiktig</string>
<string name="settings_bar_theme">Tema for status- og navigasjonslinjen</string> <string name="settings_bar_theme">Tema for status- og navigasjonslinjen</string>
<string name="settings_colors_and_fonts">Farger og fonter</string>
</resources> </resources>

View File

@ -328,4 +328,5 @@
<string name="bar_theme_opaque">Nieprzejrzysty</string> <string name="bar_theme_opaque">Nieprzejrzysty</string>
<string name="bar_theme_transparent">Przezroczysty</string> <string name="bar_theme_transparent">Przezroczysty</string>
<string name="settings_bar_theme">Motyw paska stanu i nawigacji</string> <string name="settings_bar_theme">Motyw paska stanu i nawigacji</string>
<string name="settings_colors_and_fonts">Kolory i czcionki</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Opaco</string> <string name="bar_theme_opaque">Opaco</string>
<string name="bar_theme_transparent">Transparente</string> <string name="bar_theme_transparent">Transparente</string>
<string name="settings_bar_theme">Tema da barra de status e navegação</string> <string name="settings_bar_theme">Tema da barra de status e navegação</string>
<string name="settings_colors_and_fonts">Cores e fontes</string>
</resources> </resources>

View File

@ -327,4 +327,5 @@
<string name="bar_theme_opaque">Opaco</string> <string name="bar_theme_opaque">Opaco</string>
<string name="bar_theme_transparent">Transparente</string> <string name="bar_theme_transparent">Transparente</string>
<string name="settings_bar_theme">Tema da barra de status e navegação</string> <string name="settings_bar_theme">Tema da barra de status e navegação</string>
<string name="settings_colors_and_fonts">Cores e fontes</string>
</resources> </resources>

View File

@ -326,4 +326,5 @@
<string name="bar_theme_opaque">Opac</string> <string name="bar_theme_opaque">Opac</string>
<string name="bar_theme_transparent">Transparent</string> <string name="bar_theme_transparent">Transparent</string>
<string name="settings_bar_theme">Tema barei de stare și navigare</string> <string name="settings_bar_theme">Tema barei de stare și navigare</string>
<string name="settings_colors_and_fonts">Culori și fonturi</string>
</resources> </resources>

View File

@ -329,4 +329,5 @@
<string name="bar_theme_opaque">Непрозрачный</string> <string name="bar_theme_opaque">Непрозрачный</string>
<string name="bar_theme_transparent">Прозрачный</string> <string name="bar_theme_transparent">Прозрачный</string>
<string name="settings_bar_theme">Тема статусной и навигационной панели</string> <string name="settings_bar_theme">Тема статусной и навигационной панели</string>
<string name="settings_colors_and_fonts">Цвета и шрифты</string>
</resources> </resources>

View File

@ -326,4 +326,5 @@
<string name="bar_theme_opaque">Ogenomskinlig</string> <string name="bar_theme_opaque">Ogenomskinlig</string>
<string name="bar_theme_transparent">Transparent</string> <string name="bar_theme_transparent">Transparent</string>
<string name="settings_bar_theme">Tema för status- och navigeringsfältet</string> <string name="settings_bar_theme">Tema för status- och navigeringsfältet</string>
<string name="settings_colors_and_fonts">Färger och typsnitt</string>
</resources> </resources>

View File

@ -327,4 +327,5 @@
<string name="bar_theme_opaque">Nepriehľadné</string> <string name="bar_theme_opaque">Nepriehľadné</string>
<string name="bar_theme_transparent">Transparentné</string> <string name="bar_theme_transparent">Transparentné</string>
<string name="settings_bar_theme">Téma stavovej a navigačnej lišty</string> <string name="settings_bar_theme">Téma stavovej a navigačnej lišty</string>
<string name="settings_colors_and_fonts">Farby a písma</string>
</resources> </resources>

View File

@ -325,4 +325,5 @@
<string name="bar_theme_opaque">Neprozoren</string> <string name="bar_theme_opaque">Neprozoren</string>
<string name="bar_theme_transparent">Pregleden</string> <string name="bar_theme_transparent">Pregleden</string>
<string name="settings_bar_theme">Tema statusne in navigacijske vrstice</string> <string name="settings_bar_theme">Tema statusne in navigacijske vrstice</string>
<string name="settings_colors_and_fonts">Barve in pisave</string>
</resources> </resources>

View File

@ -331,4 +331,5 @@
<string name="bar_theme_opaque">I errët</string> <string name="bar_theme_opaque">I errët</string>
<string name="bar_theme_transparent">Transparente</string> <string name="bar_theme_transparent">Transparente</string>
<string name="settings_bar_theme">Tema e shiritit të statusit dhe navigimit</string> <string name="settings_bar_theme">Tema e shiritit të statusit dhe navigimit</string>
<string name="settings_colors_and_fonts">Ngjyrat dhe shkronjat</string>
</resources> </resources>

View File

@ -324,4 +324,5 @@
<string name="bar_theme_opaque">lukin ala</string> <string name="bar_theme_opaque">lukin ala</string>
<string name="bar_theme_transparent">lukin</string> <string name="bar_theme_transparent">lukin</string>
<string name="settings_bar_theme">nasin lukin pi linja sewi pi linja anpa</string> <string name="settings_bar_theme">nasin lukin pi linja sewi pi linja anpa</string>
<string name="settings_colors_and_fonts">Kule en sitelen</string>
</resources> </resources>

View File

@ -328,4 +328,5 @@
<string name="bar_theme_opaque">Opak</string> <string name="bar_theme_opaque">Opak</string>
<string name="bar_theme_transparent">Şeffaf</string> <string name="bar_theme_transparent">Şeffaf</string>
<string name="settings_bar_theme">Durum ve gezinme çubuğunun teması</string> <string name="settings_bar_theme">Durum ve gezinme çubuğunun teması</string>
<string name="settings_colors_and_fonts">Renkler ve yazı tipleri</string>
</resources> </resources>

View File

@ -308,7 +308,8 @@
<string name="settings_manage_ban_action_unban">Зняти бан</string> <string name="settings_manage_ban_action_unban">Зняти бан</string>
<string name="settings_manage_ban_section_instances">Примірники</string> <string name="settings_manage_ban_section_instances">Примірники</string>
<string name="settings_edge_to_edge">Вміст від краю до краю</string> <string name="settings_edge_to_edge">Вміст від краю до краю</string>
<string name="settings_post_body_max_lines">Максимальна кількість рядків для тіла повідомлення</string> <string name="settings_post_body_max_lines">Максимальна кількість рядків для тіла повідомлення
</string>
<string name="settings_post_body_max_lines_unlimited">Необмежений</string> <string name="settings_post_body_max_lines_unlimited">Необмежений</string>
<string name="message_content_removed">(цей вміст було видалено)</string> <string name="message_content_removed">(цей вміст було видалено)</string>
<string name="post_list_load_more_posts">Завантажити більше дописів</string> <string name="post_list_load_more_posts">Завантажити більше дописів</string>
@ -327,4 +328,5 @@
<string name="bar_theme_opaque">Непрозорий</string> <string name="bar_theme_opaque">Непрозорий</string>
<string name="bar_theme_transparent">Прозорий</string> <string name="bar_theme_transparent">Прозорий</string>
<string name="settings_bar_theme">Тема панелі стану та навігації</string> <string name="settings_bar_theme">Тема панелі стану та навігації</string>
<string name="settings_colors_and_fonts">Кольори та шрифти</string>
</resources> </resources>