Sad Ellie b7127e75a9 Better theming options:
- Improved UI/UX
- Added ability to pick color scheme
2023-04-09 13:14:44 +03:00

150 lines
6.2 KiB
Kotlin

/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 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
import androidx.compose.animation.core.tween
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.navigation.NavDestination.Companion.hierarchy
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.TopLevelDestinations
import com.sadellie.unitto.core.ui.model.DrawerItems
import com.sadellie.unitto.core.ui.common.UnittoDrawerSheet
import com.sadellie.unitto.core.ui.theme.AppTypography
import com.sadellie.unitto.core.ui.theme.DarkThemeColors
import com.sadellie.unitto.core.ui.theme.LightThemeColors
import com.sadellie.unitto.feature.converter.ConverterViewModel
import com.sadellie.unitto.feature.settings.SettingsViewModel
import com.sadellie.unitto.feature.unitslist.UnitsListViewModel
import io.github.sadellie.themmo.Themmo
import io.github.sadellie.themmo.rememberThemmoController
import kotlinx.coroutines.launch
@Composable
internal fun UnittoApp() {
val converterViewModel: ConverterViewModel = hiltViewModel()
val unitsListViewModel: UnitsListViewModel = hiltViewModel()
val settingsViewModel: SettingsViewModel = hiltViewModel()
val userPrefs = settingsViewModel.userPrefs.collectAsStateWithLifecycle()
val themmoController = rememberThemmoController(
lightColorScheme = LightThemeColors,
darkColorScheme = DarkThemeColors,
// Anything below will not be called if theming mode is still loading from DataStore
themingMode = userPrefs.value.themingMode ?: return,
dynamicThemeEnabled = userPrefs.value.enableDynamicTheme,
amoledThemeEnabled = userPrefs.value.enableAmoledTheme,
customColor = userPrefs.value.customColor
)
val navController = rememberNavController()
val sysUiController = rememberSystemUiController()
// Navigation drawer stuff
val drawerState = rememberDrawerState(DrawerValue.Closed)
val drawerScope = rememberCoroutineScope()
val mainTabs = listOf(DrawerItems.Calculator, DrawerItems.Converter)
val additionalTabs = listOf(DrawerItems.Settings)
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute: TopLevelDestinations? by remember(navBackStackEntry?.destination) {
derivedStateOf {
val hierarchyRoutes = navBackStackEntry?.destination?.hierarchy?.map { it.route }
?: emptySequence()
(mainTabs + additionalTabs)
.map { it.destination }
.firstOrNull {
hierarchyRoutes.contains(it.route)
}
}
}
val gesturesEnabled: Boolean by remember(navBackStackEntry?.destination) {
derivedStateOf {
// Will be true for routes like
// [null, calculator_route, settings_graph, settings_route, themes_route]
// We disable drawer drag gesture when we are too deep
navController.backQueue.size <= 4
}
}
Themmo(
themmoController = themmoController,
typography = AppTypography,
animationSpec = tween(150)
) {
val statusBarColor = when (currentRoute) {
// Match text field container color
TopLevelDestinations.Calculator -> MaterialTheme.colorScheme.surfaceVariant
else -> MaterialTheme.colorScheme.background
}
val navigationBarColor = MaterialTheme.colorScheme.background
ModalNavigationDrawer(
drawerState = drawerState,
gesturesEnabled = gesturesEnabled,
drawerContent = {
UnittoDrawerSheet(
modifier = Modifier,
mainTabs = mainTabs,
additionalTabs = additionalTabs,
currentDestination = currentRoute
) {
drawerScope.launch { drawerState.close() }
navController.navigate(it) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
}
) {
UnittoNavigation(
navController = navController,
converterViewModel = converterViewModel,
unitsListViewModel = unitsListViewModel,
settingsViewModel = settingsViewModel,
themmoController = it,
startDestination = userPrefs.value.startingScreen,
openDrawer = { drawerScope.launch { drawerState.open() } }
)
}
SideEffect {
sysUiController.setNavigationBarColor(navigationBarColor)
sysUiController.setStatusBarColor(statusBarColor)
}
}
}