2024-11-17 20:07:42 +08:00
|
|
|
|
package com.aiosman.ravenow.ui
|
2024-07-23 15:25:00 +08:00
|
|
|
|
|
2024-08-13 22:32:27 +08:00
|
|
|
|
import ChangePasswordScreen
|
2024-08-03 15:58:19 +08:00
|
|
|
|
import ImageViewer
|
2024-07-23 15:25:00 +08:00
|
|
|
|
import ModificationListScreen
|
|
|
|
|
|
import androidx.compose.animation.ExperimentalSharedTransitionApi
|
|
|
|
|
|
import androidx.compose.animation.SharedTransitionLayout
|
2024-08-24 21:59:16 +08:00
|
|
|
|
import androidx.compose.animation.core.tween
|
2025-09-03 14:21:13 +08:00
|
|
|
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
2024-08-24 21:59:16 +08:00
|
|
|
|
import androidx.compose.animation.fadeIn
|
|
|
|
|
|
import androidx.compose.animation.fadeOut
|
2025-08-31 21:13:06 +08:00
|
|
|
|
import androidx.compose.animation.slideInHorizontally
|
|
|
|
|
|
import androidx.compose.animation.slideOutHorizontally
|
2025-09-03 14:21:13 +08:00
|
|
|
|
import androidx.compose.animation.slideInVertically
|
|
|
|
|
|
import androidx.compose.animation.slideOutVertically
|
2024-07-23 15:25:00 +08:00
|
|
|
|
import androidx.compose.foundation.layout.Box
|
|
|
|
|
|
import androidx.compose.foundation.layout.WindowInsets
|
|
|
|
|
|
import androidx.compose.foundation.layout.navigationBars
|
|
|
|
|
|
import androidx.compose.foundation.layout.padding
|
|
|
|
|
|
import androidx.compose.runtime.Composable
|
|
|
|
|
|
import androidx.compose.runtime.CompositionLocalProvider
|
2024-09-05 22:04:41 +08:00
|
|
|
|
import androidx.compose.runtime.LaunchedEffect
|
2024-07-23 15:25:00 +08:00
|
|
|
|
import androidx.compose.ui.Modifier
|
|
|
|
|
|
import androidx.compose.ui.platform.LocalDensity
|
|
|
|
|
|
import androidx.compose.ui.unit.dp
|
|
|
|
|
|
import androidx.navigation.NavHostController
|
|
|
|
|
|
import androidx.navigation.NavType
|
|
|
|
|
|
import androidx.navigation.compose.NavHost
|
|
|
|
|
|
import androidx.navigation.compose.composable
|
|
|
|
|
|
import androidx.navigation.compose.rememberNavController
|
|
|
|
|
|
import androidx.navigation.navArgument
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.LocalAnimatedContentScope
|
|
|
|
|
|
import com.aiosman.ravenow.LocalNavController
|
|
|
|
|
|
import com.aiosman.ravenow.LocalSharedTransitionScope
|
2024-12-07 17:14:45 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.about.AboutScreen
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.account.AccountEditScreen2
|
2024-12-07 17:14:45 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.account.AccountSetting
|
2025-08-28 14:30:47 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.account.RemoveAccountScreen
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.account.ResetPasswordScreen
|
2025-07-31 15:22:34 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.agent.AddAgentScreen
|
2025-08-31 23:18:33 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.agent.AgentImageCropScreen
|
2025-08-12 19:06:56 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.group.CreateGroupChatScreen
|
2025-08-07 19:03:05 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.chat.ChatAiScreen
|
2025-10-31 11:57:49 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.chat.ChatSettingScreen
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.chat.ChatScreen
|
2025-08-18 19:02:11 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.chat.GroupChatScreen
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.comment.CommentsScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.comment.notice.CommentNoticeScreen
|
2025-09-26 17:00:12 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.composables.AgentCreatedSuccessIndicator
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.crop.ImageCropScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.favourite.FavouriteListPage
|
|
|
|
|
|
import com.aiosman.ravenow.ui.favourite.FavouriteNoticeScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.follower.FollowerListScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.follower.FollowerNoticeScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.follower.FollowingListScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.gallery.OfficialGalleryScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.gallery.OfficialPhotographerScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.gallery.ProfileTimelineScreen
|
2025-08-25 10:49:00 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.group.GroupChatInfoScreen
|
2024-11-17 20:07:42 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.index.IndexScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.index.tabs.message.NotificationsScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.index.tabs.search.SearchScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.like.LikeNoticeScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.location.LocationDetailScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.login.EmailSignupScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.login.LoginPage
|
|
|
|
|
|
import com.aiosman.ravenow.ui.login.SignupScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.login.UserAuthScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.modification.EditModificationScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.post.NewPostImageGridScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.post.NewPostScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.post.PostScreen
|
|
|
|
|
|
import com.aiosman.ravenow.ui.profile.AccountProfileV2
|
Add VIP selection page and related data models
This commit introduces a new VIP selection page (`VipSelPage.kt`) that allows users to choose between Premium and Standard membership plans.
Key changes include:
* **New VIP Selection UI:**
* `VipSelPage.kt`: Implements the UI for selecting VIP plans, displaying prices, and benefits.
* `SelfProfileAction.kt`: Updated to include a "Rave Premium" button alongside "Edit Profile".
* **Data Models for Membership:**
* `MembershipModels.kt`: Defines data classes for membership configuration (`MembershipConfigData`, `ConfigData`, `Member`, `Benefit`, `Good`), price models (`VipPriceModel`), page data models (`VipPageDataModel`), and request bodies (`ValidateProductRequestBody`, `ValidateData`).
* `VipModelMapper`: Provides functions to transform backend data into UI-friendly models for price and benefit display.
* **API Integration:**
* `RiderProAPI.kt`: Added new endpoints `getMembershipConfig` to fetch membership details and `validateAndroidProduct` for product validation.
* **Navigation:**
* `Navi.kt`: Added `VipSelPage` to the navigation routes.
* `ProfileV3.kt`: The "Rave Premium" button in the self profile action now navigates to the `VipSelPage`.
* **Theming:**
* `Colors.kt`: Added new color definitions for premium buttons, VIP benefit highlighting, and price card states (selected/unselected).
* **Assets:**
* `ic_member.webp`: New icon for the "Rave Premium" button.
2025-08-31 22:17:20 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.index.tabs.profile.vip.VipSelPage
|
2025-10-10 18:41:57 +08:00
|
|
|
|
import com.aiosman.ravenow.ui.notification.NotificationScreen
|
2024-07-23 15:25:00 +08:00
|
|
|
|
|
|
|
|
|
|
sealed class NavigationRoute(
|
|
|
|
|
|
val route: String,
|
|
|
|
|
|
) {
|
|
|
|
|
|
data object Index : NavigationRoute("Index")
|
|
|
|
|
|
data object ProfileTimeline : NavigationRoute("ProfileTimeline")
|
|
|
|
|
|
data object LocationDetail : NavigationRoute("LocationDetail/{x}/{y}")
|
|
|
|
|
|
data object OfficialPhoto : NavigationRoute("OfficialPhoto")
|
|
|
|
|
|
data object OfficialPhotographer : NavigationRoute("OfficialPhotographer")
|
2024-09-22 15:35:42 +08:00
|
|
|
|
data object Post : NavigationRoute("Post/{id}/{highlightCommentId}/{initImagePagerIndex}")
|
2024-07-23 15:25:00 +08:00
|
|
|
|
data object ModificationList : NavigationRoute("ModificationList")
|
|
|
|
|
|
data object MyMessage : NavigationRoute("MyMessage")
|
|
|
|
|
|
data object Comments : NavigationRoute("Comments")
|
|
|
|
|
|
data object Likes : NavigationRoute("Likes")
|
|
|
|
|
|
data object Followers : NavigationRoute("Followers")
|
|
|
|
|
|
data object NewPost : NavigationRoute("NewPost")
|
|
|
|
|
|
data object EditModification : NavigationRoute("EditModification")
|
2024-07-29 00:01:09 +08:00
|
|
|
|
data object Login : NavigationRoute("Login")
|
2025-09-01 01:10:35 +08:00
|
|
|
|
data object AccountProfile : NavigationRoute("AccountProfile/{id}?isAiAccount={isAiAccount}")
|
2024-07-30 09:04:07 +08:00
|
|
|
|
data object SignUp : NavigationRoute("SignUp")
|
|
|
|
|
|
data object UserAuth : NavigationRoute("UserAuth")
|
|
|
|
|
|
data object EmailSignUp : NavigationRoute("EmailSignUp")
|
2024-07-31 14:50:55 +08:00
|
|
|
|
data object AccountEdit : NavigationRoute("AccountEditScreen")
|
2024-08-03 15:58:19 +08:00
|
|
|
|
data object ImageViewer : NavigationRoute("ImageViewer")
|
2024-08-13 22:32:27 +08:00
|
|
|
|
data object ChangePasswordScreen : NavigationRoute("ChangePasswordScreen")
|
2024-08-20 19:48:12 +08:00
|
|
|
|
data object FavouritesScreen : NavigationRoute("FavouritesScreen")
|
2024-08-24 17:57:04 +08:00
|
|
|
|
data object NewPostImageGrid : NavigationRoute("NewPostImageGrid")
|
2024-08-28 23:38:29 +08:00
|
|
|
|
data object Search : NavigationRoute("Search")
|
2024-09-06 01:55:12 +08:00
|
|
|
|
data object FollowerList : NavigationRoute("FollowerList/{id}")
|
|
|
|
|
|
data object FollowingList : NavigationRoute("FollowingList/{id}")
|
2024-09-12 23:13:11 +08:00
|
|
|
|
data object ResetPassword : NavigationRoute("ResetPassword")
|
2024-09-13 23:20:38 +08:00
|
|
|
|
data object FavouriteList : NavigationRoute("FavouriteList")
|
2024-09-23 23:47:16 +08:00
|
|
|
|
data object Chat : NavigationRoute("Chat/{id}")
|
2025-08-07 19:03:05 +08:00
|
|
|
|
data object ChatAi : NavigationRoute("ChatAi/{id}")
|
2025-10-31 11:57:49 +08:00
|
|
|
|
data object ChatSetting : NavigationRoute("ChatSetting")
|
2025-08-20 19:19:14 +08:00
|
|
|
|
data object ChatGroup : NavigationRoute("ChatGroup/{id}/{name}/{avatar}")
|
2024-09-27 21:29:30 +08:00
|
|
|
|
data object CommentNoticeScreen : NavigationRoute("CommentNoticeScreen")
|
2024-10-09 15:33:08 +08:00
|
|
|
|
data object ImageCrop : NavigationRoute("ImageCrop")
|
2025-08-31 23:18:33 +08:00
|
|
|
|
data object AgentImageCrop : NavigationRoute("AgentImageCrop")
|
2024-12-07 17:14:45 +08:00
|
|
|
|
data object AccountSetting : NavigationRoute("AccountSetting")
|
|
|
|
|
|
data object AboutScreen : NavigationRoute("AboutScreen")
|
2025-07-31 15:22:34 +08:00
|
|
|
|
data object AddAgent : NavigationRoute("AddAgent")
|
2025-08-12 19:06:56 +08:00
|
|
|
|
data object CreateGroupChat : NavigationRoute("CreateGroupChat")
|
2025-08-25 10:49:00 +08:00
|
|
|
|
data object GroupInfo : NavigationRoute("GroupInfo/{id}")
|
Add VIP selection page and related data models
This commit introduces a new VIP selection page (`VipSelPage.kt`) that allows users to choose between Premium and Standard membership plans.
Key changes include:
* **New VIP Selection UI:**
* `VipSelPage.kt`: Implements the UI for selecting VIP plans, displaying prices, and benefits.
* `SelfProfileAction.kt`: Updated to include a "Rave Premium" button alongside "Edit Profile".
* **Data Models for Membership:**
* `MembershipModels.kt`: Defines data classes for membership configuration (`MembershipConfigData`, `ConfigData`, `Member`, `Benefit`, `Good`), price models (`VipPriceModel`), page data models (`VipPageDataModel`), and request bodies (`ValidateProductRequestBody`, `ValidateData`).
* `VipModelMapper`: Provides functions to transform backend data into UI-friendly models for price and benefit display.
* **API Integration:**
* `RiderProAPI.kt`: Added new endpoints `getMembershipConfig` to fetch membership details and `validateAndroidProduct` for product validation.
* **Navigation:**
* `Navi.kt`: Added `VipSelPage` to the navigation routes.
* `ProfileV3.kt`: The "Rave Premium" button in the self profile action now navigates to the `VipSelPage`.
* **Theming:**
* `Colors.kt`: Added new color definitions for premium buttons, VIP benefit highlighting, and price card states (selected/unselected).
* **Assets:**
* `ic_member.webp`: New icon for the "Rave Premium" button.
2025-08-31 22:17:20 +08:00
|
|
|
|
data object VipSelPage : NavigationRoute("VipSelPage")
|
2025-08-28 14:30:47 +08:00
|
|
|
|
data object RemoveAccountScreen: NavigationRoute("RemoveAccount")
|
2025-10-10 18:41:57 +08:00
|
|
|
|
data object NotificationScreen : NavigationRoute("NotificationScreen")
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Composable
|
2024-07-31 14:50:55 +08:00
|
|
|
|
fun NavigationController(
|
|
|
|
|
|
navController: NavHostController,
|
|
|
|
|
|
startDestination: String = NavigationRoute.Login.route
|
|
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
val navigationBarHeight = with(LocalDensity.current) {
|
|
|
|
|
|
WindowInsets.navigationBars.getBottom(this).toDp()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NavHost(
|
|
|
|
|
|
navController = navController,
|
2024-07-30 16:57:25 +08:00
|
|
|
|
startDestination = startDestination,
|
2024-07-23 15:25:00 +08:00
|
|
|
|
) {
|
|
|
|
|
|
composable(route = NavigationRoute.Index.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
IndexScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(route = NavigationRoute.ProfileTimeline.route) {
|
|
|
|
|
|
ProfileTimelineScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.LocationDetail.route,
|
|
|
|
|
|
arguments = listOf(
|
|
|
|
|
|
navArgument("x") { type = NavType.FloatType },
|
|
|
|
|
|
navArgument("y") { type = NavType.FloatType }
|
|
|
|
|
|
)
|
|
|
|
|
|
) {
|
|
|
|
|
|
Box(
|
|
|
|
|
|
modifier = Modifier.padding(bottom = navigationBarHeight)
|
|
|
|
|
|
) {
|
|
|
|
|
|
val x = it.arguments?.getFloat("x") ?: 0f
|
|
|
|
|
|
val y = it.arguments?.getFloat("y") ?: 0f
|
|
|
|
|
|
LocationDetailScreen(
|
|
|
|
|
|
x, y
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(route = NavigationRoute.OfficialPhoto.route) {
|
|
|
|
|
|
OfficialGalleryScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(route = NavigationRoute.OfficialPhotographer.route) {
|
|
|
|
|
|
OfficialPhotographerScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.Post.route,
|
2024-09-20 17:10:54 +08:00
|
|
|
|
arguments = listOf(
|
|
|
|
|
|
navArgument("id") { type = NavType.StringType },
|
2024-09-22 15:35:42 +08:00
|
|
|
|
navArgument("highlightCommentId") { type = NavType.IntType },
|
|
|
|
|
|
navArgument("initImagePagerIndex") { type = NavType.IntType }
|
2024-09-20 17:10:54 +08:00
|
|
|
|
),
|
2024-10-27 11:31:27 +08:00
|
|
|
|
enterTransition = {
|
2025-08-31 21:13:06 +08:00
|
|
|
|
// iOS push: new screen slides in from the right
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
2024-10-27 11:31:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
2025-08-31 21:13:06 +08:00
|
|
|
|
// iOS push: previous screen shifts slightly left (parallax)
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
2024-10-27 11:31:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
popEnterTransition = {
|
2025-08-31 21:13:06 +08:00
|
|
|
|
// iOS pop: previous screen slides back from slight left offset
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
2024-10-27 11:31:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
popExitTransition = {
|
2025-08-31 21:13:06 +08:00
|
|
|
|
// iOS pop: current screen slides out to the right
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
2024-10-27 11:31:27 +08:00
|
|
|
|
) { backStackEntry ->
|
|
|
|
|
|
val id = backStackEntry.arguments?.getString("id")
|
|
|
|
|
|
val highlightCommentId =
|
|
|
|
|
|
backStackEntry.arguments?.getInt("highlightCommentId")?.let {
|
|
|
|
|
|
if (it == 0) null else it
|
|
|
|
|
|
}
|
|
|
|
|
|
val initIndex = backStackEntry.arguments?.getInt("initImagePagerIndex")
|
|
|
|
|
|
PostScreen(
|
|
|
|
|
|
id!!,
|
|
|
|
|
|
highlightCommentId,
|
|
|
|
|
|
initImagePagerIndex = initIndex
|
|
|
|
|
|
)
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
2024-10-27 11:31:27 +08:00
|
|
|
|
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(route = NavigationRoute.ModificationList.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
ModificationListScreen()
|
|
|
|
|
|
}
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(route = NavigationRoute.MyMessage.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
NotificationsScreen()
|
|
|
|
|
|
}
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(route = NavigationRoute.Comments.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
CommentsScreen()
|
|
|
|
|
|
}
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(route = NavigationRoute.Likes.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-09-06 08:28:57 +08:00
|
|
|
|
LikeNoticeScreen()
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(route = NavigationRoute.Followers.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-09-06 08:28:57 +08:00
|
|
|
|
FollowerNoticeScreen()
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
2024-08-24 21:59:16 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.NewPost.route,
|
2024-09-12 21:47:00 +08:00
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
2024-08-24 21:59:16 +08:00
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
NewPostScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(route = NavigationRoute.EditModification.route) {
|
|
|
|
|
|
Box(
|
|
|
|
|
|
modifier = Modifier.padding(top = 64.dp)
|
|
|
|
|
|
) {
|
|
|
|
|
|
EditModificationScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-07-29 00:01:09 +08:00
|
|
|
|
composable(route = NavigationRoute.Login.route) {
|
|
|
|
|
|
LoginPage()
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.AccountProfile.route,
|
2025-09-01 01:10:35 +08:00
|
|
|
|
arguments = listOf(
|
|
|
|
|
|
navArgument("id") { type = NavType.StringType },
|
|
|
|
|
|
navArgument("isAiAccount") {
|
|
|
|
|
|
type = NavType.BoolType
|
|
|
|
|
|
defaultValue = false
|
|
|
|
|
|
}
|
|
|
|
|
|
),
|
2025-08-31 23:26:13 +08:00
|
|
|
|
enterTransition = {
|
|
|
|
|
|
// iOS push: new screen slides in from the right
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
// iOS push: previous screen shifts slightly left (parallax)
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popEnterTransition = {
|
|
|
|
|
|
// iOS pop: previous screen slides back from slight left offset
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popExitTransition = {
|
|
|
|
|
|
// iOS pop: current screen slides out to the right
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2024-07-29 00:01:09 +08:00
|
|
|
|
) {
|
2024-08-11 17:15:17 +08:00
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
2025-09-01 01:10:35 +08:00
|
|
|
|
val id = it.arguments?.getString("id")!!
|
|
|
|
|
|
val isAiAccount = it.arguments?.getBoolean("isAiAccount") ?: false
|
|
|
|
|
|
AccountProfileV2(id, isAiAccount)
|
2024-08-11 17:15:17 +08:00
|
|
|
|
}
|
2024-07-29 00:01:09 +08:00
|
|
|
|
}
|
2024-09-06 09:15:32 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.SignUp.route,
|
|
|
|
|
|
enterTransition = {
|
|
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
|
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-30 09:04:07 +08:00
|
|
|
|
SignupScreen()
|
|
|
|
|
|
}
|
2024-09-06 09:15:32 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.UserAuth.route,
|
|
|
|
|
|
enterTransition = {
|
2024-09-12 21:47:00 +08:00
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
2024-09-06 09:15:32 +08:00
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
2024-09-12 21:47:00 +08:00
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
2024-09-06 09:15:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-30 09:04:07 +08:00
|
|
|
|
UserAuthScreen()
|
|
|
|
|
|
}
|
2024-09-06 09:15:32 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.EmailSignUp.route,
|
|
|
|
|
|
enterTransition = {
|
2024-09-12 21:47:00 +08:00
|
|
|
|
fadeIn(animationSpec = tween(durationMillis = 0))
|
2024-09-06 09:15:32 +08:00
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
2024-09-12 21:47:00 +08:00
|
|
|
|
fadeOut(animationSpec = tween(durationMillis = 0))
|
2024-09-06 09:15:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-07-30 09:04:07 +08:00
|
|
|
|
EmailSignupScreen()
|
|
|
|
|
|
}
|
2024-09-12 21:47:00 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.AccountEdit.route,
|
|
|
|
|
|
enterTransition = {
|
2025-09-03 14:21:13 +08:00
|
|
|
|
// iOS风格:从底部向上滑入
|
|
|
|
|
|
slideInVertically(
|
|
|
|
|
|
initialOffsetY = { fullHeight -> fullHeight },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
|
|
|
|
|
|
) + fadeIn(
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300)
|
|
|
|
|
|
)
|
2024-09-12 21:47:00 +08:00
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
2025-09-03 14:21:13 +08:00
|
|
|
|
// iOS风格:向底部滑出
|
|
|
|
|
|
slideOutVertically(
|
|
|
|
|
|
targetOffsetY = { fullHeight -> fullHeight },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
|
|
|
|
|
|
) + fadeOut(
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popEnterTransition = {
|
|
|
|
|
|
// 返回时从底部滑入
|
|
|
|
|
|
slideInVertically(
|
|
|
|
|
|
initialOffsetY = { fullHeight -> fullHeight },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
|
|
|
|
|
|
) + fadeIn(
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popExitTransition = {
|
|
|
|
|
|
// 返回时向底部滑出
|
|
|
|
|
|
slideOutVertically(
|
|
|
|
|
|
targetOffsetY = { fullHeight -> fullHeight },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
|
|
|
|
|
|
) + fadeOut(
|
|
|
|
|
|
animationSpec = tween(durationMillis = 300)
|
|
|
|
|
|
)
|
2024-09-12 21:47:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
) {
|
2024-09-05 22:04:41 +08:00
|
|
|
|
AccountEditScreen2()
|
2024-07-31 14:50:55 +08:00
|
|
|
|
}
|
2024-08-03 15:58:19 +08:00
|
|
|
|
composable(route = NavigationRoute.ImageViewer.route) {
|
2024-10-27 11:31:27 +08:00
|
|
|
|
|
|
|
|
|
|
ImageViewer()
|
|
|
|
|
|
|
2024-08-03 15:58:19 +08:00
|
|
|
|
}
|
2024-08-13 22:32:27 +08:00
|
|
|
|
composable(route = NavigationRoute.ChangePasswordScreen.route) {
|
|
|
|
|
|
ChangePasswordScreen()
|
|
|
|
|
|
}
|
2025-08-28 14:30:47 +08:00
|
|
|
|
composable(route = NavigationRoute.RemoveAccountScreen.route) {
|
|
|
|
|
|
RemoveAccountScreen()
|
|
|
|
|
|
}
|
Add VIP selection page and related data models
This commit introduces a new VIP selection page (`VipSelPage.kt`) that allows users to choose between Premium and Standard membership plans.
Key changes include:
* **New VIP Selection UI:**
* `VipSelPage.kt`: Implements the UI for selecting VIP plans, displaying prices, and benefits.
* `SelfProfileAction.kt`: Updated to include a "Rave Premium" button alongside "Edit Profile".
* **Data Models for Membership:**
* `MembershipModels.kt`: Defines data classes for membership configuration (`MembershipConfigData`, `ConfigData`, `Member`, `Benefit`, `Good`), price models (`VipPriceModel`), page data models (`VipPageDataModel`), and request bodies (`ValidateProductRequestBody`, `ValidateData`).
* `VipModelMapper`: Provides functions to transform backend data into UI-friendly models for price and benefit display.
* **API Integration:**
* `RiderProAPI.kt`: Added new endpoints `getMembershipConfig` to fetch membership details and `validateAndroidProduct` for product validation.
* **Navigation:**
* `Navi.kt`: Added `VipSelPage` to the navigation routes.
* `ProfileV3.kt`: The "Rave Premium" button in the self profile action now navigates to the `VipSelPage`.
* **Theming:**
* `Colors.kt`: Added new color definitions for premium buttons, VIP benefit highlighting, and price card states (selected/unselected).
* **Assets:**
* `ic_member.webp`: New icon for the "Rave Premium" button.
2025-08-31 22:17:20 +08:00
|
|
|
|
composable(route = NavigationRoute.VipSelPage.route) {
|
|
|
|
|
|
VipSelPage()
|
|
|
|
|
|
}
|
2024-08-20 19:48:12 +08:00
|
|
|
|
composable(route = NavigationRoute.FavouritesScreen.route) {
|
2024-09-06 08:28:57 +08:00
|
|
|
|
FavouriteNoticeScreen()
|
2024-08-20 19:48:12 +08:00
|
|
|
|
}
|
2024-08-24 17:57:04 +08:00
|
|
|
|
composable(route = NavigationRoute.NewPostImageGrid.route) {
|
|
|
|
|
|
NewPostImageGridScreen()
|
|
|
|
|
|
}
|
2024-08-28 23:38:29 +08:00
|
|
|
|
composable(route = NavigationRoute.Search.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
SearchScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-06 01:55:12 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.FollowerList.route,
|
|
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
|
|
|
|
|
) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
FollowerListScreen(it.arguments?.getInt("id")!!)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.FollowingList.route,
|
|
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.IntType })
|
|
|
|
|
|
) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
FollowingListScreen(it.arguments?.getInt("id")!!)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-12 23:13:11 +08:00
|
|
|
|
composable(route = NavigationRoute.ResetPassword.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
ResetPasswordScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-13 23:20:38 +08:00
|
|
|
|
composable(route = NavigationRoute.FavouriteList.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
FavouriteListPage()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-23 23:47:16 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.Chat.route,
|
|
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.StringType })
|
|
|
|
|
|
) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
2024-10-27 11:31:27 +08:00
|
|
|
|
ChatScreen(it.arguments?.getString("id")!!)
|
2024-09-23 23:47:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-07 19:03:05 +08:00
|
|
|
|
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.ChatAi.route,
|
|
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.StringType })
|
|
|
|
|
|
) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
ChatAiScreen(it.arguments?.getString("id")!!)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-31 11:57:49 +08:00
|
|
|
|
composable(route = NavigationRoute.ChatSetting.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
ChatSettingScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-18 19:02:11 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.ChatGroup.route,
|
2025-08-20 19:19:14 +08:00
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.StringType },
|
|
|
|
|
|
navArgument("name") { type = NavType.StringType },
|
|
|
|
|
|
navArgument("avatar") { type = NavType.StringType })
|
2025-08-18 19:02:11 +08:00
|
|
|
|
) {
|
|
|
|
|
|
val encodedId = it.arguments?.getString("id")
|
|
|
|
|
|
val decodedId = encodedId?.let { java.net.URLDecoder.decode(it, "UTF-8") }
|
2025-08-20 19:19:14 +08:00
|
|
|
|
val name = it.arguments?.getString("name")
|
|
|
|
|
|
val avatar = it.arguments?.getString("avatar")
|
2025-08-18 19:02:11 +08:00
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
2025-08-20 19:19:14 +08:00
|
|
|
|
GroupChatScreen(decodedId?:"",name?:"",avatar?:"")
|
2025-08-18 19:02:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 19:03:05 +08:00
|
|
|
|
|
2024-09-27 21:29:30 +08:00
|
|
|
|
composable(route = NavigationRoute.CommentNoticeScreen.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
CommentNoticeScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-09 15:33:08 +08:00
|
|
|
|
composable(route = NavigationRoute.ImageCrop.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
ImageCropScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-31 23:18:33 +08:00
|
|
|
|
composable(route = NavigationRoute.AgentImageCrop.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
AgentImageCropScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-12-07 17:14:45 +08:00
|
|
|
|
composable(route = NavigationRoute.AccountSetting.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
AccountSetting()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
composable(route = NavigationRoute.AboutScreen.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
AboutScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-31 15:22:34 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.AddAgent.route,
|
|
|
|
|
|
) {
|
|
|
|
|
|
AddAgentScreen()
|
|
|
|
|
|
}
|
2025-08-12 19:06:56 +08:00
|
|
|
|
|
|
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.CreateGroupChat.route,
|
2025-08-31 21:13:06 +08:00
|
|
|
|
enterTransition = {
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
exitTransition = {
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popEnterTransition = {
|
|
|
|
|
|
slideInHorizontally(
|
|
|
|
|
|
initialOffsetX = { fullWidth -> -fullWidth / 3 },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
popExitTransition = {
|
|
|
|
|
|
slideOutHorizontally(
|
|
|
|
|
|
targetOffsetX = { fullWidth -> fullWidth },
|
|
|
|
|
|
animationSpec = tween(durationMillis = 280)
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2025-08-12 19:06:56 +08:00
|
|
|
|
) {
|
|
|
|
|
|
CreateGroupChatScreen()
|
|
|
|
|
|
}
|
2025-08-11 18:21:22 +08:00
|
|
|
|
|
2025-08-25 10:49:00 +08:00
|
|
|
|
composable(
|
|
|
|
|
|
route = NavigationRoute.GroupInfo.route,
|
|
|
|
|
|
arguments = listOf(navArgument("id") { type = NavType.StringType })
|
|
|
|
|
|
) {
|
|
|
|
|
|
val encodedId = it.arguments?.getString("id")
|
|
|
|
|
|
val decodedId = encodedId?.let { java.net.URLDecoder.decode(it, "UTF-8") }
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
GroupChatInfoScreen(decodedId?:"")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-10 18:41:57 +08:00
|
|
|
|
composable(route = NavigationRoute.NotificationScreen.route) {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalAnimatedContentScope provides this,
|
|
|
|
|
|
) {
|
|
|
|
|
|
NotificationScreen()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-25 10:49:00 +08:00
|
|
|
|
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@OptIn(ExperimentalSharedTransitionApi::class)
|
|
|
|
|
|
@Composable
|
2024-09-06 09:15:32 +08:00
|
|
|
|
fun Navigation(
|
|
|
|
|
|
startDestination: String = NavigationRoute.Login.route,
|
|
|
|
|
|
onLaunch: (navController: NavHostController) -> Unit
|
|
|
|
|
|
) {
|
2024-07-23 15:25:00 +08:00
|
|
|
|
val navController = rememberNavController()
|
2024-09-05 22:04:41 +08:00
|
|
|
|
LaunchedEffect(Unit) {
|
|
|
|
|
|
onLaunch(navController)
|
|
|
|
|
|
}
|
2024-07-23 15:25:00 +08:00
|
|
|
|
SharedTransitionLayout {
|
|
|
|
|
|
CompositionLocalProvider(
|
|
|
|
|
|
LocalNavController provides navController,
|
|
|
|
|
|
LocalSharedTransitionScope provides this@SharedTransitionLayout,
|
|
|
|
|
|
) {
|
|
|
|
|
|
Box {
|
2024-07-31 14:50:55 +08:00
|
|
|
|
NavigationController(
|
|
|
|
|
|
navController = navController,
|
|
|
|
|
|
startDestination = startDestination
|
|
|
|
|
|
)
|
2025-09-26 17:00:12 +08:00
|
|
|
|
AgentCreatedSuccessIndicator()
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-09-22 15:35:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun NavHostController.navigateToPost(
|
|
|
|
|
|
id: Int,
|
|
|
|
|
|
highlightCommentId: Int? = 0,
|
2024-09-29 23:17:59 +08:00
|
|
|
|
initImagePagerIndex: Int? = 0
|
2024-09-22 15:35:42 +08:00
|
|
|
|
) {
|
|
|
|
|
|
navigate(
|
|
|
|
|
|
route = NavigationRoute.Post.route
|
|
|
|
|
|
.replace("{id}", id.toString())
|
|
|
|
|
|
.replace("{highlightCommentId}", highlightCommentId.toString())
|
|
|
|
|
|
.replace("{initImagePagerIndex}", initImagePagerIndex.toString())
|
|
|
|
|
|
)
|
2024-09-23 23:47:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun NavHostController.navigateToChat(id: String) {
|
|
|
|
|
|
navigate(
|
|
|
|
|
|
route = NavigationRoute.Chat.route
|
|
|
|
|
|
.replace("{id}", id)
|
2025-08-20 19:19:14 +08:00
|
|
|
|
|
2024-09-23 23:47:16 +08:00
|
|
|
|
)
|
2024-12-07 17:14:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-08 18:53:10 +08:00
|
|
|
|
fun NavHostController.navigateToChatAi(id: String) {
|
2025-08-07 19:03:05 +08:00
|
|
|
|
navigate(
|
2025-08-08 18:53:10 +08:00
|
|
|
|
route = NavigationRoute.ChatAi.route
|
2025-08-07 19:03:05 +08:00
|
|
|
|
.replace("{id}", id)
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-20 19:19:14 +08:00
|
|
|
|
fun NavHostController.navigateToGroupChat(id: String,name:String,avatar:String) {
|
2025-08-18 19:02:11 +08:00
|
|
|
|
val encodedId = java.net.URLEncoder.encode(id, "UTF-8")
|
2025-08-20 19:19:14 +08:00
|
|
|
|
val encodedName = java.net.URLEncoder.encode(name, "UTF-8")
|
|
|
|
|
|
val encodedAvator = java.net.URLEncoder.encode(avatar, "UTF-8")
|
2025-08-18 19:02:11 +08:00
|
|
|
|
navigate(
|
|
|
|
|
|
route = NavigationRoute.ChatGroup.route
|
|
|
|
|
|
.replace("{id}", encodedId)
|
2025-08-20 19:19:14 +08:00
|
|
|
|
.replace("{name}", encodedName)
|
|
|
|
|
|
.replace("{avatar}", encodedAvator)
|
2025-08-18 19:02:11 +08:00
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-21 19:04:59 +08:00
|
|
|
|
fun NavHostController.navigateToGroupInfo(id: String) {
|
|
|
|
|
|
val encodedId = java.net.URLEncoder.encode(id, "UTF-8")
|
2025-08-25 10:49:00 +08:00
|
|
|
|
|
2025-08-21 19:04:59 +08:00
|
|
|
|
navigate(
|
2025-08-25 18:35:06 +08:00
|
|
|
|
route = NavigationRoute.GroupInfo.route
|
2025-08-25 10:49:00 +08:00
|
|
|
|
.replace("{id}", encodedId)
|
2025-08-21 19:04:59 +08:00
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-07 19:03:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-08-25 10:49:00 +08:00
|
|
|
|
|
2024-12-07 17:14:45 +08:00
|
|
|
|
fun NavHostController.goTo(
|
|
|
|
|
|
route: NavigationRoute
|
|
|
|
|
|
) {
|
|
|
|
|
|
navigate(route.route)
|
2024-07-23 15:25:00 +08:00
|
|
|
|
}
|