feat(nav): Messages replaces Question Packs in bottom bar, conversation route with deep link, Play Hub hosts Packs
- AppNavigation: MESSAGES + CONVERSATION composable routes, bottom bar swaps Packs for Messages - AppRoute: MESSAGES + CONVERSATION route constants, conversation() helper, bottom nav list updated - PlayHubScreen: Question Packs card added (moved from bottom bar) - AnswerRevealScreen: discuss button navigates to conversation route - DailyQuestionScreen: discuss button navigates to conversation route
This commit is contained in:
parent
33baf220e4
commit
c85e55a790
|
|
@ -3,6 +3,7 @@ package app.closer.core.navigation
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.Chat
|
||||||
import androidx.compose.material.icons.filled.Favorite
|
import androidx.compose.material.icons.filled.Favorite
|
||||||
import androidx.compose.material.icons.filled.Home
|
import androidx.compose.material.icons.filled.Home
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.PlayArrow
|
||||||
|
|
@ -66,6 +67,8 @@ import app.closer.ui.questions.QuestionCategoryScreen
|
||||||
import app.closer.ui.questions.QuestionComposerScreen
|
import app.closer.ui.questions.QuestionComposerScreen
|
||||||
import app.closer.ui.questions.QuestionPackLibraryScreen
|
import app.closer.ui.questions.QuestionPackLibraryScreen
|
||||||
import app.closer.ui.questions.QuestionThreadScreen
|
import app.closer.ui.questions.QuestionThreadScreen
|
||||||
|
import app.closer.ui.messages.MessagesInboxScreen
|
||||||
|
import app.closer.ui.messages.ConversationScreen
|
||||||
import app.closer.ui.settings.AccountScreen
|
import app.closer.ui.settings.AccountScreen
|
||||||
import app.closer.ui.settings.AppearanceScreen
|
import app.closer.ui.settings.AppearanceScreen
|
||||||
import app.closer.ui.settings.DeleteAccountScreen
|
import app.closer.ui.settings.DeleteAccountScreen
|
||||||
|
|
@ -240,6 +243,21 @@ fun AppNavigation(
|
||||||
composable(route = AppRoute.QUESTION_PACKS) {
|
composable(route = AppRoute.QUESTION_PACKS) {
|
||||||
QuestionPackLibraryScreen(onNavigate = navigateRoute)
|
QuestionPackLibraryScreen(onNavigate = navigateRoute)
|
||||||
}
|
}
|
||||||
|
composable(route = AppRoute.MESSAGES) {
|
||||||
|
MessagesInboxScreen(onNavigate = navigateRoute)
|
||||||
|
}
|
||||||
|
composable(
|
||||||
|
route = AppRoute.CONVERSATION,
|
||||||
|
arguments = listOf(
|
||||||
|
navArgument("coupleId") { type = NavType.StringType },
|
||||||
|
navArgument("conversationId") { type = NavType.StringType }
|
||||||
|
),
|
||||||
|
deepLinks = listOf(
|
||||||
|
navDeepLink { uriPattern = "closer://closer.app/conversation/{coupleId}/{conversationId}" }
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
ConversationScreen(onNavigate = navigateRoute)
|
||||||
|
}
|
||||||
composable(
|
composable(
|
||||||
route = AppRoute.QUESTION_CATEGORY,
|
route = AppRoute.QUESTION_CATEGORY,
|
||||||
arguments = listOf(navArgument("categoryId") { type = NavType.StringType })
|
arguments = listOf(navArgument("categoryId") { type = NavType.StringType })
|
||||||
|
|
@ -517,7 +535,7 @@ fun AppNavigation(
|
||||||
// Floating in-app chat-head for incoming partner messages — drifts over every screen,
|
// Floating in-app chat-head for incoming partner messages — drifts over every screen,
|
||||||
// draggable, tap to open the conversation.
|
// draggable, tap to open the conversation.
|
||||||
app.closer.ui.components.MessageBubbleOverlay(
|
app.closer.ui.components.MessageBubbleOverlay(
|
||||||
onOpen = { c, q -> navigateRoute(AppRoute.questionThread(c, q)) }
|
onOpen = { c, conv -> navigateRoute(AppRoute.conversation(c, conv)) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -532,7 +550,7 @@ private val topLevelRoutes = listOf(
|
||||||
TopLevelRoute(AppRoute.HOME, "Home", Icons.Filled.Home),
|
TopLevelRoute(AppRoute.HOME, "Home", Icons.Filled.Home),
|
||||||
TopLevelRoute(AppRoute.DAILY_QUESTION, "Today", Icons.Filled.Favorite),
|
TopLevelRoute(AppRoute.DAILY_QUESTION, "Today", Icons.Filled.Favorite),
|
||||||
TopLevelRoute(AppRoute.PLAY, "Play", Icons.Filled.PlayArrow),
|
TopLevelRoute(AppRoute.PLAY, "Play", Icons.Filled.PlayArrow),
|
||||||
TopLevelRoute(AppRoute.QUESTION_PACKS, "Packs", Icons.Filled.Star),
|
TopLevelRoute(AppRoute.MESSAGES, "Messages", Icons.AutoMirrored.Filled.Chat),
|
||||||
TopLevelRoute(AppRoute.SETTINGS, "Settings", Icons.Filled.Settings)
|
TopLevelRoute(AppRoute.SETTINGS, "Settings", Icons.Filled.Settings)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ object AppRoute {
|
||||||
const val PLAY = "play"
|
const val PLAY = "play"
|
||||||
const val DAILY_QUESTION = "daily_question"
|
const val DAILY_QUESTION = "daily_question"
|
||||||
const val QUESTION_PACKS = "question_packs"
|
const val QUESTION_PACKS = "question_packs"
|
||||||
|
const val MESSAGES = "messages"
|
||||||
|
const val CONVERSATION = "conversation/{coupleId}/{conversationId}"
|
||||||
const val QUESTION_CATEGORY = "question_category/{categoryId}"
|
const val QUESTION_CATEGORY = "question_category/{categoryId}"
|
||||||
const val QUESTION_COMPOSER = "question_composer"
|
const val QUESTION_COMPOSER = "question_composer"
|
||||||
const val ANSWER_REVEAL = "answer_reveal/{questionId}"
|
const val ANSWER_REVEAL = "answer_reveal/{questionId}"
|
||||||
|
|
@ -85,6 +87,8 @@ object AppRoute {
|
||||||
Definition(PLAY, "Play", "play"),
|
Definition(PLAY, "Play", "play"),
|
||||||
Definition(DAILY_QUESTION, "Daily Question", "questions"),
|
Definition(DAILY_QUESTION, "Daily Question", "questions"),
|
||||||
Definition(QUESTION_PACKS, "Question Packs", "questions"),
|
Definition(QUESTION_PACKS, "Question Packs", "questions"),
|
||||||
|
Definition(MESSAGES, "Messages", "messages"),
|
||||||
|
Definition(CONVERSATION, "Conversation", "messages"),
|
||||||
Definition(QUESTION_CATEGORY, "Question Pack", "questions"),
|
Definition(QUESTION_CATEGORY, "Question Pack", "questions"),
|
||||||
Definition(QUESTION_COMPOSER, "New Question", "questions"),
|
Definition(QUESTION_COMPOSER, "New Question", "questions"),
|
||||||
Definition(QUESTION_THREAD, "Answer", "questions"),
|
Definition(QUESTION_THREAD, "Answer", "questions"),
|
||||||
|
|
@ -132,7 +136,7 @@ object AppRoute {
|
||||||
HOME,
|
HOME,
|
||||||
DAILY_QUESTION,
|
DAILY_QUESTION,
|
||||||
PLAY,
|
PLAY,
|
||||||
QUESTION_PACKS,
|
MESSAGES,
|
||||||
SETTINGS
|
SETTINGS
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -191,6 +195,9 @@ object AppRoute {
|
||||||
|
|
||||||
fun answerReveal(questionId: String): String = "answer_reveal/${questionId.asRouteArg()}"
|
fun answerReveal(questionId: String): String = "answer_reveal/${questionId.asRouteArg()}"
|
||||||
|
|
||||||
|
fun conversation(coupleId: String, conversationId: String): String =
|
||||||
|
"conversation/${coupleId.asRouteArg()}/${conversationId.asRouteArg()}"
|
||||||
|
|
||||||
fun inviteConfirm(inviteCode: String): String = "invite_confirm/${inviteCode.asRouteArg()}"
|
fun inviteConfirm(inviteCode: String): String = "invite_confirm/${inviteCode.asRouteArg()}"
|
||||||
|
|
||||||
fun questionCategory(categoryId: String): String = "question_category/${categoryId.asRouteArg()}"
|
fun questionCategory(categoryId: String): String = "question_category/${categoryId.asRouteArg()}"
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ fun AnswerRevealScreen(
|
||||||
onAnswerQuestion = {
|
onAnswerQuestion = {
|
||||||
val coupleId = state.coupleId
|
val coupleId = state.coupleId
|
||||||
if (coupleId != null) {
|
if (coupleId != null) {
|
||||||
onNavigate(AppRoute.questionThread(coupleId, questionId))
|
onNavigate(AppRoute.conversation(coupleId, "q_" + questionId))
|
||||||
} else {
|
} else {
|
||||||
// Discussing requires a paired partner; send unpaired users to invite one.
|
// Discussing requires a paired partner; send unpaired users to invite one.
|
||||||
onNavigate(AppRoute.CREATE_INVITE)
|
onNavigate(AppRoute.CREATE_INVITE)
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,18 @@ private fun PlayHubContent(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Question Packs — moved here from the bottom bar (which now hosts Messages).
|
||||||
|
item {
|
||||||
|
CompactPlayCard(
|
||||||
|
title = "Question Packs",
|
||||||
|
subtitle = "Themed prompts to explore together",
|
||||||
|
icon = Icons.Filled.Star,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
onClick = { onNavigate(AppRoute.QUESTION_PACKS) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
item {
|
item {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ fun DailyQuestionScreen(
|
||||||
onPrimaryRoute = { question ->
|
onPrimaryRoute = { question ->
|
||||||
val coupleId = state.coupleId
|
val coupleId = state.coupleId
|
||||||
if (coupleId != null) {
|
if (coupleId != null) {
|
||||||
onNavigate(AppRoute.questionThread(coupleId, question.id))
|
onNavigate(AppRoute.conversation(coupleId, "q_" + question.id))
|
||||||
} else {
|
} else {
|
||||||
onNavigate(AppRoute.CREATE_INVITE)
|
onNavigate(AppRoute.CREATE_INVITE)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue