package com.aiosman.riderpro import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts 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.content.ContextCompat 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 com.google.firebase.analytics.FirebaseAnalytics import com.google.firebase.analytics.ktx.analytics import com.google.firebase.ktx.Firebase import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import android.Manifest import android.app.NotificationChannel import android.app.NotificationManager import android.content.Context import android.content.Intent import android.content.pm.PackageManager import android.os.Build import android.util.Log import android.widget.Toast import androidx.lifecycle.ProcessLifecycleOwner import androidx.lifecycle.viewModelScope import androidx.navigation.findNavController import com.aiosman.riderpro.ui.post.PostViewModel import com.google.android.gms.tasks.OnCompleteListener import com.google.firebase.messaging.FirebaseMessaging class MainActivity : ComponentActivity() { // Firebase Analytics private lateinit var analytics: FirebaseAnalytics private val scope = CoroutineScope(Dispatchers.Main) // 请求通知权限 private val requestPermissionLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission(), ) { isGranted: Boolean -> if (isGranted) { // FCM SDK (and your app) can post notifications. } else { // TODO: Inform user that that your app will not show notifications. } } /** * 获取账号信息 */ private suspend fun getAccount(): Boolean { val accountService: AccountService = AccountServiceImpl() try { val resp = accountService.getMyAccount() // 设置当前登录用户 ID AppState.UserId = resp.id return true } catch (e: Exception) { return false } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 监听应用生命周期 ProcessLifecycleOwner.get().lifecycle.addObserver(MainActivityLifecycleObserver()) // 创建通知渠道 createNotificationChannel() // 沉浸式状态栏 WindowCompat.setDecorFitsSystemWindows(window, false) // 初始化 Places SDK if (!Places.isInitialized()) { Places.initialize(applicationContext, "AIzaSyDpgLDH1-SECw_pdjJq_msynq1XrxwgKVI") } // 初始化 Firebase Analytics analytics = Firebase.analytics // 请求通知权限 askNotificationPermission() // 加载一些本地化的配置 AppStore.init(this) enableEdgeToEdge() scope.launch { // 检查是否有登录态 val isAccountValidate = getAccount() var startDestination = NavigationRoute.Login.route // 如果有登录态,且记住登录状态,且账号有效,则初始化 FCM,下一步进入首页 if (AppStore.token != null && AppStore.rememberMe && isAccountValidate) { Messaging.InitFCM(scope) startDestination = NavigationRoute.Index.route } setContent { Navigation(startDestination) { navController -> // 处理带有 postId 的通知点击 val postId = intent.getStringExtra("POST_ID") if (postId != null) { Log.d("MainActivity", "Navigation to Post$postId") PostViewModel.postId = postId PostViewModel.viewModelScope.launch { PostViewModel.initData() navController.navigate(NavigationRoute.Post.route.replace("{id}", postId)) } } } } } } /** * 请求通知权限 */ private fun askNotificationPermission() { // This is only necessary for API level >= 33 (TIRAMISU) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED ) { // FCM SDK (and your app) can post notifications. } else if (shouldShowRequestPermissionRationale(android.Manifest.permission.POST_NOTIFICATIONS)) { } else { // Directly ask for the permission requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) } } } /** * 创建通知渠道 */ private fun createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val channelId = ConstVars.MOMENT_LIKE_CHANNEL_ID val channelName = ConstVars.MOMENT_LIKE_CHANNEL_NAME val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT) val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) } } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) } } val LocalNavController = compositionLocalOf { error("NavController not provided") } @OptIn(ExperimentalSharedTransitionApi::class) val LocalSharedTransitionScope = compositionLocalOf { error("SharedTransitionScope not provided") } val LocalAnimatedContentScope = compositionLocalOf { error("AnimatedContentScope not provided") }