From 72f01ff64471d189c6f0d64edad3b42f486aef41 Mon Sep 17 00:00:00 2001 From: 2olka Date: Fri, 5 Dec 2025 16:37:59 +0500 Subject: [PATCH 1/4] =?UTF-8?q?ANDR-28:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B8=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B5=D1=85=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=B6=D0=B4=D1=83=20=D0=B2=D0=BE=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core_ui/component/PopoverQuestion.kt | 63 ++++++++-------- .../presentation/DetailQuestionFeatureImpl.kt | 74 +++++++++++++++++-- .../intents/DetailQuestionCommand.kt | 1 + .../intents/DetailQuestionEvent.kt | 2 + .../intents/DetailQuestionResult.kt | 1 + .../presentation/view/DetailQuestionScreen.kt | 46 ++++++++++-- .../impl/presentation/view/QuestionContent.kt | 20 ++++- .../viewmodel/DetailQuestionViewModel.kt | 18 ++++- .../impl/PublicQuestionsFeatureImpl.kt | 11 +-- .../intents/PublicQuestionsResult.kt | 5 +- .../intents/PublicQuestionsScreenCommand.kt | 5 +- .../intents/PublicQuestionsScreenEvent.kt | 5 +- .../screen/PublicQuestionsScreen.kt | 25 +++++-- .../viewmodel/PublicQuestionsViewModel.kt | 9 ++- 14 files changed, 220 insertions(+), 65 deletions(-) diff --git a/core/ui/src/main/java/ru/yeahub/core_ui/component/PopoverQuestion.kt b/core/ui/src/main/java/ru/yeahub/core_ui/component/PopoverQuestion.kt index e75bccb9..25515fec 100644 --- a/core/ui/src/main/java/ru/yeahub/core_ui/component/PopoverQuestion.kt +++ b/core/ui/src/main/java/ru/yeahub/core_ui/component/PopoverQuestion.kt @@ -104,38 +104,39 @@ fun PopoverQuestion( verticalArrangement = Arrangement.spacedBy(rowSpacing), ) { // Первый ряд: Изучить, Повторить, Избранное - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.SpaceEvenly - ) { - IconWithText( - iconResId = R.drawable.student, - text = stringResource(R.string.learn), - contentDescription = stringResource(R.string.learn), - isClickable = onLearnClick != null, - onItemClickListener = { onLearnClick?.invoke() }, - screenWidth = screenWidth - ) - IconWithText( - iconResId = R.drawable.clockcounterclockwise, - text = stringResource(R.string.repeat), - contentDescription = stringResource(R.string.repeat), - isClickable = onRepeatClick != null, - onItemClickListener = { onRepeatClick?.invoke() }, - screenWidth = screenWidth - ) - IconWithText( - iconResId = getFavoriteIconRes(favoriteState), - text = stringResource(R.string.favorite), - contentDescription = stringResource(R.string.favorite), - isClickable = favoriteState.isClickable, - iconColor = getFavoriteIconColor(favoriteState), - textColor = getFavoriteTextColor(favoriteState), - onItemClickListener = { onFavoriteClick?.invoke() }, - screenWidth = screenWidth - ) + if (false) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly, + ) { + IconWithText( + iconResId = R.drawable.student, + text = stringResource(R.string.learn), + contentDescription = stringResource(R.string.learn), + isClickable = onLearnClick != null, + onItemClickListener = { onLearnClick?.invoke() }, + screenWidth = screenWidth + ) + IconWithText( + iconResId = R.drawable.clockcounterclockwise, + text = stringResource(R.string.repeat), + contentDescription = stringResource(R.string.repeat), + isClickable = onRepeatClick != null, + onItemClickListener = { onRepeatClick?.invoke() }, + screenWidth = screenWidth + ) + IconWithText( + iconResId = getFavoriteIconRes(favoriteState), + text = stringResource(R.string.favorite), + contentDescription = stringResource(R.string.favorite), + isClickable = favoriteState.isClickable, + iconColor = getFavoriteIconColor(favoriteState), + textColor = getFavoriteTextColor(favoriteState), + onItemClickListener = { onFavoriteClick?.invoke() }, + screenWidth = screenWidth + ) + } } - // Второй ряд: Назад, Вперед Row( modifier = Modifier.fillMaxWidth(), diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt index a0ffa6f9..45951e83 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt @@ -13,6 +13,7 @@ import ru.yeahub.detail_question.impl.presentation.view.DetailQuestionScreen import ru.yeahub.navigation_api.FeatureApi import ru.yeahub.navigation_api.FeatureRoute import ru.yeahub.navigation_api.NavigationPathManager +import timber.log.Timber class DetailQuestionFeatureImpl : FeatureApi { @@ -28,30 +29,53 @@ class DetailQuestionFeatureImpl : FeatureApi { ) { val detailQuestionRoute = pathManager.createParametrizedPath( featureName = getFeatureName(), - "questionId" + "questionIds", + "currentIndex" ) navGraphBuilder.composable( route = detailQuestionRoute, arguments = listOf( - navArgument("questionId") { type = NavType.LongType } + navArgument("questionIds") { type = NavType.StringType }, + navArgument("currentIndex") { type = NavType.IntType } ) ) { backStackEntry -> - val questionId = backStackEntry.arguments?.getLong("questionId") ?: 0L + val questionIdsString = backStackEntry.arguments?.getString("questionIds") ?: "" + val questionIds = questionIdsString.split(",").map { it.toLongOrNull() ?: 0L } + val currentIndex = backStackEntry.arguments?.getInt("currentIndex") ?: 0 + val currentQuestionId = questionIds.getOrNull(currentIndex) ?: 0L + + // Извлекаем родительский путь из текущего маршрута, а не из pathManager + val currentRoute = backStackEntry.destination.route ?: "" + val parentPathFromRoute = extractParentPath(currentRoute) + + Timber.tag("DetailQuestionFeature") + .d("Current route: $currentRoute, Parent path: $parentPathFromRoute") + DetailQuestionScreen( onResult = { result -> when (result) { - DetailQuestionResult.BackClick -> handleBackNavigation( + is DetailQuestionResult.BackClick -> handleBackNavigation( pathManager, navController ) + is DetailQuestionResult.UrlClick -> { val intent = Intent(Intent.ACTION_VIEW, result.url.toUri()) navController.context.startActivity(intent) } + + is DetailQuestionResult.NavigateToQuestion -> handleQuestionNavigation( + navController, + questionIds, + result.newIndex, + parentPathFromRoute + ) } }, - questionId = questionId + questionId = currentQuestionId, + questionIds = questionIds, + currentIndex = currentIndex ) } } @@ -62,7 +86,6 @@ private fun handleBackNavigation( navController: NavHostController ) { val parentPath = pathManager.getParentPath() - pathManager.setCurrentPath(parentPath) if (parentPath.isEmpty()) { @@ -74,4 +97,43 @@ private fun handleBackNavigation( } } } +} + +private fun handleQuestionNavigation( + navController: NavHostController, + questionIds: List, + newIndex: Int, + parentPath: String +) { + val questionIdsParam = questionIds.joinToString(",") + val concretePath = if (parentPath.isEmpty()) { + "${FeatureRoute.DetailQuestionFeature.FEATURE_NAME}/$questionIdsParam/$newIndex" + } else { + "$parentPath/${FeatureRoute.DetailQuestionFeature.FEATURE_NAME}/$questionIdsParam/$newIndex" + } + + Timber.tag("DetailQuestionFeature") + .d("Navigating to: $concretePath (parent: $parentPath)") + + navController.navigate(concretePath) +} + +/** + * Извлекает родительский путь из текущего маршрута. + * Например, из "questions/detail_question/{questionIds}/{currentIndex}" + * извлечет "questions" + */ +private fun extractParentPath(route: String): String { + if (route.isEmpty()) return "" + + // Удаляем параметры маршрута (все что после /) + val featureName = FeatureRoute.DetailQuestionFeature.FEATURE_NAME + val featureIndex = route.indexOf(featureName) + + return if (featureIndex > 0) { + // Возвращаем все до имени фичи detail_question (без последнего /) + route.substring(0, featureIndex - 1) + } else { + "" + } } \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionCommand.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionCommand.kt index 7870d0a4..0fd5dec9 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionCommand.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionCommand.kt @@ -3,4 +3,5 @@ package ru.yeahub.detail_question.impl.presentation.intents internal sealed class DetailQuestionCommand { data object NavigateBack : DetailQuestionCommand() data class OpenUrl(val url: String) : DetailQuestionCommand() + data class NavigateToQuestion(val newIndex: Int) : DetailQuestionCommand() } \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionEvent.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionEvent.kt index e6cbb684..fa0a549c 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionEvent.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionEvent.kt @@ -5,4 +5,6 @@ internal sealed class DetailQuestionEvent { data object OnBackClick : DetailQuestionEvent() data class OnTelegramClick(val url: String) : DetailQuestionEvent() data class OnYoutubeClick(val url: String) : DetailQuestionEvent() + data class OnPreviousQuestionClick(val currentQuestionId: Long) : DetailQuestionEvent() + data class OnNextQuestionClick(val currentQuestionId: Long) : DetailQuestionEvent() } \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionResult.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionResult.kt index 73b06bf9..31dd389a 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionResult.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/intents/DetailQuestionResult.kt @@ -3,4 +3,5 @@ package ru.yeahub.detail_question.impl.presentation.intents sealed class DetailQuestionResult { data object BackClick : DetailQuestionResult() data class UrlClick(val url: String) : DetailQuestionResult() + data class NavigateToQuestion(val newIndex: Int) : DetailQuestionResult() } \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt index b60de855..041af2e0 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt @@ -41,17 +41,24 @@ import ru.yeahub.detail_question.impl.presentation.viewmodel.viewModelCreator @Composable fun DetailQuestionScreen( onResult: (DetailQuestionResult) -> Unit, - questionId: Long + questionId: Long, + questionIds: List = emptyList(), + currentIndex: Int = 0 ) { val viewModel: DetailQuestionViewModel = koinViewModel() - LaunchedEffect(Unit) { + LaunchedEffect(questionId) { viewModel.handleEvents(DetailQuestionEvent.LoadQuestion(questionId)) } DetailQuestionScreenView( onBackClick = { viewModel.handleEvents(DetailQuestionEvent.OnBackClick) }, - viewModel = viewModel + viewModel = viewModel, + questionIds = questionIds, + currentIndex = currentIndex, + onNavigateToQuestion = { newIndex -> + onResult(DetailQuestionResult.NavigateToQuestion(newIndex)) + } ) HandleCommands(viewModel.commands, onResult) @@ -65,8 +72,11 @@ internal fun HandleCommands( LaunchedEffect(Unit) { commands.collect { command -> when (command) { - DetailQuestionCommand.NavigateBack -> onResult(DetailQuestionResult.BackClick) + is DetailQuestionCommand.NavigateBack -> onResult(DetailQuestionResult.BackClick) is DetailQuestionCommand.OpenUrl -> onResult(DetailQuestionResult.UrlClick(command.url)) + is DetailQuestionCommand.NavigateToQuestion -> onResult( + DetailQuestionResult.NavigateToQuestion(command.newIndex) + ) } } } @@ -76,10 +86,16 @@ internal fun HandleCommands( @Composable fun DetailQuestionScreenView( onBackClick: () -> Unit, - viewModel: DetailQuestionViewModel + viewModel: DetailQuestionViewModel, + questionIds: List = emptyList(), + currentIndex: Int = 0, + onNavigateToQuestion: (Int) -> Unit = {} ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() - Scaffold( + val hasPrevious = currentIndex > 0 + val hasNext = currentIndex < questionIds.size - 1 + + Scaffold( containerColor = Theme.colors.black25, topBar = { TopAppBarWithBottomBorder( @@ -109,6 +125,16 @@ fun DetailQuestionScreenView( ) } }, + onPreviousQuestionClick = { + if (hasPrevious) { + onNavigateToQuestion(currentIndex - 1) + } + }, + onNextQuestionClick = { + if (hasNext) { + onNavigateToQuestion(currentIndex + 1) + } + }, padding = padding ) } @@ -120,6 +146,8 @@ fun DetailQuestionScreenState( onBackClick: () -> Unit, onTelegramClick: () -> Unit, onYoutubeClick: () -> Unit, + onPreviousQuestionClick: () -> Unit, + onNextQuestionClick: () -> Unit, padding: PaddingValues ) { when (uiState) { @@ -128,6 +156,8 @@ fun DetailQuestionScreenState( uiState.data, onTelegramClick, onYoutubeClick, + onPreviousQuestionClick, + onNextQuestionClick, padding, TextOrResource.Resource(R.string.guru_description_text) ) @@ -256,7 +286,9 @@ fun StatesDetailQuestionPreview(params: DetailQuestionScreenStateParams) { padding = params.padding, onTelegramClick = {}, onYoutubeClick = {}, - onBackClick = {} + onBackClick = {}, + onPreviousQuestionClick = {}, + onNextQuestionClick = {} ) } diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/QuestionContent.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/QuestionContent.kt index 922de7c4..20369dc3 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/QuestionContent.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/QuestionContent.kt @@ -18,8 +18,10 @@ import androidx.compose.ui.unit.dp import ru.yeahub.core_ui.component.DetailHeaderQuestion import ru.yeahub.core_ui.component.DetailedQuestionAnswer import ru.yeahub.core_ui.component.DetailedQuestionAnswerBlock +import ru.yeahub.core_ui.component.FavoriteState import ru.yeahub.core_ui.component.GuruCard import ru.yeahub.core_ui.component.GuruData +import ru.yeahub.core_ui.component.PopoverQuestion import ru.yeahub.core_ui.component.ShortQuestionAnswer import ru.yeahub.core_ui.example.staticPreview.StaticPreview import ru.yeahub.core_utils.common.TextOrResource @@ -34,6 +36,8 @@ fun QuestionContent( question: DetailQuestionState.Success.PublicQuestionVO, onTelegramClick: () -> Unit, onYoutubeClick: () -> Unit, + onPreviousQuestionClick: () -> Unit, + onNextQuestionClick: () -> Unit, padding: PaddingValues, guruDescriptionText: TextOrResource ) { @@ -62,6 +66,18 @@ fun QuestionContent( ) } } + item { + PopoverQuestion( + onLearnClick = null, + onRepeatClick = null, + onFavoriteClick = null, + onPreviousClick = onPreviousQuestionClick, + onNextClick = onNextQuestionClick, + favoriteState = FavoriteState.DISABLED, + modifier = Modifier + .padding(start = 16.dp, end = 16.dp, bottom = 20.dp) + ) + } item { Box( modifier = Modifier @@ -374,6 +390,8 @@ fun StatesQuestionContentPreview(params: QuestionContentParams) { padding = params.padding, guruDescriptionText = TextOrResource.Text("Guru – это эксперты YeaHub, которые помогают развивать комьюнити."), onTelegramClick = {}, - onYoutubeClick = {} + onYoutubeClick = {}, + onPreviousQuestionClick = {}, + onNextQuestionClick = {} ) } \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/viewmodel/DetailQuestionViewModel.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/viewmodel/DetailQuestionViewModel.kt index 4163a742..9caff41a 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/viewmodel/DetailQuestionViewModel.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/viewmodel/DetailQuestionViewModel.kt @@ -26,9 +26,11 @@ class DetailQuestionViewModel( internal fun handleEvents(event: DetailQuestionEvent) { when (event) { is DetailQuestionEvent.LoadQuestion -> getQuestionById(event.id) - DetailQuestionEvent.OnBackClick -> handleBackClick() + is DetailQuestionEvent.OnBackClick -> handleBackClick() is DetailQuestionEvent.OnTelegramClick -> handleTelegramClick(event.url) is DetailQuestionEvent.OnYoutubeClick -> handleYoutubeClick(event.url) + is DetailQuestionEvent.OnPreviousQuestionClick -> handlePreviousQuestionClick(event.currentQuestionId) + is DetailQuestionEvent.OnNextQuestionClick -> handleNextQuestionClick(event.currentQuestionId) } } @@ -62,4 +64,18 @@ class DetailQuestionViewModel( _commands.emit(DetailQuestionCommand.OpenUrl(url)) } } + + private fun handlePreviousQuestionClick(currentQuestionId: Long) { + viewModelScopeSafe.launch { + val previousQuestionId = if (currentQuestionId > 1) currentQuestionId - 1 else currentQuestionId + _commands.emit(DetailQuestionCommand.NavigateToQuestion(previousQuestionId.toInt())) + } + } + + private fun handleNextQuestionClick(currentQuestionId: Long) { + viewModelScopeSafe.launch { + val nextQuestionId = currentQuestionId + 1 + _commands.emit(DetailQuestionCommand.NavigateToQuestion(nextQuestionId.toInt())) + } + } } \ No newline at end of file diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/PublicQuestionsFeatureImpl.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/PublicQuestionsFeatureImpl.kt index bbf7780b..c0920870 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/PublicQuestionsFeatureImpl.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/PublicQuestionsFeatureImpl.kt @@ -76,12 +76,13 @@ class PublicQuestionsFeatureImpl : FeatureApi { ) is PublicQuestionsResult.NavigateToDetail -> { - val detailRout = + val questionIdsParam = result.questionIds.joinToString(",") + val detailRoute = "$currentTabPrefix/" + FeatureRoute.DetailQuestionFeature - .FEATURE_NAME + "/" + result.id + .FEATURE_NAME + "/" + questionIdsParam + "/" + result.currentIndex Timber.tag("Test") - .d("PublicQuestionsFeatureImpl registerGraph: $detailRout") - navController.navigate(detailRout) + .d("PublicQuestionsFeatureImpl registerGraph: $detailRoute") + navController.navigate(detailRoute) } } }, @@ -90,7 +91,7 @@ class PublicQuestionsFeatureImpl : FeatureApi { idSpecialization = idSpecialization, ) Timber.tag("Test12") - .d(" Title - $tittleTopAppBar idColection - $idCollection idSpec - $idSpecialization") + .d(" Title - $tittleTopAppBar idCollection - $idCollection idSpec - $idSpecialization") } } diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsResult.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsResult.kt index 60f4f4f0..fdfefb1a 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsResult.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsResult.kt @@ -2,5 +2,8 @@ package ru.yeahub.public_questions.impl.presentation.intents sealed class PublicQuestionsResult { data object NavigateBack : PublicQuestionsResult() - data class NavigateToDetail(val id: String) : PublicQuestionsResult() + data class NavigateToDetail( + val questionIds: List, + val currentIndex: Int + ) : PublicQuestionsResult() } \ No newline at end of file diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenCommand.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenCommand.kt index a94c7774..926680fa 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenCommand.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenCommand.kt @@ -2,5 +2,8 @@ package ru.yeahub.public_questions.impl.presentation.intents sealed class PublicQuestionsScreenCommand { data object OnBackClick : PublicQuestionsScreenCommand() - data class OnMoreClick(val id: String) : PublicQuestionsScreenCommand() + data class OnMoreClick( + val questionIds: List, + val currentIndex: Int + ) : PublicQuestionsScreenCommand() } \ No newline at end of file diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenEvent.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenEvent.kt index d47b7609..ae735df0 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenEvent.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/intents/PublicQuestionsScreenEvent.kt @@ -16,7 +16,10 @@ sealed class PublicQuestionsScreenEvent { /** Клик по карточке вопроса(подробнее) */ - data class OnMoreClick(val id: String) : PublicQuestionsScreenEvent() + data class OnMoreClick( + val questionIds: List, + val currentIndex: Int + ) : PublicQuestionsScreenEvent() /** Клик назад */ diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/screen/PublicQuestionsScreen.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/screen/PublicQuestionsScreen.kt index 450f2450..a594427c 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/screen/PublicQuestionsScreen.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/screen/PublicQuestionsScreen.kt @@ -117,10 +117,11 @@ fun PublicQuestionsScreen( listState = lazyListState, onRetryLoadInitial = { viewModel.onEvent(PublicQuestionsScreenEvent.LoadInitial) }, nameQuestions = tittleTopAppBar, - onMoreCLick = { id -> + onMoreCLick = { questionIds, currentIndex -> viewModel.onEvent( PublicQuestionsScreenEvent.OnMoreClick( - id = id + questionIds = questionIds, + currentIndex = currentIndex ) ) } @@ -140,7 +141,12 @@ fun HandlePublicQuestionsCommand( .collect { command -> when (command) { is PublicQuestionsScreenCommand.OnMoreClick -> { - onResult(PublicQuestionsResult.NavigateToDetail(command.id)) + onResult( + PublicQuestionsResult.NavigateToDetail( + questionIds = command.questionIds, + currentIndex = command.currentIndex + ) + ) } PublicQuestionsScreenCommand.OnBackClick -> { @@ -156,7 +162,7 @@ private fun PublicQuestionsContent( modifier: Modifier = Modifier, padding: PaddingValues, nameQuestions: String, - onMoreCLick: (id: String) -> Unit, + onMoreCLick: (questionIds: List, currentIndex: Int) -> Unit, screenState: PublicQuestionsScreenState, listState: LazyListState, onRetryLoadInitial: () -> Unit, @@ -179,6 +185,7 @@ private fun PublicQuestionsContent( onRetry = onRetryLoadInitial ) } else { + val questionIds = screenState.questions.map { it.id } QuestionsListWithFooter( padding = padding, listState = listState, @@ -188,7 +195,7 @@ private fun PublicQuestionsContent( paginationError = screenState.throwable, onRetryPagination = { onRetryLoadInitial() }, nameQuestion = nameQuestions, - onMoreCLick = { id -> onMoreCLick(id) } + onMoreCLick = { currentIndex -> onMoreCLick(questionIds, currentIndex) } ) } } @@ -199,6 +206,7 @@ private fun PublicQuestionsContent( ) { EmptyState() } else { + val questionIds = screenState.questions.map { it.id } QuestionsListWithFooter( padding = padding, listState = listState, @@ -208,7 +216,7 @@ private fun PublicQuestionsContent( paginationError = null, onRetryPagination = { onRetryLoadInitial() }, nameQuestion = nameQuestions, - onMoreCLick = { id -> onMoreCLick(id) }, + onMoreCLick = { currentIndex -> onMoreCLick(questionIds, currentIndex) }, ) } } @@ -268,7 +276,7 @@ private fun QuestionsListWithFooter( isEndReached: Boolean, isLoadingNextPage: Boolean, paginationError: Throwable?, - onMoreCLick: (id: String) -> Unit, + onMoreCLick: (currentIndex: Int) -> Unit, onRetryPagination: () -> Unit, ) { LazyColumn( @@ -291,9 +299,10 @@ private fun QuestionsListWithFooter( items = questions, key = { question -> question.id } ) { question -> + val currentIndex = questions.indexOf(question) PublicQuestionsItem( questions = question, - onClickMore = { id -> onMoreCLick(id) } + onClickMore = { onMoreCLick(currentIndex) } ) } } diff --git a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/viewmodel/PublicQuestionsViewModel.kt b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/viewmodel/PublicQuestionsViewModel.kt index b66b1e5e..7aefa2a9 100644 --- a/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/viewmodel/PublicQuestionsViewModel.kt +++ b/feature/public-questions/impl/src/main/java/ru/yeahub/public_questions/impl/presentation/viewmodel/PublicQuestionsViewModel.kt @@ -109,7 +109,10 @@ class PublicQuestionsViewModel( is PublicQuestionsScreenEvent.LoadInitial -> loadInitial() is PublicQuestionsScreenEvent.LoadNextPage -> loadNextPage() is PublicQuestionsScreenEvent.Refresh -> refresh() - is PublicQuestionsScreenEvent.OnMoreClick -> onMoreClick(event.id) + is PublicQuestionsScreenEvent.OnMoreClick -> onMoreClick( + event.questionIds, + event.currentIndex + ) is PublicQuestionsScreenEvent.OnBackClick -> onBackClick() } } @@ -137,9 +140,9 @@ class PublicQuestionsViewModel( } } - private fun onMoreClick(id: String) { + private fun onMoreClick(questionIds: List, currentIndex: Int) { viewModelScopeSafe.launch(Dispatchers.IO) { - _commandState.emit(PublicQuestionsScreenCommand.OnMoreClick(id)) + _commandState.emit(PublicQuestionsScreenCommand.OnMoreClick(questionIds, currentIndex)) } } From f517e29d6a49ff03375452e81c1b7ad558f16483 Mon Sep 17 00:00:00 2001 From: 2olka Date: Fri, 5 Dec 2025 17:41:13 +0500 Subject: [PATCH 2/4] =?UTF-8?q?ANDR-28:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BA=D0=BE=D1=80=D1=80=D0=B5=D0=BA?= =?UTF-8?q?=D1=82=D0=BD=D0=B0=D1=8F=20=D0=BD=D0=B0=D0=B2=D0=B8=D0=B3=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BA=D0=BD=D0=BE=D0=BF?= =?UTF-8?q?=D0=BA=D0=B5=20"=D0=BD=D0=B0=D0=B7=D0=B0=D0=B4"=20=D0=B2=20?= =?UTF-8?q?=D0=A2=D0=BE=D0=BF=D0=90=D0=BF=D0=91=D0=B0=D1=80=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/DetailQuestionFeatureImpl.kt | 36 +++++++++---------- .../PublicCollectionsFeatureImpl.kt | 2 -- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt index 45951e83..7b8b0e68 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/DetailQuestionFeatureImpl.kt @@ -55,10 +55,7 @@ class DetailQuestionFeatureImpl : FeatureApi { DetailQuestionScreen( onResult = { result -> when (result) { - is DetailQuestionResult.BackClick -> handleBackNavigation( - pathManager, - navController - ) + is DetailQuestionResult.BackClick -> handleBackNavigation(navController) is DetailQuestionResult.UrlClick -> { val intent = Intent(Intent.ACTION_VIEW, result.url.toUri()) @@ -82,21 +79,12 @@ class DetailQuestionFeatureImpl : FeatureApi { } private fun handleBackNavigation( - pathManager: NavigationPathManager, navController: NavHostController ) { - val parentPath = pathManager.getParentPath() - pathManager.setCurrentPath(parentPath) - - if (parentPath.isEmpty()) { - navController.navigateUp() - } else { - navController.navigate(parentPath) { - popUpTo(parentPath) { - inclusive = true - } - } - } + // Используем navigateUp для возврата на предыдущий экран (список вопросов) + Timber.tag("DetailQuestion") + .d("handleBackNavigation: Using navigateUp to return to questions list") + navController.navigateUp() } private fun handleQuestionNavigation( @@ -115,7 +103,19 @@ private fun handleQuestionNavigation( Timber.tag("DetailQuestionFeature") .d("Navigating to: $concretePath (parent: $parentPath)") - navController.navigate(concretePath) + // Получаем текущий маршрут из стека для popUpTo + val currentRoute = navController.currentBackStackEntry?.destination?.route + + navController.navigate(concretePath) { + // Удаляем текущий экран детального вопроса из стека + if (currentRoute != null) { + popUpTo(currentRoute) { + inclusive = true + } + } + // Предотвращаем создание нескольких копий одного экрана + launchSingleTop = true + } } /** diff --git a/feature/public-collections/impl/src/main/java/ru/yeahub/public_collections/PublicCollectionsFeatureImpl.kt b/feature/public-collections/impl/src/main/java/ru/yeahub/public_collections/PublicCollectionsFeatureImpl.kt index cdd72e96..b570baab 100644 --- a/feature/public-collections/impl/src/main/java/ru/yeahub/public_collections/PublicCollectionsFeatureImpl.kt +++ b/feature/public-collections/impl/src/main/java/ru/yeahub/public_collections/PublicCollectionsFeatureImpl.kt @@ -48,7 +48,6 @@ class PublicCollectionsFeatureImpl : FeatureApi { ) is PublicCollectionsScreenResult.NavigateToQuestions -> handleQuestionsNavigation( - pathManager, navController, result.collectionId.toString(), result.title @@ -62,7 +61,6 @@ class PublicCollectionsFeatureImpl : FeatureApi { } private fun handleQuestionsNavigation( - pathManager: NavigationPathManager, navController: NavHostController, collectionId: String, title: String From dc4e4d3794dbad227e869644cf3b71365a7f682c Mon Sep 17 00:00:00 2001 From: 2olka Date: Wed, 4 Feb 2026 22:14:31 +0500 Subject: [PATCH 3/4] =?UTF-8?q?ANDR-28:=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 6 +++++- .../impl/presentation/view/DetailQuestionScreen.kt | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8a..9cb8c8df 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,10 @@ - + + + + + \ No newline at end of file diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt index 041af2e0..62023dc4 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt @@ -42,7 +42,7 @@ import ru.yeahub.detail_question.impl.presentation.viewmodel.viewModelCreator fun DetailQuestionScreen( onResult: (DetailQuestionResult) -> Unit, questionId: Long, - questionIds: List = emptyList(), + questionIds: List, currentIndex: Int = 0 ) { val viewModel: DetailQuestionViewModel = koinViewModel() @@ -87,7 +87,7 @@ internal fun HandleCommands( fun DetailQuestionScreenView( onBackClick: () -> Unit, viewModel: DetailQuestionViewModel, - questionIds: List = emptyList(), + questionIds: List, currentIndex: Int = 0, onNavigateToQuestion: (Int) -> Unit = {} ) { @@ -398,5 +398,6 @@ fun DetailQuestionScreenDynamicPreview() { DetailQuestionScreenView( onBackClick = {}, viewModel = mockViewModel, + questionIds = emptyList() ) } \ No newline at end of file From 0b2daea772557fda007c4ceeae06663fff847c9b Mon Sep 17 00:00:00 2001 From: 2olka Date: Thu, 5 Feb 2026 13:27:00 +0500 Subject: [PATCH 4/4] =?UTF-8?q?ANDR-28:=20=D0=9F=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 3 +++ .../impl/presentation/view/DetailQuestionScreen.kt | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 9cb8c8df..357fd146 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -2,6 +2,9 @@ + + + diff --git a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt index bf0d6574..7c53d902 100644 --- a/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt +++ b/feature/detail-question/impl/src/main/java/ru/yeahub/detail_question/impl/presentation/view/DetailQuestionScreen.kt @@ -100,7 +100,6 @@ fun DetailQuestionScreenView( val uiState by viewModel.uiState.collectAsStateWithLifecycle() val hasPrevious = currentIndex > 0 val hasNext = currentIndex < questionIds.size - 1 - val configuration = LocalConfiguration.current val isLandscape = configuration.orientation == Configuration.ORIENTATION_LANDSCAPE Scaffold( @@ -163,7 +162,6 @@ fun DetailQuestionScreenView( onNavigateToQuestion(currentIndex + 1) } }, - padding = PaddingValues( top = paddingValues.calculateTopPadding() )