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.
This commit is contained in:
@@ -45,6 +45,12 @@ object AppState {
|
||||
var enableGoogleLogin: Boolean = false
|
||||
var enableChat = false
|
||||
suspend fun initWithAccount(scope: CoroutineScope, context: Context) {
|
||||
// 如果是游客模式,使用简化的初始化流程
|
||||
if (AppStore.isGuest) {
|
||||
initWithGuestAccount()
|
||||
return
|
||||
}
|
||||
|
||||
val accountService: AccountService = AccountServiceImpl()
|
||||
// 获取用户认证信息
|
||||
val resp = accountService.getMyAccount()
|
||||
@@ -69,6 +75,18 @@ object AppState {
|
||||
initChat(context)
|
||||
}
|
||||
|
||||
/**
|
||||
* 游客模式的简化初始化
|
||||
*/
|
||||
private fun initWithGuestAccount() {
|
||||
// 游客模式下,不初始化推送和TRTC
|
||||
// 设置默认的用户信息
|
||||
UserId = 0
|
||||
profile = null
|
||||
enableChat = false
|
||||
Log.d("AppState", "Guest mode initialized without push notifications and TRTC")
|
||||
}
|
||||
|
||||
private suspend fun initChat(context: Context){
|
||||
val dictService :DictService = DictServiceImpl()
|
||||
val enableItem = dictService.getDictByKey(ConstVars.DICT_KEY_ENABLE_TRTC)
|
||||
@@ -149,6 +167,27 @@ object AppState {
|
||||
AppStore.saveDarkMode(darkMode)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否是游客模式,并且是否需要登录
|
||||
* @return true 如果是游客模式
|
||||
*/
|
||||
fun isGuestMode(): Boolean {
|
||||
return AppStore.isGuest
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查游客模式并提示登录
|
||||
* @param onGuestMode 当是游客模式时的回调
|
||||
* @return true 如果是游客模式
|
||||
*/
|
||||
fun checkGuestModeAndPromptLogin(onGuestMode: (() -> Unit)? = null): Boolean {
|
||||
if (AppStore.isGuest) {
|
||||
onGuestMode?.invoke()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun ReloadAppState(context: Context) {
|
||||
// 重置动态列表页面
|
||||
TimelineMomentViewModel.ResetModel()
|
||||
@@ -175,6 +214,9 @@ object AppState {
|
||||
IndexViewModel.ResetModel()
|
||||
UserId = null
|
||||
|
||||
// 清除游客状态
|
||||
AppStore.isGuest = false
|
||||
|
||||
// 关闭 TrtcService
|
||||
val trtcService = Intent(
|
||||
context,
|
||||
|
||||
@@ -41,3 +41,33 @@ object ConstVars {
|
||||
const val DICT_KEY_REPORT_OPTIONS = "report_reasons"
|
||||
}
|
||||
|
||||
enum class GuestLoginCheckOutScene {
|
||||
CREATE_POST,
|
||||
CREATE_AGENT,
|
||||
VIEW_MESSAGES,
|
||||
VIEW_PROFILE,
|
||||
JOIN_GROUP_CHAT,
|
||||
CHAT_WITH_AGENT,
|
||||
LIKE_MOMENT,
|
||||
COMMENT_MOMENT,
|
||||
FOLLOW_USER,
|
||||
REPORT_CONTENT
|
||||
}
|
||||
|
||||
object GuestLoginCheckOut {
|
||||
var NeedLoginScene = listOf<GuestLoginCheckOutScene>(
|
||||
GuestLoginCheckOutScene.CREATE_POST,
|
||||
GuestLoginCheckOutScene.CREATE_AGENT,
|
||||
GuestLoginCheckOutScene.VIEW_MESSAGES,
|
||||
GuestLoginCheckOutScene.VIEW_PROFILE,
|
||||
GuestLoginCheckOutScene.JOIN_GROUP_CHAT,
|
||||
GuestLoginCheckOutScene.CHAT_WITH_AGENT,
|
||||
GuestLoginCheckOutScene.LIKE_MOMENT,
|
||||
GuestLoginCheckOutScene.COMMENT_MOMENT,
|
||||
GuestLoginCheckOutScene.FOLLOW_USER,
|
||||
GuestLoginCheckOutScene.REPORT_CONTENT
|
||||
)
|
||||
fun needLogin(scene: GuestLoginCheckOutScene): Boolean {
|
||||
return AppStore.isGuest && NeedLoginScene.contains(scene)
|
||||
}
|
||||
}
|
||||
@@ -114,8 +114,9 @@ class MainActivity : ComponentActivity() {
|
||||
// 检查是否有登录态
|
||||
val isAccountValidate = getAccount()
|
||||
var startDestination = NavigationRoute.Login.route
|
||||
// 如果有登录态,且记住登录状态,且账号有效,则初始化 FCM,下一步进入首页
|
||||
if (AppStore.token != null && AppStore.rememberMe && isAccountValidate) {
|
||||
// 如果有登录态,且记住登录状态,且账号有效,则初始化应用状态,下一步进入首页
|
||||
if (AppStore.token != null && AppStore.rememberMe && (isAccountValidate || AppStore.isGuest)) {
|
||||
// 根据用户类型进行相应的初始化(游客模式会跳过推送和TRTC初始化)
|
||||
AppState.initWithAccount(scope, this@MainActivity)
|
||||
startDestination = NavigationRoute.Index.route
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.aiosman.ravenow.data.api.AppConfig
|
||||
import com.aiosman.ravenow.data.api.CaptchaInfo
|
||||
import com.aiosman.ravenow.data.api.ChangePasswordRequestBody
|
||||
import com.aiosman.ravenow.data.api.GoogleRegisterRequestBody
|
||||
import com.aiosman.ravenow.data.api.GuestLoginRequestBody
|
||||
import com.aiosman.ravenow.data.api.LoginUserRequestBody
|
||||
import com.aiosman.ravenow.data.api.RegisterMessageChannelRequestBody
|
||||
import com.aiosman.ravenow.data.api.RegisterRequestBody
|
||||
@@ -300,6 +301,13 @@ interface AccountService {
|
||||
*/
|
||||
suspend fun loginUserWithGoogle(googleId: String): UserAuth
|
||||
|
||||
/**
|
||||
* 游客登录
|
||||
* @param deviceId 设备ID
|
||||
* @param deviceInfo 设备信息
|
||||
*/
|
||||
suspend fun guestLogin(deviceId: String, deviceInfo: String? = null): UserAuth
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
@@ -456,6 +464,21 @@ class AccountServiceImpl : AccountService {
|
||||
return UserAuth(0, body.token)
|
||||
}
|
||||
|
||||
override suspend fun guestLogin(deviceId: String, deviceInfo: String?): UserAuth {
|
||||
val resp = ApiClient.api.guestLogin(GuestLoginRequestBody(
|
||||
deviceId = deviceId,
|
||||
deviceInfo = deviceInfo
|
||||
))
|
||||
if (!resp.isSuccessful) {
|
||||
parseErrorResponse(resp.errorBody())?.let {
|
||||
throw it.toServiceException()
|
||||
}
|
||||
throw ServiceException("Failed to guest login")
|
||||
}
|
||||
val body = resp.body() ?: throw ServiceException("Failed to guest login")
|
||||
return UserAuth(0, body.token, isGuest = true)
|
||||
}
|
||||
|
||||
override suspend fun regiterUserWithGoogleAccount(idToken: String) {
|
||||
val resp = ApiClient.api.registerWithGoogle(GoogleRegisterRequestBody(idToken))
|
||||
if (!resp.isSuccessful) {
|
||||
|
||||
@@ -5,7 +5,8 @@ import com.aiosman.ravenow.entity.AccountProfileEntity
|
||||
|
||||
data class UserAuth(
|
||||
val id: Int,
|
||||
val token: String? = null
|
||||
val token: String? = null,
|
||||
val isGuest: Boolean = false
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,7 +23,29 @@ fun getUnsafeOkHttpClient(
|
||||
): OkHttpClient {
|
||||
return try {
|
||||
// Create a trust manager that does not validate certificate chains
|
||||
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
|
||||
}
|
||||
|
||||
@Throws(CertificateException::class)
|
||||
override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
|
||||
}
|
||||
|
||||
override fun getAcceptedIssuers(): Array<java.security.cert.X509Certificate> {
|
||||
return arrayOf()
|
||||
}
|
||||
})
|
||||
|
||||
// Install the all-trusting trust manager
|
||||
val sslContext = SSLContext.getInstance("SSL")
|
||||
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
|
||||
|
||||
// Create an ssl socket factory with our all-trusting manager
|
||||
val sslSocketFactory = sslContext.socketFactory
|
||||
|
||||
OkHttpClient.Builder()
|
||||
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
|
||||
.hostnameVerifier { _, _ -> true }
|
||||
.apply {
|
||||
authInterceptor?.let {
|
||||
|
||||
@@ -95,6 +95,19 @@ data class LoginUserRequestBody(
|
||||
val captcha: CaptchaInfo? = null,
|
||||
)
|
||||
|
||||
data class GuestLoginRequestBody(
|
||||
@SerializedName("deviceID")
|
||||
val deviceId: String,
|
||||
@SerializedName("platform")
|
||||
val platform: String = "android",
|
||||
@SerializedName("deviceInfo")
|
||||
val deviceInfo: String? = null,
|
||||
@SerializedName("userAgent")
|
||||
val userAgent: String? = null,
|
||||
@SerializedName("ipAddress")
|
||||
val ipAddress: String? = null
|
||||
)
|
||||
|
||||
data class GoogleRegisterRequestBody(
|
||||
@SerializedName("idToken")
|
||||
val idToken: String
|
||||
@@ -274,6 +287,9 @@ interface RaveNowAPI {
|
||||
@POST("login")
|
||||
suspend fun login(@Body body: LoginUserRequestBody): Response<AuthResult>
|
||||
|
||||
@POST("guest/login")
|
||||
suspend fun guestLogin(@Body body: GuestLoginRequestBody): Response<AuthResult>
|
||||
|
||||
@GET("auth/token")
|
||||
suspend fun checkToken(): Response<ValidateTokenResult>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.aiosman.ravenow.entity
|
||||
|
||||
import androidx.paging.PagingSource
|
||||
import androidx.paging.PagingState
|
||||
import com.aiosman.ravenow.AppStore
|
||||
import com.aiosman.ravenow.data.Agent
|
||||
import com.aiosman.ravenow.data.ListContainer
|
||||
import com.aiosman.ravenow.data.AgentService
|
||||
@@ -28,24 +29,37 @@ suspend fun createAgent(
|
||||
title: String,
|
||||
desc: String,
|
||||
avatar: UploadImage? = null,
|
||||
workflowId:Int = 1,
|
||||
isPublic:Boolean = true,
|
||||
breakMode:Boolean = false,
|
||||
useWorkflow:Boolean = true,
|
||||
workflowId: Int = 1,
|
||||
isPublic: Boolean = true,
|
||||
breakMode: Boolean = false,
|
||||
useWorkflow: Boolean = true,
|
||||
): AgentEntity {
|
||||
val textTitle = title.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val textDesc = desc.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val workflowIdRequestBody = workflowId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val workflowIdRequestBody =
|
||||
workflowId.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val isPublicRequestBody = isPublic.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val breakModeRequestBody = breakMode.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val useWorkflowRequestBody = useWorkflow.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val useWorkflowRequestBody =
|
||||
useWorkflow.toString().toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val workflowInputsValue = "{\"si\":\"$desc\"}"
|
||||
val workflowInputsRequestBody = workflowInputsValue.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
val workflowInputsRequestBody =
|
||||
workflowInputsValue.toRequestBody("text/plain".toMediaTypeOrNull())
|
||||
|
||||
val avatarField: MultipartBody.Part? = avatar?.let {
|
||||
createMultipartBody(it.file, it.filename, "avatar")
|
||||
}
|
||||
val response = ApiClient.api.createAgent(avatarField, textTitle ,textDesc,textDesc,workflowIdRequestBody,isPublicRequestBody,breakModeRequestBody,useWorkflowRequestBody,workflowInputsRequestBody)
|
||||
val response = ApiClient.api.createAgent(
|
||||
avatarField,
|
||||
textTitle,
|
||||
textDesc,
|
||||
textDesc,
|
||||
workflowIdRequestBody,
|
||||
isPublicRequestBody,
|
||||
breakModeRequestBody,
|
||||
useWorkflowRequestBody,
|
||||
workflowInputsRequestBody
|
||||
)
|
||||
val body = response.body()?.data ?: throw ServiceException("Failed to create agent")
|
||||
return body.toAgentEntity()
|
||||
|
||||
@@ -99,7 +113,11 @@ class AgentRemoteDataSource(
|
||||
class AgentServiceImpl() : AgentService {
|
||||
val agentBackend = AgentBackend()
|
||||
|
||||
override suspend fun getAgent(pageNumber: Int, pageSize: Int, authorId: Int?): ListContainer<AgentEntity> {
|
||||
override suspend fun getAgent(
|
||||
pageNumber: Int,
|
||||
pageSize: Int,
|
||||
authorId: Int?
|
||||
): ListContainer<AgentEntity> {
|
||||
return agentBackend.getAgent(
|
||||
pageNumber = pageNumber,
|
||||
authorId = authorId
|
||||
@@ -107,50 +125,62 @@ class AgentServiceImpl() : AgentService {
|
||||
}
|
||||
}
|
||||
|
||||
class AgentBackend {
|
||||
val DataBatchSize = 20
|
||||
suspend fun getAgent(
|
||||
pageNumber: Int,
|
||||
authorId: Int? = null
|
||||
): ListContainer<AgentEntity> {
|
||||
val resp = if (authorId != null) {
|
||||
ApiClient.api.getAgent(
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
authorId = authorId
|
||||
)
|
||||
} else {
|
||||
ApiClient.api.getMyAgent(
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize
|
||||
)
|
||||
}
|
||||
|
||||
val body = resp.body() ?: throw ServiceException("Failed to get agents")
|
||||
|
||||
// 处理不同的返回类型
|
||||
return if (authorId != null) {
|
||||
// getAgent 返回 DataContainer<ListContainer<Agent>>
|
||||
val dataContainer = body as com.aiosman.ravenow.data.DataContainer<com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>>
|
||||
val listContainer = dataContainer.data
|
||||
ListContainer(
|
||||
total = listContainer.total,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = listContainer.list.map { it.toAgentEntity() }
|
||||
)
|
||||
} else {
|
||||
// getMyAgent 返回 ListContainer<Agent>
|
||||
val listContainer = body as com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>
|
||||
ListContainer(
|
||||
total = listContainer.total,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = listContainer.list.map { it.toAgentEntity() }
|
||||
)
|
||||
}
|
||||
class AgentBackend {
|
||||
val DataBatchSize = 20
|
||||
suspend fun getAgent(
|
||||
pageNumber: Int,
|
||||
authorId: Int? = null
|
||||
): ListContainer<AgentEntity> {
|
||||
// 如果是游客模式且获取我的Agent(authorId为null),返回空列表
|
||||
if (authorId == null && AppStore.isGuest) {
|
||||
return ListContainer(
|
||||
total = 0,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
val resp = if (authorId != null) {
|
||||
ApiClient.api.getAgent(
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
authorId = authorId
|
||||
)
|
||||
} else {
|
||||
ApiClient.api.getMyAgent(
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize
|
||||
)
|
||||
}
|
||||
|
||||
val body = resp.body() ?: throw ServiceException("Failed to get agents")
|
||||
|
||||
// 处理不同的返回类型
|
||||
return if (authorId != null) {
|
||||
// getAgent 返回 DataContainer<ListContainer<Agent>>
|
||||
val dataContainer =
|
||||
body as com.aiosman.ravenow.data.DataContainer<com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>>
|
||||
val listContainer = dataContainer.data
|
||||
ListContainer(
|
||||
total = listContainer.total,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = listContainer.list.map { it.toAgentEntity() }
|
||||
)
|
||||
} else {
|
||||
// getMyAgent 返回 ListContainer<Agent>
|
||||
val listContainer =
|
||||
body as com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>
|
||||
ListContainer(
|
||||
total = listContainer.total,
|
||||
page = pageNumber,
|
||||
pageSize = DataBatchSize,
|
||||
list = listContainer.list.map { it.toAgentEntity() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class AgentEntity(
|
||||
//val author: String,
|
||||
@@ -172,15 +202,27 @@ fun createMultipartBody(file: File, filename: String, name: String): MultipartBo
|
||||
val requestFile = file.asRequestBody("image/*".toMediaTypeOrNull())
|
||||
return MultipartBody.Part.createFormData(name, filename, requestFile)
|
||||
}
|
||||
|
||||
class AgentLoaderExtraArgs(
|
||||
val authorId: Int? = null
|
||||
)
|
||||
class AgentLoader : DataLoader<AgentEntity,AgentLoaderExtraArgs>() {
|
||||
|
||||
class AgentLoader : DataLoader<AgentEntity, AgentLoaderExtraArgs>() {
|
||||
override suspend fun fetchData(
|
||||
page: Int,
|
||||
pageSize: Int,
|
||||
extra: AgentLoaderExtraArgs
|
||||
): ListContainer<AgentEntity> {
|
||||
// 如果是游客模式且获取我的Agent(authorId为null),返回空列表
|
||||
if (extra.authorId == null && AppStore.isGuest) {
|
||||
return ListContainer(
|
||||
total = 0,
|
||||
page = page,
|
||||
pageSize = pageSize,
|
||||
list = emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
val result = if (extra.authorId != null) {
|
||||
ApiClient.api.getAgent(
|
||||
page = page,
|
||||
@@ -193,24 +235,25 @@ class AgentLoader : DataLoader<AgentEntity,AgentLoaderExtraArgs>() {
|
||||
pageSize = pageSize
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val body = result.body() ?: throw ServiceException("Failed to get agent")
|
||||
|
||||
|
||||
return if (extra.authorId != null) {
|
||||
// getAgent 返回 DataContainer<ListContainer<Agent>>
|
||||
val dataContainer = body as DataContainer<ListContainer<Agent>>
|
||||
val listContainer = dataContainer.data
|
||||
ListContainer(
|
||||
list = listContainer.list.map { it.toAgentEntity()},
|
||||
list = listContainer.list.map { it.toAgentEntity() },
|
||||
total = listContainer.total,
|
||||
page = page,
|
||||
pageSize = pageSize
|
||||
)
|
||||
} else {
|
||||
// getMyAgent 返回 ListContainer<Agent>
|
||||
val listContainer = body as com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>
|
||||
val listContainer =
|
||||
body as com.aiosman.ravenow.data.ListContainer<com.aiosman.ravenow.data.Agent>
|
||||
ListContainer(
|
||||
list = listContainer.list.map { it.toAgentEntity()},
|
||||
list = listContainer.list.map { it.toAgentEntity() },
|
||||
total = listContainer.total,
|
||||
page = page,
|
||||
pageSize = pageSize
|
||||
|
||||
@@ -12,6 +12,7 @@ object AppStore {
|
||||
private const val PREFS_NAME = "app_prefs_$STORE_VERSION"
|
||||
var token: String? = null
|
||||
var rememberMe: Boolean = false
|
||||
var isGuest: Boolean = false
|
||||
private lateinit var sharedPreferences: SharedPreferences
|
||||
lateinit var googleSignInOptions: GoogleSignInOptions
|
||||
fun init(context: Context) {
|
||||
@@ -36,6 +37,7 @@ object AppStore {
|
||||
sharedPreferences.edit().apply {
|
||||
putString("token", token)
|
||||
putBoolean("rememberMe", rememberMe)
|
||||
putBoolean("isGuest", isGuest)
|
||||
}.apply()
|
||||
}
|
||||
|
||||
@@ -43,6 +45,7 @@ object AppStore {
|
||||
// shared preferences
|
||||
token = sharedPreferences.getString("token", null)
|
||||
rememberMe = sharedPreferences.getBoolean("rememberMe", false)
|
||||
isGuest = sharedPreferences.getBoolean("isGuest", false)
|
||||
}
|
||||
|
||||
fun saveDarkMode(darkMode: Boolean) {
|
||||
|
||||
@@ -59,6 +59,8 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.ravenow.AppState
|
||||
import com.aiosman.ravenow.AppStore
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.Messaging
|
||||
@@ -238,10 +240,14 @@ fun IndexScreen() {
|
||||
modifier = Modifier.noRippleClickable {
|
||||
coroutineScope.launch {
|
||||
drawerState.close()
|
||||
Messaging.unregisterDevice(context)
|
||||
// 只有非游客用户才需要取消注册推送设备
|
||||
if (!AppStore.isGuest) {
|
||||
Messaging.unregisterDevice(context)
|
||||
}
|
||||
AppStore.apply {
|
||||
token = null
|
||||
rememberMe = false
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
// 删除推送渠道
|
||||
@@ -280,10 +286,32 @@ fun IndexScreen() {
|
||||
.padding(top = 2.dp)
|
||||
.noRippleClickable {
|
||||
if (it.route === NavigationItem.Add.route) {
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_POST)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
return@noRippleClickable
|
||||
}
|
||||
NewPostViewModel.asNewPost()
|
||||
navController.navigate(NavigationRoute.NewPost.route)
|
||||
return@noRippleClickable
|
||||
}
|
||||
|
||||
// 检查消息tab的游客模式
|
||||
if (it.route === NavigationItem.Notification.route) {
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.VIEW_MESSAGES)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
return@noRippleClickable
|
||||
}
|
||||
}
|
||||
|
||||
// 检查我的tab的游客模式
|
||||
if (it.route === NavigationItem.Profile.route) {
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.VIEW_PROFILE)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
return@noRippleClickable
|
||||
}
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
pagerState.scrollToPage(idx)
|
||||
}
|
||||
|
||||
@@ -46,6 +46,9 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import com.aiosman.ravenow.AppStore
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
@@ -70,7 +73,9 @@ fun Agent() {
|
||||
val navigationBarPaddings =
|
||||
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
|
||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||
var pagerState = rememberPagerState { 2 }
|
||||
// 游客模式下只显示热门Agent,正常用户显示我的Agent和热门Agent
|
||||
val tabCount = if (AppStore.isGuest) 1 else 2
|
||||
var pagerState = rememberPagerState { tabCount }
|
||||
var scope = rememberCoroutineScope()
|
||||
|
||||
val viewModel: AgentViewModel = viewModel()
|
||||
@@ -137,10 +142,15 @@ fun Agent() {
|
||||
.size(36.dp)
|
||||
.noRippleClickable {
|
||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||
// 导航到添加智能体页面
|
||||
navController.navigate(
|
||||
NavigationRoute.AddAgent.route
|
||||
)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_AGENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
// 导航到添加智能体页面
|
||||
navController.navigate(
|
||||
NavigationRoute.AddAgent.route
|
||||
)
|
||||
}
|
||||
}) {
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
}
|
||||
@@ -205,27 +215,33 @@ fun Agent() {
|
||||
color = AppColors.text
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
TabItem(
|
||||
text = stringResource(R.string.agent_mine),
|
||||
isSelected = pagerState.currentPage == 0,
|
||||
onClick = {
|
||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 300L) {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(0)
|
||||
|
||||
// 只有非游客用户才显示"我的Agent"tab
|
||||
if (!AppStore.isGuest) {
|
||||
TabItem(
|
||||
text = stringResource(R.string.agent_mine),
|
||||
isSelected = pagerState.currentPage == 0,
|
||||
onClick = {
|
||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 300L) {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(0)
|
||||
}
|
||||
}) {
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
}
|
||||
}) {
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
)
|
||||
TabSpacer()
|
||||
)
|
||||
TabSpacer()
|
||||
}
|
||||
|
||||
TabItem(
|
||||
text = stringResource(R.string.agent_hot),
|
||||
isSelected = pagerState.currentPage == 1,
|
||||
isSelected = if (AppStore.isGuest) pagerState.currentPage == 0 else pagerState.currentPage == 1,
|
||||
onClick = {
|
||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 300L) {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(1)
|
||||
val targetPage = if (AppStore.isGuest) 0 else 1
|
||||
pagerState.animateScrollToPage(targetPage)
|
||||
}
|
||||
}) {
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
@@ -261,23 +277,24 @@ fun Agent() {
|
||||
.weight(1f),
|
||||
beyondBoundsPageCount = 1 // 预加载相邻页面,避免切换时重新加载
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
MineAgent()
|
||||
if (AppStore.isGuest) {
|
||||
// 游客模式下只显示热门Agent
|
||||
when (it) {
|
||||
0 -> {
|
||||
HotAgent()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 正常用户显示我的Agent和热门Agent
|
||||
when (it) {
|
||||
0 -> {
|
||||
MineAgent()
|
||||
}
|
||||
|
||||
1 -> {
|
||||
HotAgent()
|
||||
1 -> {
|
||||
HotAgent()
|
||||
}
|
||||
}
|
||||
|
||||
2 -> {
|
||||
|
||||
}
|
||||
|
||||
3 -> {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.ravenow.AppStore
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
@@ -62,7 +63,9 @@ fun MomentsList() {
|
||||
val navigationBarPaddings =
|
||||
WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding() + 48.dp
|
||||
val statusBarPaddingValues = WindowInsets.systemBars.asPaddingValues()
|
||||
var pagerState = rememberPagerState { 4 }
|
||||
// 游客模式下不显示timeline,只显示3个tab:Explore、Dynamic、Hot
|
||||
val tabCount = if (AppStore.isGuest) 3 else 4
|
||||
var pagerState = rememberPagerState { tabCount }
|
||||
var scope = rememberCoroutineScope()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@@ -141,36 +144,40 @@ fun MomentsList() {
|
||||
)
|
||||
|
||||
}
|
||||
//关注tab
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.noRippleClickable {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(2)
|
||||
}
|
||||
},
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.index_following),
|
||||
fontSize = if (pagerState.currentPage == 2)18.sp else 16.sp,
|
||||
color = if (pagerState.currentPage == 2) AppColors.text else Color(0X993c3c43),
|
||||
fontWeight = FontWeight.W600)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
Image(
|
||||
painter = painterResource(
|
||||
if (pagerState.currentPage == 2) R.mipmap.tab_indicator_selected
|
||||
else R.drawable.tab_indicator_unselected
|
||||
),
|
||||
contentDescription = "tab indicator",
|
||||
|
||||
// 只有非游客用户才显示"关注"tab
|
||||
if (!AppStore.isGuest) {
|
||||
//关注tab
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.width(34.dp)
|
||||
.height(4.dp)
|
||||
)
|
||||
.noRippleClickable {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(2)
|
||||
}
|
||||
},
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.index_following),
|
||||
fontSize = if (pagerState.currentPage == 2)18.sp else 16.sp,
|
||||
color = if (pagerState.currentPage == 2) AppColors.text else Color(0X993c3c43),
|
||||
fontWeight = FontWeight.W600)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
Image(
|
||||
painter = painterResource(
|
||||
if (pagerState.currentPage == 2) R.mipmap.tab_indicator_selected
|
||||
else R.drawable.tab_indicator_unselected
|
||||
),
|
||||
contentDescription = "tab indicator",
|
||||
modifier = Modifier
|
||||
.width(34.dp)
|
||||
.height(4.dp)
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
//热门tab
|
||||
Spacer(modifier = Modifier.width(16.dp))
|
||||
@@ -178,7 +185,8 @@ fun MomentsList() {
|
||||
modifier = Modifier
|
||||
.noRippleClickable {
|
||||
scope.launch {
|
||||
pagerState.animateScrollToPage(3)
|
||||
val targetPage = if (AppStore.isGuest) 2 else 3
|
||||
pagerState.animateScrollToPage(targetPage)
|
||||
}
|
||||
},
|
||||
verticalArrangement = Arrangement.Center,
|
||||
@@ -186,14 +194,14 @@ fun MomentsList() {
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.index_hot),
|
||||
fontSize = if (pagerState.currentPage == 3)18.sp else 16.sp,
|
||||
color = if (pagerState.currentPage == 3) AppColors.text else Color(0X993c3c43),
|
||||
fontSize = if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) 18.sp else 16.sp,
|
||||
color = if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) AppColors.text else Color(0X993c3c43),
|
||||
fontWeight = FontWeight.W600)
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
Image(
|
||||
painter = painterResource(
|
||||
if (pagerState.currentPage == 3) R.mipmap.tab_indicator_selected
|
||||
if ((AppStore.isGuest && pagerState.currentPage == 2) || (!AppStore.isGuest && pagerState.currentPage == 3)) R.mipmap.tab_indicator_selected
|
||||
else R.drawable.tab_indicator_unselected
|
||||
),
|
||||
contentDescription = "tab indicator",
|
||||
@@ -228,22 +236,35 @@ fun MomentsList() {
|
||||
.fillMaxWidth()
|
||||
.weight(1f)
|
||||
) {
|
||||
when (it) {
|
||||
0 -> {
|
||||
Explore()
|
||||
if (AppStore.isGuest) {
|
||||
// 游客模式:Explore(0), Dynamic(1), Hot(2)
|
||||
when (it) {
|
||||
0 -> {
|
||||
Explore()
|
||||
}
|
||||
1 -> {
|
||||
Dynamic()
|
||||
}
|
||||
2 -> {
|
||||
HotMomentsList()
|
||||
}
|
||||
}
|
||||
1 -> {
|
||||
Dynamic()
|
||||
} else {
|
||||
// 正常用户:Explore(0), Dynamic(1), Timeline(2), Hot(3)
|
||||
when (it) {
|
||||
0 -> {
|
||||
Explore()
|
||||
}
|
||||
1 -> {
|
||||
Dynamic()
|
||||
}
|
||||
2 -> {
|
||||
TimelineMomentsList()
|
||||
}
|
||||
3 -> {
|
||||
HotMomentsList()
|
||||
}
|
||||
}
|
||||
|
||||
2 -> {
|
||||
TimelineMomentsList()
|
||||
}
|
||||
|
||||
3 -> {
|
||||
HotMomentsList()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,10 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.ui.NavigationRoute
|
||||
import com.aiosman.ravenow.ui.composables.MomentCard
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -28,6 +32,7 @@ import kotlinx.coroutines.launch
|
||||
fun Dynamic() {
|
||||
val model = DynamicViewModel
|
||||
var moments = model.moments
|
||||
val navController = LocalNavController.current
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val state = rememberPullRefreshState(model.refreshing, onRefresh = {
|
||||
@@ -73,30 +78,50 @@ fun Dynamic() {
|
||||
val momentItem = moments[idx] ?: return@items
|
||||
MomentCard(momentEntity = momentItem,
|
||||
onAddComment = {
|
||||
scope.launch {
|
||||
model.onAddComment(momentItem.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
model.onAddComment(momentItem.id)
|
||||
}
|
||||
}
|
||||
},
|
||||
onLikeClick = {
|
||||
scope.launch {
|
||||
if (momentItem.liked) {
|
||||
model.dislikeMoment(momentItem.id)
|
||||
} else {
|
||||
model.likeMoment(momentItem.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
if (momentItem.liked) {
|
||||
model.dislikeMoment(momentItem.id)
|
||||
} else {
|
||||
model.likeMoment(momentItem.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onFavoriteClick = {
|
||||
scope.launch {
|
||||
if (momentItem.isFavorite) {
|
||||
model.unfavoriteMoment(momentItem.id)
|
||||
} else {
|
||||
model.favoriteMoment(momentItem.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
if (momentItem.isFavorite) {
|
||||
model.unfavoriteMoment(momentItem.id)
|
||||
} else {
|
||||
model.favoriteMoment(momentItem.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onFollowClick = {
|
||||
model.followAction(momentItem)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.FOLLOW_USER)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
model.followAction(momentItem)
|
||||
}
|
||||
},
|
||||
showFollowButton = true
|
||||
)
|
||||
|
||||
@@ -54,6 +54,8 @@ import androidx.compose.ui.res.stringResource
|
||||
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.aiosman.ravenow.AppStore
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
@@ -236,8 +238,13 @@ fun Explore() {
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.clickable {
|
||||
viewModel.createSingleChat(agentItem.openId)
|
||||
viewModel.goToChatAi(agentItem.openId, navController = navController)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
viewModel.createSingleChat(agentItem.openId)
|
||||
viewModel.goToChatAi(agentItem.openId, navController = navController)
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
@@ -353,19 +360,24 @@ fun Explore() {
|
||||
},
|
||||
shape = RoundedCornerShape(12.dp))
|
||||
.clickable {
|
||||
// 调用加入房间接口
|
||||
viewModel.joinRoom(
|
||||
trtcId = roomItem.trtcId.toString(),
|
||||
name = roomItem.title,
|
||||
avatar = roomItem.avatar,
|
||||
navController = navController,
|
||||
onSuccess = {
|
||||
Toast.makeText(context, enterSuccessText, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onError = { errorMessage ->
|
||||
Toast.makeText(context, enterFailText, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.JOIN_GROUP_CHAT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
// 调用加入房间接口
|
||||
viewModel.joinRoom(
|
||||
trtcId = roomItem.trtcId.toString(),
|
||||
name = roomItem.title,
|
||||
avatar = roomItem.avatar,
|
||||
navController = navController,
|
||||
onSuccess = {
|
||||
Toast.makeText(context, enterSuccessText, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onError = { errorMessage ->
|
||||
Toast.makeText(context, enterFailText, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
@@ -615,19 +627,24 @@ fun Explore() {
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
)
|
||||
.clickable {
|
||||
// 调用加入房间接口
|
||||
viewModel.joinRoom(
|
||||
trtcId = bannerItem.trtcId.toString(),
|
||||
name = bannerItem.title,
|
||||
avatar = bannerItem.avatar,
|
||||
navController = navController,
|
||||
onSuccess = {
|
||||
Toast.makeText(context, enterSuccessText, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onError = { errorMessage ->
|
||||
Toast.makeText(context, enterFailText, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.JOIN_GROUP_CHAT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
// 调用加入房间接口
|
||||
viewModel.joinRoom(
|
||||
trtcId = bannerItem.trtcId.toString(),
|
||||
name = bannerItem.title,
|
||||
avatar = bannerItem.avatar,
|
||||
navController = navController,
|
||||
onSuccess = {
|
||||
Toast.makeText(context, enterSuccessText, Toast.LENGTH_SHORT).show()
|
||||
},
|
||||
onError = { errorMessage ->
|
||||
Toast.makeText(context, enterFailText, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
@@ -671,7 +688,12 @@ fun Explore() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
navController.navigate(NavigationRoute.CreateGroupChat.route)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.JOIN_GROUP_CHAT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
navController.navigate(NavigationRoute.CreateGroupChat.route)
|
||||
}
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
@@ -706,8 +728,12 @@ fun Explore() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
navController.navigate(
|
||||
NavigationRoute.AddAgent.route)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_AGENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
navController.navigate(NavigationRoute.AddAgent.route)
|
||||
}
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
@@ -737,8 +763,13 @@ fun Explore() {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clickable {
|
||||
NewPostViewModel.asNewPost()
|
||||
navController.navigate("NewPost")
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CREATE_POST)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
NewPostViewModel.asNewPost()
|
||||
navController.navigate("NewPost")
|
||||
}
|
||||
},
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
|
||||
@@ -58,6 +58,12 @@ object MyProfileViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
suspend fun loadUserProfile() {
|
||||
// 游客模式下不获取用户资料
|
||||
if (AppStore.isGuest) {
|
||||
MyProfileViewModel.profile = null
|
||||
return
|
||||
}
|
||||
|
||||
val profile = accountService.getMyAccountProfile()
|
||||
MyProfileViewModel.profile = profile
|
||||
}
|
||||
@@ -71,6 +77,12 @@ object MyProfileViewModel : ViewModel() {
|
||||
firstLoad = false
|
||||
loadUserProfile()
|
||||
refreshing = false
|
||||
|
||||
// 游客模式下不加载个人动态和智能体
|
||||
if (AppStore.isGuest) {
|
||||
return@launch
|
||||
}
|
||||
|
||||
profile?.let {
|
||||
try {
|
||||
momentLoader.loadData(extra = MomentLoaderExtraArgs(authorId = it.id))
|
||||
@@ -85,6 +97,12 @@ object MyProfileViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun loadMoreMoment() {
|
||||
// 游客模式下不加载更多动态
|
||||
if (AppStore.isGuest) {
|
||||
Log.d("MyProfileViewModel", "loadMoreMoment: 游客模式下跳过加载更多动态")
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
profile?.let { profileData ->
|
||||
try {
|
||||
@@ -100,19 +118,30 @@ object MyProfileViewModel : ViewModel() {
|
||||
|
||||
fun logout(context: Context) {
|
||||
viewModelScope.launch {
|
||||
Messaging.unregisterDevice(context)
|
||||
// 只有非游客用户才需要取消注册推送设备
|
||||
if (!AppStore.isGuest) {
|
||||
Messaging.unregisterDevice(context)
|
||||
}
|
||||
|
||||
AppStore.apply {
|
||||
token = null
|
||||
rememberMe = false
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
// 删除推送渠道
|
||||
// 删除推送渠道和重置应用状态
|
||||
AppState.ReloadAppState(context)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun updateUserProfileBanner(bannerImageUrl: Uri?, file: File, context: Context) {
|
||||
// 游客模式下不允许更新用户资料
|
||||
if (AppStore.isGuest) {
|
||||
Log.d("MyProfileViewModel", "updateUserProfileBanner: 游客模式下无法更新用户资料")
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
val newBanner = bannerImageUrl?.let {
|
||||
val cursor = context.contentResolver.query(it, null, null, null, null)
|
||||
@@ -141,6 +170,12 @@ object MyProfileViewModel : ViewModel() {
|
||||
}
|
||||
|
||||
fun likeMoment(momentLMomentEntity: MomentEntity) {
|
||||
// 游客模式下不允许点赞
|
||||
if (AppStore.isGuest) {
|
||||
Log.d("MyProfileViewModel", "likeMoment: 游客模式下无法点赞")
|
||||
return
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
if (momentLMomentEntity.liked) {
|
||||
momentService.dislikeMoment(momentLMomentEntity.id)
|
||||
|
||||
@@ -61,6 +61,8 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.ravenow.AppState
|
||||
import com.aiosman.ravenow.ConstVars
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.MainActivity
|
||||
|
||||
@@ -29,8 +29,12 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.ravenow.AppState
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
import com.aiosman.ravenow.ui.NavigationRoute
|
||||
import com.aiosman.ravenow.entity.AccountProfileEntity
|
||||
import com.aiosman.ravenow.ui.modifiers.noRippleClickable
|
||||
|
||||
@@ -41,6 +45,7 @@ fun OtherProfileAction(
|
||||
onChat: (() -> Unit)? = null
|
||||
) {
|
||||
val AppColors = LocalAppTheme.current
|
||||
val navController = LocalNavController.current
|
||||
|
||||
// 定义渐变色
|
||||
val followGradient = Brush.horizontalGradient(
|
||||
@@ -84,7 +89,12 @@ fun OtherProfileAction(
|
||||
}
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
.noRippleClickable {
|
||||
onFollow?.invoke()
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.FOLLOW_USER)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
onFollow?.invoke()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
@@ -112,7 +122,12 @@ fun OtherProfileAction(
|
||||
.background(AppColors.nonActive) // 使用主题灰色背景
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
.noRippleClickable {
|
||||
onChat?.invoke()
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
onChat?.invoke()
|
||||
}
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
|
||||
@@ -35,8 +35,12 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
import com.aiosman.ravenow.ui.NavigationRoute
|
||||
import com.aiosman.ravenow.entity.AgentEntity
|
||||
import com.aiosman.ravenow.ui.composables.CustomAsyncImage
|
||||
import com.aiosman.ravenow.utils.DebounceUtils
|
||||
@@ -82,6 +86,7 @@ fun UserAgentCard(
|
||||
onAvatarClick: (AgentEntity) -> Unit = {}
|
||||
) {
|
||||
val AppColors = LocalAppTheme.current
|
||||
val navController = LocalNavController.current
|
||||
|
||||
// 防抖状态
|
||||
var lastClickTime by remember { mutableStateOf(0L) }
|
||||
@@ -165,7 +170,12 @@ fun UserAgentCard(
|
||||
)
|
||||
.clickable {
|
||||
if (DebounceUtils.simpleDebounceClick(lastClickTime, 500L) {
|
||||
onAgentClick(agent)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.CHAT_WITH_AGENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
onAgentClick(agent)
|
||||
}
|
||||
}) {
|
||||
lastClickTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
@@ -149,6 +149,7 @@ fun EmailSignupScreen() {
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
this.rememberMe = rememberMe
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
// 获取token 信息
|
||||
|
||||
@@ -153,6 +153,7 @@ fun LoginPage() {
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
this.rememberMe = true
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
// 获取token 信息
|
||||
@@ -180,6 +181,76 @@ fun LoginPage() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun guestLogin() {
|
||||
coroutineScope.launch {
|
||||
try {
|
||||
// 生成设备ID
|
||||
val deviceId = android.provider.Settings.Secure.getString(
|
||||
context.contentResolver,
|
||||
android.provider.Settings.Secure.ANDROID_ID
|
||||
) ?: "unknown_device"
|
||||
|
||||
// 获取设备信息
|
||||
val deviceInfo = "${android.os.Build.MANUFACTURER} ${android.os.Build.MODEL}"
|
||||
|
||||
// 调用游客登录API
|
||||
val authResp = accountService.guestLogin(deviceId, deviceInfo)
|
||||
|
||||
// 保存token和游客状态
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
isGuest = true
|
||||
rememberMe = true
|
||||
saveData()
|
||||
}
|
||||
|
||||
// 显示成功提示
|
||||
coroutineScope.launch(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"游客登录成功",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
// 初始化应用状态(游客模式会自动跳过推送和TRTC初始化)
|
||||
try {
|
||||
AppState.initWithAccount(coroutineScope, context)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to init with guest account", e)
|
||||
// 游客模式下初始化失败不是致命错误,可以继续
|
||||
}
|
||||
|
||||
// 导航到主页
|
||||
coroutineScope.launch(Dispatchers.Main) {
|
||||
navController.navigate(NavigationRoute.Index.route) {
|
||||
popUpTo(NavigationRoute.Login.route) { inclusive = true }
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e: ServiceException) {
|
||||
coroutineScope.launch(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"游客登录失败: ${e.message}",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
Log.e(TAG, "Guest login failed", e)
|
||||
} catch (e: Exception) {
|
||||
coroutineScope.launch(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"游客登录失败",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
Log.e(TAG, "Guest login failed", e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@@ -260,6 +331,16 @@ fun LoginPage() {
|
||||
NavigationRoute.UserAuth.route,
|
||||
)
|
||||
}
|
||||
|
||||
// 游客登录按钮
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
ActionButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = "游客模式",
|
||||
color = AppColors.text.copy(alpha = 0.7f),
|
||||
) {
|
||||
guestLogin()
|
||||
}
|
||||
Spacer(modifier = Modifier.height(70.dp))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ fun SignupScreen() {
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
this.rememberMe = true
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
// 获取token 信息
|
||||
|
||||
@@ -111,6 +111,7 @@ fun UserAuthScreen() {
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
this.rememberMe = rememberMe
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
AppState.initWithAccount(scope, context)
|
||||
@@ -163,6 +164,7 @@ fun UserAuthScreen() {
|
||||
AppStore.apply {
|
||||
token = authResp.token
|
||||
this.rememberMe = rememberMe
|
||||
isGuest = false // 清除游客状态
|
||||
saveData()
|
||||
}
|
||||
navController.navigate(NavigationRoute.Index.route) {
|
||||
|
||||
@@ -91,6 +91,8 @@ import androidx.paging.LoadState
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.aiosman.ravenow.AppState
|
||||
import com.aiosman.ravenow.ConstVars
|
||||
import com.aiosman.ravenow.GuestLoginCheckOut
|
||||
import com.aiosman.ravenow.GuestLoginCheckOutScene
|
||||
import com.aiosman.ravenow.LocalAppTheme
|
||||
import com.aiosman.ravenow.LocalNavController
|
||||
import com.aiosman.ravenow.R
|
||||
@@ -194,27 +196,45 @@ fun PostScreen(
|
||||
},
|
||||
isSelf = AppState.UserId?.toLong() == contextComment?.author,
|
||||
onLikeClick = {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
}
|
||||
contextComment?.let {
|
||||
viewModel.viewModelScope.launch {
|
||||
if (it.liked) {
|
||||
viewModel.unlikeComment(it.id)
|
||||
} else {
|
||||
viewModel.likeComment(it.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
}
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
}
|
||||
contextComment?.let {
|
||||
viewModel.viewModelScope.launch {
|
||||
if (it.liked) {
|
||||
viewModel.unlikeComment(it.id)
|
||||
} else {
|
||||
viewModel.likeComment(it.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
onReplyClick = {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
replyComment = contextComment
|
||||
showCommentModal = true
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
}
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
commentModalState.hide()
|
||||
showCommentMenu = false
|
||||
replyComment = contextComment
|
||||
showCommentModal = true
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -293,24 +313,39 @@ fun PostScreen(
|
||||
if (!viewModel.isError) {
|
||||
PostBottomBar(
|
||||
onLikeClick = {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.liked == true) {
|
||||
viewModel.dislikeMoment()
|
||||
} else {
|
||||
viewModel.likeMoment()
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.liked == true) {
|
||||
viewModel.dislikeMoment()
|
||||
} else {
|
||||
viewModel.likeMoment()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onCreateCommentClick = {
|
||||
replyComment = null
|
||||
showCommentModal = true
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
replyComment = null
|
||||
showCommentModal = true
|
||||
}
|
||||
},
|
||||
onFavoriteClick = {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.isFavorite == true) {
|
||||
viewModel.unfavoriteMoment()
|
||||
} else {
|
||||
viewModel.favoriteMoment()
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.isFavorite == true) {
|
||||
viewModel.unfavoriteMoment()
|
||||
} else {
|
||||
viewModel.favoriteMoment()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -356,11 +391,16 @@ fun PostScreen(
|
||||
userId = viewModel.moment?.authorId,
|
||||
isFollowing = viewModel.moment?.followStatus == true,
|
||||
onFollowClick = {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.followStatus == true) {
|
||||
viewModel.unfollowUser()
|
||||
} else {
|
||||
viewModel.followUser()
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.FOLLOW_USER)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
scope.launch {
|
||||
if (viewModel.moment?.followStatus == true) {
|
||||
viewModel.unfollowUser()
|
||||
} else {
|
||||
viewModel.followUser()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -370,7 +410,12 @@ fun PostScreen(
|
||||
}
|
||||
},
|
||||
onReportClick = {
|
||||
showReportDialog = true
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.REPORT_CONTENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
showReportDialog = true
|
||||
}
|
||||
}
|
||||
)
|
||||
LazyColumn(
|
||||
@@ -430,8 +475,13 @@ fun PostScreen(
|
||||
contextComment = comment
|
||||
},
|
||||
onReply = { parentComment, _, _, _ ->
|
||||
replyComment = parentComment
|
||||
showCommentModal = true
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
replyComment = parentComment
|
||||
showCommentModal = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -454,6 +504,7 @@ fun CommentContent(
|
||||
onReply: (CommentEntity, Long?, String?, String?) -> Unit
|
||||
) {
|
||||
val AppColors = LocalAppTheme.current
|
||||
val navController = LocalNavController.current
|
||||
|
||||
val commentsPagging = viewModel.commentsFlow.collectAsLazyPagingItems()
|
||||
val addedTopLevelComment = viewModel.addedCommentList.filter {
|
||||
@@ -468,11 +519,16 @@ fun CommentContent(
|
||||
CommentItem(
|
||||
it,
|
||||
onLike = { comment ->
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -480,12 +536,17 @@ fun CommentContent(
|
||||
onLongClick(comment)
|
||||
},
|
||||
onReply = { parentComment, _, _, _ ->
|
||||
onReply(
|
||||
parentComment,
|
||||
parentComment.author,
|
||||
parentComment.name,
|
||||
parentComment.avatar
|
||||
)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
onReply(
|
||||
parentComment,
|
||||
parentComment.author,
|
||||
parentComment.name,
|
||||
parentComment.avatar
|
||||
)
|
||||
}
|
||||
},
|
||||
onLoadMoreSubComments = {
|
||||
viewModel.viewModelScope.launch {
|
||||
@@ -512,11 +573,16 @@ fun CommentContent(
|
||||
CommentItem(
|
||||
item,
|
||||
onLike = { comment ->
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -560,11 +626,16 @@ fun CommentContent(
|
||||
CommentItem(
|
||||
item,
|
||||
onLike = { comment ->
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.LIKE_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
viewModel.viewModelScope.launch {
|
||||
if (comment.liked) {
|
||||
viewModel.unlikeComment(comment.id)
|
||||
} else {
|
||||
viewModel.likeComment(comment.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -572,12 +643,17 @@ fun CommentContent(
|
||||
onLongClick(comment)
|
||||
},
|
||||
onReply = { parentComment, _, _, _ ->
|
||||
onReply(
|
||||
parentComment,
|
||||
parentComment.author,
|
||||
parentComment.name,
|
||||
parentComment.avatar
|
||||
)
|
||||
// 检查游客模式,如果是游客则跳转登录
|
||||
if (GuestLoginCheckOut.needLogin(GuestLoginCheckOutScene.COMMENT_MOMENT)) {
|
||||
navController.navigate(NavigationRoute.Login.route)
|
||||
} else {
|
||||
onReply(
|
||||
parentComment,
|
||||
parentComment.author,
|
||||
parentComment.name,
|
||||
parentComment.avatar
|
||||
)
|
||||
}
|
||||
},
|
||||
onLoadMoreSubComments = {
|
||||
viewModel.viewModelScope.launch {
|
||||
|
||||
Reference in New Issue
Block a user