Files
rider-pro-android-app/app/src/main/java/com/aiosman/riderpro/MainActivity.kt
2024-08-23 18:31:14 +08:00

187 lines
7.6 KiB
Kotlin

package com.aiosman.riderpro
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.NavigationBarItemColors
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat
import androidx.navigation.NavHostController
import androidx.navigation.compose.currentBackStackEntryAsState
import com.aiosman.riderpro.data.AccountService
import com.aiosman.riderpro.data.AccountServiceImpl
import com.aiosman.riderpro.ui.Navigation
import com.aiosman.riderpro.ui.NavigationRoute
import com.aiosman.riderpro.ui.index.NavigationItem
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.google.android.libraries.places.api.Places
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
private val scope = CoroutineScope(Dispatchers.Main)
suspend fun getAccount(): Boolean {
val accountService: AccountService = AccountServiceImpl()
try {
val resp = accountService.getMyAccount()
return true
} catch (e: Exception) {
return false
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
if (!Places.isInitialized()) {
Places.initialize(applicationContext, "AIzaSyDpgLDH1-SECw_pdjJq_msynq1XrxwgKVI")
}
AppStore.init(this)
enableEdgeToEdge()
scope.launch {
val isAccountValidate = getAccount()
var startDestination = NavigationRoute.Login.route
if (AppStore.token != null && AppStore.rememberMe && isAccountValidate) {
startDestination = NavigationRoute.Index.route
}
setContent {
Navigation(startDestination)
}
}
}
}
val LocalNavController = compositionLocalOf<NavHostController> {
error("NavController not provided")
}
@OptIn(ExperimentalSharedTransitionApi::class)
val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> {
error("SharedTransitionScope not provided")
}
val LocalAnimatedContentScope = compositionLocalOf<AnimatedContentScope> {
error("AnimatedContentScope not provided")
}
// 用于带导航栏的路由的可复用 composable
@Composable
fun ScaffoldWithNavigationBar(
navController: NavHostController,
content: @Composable () -> Unit
) {
val navigationBarHeight = with(LocalDensity.current) {
WindowInsets.navigationBars.getBottom(this).toDp()
}
val item = listOf(
NavigationItem.Home,
NavigationItem.Street,
NavigationItem.Add,
NavigationItem.Message,
NavigationItem.Profile
)
Scaffold(
modifier = Modifier.statusBarsPadding(),
bottomBar = {
NavigationBar(
modifier = Modifier.height(56.dp + navigationBarHeight),
containerColor = Color.Black
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
val systemUiController = rememberSystemUiController()
item.forEach { it ->
val isSelected = currentRoute == it.route
val iconTint by animateColorAsState(
targetValue = if (isSelected) Color.Red else Color.White,
animationSpec = tween(durationMillis = 250), label = ""
)
NavigationBarItem(
selected = currentRoute == it.route,
onClick = {
// Check if the current route is not the same as the tab's route to avoid unnecessary navigation
if (currentRoute != it.route) {
navController.navigate(it.route) {
// Avoid creating a new layer on top of the navigation stack
launchSingleTop = true
// Attempt to pop up to the existing instance of the destination, if present
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
// Restore state when navigating back to the composable
restoreState = true
}
}
// Additional logic for system UI color changes
when (it.route) {
NavigationItem.Add.route -> {
systemUiController.setSystemBarsColor(color = Color.Black)
}
NavigationItem.Message.route -> {
systemUiController.setSystemBarsColor(color = Color.Black)
}
else -> {
systemUiController.setSystemBarsColor(color = Color.Transparent)
}
}
},
colors = NavigationBarItemColors(
selectedTextColor = Color.Red,
selectedIndicatorColor = Color.Black,
unselectedTextColor = Color.Red,
disabledIconColor = Color.Red,
disabledTextColor = Color.Red,
selectedIconColor = iconTint,
unselectedIconColor = iconTint,
),
icon = {
Icon(
modifier = Modifier.size(24.dp),
imageVector = if (currentRoute == it.route) it.selectedIcon() else it.icon(),
contentDescription = null,
tint = iconTint
)
}
)
}
}
}
) { innerPadding ->
Box(
modifier = Modifier.padding(innerPadding)
) {
content()
}
}
}