diff --git a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt index adfd8136..6a4eeeab 100644 --- a/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt +++ b/app/src/main/java/com/sadellie/unitto/UnittoNavigation.kt @@ -19,13 +19,16 @@ package com.sadellie.unitto import androidx.compose.runtime.Composable +import androidx.navigation.NavController import androidx.navigation.NavHostController +import androidx.navigation.NavOptions import androidx.navigation.compose.NavHost import com.sadellie.unitto.feature.calculator.navigation.calculatorScreen import com.sadellie.unitto.feature.calculator.navigation.navigateToCalculator import com.sadellie.unitto.feature.converter.ConverterViewModel import com.sadellie.unitto.feature.converter.navigation.converterRoute import com.sadellie.unitto.feature.converter.navigation.converterScreen +import com.sadellie.unitto.feature.converter.navigation.navigateToConverter import com.sadellie.unitto.feature.epoch.navigation.epochScreen import com.sadellie.unitto.feature.epoch.navigation.navigateToEpoch import com.sadellie.unitto.feature.settings.SettingsViewModel @@ -57,7 +60,7 @@ fun UnittoNavigation( navigateToLeftScreen = navController::navigateToLeftSide, navigateToRightScreen = navController::navigateToRightSide, navigateToSettings = navController::navigateToSettings, - navigateToTools = navController::navigateToTools, + navigateToMenu = navController::navigateToTools, viewModel = converterViewModel ) @@ -83,14 +86,16 @@ fun UnittoNavigation( toolsScreen( navigateUpAction = navController::navigateUp, - navigateToCalculator = navController::navigateToCalculator, - navigateToEpoch = navController::navigateToEpoch + navigateToConverter = { navController.navigateToConverter(navController.clearStack) }, + navigateToCalculator = { navController.navigateToCalculator(navController.clearStack) }, + navigateToEpoch = { navController.navigateToEpoch(navController.clearStack) } ) - calculatorScreen(navigateUpAction = navController::navigateUp) + calculatorScreen(navigateToMenu = navController::navigateToTools) - epochScreen( - navigateUpAction = navController::navigateUp - ) + epochScreen(navigateToMenu = navController::navigateToTools) } } + +val NavController.clearStack: NavOptions + get() = NavOptions.Builder().setPopUpTo(this.graph.id, false).build() \ No newline at end of file diff --git a/core/base/src/main/res/values/strings.xml b/core/base/src/main/res/values/strings.xml index 9f727888..3a4da175 100644 --- a/core/base/src/main/res/values/strings.xml +++ b/core/base/src/main/res/values/strings.xml @@ -1016,9 +1016,12 @@ Additional + Unit converter + Convert from one unit to another Epoch converter Convert Unix timestamp Experimental features! + Soon This screen is part of an experiment. It may change in the future. Click to read more! diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt index 909a5ad1..fe4e5227 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/CalculatorScreen.kt @@ -75,14 +75,14 @@ import kotlin.math.roundToInt @Composable internal fun CalculatorRoute( - navigateUpAction: () -> Unit, + navigateToMenu: () -> Unit, viewModel: CalculatorViewModel = hiltViewModel() ) { val uiState = viewModel.uiState.collectAsStateWithLifecycle() CalculatorScreen( uiState = uiState.value, - navigateUpAction = navigateUpAction, + navigateToMenu = navigateToMenu, addSymbol = viewModel::addSymbol, clearSymbols = viewModel::clearSymbols, deleteSymbol = viewModel::deleteSymbol, @@ -96,7 +96,7 @@ internal fun CalculatorRoute( @Composable private fun CalculatorScreen( uiState: CalculatorUIState, - navigateUpAction: () -> Unit, + navigateToMenu: () -> Unit, addSymbol: (String) -> Unit, clearSymbols: () -> Unit, deleteSymbol: () -> Unit, @@ -115,7 +115,7 @@ private fun CalculatorScreen( UnittoScreenWithTopBar( title = { Text(stringResource(R.string.calculator)) }, - navigationIcon = { MenuButton { navigateUpAction() } }, + navigationIcon = { MenuButton { navigateToMenu() } }, colors = TopAppBarDefaults.topAppBarColors(MaterialTheme.colorScheme.surfaceVariant), actions = { AnimatedVisibility( @@ -287,7 +287,7 @@ private fun PreviewCalculatorScreen() { output = "12345", history = historyItems ), - navigateUpAction = {}, + navigateToMenu = {}, addSymbol = {}, clearSymbols = {}, deleteSymbol = {}, diff --git a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt index 763f68c5..21f984bf 100644 --- a/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt +++ b/feature/calculator/src/main/java/com/sadellie/unitto/feature/calculator/navigation/CalculatorNavigation.kt @@ -20,24 +20,25 @@ package com.sadellie.unitto.feature.calculator.navigation import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.navDeepLink import com.sadellie.unitto.feature.calculator.CalculatorRoute private const val calculatorRoute = "calculator_route" -fun NavController.navigateToCalculator() { - navigate(calculatorRoute) +fun NavController.navigateToCalculator(navOptions: NavOptions) { + navigate(calculatorRoute, navOptions) } fun NavGraphBuilder.calculatorScreen( - navigateUpAction: () -> Unit + navigateToMenu: () -> Unit ) { composable( route = calculatorRoute, deepLinks = listOf( navDeepLink { uriPattern = "app://com.sadellie.unitto/$calculatorRoute" } )) { - CalculatorRoute(navigateUpAction = navigateUpAction) + CalculatorRoute(navigateToMenu = navigateToMenu) } } diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt index f4c35ee3..0bcc38cc 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterScreen.kt @@ -18,39 +18,30 @@ package com.sadellie.unitto.feature.converter -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.MoreVert -import androidx.compose.material.icons.outlined.Science -import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Badge -import androidx.compose.material3.BadgedBox import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import androidx.compose.ui.semantics.Role 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.ui.R import com.sadellie.unitto.core.ui.common.AnimatedTopBarText -import com.sadellie.unitto.feature.converter.components.Keyboard +import com.sadellie.unitto.core.ui.common.MenuButton import com.sadellie.unitto.core.ui.common.PortraitLandscape import com.sadellie.unitto.core.ui.common.UnittoScreenWithTopBar +import com.sadellie.unitto.feature.converter.components.Keyboard import com.sadellie.unitto.feature.converter.components.TopScreenPart import kotlinx.coroutines.delay @@ -59,7 +50,7 @@ internal fun ConverterRoute( viewModel: ConverterViewModel = hiltViewModel(), navigateToLeftScreen: (String) -> Unit, navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit, - navigateToTools: () -> Unit, + navigateToMenu: () -> Unit, navigateToSettings: () -> Unit ) { val uiState = viewModel.uiStateFlow.collectAsStateWithLifecycle() @@ -69,7 +60,7 @@ internal fun ConverterRoute( navigateToLeftScreen = navigateToLeftScreen, navigateToRightScreen = navigateToRightScreen, navigateToSettings = navigateToSettings, - navigateToTools = navigateToTools, + navigateToMenu = navigateToMenu, swapMeasurements = viewModel::swapUnits, processInput = viewModel::processInput, deleteDigit = viewModel::deleteDigit, @@ -84,7 +75,7 @@ private fun ConverterScreen( navigateToLeftScreen: (String) -> Unit, navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit, navigateToSettings: () -> Unit, - navigateToTools: () -> Unit, + navigateToMenu: () -> Unit, swapMeasurements: () -> Unit, processInput: (String) -> Unit, deleteDigit: () -> Unit, @@ -95,27 +86,7 @@ private fun ConverterScreen( UnittoScreenWithTopBar( title = { AnimatedTopBarText(launched) }, - navigationIcon = { - BadgedBox( - modifier = Modifier - .padding(horizontal = 16.dp) - .clickable( - onClick = navigateToTools, - interactionSource = remember { MutableInteractionSource() }, - indication = rememberRipple(false), - role = Role.Button - ), - badge = { - Badge { Text("1") } - }, - content = { - Icon( - Icons.Outlined.Science, - contentDescription = stringResource(R.string.tools_screen) - ) - } - ) - }, + navigationIcon = { MenuButton { navigateToMenu() } }, actions = { IconButton(onClick = navigateToSettings) { Icon( @@ -180,7 +151,7 @@ private fun PreviewConverterScreen() { navigateToLeftScreen = {}, navigateToRightScreen = {_, _, _ -> }, navigateToSettings = {}, - navigateToTools = {}, + navigateToMenu = {}, swapMeasurements = {}, processInput = {}, deleteDigit = {}, diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt index 01db9187..185f7752 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterUIState.kt @@ -34,7 +34,6 @@ import com.sadellie.unitto.data.model.AbstractUnit * @property unitTo Unit on the right. * @property mode * @property formatTime If true will format output when converting time. - * @property showTools If true will show tools button in TopBar. * @property allowVibration When true will vibrate on button clicks. */ data class ConverterUIState( @@ -47,7 +46,6 @@ data class ConverterUIState( val unitTo: AbstractUnit? = null, val mode: ConverterMode = ConverterMode.DEFAULT, val formatTime: Boolean = true, - val showTools: Boolean = false, val allowVibration: Boolean = false ) diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt index fb7df6a7..4336cd8b 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/ConverterViewModel.kt @@ -56,6 +56,7 @@ import com.sadellie.unitto.data.units.MyUnitIDS import com.sadellie.unitto.data.units.combine import com.sadellie.unitto.data.units.remote.CurrencyApi import com.sadellie.unitto.data.units.remote.CurrencyUnitResponse +import com.sadellie.unitto.data.userprefs.UserPreferences import com.sadellie.unitto.data.userprefs.UserPreferencesRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -86,7 +87,7 @@ class ConverterViewModel @Inject constructor( private val _userPrefs = userPrefsRepository.userPreferencesFlow.stateIn( viewModelScope, SharingStarted.WhileSubscribed(5000), - com.sadellie.unitto.data.userprefs.UserPreferences() + UserPreferences() ) /** @@ -159,7 +160,6 @@ class ConverterViewModel @Inject constructor( */ mode = if (_unitFrom.value is NumberBaseUnit) ConverterMode.BASE else ConverterMode.DEFAULT, formatTime = formatTime, - showTools = prefs.enableToolsExperiment, allowVibration = prefs.enableVibrations ) } diff --git a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt index 0ebe7ebf..866e01ba 100644 --- a/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt +++ b/feature/converter/src/main/java/com/sadellie/unitto/feature/converter/navigation/ConverterNavigation.kt @@ -18,18 +18,24 @@ package com.sadellie.unitto.feature.converter.navigation +import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions import androidx.navigation.compose.composable import com.sadellie.unitto.feature.converter.ConverterRoute import com.sadellie.unitto.feature.converter.ConverterViewModel const val converterRoute = "converter_route" +fun NavController.navigateToConverter(navOptions: NavOptions) { + navigate(converterRoute, navOptions) +} + fun NavGraphBuilder.converterScreen( navigateToLeftScreen: (String) -> Unit, navigateToRightScreen: (unitFrom: String, unitTo: String, input: String) -> Unit, navigateToSettings: () -> Unit, - navigateToTools: () -> Unit, + navigateToMenu: () -> Unit, viewModel: ConverterViewModel ) { composable(converterRoute) { @@ -38,7 +44,7 @@ fun NavGraphBuilder.converterScreen( navigateToLeftScreen = navigateToLeftScreen, navigateToRightScreen = navigateToRightScreen, navigateToSettings = navigateToSettings, - navigateToTools = navigateToTools + navigateToMenu = navigateToMenu ) } } diff --git a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/EpochScreen.kt b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/EpochScreen.kt index aa4e3b31..0c1b0286 100644 --- a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/EpochScreen.kt +++ b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/EpochScreen.kt @@ -35,12 +35,12 @@ import com.sadellie.unitto.feature.epoch.component.TopPart @Composable internal fun EpochRoute( - navigateUpAction: () -> Unit, + navigateToMenu: () -> Unit, viewModel: EpochViewModel = hiltViewModel() ) { val uiState = viewModel.uiState.collectAsStateWithLifecycle() EpochScreen( - navigateUpAction = navigateUpAction, + navigateToMenu = navigateToMenu, uiState = uiState.value, addSymbol = viewModel::addSymbol, deleteSymbol = viewModel::deleteSymbol, @@ -52,7 +52,7 @@ internal fun EpochRoute( @Composable private fun EpochScreen( - navigateUpAction: () -> Unit, + navigateToMenu: () -> Unit, uiState: EpochUIState, addSymbol: (String) -> Unit, deleteSymbol: () -> Unit, @@ -62,7 +62,7 @@ private fun EpochScreen( ) { UnittoScreenWithTopBar( title = { Text(stringResource(R.string.epoch_converter)) }, - navigationIcon = { MenuButton { navigateUpAction() } } + navigationIcon = { MenuButton { navigateToMenu() } } ) { padding -> PortraitLandscape( modifier = Modifier.padding(padding), diff --git a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt index c8409a63..70a12d7d 100644 --- a/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt +++ b/feature/epoch/src/main/java/com/sadellie/unitto/feature/epoch/navigation/EpochNavigation.kt @@ -18,42 +18,21 @@ package com.sadellie.unitto.feature.epoch.navigation -import android.content.Intent -import android.net.Uri -import androidx.core.content.pm.ShortcutInfoCompat -import androidx.core.content.pm.ShortcutManagerCompat -import androidx.core.graphics.drawable.IconCompat import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.navDeepLink import com.sadellie.unitto.feature.epoch.EpochRoute -import com.sadellie.unitto.feature.epoch.R private const val epochRoute = "epoch_route" -fun NavController.navigateToEpoch() { - val shortcut = ShortcutInfoCompat - .Builder(context, epochRoute) - .setShortLabel(context.getString(R.string.epoch_converter)) - .setLongLabel(context.getString(R.string.epoch_converter)) - .setIcon(IconCompat.createWithResource(context, R.drawable.ic_shortcut_epoch)) - .setIntent( - Intent( - Intent.ACTION_VIEW, - Uri.parse("app://com.sadellie.unitto/$epochRoute"), - context, - context.javaClass - ) - ) - .build() - ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) - - navigate(epochRoute) +fun NavController.navigateToEpoch(navOptions: NavOptions) { + navigate(epochRoute, navOptions) } fun NavGraphBuilder.epochScreen( - navigateUpAction: () -> Unit + navigateToMenu: () -> Unit ) { composable( route = epochRoute, @@ -61,8 +40,6 @@ fun NavGraphBuilder.epochScreen( navDeepLink { uriPattern = "app://com.sadellie.unitto/$epochRoute" } ) ) { - EpochRoute( - navigateUpAction = navigateUpAction - ) + EpochRoute(navigateToMenu = navigateToMenu) } } diff --git a/feature/epoch/src/main/res/drawable/ic_shortcut_epoch.xml b/feature/epoch/src/main/res/drawable/ic_shortcut_epoch.xml deleted file mode 100644 index 6b8e9b46..00000000 --- a/feature/epoch/src/main/res/drawable/ic_shortcut_epoch.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - diff --git a/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/ToolsScreen.kt b/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/ToolsScreen.kt index d868feed..cdab3e9e 100644 --- a/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/ToolsScreen.kt +++ b/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/ToolsScreen.kt @@ -1,13 +1,17 @@ package com.sadellie.unitto.feature.tools import androidx.compose.foundation.clickable +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.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Calculate import androidx.compose.material.icons.filled.Schedule +import androidx.compose.material.icons.filled.SwapHoriz +import androidx.compose.material3.Badge import androidx.compose.material3.Card import androidx.compose.material3.Icon import androidx.compose.material3.ListItem @@ -16,14 +20,17 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sadellie.unitto.core.ui.common.UnittoLargeTopAppBar @Composable +@Suppress("UNUSED_PARAMETER") internal fun ToolsScreen( navigateUpAction: () -> Unit, + navigateToConverter: () -> Unit, navigateToCalculator: () -> Unit, navigateToEpoch: () -> Unit ) { @@ -59,6 +66,19 @@ internal fun ToolsScreen( } } } + item { + ListItem( + leadingContent = { + Icon( + Icons.Default.SwapHoriz, + stringResource(R.string.unit_converter) + ) + }, + headlineText = { Text(stringResource(R.string.unit_converter)) }, + supportingText = { Text(stringResource(R.string.unit_converter_support)) }, + modifier = Modifier.clickable { navigateToConverter() } + ) + } item { ListItem( leadingContent = { @@ -80,9 +100,14 @@ internal fun ToolsScreen( stringResource(R.string.epoch_converter) ) }, - headlineText = { Text(stringResource(R.string.epoch_converter)) }, + headlineText = { + Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { + Text(stringResource(R.string.epoch_converter)) + Badge { Text(stringResource(R.string.soon_label)) } + } + }, supportingText = { Text(stringResource(R.string.epoch_converter_support)) }, - modifier = Modifier.clickable { navigateToEpoch() } + modifier = Modifier.alpha(0.5f) ) } } @@ -94,6 +119,7 @@ internal fun ToolsScreen( internal fun PreviewToolsScreen() { ToolsScreen( navigateUpAction = {}, + navigateToConverter = {}, navigateToEpoch = {}, navigateToCalculator = {} ) diff --git a/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/navigation/ToolsNavigation.kt b/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/navigation/ToolsNavigation.kt index 462dcb2a..7fe47c2c 100644 --- a/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/navigation/ToolsNavigation.kt +++ b/feature/tools/src/main/java/com/sadellie/unitto/feature/tools/navigation/ToolsNavigation.kt @@ -31,12 +31,14 @@ fun NavController.navigateToTools() { fun NavGraphBuilder.toolsScreen( navigateUpAction: () -> Unit, + navigateToConverter: () -> Unit, navigateToCalculator: () -> Unit, navigateToEpoch: () -> Unit ) { composable(toolsRoute) { ToolsScreen( navigateUpAction = navigateUpAction, + navigateToConverter = navigateToConverter, navigateToCalculator = navigateToCalculator, navigateToEpoch = navigateToEpoch )