clean up settings and some other things
This commit is contained in:
@@ -9,14 +9,15 @@ import androidx.lifecycle.viewModelScope
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.PermissionStatus
|
||||
import com.meloda.app.fast.auth.AuthGraph
|
||||
import com.meloda.app.fast.common.LongPollController
|
||||
import com.meloda.app.fast.common.UserConfig
|
||||
import com.meloda.app.fast.common.extensions.ifEmpty
|
||||
import com.meloda.app.fast.common.extensions.listenValue
|
||||
import com.meloda.app.fast.common.extensions.setValue
|
||||
import com.meloda.app.fast.common.model.LongPollState
|
||||
import com.meloda.app.fast.data.db.GetCurrentAccountUseCase
|
||||
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.BaseError
|
||||
import com.meloda.app.fast.navigation.Main
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -54,7 +55,8 @@ interface MainViewModel {
|
||||
|
||||
class MainViewModelImpl(
|
||||
private val getCurrentAccountUseCase: GetCurrentAccountUseCase,
|
||||
private val userSettings: UserSettings
|
||||
private val userSettings: UserSettings,
|
||||
private val longPollController: LongPollController
|
||||
) : MainViewModel, ViewModel() {
|
||||
|
||||
init {
|
||||
@@ -83,11 +85,11 @@ class MainViewModelImpl(
|
||||
|
||||
override fun onAppResumed() {
|
||||
if (isNeedToShowNotificationsRationaleDialog.value) {
|
||||
isNeedToShowNotificationsRationaleDialog.update { false }
|
||||
isNeedToCheckNotificationsPermission.update { true }
|
||||
}
|
||||
|
||||
userSettings.onLanguageChanged(
|
||||
AppCompatDelegate.getApplicationLocales()
|
||||
val newLanguage = AppCompatDelegate.getApplicationLocales()
|
||||
.toLanguageTags()
|
||||
.ifEmpty { null }
|
||||
?: LocaleListCompat.getDefault()
|
||||
@@ -96,9 +98,8 @@ class MainViewModelImpl(
|
||||
.firstOrNull()
|
||||
.orEmpty()
|
||||
.take(5)
|
||||
)
|
||||
|
||||
userSettings.updateUsingDarkTheme()
|
||||
userSettings.onAppLanguageChanged(newLanguage)
|
||||
}
|
||||
|
||||
@ExperimentalPermissionsApi
|
||||
@@ -151,7 +152,7 @@ class MainViewModelImpl(
|
||||
}
|
||||
|
||||
private fun listenLongPollState() {
|
||||
userSettings.longPollStateToApply.listenValue { newState ->
|
||||
longPollController.stateToApply.listenValue { newState ->
|
||||
if (newState == LongPollState.Background) {
|
||||
isNeedToCheckNotificationsPermission.update { true }
|
||||
}
|
||||
@@ -174,8 +175,8 @@ class MainViewModelImpl(
|
||||
this.trustedHash = currentAccount.trustedHash
|
||||
}
|
||||
|
||||
userSettings.setLongPollStateToApply(
|
||||
if (SettingsController.isLongPollInBackgroundEnabled) {
|
||||
longPollController.setStateToApply(
|
||||
if (AppSettings.Debug.longPollInBackground) {
|
||||
LongPollState.Background
|
||||
} else {
|
||||
LongPollState.InApp
|
||||
@@ -191,7 +192,7 @@ class MainViewModelImpl(
|
||||
}
|
||||
|
||||
private fun disableBackgroundLongPoll() {
|
||||
SettingsController.isLongPollInBackgroundEnabled = false
|
||||
userSettings.setLongPollStateToApply(LongPollState.InApp)
|
||||
AppSettings.Debug.longPollInBackground = false
|
||||
longPollController.setStateToApply(LongPollState.InApp)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import androidx.preference.PreferenceManager
|
||||
import coil.ImageLoader
|
||||
import coil.ImageLoaderFactory
|
||||
import com.meloda.app.fast.common.di.applicationModule
|
||||
import com.meloda.app.fast.datastore.SettingsController
|
||||
import com.meloda.app.fast.datastore.AppSettings
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
@@ -17,7 +17,7 @@ class AppGlobal : Application(), ImageLoaderFactory {
|
||||
super.onCreate()
|
||||
|
||||
val preferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
SettingsController.init(preferences)
|
||||
AppSettings.init(preferences)
|
||||
UserConfig.init(preferences)
|
||||
|
||||
initKoin()
|
||||
|
||||
@@ -33,15 +33,17 @@ import com.google.accompanist.permissions.rememberPermissionState
|
||||
import com.meloda.app.fast.MainViewModel
|
||||
import com.meloda.app.fast.MainViewModelImpl
|
||||
import com.meloda.app.fast.common.AppConstants
|
||||
import com.meloda.app.fast.common.LongPollController
|
||||
import com.meloda.app.fast.common.extensions.isSdkAtLeast
|
||||
import com.meloda.app.fast.datastore.SettingsController
|
||||
import com.meloda.app.fast.common.model.LongPollState
|
||||
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.service.OnlineService
|
||||
import com.meloda.app.fast.service.longpolling.LongPollingService
|
||||
import com.meloda.app.fast.ui.model.ThemeConfig
|
||||
import com.meloda.app.fast.ui.theme.AppTheme
|
||||
import com.meloda.app.fast.ui.theme.LocalTheme
|
||||
import com.meloda.app.fast.ui.theme.LocalThemeConfig
|
||||
import com.meloda.app.fast.ui.util.isNeedToEnableDarkMode
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
import org.koin.compose.KoinContext
|
||||
import org.koin.compose.koinInject
|
||||
@@ -53,7 +55,7 @@ class MainActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
SettingsController.deviceId = Settings.Secure.getString(
|
||||
AppSettings.deviceId = Settings.Secure.getString(
|
||||
contentResolver,
|
||||
Settings.Secure.ANDROID_ID
|
||||
)
|
||||
@@ -78,10 +80,12 @@ class MainActivity : AppCompatActivity() {
|
||||
setContent {
|
||||
KoinContext {
|
||||
val context = LocalContext.current
|
||||
val userSettings: UserSettings = koinInject()
|
||||
|
||||
val longPollCurrentState by userSettings.longPollCurrentState.collectAsStateWithLifecycle()
|
||||
val longPollStateToApply by userSettings.longPollStateToApply.collectAsStateWithLifecycle()
|
||||
val userSettings: UserSettings = koinInject()
|
||||
val longPollController: LongPollController = koinInject()
|
||||
|
||||
val longPollCurrentState by longPollController.currentState.collectAsStateWithLifecycle()
|
||||
val longPollStateToApply by longPollController.stateToApply.collectAsStateWithLifecycle()
|
||||
|
||||
val viewModel: MainViewModel = koinViewModel<MainViewModelImpl>()
|
||||
|
||||
@@ -136,9 +140,9 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
val isOnline by userSettings.online.collectAsStateWithLifecycle()
|
||||
LifecycleResumeEffect(isOnline) {
|
||||
toggleOnlineService(isOnline)
|
||||
val sendOnline by userSettings.sendOnlineStatus.collectAsStateWithLifecycle()
|
||||
LifecycleResumeEffect(sendOnline) {
|
||||
toggleOnlineService(sendOnline)
|
||||
|
||||
onPauseOrDispose {
|
||||
toggleOnlineService(false)
|
||||
@@ -151,25 +155,22 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
val theme by userSettings.theme.collectAsStateWithLifecycle()
|
||||
CompositionLocalProvider(
|
||||
LocalTheme provides ThemeConfig(
|
||||
usingDarkStyle = theme.usingDarkStyle,
|
||||
usingDynamicColors = theme.usingDynamicColors,
|
||||
selectedColorScheme = theme.selectedColorScheme,
|
||||
usingAmoledBackground = theme.usingAmoledBackground,
|
||||
usingBlur = theme.usingBlur,
|
||||
isMultiline = theme.isMultiline,
|
||||
val themeConfig = ThemeConfig(
|
||||
darkMode = isNeedToEnableDarkMode(userSettings.darkMode.value),
|
||||
dynamicColors = userSettings.enableDynamicColors.value,
|
||||
selectedColorScheme = 0,
|
||||
amoledDark = userSettings.enableAmoledDark.value,
|
||||
enableBlur = userSettings.useBlur.value,
|
||||
enableMultiline = userSettings.enableMultiline.value,
|
||||
isDeviceCompact = isDeviceCompact
|
||||
)
|
||||
) {
|
||||
val currentTheme = LocalTheme.current
|
||||
|
||||
CompositionLocalProvider(LocalThemeConfig provides themeConfig) {
|
||||
AppTheme(
|
||||
useDarkTheme = currentTheme.usingDarkStyle,
|
||||
useDynamicColors = currentTheme.usingDynamicColors,
|
||||
selectedColorScheme = currentTheme.selectedColorScheme,
|
||||
useAmoledBackground = currentTheme.usingAmoledBackground,
|
||||
useDarkTheme = themeConfig.darkMode,
|
||||
useDynamicColors = themeConfig.dynamicColors,
|
||||
selectedColorScheme = themeConfig.selectedColorScheme,
|
||||
useAmoledBackground = themeConfig.amoledDark,
|
||||
) {
|
||||
RootScreen(viewModel = viewModel)
|
||||
}
|
||||
@@ -220,7 +221,7 @@ class MainActivity : AppCompatActivity() {
|
||||
|
||||
private fun toggleLongPollService(
|
||||
enable: Boolean,
|
||||
inBackground: Boolean = SettingsController.isLongPollInBackgroundEnabled
|
||||
inBackground: Boolean = AppSettings.Debug.longPollInBackground
|
||||
) {
|
||||
if (enable) {
|
||||
val longPollIntent = Intent(this, LongPollingService::class.java)
|
||||
@@ -246,7 +247,7 @@ class MainActivity : AppCompatActivity() {
|
||||
private fun stopServices() {
|
||||
toggleOnlineService(enable = false)
|
||||
|
||||
val asForeground = SettingsController.isLongPollInBackgroundEnabled
|
||||
val asForeground = AppSettings.Debug.longPollInBackground
|
||||
|
||||
if (!asForeground) {
|
||||
toggleLongPollService(enable = false)
|
||||
|
||||
@@ -28,7 +28,7 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.meloda.app.fast.conversations.navigation.conversationsScreen
|
||||
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.friends.navigation.friendsScreen
|
||||
import com.meloda.app.fast.model.BaseError
|
||||
import com.meloda.app.fast.model.BottomNavigationItem
|
||||
@@ -47,7 +47,7 @@ fun MainScreen(
|
||||
onSettingsButtonClicked: () -> Unit = {},
|
||||
onConversationItemClicked: (conversationId: Int) -> Unit = {}
|
||||
) {
|
||||
val currentTheme = LocalTheme.current
|
||||
val currentTheme = LocalThemeConfig.current
|
||||
val hazeState = remember { HazeState() }
|
||||
val navController = rememberNavController()
|
||||
|
||||
@@ -60,7 +60,7 @@ fun MainScreen(
|
||||
NavigationBar(
|
||||
modifier = Modifier
|
||||
.then(
|
||||
if (currentTheme.usingBlur) {
|
||||
if (currentTheme.enableBlur) {
|
||||
Modifier.hazeChild(
|
||||
state = hazeState,
|
||||
style = HazeMaterials.thick()
|
||||
@@ -69,7 +69,7 @@ fun MainScreen(
|
||||
)
|
||||
.fillMaxWidth(),
|
||||
containerColor = NavigationBarDefaults.containerColor.copy(
|
||||
alpha = if (currentTheme.usingBlur) 0f else 1f
|
||||
alpha = if (currentTheme.enableBlur) 0f else 1f
|
||||
)
|
||||
) {
|
||||
navigationItems.forEachIndexed { index, item ->
|
||||
@@ -105,11 +105,11 @@ fun MainScreen(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(bottom = if (currentTheme.usingBlur) 0.dp else padding.calculateBottomPadding())
|
||||
.padding(bottom = if (currentTheme.enableBlur) 0.dp else padding.calculateBottomPadding())
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalHazeState provides hazeState,
|
||||
LocalBottomPadding provides if (currentTheme.usingBlur) padding.calculateBottomPadding() else 0.dp
|
||||
LocalBottomPadding provides if (currentTheme.enableBlur) padding.calculateBottomPadding() else 0.dp
|
||||
) {
|
||||
NavHost(
|
||||
navController = navController,
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package com.meloda.app.fast.provider
|
||||
|
||||
import com.meloda.app.fast.common.ApiLanguage
|
||||
import com.meloda.app.fast.common.model.ApiLanguage
|
||||
import com.meloda.app.fast.common.provider.Provider
|
||||
import com.meloda.app.fast.datastore.UserSettings
|
||||
|
||||
class ApiLanguageProvider(private val userSettings: UserSettings) : Provider<ApiLanguage> {
|
||||
|
||||
override fun provide(): ApiLanguage? {
|
||||
val language = userSettings.language.value
|
||||
val language = userSettings.appLanguage.value
|
||||
|
||||
return when {
|
||||
language == "ru-RU" -> "ru"
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.meloda.app.fast.service.longpolling
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
@@ -13,19 +12,18 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.ServiceCompat
|
||||
import com.conena.nanokt.android.app.stopForegroundCompat
|
||||
import com.meloda.app.fast.common.AppConstants
|
||||
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.model.LongPollState
|
||||
import com.meloda.app.fast.data.LongPollUpdatesParser
|
||||
import com.meloda.app.fast.data.LongPollUseCase
|
||||
import com.meloda.app.fast.data.processState
|
||||
import com.meloda.app.fast.datastore.SettingsController
|
||||
import com.meloda.app.fast.datastore.SettingsKeys
|
||||
import com.meloda.app.fast.datastore.UserSettings
|
||||
import com.meloda.app.fast.datastore.model.LongPollState
|
||||
import com.meloda.app.fast.ui.R
|
||||
import com.meloda.app.fast.datastore.AppSettings
|
||||
import com.meloda.app.fast.model.api.data.LongPollUpdates
|
||||
import com.meloda.app.fast.model.api.data.VkLongPollData
|
||||
import com.meloda.app.fast.ui.R
|
||||
import com.meloda.app.fast.util.NotificationsUtils
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -40,7 +38,7 @@ import kotlin.coroutines.suspendCoroutine
|
||||
|
||||
class LongPollingService : Service() {
|
||||
|
||||
private val userSettings: UserSettings by inject()
|
||||
private val longPollController: LongPollController by inject()
|
||||
|
||||
private val job = SupervisorJob()
|
||||
|
||||
@@ -51,8 +49,8 @@ class LongPollingService : Service() {
|
||||
throwable.printStackTrace()
|
||||
}
|
||||
|
||||
userSettings.updateLongPollCurrentState(LongPollState.Exception)
|
||||
userSettings.setLongPollStateToApply(LongPollState.Exception)
|
||||
longPollController.updateCurrentState(LongPollState.Exception)
|
||||
longPollController.setStateToApply(LongPollState.Exception)
|
||||
}
|
||||
|
||||
private val coroutineContext: CoroutineContext
|
||||
@@ -62,7 +60,6 @@ class LongPollingService : Service() {
|
||||
|
||||
private val longPollUseCase: LongPollUseCase by inject()
|
||||
private val updatesParser: LongPollUpdatesParser by inject()
|
||||
private val preferences: SharedPreferences by inject()
|
||||
|
||||
private var currentJob: Job? = null
|
||||
|
||||
@@ -79,10 +76,7 @@ class LongPollingService : Service() {
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
if (startId > 1) return START_STICKY
|
||||
|
||||
val inBackground = preferences.getBoolean(
|
||||
SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND,
|
||||
SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND
|
||||
)
|
||||
val inBackground = AppSettings.Debug.longPollInBackground
|
||||
|
||||
Log.d(
|
||||
STATE_TAG,
|
||||
@@ -114,7 +108,7 @@ class LongPollingService : Service() {
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
userSettings.updateLongPollCurrentState(
|
||||
longPollController.updateCurrentState(
|
||||
if (inBackground) LongPollState.Background
|
||||
else LongPollState.InApp
|
||||
)
|
||||
@@ -254,11 +248,9 @@ class LongPollingService : Service() {
|
||||
|
||||
override fun onDestroy() {
|
||||
Log.d(STATE_TAG, "onDestroy")
|
||||
userSettings.updateLongPollCurrentState(LongPollState.Stopped)
|
||||
longPollController.updateCurrentState(LongPollState.Stopped)
|
||||
try {
|
||||
SettingsController.edit {
|
||||
putBoolean(KEY_LONG_POLL_WAS_DESTROYED, true)
|
||||
}
|
||||
AppSettings.edit { putBoolean(KEY_LONG_POLL_WAS_DESTROYED, true) }
|
||||
job.cancel()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
@@ -268,6 +260,7 @@ class LongPollingService : Service() {
|
||||
|
||||
override fun onLowMemory() {
|
||||
Log.d(STATE_TAG, "onLowMemory")
|
||||
longPollController.updateCurrentState(LongPollState.Stopped)
|
||||
super.onLowMemory()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.meloda.app.fast.common
|
||||
|
||||
import com.meloda.app.fast.common.model.LongPollState
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface LongPollController {
|
||||
val currentState: StateFlow<LongPollState>
|
||||
val stateToApply: StateFlow<LongPollState>
|
||||
|
||||
fun updateCurrentState(newState: LongPollState)
|
||||
fun setStateToApply(newState: LongPollState)
|
||||
}
|
||||
|
||||
class LongPollControllerImpl : LongPollController {
|
||||
|
||||
override val currentState = MutableStateFlow<LongPollState>(LongPollState.Stopped)
|
||||
override val stateToApply = MutableStateFlow<LongPollState>(LongPollState.Stopped)
|
||||
|
||||
override fun updateCurrentState(newState: LongPollState) {
|
||||
currentState.value = newState
|
||||
}
|
||||
|
||||
override fun setStateToApply(newState: LongPollState) {
|
||||
currentState.value = newState
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
package com.meloda.app.fast.common.di
|
||||
|
||||
import coil.ImageLoader
|
||||
import com.meloda.app.fast.common.LongPollController
|
||||
import com.meloda.app.fast.common.LongPollControllerImpl
|
||||
import com.meloda.app.fast.common.provider.ResourceProvider
|
||||
import com.meloda.app.fast.common.provider.ResourceProviderImpl
|
||||
import org.koin.core.module.dsl.singleOf
|
||||
import org.koin.dsl.bind
|
||||
import org.koin.dsl.module
|
||||
|
||||
val commonModule = module {
|
||||
@@ -9,4 +15,7 @@ val commonModule = module {
|
||||
.crossfade(true)
|
||||
.build()
|
||||
}
|
||||
|
||||
singleOf(::LongPollControllerImpl) bind LongPollController::class
|
||||
singleOf(::ResourceProviderImpl) bind ResourceProvider::class
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.app.fast.common
|
||||
package com.meloda.app.fast.common.extensions
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
package com.meloda.app.fast.common
|
||||
package com.meloda.app.fast.common.model
|
||||
|
||||
data class ApiLanguage(val value: String)
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.meloda.app.fast.common.model
|
||||
|
||||
private const val MODE_NIGHT_NO = 1
|
||||
private const val MODE_NIGHT_YES = 2
|
||||
private const val MODE_NIGHT_FOLLOW_SYSTEM = -1
|
||||
private const val MODE_NIGHT_AUTO_BATTERY = 3
|
||||
|
||||
enum class DarkMode(val value: Int) {
|
||||
DISABLED(MODE_NIGHT_NO),
|
||||
FOLLOW_SYSTEM(MODE_NIGHT_FOLLOW_SYSTEM),
|
||||
AUTO_BATTERY(MODE_NIGHT_AUTO_BATTERY),
|
||||
ENABLED(MODE_NIGHT_YES);
|
||||
|
||||
companion object {
|
||||
|
||||
fun parse(value: Int): DarkMode = entries.firstOrNull { it.value == value }
|
||||
?: throw IllegalArgumentException("Unknown dark mode with value: $value")
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,5 +1,4 @@
|
||||
package com.meloda.app.fast.datastore.model
|
||||
|
||||
package com.meloda.app.fast.common.model
|
||||
sealed class LongPollState {
|
||||
data object Stopped : LongPollState()
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.app.fast.common
|
||||
package com.meloda.app.fast.common.model
|
||||
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.annotation.ColorInt
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
package com.meloda.app.fast.common
|
||||
package com.meloda.app.fast.common.model
|
||||
|
||||
import android.content.res.Resources
|
||||
import androidx.annotation.PluralsRes
|
||||
@@ -18,6 +18,8 @@ sealed class UiText {
|
||||
data class Simple(val text: String) : UiText()
|
||||
|
||||
data class QuantityResource(@PluralsRes val resId: Int, val quantity: Int) : UiText()
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun UiText?.parseString(resources: Resources): String? {
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.meloda.app.fast.common.provider
|
||||
|
||||
import android.content.res.Resources
|
||||
|
||||
interface ResourceProvider {
|
||||
|
||||
fun getString(resId: Int): String
|
||||
}
|
||||
|
||||
class ResourceProviderImpl(private val resources: Resources) : ResourceProvider {
|
||||
|
||||
override fun getString(resId: Int): String {
|
||||
return resources.getString(resId)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.meloda.app.fast.datastore
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import com.meloda.app.fast.common.model.DarkMode
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object AppSettings {
|
||||
|
||||
private var preferences: SharedPreferences by Delegates.notNull()
|
||||
|
||||
fun init(preferences: SharedPreferences) {
|
||||
this.preferences = preferences
|
||||
}
|
||||
|
||||
fun edit(
|
||||
commit: Boolean = false,
|
||||
action: SharedPreferences.Editor.() -> Unit
|
||||
) {
|
||||
preferences.edit(commit, action)
|
||||
}
|
||||
|
||||
fun getString(key: String, defaultValue: String?): String? {
|
||||
return preferences.getString(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
|
||||
return preferences.getBoolean(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getInt(key: String, defaultValue: Int): Int {
|
||||
return preferences.getInt(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getLong(key: String, defaultValue: Long): Long {
|
||||
return preferences.getLong(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getFloat(key: String, defaultValue: Float): Float {
|
||||
return preferences.getFloat(key, defaultValue)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> get(clazz: KClass<T>, key: String, defaultValue: T): T {
|
||||
return when (clazz) {
|
||||
String::class -> getString(key, defaultValue as String)
|
||||
Boolean::class -> getBoolean(key, defaultValue as Boolean)
|
||||
Int::class -> getInt(key, defaultValue as Int)
|
||||
Long::class -> getLong(key, defaultValue as Long)
|
||||
Float::class -> getFloat(key, defaultValue as Float)
|
||||
else -> throw IllegalStateException("Unsupported class: $clazz")
|
||||
} as T
|
||||
}
|
||||
|
||||
inline fun <reified T> get(key: String, defaultValue: T): T {
|
||||
return when (T::class) {
|
||||
String::class -> getString(key, defaultValue as String)
|
||||
Boolean::class -> getBoolean(key, defaultValue as Boolean)
|
||||
Int::class -> getInt(key, defaultValue as Int)
|
||||
Long::class -> getLong(key, defaultValue as Long)
|
||||
Float::class -> getFloat(key, defaultValue as Float)
|
||||
else -> throw IllegalStateException("Unsupported class: ${T::class}")
|
||||
} as T
|
||||
}
|
||||
|
||||
fun <T> put(key: String, newValue: T?) {
|
||||
preferences.edit {
|
||||
when (newValue) {
|
||||
is String -> putString(key, newValue)
|
||||
is Boolean -> putBoolean(key, newValue)
|
||||
is Int -> putInt(key, newValue)
|
||||
is Long -> putLong(key, newValue)
|
||||
is Float -> putFloat(key, newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var deviceId: String
|
||||
get() = get("device_id", "")
|
||||
set(value) = put("device_id", value)
|
||||
|
||||
object General {
|
||||
var useContactNames: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_USE_CONTACT_NAMES,
|
||||
SettingsKeys.DEFAULT_VALUE_USE_CONTACT_NAMES
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_USE_CONTACT_NAMES, value)
|
||||
|
||||
var enablePullToRefresh: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH,
|
||||
SettingsKeys.DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH, value)
|
||||
}
|
||||
|
||||
object Appearance {
|
||||
var enableMultiline: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_APPEARANCE_MULTILINE,
|
||||
SettingsKeys.DEFAULT_VALUE_MULTILINE
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_APPEARANCE_MULTILINE, value)
|
||||
|
||||
var darkMode: DarkMode
|
||||
get() = get(
|
||||
SettingsKeys.KEY_APPEARANCE_DARK_MODE,
|
||||
SettingsKeys.DEFAULT_VALUE_APPEARANCE_DARK_MODE
|
||||
).let(DarkMode.Companion::parse)
|
||||
set(mode) = put(SettingsKeys.KEY_APPEARANCE_DARK_MODE, mode.value)
|
||||
|
||||
var enableAmoledDark: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_APPEARANCE_AMOLED_THEME,
|
||||
SettingsKeys.DEFAULT_VALUE_APPEARANCE_AMOLED_THEME
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_APPEARANCE_AMOLED_THEME, value)
|
||||
|
||||
var enableDynamicColors: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_USE_DYNAMIC_COLORS,
|
||||
SettingsKeys.DEFAULT_VALUE_USE_DYNAMIC_COLORS
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_USE_DYNAMIC_COLORS, value)
|
||||
|
||||
var appLanguage: String
|
||||
get() = get(
|
||||
SettingsKeys.KEY_APPEARANCE_LANGUAGE,
|
||||
SettingsKeys.DEFAULT_APPEARANCE_LANGUAGE
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_APPEARANCE_LANGUAGE, value)
|
||||
}
|
||||
|
||||
object Features {
|
||||
var fastText: String
|
||||
get() = get(
|
||||
SettingsKeys.KEY_FEATURES_FAST_TEXT,
|
||||
SettingsKeys.DEFAULT_VALUE_FEATURES_FAST_TEXT
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_FEATURES_FAST_TEXT, value)
|
||||
}
|
||||
|
||||
object Activity {
|
||||
var sendOnlineStatus: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS,
|
||||
SettingsKeys.DEFAULT_VALUE_KEY_ACTIVITY_SEND_ONLINE_STATUS
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS, value)
|
||||
}
|
||||
|
||||
object Debug {
|
||||
var showAlertAfterCrash: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_DEBUG_SHOW_CRASH_ALERT,
|
||||
true
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_DEBUG_SHOW_CRASH_ALERT, value)
|
||||
|
||||
var longPollInBackground: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND,
|
||||
SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND, value)
|
||||
|
||||
var useBlur: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_APPEARANCE_USE_BLUR,
|
||||
SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_USE_BLUR
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_APPEARANCE_USE_BLUR, value)
|
||||
|
||||
var showEmojiButton: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_SHOW_EMOJI_BUTTON,
|
||||
SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_SHOW_EMOJI_BUTTON, value)
|
||||
|
||||
var showDebugCategory: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_SHOW_DEBUG_CATEGORY,
|
||||
false
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_SHOW_DEBUG_CATEGORY, value)
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package com.meloda.app.fast.datastore
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.os.PowerManager
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
|
||||
fun isUsingDarkMode(
|
||||
resources: Resources,
|
||||
powerManager: PowerManager,
|
||||
): Boolean {
|
||||
val nightThemeMode: Int = SettingsController.getInt(
|
||||
SettingsKeys.KEY_APPEARANCE_DARK_THEME,
|
||||
SettingsKeys.DEFAULT_VALUE_APPEARANCE_DARK_THEME
|
||||
)
|
||||
|
||||
val appForceDarkMode = nightThemeMode == AppCompatDelegate.MODE_NIGHT_YES
|
||||
val appBatterySaver = nightThemeMode == AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY
|
||||
|
||||
val systemUiNightMode = resources.configuration.uiMode
|
||||
|
||||
val isSystemBatterySaver = powerManager.isPowerSaveMode
|
||||
val isSystemUsingDarkTheme =
|
||||
systemUiNightMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
return appForceDarkMode || (appBatterySaver && isSystemBatterySaver) || (!appBatterySaver && isSystemUsingDarkTheme && nightThemeMode == AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
}
|
||||
|
||||
fun isUsingDynamicColors(): Boolean = SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_USE_DYNAMIC_COLORS,
|
||||
SettingsKeys.DEFAULT_VALUE_USE_DYNAMIC_COLORS
|
||||
)
|
||||
|
||||
fun isUsingAmoledBackground(): Boolean = SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_APPEARANCE_AMOLED_THEME,
|
||||
SettingsKeys.DEFAULT_VALUE_APPEARANCE_AMOLED_THEME
|
||||
)
|
||||
|
||||
fun selectedColorScheme(): Int = SettingsController.getInt(
|
||||
SettingsKeys.KEY_APPEARANCE_COLOR_SCHEME,
|
||||
SettingsKeys.DEFAULT_VALUE_APPEARANCE_COLOR_SCHEME
|
||||
)
|
||||
|
||||
fun isUsingBlur(): Boolean = SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_APPEARANCE_BLUR,
|
||||
SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_BLUR
|
||||
)
|
||||
|
||||
fun isDebugSettingsShown(): Boolean = SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_SHOW_DEBUG_CATEGORY,
|
||||
false
|
||||
)
|
||||
|
||||
fun isMultiline(): Boolean = SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_APPEARANCE_MULTILINE,
|
||||
SettingsKeys.DEFAULT_VALUE_MULTILINE
|
||||
)
|
||||
@@ -1,95 +0,0 @@
|
||||
package com.meloda.app.fast.datastore
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.core.content.edit
|
||||
import kotlin.properties.Delegates
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
object SettingsController {
|
||||
|
||||
private var preferences: SharedPreferences by Delegates.notNull()
|
||||
|
||||
fun init(preferences: SharedPreferences) {
|
||||
this.preferences = preferences
|
||||
}
|
||||
|
||||
fun edit(
|
||||
commit: Boolean = false,
|
||||
action: SharedPreferences.Editor.() -> Unit
|
||||
) {
|
||||
preferences.edit(commit, action)
|
||||
}
|
||||
|
||||
fun getString(key: String, defaultValue: String?): String? {
|
||||
return preferences.getString(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
|
||||
return preferences.getBoolean(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getInt(key: String, defaultValue: Int): Int {
|
||||
return preferences.getInt(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getLong(key: String, defaultValue: Long): Long {
|
||||
return preferences.getLong(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getFloat(key: String, defaultValue: Float): Float {
|
||||
return preferences.getFloat(key, defaultValue)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : Any> get(clazz: KClass<T>, key: String, defaultValue: T): T {
|
||||
return when (clazz) {
|
||||
String::class -> getString(key, defaultValue as String)
|
||||
Boolean::class -> getBoolean(key, defaultValue as Boolean)
|
||||
Int::class -> getInt(key, defaultValue as Int)
|
||||
Long::class -> getLong(key, defaultValue as Long)
|
||||
Float::class -> getFloat(key, defaultValue as Float)
|
||||
else -> throw IllegalStateException("Unsupported class: $clazz")
|
||||
} as T
|
||||
}
|
||||
|
||||
inline fun <reified T> get(key: String, defaultValue: T): T {
|
||||
return when (T::class) {
|
||||
String::class -> getString(key, defaultValue as String)
|
||||
Boolean::class -> getBoolean(key, defaultValue as Boolean)
|
||||
Int::class -> getInt(key, defaultValue as Int)
|
||||
Long::class -> getLong(key, defaultValue as Long)
|
||||
Float::class -> getFloat(key, defaultValue as Float)
|
||||
else -> throw IllegalStateException("Unsupported class: ${T::class}")
|
||||
} as T
|
||||
}
|
||||
|
||||
fun <T> put(key: String, newValue: T?) {
|
||||
preferences.edit {
|
||||
when (newValue) {
|
||||
is String -> putString(key, newValue)
|
||||
is Boolean -> putBoolean(key, newValue)
|
||||
is Int -> putInt(key, newValue)
|
||||
is Long -> putLong(key, newValue)
|
||||
is Float -> putFloat(key, newValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var isLongPollInBackgroundEnabled: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND,
|
||||
SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND, value)
|
||||
|
||||
var deviceId: String
|
||||
get() = get("device_id", "")
|
||||
set(value) = put("device_id", value)
|
||||
|
||||
var enablePullToRefresh: Boolean
|
||||
get() = get(
|
||||
SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH,
|
||||
SettingsKeys.DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH
|
||||
)
|
||||
set(value) = put(SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH, value)
|
||||
}
|
||||
@@ -17,8 +17,8 @@ object SettingsKeys {
|
||||
const val KEY_APPEARANCE = "appearance"
|
||||
const val KEY_APPEARANCE_MULTILINE = "appearance_multiline"
|
||||
const val DEFAULT_VALUE_MULTILINE = true
|
||||
const val KEY_APPEARANCE_DARK_THEME = "appearance_appearance_dark_theme"
|
||||
const val DEFAULT_VALUE_APPEARANCE_DARK_THEME = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
const val KEY_APPEARANCE_DARK_MODE = "appearance_appearance_dark_mode"
|
||||
const val DEFAULT_VALUE_APPEARANCE_DARK_MODE = AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
|
||||
const val KEY_APPEARANCE_AMOLED_THEME = "appearance_amoled_theme"
|
||||
const val DEFAULT_VALUE_APPEARANCE_AMOLED_THEME = false
|
||||
const val KEY_USE_DYNAMIC_COLORS = "appearance_use_dynamic_colors"
|
||||
@@ -26,8 +26,9 @@ object SettingsKeys {
|
||||
const val KEY_APPEARANCE_COLOR_SCHEME = "appearance_color_scheme"
|
||||
const val DEFAULT_VALUE_APPEARANCE_COLOR_SCHEME = 0
|
||||
const val KEY_APPEARANCE_LANGUAGE = "appearance_language"
|
||||
const val KEY_APPEARANCE_BLUR = "appearance_blur"
|
||||
const val DEFAULT_VALUE_KEY_APPEARANCE_BLUR = false
|
||||
const val DEFAULT_APPEARANCE_LANGUAGE = ""
|
||||
const val KEY_APPEARANCE_USE_BLUR = "appearance_use_blur"
|
||||
const val DEFAULT_VALUE_KEY_APPEARANCE_USE_BLUR = false
|
||||
|
||||
const val KEY_FEATURES_FAST_TEXT = "features_fast_text"
|
||||
const val DEFAULT_VALUE_FEATURES_FAST_TEXT = "¯\\_(ツ)_/¯"
|
||||
|
||||
@@ -1,144 +1,124 @@
|
||||
package com.meloda.app.fast.datastore
|
||||
|
||||
import android.content.res.Resources
|
||||
import android.os.PowerManager
|
||||
import android.util.Log
|
||||
import com.meloda.app.fast.datastore.model.LongPollState
|
||||
import com.meloda.app.fast.ui.model.ThemeConfig
|
||||
import com.meloda.app.fast.common.model.DarkMode
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
interface UserSettings {
|
||||
val theme: StateFlow<ThemeConfig>
|
||||
val longPollStateToApply: StateFlow<LongPollState>
|
||||
val longPollCurrentState: StateFlow<LongPollState>
|
||||
val online: StateFlow<Boolean>
|
||||
val debugSettingsEnabled: StateFlow<Boolean>
|
||||
|
||||
val useContactNames: StateFlow<Boolean>
|
||||
val language: StateFlow<String>
|
||||
val enablePullToRefresh: StateFlow<Boolean>
|
||||
|
||||
fun updateUsingDarkTheme()
|
||||
fun useDarkThemeChanged(use: Boolean)
|
||||
fun useAmoledThemeChanged(use: Boolean)
|
||||
fun useDynamicColorsChanged(use: Boolean)
|
||||
fun useBlurChanged(use: Boolean)
|
||||
fun useMultiline(use: Boolean)
|
||||
fun setLongPollStateToApply(newState: LongPollState)
|
||||
fun updateLongPollCurrentState(currentState: LongPollState)
|
||||
fun setOnline(use: Boolean)
|
||||
fun enableDebugSettings(enable: Boolean)
|
||||
val enableMultiline: StateFlow<Boolean>
|
||||
val darkMode: StateFlow<DarkMode>
|
||||
val enableAmoledDark: StateFlow<Boolean>
|
||||
val enableDynamicColors: StateFlow<Boolean>
|
||||
val appLanguage: StateFlow<String>
|
||||
|
||||
val fastText: StateFlow<String>
|
||||
|
||||
val sendOnlineStatus: StateFlow<Boolean>
|
||||
|
||||
val showAlertAfterCrash: StateFlow<Boolean>
|
||||
val longPollInBackground: StateFlow<Boolean>
|
||||
val useBlur: StateFlow<Boolean>
|
||||
val showEmojiButton: StateFlow<Boolean>
|
||||
val showDebugCategory: StateFlow<Boolean>
|
||||
|
||||
fun onUseContactNamesChanged(use: Boolean)
|
||||
fun onLanguageChanged(newLanguage: String)
|
||||
fun onEnablePullToRefreshChanged(enable: Boolean)
|
||||
|
||||
fun onEnableMultilineChanged(enable: Boolean)
|
||||
fun onDarkModeChanged(mode: DarkMode)
|
||||
fun onEnableAmoledDarkChanged(enable: Boolean)
|
||||
fun onEnableDynamicColorsChanged(enable: Boolean)
|
||||
fun onAppLanguageChanged(language: String)
|
||||
|
||||
fun onFastTextChanged(text: String)
|
||||
|
||||
fun onSendOnlineStatusChanged(send: Boolean)
|
||||
|
||||
fun onShowAlertAfterCrashChanged(show: Boolean)
|
||||
fun onLongPollInBackgroundChanged(inBackground: Boolean)
|
||||
fun onUseBlurChanged(use: Boolean)
|
||||
fun onShowEmojiButtonChanged(show: Boolean)
|
||||
fun onShowDebugCategoryChanged(show: Boolean)
|
||||
}
|
||||
|
||||
class UserSettingsImpl(
|
||||
private val resources: Resources,
|
||||
private val powerManager: PowerManager
|
||||
) : UserSettings {
|
||||
class UserSettingsImpl : UserSettings {
|
||||
|
||||
override val theme = MutableStateFlow(
|
||||
ThemeConfig(
|
||||
usingDarkStyle = isUsingDarkMode(resources, powerManager),
|
||||
usingDynamicColors = isUsingDynamicColors(),
|
||||
selectedColorScheme = selectedColorScheme(),
|
||||
usingAmoledBackground = isUsingAmoledBackground(),
|
||||
usingBlur = isUsingBlur(),
|
||||
isMultiline = isMultiline(),
|
||||
isDeviceCompact = false
|
||||
)
|
||||
)
|
||||
override val useContactNames = MutableStateFlow(AppSettings.General.useContactNames)
|
||||
override val enablePullToRefresh = MutableStateFlow(AppSettings.General.enablePullToRefresh)
|
||||
|
||||
override val longPollStateToApply = MutableStateFlow<LongPollState>(LongPollState.Stopped)
|
||||
override val longPollCurrentState = MutableStateFlow<LongPollState>(LongPollState.Stopped)
|
||||
override val enableMultiline = MutableStateFlow(AppSettings.Appearance.enableMultiline)
|
||||
override val darkMode = MutableStateFlow(AppSettings.Appearance.darkMode)
|
||||
override val enableAmoledDark = MutableStateFlow(AppSettings.Appearance.enableAmoledDark)
|
||||
override val enableDynamicColors = MutableStateFlow(AppSettings.Appearance.enableDynamicColors)
|
||||
override val appLanguage = MutableStateFlow(AppSettings.Appearance.appLanguage)
|
||||
|
||||
override val online = MutableStateFlow(
|
||||
SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS,
|
||||
SettingsKeys.DEFAULT_VALUE_KEY_ACTIVITY_SEND_ONLINE_STATUS
|
||||
)
|
||||
)
|
||||
override val fastText = MutableStateFlow(AppSettings.Features.fastText)
|
||||
|
||||
override val debugSettingsEnabled = MutableStateFlow(
|
||||
SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_SHOW_DEBUG_CATEGORY,
|
||||
false
|
||||
)
|
||||
)
|
||||
override val sendOnlineStatus = MutableStateFlow(AppSettings.Activity.sendOnlineStatus)
|
||||
|
||||
override val useContactNames = MutableStateFlow(
|
||||
SettingsController.getBoolean(
|
||||
SettingsKeys.KEY_USE_CONTACT_NAMES,
|
||||
SettingsKeys.DEFAULT_VALUE_USE_CONTACT_NAMES
|
||||
)
|
||||
)
|
||||
|
||||
override val language = MutableStateFlow("")
|
||||
|
||||
override val enablePullToRefresh = MutableStateFlow(SettingsController.enablePullToRefresh)
|
||||
|
||||
override fun updateUsingDarkTheme() {
|
||||
useDarkThemeChanged(
|
||||
isUsingDarkMode(
|
||||
resources = resources,
|
||||
powerManager = powerManager,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun useDarkThemeChanged(use: Boolean) {
|
||||
theme.value = theme.value.copy(
|
||||
usingDarkStyle = use
|
||||
)
|
||||
}
|
||||
|
||||
override fun useAmoledThemeChanged(use: Boolean) {
|
||||
theme.value = theme.value.copy(
|
||||
usingAmoledBackground = use
|
||||
)
|
||||
}
|
||||
|
||||
override fun useDynamicColorsChanged(use: Boolean) {
|
||||
theme.value = theme.value.copy(usingDynamicColors = use)
|
||||
}
|
||||
|
||||
override fun useBlurChanged(use: Boolean) {
|
||||
theme.value = theme.value.copy(usingBlur = use)
|
||||
}
|
||||
|
||||
override fun useMultiline(use: Boolean) {
|
||||
theme.value = theme.value.copy(isMultiline = use)
|
||||
}
|
||||
|
||||
override fun setLongPollStateToApply(newState: LongPollState) {
|
||||
longPollStateToApply.update { newState }
|
||||
Log.d("UserSettings", "setLongPollState: $newState")
|
||||
}
|
||||
|
||||
override fun updateLongPollCurrentState(currentState: LongPollState) {
|
||||
longPollCurrentState.update { currentState }
|
||||
Log.d("UserSettings", "updateLongPollCurrentState: $currentState")
|
||||
}
|
||||
|
||||
override fun setOnline(use: Boolean) {
|
||||
online.value = use
|
||||
}
|
||||
|
||||
override fun enableDebugSettings(enable: Boolean) {
|
||||
debugSettingsEnabled.update { enable }
|
||||
}
|
||||
override val showAlertAfterCrash = MutableStateFlow(AppSettings.Debug.showAlertAfterCrash)
|
||||
override val longPollInBackground = MutableStateFlow(AppSettings.Debug.longPollInBackground)
|
||||
override val useBlur = MutableStateFlow(AppSettings.Debug.useBlur)
|
||||
override val showEmojiButton = MutableStateFlow(AppSettings.Debug.showEmojiButton)
|
||||
override val showDebugCategory = MutableStateFlow(AppSettings.Debug.showDebugCategory)
|
||||
|
||||
override fun onUseContactNamesChanged(use: Boolean) {
|
||||
useContactNames.update { use }
|
||||
}
|
||||
|
||||
override fun onLanguageChanged(newLanguage: String) {
|
||||
language.update { newLanguage }
|
||||
useContactNames.value = use
|
||||
}
|
||||
|
||||
override fun onEnablePullToRefreshChanged(enable: Boolean) {
|
||||
enablePullToRefresh.update { enable }
|
||||
enablePullToRefresh.value = enable
|
||||
}
|
||||
|
||||
override fun onEnableMultilineChanged(enable: Boolean) {
|
||||
enableMultiline.value = enable
|
||||
}
|
||||
|
||||
override fun onDarkModeChanged(mode: DarkMode) {
|
||||
darkMode.value = mode
|
||||
}
|
||||
|
||||
override fun onEnableAmoledDarkChanged(enable: Boolean) {
|
||||
enableAmoledDark.value = enable
|
||||
}
|
||||
|
||||
override fun onEnableDynamicColorsChanged(enable: Boolean) {
|
||||
enableDynamicColors.value = enable
|
||||
}
|
||||
|
||||
override fun onAppLanguageChanged(language: String) {
|
||||
appLanguage.value = language
|
||||
}
|
||||
|
||||
override fun onFastTextChanged(text: String) {
|
||||
fastText.value = text
|
||||
}
|
||||
|
||||
override fun onSendOnlineStatusChanged(send: Boolean) {
|
||||
sendOnlineStatus.value = send
|
||||
}
|
||||
|
||||
override fun onShowAlertAfterCrashChanged(show: Boolean) {
|
||||
showAlertAfterCrash.value = show
|
||||
}
|
||||
|
||||
override fun onLongPollInBackgroundChanged(inBackground: Boolean) {
|
||||
longPollInBackground.value = inBackground
|
||||
}
|
||||
|
||||
override fun onUseBlurChanged(use: Boolean) {
|
||||
useBlur.value = use
|
||||
}
|
||||
|
||||
override fun onShowEmojiButtonChanged(show: Boolean) {
|
||||
showEmojiButton.value = show
|
||||
}
|
||||
|
||||
override fun onShowDebugCategoryChanged(show: Boolean) {
|
||||
showDebugCategory.value = show
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
package com.meloda.app.fast.network.interceptor
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import com.meloda.app.fast.common.ApiLanguage
|
||||
import com.meloda.app.fast.common.model.ApiLanguage
|
||||
import com.meloda.app.fast.common.provider.Provider
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
@@ -22,7 +22,7 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.graphics.luminance
|
||||
import com.meloda.app.fast.ui.theme.LocalIsDarkTheme
|
||||
import com.meloda.app.fast.ui.theme.LocalThemeConfig
|
||||
|
||||
/**
|
||||
* Default alpha levels used by Material components.
|
||||
@@ -79,7 +79,7 @@ object ContentAlpha {
|
||||
lowContrastAlpha: Float
|
||||
): Float {
|
||||
val contentColor = LocalContentColor.current
|
||||
return if (!LocalIsDarkTheme.current) {
|
||||
return if (!LocalThemeConfig.current.darkMode) {
|
||||
if (contentColor.luminance() > 0.5) highContrastAlpha else lowContrastAlpha
|
||||
} else {
|
||||
if (contentColor.luminance() < 0.5) highContrastAlpha else lowContrastAlpha
|
||||
|
||||
@@ -33,8 +33,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.meloda.app.fast.common.UiText
|
||||
import com.meloda.app.fast.common.parseString
|
||||
import com.meloda.app.fast.common.model.UiText
|
||||
import com.meloda.app.fast.common.model.parseString
|
||||
import com.meloda.app.fast.ui.util.ImmutableList
|
||||
import com.meloda.app.fast.ui.util.ImmutableList.Companion.toImmutableList
|
||||
import com.meloda.app.fast.ui.util.getString
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.meloda.app.fast.ui.model
|
||||
|
||||
data class ThemeConfig(
|
||||
val usingDarkStyle: Boolean,
|
||||
val usingDynamicColors: Boolean,
|
||||
val darkMode: Boolean,
|
||||
val dynamicColors: Boolean,
|
||||
val selectedColorScheme: Int,
|
||||
val usingAmoledBackground: Boolean,
|
||||
val usingBlur: Boolean,
|
||||
val isMultiline: Boolean,
|
||||
val amoledDark: Boolean,
|
||||
val enableBlur: Boolean,
|
||||
val enableMultiline: Boolean,
|
||||
val isDeviceCompact: Boolean
|
||||
)
|
||||
|
||||
@@ -9,7 +9,6 @@ import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -104,20 +103,18 @@ private val robotoFonts = FontFamily(
|
||||
)
|
||||
)
|
||||
|
||||
val LocalTheme = compositionLocalOf {
|
||||
val LocalThemeConfig = compositionLocalOf {
|
||||
ThemeConfig(
|
||||
usingDarkStyle = false,
|
||||
usingDynamicColors = false,
|
||||
darkMode = false,
|
||||
dynamicColors = false,
|
||||
selectedColorScheme = 0,
|
||||
usingAmoledBackground = false,
|
||||
usingBlur = false,
|
||||
isMultiline = false,
|
||||
amoledDark = false,
|
||||
enableBlur = false,
|
||||
enableMultiline = false,
|
||||
isDeviceCompact = false
|
||||
)
|
||||
}
|
||||
|
||||
val LocalIsDarkTheme = compositionLocalOf { false }
|
||||
|
||||
val LocalHazeState = compositionLocalOf {
|
||||
HazeState()
|
||||
}
|
||||
@@ -181,11 +178,9 @@ fun AppTheme(
|
||||
}
|
||||
}
|
||||
|
||||
CompositionLocalProvider(LocalIsDarkTheme provides useDarkTheme) {
|
||||
MaterialTheme(
|
||||
colorScheme = predefinedColorScheme ?: colorScheme,
|
||||
typography = typography,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.meloda.app.fast.ui.util
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.PowerManager
|
||||
import android.view.KeyEvent
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -10,9 +12,12 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.key.onKeyEvent
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.meloda.app.fast.common.UiText
|
||||
import androidx.core.content.getSystemService
|
||||
import com.meloda.app.fast.common.model.DarkMode
|
||||
import com.meloda.app.fast.common.model.UiText
|
||||
|
||||
@Composable
|
||||
fun UiText?.getString(): String? {
|
||||
@@ -75,3 +80,19 @@ fun LazyListState.isScrollingUp(): Boolean {
|
||||
}
|
||||
}.value
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun isNeedToEnableDarkMode(darkMode: DarkMode): Boolean {
|
||||
val context = LocalContext.current
|
||||
|
||||
val appForceDarkMode = darkMode == DarkMode.ENABLED
|
||||
val appBatterySaver = darkMode == DarkMode.AUTO_BATTERY
|
||||
|
||||
val systemUiNightMode = context.resources.configuration.uiMode
|
||||
|
||||
val isSystemBatterySaver = context.getSystemService<PowerManager>()?.isPowerSaveMode == true
|
||||
val isSystemUsingDarkTheme =
|
||||
systemUiNightMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES
|
||||
|
||||
return appForceDarkMode || (appBatterySaver && isSystemBatterySaver) || (!appBatterySaver && isSystemUsingDarkTheme && darkMode == DarkMode.FOLLOW_SYSTEM)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
+3
-3
@@ -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()
|
||||
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+8
-8
@@ -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
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+7
-7
@@ -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()
|
||||
|
||||
+3
-3
@@ -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(
|
||||
|
||||
+7
-7
@@ -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
|
||||
|
||||
+2
-2
@@ -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
-1
@@ -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
-1
@@ -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,
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+4
-4
@@ -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 = {
|
||||
|
||||
+3
-3
@@ -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()
|
||||
|
||||
+3
-3
@@ -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
-1
@@ -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
-1
@@ -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(
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
|
||||
+109
-94
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-7
@@ -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
-1
@@ -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?
|
||||
|
||||
+12
-40
@@ -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()
|
||||
|
||||
+4
-4
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
+4
-4
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
+4
-4
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
+3
-3
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
+4
-4
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user