Skip to content

Commit

Permalink
Refactor TopLevelDestinations
Browse files Browse the repository at this point in the history
closes #160
closes #161
  • Loading branch information
sadellie committed Jan 15, 2024
1 parent 3c6abd1 commit 9f24b9b
Show file tree
Hide file tree
Showing 16 changed files with 204 additions and 266 deletions.
19 changes: 4 additions & 15 deletions app/src/main/java/com/sadellie/unitto/UnittoApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -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() }
Expand All @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 9f24b9b

Please sign in to comment.