clean up settings and some other things

This commit is contained in:
2024-07-16 02:12:19 +03:00
parent 46d3fe63fa
commit b252c03be7
60 changed files with 698 additions and 613 deletions
@@ -4,18 +4,19 @@ import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.meloda.app.fast.auth.login.BuildConfig
import com.meloda.app.fast.common.LongPollController
import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.common.VkConstants
import com.meloda.app.fast.common.extensions.listenValue
import com.meloda.app.fast.common.extensions.setValue
import com.meloda.app.fast.common.extensions.updateValue
import com.meloda.app.fast.common.model.LongPollState
import com.meloda.app.fast.data.State
import com.meloda.app.fast.data.api.users.UsersUseCase
import com.meloda.app.fast.data.db.AccountsRepository
import com.meloda.app.fast.data.processState
import com.meloda.app.fast.datastore.SettingsController
import com.meloda.app.fast.datastore.AppSettings
import com.meloda.app.fast.datastore.UserSettings
import com.meloda.app.fast.datastore.model.LongPollState
import com.meloda.app.fast.model.database.AccountEntity
import com.meloda.app.fast.network.OAuthErrorDomain
import com.meloda.fast.auth.login.model.CaptchaArguments
@@ -71,7 +72,8 @@ class LoginViewModelImpl(
private val usersUseCase: UsersUseCase,
private val accountsRepository: AccountsRepository,
private val loginValidator: LoginValidator,
private val userSettings: UserSettings
private val userSettings: UserSettings,
private val longPollController: LongPollController
) : ViewModel(), LoginViewModel {
override val screenState = MutableStateFlow(LoginScreenState.EMPTY)
@@ -347,8 +349,8 @@ class LoginViewModelImpl(
}
private fun startLongPoll() {
userSettings.setLongPollStateToApply(
if (SettingsController.isLongPollInBackgroundEnabled) {
longPollController.setStateToApply(
if (AppSettings.Debug.longPollInBackground) {
LongPollState.Background
} else {
LongPollState.InApp
@@ -50,13 +50,13 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.ui.basic.autoFillRequestHandler
import com.meloda.app.fast.ui.basic.connectNode
import com.meloda.app.fast.ui.basic.defaultFocusChangeAutoFill
import com.meloda.app.fast.ui.components.MaterialDialog
import com.meloda.app.fast.ui.components.TextFieldErrorText
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.handleEnterKey
import com.meloda.app.fast.ui.util.handleTabKey
import com.meloda.fast.auth.login.LoginViewModel
@@ -157,7 +157,7 @@ fun LoginScreen(
onPasswordFieldGoAction: () -> Unit = {},
onSignInButtonClicked: () -> Unit = {}
) {
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
val focusManager = LocalFocusManager.current
val (loginFocusable, passwordFocusable) = FocusRequester.createRefs()
@@ -31,7 +31,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.fast.auth.login.LoginViewModel
import com.meloda.fast.auth.login.LoginViewModelImpl
import org.koin.androidx.compose.koinViewModel
@@ -64,7 +64,7 @@ fun LogoScreen(
onLogoLongClicked: () -> Unit = {},
onGoNextButtonClicked: () -> Unit = {}
) {
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
Scaffold { padding ->
val topPadding by animateDpAsState(
@@ -7,7 +7,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.meloda.app.fast.auth.validation.model.ValidationArguments
import com.meloda.app.fast.auth.validation.presentation.ValidationRoute
import com.meloda.app.fast.common.customNavType
import com.meloda.app.fast.common.extensions.customNavType
import kotlinx.serialization.Serializable
import kotlin.reflect.typeOf
@@ -66,7 +66,7 @@ import com.meloda.app.fast.chatmaterials.ChatMaterialsViewModelImpl
import com.meloda.app.fast.chatmaterials.model.ChatMaterialsScreenState
import com.meloda.app.fast.datastore.UserSettings
import com.meloda.app.fast.ui.R
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
@@ -110,7 +110,7 @@ fun ChatMaterialsScreen(
onRefreshDropdownItemClicked: () -> Unit = {},
onRefresh: () -> Unit = {}
) {
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
val attachments = screenState.materials
@@ -154,7 +154,7 @@ fun ChatMaterialsScreen(
Log.d("ChatMaterialsScreen", "ChatMaterialsScreen: canScrollBackward: $canScrollBackward")
val topBarContainerColorAlpha by animateFloatAsState(
targetValue = if (!currentTheme.usingBlur || !canScrollBackward) 1f else 0f,
targetValue = if (!currentTheme.enableBlur || !canScrollBackward) 1f else 0f,
label = "toolbarColorAlpha",
animationSpec = tween(
durationMillis = 200,
@@ -164,7 +164,7 @@ fun ChatMaterialsScreen(
val topBarContainerColor by animateColorAsState(
targetValue =
if (currentTheme.usingBlur || !canScrollBackward)
if (currentTheme.enableBlur || !canScrollBackward)
MaterialTheme.colorScheme.surface
else
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
@@ -182,7 +182,7 @@ fun ChatMaterialsScreen(
Column(
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.hazeChild(
state = hazeState,
style = hazeStyle
@@ -244,7 +244,7 @@ fun ChatMaterialsScreen(
}
)
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
DropdownMenuItem(
text = {
Text(text = if (moreClearBlur) "Default blur" else "Clearer blur")
@@ -300,7 +300,7 @@ fun ChatMaterialsScreen(
horizontalArrangement = Arrangement.spacedBy(2.dp),
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.haze(
state = hazeState,
style = hazeStyle
@@ -331,7 +331,7 @@ fun ChatMaterialsScreen(
state = listState,
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.haze(
state = hazeState,
style = hazeStyle
@@ -1,7 +1,7 @@
package com.meloda.app.fast.conversations.model
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.ui.R as UiR
sealed class ConversationOption(
@@ -2,7 +2,7 @@ package com.meloda.app.fast.conversations.model
import androidx.compose.runtime.Immutable
import androidx.compose.ui.text.AnnotatedString
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.model.api.PeerType
import com.meloda.app.fast.model.api.domain.VkMessage
import com.meloda.app.fast.ui.util.ImmutableList
@@ -52,7 +52,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import coil.compose.AsyncImage
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.conversations.model.ConversationOption
import com.meloda.app.fast.conversations.model.UiConversation
import com.meloda.app.fast.ui.basic.ContentAlpha
@@ -78,7 +78,7 @@ import com.meloda.app.fast.ui.components.FullScreenLoader
import com.meloda.app.fast.ui.components.MaterialDialog
import com.meloda.app.fast.ui.theme.LocalBottomPadding
import com.meloda.app.fast.ui.theme.LocalHazeState
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.isScrollingUp
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
@@ -159,10 +159,10 @@ fun ConversationsScreen(
onRefresh: () -> Unit = {}
) {
val view = LocalView.current
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
val maxLines by remember(currentTheme) {
mutableIntStateOf(if (currentTheme.isMultiline) 2 else 1)
mutableIntStateOf(if (currentTheme.enableMultiline) 2 else 1)
}
val listState = rememberLazyListState()
@@ -195,7 +195,7 @@ fun ConversationsScreen(
val toolbarContainerColor by animateColorAsState(
targetValue =
if (currentTheme.usingBlur || !listState.canScrollBackward)
if (currentTheme.enableBlur || !listState.canScrollBackward)
MaterialTheme.colorScheme.surface
else
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
@@ -258,12 +258,12 @@ fun ConversationsScreen(
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = toolbarContainerColor.copy(
alpha = if (currentTheme.usingBlur) toolbarColorAlpha else 1f
alpha = if (currentTheme.enableBlur) toolbarColorAlpha else 1f
)
),
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.hazeChild(
state = hazeState,
style = HazeMaterials.thick()
@@ -355,7 +355,7 @@ fun ConversationsScreen(
screenState = screenState,
state = listState,
maxLines = maxLines,
modifier = if (currentTheme.usingBlur) {
modifier = if (currentTheme.enableBlur) {
Modifier.haze(
state = hazeState,
style = HazeMaterials.thick()
@@ -9,11 +9,11 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import com.conena.nanokt.jvm.util.dayOfMonth
import com.conena.nanokt.jvm.util.month
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.common.extensions.orDots
import com.meloda.app.fast.common.parseString
import com.meloda.app.fast.common.model.parseString
import com.meloda.app.fast.common.util.TimeUtils
import com.meloda.app.fast.conversations.model.ActionState
import com.meloda.app.fast.conversations.model.UiConversation
@@ -1,6 +1,6 @@
package com.meloda.app.fast.friends.model
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.model.api.domain.OnlineStatus
data class UiFriend(
@@ -59,7 +59,7 @@ import com.meloda.app.fast.ui.components.FullScreenLoader
import com.meloda.app.fast.ui.components.NoItemsView
import com.meloda.app.fast.ui.model.TabItem
import com.meloda.app.fast.ui.theme.LocalHazeState
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.ImmutableList
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
@@ -122,11 +122,11 @@ fun FriendsScreen(
onPaginationConditionsMet: () -> Unit = {},
onRefresh: () -> Unit = {}
) {
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
val maxLines by remember {
derivedStateOf {
if (currentTheme.isMultiline) 2 else 1
if (currentTheme.enableMultiline) 2 else 1
}
}
@@ -149,7 +149,7 @@ fun FriendsScreen(
val hazeState = LocalHazeState.current
val topBarContainerColorAlpha by animateFloatAsState(
targetValue = if (!currentTheme.usingBlur || !listState.canScrollBackward) 1f else 0f,
targetValue = if (!currentTheme.enableBlur || !listState.canScrollBackward) 1f else 0f,
label = "toolbarColorAlpha",
animationSpec = tween(
durationMillis = 200,
@@ -159,7 +159,7 @@ fun FriendsScreen(
val topBarContainerColor by animateColorAsState(
targetValue =
if (currentTheme.usingBlur || !listState.canScrollBackward)
if (currentTheme.enableBlur || !listState.canScrollBackward)
MaterialTheme.colorScheme.surface
else
MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp),
@@ -196,7 +196,7 @@ fun FriendsScreen(
Column(
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.hazeChild(
state = hazeState,
style = HazeMaterials.thick()
@@ -295,7 +295,7 @@ fun FriendsScreen(
val friendsToDisplay = screenState.friends
FriendsList(
modifier = if (currentTheme.usingBlur) {
modifier = if (currentTheme.enableBlur) {
Modifier.haze(
state = hazeState,
style = HazeMaterials.thick()
@@ -1,6 +1,6 @@
package com.meloda.app.fast.friends.util
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.data.VkMemoryCache
import com.meloda.app.fast.friends.model.UiFriend
import com.meloda.app.fast.model.api.domain.VkUser
@@ -4,9 +4,9 @@ import android.content.res.Resources
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import androidx.lifecycle.ViewModel
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.common.extensions.setValue
import com.meloda.app.fast.common.parseString
import com.meloda.app.fast.common.model.parseString
import com.meloda.app.fast.languagepicker.model.LanguagePickerScreenState
import com.meloda.app.fast.languagepicker.model.SelectableLanguage
import kotlinx.coroutines.flow.MutableStateFlow
@@ -1,7 +1,7 @@
package com.meloda.app.fast.messageshistory.model
import androidx.compose.runtime.Immutable
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.model.api.domain.VkAttachment
@Immutable
@@ -1,6 +1,6 @@
package com.meloda.app.fast.messageshistory.model
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
data class UiMessage(
val id: Int,
@@ -5,7 +5,7 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import androidx.navigation.toRoute
import com.meloda.app.fast.common.customNavType
import com.meloda.app.fast.common.extensions.customNavType
import com.meloda.app.fast.messageshistory.model.MessagesHistoryArguments
import com.meloda.app.fast.messageshistory.presentation.MessagesHistoryRoute
import com.meloda.app.fast.model.BaseError
@@ -72,7 +72,7 @@ import com.meloda.app.fast.messageshistory.MessagesHistoryViewModelImpl
import com.meloda.app.fast.messageshistory.model.ActionMode
import com.meloda.app.fast.messageshistory.model.MessagesHistoryScreenState
import com.meloda.app.fast.model.BaseError
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.ImmutableList
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.hazeChild
@@ -131,7 +131,7 @@ fun MessagesHistoryScreen(
val view = LocalView.current
val preferences: SharedPreferences = koinInject()
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
val listState = rememberLazyListState()
@@ -178,7 +178,7 @@ fun MessagesHistoryScreen(
TopAppBar(
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.hazeChild(
state = hazeSate,
style = HazeMaterials.thick()
@@ -203,7 +203,7 @@ fun MessagesHistoryScreen(
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface.copy(
alpha = if (currentTheme.usingBlur) toolbarColorAlpha else 1f
alpha = if (currentTheme.enableBlur) toolbarColorAlpha else 1f
)
),
actions = {
@@ -17,7 +17,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.meloda.app.fast.messageshistory.model.UiMessage
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.ImmutableList
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.haze
@@ -35,13 +35,13 @@ fun MessagesList(
enableAnimations: Boolean
) {
val messages = immutableMessages.toList()
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
LazyColumn(
modifier = modifier
.fillMaxWidth()
.then(
if (currentTheme.usingBlur) {
if (currentTheme.enableBlur) {
Modifier.haze(
state = hazeState,
style = HazeMaterials.regular()
@@ -1,11 +1,11 @@
package com.meloda.app.fast.messageshistory.util
import android.content.res.Resources
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.common.extensions.orDots
import com.meloda.app.fast.common.parseString
import com.meloda.app.fast.common.model.parseString
import com.meloda.app.fast.data.VkMemoryCache
import com.meloda.app.fast.ui.R
import com.meloda.app.fast.messageshistory.model.UiMessage
@@ -1,7 +1,7 @@
package com.meloda.app.fast.photoviewer.model
import androidx.compose.runtime.Immutable
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
@Immutable
data class PhotoViewArguments(
@@ -1,7 +1,7 @@
package com.meloda.app.fast.photoviewer.model
import androidx.compose.runtime.Immutable
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
@Immutable
data class PhotoViewState(
@@ -44,7 +44,7 @@ import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil.compose.AsyncImage
import com.meloda.app.fast.common.UiImage
import com.meloda.app.fast.common.model.UiImage
import com.meloda.app.fast.photoviewer.PhotoViewViewModel
import com.meloda.app.fast.photoviewer.model.PhotoViewState
@@ -6,17 +6,18 @@ import androidx.appcompat.app.AppCompatDelegate
import androidx.core.view.HapticFeedbackConstantsCompat
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.LongPollController
import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.common.extensions.findWithIndex
import com.meloda.app.fast.common.extensions.isSdkAtLeast
import com.meloda.app.fast.common.extensions.setValue
import com.meloda.app.fast.common.model.DarkMode
import com.meloda.app.fast.common.model.LongPollState
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.data.db.AccountsRepository
import com.meloda.app.fast.datastore.SettingsController
import com.meloda.app.fast.datastore.AppSettings
import com.meloda.app.fast.datastore.SettingsKeys
import com.meloda.app.fast.datastore.UserSettings
import com.meloda.app.fast.datastore.isDebugSettingsShown
import com.meloda.app.fast.datastore.model.LongPollState
import com.meloda.app.fast.model.database.AccountEntity
import com.meloda.app.fast.settings.model.SettingsItem
import com.meloda.app.fast.settings.model.SettingsScreenState
@@ -32,8 +33,7 @@ import com.meloda.app.fast.ui.R as UiR
interface SettingsViewModel {
val screenState: StateFlow<SettingsScreenState>
val isLongPollBackgroundEnabled: StateFlow<Boolean?>
val hapticType: StateFlow<HapticType?>
fun onLogOutAlertDismissed()
fun onLogOutAlertPositiveClick()
@@ -46,22 +46,20 @@ interface SettingsViewModel {
fun onSettingsItemChanged(key: String, newValue: Any?)
fun onHapticPerformed()
fun onNotificationsPermissionRequested()
}
class SettingsViewModelImpl(
private val accountsRepository: AccountsRepository,
private val userSettings: UserSettings,
private val resources: Resources
private val resources: Resources,
private val longPollController: LongPollController
) : SettingsViewModel, ViewModel() {
override val screenState = MutableStateFlow(SettingsScreenState.EMPTY)
override val hapticType = MutableStateFlow<HapticType?>(null)
private val settings = MutableStateFlow<List<SettingsItem<*>>>(emptyList())
override val isLongPollBackgroundEnabled = MutableStateFlow<Boolean?>(null)
init {
createSettings()
}
@@ -106,22 +104,15 @@ class SettingsViewModelImpl(
}
SettingsKeys.KEY_DEBUG_HIDE_DEBUG_LIST -> {
val showDebugCategory = isDebugSettingsShown()
val showDebugCategory = AppSettings.Debug.showDebugCategory
if (!showDebugCategory) return
SettingsController.put(
SettingsKeys.KEY_SHOW_DEBUG_CATEGORY,
false
)
onSettingsItemChanged(key, false)
createSettings()
screenState.setValue { old ->
old.copy(
useHaptics = HapticType.REJECT,
showDebugOptions = false
)
}
hapticType.update { HapticType.REJECT }
screenState.setValue { old -> old.copy(showDebugOptions = false) }
}
}
}
@@ -129,18 +120,14 @@ class SettingsViewModelImpl(
override fun onSettingsItemLongClicked(key: String) {
when (key) {
SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS -> {
if (isDebugSettingsShown()) return
if (AppSettings.Debug.showDebugCategory) return
SettingsController.put(SettingsKeys.KEY_SHOW_DEBUG_CATEGORY, true)
onSettingsItemChanged(key, true)
createSettings()
screenState.setValue { old ->
old.copy(
useHaptics = HapticType.LONG_PRESS,
showDebugOptions = true
)
}
hapticType.update { HapticType.LONG_PRESS }
screenState.setValue { old -> old.copy(showDebugOptions = true) }
}
}
}
@@ -160,70 +147,98 @@ class SettingsViewModelImpl(
}
when (key) {
SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND -> {
val isEnabled = (newValue as? Boolean) == true
userSettings.setLongPollStateToApply(
userSettings.longPollStateToApply.value.let { state ->
if (state.isLaunched()) {
if (isEnabled) LongPollState.Background
else LongPollState.InApp
} else state
}
)
if (isEnabled) {
// TODO: 26/11/2023, Danil Nikolaev: implement
val isNotificationsPermissionGranted = false
if (!isNotificationsPermissionGranted) {
// TODO: 26/11/2023, Danil Nikolaev: implement restart
}
}
}
SettingsKeys.KEY_APPEARANCE_MULTILINE -> {
val isUsing = newValue as? Boolean ?: false
userSettings.useMultiline(isUsing)
}
SettingsKeys.KEY_APPEARANCE_AMOLED_THEME -> {
val isUsing = newValue as? Boolean ?: false
userSettings.useAmoledThemeChanged(isUsing)
}
SettingsKeys.KEY_USE_DYNAMIC_COLORS -> {
val isUsing = newValue as? Boolean ?: false
userSettings.useDynamicColorsChanged(isUsing)
}
SettingsKeys.KEY_APPEARANCE_BLUR -> {
val isUsing = newValue as? Boolean ?: false
userSettings.useBlurChanged(isUsing)
}
SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS -> {
val isUsing = newValue as? Boolean ?: false
userSettings.setOnline(isUsing)
}
SettingsKeys.KEY_USE_CONTACT_NAMES -> {
val isUsing = newValue as? Boolean ?: false
val isUsing = newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_USE_CONTACT_NAMES
userSettings.onUseContactNamesChanged(isUsing)
}
SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH -> {
val enable = newValue as? Boolean ?: false
val enable =
newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH
userSettings.onEnablePullToRefreshChanged(enable)
}
SettingsKeys.KEY_APPEARANCE_MULTILINE -> {
val isUsing = newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_MULTILINE
userSettings.onEnableMultilineChanged(isUsing)
}
SettingsKeys.KEY_APPEARANCE_DARK_MODE -> {
val newMode = newValue as? Int ?: SettingsKeys.DEFAULT_VALUE_APPEARANCE_DARK_MODE
AppCompatDelegate.setDefaultNightMode(newMode)
userSettings.onDarkModeChanged(DarkMode.parse(newMode))
}
SettingsKeys.KEY_APPEARANCE_AMOLED_THEME -> {
val isUsing =
newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_APPEARANCE_AMOLED_THEME
userSettings.onEnableAmoledDarkChanged(isUsing)
}
SettingsKeys.KEY_USE_DYNAMIC_COLORS -> {
val isUsing = newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_USE_DYNAMIC_COLORS
userSettings.onEnableDynamicColorsChanged(isUsing)
}
SettingsKeys.KEY_APPEARANCE_LANGUAGE -> {
val newLanguage = newValue as? String ?: SettingsKeys.DEFAULT_APPEARANCE_LANGUAGE
userSettings.onAppLanguageChanged(newLanguage)
}
SettingsKeys.DEFAULT_VALUE_FEATURES_FAST_TEXT -> {
val newText = newValue as? String ?: SettingsKeys.DEFAULT_VALUE_FEATURES_FAST_TEXT
userSettings.onFastTextChanged(newText)
}
SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS -> {
val isUsing = newValue as? Boolean
?: SettingsKeys.DEFAULT_VALUE_KEY_ACTIVITY_SEND_ONLINE_STATUS
userSettings.onSendOnlineStatusChanged(isUsing)
}
SettingsKeys.KEY_DEBUG_SHOW_CRASH_ALERT -> {
val show = newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON
userSettings.onShowAlertAfterCrashChanged(show)
}
SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND -> {
val inBackground = newValue as? Boolean
?: SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND
userSettings.onLongPollInBackgroundChanged(inBackground)
longPollController.setStateToApply(
longPollController.stateToApply.value.let { state ->
if (state.isLaunched()) {
if (inBackground) LongPollState.Background
else LongPollState.InApp
} else state
}
)
}
SettingsKeys.KEY_APPEARANCE_USE_BLUR -> {
val isUsing =
newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_USE_BLUR
userSettings.onUseBlurChanged(isUsing)
}
SettingsKeys.KEY_SHOW_EMOJI_BUTTON -> {
val show = newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON
userSettings.onShowEmojiButtonChanged(show)
}
SettingsKeys.KEY_SHOW_DEBUG_CATEGORY -> {
val show = newValue as? Boolean ?: false
userSettings.onShowDebugCategoryChanged(show)
}
}
}
override fun onHapticPerformed() {
screenState.setValue { old -> old.copy(useHaptics = null) }
}
override fun onNotificationsPermissionRequested() {
screenState.setValue { old -> old.copy(isNeedToRequestNotificationPermission = false) }
hapticType.update { null }
}
private fun emitShowOptions(function: (SettingsShowOptions) -> SettingsShowOptions) {
@@ -273,22 +288,22 @@ class SettingsViewModelImpl(
)
val darkThemeValues = listOf(
AppCompatDelegate.MODE_NIGHT_YES to UiText.Resource(UiR.string.settings_dark_theme_value_enabled),
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM to UiText.Resource(UiR.string.settings_dark_theme_value_follow_system),
AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY to UiText.Resource(UiR.string.settings_dark_theme_value_battery_saver),
AppCompatDelegate.MODE_NIGHT_NO to UiText.Resource(UiR.string.settings_dark_theme_value_disabled)
DarkMode.ENABLED to UiText.Resource(UiR.string.settings_dark_theme_value_enabled),
DarkMode.FOLLOW_SYSTEM to UiText.Resource(UiR.string.settings_dark_theme_value_follow_system),
DarkMode.AUTO_BATTERY to UiText.Resource(UiR.string.settings_dark_theme_value_battery_saver),
DarkMode.DISABLED to UiText.Resource(UiR.string.settings_dark_theme_value_disabled)
).toMap()
val appearanceDarkTheme = SettingsItem.ListItem(
key = SettingsKeys.KEY_APPEARANCE_DARK_THEME,
key = SettingsKeys.KEY_APPEARANCE_DARK_MODE,
title = UiText.Resource(UiR.string.settings_dark_theme),
valueClass = Int::class,
defaultValue = SettingsKeys.DEFAULT_VALUE_APPEARANCE_DARK_THEME,
defaultValue = SettingsKeys.DEFAULT_VALUE_APPEARANCE_DARK_MODE,
titles = darkThemeValues.values.toList(),
values = darkThemeValues.keys.toList()
values = darkThemeValues.keys.toList().map(DarkMode::value)
).apply {
textProvider = TextProvider { item ->
val darkThemeValue = darkThemeValues[item.value]
val darkThemeValue = darkThemeValues[DarkMode.parse(item.value)]
UiText.ResourceParams(
value = UiR.string.settings_dark_theme_current_value,
@@ -368,8 +383,8 @@ class SettingsViewModelImpl(
text = UiText.Simple("Shows alert dialog with stacktrace after app crashed\n(it will be not shown if you perform crash manually)")
)
val debugUseBlur = SettingsItem.Switch(
key = SettingsKeys.KEY_APPEARANCE_BLUR,
defaultValue = SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_BLUR,
key = SettingsKeys.KEY_APPEARANCE_USE_BLUR,
defaultValue = SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_USE_BLUR,
title = UiText.Simple("[WIP] Use blur"),
text = UiText.Simple("Adds blur wherever possible\nOn android 11 and older will have transparency instead of blurring"),
)
@@ -432,7 +447,7 @@ class SettingsViewModelImpl(
debugList,
).forEach(settingsList::addAll)
if (!isDebugSettingsShown()) {
if (!AppSettings.Debug.showDebugCategory) {
settingsList.removeAll(debugList)
}
@@ -2,9 +2,9 @@ package com.meloda.app.fast.settings.model
import android.content.res.Resources
import androidx.compose.runtime.Immutable
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.parseString
import com.meloda.app.fast.datastore.SettingsController
import com.meloda.app.fast.common.model.UiText
import com.meloda.app.fast.common.model.parseString
import com.meloda.app.fast.datastore.AppSettings
import kotlin.reflect.KClass
@Immutable
@@ -37,7 +37,7 @@ sealed class SettingsItem<T>(
protected set(newValue) {
field = newValue
SettingsController.put(key, newValue)
AppSettings.put(key, newValue)
}
var title: UiText? = null
@@ -165,7 +165,7 @@ sealed class SettingsItem<T>(
val values: List<T>
) : SettingsItem<T>(
key = key,
value = selectedValue ?: SettingsController.get(valueClass, key, defaultValue),
value = selectedValue ?: AppSettings.get(valueClass, key, defaultValue),
defaultValue = defaultValue
) {
@@ -245,6 +245,6 @@ private inline fun <reified T> getCurrentValue(key: String, defaultValue: T): T
if (T::class == Nothing::class) {
throw IllegalStateException("Items with Nothing does not have a value")
} else {
return SettingsController.get(key, defaultValue)
return AppSettings.get(key, defaultValue)
}
}
@@ -1,15 +1,12 @@
package com.meloda.app.fast.settings.model
import androidx.compose.runtime.Immutable
import com.meloda.app.fast.datastore.isDebugSettingsShown
import com.meloda.app.fast.settings.HapticType
import com.meloda.app.fast.datastore.AppSettings
@Immutable
data class SettingsScreenState(
val showOptions: SettingsShowOptions,
val settings: List<UiItem>,
val useHaptics: HapticType?,
val isNeedToRequestNotificationPermission: Boolean,
val showDebugOptions: Boolean
) {
@@ -17,9 +14,7 @@ data class SettingsScreenState(
val EMPTY: SettingsScreenState = SettingsScreenState(
showOptions = SettingsShowOptions.EMPTY,
settings = emptyList(),
useHaptics = null,
isNeedToRequestNotificationPermission = false,
showDebugOptions = isDebugSettingsShown()
showDebugOptions = AppSettings.Debug.showDebugCategory
)
}
}
@@ -1,6 +1,6 @@
package com.meloda.app.fast.settings.model
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiText
fun interface TextProvider<T, S : SettingsItem<T>> {
fun provideText(item: S): UiText?
@@ -1,6 +1,6 @@
package com.meloda.app.fast.settings.model
import com.meloda.app.fast.common.UiText
import com.meloda.app.fast.common.model.UiText
fun interface TitleProvider<T, S : SettingsItem<T>> {
fun provideTitle(item: S): UiText?
@@ -1,7 +1,5 @@
package com.meloda.app.fast.settings.presentation
import android.os.PowerManager
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.calculateEndPadding
@@ -27,17 +25,14 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.LayoutDirection
import androidx.core.content.getSystemService
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.meloda.app.fast.common.UserConfig
import com.meloda.app.fast.datastore.SettingsKeys
import com.meloda.app.fast.datastore.UserSettings
import com.meloda.app.fast.datastore.isUsingDarkMode
import com.meloda.app.fast.settings.HapticType
import com.meloda.app.fast.settings.SettingsViewModel
import com.meloda.app.fast.settings.SettingsViewModelImpl
import com.meloda.app.fast.settings.model.SettingsScreenState
@@ -49,14 +44,13 @@ import com.meloda.app.fast.settings.presentation.item.TitleItem
import com.meloda.app.fast.settings.presentation.item.TitleTextItem
import com.meloda.app.fast.ui.components.ActionInvokeDismiss
import com.meloda.app.fast.ui.components.MaterialDialog
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import dev.chrisbanes.haze.HazeState
import dev.chrisbanes.haze.haze
import dev.chrisbanes.haze.hazeChild
import dev.chrisbanes.haze.materials.ExperimentalHazeMaterialsApi
import dev.chrisbanes.haze.materials.HazeMaterials
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject
import com.meloda.app.fast.ui.R as UiR
@Composable
@@ -66,16 +60,12 @@ fun SettingsRoute(
onLanguageItemClicked: () -> Unit,
viewModel: SettingsViewModel = koinViewModel<SettingsViewModelImpl>()
) {
val context = LocalContext.current
val screenState by viewModel.screenState.collectAsStateWithLifecycle()
val hapticType by viewModel.hapticType.collectAsStateWithLifecycle()
val userSettings: UserSettings = koinInject()
LaunchedEffect(true) {
userSettings.enableDebugSettings(screenState.showDebugOptions)
}
SettingsScreen(screenState = screenState,
SettingsScreen(
screenState = screenState,
hapticType = hapticType,
onBack = onBack,
onHapticPerformed = viewModel::onHapticPerformed,
onSettingsItemClicked = { key ->
@@ -88,25 +78,7 @@ fun SettingsRoute(
}
},
onSettingsItemLongClicked = viewModel::onSettingsItemLongClicked,
onSettingsItemValueChanged = { key, newValue ->
viewModel.onSettingsItemChanged(key, newValue)
when (key) {
SettingsKeys.KEY_APPEARANCE_DARK_THEME -> {
val newMode = newValue as? Int ?: 0
AppCompatDelegate.setDefaultNightMode(newMode)
val isUsing = context.getSystemService<PowerManager>()?.let { manager ->
isUsingDarkMode(
context.resources,
manager
)
} ?: false
userSettings.useDarkThemeChanged(isUsing)
}
}
}
onSettingsItemValueChanged = viewModel::onSettingsItemChanged
)
HandlePopups(
@@ -128,6 +100,7 @@ fun SettingsRoute(
@Composable
fun SettingsScreen(
screenState: SettingsScreenState = SettingsScreenState.EMPTY,
hapticType: HapticType? = null,
onBack: () -> Unit = {},
onHapticPerformed: () -> Unit = {},
onSettingsItemClicked: (key: String) -> Unit = {},
@@ -135,7 +108,6 @@ fun SettingsScreen(
onSettingsItemValueChanged: (key: String, newValue: Any?) -> Unit = { _, _ -> }
) {
val view = LocalView.current
val hapticType = screenState.useHaptics
LaunchedEffect(hapticType) {
if (hapticType != null) {
@@ -144,7 +116,7 @@ fun SettingsScreen(
}
}
val currentTheme = LocalTheme.current
val themeConfig = LocalThemeConfig.current
val hazeState = remember { HazeState() }
@@ -164,12 +136,12 @@ fun SettingsScreen(
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.surface.copy(
alpha = if (currentTheme.usingBlur) 0f else 1f
alpha = if (themeConfig.enableBlur) 0f else 1f
)
),
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (themeConfig.enableBlur) {
Modifier.hazeChild(
state = hazeState,
style = HazeMaterials.thick()
@@ -185,7 +157,7 @@ fun SettingsScreen(
LazyColumn(
modifier = Modifier
.then(
if (currentTheme.usingBlur) {
if (themeConfig.enableBlur) {
Modifier.haze(
state = hazeState,
style = HazeMaterials.thick()
@@ -32,7 +32,7 @@ import com.meloda.app.fast.ui.basic.LocalContentAlpha
import com.meloda.app.fast.ui.components.ActionInvokeDismiss
import com.meloda.app.fast.ui.components.MaterialDialog
import com.meloda.app.fast.ui.components.SelectionType
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
import com.meloda.app.fast.ui.util.ImmutableList
import com.meloda.app.fast.ui.util.ImmutableList.Companion.toImmutableList
@@ -51,7 +51,7 @@ fun ListItem(
mutableStateOf(false)
}
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
Row(
modifier = modifier
@@ -81,7 +81,7 @@ fun ListItem(
Text(
text = title,
style = MaterialTheme.typography.headlineSmall,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -94,7 +94,7 @@ fun ListItem(
Text(
text = text,
style = MaterialTheme.typography.bodyMedium,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -22,7 +22,7 @@ import androidx.compose.ui.unit.dp
import com.meloda.app.fast.settings.model.UiItem
import com.meloda.app.fast.ui.basic.ContentAlpha
import com.meloda.app.fast.ui.basic.LocalContentAlpha
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -35,7 +35,7 @@ fun SwitchItem(
) {
if (!item.isVisible) return
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
Row(
modifier = modifier
@@ -65,7 +65,7 @@ fun SwitchItem(
Text(
text = title,
style = MaterialTheme.typography.headlineSmall,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -78,7 +78,7 @@ fun SwitchItem(
Text(
text = text,
style = MaterialTheme.typography.bodyMedium,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -38,7 +38,7 @@ import com.meloda.app.fast.ui.basic.ContentAlpha
import com.meloda.app.fast.ui.basic.LocalContentAlpha
import com.meloda.app.fast.ui.components.ActionInvokeDismiss
import com.meloda.app.fast.ui.components.MaterialDialog
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -51,7 +51,7 @@ fun TextFieldItem(
) {
if (!item.isVisible) return
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
var showDialog by rememberSaveable {
mutableStateOf(false)
@@ -93,7 +93,7 @@ fun TextFieldItem(
Text(
text = title,
style = MaterialTheme.typography.headlineSmall,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -106,7 +106,7 @@ fun TextFieldItem(
Text(
text = text,
style = MaterialTheme.typography.bodyMedium,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -9,7 +9,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.meloda.app.fast.settings.model.UiItem
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
@Composable
fun TitleItem(
@@ -18,7 +18,7 @@ fun TitleItem(
) {
if (!item.isVisible) return
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
Text(
text = item.title,
@@ -32,7 +32,7 @@ fun TitleItem(
bottom = 4.dp
)
.animateContentSize(),
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp
import com.meloda.app.fast.settings.model.UiItem
import com.meloda.app.fast.ui.basic.ContentAlpha
import com.meloda.app.fast.ui.basic.LocalContentAlpha
import com.meloda.app.fast.ui.theme.LocalTheme
import com.meloda.app.fast.ui.theme.LocalThemeConfig
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -33,7 +33,7 @@ fun TitleTextItem(
) {
if (!item.isVisible) return
val currentTheme = LocalTheme.current
val currentTheme = LocalThemeConfig.current
Row(
modifier = modifier
@@ -62,7 +62,7 @@ fun TitleTextItem(
Text(
text = title,
style = MaterialTheme.typography.headlineSmall,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}
@@ -75,7 +75,7 @@ fun TitleTextItem(
Text(
text = text,
style = MaterialTheme.typography.bodyMedium,
maxLines = if (currentTheme.isMultiline) Int.MAX_VALUE else 1,
maxLines = if (currentTheme.enableMultiline) Int.MAX_VALUE else 1,
overflow = TextOverflow.Ellipsis,
)
}