diff --git a/app/src/main/kotlin/dev/meloda/fast/MainViewModel.kt b/app/src/main/kotlin/dev/meloda/fast/MainViewModel.kt index f302b0ee..8670d011 100644 --- a/app/src/main/kotlin/dev/meloda/fast/MainViewModel.kt +++ b/app/src/main/kotlin/dev/meloda/fast/MainViewModel.kt @@ -209,7 +209,7 @@ class MainViewModelImpl( } longPollController.setStateToApply( - if (AppSettings.Debug.longPollInBackground) { + if (AppSettings.Experimental.longPollInBackground) { LongPollState.Background } else { LongPollState.InApp @@ -233,7 +233,7 @@ class MainViewModelImpl( } private fun disableBackgroundLongPoll() { - AppSettings.Debug.longPollInBackground = false + AppSettings.Experimental.longPollInBackground = false longPollController.setStateToApply(LongPollState.InApp) } } diff --git a/app/src/main/kotlin/dev/meloda/fast/presentation/MainActivity.kt b/app/src/main/kotlin/dev/meloda/fast/presentation/MainActivity.kt index 78bbe1ec..9c1fe083 100644 --- a/app/src/main/kotlin/dev/meloda/fast/presentation/MainActivity.kt +++ b/app/src/main/kotlin/dev/meloda/fast/presentation/MainActivity.kt @@ -24,7 +24,6 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalContext -import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -250,12 +249,11 @@ class MainActivity : AppCompatActivity() { val noCategoryName = getString(UiR.string.notification_channel_no_category_name) val noCategoryDescriptionText = getString(UiR.string.notification_channel_no_category_description) - val noCategoryImportance = NotificationManagerCompat.IMPORTANCE_HIGH val noCategoryChannel = NotificationChannel( AppConstants.NOTIFICATION_CHANNEL_UNCATEGORIZED, noCategoryName, - noCategoryImportance + NotificationManager.IMPORTANCE_HIGH ).apply { description = noCategoryDescriptionText } @@ -263,12 +261,11 @@ class MainActivity : AppCompatActivity() { val longPollName = getString(UiR.string.notification_channel_long_polling_service_name) val longPollDescriptionText = getString(UiR.string.notification_channel_long_polling_service_description) - val longPollImportance = NotificationManagerCompat.IMPORTANCE_NONE val longPollChannel = NotificationChannel( AppConstants.NOTIFICATION_CHANNEL_LONG_POLLING, longPollName, - longPollImportance + NotificationManager.IMPORTANCE_NONE ).apply { description = longPollDescriptionText } @@ -287,7 +284,7 @@ class MainActivity : AppCompatActivity() { private fun toggleLongPollService( enable: Boolean, - inBackground: Boolean = AppSettings.Debug.longPollInBackground + inBackground: Boolean = AppSettings.Experimental.longPollInBackground ) { if (enable) { val longPollIntent = Intent(this, LongPollingService::class.java) @@ -313,7 +310,7 @@ class MainActivity : AppCompatActivity() { private fun stopServices() { toggleOnlineService(enable = false) - val asForeground = AppSettings.Debug.longPollInBackground + val asForeground = AppSettings.Experimental.longPollInBackground if (!asForeground) { toggleLongPollService(enable = false) diff --git a/app/src/main/kotlin/dev/meloda/fast/service/longpolling/LongPollingService.kt b/app/src/main/kotlin/dev/meloda/fast/service/longpolling/LongPollingService.kt index 4c4a7889..30056e51 100644 --- a/app/src/main/kotlin/dev/meloda/fast/service/longpolling/LongPollingService.kt +++ b/app/src/main/kotlin/dev/meloda/fast/service/longpolling/LongPollingService.kt @@ -76,7 +76,7 @@ class LongPollingService : Service() { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (startId > 1) return START_STICKY - val inBackground = AppSettings.Debug.longPollInBackground + val inBackground = AppSettings.Experimental.longPollInBackground Log.d( STATE_TAG, @@ -258,10 +258,10 @@ class LongPollingService : Service() { super.onDestroy() } - override fun onLowMemory() { - Log.d(STATE_TAG, "onLowMemory") + override fun onTrimMemory(level: Int) { + Log.d(STATE_TAG, "onTrimMemory") longPollController.updateCurrentState(LongPollState.Stopped) - super.onLowMemory() + super.onTrimMemory(level) } companion object { diff --git a/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt index 85193c88..c0ce7a51 100644 --- a/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/dev/meloda/fast/KotlinAndroid.kt @@ -9,8 +9,8 @@ import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.provideDelegate import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinBaseExtension import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinTopLevelExtension internal fun Project.configureKotlinAndroid( commonExtension: CommonExtension<*, *, *, *, *, *>, @@ -40,7 +40,7 @@ internal fun Project.configureKotlinJvm() { configureKotlin() } -private inline fun Project.configureKotlin() = configure { +private inline fun Project.configureKotlin() = configure { // Treat all Kotlin warnings as errors (disabled by default) // Override by setting warningsAsErrors=true in your ~/.gradle/gradle.properties val warningsAsErrors: String? by project diff --git a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/AppSettings.kt b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/AppSettings.kt index e1f1f649..36a2b11b 100644 --- a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/AppSettings.kt +++ b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/AppSettings.kt @@ -89,12 +89,20 @@ object AppSettings { ) set(value) = put(SettingsKeys.KEY_USE_CONTACT_NAMES, value) - var enablePullToRefresh: Boolean + var showEmojiButton: Boolean get() = get( - SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH, - SettingsKeys.DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH + SettingsKeys.KEY_SHOW_EMOJI_BUTTON, + SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON ) - set(value) = put(SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH, value) + set(value) = put(SettingsKeys.KEY_SHOW_EMOJI_BUTTON, value) + + var enableHaptic: Boolean + get() = get( + SettingsKeys.KEY_ENABLE_HAPTIC, + SettingsKeys.DEFAULT_ENABLE_HAPTIC + ) + set(value) = put(SettingsKeys.KEY_ENABLE_HAPTIC, value) + } object Appearance { @@ -126,6 +134,13 @@ object AppSettings { ) set(value) = put(SettingsKeys.KEY_USE_DYNAMIC_COLORS, value) + var useSystemFont: Boolean + get() = get( + SettingsKeys.KEY_USE_SYSTEM_FONT, + SettingsKeys.DEFAULT_USE_SYSTEM_FONT + ) + set(value) = put(SettingsKeys.KEY_USE_SYSTEM_FONT, value) + var appLanguage: String get() = get( SettingsKeys.KEY_APPEARANCE_LANGUAGE, @@ -152,6 +167,29 @@ object AppSettings { set(value) = put(SettingsKeys.KEY_ACTIVITY_SEND_ONLINE_STATUS, value) } + object Experimental { + var longPollInBackground: Boolean + get() = get( + SettingsKeys.KEY_LONG_POLL_IN_BACKGROUND, + SettingsKeys.DEFAULT_LONG_POLL_IN_BACKGROUND + ) + set(value) = put(SettingsKeys.KEY_LONG_POLL_IN_BACKGROUND, value) + + var showTimeInActionMessages: Boolean + get() = get( + SettingsKeys.KEY_SHOW_TIME_IN_ACTION_MESSAGES, + SettingsKeys.DEFAULT_SHOW_TIME_IN_ACTION_MESSAGES + ) + set(value) = put(SettingsKeys.KEY_SHOW_TIME_IN_ACTION_MESSAGES, value) + + var useBlur: Boolean + get() = get( + SettingsKeys.KEY_USE_BLUR, + SettingsKeys.DEFAULT_USE_BLUR + ) + set(value) = put(SettingsKeys.KEY_USE_BLUR, value) + } + object Debug { var showAlertAfterCrash: Boolean get() = get( @@ -160,41 +198,6 @@ object AppSettings { ) 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 showTimeInActionMessages: Boolean - get() = get( - SettingsKeys.KEY_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES, - SettingsKeys.DEFAULT_VALUE_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES - ) - set(value) = put(SettingsKeys.KEY_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES, value) - - var enableHaptic: Boolean - get() = get( - SettingsKeys.KEY_DEBUG_ENABLE_HAPTIC, - SettingsKeys.DEFAULT_DEBUG_ENABLE_HAPTIC - ) - set(value) = put(SettingsKeys.KEY_DEBUG_ENABLE_HAPTIC, value) - var networkLogLevel: LogLevel get() = get( SettingsKeys.KEY_DEBUG_NETWORK_LOG_LEVEL, @@ -202,13 +205,6 @@ object AppSettings { ).let(LogLevel::parse) set(level) = put(SettingsKeys.KEY_DEBUG_NETWORK_LOG_LEVEL, level.value) - var useSystemFont: Boolean - get() = get( - SettingsKeys.KEY_DEBUG_USE_SYSTEM_FONT, - SettingsKeys.DEFAULT_DEBUG_USE_SYSTEM_FONT - ) - set(value) = put(SettingsKeys.KEY_DEBUG_USE_SYSTEM_FONT, value) - var showDebugCategory: Boolean get() = get( SettingsKeys.KEY_SHOW_DEBUG_CATEGORY, diff --git a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/SettingsKeys.kt b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/SettingsKeys.kt index 5681017b..3634c050 100644 --- a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/SettingsKeys.kt +++ b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/SettingsKeys.kt @@ -7,11 +7,9 @@ object SettingsKeys { const val KEY_ACCOUNT_LOGOUT = "account_logout" const val KEY_GENERAL = "general" - const val KEY_USE_CONTACT_NAMES = "general_use_contact_names" + const val KEY_USE_CONTACT_NAMES = "use_contact_names" const val DEFAULT_VALUE_USE_CONTACT_NAMES = false - const val KEY_ENABLE_PULL_TO_REFRESH = "general_pull_to_refresh" - const val DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH = false - const val KEY_SHOW_EMOJI_BUTTON = "general_show_emoji_button" + const val KEY_SHOW_EMOJI_BUTTON = "show_emoji_button" const val DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON = false const val KEY_APPEARANCE = "appearance" @@ -23,20 +21,20 @@ object SettingsKeys { const val DEFAULT_VALUE_APPEARANCE_AMOLED_THEME = false const val KEY_USE_DYNAMIC_COLORS = "appearance_use_dynamic_colors" const val DEFAULT_VALUE_USE_DYNAMIC_COLORS = false - const val KEY_APPEARANCE_COLOR_SCHEME = "appearance_color_scheme" - const val DEFAULT_VALUE_APPEARANCE_COLOR_SCHEME = 0 + const val KEY_COLOR_SCHEME = "appearance_color_scheme" + const val DEFAULT_COLOR_SCHEME = 0 const val KEY_APPEARANCE_LANGUAGE = "appearance_language" 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_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES = - "appearance_show_time_in_action_messages" - const val DEFAULT_VALUE_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES = false + const val KEY_USE_BLUR = "use_blur" + const val DEFAULT_USE_BLUR = false + const val KEY_SHOW_TIME_IN_ACTION_MESSAGES = + "show_time_in_action_messages" + const val DEFAULT_SHOW_TIME_IN_ACTION_MESSAGES = false const val KEY_FEATURES_FAST_TEXT = "features_fast_text" const val DEFAULT_VALUE_FEATURES_FAST_TEXT = "¯\\_(ツ)_/¯" - const val KEY_FEATURES_LONG_POLL_IN_BACKGROUND = "features_lp_background" - const val DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND = false + const val KEY_LONG_POLL_IN_BACKGROUND = "lp_background" + const val DEFAULT_LONG_POLL_IN_BACKGROUND = false const val KEY_ACTIVITY_SEND_ONLINE_STATUS = "activity_send_online_status" const val DEFAULT_VALUE_KEY_ACTIVITY_SEND_ONLINE_STATUS = false @@ -45,12 +43,12 @@ object SettingsKeys { const val KEY_DEBUG_SHOW_CRASH_ALERT = "debug_show_crash_alert" const val KEY_DEBUG_HIDE_DEBUG_LIST = "debug_hide_debug_list" const val KEY_ENABLE_ANIMATIONS_IN_MESSAGES = "debug_enable_animations_in_messages" - const val KEY_DEBUG_ENABLE_HAPTIC = "debug_enable_haptic" - const val DEFAULT_DEBUG_ENABLE_HAPTIC = true + const val KEY_ENABLE_HAPTIC = "enable_haptic" + const val DEFAULT_ENABLE_HAPTIC = true const val KEY_DEBUG_NETWORK_LOG_LEVEL = "debug_network_log_level" const val DEFAULT_NETWORK_LOG_LEVEL = 0 - const val KEY_DEBUG_USE_SYSTEM_FONT = "debug_use_system_font" - const val DEFAULT_DEBUG_USE_SYSTEM_FONT = false + const val KEY_USE_SYSTEM_FONT = "use_system_font" + const val DEFAULT_USE_SYSTEM_FONT = false const val KEY_SHOW_DEBUG_CATEGORY = "show_debug_category" diff --git a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/UserSettings.kt b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/UserSettings.kt index 22e57a24..a8585cef 100644 --- a/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/UserSettings.kt +++ b/core/datastore/src/main/kotlin/dev/meloda/fast/datastore/UserSettings.kt @@ -7,7 +7,6 @@ import kotlinx.coroutines.flow.StateFlow interface UserSettings { val useContactNames: StateFlow - val enablePullToRefresh: StateFlow val enableMultiline: StateFlow val darkMode: StateFlow @@ -28,7 +27,6 @@ interface UserSettings { val showDebugCategory: StateFlow fun onUseContactNamesChanged(use: Boolean) - fun onEnablePullToRefreshChanged(enable: Boolean) fun onEnableMultilineChanged(enable: Boolean) fun onDarkModeChanged(mode: DarkMode) @@ -52,7 +50,6 @@ interface UserSettings { class UserSettingsImpl : UserSettings { override val useContactNames = MutableStateFlow(AppSettings.General.useContactNames) - override val enablePullToRefresh = MutableStateFlow(AppSettings.General.enablePullToRefresh) override val enableMultiline = MutableStateFlow(AppSettings.Appearance.enableMultiline) override val darkMode = MutableStateFlow(AppSettings.Appearance.darkMode) @@ -65,22 +62,18 @@ class UserSettingsImpl : UserSettings { override val sendOnlineStatus = MutableStateFlow(AppSettings.Activity.sendOnlineStatus) 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 longPollInBackground = MutableStateFlow(AppSettings.Experimental.longPollInBackground) + override val useBlur = MutableStateFlow(AppSettings.Experimental.useBlur) + override val showEmojiButton = MutableStateFlow(AppSettings.General.showEmojiButton) override val showTimeInActionMessages = - MutableStateFlow(AppSettings.Debug.showTimeInActionMessages) - override val useSystemFont = MutableStateFlow(AppSettings.Debug.useSystemFont) + MutableStateFlow(AppSettings.Experimental.showTimeInActionMessages) + override val useSystemFont = MutableStateFlow(AppSettings.Appearance.useSystemFont) override val showDebugCategory = MutableStateFlow(AppSettings.Debug.showDebugCategory) override fun onUseContactNamesChanged(use: Boolean) { useContactNames.value = use } - override fun onEnablePullToRefreshChanged(enable: Boolean) { - enablePullToRefresh.value = enable - } - override fun onEnableMultilineChanged(enable: Boolean) { enableMultiline.value = enable } diff --git a/core/ui/src/main/kotlin/dev/meloda/fast/ui/components/IconButton.kt b/core/ui/src/main/kotlin/dev/meloda/fast/ui/components/IconButton.kt new file mode 100644 index 00000000..e6516beb --- /dev/null +++ b/core/ui/src/main/kotlin/dev/meloda/fast/ui/components/IconButton.kt @@ -0,0 +1,90 @@ +package dev.meloda.fast.ui.components + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.Indication +import androidx.compose.foundation.background +import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material.ripple.rememberRipple +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.IconButtonColors +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.LocalUseFallbackRippleImplementation +import androidx.compose.material3.minimumInteractiveComponentSize +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.Stable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun IconButton( + onClick: () -> Unit = {}, + onLongClick: (() -> Unit)? = null, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: IconButtonColors = IconButtonDefaults.iconButtonColors(), + interactionSource: MutableInteractionSource? = null, + content: @Composable () -> Unit +) { + Box( + modifier = + modifier + .minimumInteractiveComponentSize() + .size(IconButtonTokens.StateLayerSize) + .clip(IconButtonTokens.StateLayerShape) + .background(color = colors.containerColor(enabled)) + .combinedClickable( + onClick = onClick, + onLongClick = onLongClick, + enabled = enabled, + interactionSource = interactionSource, + indication = rippleOrFallbackImplementation( + bounded = false, + radius = IconButtonTokens.StateLayerSize / 2 + ) + ), + contentAlignment = Alignment.Center + ) { + val contentColor = colors.contentColor(enabled) + CompositionLocalProvider(LocalContentColor provides contentColor, content = content) + } +} + +@Suppress("DEPRECATION_ERROR") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +internal fun rippleOrFallbackImplementation( + bounded: Boolean = true, + radius: Dp = Dp.Unspecified, + color: Color = Color.Unspecified +): Indication { + return if (LocalUseFallbackRippleImplementation.current) { + rememberRipple(bounded, radius, color) + } else { + ripple(bounded, radius, color) + } +} + +internal object IconButtonTokens { + val StateLayerShape = CircleShape + val StateLayerSize = 40.0.dp +} + +@Stable +internal fun IconButtonColors.containerColor(enabled: Boolean): Color = + if (enabled) containerColor else disabledContainerColor + +@Stable +internal fun IconButtonColors.contentColor(enabled: Boolean): Color = + if (enabled) contentColor else disabledContentColor diff --git a/core/ui/src/main/res/values-ru/strings.xml b/core/ui/src/main/res/values-ru/strings.xml index 9368b131..b099304a 100644 --- a/core/ui/src/main/res/values-ru/strings.xml +++ b/core/ui/src/main/res/values-ru/strings.xml @@ -182,7 +182,7 @@ Заголовок чата и текст сообщения смогут занимать несколько строчек Фичи Fast текст - [WIP] LongPoll в фоне + LongPoll в фоне Ваши сообщения будут обновляться, даже если приложение находится в фоне Активность Быть «в сети» diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml index 49fa7ae6..a1cbf61e 100644 --- a/core/ui/src/main/res/values/strings.xml +++ b/core/ui/src/main/res/values/strings.xml @@ -240,8 +240,8 @@ The title of the conversation and the text of the message can take up multiple lines Features Fast text - [WIP] LongPoll in background - Your messages will be updates even when app is not on the screen + LongPoll in background + Your messages will be updating even when app is not on the screen Activity Send online status Online status will be sent every five minutes diff --git a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/captcha/di/CaptchaDI.kt b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/captcha/di/CaptchaDI.kt index c63fce8e..3ea7203f 100644 --- a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/captcha/di/CaptchaDI.kt +++ b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/captcha/di/CaptchaDI.kt @@ -3,8 +3,8 @@ package dev.meloda.fast.auth.captcha.di import dev.meloda.fast.auth.captcha.CaptchaViewModel import dev.meloda.fast.auth.captcha.CaptchaViewModelImpl import dev.meloda.fast.auth.captcha.validation.CaptchaValidator -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module diff --git a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/LoginViewModel.kt b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/LoginViewModel.kt index f8227713..9390645f 100644 --- a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/LoginViewModel.kt +++ b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/LoginViewModel.kt @@ -368,7 +368,7 @@ class LoginViewModelImpl( private fun startLongPoll() { longPollController.setStateToApply( - if (AppSettings.Debug.longPollInBackground) { + if (AppSettings.Experimental.longPollInBackground) { LongPollState.Background } else { LongPollState.InApp diff --git a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/di/LoginModule.kt b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/di/LoginModule.kt index 5a149d8a..de8e3c95 100644 --- a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/di/LoginModule.kt +++ b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/login/di/LoginModule.kt @@ -4,8 +4,8 @@ import dev.meloda.fast.auth.login.LoginViewModelImpl import dev.meloda.fast.domain.OAuthUseCase import dev.meloda.fast.domain.OAuthUseCaseImpl import dev.meloda.fast.auth.login.validation.LoginValidator -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module diff --git a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/validation/di/ValidationModule.kt b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/validation/di/ValidationModule.kt index 54280c3b..a04297c2 100644 --- a/feature/auth/src/main/kotlin/dev/meloda/fast/auth/validation/di/ValidationModule.kt +++ b/feature/auth/src/main/kotlin/dev/meloda/fast/auth/validation/di/ValidationModule.kt @@ -5,8 +5,8 @@ import dev.meloda.fast.domain.AuthUseCaseImpl import dev.meloda.fast.auth.validation.ValidationViewModel import dev.meloda.fast.auth.validation.ValidationViewModelImpl import dev.meloda.fast.auth.validation.validation.ValidationValidator -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module diff --git a/feature/chatmaterials/src/main/kotlin/dev/meloda/fast/chatmaterials/presentation/ChatMaterialsScreen.kt b/feature/chatmaterials/src/main/kotlin/dev/meloda/fast/chatmaterials/presentation/ChatMaterialsScreen.kt index 1b7ed4bb..bc73daef 100644 --- a/feature/chatmaterials/src/main/kotlin/dev/meloda/fast/chatmaterials/presentation/ChatMaterialsScreen.kt +++ b/feature/chatmaterials/src/main/kotlin/dev/meloda/fast/chatmaterials/presentation/ChatMaterialsScreen.kt @@ -70,11 +70,9 @@ import dev.meloda.fast.chatmaterials.ChatMaterialsViewModel import dev.meloda.fast.chatmaterials.ChatMaterialsViewModelImpl import dev.meloda.fast.chatmaterials.model.ChatMaterialsScreenState import dev.meloda.fast.chatmaterials.model.UiChatMaterial -import dev.meloda.fast.datastore.UserSettings import dev.meloda.fast.ui.R import dev.meloda.fast.ui.theme.LocalThemeConfig import org.koin.androidx.compose.koinViewModel -import org.koin.compose.koinInject @Composable fun ChatMaterialsRoute( @@ -82,15 +80,10 @@ fun ChatMaterialsRoute( onPhotoClicked: (url: String) -> Unit, viewModel: ChatMaterialsViewModel = koinViewModel() ) { - val userSettings: UserSettings = koinInject() - - val enablePullToRefresh by userSettings.enablePullToRefresh.collectAsStateWithLifecycle() - val screenState by viewModel.screenState.collectAsStateWithLifecycle() ChatMaterialsScreen( screenState = screenState, - enablePullToRefresh = enablePullToRefresh, onBack = onBack, onTypeChanged = viewModel::onTypeChanged, onRefreshDropdownItemClicked = viewModel::onRefresh, @@ -107,7 +100,6 @@ fun ChatMaterialsRoute( @Composable fun ChatMaterialsScreen( screenState: ChatMaterialsScreenState = ChatMaterialsScreenState.EMPTY, - enablePullToRefresh: Boolean = false, onBack: () -> Unit = {}, onTypeChanged: (String) -> Unit = {}, onRefreshDropdownItemClicked: () -> Unit = {}, diff --git a/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/di/ConversationsModule.kt b/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/di/ConversationsModule.kt index b7ac163e..15b4edf4 100644 --- a/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/di/ConversationsModule.kt +++ b/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/di/ConversationsModule.kt @@ -1,14 +1,14 @@ package dev.meloda.fast.conversations.di import dev.meloda.fast.conversations.ConversationsViewModelImpl -import dev.meloda.fast.domain.ConversationsUseCaseImpl import dev.meloda.fast.domain.ConversationsUseCase -import org.koin.androidx.viewmodel.dsl.viewModelOf +import dev.meloda.fast.domain.ConversationsUseCaseImpl import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module val conversationsModule = module { - singleOf(::ConversationsUseCaseImpl) bind dev.meloda.fast.domain.ConversationsUseCase::class + singleOf(::ConversationsUseCaseImpl) bind ConversationsUseCase::class viewModelOf(::ConversationsViewModelImpl) } diff --git a/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/presentation/ConversationsScreen.kt b/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/presentation/ConversationsScreen.kt index 841f19c4..a81086c5 100644 --- a/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/presentation/ConversationsScreen.kt +++ b/feature/conversations/src/main/kotlin/dev/meloda/fast/conversations/presentation/ConversationsScreen.kt @@ -310,7 +310,7 @@ fun ConversationsScreen( ) { FloatingActionButton( onClick = { - if (AppSettings.Debug.enableHaptic) { + if (AppSettings.General.enableHaptic) { view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT) } scope.launch { diff --git a/feature/friends/src/main/kotlin/dev/meloda/fast/friends/di/FriendsModule.kt b/feature/friends/src/main/kotlin/dev/meloda/fast/friends/di/FriendsModule.kt index d3e56173..c19b8cd4 100644 --- a/feature/friends/src/main/kotlin/dev/meloda/fast/friends/di/FriendsModule.kt +++ b/feature/friends/src/main/kotlin/dev/meloda/fast/friends/di/FriendsModule.kt @@ -3,13 +3,12 @@ package dev.meloda.fast.friends.di import dev.meloda.fast.domain.FriendsUseCase import dev.meloda.fast.friends.FriendsViewModelImpl import dev.meloda.fast.domain.FriendsUseCaseImpl -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module val friendsModule = module { - singleOf(::FriendsUseCaseImpl) bind dev.meloda.fast.domain.FriendsUseCase::class - + singleOf(::FriendsUseCaseImpl) bind FriendsUseCase::class viewModelOf(::FriendsViewModelImpl) } diff --git a/feature/languagepicker/src/main/kotlin/dev/meloda/fast/languagepicker/di/LanguagePickerModule.kt b/feature/languagepicker/src/main/kotlin/dev/meloda/fast/languagepicker/di/LanguagePickerModule.kt index 669cf33a..1aad5644 100644 --- a/feature/languagepicker/src/main/kotlin/dev/meloda/fast/languagepicker/di/LanguagePickerModule.kt +++ b/feature/languagepicker/src/main/kotlin/dev/meloda/fast/languagepicker/di/LanguagePickerModule.kt @@ -1,7 +1,7 @@ package dev.meloda.fast.languagepicker.di import dev.meloda.fast.languagepicker.LanguagePickerViewModelImpl -import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module val languagePickerModule = module { diff --git a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt index f2004a86..f349cc65 100644 --- a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt +++ b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/MessagesHistoryViewModel.kt @@ -2,6 +2,7 @@ package dev.meloda.fast.messageshistory import android.content.SharedPreferences import android.util.Log +import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.TextFieldValue import androidx.core.content.edit import androidx.lifecycle.SavedStateHandle @@ -10,6 +11,7 @@ import androidx.lifecycle.viewModelScope import com.conena.nanokt.collections.indexOfFirstOrNull import com.conena.nanokt.collections.indexOfOrNull import com.conena.nanokt.text.isEmptyOrBlank +import com.conena.nanokt.text.isNotEmptyOrBlank import dev.meloda.fast.common.extensions.listenValue import dev.meloda.fast.common.extensions.setValue import dev.meloda.fast.common.provider.ResourceProvider @@ -54,7 +56,7 @@ interface MessagesHistoryViewModel { fun onRefresh() fun onAttachmentButtonClicked() fun onMessageInputChanged(newText: TextFieldValue) - fun onEmojiButtonClicked() + fun onEmojiButtonLongClicked() fun onActionButtonClicked() fun onPaginationConditionsMet() @@ -123,8 +125,15 @@ class MessagesHistoryViewModelImpl( screenState.setValue { old -> old.copy(message = newText) } } - override fun onEmojiButtonClicked() { - + override fun onEmojiButtonLongClicked() { + AppSettings.Features.fastText.takeIf { it.isNotEmptyOrBlank() }?.let { text -> + screenState.setValue { old -> + val newText = "${old.message.text}$text" + old.copy( + message = TextFieldValue(text = newText, selection = TextRange(newText.length)) + ) + } + } } override fun onActionButtonClicked() { diff --git a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/di/MessagesHistoryModule.kt b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/di/MessagesHistoryModule.kt index e04ba4d4..deba32e1 100644 --- a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/di/MessagesHistoryModule.kt +++ b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/di/MessagesHistoryModule.kt @@ -1,17 +1,17 @@ package dev.meloda.fast.messageshistory.di import dev.meloda.fast.domain.MessagesUseCase +import dev.meloda.fast.domain.MessagesUseCaseImpl import dev.meloda.fast.messageshistory.MessagesHistoryViewModel import dev.meloda.fast.messageshistory.MessagesHistoryViewModelImpl -import dev.meloda.fast.domain.MessagesUseCaseImpl import dev.meloda.fast.messageshistory.validation.MessagesHistoryValidator -import org.koin.androidx.viewmodel.dsl.viewModelOf import org.koin.core.module.dsl.singleOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module val messagesHistoryModule = module { - singleOf(::MessagesUseCaseImpl) bind dev.meloda.fast.domain.MessagesUseCase::class + singleOf(::MessagesUseCaseImpl) bind MessagesUseCase::class singleOf(::MessagesHistoryValidator) viewModelOf(::MessagesHistoryViewModelImpl) bind MessagesHistoryViewModel::class } diff --git a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/MessagesHistoryScreen.kt b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/MessagesHistoryScreen.kt index c5b8764b..217d9705 100644 --- a/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/MessagesHistoryScreen.kt +++ b/feature/messageshistory/src/main/kotlin/dev/meloda/fast/messageshistory/presentation/MessagesHistoryScreen.kt @@ -37,7 +37,6 @@ import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold @@ -86,6 +85,7 @@ import dev.meloda.fast.messageshistory.model.MessagesHistoryScreenState import dev.meloda.fast.messageshistory.util.firstMessage import dev.meloda.fast.messageshistory.util.indexOfMessageByCmId import dev.meloda.fast.model.BaseError +import dev.meloda.fast.ui.components.IconButton import dev.meloda.fast.ui.theme.LocalThemeConfig import dev.meloda.fast.ui.util.ImmutableList import kotlinx.coroutines.launch @@ -119,7 +119,8 @@ fun MessagesHistoryRoute( onPaginationConditionsMet = viewModel::onPaginationConditionsMet, onMessageInputChanged = viewModel::onMessageInputChanged, onAttachmentButtonClicked = viewModel::onAttachmentButtonClicked, - onActionButtonClicked = viewModel::onActionButtonClicked + onActionButtonClicked = viewModel::onActionButtonClicked, + onEmojiButtonLongClicked = viewModel::onEmojiButtonLongClicked ) } @@ -141,7 +142,8 @@ fun MessagesHistoryScreen( onPaginationConditionsMet: () -> Unit = {}, onMessageInputChanged: (TextFieldValue) -> Unit = {}, onAttachmentButtonClicked: () -> Unit = {}, - onActionButtonClicked: () -> Unit = {} + onActionButtonClicked: () -> Unit = {}, + onEmojiButtonLongClicked: () -> Unit = {} ) { val view = LocalView.current @@ -371,7 +373,7 @@ fun MessagesHistoryScreen( Column(verticalArrangement = Arrangement.Bottom) { IconButton( onClick = { - if (AppSettings.Debug.enableHaptic) { + if (AppSettings.General.enableHaptic) { view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT) } scope.launch { @@ -389,6 +391,12 @@ fun MessagesHistoryScreen( } } }, + onLongClick = { + if (AppSettings.General.enableHaptic) { + view.performHapticFeedback(HapticFeedbackConstantsCompat.LONG_PRESS) + } + onEmojiButtonLongClicked() + }, modifier = Modifier.rotate(rotation.value) ) { Icon( @@ -427,7 +435,7 @@ fun MessagesHistoryScreen( Column(verticalArrangement = Arrangement.Bottom) { IconButton( onClick = { - if (AppSettings.Debug.enableHaptic) { + if (AppSettings.General.enableHaptic) { view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT) } scope.launch { @@ -463,7 +471,7 @@ fun MessagesHistoryScreen( IconButton( onClick = { if (screenState.actionMode == ActionMode.Record) { - if (AppSettings.Debug.enableHaptic) { + if (AppSettings.General.enableHaptic) { view.performHapticFeedback(HapticFeedbackConstantsCompat.REJECT) } scope.launch { diff --git a/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/di/PhotoViewDI.kt b/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/di/PhotoViewDI.kt index 9da0cec5..4bbaca21 100644 --- a/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/di/PhotoViewDI.kt +++ b/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/di/PhotoViewDI.kt @@ -2,7 +2,7 @@ package dev.meloda.fast.photoviewer.di import dev.meloda.fast.photoviewer.PhotoViewViewModel import dev.meloda.fast.photoviewer.PhotoViewViewModelImpl -import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module diff --git a/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/presentation/PhotoViewScreen.kt b/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/presentation/PhotoViewScreen.kt index 11a12915..a756183e 100644 --- a/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/presentation/PhotoViewScreen.kt +++ b/feature/photoviewer/src/main/kotlin/dev/meloda/fast/photoviewer/presentation/PhotoViewScreen.kt @@ -123,7 +123,7 @@ fun TopBar( } }, actions = { -// IconButton( +// IconButton.kt( // onClick = { dropdownMenuShown = true } // ) { // Icon( diff --git a/feature/profile/src/main/kotlin/dev/meloda/fast/profile/di/ProfileModule.kt b/feature/profile/src/main/kotlin/dev/meloda/fast/profile/di/ProfileModule.kt index f4383c12..f4903930 100644 --- a/feature/profile/src/main/kotlin/dev/meloda/fast/profile/di/ProfileModule.kt +++ b/feature/profile/src/main/kotlin/dev/meloda/fast/profile/di/ProfileModule.kt @@ -1,7 +1,7 @@ package dev.meloda.fast.profile.di import dev.meloda.fast.profile.ProfileViewModelImpl -import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module val profileModule = module { diff --git a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/SettingsViewModel.kt b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/SettingsViewModel.kt index c2dde53d..f529652d 100644 --- a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/SettingsViewModel.kt @@ -154,13 +154,6 @@ class SettingsViewModelImpl( userSettings.onUseContactNamesChanged(isUsing) } - SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH -> { - 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) @@ -206,9 +199,9 @@ class SettingsViewModelImpl( userSettings.onShowAlertAfterCrashChanged(show) } - SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND -> { + SettingsKeys.KEY_LONG_POLL_IN_BACKGROUND -> { val inBackground = newValue as? Boolean - ?: SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND + ?: SettingsKeys.DEFAULT_LONG_POLL_IN_BACKGROUND userSettings.onLongPollInBackgroundChanged(inBackground) longPollController.setStateToApply( @@ -221,9 +214,9 @@ class SettingsViewModelImpl( ) } - SettingsKeys.KEY_APPEARANCE_USE_BLUR -> { + SettingsKeys.KEY_USE_BLUR -> { val isUsing = - newValue as? Boolean ?: SettingsKeys.DEFAULT_VALUE_KEY_APPEARANCE_USE_BLUR + newValue as? Boolean ?: SettingsKeys.DEFAULT_USE_BLUR userSettings.onUseBlurChanged(isUsing) } @@ -232,14 +225,14 @@ class SettingsViewModelImpl( userSettings.onShowEmojiButtonChanged(show) } - SettingsKeys.KEY_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES -> { + SettingsKeys.KEY_SHOW_TIME_IN_ACTION_MESSAGES -> { val show = newValue as? Boolean - ?: SettingsKeys.DEFAULT_VALUE_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES + ?: SettingsKeys.DEFAULT_SHOW_TIME_IN_ACTION_MESSAGES userSettings.onShowTimeInActionMessagesChanged(show) } - SettingsKeys.KEY_DEBUG_USE_SYSTEM_FONT -> { - val use = newValue as? Boolean ?: SettingsKeys.DEFAULT_DEBUG_USE_SYSTEM_FONT + SettingsKeys.KEY_USE_SYSTEM_FONT -> { + val use = newValue as? Boolean ?: SettingsKeys.DEFAULT_USE_SYSTEM_FONT userSettings.onUseSystemFontChanged(use) } @@ -283,10 +276,16 @@ class SettingsViewModelImpl( text = UiText.Resource(UiR.string.settings_general_contact_names_summary), defaultValue = SettingsKeys.DEFAULT_VALUE_USE_CONTACT_NAMES ) - val generalEnablePullToRefresh = SettingsItem.Switch( - key = SettingsKeys.KEY_ENABLE_PULL_TO_REFRESH, - defaultValue = SettingsKeys.DEFAULT_VALUE_ENABLE_PULL_TO_REFRESH, - title = UiText.Resource(UiR.string.settings_general_enable_pull_to_refresh_title) + val generalShowEmojiButton = SettingsItem.Switch( + key = SettingsKeys.KEY_SHOW_EMOJI_BUTTON, + title = UiText.Simple("Show emoji button"), + text = UiText.Simple("Show emoji button in chat panel"), + defaultValue = SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON + ) + val generalEnableHaptic = SettingsItem.Switch( + key = SettingsKeys.KEY_ENABLE_HAPTIC, + defaultValue = SettingsKeys.DEFAULT_ENABLE_HAPTIC, + title = UiText.Simple("Enable haptic") ) val appearanceTitle = SettingsItem.Title( @@ -340,7 +339,11 @@ class SettingsViewModelImpl( text = UiText.Resource(UiR.string.settings_dynamic_colors_description), defaultValue = SettingsKeys.DEFAULT_VALUE_USE_DYNAMIC_COLORS ) - + val appearanceUseSystemFont = SettingsItem.Switch( + key = SettingsKeys.KEY_USE_SYSTEM_FONT, + defaultValue = SettingsKeys.DEFAULT_USE_SYSTEM_FONT, + title = UiText.Simple("Use system font") + ) val appearanceLanguage = SettingsItem.TitleText( key = SettingsKeys.KEY_APPEARANCE_LANGUAGE, title = UiText.Resource(UiR.string.settings_application_language), @@ -374,6 +377,28 @@ class SettingsViewModelImpl( text = UiText.Resource(UiR.string.settings_activity_send_online_summary) ) + val experimentalTitle = SettingsItem.Title( + key = "experimental", + title = UiText.Simple("Experimental - VERY unstable") + ) + val experimentalLongPollBackground = SettingsItem.Switch( + key = SettingsKeys.KEY_LONG_POLL_IN_BACKGROUND, + defaultValue = SettingsKeys.DEFAULT_LONG_POLL_IN_BACKGROUND, + title = UiText.Resource(UiR.string.settings_features_long_poll_in_background_title), + text = UiText.Resource(UiR.string.settings_features_long_poll_in_background_summary) + ) + val experimentalUseBlur = SettingsItem.Switch( + key = SettingsKeys.KEY_USE_BLUR, + defaultValue = SettingsKeys.DEFAULT_USE_BLUR, + title = UiText.Simple("Use blur"), + text = UiText.Simple("Adds blur wherever possible\nWorks on android 12 and newer"), + ) + val experimentalShowTimeInActionMessages = SettingsItem.Switch( + key = SettingsKeys.KEY_SHOW_TIME_IN_ACTION_MESSAGES, + defaultValue = SettingsKeys.DEFAULT_SHOW_TIME_IN_ACTION_MESSAGES, + title = UiText.Simple("Show time in action messages") + ) + val debugTitle = SettingsItem.Title( key = "debug", title = UiText.Resource(UiR.string.settings_debug_title) @@ -389,34 +414,6 @@ class SettingsViewModelImpl( title = UiText.Simple("Show alert after crash"), text = UiText.Simple("Shows alert dialog with stacktrace after app crashed\n(it will be not shown if you perform crash manually)") ) - val debugLongPollBackground = SettingsItem.Switch( - key = SettingsKeys.KEY_FEATURES_LONG_POLL_IN_BACKGROUND, - defaultValue = SettingsKeys.DEFAULT_VALUE_FEATURES_LONG_POLL_IN_BACKGROUND, - title = UiText.Resource(UiR.string.settings_features_long_poll_in_background_title), - text = UiText.Resource(UiR.string.settings_features_long_poll_in_background_summary) - ) - val debugUseBlur = SettingsItem.Switch( - 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\nWorks on android 12 and newer"), - ) - val debugShowEmojiButton = SettingsItem.Switch( - key = SettingsKeys.KEY_SHOW_EMOJI_BUTTON, - title = UiText.Simple("Show emoji button"), - text = UiText.Simple("Show emoji button in chat panel"), - defaultValue = SettingsKeys.DEFAULT_VALUE_KEY_SHOW_EMOJI_BUTTON - ) - val debugShowTimeInActionMessages = SettingsItem.Switch( - key = SettingsKeys.KEY_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES, - defaultValue = SettingsKeys.DEFAULT_VALUE_APPEARANCE_SHOW_TIME_IN_ACTION_MESSAGES, - title = UiText.Simple("Show time in action messages") - ) - val debugEnableHaptic = SettingsItem.Switch( - key = SettingsKeys.KEY_DEBUG_ENABLE_HAPTIC, - defaultValue = SettingsKeys.DEFAULT_DEBUG_ENABLE_HAPTIC, - title = UiText.Simple("Enable haptic") - ) val logLevelValues = listOf( LogLevel.NONE to UiText.Simple("None"), @@ -440,12 +437,6 @@ class SettingsViewModelImpl( } } - val debugUseSystemFont = SettingsItem.Switch( - key = SettingsKeys.KEY_DEBUG_USE_SYSTEM_FONT, - defaultValue = SettingsKeys.DEFAULT_DEBUG_USE_SYSTEM_FONT, - title = UiText.Simple("Use system font") - ) - val debugHideDebugList = SettingsItem.TitleText( key = SettingsKeys.KEY_DEBUG_HIDE_DEBUG_LIST, title = UiText.Simple("Hide debug list") @@ -458,7 +449,8 @@ class SettingsViewModelImpl( val generalList = listOf( generalTitle, generalUseContactNames, - generalEnablePullToRefresh + generalShowEmojiButton, + generalEnableHaptic ) val appearanceList = listOf( appearanceTitle, @@ -466,6 +458,7 @@ class SettingsViewModelImpl( appearanceDarkTheme, appearanceUseAmoledDarkTheme, appearanceUseDynamicColors, + appearanceUseSystemFont, appearanceLanguage ) val featuresList = listOf( @@ -476,18 +469,18 @@ class SettingsViewModelImpl( activityTitle, visibilitySendOnlineStatus, ) + val experimentalList = listOf( + experimentalTitle, + experimentalLongPollBackground, + experimentalShowTimeInActionMessages, + experimentalUseBlur + ) val debugList = mutableListOf>() listOf( debugTitle, debugPerformCrash, debugShowCrashAlert, - debugLongPollBackground, - debugUseBlur, - debugShowEmojiButton, - debugShowTimeInActionMessages, - debugEnableHaptic, debugNetworkLogLevel, - debugUseSystemFont ).forEach(debugList::add) debugList += debugHideDebugList @@ -499,6 +492,7 @@ class SettingsViewModelImpl( appearanceList, featuresList, visibilityList, + experimentalList, debugList, ).forEach(settingsList::addAll) diff --git a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/di/SettingsModule.kt b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/di/SettingsModule.kt index 1cfb19d0..2e104d11 100644 --- a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/di/SettingsModule.kt +++ b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/di/SettingsModule.kt @@ -2,7 +2,7 @@ package dev.meloda.fast.settings.di import dev.meloda.fast.settings.SettingsViewModel import dev.meloda.fast.settings.SettingsViewModelImpl -import org.koin.androidx.viewmodel.dsl.viewModelOf +import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.bind import org.koin.dsl.module diff --git a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/presentation/SettingsScreen.kt b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/presentation/SettingsScreen.kt index 80486577..c177ad53 100644 --- a/feature/settings/src/main/kotlin/dev/meloda/fast/settings/presentation/SettingsScreen.kt +++ b/feature/settings/src/main/kotlin/dev/meloda/fast/settings/presentation/SettingsScreen.kt @@ -113,7 +113,7 @@ fun SettingsScreen( LaunchedEffect(hapticType) { if (hapticType != null) { - if (AppSettings.Debug.enableHaptic) { + if (AppSettings.General.enableHaptic) { view.performHapticFeedback(hapticType.getHaptic()) } onHapticPerformed()