mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
parent
3c6abd137a
commit
9f24b9b3cc
@ -35,11 +35,9 @@ import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.sadellie.unitto.core.base.Shortcut
|
||||
import com.sadellie.unitto.core.base.TOP_LEVEL_START_ROUTES
|
||||
import com.sadellie.unitto.core.ui.common.UnittoNavigationDrawer
|
||||
import com.sadellie.unitto.core.ui.common.rememberDrawerState
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItems
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.pushDynamicShortcut
|
||||
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
|
||||
import com.sadellie.unitto.core.ui.theme.LightThemeColors
|
||||
@ -67,7 +65,7 @@ internal fun UnittoApp(prefs: AppPreferences?) {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val gesturesEnabled: Boolean by remember(navBackStackEntry?.destination) {
|
||||
derivedStateOf {
|
||||
TOP_LEVEL_START_ROUTES.contains(navBackStackEntry?.destination?.route)
|
||||
DrawerItem.startRoutes.contains(navBackStackEntry?.destination?.route)
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,7 +94,7 @@ internal fun UnittoApp(prefs: AppPreferences?) {
|
||||
modifier = Modifier,
|
||||
state = drawerState,
|
||||
gesturesEnabled = gesturesEnabled,
|
||||
tabs = DrawerItems.MAIN,
|
||||
tabs = DrawerItem.main,
|
||||
currentDestination = navBackStackEntry?.destination?.route,
|
||||
onItemClick = { destination ->
|
||||
drawerScope.launch { drawerState.close() }
|
||||
@ -109,16 +107,7 @@ internal fun UnittoApp(prefs: AppPreferences?) {
|
||||
restoreState = true
|
||||
}
|
||||
|
||||
shortcutsScope.launch {
|
||||
destination.shortcut?.let { shortcut: Shortcut ->
|
||||
mContext.pushDynamicShortcut(
|
||||
destination.graph,
|
||||
shortcut.shortcutShortLabel,
|
||||
shortcut.shortcutLongLabel,
|
||||
shortcut.shortcutDrawable
|
||||
)
|
||||
}
|
||||
}
|
||||
shortcutsScope.launch { mContext.pushDynamicShortcut(destination) }
|
||||
},
|
||||
content = {
|
||||
UnittoNavigation(
|
||||
|
@ -18,126 +18,18 @@
|
||||
|
||||
package com.sadellie.unitto.core.base
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
// Don't touch, users have "..._route" in their settings
|
||||
private const val CONVERTER_GRAPH = "converter_route"
|
||||
private const val CONVERTER_START = "converter_start"
|
||||
|
||||
private const val CALCULATOR_GRAPH = "calculator_route"
|
||||
private const val CALCULATOR_START = "calculator_start"
|
||||
|
||||
private const val DATE_CALCULATOR_GRAPH = "date_calculator_route"
|
||||
private const val DATE_CALCULATOR_START = "date_calculator_start"
|
||||
|
||||
private const val TIME_ZONE_GRAPH = "time_zone_route"
|
||||
private const val TIME_ZONE_START = "time_zone_start"
|
||||
|
||||
private const val BODY_MASS_GRAPH = "body_mass_route"
|
||||
private const val BODY_MASS_START = "body_mass_start"
|
||||
|
||||
private const val SETTINGS_GRAPH = "settings_route"
|
||||
private const val SETTINGS_START = "settings_start"
|
||||
|
||||
data class Shortcut(
|
||||
@StringRes val shortcutShortLabel: Int,
|
||||
@StringRes val shortcutLongLabel: Int,
|
||||
@DrawableRes val shortcutDrawable: Int,
|
||||
)
|
||||
|
||||
sealed class TopLevelDestinations(
|
||||
val graph: String,
|
||||
val start: String = graph,
|
||||
@StringRes val name: Int,
|
||||
val shortcut: Shortcut? = null
|
||||
) {
|
||||
data object Converter : TopLevelDestinations(
|
||||
graph = CONVERTER_GRAPH,
|
||||
start = CONVERTER_START,
|
||||
name = R.string.unit_converter_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.unit_converter_title,
|
||||
R.string.unit_converter_title,
|
||||
R.drawable.ic_shortcut_unit_converter
|
||||
)
|
||||
)
|
||||
|
||||
data object Calculator : TopLevelDestinations(
|
||||
graph = CALCULATOR_GRAPH,
|
||||
start = CALCULATOR_START,
|
||||
name = R.string.calculator_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.calculator_title,
|
||||
R.string.calculator_title,
|
||||
R.drawable.ic_shortcut_calculator
|
||||
)
|
||||
)
|
||||
|
||||
data object DateCalculator : TopLevelDestinations(
|
||||
graph = DATE_CALCULATOR_GRAPH,
|
||||
start = DATE_CALCULATOR_START,
|
||||
name = R.string.date_calculator_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.date_calculator_title,
|
||||
R.string.date_calculator_title,
|
||||
R.drawable.ic_shortcut_date_calculator
|
||||
)
|
||||
)
|
||||
|
||||
data object TimeZone : TopLevelDestinations(
|
||||
graph = TIME_ZONE_GRAPH,
|
||||
start = TIME_ZONE_START,
|
||||
name = R.string.time_zone_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.time_zone_title,
|
||||
R.string.time_zone_title,
|
||||
R.drawable.ic_shortcut_time_zone
|
||||
)
|
||||
)
|
||||
|
||||
data object BodyMass : TopLevelDestinations(
|
||||
graph = BODY_MASS_GRAPH,
|
||||
start = BODY_MASS_START,
|
||||
name = R.string.body_mass_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.body_mass_title,
|
||||
R.string.body_mass_title,
|
||||
R.drawable.ic_shortcut_body_mass
|
||||
)
|
||||
)
|
||||
|
||||
data object Settings : TopLevelDestinations(
|
||||
graph = SETTINGS_GRAPH,
|
||||
start = SETTINGS_START,
|
||||
name = R.string.settings_title
|
||||
)
|
||||
}
|
||||
|
||||
// Shown in settings
|
||||
val TOP_LEVEL_DESTINATIONS by lazy {
|
||||
var all = listOf(
|
||||
TopLevelDestinations.Calculator,
|
||||
TopLevelDestinations.Converter,
|
||||
TopLevelDestinations.DateCalculator,
|
||||
TopLevelDestinations.TimeZone,
|
||||
TopLevelDestinations.BodyMass,
|
||||
)
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
all = all - TopLevelDestinations.TimeZone
|
||||
}
|
||||
|
||||
all
|
||||
}
|
||||
|
||||
// Only routes, not graphs!
|
||||
val TOP_LEVEL_START_ROUTES by lazy {
|
||||
listOf(
|
||||
CALCULATOR_START,
|
||||
CONVERTER_START,
|
||||
DATE_CALCULATOR_START,
|
||||
TIME_ZONE_START,
|
||||
)
|
||||
object TopLevelDestinations {
|
||||
const val CONVERTER_GRAPH = "converter_route"
|
||||
const val CONVERTER_START = "converter_start"
|
||||
const val CALCULATOR_GRAPH = "calculator_route"
|
||||
const val CALCULATOR_START = "calculator_start"
|
||||
const val DATE_CALCULATOR_GRAPH = "date_calculator_route"
|
||||
const val DATE_CALCULATOR_START = "date_calculator_start"
|
||||
const val TIME_ZONE_GRAPH = "time_zone_route"
|
||||
const val TIME_ZONE_START = "time_zone_start"
|
||||
const val BODY_MASS_GRAPH = "body_mass_route"
|
||||
const val BODY_MASS_START = "body_mass_start"
|
||||
const val SETTINGS_GRAPH = "settings_route"
|
||||
const val SETTINGS_START = "settings_start"
|
||||
}
|
||||
|
@ -23,61 +23,63 @@ import android.app.PendingIntent.FLAG_IMMUTABLE
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.model.Shortcut
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
// I think it makes sense to run in coroutine
|
||||
/**
|
||||
* Tries to push a dynamic shortcut. Does nothing if [DrawerItem.shortcut] is `null`
|
||||
*
|
||||
* @param drawerItem [DrawerItem]
|
||||
*/
|
||||
suspend fun Context.pushDynamicShortcut(
|
||||
route: String,
|
||||
@StringRes shortLabel: Int,
|
||||
@StringRes longLabel: Int,
|
||||
@DrawableRes drawable: Int,
|
||||
drawerItem: DrawerItem,
|
||||
) = withContext(Dispatchers.IO) {
|
||||
// Low chance that we WILL push the shortcut
|
||||
if ((0..10).random() != 0) return@withContext
|
||||
|
||||
val shortcut = drawerItem.shortcut ?: return@withContext
|
||||
// Resource intensive method!
|
||||
val context = this@pushDynamicShortcut
|
||||
|
||||
val shortcut = shortcutInfoCompat(
|
||||
val shortcutCompat = shortcutInfoCompat(
|
||||
context = context,
|
||||
route = route,
|
||||
shortLabel = shortLabel,
|
||||
longLabel = longLabel,
|
||||
drawable = drawable
|
||||
route = drawerItem.graph,
|
||||
shortcut = shortcut
|
||||
)
|
||||
|
||||
kotlin.runCatching {
|
||||
ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)
|
||||
ShortcutManagerCompat.pushDynamicShortcut(context, shortcutCompat)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to pin shortcut. Does nothing if [DrawerItem.shortcut] is `null`
|
||||
*
|
||||
* @param drawerItem [DrawerItem]
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
fun Context.addShortcut(
|
||||
route: String,
|
||||
@StringRes shortLabel: Int,
|
||||
@StringRes longLabel: Int,
|
||||
@DrawableRes drawable: Int,
|
||||
drawerItem: DrawerItem,
|
||||
) {
|
||||
val shortcut = drawerItem.shortcut ?: return
|
||||
val context = this@addShortcut
|
||||
|
||||
val shortcut = shortcutInfoCompat(
|
||||
val shortcutCompat = shortcutInfoCompat(
|
||||
context = context,
|
||||
route = route,
|
||||
shortLabel = shortLabel,
|
||||
longLabel = longLabel,
|
||||
drawable = drawable
|
||||
route = drawerItem.graph,
|
||||
shortcut = shortcut
|
||||
)
|
||||
|
||||
val shortCutIntent = ShortcutManagerCompat.createShortcutResultIntent(context, shortcut)
|
||||
val shortCutIntent = ShortcutManagerCompat.createShortcutResultIntent(context, shortcutCompat)
|
||||
|
||||
try {
|
||||
ShortcutManagerCompat.requestPinShortcut(
|
||||
context,
|
||||
shortcut,
|
||||
shortcutCompat,
|
||||
PendingIntent.getBroadcast(context, 0, shortCutIntent, FLAG_IMMUTABLE).intentSender
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
@ -88,14 +90,12 @@ fun Context.addShortcut(
|
||||
private fun Context.shortcutInfoCompat(
|
||||
context: Context,
|
||||
route: String,
|
||||
shortLabel: Int,
|
||||
longLabel: Int,
|
||||
drawable: Int,
|
||||
shortcut: Shortcut,
|
||||
): ShortcutInfoCompat {
|
||||
return ShortcutInfoCompat.Builder(context, route)
|
||||
.setShortLabel(getString(shortLabel))
|
||||
.setLongLabel(getString(longLabel))
|
||||
.setIcon(IconCompat.createWithResource(context, drawable))
|
||||
.setShortLabel(getString(shortcut.shortcutShortLabel))
|
||||
.setLongLabel(getString(shortcut.shortcutLongLabel))
|
||||
.setIcon(IconCompat.createWithResource(context, shortcut.shortcutDrawable))
|
||||
.setIntent(
|
||||
Intent(
|
||||
Intent.ACTION_VIEW,
|
@ -25,15 +25,15 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
|
||||
@Composable
|
||||
internal fun UnittoDrawerItem(
|
||||
modifier: Modifier = Modifier,
|
||||
destination: TopLevelDestinations,
|
||||
destination: DrawerItem,
|
||||
icon: ImageVector,
|
||||
selected: Boolean,
|
||||
onClick: (TopLevelDestinations) -> Unit
|
||||
onClick: (DrawerItem) -> Unit
|
||||
) {
|
||||
NavigationDrawerItem(
|
||||
modifier = modifier,
|
||||
|
@ -58,10 +58,9 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.LocalWindowSize
|
||||
import com.sadellie.unitto.core.ui.WindowWidthSizeClass
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItems
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -112,9 +111,9 @@ fun UnittoNavigationDrawer(
|
||||
modifier: Modifier,
|
||||
gesturesEnabled: Boolean,
|
||||
state: DrawerState = rememberDrawerState(),
|
||||
tabs: List<DrawerItems>,
|
||||
tabs: List<DrawerItem>,
|
||||
currentDestination: String?,
|
||||
onItemClick: (TopLevelDestinations) -> Unit,
|
||||
onItemClick: (DrawerItem) -> Unit,
|
||||
content: @Composable () -> Unit,
|
||||
) {
|
||||
if (LocalWindowSize.current.widthSizeClass == WindowWidthSizeClass.Expanded) {
|
||||
@ -280,8 +279,8 @@ private fun PreviewUnittoModalNavigationDrawerClose() {
|
||||
modifier = Modifier,
|
||||
state = drawerState,
|
||||
gesturesEnabled = true,
|
||||
tabs = DrawerItems.MAIN,
|
||||
currentDestination = DrawerItems.Calculator.destination.start,
|
||||
tabs = DrawerItem.main,
|
||||
currentDestination = DrawerItem.Calculator.start,
|
||||
onItemClick = {},
|
||||
content = {
|
||||
Column {
|
||||
|
@ -39,18 +39,17 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.LocalWindowSize
|
||||
import com.sadellie.unitto.core.ui.WindowHeightSizeClass
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItems
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
@Suppress("UnusedReceiverParameter")
|
||||
@Composable
|
||||
internal fun ColumnScope.SheetContent(
|
||||
tabs: List<DrawerItems>,
|
||||
tabs: List<DrawerItem>,
|
||||
currentDestination: String?,
|
||||
onItemClick: (TopLevelDestinations) -> Unit,
|
||||
onItemClick: (DrawerItem) -> Unit,
|
||||
) {
|
||||
var showHello by remember { mutableStateOf(false) }
|
||||
val interactionSource = remember {
|
||||
@ -81,10 +80,10 @@ internal fun ColumnScope.SheetContent(
|
||||
}
|
||||
|
||||
tabs.forEach { drawerItem ->
|
||||
val selected = drawerItem.destination.start == currentDestination
|
||||
val selected = drawerItem.start == currentDestination
|
||||
UnittoDrawerItem(
|
||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding),
|
||||
destination = drawerItem.destination,
|
||||
destination = drawerItem,
|
||||
icon = if (selected) drawerItem.selectedIcon else drawerItem.defaultIcon,
|
||||
selected = selected,
|
||||
onClick = onItemClick
|
||||
@ -97,8 +96,8 @@ internal fun ColumnScope.SheetContent(
|
||||
|
||||
UnittoDrawerItem(
|
||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding),
|
||||
destination = DrawerItems.Settings.destination,
|
||||
icon = DrawerItems.Settings.defaultIcon,
|
||||
destination = DrawerItem.Settings,
|
||||
icon = DrawerItem.Settings.defaultIcon,
|
||||
selected = false,
|
||||
onClick = onItemClick
|
||||
)
|
||||
@ -111,11 +110,11 @@ private fun PreviewUnittoDrawerSheet() {
|
||||
Column {
|
||||
SheetContent(
|
||||
tabs = listOf(
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
DrawerItems.Calculator,
|
||||
DrawerItem.Calculator,
|
||||
DrawerItem.Calculator,
|
||||
DrawerItem.Calculator,
|
||||
),
|
||||
currentDestination = DrawerItems.Calculator.destination.start,
|
||||
currentDestination = DrawerItem.Calculator.start,
|
||||
onItemClick = {}
|
||||
)
|
||||
}
|
||||
|
@ -19,15 +19,14 @@
|
||||
package com.sadellie.unitto.core.ui.model
|
||||
|
||||
import android.os.Build
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Accessibility
|
||||
import androidx.compose.material.icons.filled.AccessibilityNew
|
||||
import androidx.compose.material.icons.filled.Calculate
|
||||
import androidx.compose.material.icons.filled.Event
|
||||
import androidx.compose.material.icons.filled.Schedule
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material.icons.filled.SwapHoriz
|
||||
import androidx.compose.material.icons.outlined.Accessibility
|
||||
import androidx.compose.material.icons.outlined.AccessibilityNew
|
||||
import androidx.compose.material.icons.outlined.Calculate
|
||||
import androidx.compose.material.icons.outlined.Event
|
||||
@ -35,60 +34,102 @@ import androidx.compose.material.icons.outlined.Schedule
|
||||
import androidx.compose.material.icons.outlined.Settings
|
||||
import androidx.compose.material.icons.outlined.SwapHoriz
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
|
||||
sealed class DrawerItems(
|
||||
val destination: TopLevelDestinations,
|
||||
sealed class DrawerItem(
|
||||
val graph: String,
|
||||
val start: String,
|
||||
@StringRes val name: Int,
|
||||
val shortcut: Shortcut?,
|
||||
val selectedIcon: ImageVector,
|
||||
val defaultIcon: ImageVector
|
||||
) {
|
||||
data object Calculator : DrawerItems(
|
||||
destination = TopLevelDestinations.Calculator,
|
||||
data object Calculator : DrawerItem(
|
||||
graph = TopLevelDestinations.CALCULATOR_GRAPH,
|
||||
start = TopLevelDestinations.CALCULATOR_START,
|
||||
name = R.string.calculator_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.calculator_title,
|
||||
R.string.calculator_title,
|
||||
R.drawable.ic_shortcut_calculator
|
||||
),
|
||||
selectedIcon = Icons.Filled.Calculate,
|
||||
defaultIcon = Icons.Outlined.Calculate
|
||||
)
|
||||
|
||||
data object Converter : DrawerItems(
|
||||
destination = TopLevelDestinations.Converter,
|
||||
data object Converter : DrawerItem(
|
||||
graph = TopLevelDestinations.CONVERTER_GRAPH,
|
||||
start = TopLevelDestinations.CONVERTER_START,
|
||||
name = R.string.unit_converter_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.unit_converter_title,
|
||||
R.string.unit_converter_title,
|
||||
R.drawable.ic_shortcut_unit_converter
|
||||
),
|
||||
selectedIcon = Icons.Filled.SwapHoriz,
|
||||
defaultIcon = Icons.Outlined.SwapHoriz
|
||||
)
|
||||
|
||||
data object DateDifference : DrawerItems(
|
||||
destination = TopLevelDestinations.DateCalculator,
|
||||
data object DateCalculator : DrawerItem(
|
||||
graph = TopLevelDestinations.DATE_CALCULATOR_GRAPH,
|
||||
start = TopLevelDestinations.DATE_CALCULATOR_START,
|
||||
name = R.string.date_calculator_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.date_calculator_title,
|
||||
R.string.date_calculator_title,
|
||||
R.drawable.ic_shortcut_date_calculator
|
||||
),
|
||||
selectedIcon = Icons.Filled.Event,
|
||||
defaultIcon = Icons.Outlined.Event
|
||||
)
|
||||
|
||||
data object TimeZones : DrawerItems(
|
||||
destination = TopLevelDestinations.TimeZone,
|
||||
data object TimeZones : DrawerItem(
|
||||
graph = TopLevelDestinations.TIME_ZONE_GRAPH,
|
||||
start = TopLevelDestinations.TIME_ZONE_START,
|
||||
name = R.string.time_zone_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.time_zone_title,
|
||||
R.string.time_zone_title,
|
||||
R.drawable.ic_shortcut_time_zone
|
||||
),
|
||||
selectedIcon = Icons.Filled.Schedule,
|
||||
defaultIcon = Icons.Outlined.Schedule
|
||||
)
|
||||
|
||||
data object BodyMass : DrawerItems(
|
||||
destination = TopLevelDestinations.BodyMass,
|
||||
data object BodyMass : DrawerItem(
|
||||
graph = TopLevelDestinations.BODY_MASS_GRAPH,
|
||||
start = TopLevelDestinations.BODY_MASS_START,
|
||||
name = R.string.body_mass_title,
|
||||
shortcut = Shortcut(
|
||||
R.string.body_mass_title,
|
||||
R.string.body_mass_title,
|
||||
R.drawable.ic_shortcut_body_mass
|
||||
),
|
||||
selectedIcon = Icons.Filled.AccessibilityNew,
|
||||
defaultIcon = Icons.Outlined.AccessibilityNew
|
||||
)
|
||||
|
||||
data object Settings : DrawerItems(
|
||||
destination = TopLevelDestinations.Settings,
|
||||
data object Settings : DrawerItem(
|
||||
graph = TopLevelDestinations.SETTINGS_GRAPH,
|
||||
start = TopLevelDestinations.SETTINGS_START,
|
||||
name = R.string.settings_title,
|
||||
shortcut = null,
|
||||
selectedIcon = Icons.Filled.Settings,
|
||||
defaultIcon = Icons.Outlined.Settings
|
||||
)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Excluding Settings tab since it appears only for expanded layout
|
||||
* Except for [Settings]
|
||||
*/
|
||||
val MAIN by lazy {
|
||||
val main by lazy {
|
||||
var all = listOf(
|
||||
Calculator,
|
||||
Converter,
|
||||
DateDifference,
|
||||
DateCalculator,
|
||||
TimeZones,
|
||||
BodyMass
|
||||
BodyMass,
|
||||
)
|
||||
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
|
||||
@ -97,5 +138,8 @@ sealed class DrawerItems(
|
||||
|
||||
all
|
||||
}
|
||||
|
||||
// Only routes, not graphs!
|
||||
val startRoutes by lazy { main.map { it.start } }
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.core.ui.model
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
|
||||
data class Shortcut(
|
||||
@StringRes val shortcutShortLabel: Int,
|
||||
@StringRes val shortcutLongLabel: Int,
|
||||
@DrawableRes val shortcutDrawable: Int,
|
||||
)
|
@ -48,7 +48,7 @@ fun Preferences.getMonetMode(): String {
|
||||
}
|
||||
|
||||
fun Preferences.getStartingScreen(): String {
|
||||
return this[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.Calculator.graph
|
||||
return this[PrefsKeys.STARTING_SCREEN] ?: TopLevelDestinations.CALCULATOR_GRAPH
|
||||
}
|
||||
|
||||
fun Preferences.getEnableToolsExperiment(): Boolean {
|
||||
|
@ -20,13 +20,13 @@ package com.sadellie.unitto.feature.bodymass.navigation
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoComposable
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.feature.bodymass.BodyMassRoute
|
||||
|
||||
private val graph = TopLevelDestinations.BodyMass.graph
|
||||
private val start = TopLevelDestinations.BodyMass.start
|
||||
private val graph = DrawerItem.BodyMass.graph
|
||||
private val start = DrawerItem.BodyMass.start
|
||||
|
||||
fun NavGraphBuilder.bodyMassGraph(
|
||||
openDrawer: () -> Unit,
|
||||
|
@ -20,14 +20,14 @@ package com.sadellie.unitto.feature.calculator.navigation
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoComposable
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.feature.calculator.CalculatorRoute
|
||||
import com.sadellie.unitto.feature.calculator.RPNCalculatorRoute
|
||||
|
||||
private val graph = TopLevelDestinations.Calculator.graph
|
||||
private val start = TopLevelDestinations.Calculator.start
|
||||
private val graph = DrawerItem.Calculator.graph
|
||||
private val start = DrawerItem.Calculator.start
|
||||
|
||||
fun NavGraphBuilder.calculatorGraph(
|
||||
rpnMode: Boolean,
|
||||
|
@ -23,7 +23,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoComposable
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.feature.converter.ConverterRoute
|
||||
@ -31,8 +31,8 @@ import com.sadellie.unitto.feature.converter.ConverterViewModel
|
||||
import com.sadellie.unitto.feature.converter.LeftSideRoute
|
||||
import com.sadellie.unitto.feature.converter.RightSideRoute
|
||||
|
||||
private val graph = TopLevelDestinations.Converter.graph
|
||||
private val start = TopLevelDestinations.Converter.start
|
||||
private val graph = DrawerItem.Converter.graph
|
||||
private val start = DrawerItem.Converter.start
|
||||
private const val LEFT = "left"
|
||||
private const val RIGHT = "right"
|
||||
|
||||
|
@ -20,13 +20,13 @@ package com.sadellie.unitto.feature.datecalculator.navigation
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoComposable
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.feature.datecalculator.DateCalculatorRoute
|
||||
|
||||
private val graph = TopLevelDestinations.DateCalculator.graph
|
||||
private val start = TopLevelDestinations.DateCalculator.start
|
||||
private val graph = DrawerItem.DateCalculator.graph
|
||||
private val start = DrawerItem.DateCalculator.start
|
||||
|
||||
fun NavGraphBuilder.dateCalculatorGraph(
|
||||
navigateToMenu: () -> Unit,
|
||||
|
@ -22,7 +22,7 @@ import androidx.navigation.NavController
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.core.ui.unittoStackedComposable
|
||||
import com.sadellie.unitto.feature.settings.SettingsRoute
|
||||
@ -37,8 +37,8 @@ import com.sadellie.unitto.feature.settings.thirdparty.ThirdPartyLicensesScreen
|
||||
import com.sadellie.unitto.feature.settings.unitgroups.UnitGroupsScreen
|
||||
import io.github.sadellie.themmo.ThemmoController
|
||||
|
||||
private val graph = TopLevelDestinations.Settings.graph
|
||||
private val start = TopLevelDestinations.Settings.start
|
||||
private val graph = DrawerItem.Settings.graph
|
||||
private val start = DrawerItem.Settings.start
|
||||
internal const val displayRoute = "display_route"
|
||||
internal const val languageRoute = "language_route"
|
||||
internal const val startingScreenRoute = "starting_screen_route"
|
||||
@ -50,7 +50,7 @@ internal const val calculatorSettingsRoute = "calculator_settings_route"
|
||||
internal const val converterSettingsRoute = "converter_settings_route"
|
||||
|
||||
fun NavController.navigateToSettings() {
|
||||
navigate(TopLevelDestinations.Settings.start)
|
||||
navigate(DrawerItem.Settings.start)
|
||||
}
|
||||
|
||||
fun NavController.navigateToUnitGroups() {
|
||||
|
@ -21,6 +21,7 @@ package com.sadellie.unitto.feature.settings.startingscreen
|
||||
import android.os.Build
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.AppShortcut
|
||||
import androidx.compose.material3.Icon
|
||||
@ -35,14 +36,12 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.sadellie.unitto.core.base.R
|
||||
import com.sadellie.unitto.core.base.Shortcut
|
||||
import com.sadellie.unitto.core.base.TOP_LEVEL_DESTINATIONS
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.addShortcut
|
||||
import com.sadellie.unitto.core.ui.common.NavigateUpButton
|
||||
import com.sadellie.unitto.core.ui.common.UnittoEmptyScreen
|
||||
import com.sadellie.unitto.core.ui.common.UnittoListItem
|
||||
import com.sadellie.unitto.core.ui.common.UnittoScreenWithLargeTopBar
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
|
||||
@Composable
|
||||
internal fun StartingScreenRoute(
|
||||
@ -74,40 +73,28 @@ private fun StartingScreenScreen(
|
||||
navigationIcon = { NavigateUpButton(navigateUp) }
|
||||
) { padding ->
|
||||
LazyColumn(contentPadding = padding) {
|
||||
items(DrawerItem.main, { it.graph }) { destination ->
|
||||
UnittoListItem(
|
||||
modifier = Modifier.clickable { updateStartingScreen(destination.graph) },
|
||||
headlineContent = {
|
||||
Text(stringResource(destination.name))
|
||||
},
|
||||
leadingContent = {
|
||||
RadioButton(
|
||||
selected = destination.graph == startingScreen,
|
||||
onClick = { updateStartingScreen(destination.graph) }
|
||||
)
|
||||
},
|
||||
trailingContent = trail@{
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N_MR1) return@trail
|
||||
|
||||
TOP_LEVEL_DESTINATIONS.forEach { destination ->
|
||||
item {
|
||||
UnittoListItem(
|
||||
modifier = Modifier.clickable { updateStartingScreen(destination.graph) },
|
||||
headlineContent = {
|
||||
Text(stringResource(destination.name))
|
||||
},
|
||||
leadingContent = {
|
||||
RadioButton(
|
||||
selected = destination.graph == startingScreen,
|
||||
onClick = { updateStartingScreen(destination.graph) }
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
|
||||
IconButton(
|
||||
onClick = {
|
||||
destination.shortcut?.let { shortcut: Shortcut ->
|
||||
mContext.addShortcut(
|
||||
destination.graph,
|
||||
shortcut.shortcutShortLabel,
|
||||
shortcut.shortcutLongLabel,
|
||||
shortcut.shortcutDrawable
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Icon(Icons.Default.AppShortcut, null)
|
||||
}
|
||||
}
|
||||
IconButton(
|
||||
onClick = { mContext.addShortcut(destination) }
|
||||
) {
|
||||
Icon(Icons.Default.AppShortcut, null)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,7 +104,7 @@ private fun StartingScreenScreen(
|
||||
@Composable
|
||||
private fun StartingScreenPreview() {
|
||||
StartingScreenScreen(
|
||||
startingScreen = TopLevelDestinations.Converter.graph,
|
||||
startingScreen = DrawerItem.Converter.graph,
|
||||
updateStartingScreen = {},
|
||||
navigateUp = {}
|
||||
)
|
||||
|
@ -25,8 +25,8 @@ import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import androidx.navigation.navDeepLink
|
||||
import com.sadellie.unitto.core.base.TopLevelDestinations
|
||||
import com.sadellie.unitto.core.ui.common.UnittoEmptyScreen
|
||||
import com.sadellie.unitto.core.ui.model.DrawerItem
|
||||
import com.sadellie.unitto.core.ui.unittoComposable
|
||||
import com.sadellie.unitto.core.ui.unittoNavigation
|
||||
import com.sadellie.unitto.feature.timezone.AddTimeZoneRoute
|
||||
@ -34,8 +34,8 @@ import com.sadellie.unitto.feature.timezone.TimeZoneRoute
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
private val graph = TopLevelDestinations.TimeZone.graph
|
||||
private val start = TopLevelDestinations.TimeZone.start
|
||||
private val graph = DrawerItem.TimeZones.graph
|
||||
private val start = DrawerItem.TimeZones.start
|
||||
private const val ADD_TIME_ZONE_ROUTE = "ADD_TIME_ZONE_ROUTE"
|
||||
private const val USER_TIME_ARG = "USER_TIME_ARG"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user