diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 8b4f3078..a3c02660 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -186,6 +186,12 @@ Maybe this can be labeled better? Let me know. It should be something that can d Unit groups Units list sorting Change units order + + + %1$s has been updated + + + See what\'s new in version %1$s Version name Vibrations Haptic feedback when clicking keyboard buttons diff --git a/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/BackupManagerTest.kt b/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/BackupManagerTest.kt index 10e3d67d..d74e2d9f 100644 --- a/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/BackupManagerTest.kt +++ b/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/BackupManagerTest.kt @@ -75,6 +75,7 @@ class BackupManagerTest { it[PrefsKeys.STARTING_SCREEN] = fakeUserData.startingScreen it[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] = fakeUserData.enableToolsExperiment it[PrefsKeys.SYSTEM_FONT] = fakeUserData.systemFont + it[PrefsKeys.LAST_READ_CHANGELOG] = fakeUserData.lastReadChangelog it[PrefsKeys.ENABLE_VIBRATIONS] = fakeUserData.enableVibrations it[PrefsKeys.MIDDLE_ZERO] = fakeUserData.middleZero it[PrefsKeys.AC_BUTTON] = fakeUserData.acButton diff --git a/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/FakeUserPreferencesRepository.kt b/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/FakeUserPreferencesRepository.kt index cec8d9d2..84f22c96 100644 --- a/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/FakeUserPreferencesRepository.kt +++ b/data/backup/src/androidTest/java/com/sadellie/unitto/data/backup/FakeUserPreferencesRepository.kt @@ -27,6 +27,7 @@ internal val fakeUserData = UserData( startingScreen = "calculator_route", enableToolsExperiment = false, systemFont = false, + lastReadChangelog = "33", enableVibrations = false, middleZero = false, acButton = false, diff --git a/data/backup/src/main/java/com/sadellie/unitto/data/backup/BackupManager.kt b/data/backup/src/main/java/com/sadellie/unitto/data/backup/BackupManager.kt index f7740480..94f08b19 100644 --- a/data/backup/src/main/java/com/sadellie/unitto/data/backup/BackupManager.kt +++ b/data/backup/src/main/java/com/sadellie/unitto/data/backup/BackupManager.kt @@ -35,6 +35,7 @@ import com.sadellie.unitto.data.userprefs.getEnableAmoledTheme import com.sadellie.unitto.data.userprefs.getEnableDynamicTheme import com.sadellie.unitto.data.userprefs.getEnableToolsExperiment import com.sadellie.unitto.data.userprefs.getEnableVibrations +import com.sadellie.unitto.data.userprefs.getLastReadChangelog import com.sadellie.unitto.data.userprefs.getLatestLeftSide import com.sadellie.unitto.data.userprefs.getLatestRightSide import com.sadellie.unitto.data.userprefs.getMiddleZero @@ -128,6 +129,7 @@ class BackupManager @Inject constructor( startingScreen = data.getStartingScreen(), enableToolsExperiment = data.getEnableToolsExperiment(), systemFont = data.getSystemFont(), + lastReadChangelog = data.getLastReadChangelog(), enableVibrations = data.getEnableVibrations(), middleZero = data.getMiddleZero(), acButton = data.getAcButton(), @@ -160,6 +162,7 @@ class BackupManager @Inject constructor( it[PrefsKeys.STARTING_SCREEN] = userData.startingScreen it[PrefsKeys.ENABLE_TOOLS_EXPERIMENT] = userData.enableToolsExperiment it[PrefsKeys.SYSTEM_FONT] = userData.systemFont + it[PrefsKeys.LAST_READ_CHANGELOG] = userData.lastReadChangelog it[PrefsKeys.ENABLE_VIBRATIONS] = userData.enableVibrations it[PrefsKeys.MIDDLE_ZERO] = userData.middleZero it[PrefsKeys.AC_BUTTON] = userData.acButton diff --git a/data/backup/src/main/java/com/sadellie/unitto/data/backup/UserData.kt b/data/backup/src/main/java/com/sadellie/unitto/data/backup/UserData.kt index fc0ab364..abc7d358 100644 --- a/data/backup/src/main/java/com/sadellie/unitto/data/backup/UserData.kt +++ b/data/backup/src/main/java/com/sadellie/unitto/data/backup/UserData.kt @@ -35,6 +35,7 @@ internal data class UserData( @Json(name = "startingScreen") val startingScreen: String, @Json(name = "enableToolsExperiment") val enableToolsExperiment: Boolean, @Json(name = "systemFont") val systemFont: Boolean, + @Json(name = "lastReadChangelog") val lastReadChangelog: String, @Json(name = "enableVibrations") val enableVibrations: Boolean, @Json(name = "middleZero") val middleZero: Boolean, @Json(name = "acButton") val acButton: Boolean, diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt index 9a7a9115..afb993bd 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/repository/UserPreferencesRepository.kt @@ -69,6 +69,8 @@ interface UserPreferencesRepository { suspend fun updateShownUnitGroups(shownUnitGroups: List) + suspend fun updateLastReadChangelog(value: String) + suspend fun updateVibrations(enabled: Boolean) suspend fun updateMiddleZero(enabled: Boolean) diff --git a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/GeneralPreferences.kt b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/GeneralPreferences.kt index dc62eebd..350b0787 100644 --- a/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/GeneralPreferences.kt +++ b/data/model/src/main/java/com/sadellie/unitto/data/model/userprefs/GeneralPreferences.kt @@ -19,5 +19,6 @@ package com.sadellie.unitto.data.model.userprefs interface GeneralPreferences { + val lastReadChangelog: String val enableVibrations: Boolean } diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt index 6418f25d..b5e1c751 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceExt.kt @@ -59,6 +59,10 @@ fun Preferences.getSystemFont(): Boolean { return this[PrefsKeys.SYSTEM_FONT] ?: false } +fun Preferences.getLastReadChangelog(): String { + return this[PrefsKeys.LAST_READ_CHANGELOG] ?: "" +} + fun Preferences.getEnableVibrations(): Boolean { return this[PrefsKeys.ENABLE_VIBRATIONS] ?: true } diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt index b0245ecb..6d61e053 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PreferenceModels.kt @@ -46,6 +46,7 @@ data class AppPreferencesImpl( ) : AppPreferences data class GeneralPreferencesImpl( + override val lastReadChangelog: String, override val enableVibrations: Boolean, ) : GeneralPreferences diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt index 7f081f00..b319135f 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/PrefsKeys.kt @@ -33,6 +33,7 @@ object PrefsKeys { val STARTING_SCREEN = stringPreferencesKey("STARTING_SCREEN_PREF_KEY") val ENABLE_TOOLS_EXPERIMENT = booleanPreferencesKey("ENABLE_TOOLS_EXPERIMENT_PREF_KEY") val SYSTEM_FONT = booleanPreferencesKey("SYSTEM_FONT_PREF_KEY") + val LAST_READ_CHANGELOG = stringPreferencesKey("LAST_READ_CHANGELOG_PREF_KEY") val ENABLE_VIBRATIONS = booleanPreferencesKey("ENABLE_VIBRATIONS_PREF_KEY") val MIDDLE_ZERO = booleanPreferencesKey("MIDDLE_ZERO_PREF_KEY") val AC_BUTTON = booleanPreferencesKey("AC_BUTTON_PREF_KEY") diff --git a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt index 3be7cd6d..467224c1 100644 --- a/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt +++ b/data/userprefs/src/main/java/com/sadellie/unitto/data/userprefs/UserPreferences.kt @@ -67,6 +67,7 @@ class UserPreferencesRepositoryImpl @Inject constructor( override val generalPrefs: Flow = data .map { preferences -> GeneralPreferencesImpl( + lastReadChangelog = preferences.getLastReadChangelog(), enableVibrations = preferences.getEnableVibrations(), ) } @@ -226,6 +227,12 @@ class UserPreferencesRepositoryImpl @Inject constructor( } } + override suspend fun updateLastReadChangelog(value: String) { + dataStore.edit { preferences -> + preferences[PrefsKeys.LAST_READ_CHANGELOG] = value + } + } + override suspend fun updateVibrations(enabled: Boolean) { dataStore.edit { preferences -> preferences[PrefsKeys.ENABLE_VIBRATIONS] = enabled diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt index 1aab90cb..917d4ca6 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsScreen.kt @@ -34,6 +34,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -48,6 +49,7 @@ import androidx.compose.material.icons.filled.RateReview import androidx.compose.material.icons.filled.SwapHoriz import androidx.compose.material.icons.filled.Vibration import androidx.compose.material.icons.filled._123 +import androidx.compose.material.icons.outlined.NewReleases import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem @@ -58,15 +60,16 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.sadellie.unitto.core.base.BuildConfig @@ -78,12 +81,15 @@ import com.sadellie.unitto.core.ui.common.UnittoListItem import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar import com.sadellie.unitto.core.ui.openLink import com.sadellie.unitto.core.ui.showToast +import com.sadellie.unitto.feature.settings.components.AnnoyingBox import com.sadellie.unitto.feature.settings.navigation.aboutRoute import com.sadellie.unitto.feature.settings.navigation.calculatorSettingsRoute import com.sadellie.unitto.feature.settings.navigation.converterSettingsRoute import com.sadellie.unitto.feature.settings.navigation.displayRoute import com.sadellie.unitto.feature.settings.navigation.formattingRoute import com.sadellie.unitto.feature.settings.navigation.startingScreenRoute +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch @Composable internal fun SettingsRoute( @@ -116,9 +122,10 @@ internal fun SettingsRoute( uiState = uiState, navigateUp = navigateUp, navControllerAction = navControllerAction, + updateLastReadChangelog = viewModel::updateLastReadChangelog, updateVibrations = viewModel::updateVibrations, clearCache = viewModel::clearCache, - backup = viewModel::backup, + backup = viewModel::backup, restore = viewModel::restore ) } @@ -129,6 +136,7 @@ private fun SettingsScreen( uiState: SettingsUIState.Ready, navigateUp: () -> Unit, navControllerAction: (String) -> Unit, + updateLastReadChangelog: (String) -> Unit, updateVibrations: (Boolean) -> Unit, clearCache: () -> Unit, backup: () -> Unit, @@ -173,6 +181,26 @@ private fun SettingsScreen( .verticalScroll(rememberScrollState()) .padding(padding) ) { + AnimatedVisibility( + visible = uiState.showUpdateChangelog, + enter = expandVertically() + fadeIn(), + exit = shrinkVertically() + fadeOut(), + ) { + val title = stringResource(R.string.settings_updated, stringResource(R.string.app_name)) + AnnoyingBox( + modifier = Modifier + .padding(16.dp, 8.dp) + .fillMaxWidth(), + imageVector = Icons.Outlined.NewReleases, + imageVectorContentDescription = title, + title = title, + support = stringResource(R.string.settings_updated_support, BuildConfig.VERSION_NAME), + ) { + openLink(mContext, "https://github.com/sadellie/unitto/releases/latest") + updateLastReadChangelog(BuildConfig.VERSION_CODE) + } + } + UnittoListItem( icon = Icons.Default.Palette, headlineText = stringResource(R.string.settings_display), @@ -277,35 +305,40 @@ private const val backupMimeType = "application/octet-stream" @Preview @Composable private fun PreviewSettingsScreen() { - var cacheSize by remember { mutableFloatStateOf(0.9f) } + val corScope = rememberCoroutineScope() + var uiState by remember { + mutableStateOf( + SettingsUIState.Ready( + enableVibrations = false, + cacheSize = 2, + backupInProgress = false, + showUpdateChangelog = true + ) + ) + } SettingsScreen( uiState = SettingsUIState.Ready( enableVibrations = false, cacheSize = 2, - backupInProgress = false + backupInProgress = false, + showUpdateChangelog = true ), navigateUp = {}, navControllerAction = {}, + updateLastReadChangelog = { + uiState = uiState.copy(showUpdateChangelog = false) + }, updateVibrations = {}, - clearCache = { cacheSize = 0f }, - backup = {} - ) -} - -@Preview -@Composable -private fun PreviewBackingUpScreen() { - SettingsScreen( - uiState = SettingsUIState.Ready( - enableVibrations = false, - cacheSize = 2, - backupInProgress = true - ), - navigateUp = {}, - navControllerAction = {}, - updateVibrations = {}, - clearCache = {}, - backup = {} + clearCache = { + uiState = uiState.copy(cacheSize = 0) + }, + backup = { + corScope.launch { + uiState = uiState.copy(backupInProgress = true) + delay(2000) + uiState = uiState.copy(backupInProgress = false) + } + } ) } diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsUIState.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsUIState.kt index 001c9ca9..55420a27 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsUIState.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsUIState.kt @@ -25,5 +25,6 @@ internal sealed class SettingsUIState { val enableVibrations: Boolean, val cacheSize: Int, val backupInProgress: Boolean, + val showUpdateChangelog: Boolean, ) : SettingsUIState() } diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt index 1aabb9e6..955ed3b8 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/SettingsViewModel.kt @@ -22,6 +22,7 @@ import android.net.Uri import android.util.Log import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import com.sadellie.unitto.core.base.BuildConfig import com.sadellie.unitto.data.backup.BackupManager import com.sadellie.unitto.data.common.stateIn import com.sadellie.unitto.data.database.CurrencyRatesDao @@ -57,11 +58,11 @@ internal class SettingsViewModel @Inject constructor( currencyRatesDao.size(), _backupInProgress, ) { prefs, cacheSize, backupInProgress -> - SettingsUIState.Ready( enableVibrations = prefs.enableVibrations, cacheSize = cacheSize, - backupInProgress = backupInProgress + backupInProgress = backupInProgress, + showUpdateChangelog = prefs.lastReadChangelog != BuildConfig.VERSION_CODE ) } .stateIn(viewModelScope, SettingsUIState.Loading) @@ -97,6 +98,13 @@ internal class SettingsViewModel @Inject constructor( } } + /** + * @see UserPreferencesRepository.updateLastReadChangelog + */ + fun updateLastReadChangelog(value: String) = viewModelScope.launch { + userPrefsRepository.updateLastReadChangelog(value) + } + /** * @see UserPreferencesRepository.updateVibrations */ diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AnnoyingBox.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AnnoyingBox.kt new file mode 100644 index 00000000..01d20ab7 --- /dev/null +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/components/AnnoyingBox.kt @@ -0,0 +1,99 @@ +/* + * Unitto is a unit converter for Android + * Copyright (c) 2024 Elshan Agaev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.sadellie.unitto.feature.settings.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Accessibility +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sadellie.unitto.core.ui.common.squashable + +@Composable +internal fun AnnoyingBox( + modifier: Modifier, + imageVector: ImageVector, + imageVectorContentDescription: String, + title: String, + support: String, + onClick: () -> Unit, +) { + Row( + modifier = modifier + .squashable( + onClick = onClick, + interactionSource = remember { MutableInteractionSource() }, + cornerRadiusRange = 15..25 + ) + .background(MaterialTheme.colorScheme.secondaryContainer) + .padding(16.dp, 8.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon( + modifier = Modifier.size(24.dp), + imageVector = imageVector, + contentDescription = imageVectorContentDescription, + tint = MaterialTheme.colorScheme.onSurfaceVariant + ) + Column( + modifier = Modifier + .weight(1f) + .padding(vertical = 8.dp) + ) { + Text( + text = title, + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSecondaryContainer, + ) + Text( + text = support, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.onSecondaryContainer, + ) + } + } +} + +@Preview +@Composable +fun PreviewAnnoyingBox() { + AnnoyingBox( + modifier = Modifier.fillMaxWidth(), + imageVector = Icons.Default.Accessibility, + imageVectorContentDescription = "", + title = "Title text", + support = "Lorem ipsum or something" + ) {} +} diff --git a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/language/LanguageScreen.kt b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/language/LanguageScreen.kt index d6fd57a7..6856895b 100644 --- a/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/language/LanguageScreen.kt +++ b/feature/settings/src/main/java/com/sadellie/unitto/feature/settings/language/LanguageScreen.kt @@ -19,25 +19,16 @@ package com.sadellie.unitto.feature.settings.language import androidx.appcompat.app.AppCompatDelegate -import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Translate -import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.RadioButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -48,8 +39,8 @@ import com.sadellie.unitto.core.base.R import com.sadellie.unitto.core.ui.common.NavigateUpButton import com.sadellie.unitto.core.ui.common.UnittoListItem import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar -import com.sadellie.unitto.core.ui.common.squashable import com.sadellie.unitto.core.ui.openLink +import com.sadellie.unitto.feature.settings.components.AnnoyingBox @Composable internal fun LanguageRoute( @@ -83,43 +74,14 @@ private fun LanguageScreen( ) { padding -> LazyColumn(contentPadding = padding) { item("translate") { - Box(Modifier.padding(16.dp, 8.dp)) { - Row( - modifier = Modifier - .squashable( - onClick = { - openLink(mContext, "https://poeditor.com/join/project/T4zjmoq8dx") - }, - interactionSource = remember { MutableInteractionSource() }, - cornerRadiusRange = 15..50 - ) - .background(MaterialTheme.colorScheme.secondaryContainer) - .padding(16.dp, 4.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - verticalAlignment = Alignment.CenterVertically - ) { - Icon( - imageVector = Icons.Default.Translate, - contentDescription = stringResource(R.string.settings_translate_app), - modifier = Modifier.size(24.dp), - tint = MaterialTheme.colorScheme.onSurfaceVariant - ) - Column( - Modifier - .weight(1f) - .padding(vertical = 8.dp)) { - Text( - text = stringResource(R.string.settings_translate_app), - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSecondaryContainer, - ) - Text( - text = stringResource(R.string.settings_translate_app_support), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.onSecondaryContainer, - ) - } - } + AnnoyingBox( + modifier = Modifier.padding(16.dp, 8.dp).fillMaxWidth(), + imageVector = Icons.Default.Translate, + imageVectorContentDescription = stringResource(R.string.settings_translate_app), + title = stringResource(R.string.settings_translate_app), + support = stringResource(R.string.settings_translate_app_support) + ) { + openLink(mContext, "https://poeditor.com/join/project/T4zjmoq8dx") } }