Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
cd737ef
Создан модуль Interview_Trainer
PanMobile Jan 8, 2026
95a8631
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
742d39e
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
efed7b2
Добавление базовых классов фичи
PanMobile Jan 8, 2026
68e7927
Базовая верстка первого экрана CreateQuizScreen.kt
PanMobile Jan 8, 2026
7acdad3
Добавление объекта интервью тренажера в пути фич для будущей навигации
PanMobile Jan 8, 2026
a49296b
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
0a2cec3
ANDR-5: SkillButton.kt компонент изменен. Убрана полная заливка кнопк…
PanMobile Jan 10, 2026
54d700b
ANDR-5: Добавлены дополнительные строковые ресурсы для возможных ошибок
PanMobile Jan 11, 2026
f8b2d96
ANDR-5: Создание превью и правки по отступам
PanMobile Jan 11, 2026
b96cd8a
ANDR-5: Экран загрузки CreateQuiz
PanMobile Jan 11, 2026
00394a1
ANDR-5: Использование экрана загрузки в главном для @StaticPreview
PanMobile Jan 11, 2026
1499028
ANDR-5: Удалены неиспользуемые строки ошибок
PanMobile Jan 11, 2026
2ed9317
ANDR-5: Убран лишний класс параметров. В StaticPreview передаем сразу…
PanMobile Jan 12, 2026
1a8ac42
ANDR-5: Убрана преписка Mock у @Composable
PanMobile Jan 16, 2026
8eb8ae0
ANDR-5: id стало Long по аналогии с другими классами
PanMobile Jan 16, 2026
3e69cfa
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
1fef1a4
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
635231a
ANDR-5: Созданы Domain модели
PanMobile Jan 17, 2026
0392640
ANDR-5: ВьюМоделька экрана CreateQuiz. Сделана не до конца
PanMobile Jan 17, 2026
04978c4
ANDR-5: Изменение кол-ва вопросов через данные у ивента
PanMobile Jan 17, 2026
6d1237f
ANDR-5: изменил путь файла
PanMobile Jan 17, 2026
1eaa176
ANDR-5: Изменение кода экрана. Настроено правильное прокидывание лямб…
PanMobile Jan 17, 2026
1eb6051
ANDR-5: Сделано Динамическое превью
PanMobile Jan 17, 2026
41f25a7
ANDR-5: убраны default параметры
PanMobile Jan 19, 2026
a4396ca
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
59e9c7f
ANDR-5: Создан маппер
PanMobile Jan 19, 2026
0d7468d
ANDR-5: имплементирован маппер и отдельный флоу ввода пользователя дл…
PanMobile Jan 19, 2026
df6d2ad
ANDR-5: сделано рабочее динамик превью
PanMobile Jan 19, 2026
34863b1
ANDR-5: убран default диспатчер при обновлении ввода пользователя
PanMobile Jan 19, 2026
0c5b94b
ANDR-5: убраны параметры по умолчанию в верстке
PanMobile Jan 19, 2026
8674fae
ANDR-55 добавлен экран тренировки и класс состояний тренировки
Deyryl Jan 23, 2026
67535fc
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
f3f6b8c
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
87b922d
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
f66fd53
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
028cf6c
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
81811e8
ANDR-5: Созданы Domain модели
PanMobile Jan 17, 2026
331dc21
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
f6559d6
ANDR-55 добавлен экран тренировки и класс состояний тренировки
Deyryl Jan 23, 2026
20fa947
ANDR-55: добавление иконок
Deyryl Jan 24, 2026
7092807
ANDR-55: верстка экрана, добавление в QuizState enum class, создание …
Deyryl Jan 24, 2026
75d0b2a
Merge remote-tracking branch 'origin/feature/ANDR-55' into feature/AN…
Deyryl Jan 28, 2026
0b1a33d
ANDR-55: добавление строк для экрана тренажера
Deyryl Jan 28, 2026
2525793
ANDR-55: добавление LoadingScreen
Deyryl Jan 29, 2026
4cd3c41
ANDR-55: добавление Command, Event, ScreenMapper, State
Deyryl Jan 30, 2026
f715c43
ANDR-55: обновление string ресурсов
Deyryl Jan 30, 2026
32835c5
ANDR-55: создание и написание ViewModel
Deyryl Jan 30, 2026
27bd39f
ANDR-55: окончательная верстка. Создание динамического превью. Добавл…
Deyryl Jan 30, 2026
137c676
ANDR-55: увеличение длины ответа для данных превью
Deyryl Jan 30, 2026
e332c17
ANDR-55: рефакторинг. Кнопка Проверить результат м.б. неактивной
Deyryl Jan 30, 2026
16f211a
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
2b6f741
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
899e4e4
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
b2b790a
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
bda2c30
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
a2f427e
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
f16904f
ANDR-55 добавлен экран тренировки и класс состояний тренировки
Deyryl Jan 23, 2026
bb86320
ANDR-55: добавление иконок
Deyryl Jan 24, 2026
c1e303a
ANDR-55: верстка экрана, добавление в QuizState enum class, создание …
Deyryl Jan 24, 2026
32c8def
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
bb9cd66
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
4e9b78b
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
7d9ad90
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
016a98a
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
9be8a3a
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
1c37828
ANDR-55: добавление строк для экрана тренажера
Deyryl Jan 28, 2026
1729b9e
ANDR-55: добавление LoadingScreen
Deyryl Jan 29, 2026
fe13bee
ANDR-55: добавление Command, Event, ScreenMapper, State
Deyryl Jan 30, 2026
bb326f0
ANDR-55: обновление string ресурсов
Deyryl Jan 30, 2026
f2feafa
ANDR-55: создание и написание ViewModel
Deyryl Jan 30, 2026
0083995
ANDR-55: окончательная верстка. Создание динамического превью. Добавл…
Deyryl Jan 30, 2026
1f2604c
ANDR-55: увеличение длины ответа для данных превью
Deyryl Jan 30, 2026
e43851a
ANDR-55: рефакторинг. Кнопка Проверить результат м.б. неактивной
Deyryl Jan 30, 2026
63eca4f
ANDR-55: удаление превью из LoadingScreen
Deyryl Jan 30, 2026
f0b99aa
Merge remote-tracking branch 'origin/feature/ANDR-55' into feature/AN…
Deyryl Feb 4, 2026
77c6568
ANDR-58: из Command и Event наследники заменены на ToDo
Deyryl Feb 4, 2026
6d61ef1
ANDR-58: рефакторинг QuizScreen и QuizScreenLoading
Deyryl Feb 4, 2026
25b604d
[ANDR-83] Дополнения по Compose (#103)
PanMobile Feb 5, 2026
35b92b2
ANDR-48: Authentication — модули api/impl и экран регистрации (#104)
xMODDIIx Feb 8, 2026
52e9d68
ANDR-5: Инициализация фичи Interview Trainer и верстка первого экрана…
PanMobile Jan 25, 2026
e472c82
ANDR-5: CreateQuiz второй этап. Data + Domain (#95)
PanMobile Jan 30, 2026
f466087
[ANDR-54] ANDR-70: Третий этап CreateQuizScreen. Логика + Тесты (#100)
PanMobile Feb 2, 2026
ab5d30f
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
69669e1
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
c4124c7
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
360a2e4
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
5255e7a
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
8ad8d5e
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
e8ad011
ANDR-55 добавлен экран тренировки и класс состояний тренировки
Deyryl Jan 23, 2026
1f26151
ANDR-55: добавление иконок
Deyryl Jan 24, 2026
64ca47c
ANDR-55: верстка экрана, добавление в QuizState enum class, создание …
Deyryl Jan 24, 2026
18225aa
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
ee451b8
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
52d2437
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
caebd34
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
256f2ff
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
1a9ed51
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
7db2f87
ANDR-55: добавление строк для экрана тренажера
Deyryl Jan 28, 2026
12cf082
ANDR-55: добавление LoadingScreen
Deyryl Jan 29, 2026
fe72f9e
ANDR-55: добавление Command, Event, ScreenMapper, State
Deyryl Jan 30, 2026
eb974ba
ANDR-55: обновление string ресурсов
Deyryl Jan 30, 2026
5c32c50
ANDR-55: создание и написание ViewModel
Deyryl Jan 30, 2026
b50a548
ANDR-55: окончательная верстка. Создание динамического превью. Добавл…
Deyryl Jan 30, 2026
ced00b6
ANDR-55: увеличение длины ответа для данных превью
Deyryl Jan 30, 2026
03de904
ANDR-55: рефакторинг. Кнопка Проверить результат м.б. неактивной
Deyryl Jan 30, 2026
0f5bf66
ANDR-55: удаление превью из LoadingScreen
Deyryl Jan 30, 2026
85fcd30
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
b9ebe7c
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
dea8624
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
c32ff79
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
cd6fc0f
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
df44608
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
9f0260b
Моделирование состояний первого экрана интервью тренажера - CreateQuiz
PanMobile Jan 8, 2026
084f366
Добавление необходимых ресурсов для верстки первого экрана экрана Cre…
PanMobile Jan 8, 2026
1580396
ANDR-5: VoSpecialization перенесен внутри Loaded
PanMobile Jan 10, 2026
408977c
ANDR-5: Command'ы и Result'ы убраны из папки intents. Сама папка удалена
PanMobile Jan 17, 2026
191d08d
ANDR-5: Создан интерфейс юзкейса
PanMobile Jan 17, 2026
0ebcde6
ANDR-5: убраны лишние классы
PanMobile Jan 19, 2026
eede3d3
ANDR-58: из Command и Event наследники заменены на ToDo
Deyryl Feb 4, 2026
34ecf16
ANDR-58: рефакторинг QuizScreen и QuizScreenLoading
Deyryl Feb 4, 2026
b6ae94a
Merge remote-tracking branch 'origin/feature/ANDR-55' into feature/AN…
Deyryl Feb 9, 2026
54ac7fe
ANDR-58: подключение immutable библиотеки
Deyryl Feb 9, 2026
bb7a39b
ANDR-58: В стейте Loaded изменение коллекций на Persistent
Deyryl Feb 9, 2026
af560a4
ANDR-58: изменение под Persistent коллекции стейта
Deyryl Feb 9, 2026
528c17d
ANDR-58: добавление static preview
Deyryl Feb 9, 2026
29a2e2e
ANDR-58: убраны лишние файлы для epic
Deyryl Feb 9, 2026
76db7e5
ANDR-58: убраны лишние строки для epic
Deyryl Feb 9, 2026
8a0f7e9
ANDR-58: удаление лишнего изменения settings.gradle.kts
Deyryl Feb 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions feature/interview-trainer/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
implementation(libs.androidx.runtime.android)

implementation(libs.compose.shimmer)
implementation(libs.immutable.collections)

//KOIN
implementation(libs.koin.core)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.yeahub.interview_trainer.impl.interviewQuiz.presentation

sealed interface InterviewQuizCommand {

data object ToDo : InterviewQuizCommand
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package ru.yeahub.interview_trainer.impl.interviewQuiz.presentation

sealed interface InterviewQuizEvent {

data object ToDo : InterviewQuizEvent
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ru.yeahub.interview_trainer.impl.interviewQuiz.presentation

import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.PersistentMap

class InterviewQuizScreenMapper {

fun getScreenState(
questions: PersistentList<InterviewQuizState.Loaded.VoQuestion>,
questionIndex: Int,
isAnswerVisible: Boolean,
answers: PersistentMap<Long, InterviewQuizState.Loaded.QuizAnswer>,
selectedAnswer: InterviewQuizState.Loaded.QuizAnswer
): InterviewQuizState {
val canGoNext = answers.containsKey(questions[questionIndex].id) &&
questionIndex != questions.lastIndex

val canGoPrev = questionIndex > 0

val question = questions[questionIndex]

val questionsCount = questions.size

val isLastQuestion = questionIndex != questions.lastIndex

return InterviewQuizState.Loaded(
questions = questions,
questionsCount = questionsCount,
questionIndex = questionIndex,
question = question,
isAnswerVisible = isAnswerVisible,
answers = answers,
canGoNext = canGoNext,
canGoPrev = canGoPrev,
selectedAnswer = selectedAnswer,
isLastQuestion = isLastQuestion
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ru.yeahub.interview_trainer.impl.interviewQuiz.presentation

import androidx.compose.runtime.Immutable
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.PersistentMap

sealed interface InterviewQuizState {

/** Изначальное состояние */
data object Loading : InterviewQuizState

@Immutable
data class Loaded(
val questions: PersistentList<VoQuestion>,
val questionsCount: Int,
val questionIndex: Int,
val question: VoQuestion,
val isAnswerVisible: Boolean,
val answers: PersistentMap<Long, QuizAnswer>,
val canGoPrev: Boolean,
val canGoNext: Boolean,
val selectedAnswer: QuizAnswer,
val isLastQuestion: Boolean
) : InterviewQuizState {

enum class QuizAnswer { KNOWN, UNKNOWN, NONE }

@Immutable
data class VoQuestion(
val id: Long,
val title: String,
val shortAnswer: String
)
}

data class Error(val throwable: Throwable) : InterviewQuizState
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package ru.yeahub.interview_trainer.impl.interviewQuiz.presentation

import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import ru.yeahub.core_utils.BaseViewModel
import ru.yeahub.interview_trainer.impl.interviewQuiz.presentation.InterviewQuizState.Loaded.QuizAnswer
import ru.yeahub.interview_trainer.impl.interviewQuiz.presentation.InterviewQuizState.Loaded.VoQuestion

open class InterviewQuizViewModel(
private val screenMapper: InterviewQuizScreenMapper
) : BaseViewModel() {

// Вопросы для превью. Временно
private val previewQuestions by lazy {
previewQuestions()
}

private val userInputState = MutableStateFlow(
UserInput(
isAnswerVisible = false,
answers = persistentMapOf(),
selectedAnswer = QuizAnswer.NONE
)
)

val screenState = userInputState
.map { userInput ->
screenMapper.getScreenState(
questions = previewQuestions,
questionIndex = FIRST_QUESTION_INDEX,
isAnswerVisible = userInput.isAnswerVisible,
answers = userInput.answers,
selectedAnswer = userInput.selectedAnswer
)
}.stateIn(
scope = viewModelScopeSafe,
started = SharingStarted.WhileSubscribed(TIME_TO_CLEAN_UP_RESOURCES),
initialValue = InterviewQuizState.Loading
)

private val _commands = MutableSharedFlow<InterviewQuizCommand>()
val commands = _commands.asSharedFlow()

fun onEvent(event: InterviewQuizEvent) {
when (event) {
InterviewQuizEvent.ToDo -> { /* TODO */ }
}
}

/** Создание списка вопросов для тестирования превью */
@Suppress("MagicNumber")
private fun previewQuestions(): PersistentList<VoQuestion> {
val shortAnswer = "Виртуальный DOM (VDOM) — это легковесное " +
"представление реального DOM в памяти, которое используется в " +
"JavaScript-библиотеках, таких как React и Vue, " +
"для повышения производительности веб-приложений."

val base = VoQuestion(
id = 0,
title = "Что такое Virtual DOM, и как он работает?",
shortAnswer = shortAnswer
)
val questions = mutableListOf<VoQuestion>()
repeat(10) { index ->
questions.add(base.copy(id = index.toLong()))
}

return questions.toPersistentList()
}

private data class UserInput(
val isAnswerVisible: Boolean,
val answers: PersistentMap<Long, QuizAnswer>,
val selectedAnswer: QuizAnswer
)

companion object {

private const val TIME_TO_CLEAN_UP_RESOURCES = 5000L

private const val FIRST_QUESTION_INDEX = 0
}
}
Loading