Files
rider-pro-android-app/app/src/main/java/com/aiosman/ravenow/MainActivity.kt

260 lines
10 KiB
Kotlin
Raw Normal View History

2024-11-17 20:07:42 +08:00
package com.aiosman.ravenow
2024-06-22 04:25:20 +08:00
import android.Manifest
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context
2024-09-17 16:06:27 +08:00
import android.content.Intent
2025-08-05 17:01:23 +08:00
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
2024-09-17 16:06:27 +08:00
import android.net.Uri
import android.os.Build
2024-06-22 04:25:20 +08:00
import android.os.Bundle
import android.util.Log
2024-06-22 04:25:20 +08:00
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
2024-09-05 22:04:41 +08:00
import androidx.activity.result.contract.ActivityResultContracts
2024-10-26 06:02:30 +08:00
import androidx.annotation.RequiresApi
2024-07-20 16:06:37 +08:00
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
2024-10-26 16:06:59 +08:00
import androidx.compose.material3.ExperimentalMaterial3Api
2024-10-26 19:05:52 +08:00
import androidx.compose.runtime.CompositionLocalProvider
2024-07-12 23:37:21 +08:00
import androidx.compose.runtime.compositionLocalOf
2024-09-05 22:04:41 +08:00
import androidx.core.content.ContextCompat
2024-07-13 17:41:51 +08:00
import androidx.core.view.WindowCompat
import androidx.lifecycle.ProcessLifecycleOwner
2024-06-22 04:25:20 +08:00
import androidx.navigation.NavHostController
2024-09-18 17:03:26 +08:00
import cn.jiguang.api.utils.JCollectionAuth
import cn.jpush.android.api.JPushInterface
2024-11-17 20:07:42 +08:00
import com.aiosman.ravenow.data.AccountService
import com.aiosman.ravenow.data.AccountServiceImpl
import com.aiosman.ravenow.data.UserService
import com.aiosman.ravenow.data.UserServiceImpl
import com.aiosman.ravenow.ui.Navigation
import com.aiosman.ravenow.ui.NavigationRoute
import com.aiosman.ravenow.ui.dialogs.CheckUpdateDialog
import com.aiosman.ravenow.ui.navigateToPost
import com.aiosman.ravenow.ui.post.NewPostViewModel
2024-11-14 17:49:26 +08:00
import com.google.firebase.Firebase
import com.google.firebase.analytics.FirebaseAnalytics
2024-11-14 17:49:26 +08:00
import com.google.firebase.analytics.analytics
2024-07-30 16:57:25 +08:00
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
2025-09-28 18:24:54 +08:00
import androidx.compose.runtime.remember
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import com.aiosman.ravenow.ui.splash.SplashScreen
2024-09-23 23:47:16 +08:00
2024-06-22 04:25:20 +08:00
class MainActivity : ComponentActivity() {
2024-09-05 22:04:41 +08:00
// Firebase Analytics
private lateinit var analytics: FirebaseAnalytics
2024-07-30 16:57:25 +08:00
private val scope = CoroutineScope(Dispatchers.Main)
2024-10-26 06:02:30 +08:00
val context = this
2024-09-05 22:04:41 +08:00
// 请求通知权限
private val requestPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { isGranted: Boolean ->
if (isGranted) {
// FCM SDK (and your app) can post notifications.
} else {
2024-09-23 23:47:16 +08:00
2024-09-05 22:04:41 +08:00
}
}
/**
* 获取账号信息
*/
private suspend fun getAccount(): Boolean {
2024-08-23 18:31:14 +08:00
val accountService: AccountService = AccountServiceImpl()
2024-08-11 17:15:17 +08:00
try {
val resp = accountService.getMyAccount()
return true
2024-08-13 22:32:27 +08:00
} catch (e: Exception) {
2024-08-11 17:15:17 +08:00
return false
}
2024-07-30 16:57:25 +08:00
}
2024-08-11 17:15:17 +08:00
2024-10-26 16:06:59 +08:00
@OptIn(ExperimentalMaterial3Api::class)
2024-10-26 06:02:30 +08:00
@RequiresApi(Build.VERSION_CODES.P)
2024-06-22 04:25:20 +08:00
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
2025-09-28 18:24:54 +08:00
2025-08-05 17:01:23 +08:00
// 设置屏幕方向为竖屏
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
2025-09-28 18:24:54 +08:00
2024-09-05 22:04:41 +08:00
// 监听应用生命周期
ProcessLifecycleOwner.get().lifecycle.addObserver(MainActivityLifecycleObserver())
// 创建通知渠道
createNotificationChannel()
// 沉浸式状态栏
2024-07-13 17:41:51 +08:00
WindowCompat.setDecorFitsSystemWindows(window, false)
2024-09-05 22:04:41 +08:00
// 初始化 Places SDK
2024-09-22 20:02:58 +08:00
2024-09-05 22:04:41 +08:00
// 初始化 Firebase Analytics
2024-11-14 17:49:26 +08:00
analytics = Firebase.analytics
2024-09-05 22:04:41 +08:00
// 请求通知权限
askNotificationPermission()
// 加载一些本地化的配置
2024-07-30 16:57:25 +08:00
AppStore.init(this)
2024-09-18 17:03:26 +08:00
JPushInterface.setDebugMode(true);
// 调整点一初始化代码前增加setAuth调用
JCollectionAuth.setAuth(this, true)
JPushInterface.init(this)
2024-10-24 23:53:51 +08:00
if (AppState.darkMode) {
window.decorView.setBackgroundColor(android.graphics.Color.BLACK)
}
2024-06-22 04:25:20 +08:00
enableEdgeToEdge()
2024-07-30 16:57:25 +08:00
scope.launch {
2024-09-05 22:04:41 +08:00
// 检查是否有登录态
2024-08-11 17:15:17 +08:00
val isAccountValidate = getAccount()
2024-07-30 16:57:25 +08:00
var startDestination = NavigationRoute.Login.route
Enhance AI Agent Profile Interaction This commit introduces several enhancements to how AI agent profiles are displayed and interacted with: **Profile Display:** - **AI Account Distinction:** Profile pages now differentiate between regular user accounts and AI agent accounts. - AI agent profiles will not display the "Agents" tab in their profile. - The profile header height is adjusted for AI accounts. - **Navigation Parameter:** An `isAiAccount` boolean parameter is added to the `AccountProfile` navigation route to indicate if the profile being viewed belongs to an AI. **Interaction & Navigation:** - **Avatar Click Navigation:** - Clicking an AI agent's avatar in various lists (Hot Agents, My Agents, User Agents Row, User Agents List) now navigates to the agent's dedicated profile page. - When navigating to an agent's profile from an agent list, `isAiAccount` is set to `true`. - **Chat Initiation:** Clicking the chat button on AI agent cards in the "Agent" tab (both Hot and My Agents) now correctly initiates a chat with the respective AI. - **ViewModel Updates:** - `AgentViewModel`, `MineAgentViewModel`, and `HotAgentViewModel` now include a `goToProfile` function to handle navigation to agent profiles, correctly passing the `isAiAccount` flag. **Code Refinements:** - Click handlers for agent avatars and chat buttons are now wrapped with `DebounceUtils.simpleDebounceClick` to prevent multiple rapid clicks. - The `UserContentPageIndicator` now conditionally hides the "Agent" tab based on the `isAiAccount` status. - `UserAgentsRow` and `UserAgentsList` now accept an `onAvatarClick` callback for navigating to agent profiles. - `AgentItem` (used in `UserAgentsRow`) and `UserAgentCard` (used in `UserAgentsList`) now handle avatar clicks. - The general `Agent` composable (used in `AiPostComposable`) now also supports an `onAvatarClick` callback.
2025-09-01 14:17:44 +08:00
// 如果有登录态,且记住登录状态,且账号有效,则初始化应用状态,下一步进入首页
if (AppStore.token != null && AppStore.rememberMe && (isAccountValidate || AppStore.isGuest)) {
// 根据用户类型进行相应的初始化游客模式会跳过推送和TRTC初始化
2024-09-23 23:47:16 +08:00
AppState.initWithAccount(scope, this@MainActivity)
2024-07-30 16:57:25 +08:00
startDestination = NavigationRoute.Index.route
}
2024-09-23 23:47:16 +08:00
2024-07-30 16:57:25 +08:00
setContent {
2025-09-28 18:24:54 +08:00
var showSplash by remember { mutableStateOf(true) }
LaunchedEffect(Unit) {
kotlinx.coroutines.delay(2000)
showSplash = false
}
if (showSplash) {
SplashScreen()
} else {
CompositionLocalProvider(
LocalAppTheme provides AppState.appTheme
) {
CheckUpdateDialog()
Navigation(startDestination) { navController ->
// 处理带有 postId 的通知点击
val postId = intent.getStringExtra("POST_ID")
var commentId = intent.getStringExtra("COMMENT_ID")
val action = intent.getStringExtra("ACTION")
if (action == "newFollow") {
navController.navigate(NavigationRoute.Followers.route)
return@Navigation
}
if (action == "followCount") {
navController.navigate(NavigationRoute.Followers.route)
return@Navigation
}
if (action == "TRTC_NEW_MESSAGE") {
val userService:UserService = UserServiceImpl()
val sender = intent.getStringExtra("SENDER")
sender?.let {
scope.launch {
try {
val profile = userService.getUserProfileByTrtcUserId(it,0)
navController.navigate(NavigationRoute.Chat.route.replace(
"{id}",
profile.id.toString()
))
}catch (e:Exception){
e.printStackTrace()
}
2024-10-26 19:05:52 +08:00
}
2024-10-11 16:51:51 +08:00
}
2025-09-28 18:24:54 +08:00
return@Navigation
2024-10-11 16:51:51 +08:00
}
2025-09-28 18:24:54 +08:00
if (commentId == null) {
commentId = "0"
2024-10-26 19:05:52 +08:00
}
2024-09-17 16:06:27 +08:00
2025-09-28 18:24:54 +08:00
if (postId != null) {
Log.d("MainActivity", "Navigation to Post$postId")
navController.navigateToPost(
id = postId.toInt(),
highlightCommentId = commentId.toInt(),
initImagePagerIndex = 0
)
}
// 处理分享过来的图片
if (intent?.action == Intent.ACTION_SEND || intent?.action == Intent.ACTION_SEND_MULTIPLE) {
val imageUris: List<Uri>? = if (intent.action == Intent.ACTION_SEND) {
listOf(intent.getParcelableExtra(Intent.EXTRA_STREAM)!!)
} else {
intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM)
}
NewPostViewModel.asNewPostWithImageUris(imageUris!!.map { it.toString() })
navController.navigate(NavigationRoute.NewPost.route)
}
2024-10-26 19:05:52 +08:00
}
2024-09-17 16:06:27 +08:00
}
2024-09-05 22:04:41 +08:00
}
2024-07-30 16:57:25 +08:00
}
2024-06-22 04:25:20 +08:00
}
}
2024-09-05 22:04:41 +08:00
2024-10-26 06:02:30 +08:00
2025-09-28 18:24:54 +08:00
2024-09-05 22:04:41 +08:00
/**
* 请求通知权限
*/
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)
}
}
2024-06-22 04:25:20 +08:00
}
2024-07-12 23:37:21 +08:00
val LocalNavController = compositionLocalOf<NavHostController> {
error("NavController not provided")
}
2024-07-20 16:06:37 +08:00
@OptIn(ExperimentalSharedTransitionApi::class)
val LocalSharedTransitionScope = compositionLocalOf<SharedTransitionScope> {
error("SharedTransitionScope not provided")
}
val LocalAnimatedContentScope = compositionLocalOf<AnimatedContentScope> {
error("AnimatedContentScope not provided")
}
2024-10-26 19:05:52 +08:00
val LocalAppTheme = compositionLocalOf<AppThemeData> {
error("AppThemeData not provided")
}