From 9fe731e14fe7184d478a21b95caff1cee1fbcc6d Mon Sep 17 00:00:00 2001 From: Nguyen Quang Minh Date: Sun, 1 Dec 2024 01:04:01 +0700 Subject: [PATCH] =?UTF-8?q?fix(learn):=20s=E1=BB=ADa=20l=E1=BB=97i=20giao?= =?UTF-8?q?=20di=E1=BB=87n=20m=C3=A0n=20finish?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../detail/material/MaterialTabScreen.kt | 3 +- .../studies/component/FlipFlashCardFinish.kt | 256 --------------- .../studies/flip/FlipFlashCardScreen.kt | 10 +- .../component/FlipFlashCardButton.kt | 2 +- .../flip/component/FlipFlashCardFinish.kt | 269 ++++++++++++++++ .../component/FlipFlashCardIconButton.kt | 2 +- .../component/FlipFlashCardStatusRow.kt | 2 +- .../{ => flip}/component/StudyFlipCard.kt | 2 +- .../quiz/component/QuizFlashCardFinish.kt | 15 +- .../component/TrueFalseFlashcardFinish.kt | 14 +- .../studies/write/LearnByWriteScreen.kt | 296 +++++++++--------- .../write/component/WriteFlashcardFinish.kt | 15 +- app/src/main/res/drawable/ic_card.xml | 2 +- app/src/main/res/values-vi/strings.xml | 7 +- app/src/main/res/values/strings.xml | 1 + 15 files changed, 454 insertions(+), 442 deletions(-) delete mode 100644 app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardFinish.kt rename app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/{ => flip}/component/FlipFlashCardButton.kt (95%) create mode 100644 app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardFinish.kt rename app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/{ => flip}/component/FlipFlashCardIconButton.kt (92%) rename app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/{ => flip}/component/FlipFlashCardStatusRow.kt (98%) rename app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/{ => flip}/component/StudyFlipCard.kt (99%) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/MaterialTabScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/MaterialTabScreen.kt index 00109407..cce18f84 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/MaterialTabScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/detail/material/MaterialTabScreen.kt @@ -99,7 +99,8 @@ fun MaterialTabScreen( when { flashCards.isEmpty() -> { Column( - horizontalAlignment = CenterHorizontally + horizontalAlignment = CenterHorizontally, + modifier = Modifier.padding(16.dp) ) { Text( text = stringResource(R.string.txt_add_your_material_to_get_started), diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardFinish.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardFinish.kt deleted file mode 100644 index 71c22bf7..00000000 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardFinish.kt +++ /dev/null @@ -1,256 +0,0 @@ -package com.pwhs.quickmem.presentation.app.study_set.studies.component - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.AccessTime -import androidx.compose.material3.Button -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.zIndex -import com.airbnb.lottie.compose.LottieAnimation -import com.airbnb.lottie.compose.LottieCompositionSpec -import com.airbnb.lottie.compose.animateLottieCompositionAsState -import com.airbnb.lottie.compose.rememberLottieComposition -import com.pwhs.quickmem.R -import com.pwhs.quickmem.presentation.app.study_set.detail.progress.StudySetDonutChart -import com.pwhs.quickmem.util.toStringTime -import timber.log.Timber - -@Composable -fun FlipFlashCardFinish( - modifier: Modifier = Modifier, - isEndOfList: Boolean, - countStillLearning: Int, - countKnown: Int, - studySetColor: Color, - flashCardSize: Int, - learningTime: Long, - onContinueLearningClicked: () -> Unit, - onRestartClicked: () -> Unit, -) { - val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.confetti)) - val progress by animateLottieCompositionAsState( - composition = composition, - isPlaying = isEndOfList, - ) - Box( - modifier = modifier.fillMaxSize(), - contentAlignment = Alignment.Center - ) { - LottieAnimation( - composition = composition, - progress = { progress }, - modifier = Modifier - .fillMaxSize() - .zIndex(2f) - ) - Column( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - .padding(top = 20.dp) - .padding(16.dp) - ) { - Text( - text = "You're doing great!", - style = MaterialTheme.typography.titleLarge.copy( - fontWeight = FontWeight.Bold - ) - ) - StudySetDonutChart( - modifier = Modifier - .size(200.dp) - .padding(16.dp), - studySetsStillLearn = countStillLearning, - studySetsMastered = countKnown, - color = studySetColor - ) - - Text( - text = "Keep focusing on your study set to master it!", - style = MaterialTheme.typography.bodyMedium.copy( - fontWeight = FontWeight.Bold - ), - modifier = Modifier.padding(16.dp) - ) - - Card( - onClick = {}, - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 16.dp), - colors = CardDefaults.cardColors( - containerColor = Color.White - ), - border = BorderStroke(1.dp, studySetColor), - elevation = CardDefaults.cardElevation( - defaultElevation = 3.dp, - ) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Image( - painter = painterResource(id = R.drawable.ic_card), - contentDescription = "Card", - contentScale = ContentScale.Crop - ) - Text( - text = "Flashcards learned", - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = 18.sp - ), - modifier = Modifier - .weight(1f) - .padding( - start = 8.dp, - end = 16.dp - ), - textAlign = TextAlign.Start, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Text( - text = buildAnnotatedString { - withStyle( - style = SpanStyle( - fontWeight = FontWeight.Bold - ) - ) { - append(countKnown.toString()) - } - append("/${flashCardSize}") - }, - fontSize = 18.sp, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.padding(8.dp) - ) - } - } - Card( - onClick = {}, - modifier = Modifier.fillMaxWidth(), - colors = CardDefaults.cardColors( - containerColor = Color.White - ), - border = BorderStroke(1.dp, studySetColor), - elevation = CardDefaults.cardElevation( - defaultElevation = 3.dp, - ) - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - ) { - Image( - imageVector = Icons.Default.AccessTime, - contentDescription = "Time", - ) - Text( - text = "Learning Time", - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = 18.sp - ), - modifier = Modifier - .weight(1f) - .padding( - start = 8.dp, - end = 16.dp - ), - textAlign = TextAlign.Start, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - Timber.d("toStringTime learningTime: ${learningTime.toStringTime()}") - Text( - text = learningTime.toStringTime(), - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = 18.sp, - fontWeight = FontWeight.Bold - ), - modifier = Modifier.padding(8.dp) - ) - } - } - if (countStillLearning > 0) { - Button( - onClick = { - onContinueLearningClicked() - }, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - shape = MaterialTheme.shapes.small, - colors = ButtonDefaults.buttonColors( - containerColor = studySetColor, - contentColor = Color.White - ), - border = BorderStroke(1.dp, studySetColor) - ) { - Text( - text = "Keep reviewing $countStillLearning terms", - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = 18.sp, - fontWeight = FontWeight.Bold - ), - modifier = Modifier.padding(8.dp) - ) - } - } - Button( - onClick = { - onRestartClicked() - }, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp), - shape = MaterialTheme.shapes.small, - colors = ButtonDefaults.buttonColors( - containerColor = Color.Transparent, - contentColor = studySetColor - ), - border = BorderStroke(1.dp, studySetColor) - ) { - Text( - text = "Restart Flashcards", - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = 18.sp, - fontWeight = FontWeight.Bold - ), - modifier = Modifier.padding(8.dp) - ) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/FlipFlashCardScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/FlipFlashCardScreen.kt index 6332dc4d..614b9363 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/FlipFlashCardScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/FlipFlashCardScreen.kt @@ -43,11 +43,11 @@ import com.msusman.compose.cardstack.SwipeMethod import com.msusman.compose.cardstack.rememberStackState import com.pwhs.quickmem.domain.model.flashcard.FlashCardResponseModel import com.pwhs.quickmem.presentation.app.study_set.component.StudyCardBottomSheet -import com.pwhs.quickmem.presentation.app.study_set.studies.component.FlipFlashCardButton -import com.pwhs.quickmem.presentation.app.study_set.studies.component.FlipFlashCardFinish -import com.pwhs.quickmem.presentation.app.study_set.studies.component.FlipFlashCardIconButton -import com.pwhs.quickmem.presentation.app.study_set.studies.component.FlipFlashCardStatusRow -import com.pwhs.quickmem.presentation.app.study_set.studies.component.StudyFlipFlashCard +import com.pwhs.quickmem.presentation.app.study_set.studies.flip.component.FlipFlashCardButton +import com.pwhs.quickmem.presentation.app.study_set.studies.flip.component.FlipFlashCardFinish +import com.pwhs.quickmem.presentation.app.study_set.studies.flip.component.FlipFlashCardIconButton +import com.pwhs.quickmem.presentation.app.study_set.studies.flip.component.FlipFlashCardStatusRow +import com.pwhs.quickmem.presentation.app.study_set.studies.flip.component.StudyFlipFlashCard import com.pwhs.quickmem.presentation.app.study_set.studies.component.StudyTopAppBar import com.pwhs.quickmem.presentation.component.LoadingOverlay import com.pwhs.quickmem.ui.theme.QuickMemTheme diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardButton.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardButton.kt similarity index 95% rename from app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardButton.kt rename to app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardButton.kt index 8f71e2a8..07c487ec 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardButton.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardButton.kt @@ -1,4 +1,4 @@ -package com.pwhs.quickmem.presentation.app.study_set.studies.component +package com.pwhs.quickmem.presentation.app.study_set.studies.flip.component import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Arrangement diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardFinish.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardFinish.kt new file mode 100644 index 00000000..2fc29208 --- /dev/null +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardFinish.kt @@ -0,0 +1,269 @@ +package com.pwhs.quickmem.presentation.app.study_set.studies.flip.component + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccessTime +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.zIndex +import com.airbnb.lottie.compose.LottieAnimation +import com.airbnb.lottie.compose.LottieCompositionSpec +import com.airbnb.lottie.compose.animateLottieCompositionAsState +import com.airbnb.lottie.compose.rememberLottieComposition +import com.pwhs.quickmem.R +import com.pwhs.quickmem.presentation.app.study_set.detail.progress.StudySetDonutChart +import com.pwhs.quickmem.util.toStringTime +import timber.log.Timber + +@Composable +fun FlipFlashCardFinish( + modifier: Modifier = Modifier, + isEndOfList: Boolean, + countStillLearning: Int, + countKnown: Int, + studySetColor: Color, + flashCardSize: Int, + learningTime: Long, + onContinueLearningClicked: () -> Unit, + onRestartClicked: () -> Unit, +) { + val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.confetti)) + val progress by animateLottieCompositionAsState( + composition = composition, + isPlaying = isEndOfList, + ) + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + LottieAnimation( + composition = composition, + progress = { progress }, + modifier = Modifier + .fillMaxSize() + .zIndex(2f) + ) + LazyColumn( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .fillMaxSize() + .padding(top = 20.dp) + .padding(16.dp) + ) { + item { + Text( + text = "You're doing great!", + style = MaterialTheme.typography.titleLarge.copy( + fontWeight = FontWeight.Bold + ) + ) + } + item { + StudySetDonutChart( + modifier = Modifier + .size(200.dp) + .padding(16.dp), + studySetsStillLearn = countStillLearning.coerceAtLeast(0), + studySetsMastered = countKnown.coerceAtLeast(0), + color = studySetColor + ) + } + + item { + Text( + text = "Keep focusing on your study set to master it!", + style = MaterialTheme.typography.bodyMedium.copy( + fontWeight = FontWeight.Bold + ), + modifier = Modifier.padding(16.dp) + ) + } + + item { + Card( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 16.dp), + colors = CardDefaults.cardColors( + containerColor = Color.White + ), + border = BorderStroke(1.dp, studySetColor), + elevation = CardDefaults.cardElevation( + defaultElevation = 3.dp, + ) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Image( + painter = painterResource(id = R.drawable.ic_card), + contentDescription = "Card", + contentScale = ContentScale.Crop + ) + Text( + text = "Flashcards learned", + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = 18.sp + ), + modifier = Modifier + .weight(1f) + .padding( + start = 8.dp, + end = 16.dp + ), + textAlign = TextAlign.Start, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + Text( + text = buildAnnotatedString { + withStyle( + style = SpanStyle( + fontWeight = FontWeight.Bold + ) + ) { + append(countKnown.coerceAtLeast(0).toString()) + } + append("/${flashCardSize}") + }, + fontSize = 18.sp, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.padding(8.dp) + ) + } + } + } + item { + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors( + containerColor = Color.White + ), + border = BorderStroke(1.dp, studySetColor), + elevation = CardDefaults.cardElevation( + defaultElevation = 3.dp, + ) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp) + ) { + Image( + imageVector = Icons.Default.AccessTime, + contentDescription = "Time", + ) + Text( + text = "Learning Time", + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = 18.sp + ), + modifier = Modifier + .weight(1f) + .padding( + start = 8.dp, + end = 16.dp + ), + textAlign = TextAlign.Start, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + Timber.d("toStringTime learningTime: ${learningTime.toStringTime()}") + Text( + text = learningTime.toStringTime(), + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ), + modifier = Modifier.padding(8.dp) + ) + } + } + + } + item { + if (countStillLearning > 0) { + Button( + onClick = { + onContinueLearningClicked() + }, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + shape = MaterialTheme.shapes.small, + colors = ButtonDefaults.buttonColors( + containerColor = studySetColor, + contentColor = Color.White + ), + border = BorderStroke(1.dp, studySetColor) + ) { + Text( + text = "Keep reviewing $countStillLearning terms", + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ), + modifier = Modifier.padding(8.dp) + ) + } + } + } + item { + Button( + onClick = { + onRestartClicked() + }, + modifier = Modifier + .fillMaxWidth() + .padding(16.dp), + shape = MaterialTheme.shapes.small, + colors = ButtonDefaults.buttonColors( + containerColor = Color.Transparent, + contentColor = studySetColor + ), + border = BorderStroke(1.dp, studySetColor) + ) { + Text( + text = "Restart Flashcards", + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = 18.sp, + fontWeight = FontWeight.Bold + ), + modifier = Modifier.padding(8.dp) + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardIconButton.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardIconButton.kt similarity index 92% rename from app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardIconButton.kt rename to app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardIconButton.kt index 87764356..08bfec42 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardIconButton.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardIconButton.kt @@ -1,4 +1,4 @@ -package com.pwhs.quickmem.presentation.app.study_set.studies.component +package com.pwhs.quickmem.presentation.app.study_set.studies.flip.component import androidx.compose.foundation.border import androidx.compose.foundation.layout.padding diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardStatusRow.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardStatusRow.kt similarity index 98% rename from app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardStatusRow.kt rename to app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardStatusRow.kt index a67b6beb..62756e79 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/FlipFlashCardStatusRow.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/FlipFlashCardStatusRow.kt @@ -1,4 +1,4 @@ -package com.pwhs.quickmem.presentation.app.study_set.studies.component +package com.pwhs.quickmem.presentation.app.study_set.studies.flip.component import androidx.compose.animation.AnimatedContent import androidx.compose.animation.animateContentSize diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/StudyFlipCard.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/StudyFlipCard.kt similarity index 99% rename from app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/StudyFlipCard.kt rename to app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/StudyFlipCard.kt index 35a7f19c..f0609442 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/component/StudyFlipCard.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/flip/component/StudyFlipCard.kt @@ -1,4 +1,4 @@ -package com.pwhs.quickmem.presentation.app.study_set.studies.component +package com.pwhs.quickmem.presentation.app.study_set.studies.flip.component import androidx.compose.animation.animateContentSize import androidx.compose.animation.core.FastOutSlowInEasing diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/quiz/component/QuizFlashCardFinish.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/quiz/component/QuizFlashCardFinish.kt index 2acf313f..bdabed27 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/quiz/component/QuizFlashCardFinish.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/quiz/component/QuizFlashCardFinish.kt @@ -1,7 +1,6 @@ package com.pwhs.quickmem.presentation.app.study_set.studies.quiz.component import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -20,6 +19,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -111,8 +111,8 @@ fun QuizFlashCardFinish( modifier = Modifier .size(200.dp) .padding(16.dp), - studySetsStillLearn = wrongAnswerCount, - studySetsMastered = correctAnswerCount, + studySetsStillLearn = wrongAnswerCount.coerceAtLeast(0), + studySetsMastered = correctAnswerCount.coerceAtLeast(0), color = studySetColor ) @@ -125,7 +125,6 @@ fun QuizFlashCardFinish( ) Card( - onClick = {}, modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp), @@ -143,10 +142,9 @@ fun QuizFlashCardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( painter = painterResource(id = R.drawable.ic_card), contentDescription = "Card", - contentScale = ContentScale.Crop ) Text( text = "Flashcards learned", @@ -170,7 +168,7 @@ fun QuizFlashCardFinish( fontWeight = FontWeight.Bold ) ) { - append(correctAnswerCount.toString()) + append(correctAnswerCount.coerceAtLeast(0).toString()) } append("/${flashCardSize}") }, @@ -181,7 +179,6 @@ fun QuizFlashCardFinish( } } Card( - onClick = {}, modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors( containerColor = Color.White @@ -197,7 +194,7 @@ fun QuizFlashCardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( imageVector = Icons.Default.AccessTime, contentDescription = "Time", ) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/true_false/component/TrueFalseFlashcardFinish.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/true_false/component/TrueFalseFlashcardFinish.kt index 259e5a38..8059fd02 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/true_false/component/TrueFalseFlashcardFinish.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/true_false/component/TrueFalseFlashcardFinish.kt @@ -1,7 +1,6 @@ package com.pwhs.quickmem.presentation.app.study_set.studies.true_false.component import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -20,6 +19,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -111,8 +111,8 @@ fun TrueFalseFlashcardFinish( modifier = Modifier .size(200.dp) .padding(16.dp), - studySetsStillLearn = wrongAnswerCount, - studySetsMastered = correctAnswerCount, + studySetsStillLearn = wrongAnswerCount.coerceAtLeast(0), + studySetsMastered = correctAnswerCount.coerceAtLeast(0), color = studySetColor ) @@ -143,10 +143,9 @@ fun TrueFalseFlashcardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( painter = painterResource(id = R.drawable.ic_card), contentDescription = "Card", - contentScale = ContentScale.Crop ) Text( text = "Flashcards learned", @@ -170,7 +169,7 @@ fun TrueFalseFlashcardFinish( fontWeight = FontWeight.Bold ) ) { - append(correctAnswerCount.toString()) + append(correctAnswerCount.coerceAtLeast(0).toString()) } append("/${flashCardSize}") }, @@ -181,7 +180,6 @@ fun TrueFalseFlashcardFinish( } } Card( - onClick = {}, modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors( containerColor = Color.White @@ -197,7 +195,7 @@ fun TrueFalseFlashcardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( imageVector = Icons.Default.AccessTime, contentDescription = "Time", ) diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/LearnByWriteScreen.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/LearnByWriteScreen.kt index 967a7995..c129e810 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/LearnByWriteScreen.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/LearnByWriteScreen.kt @@ -2,6 +2,7 @@ package com.pwhs.quickmem.presentation.app.study_set.studies.write import android.widget.Toast import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.tween import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -9,12 +10,14 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeight import androidx.compose.foundation.layout.size -import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons.Default import androidx.compose.material.icons.filled.ArrowCircleUp import androidx.compose.material.icons.filled.Clear @@ -46,11 +49,10 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview @@ -58,17 +60,17 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import coil.compose.AsyncImage +import com.pwhs.quickmem.R import com.pwhs.quickmem.core.data.enums.WriteStatus import com.pwhs.quickmem.domain.model.flashcard.FlashCardResponseModel -import com.pwhs.quickmem.presentation.app.study_set.studies.true_false.LearnByTrueFalseUiEvent import com.pwhs.quickmem.presentation.app.study_set.studies.write.component.WriteFlashcardFinish import com.pwhs.quickmem.presentation.component.LoadingOverlay import com.pwhs.quickmem.presentation.component.ViewImageDialog import com.pwhs.quickmem.ui.theme.QuickMemTheme +import com.pwhs.quickmem.util.rememberImeState import com.pwhs.quickmem.util.toColor import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import com.ramcosta.composedestinations.result.ResultBackNavigator import kotlinx.coroutines.Job import kotlinx.coroutines.delay @@ -144,24 +146,27 @@ fun LearnByWrite( ) { var isImageViewerOpen by remember { mutableStateOf(false) } var definitionImageUri by remember { mutableStateOf("") } - val focusRequester = remember { FocusRequester() } var userAnswer by rememberSaveable { mutableStateOf("") } val showHintBottomSheet = remember { mutableStateOf(false) } val hintBottomSheetState = rememberModalBottomSheetState() val scope = rememberCoroutineScope() var debounceJob: Job? = null - LaunchedEffect(Unit) { - focusRequester.requestFocus() + val imeState = rememberImeState() + val scrollState = rememberScrollState() + LaunchedEffect(key1 = imeState.value) { + if (imeState.value) { + scrollState.animateScrollTo(scrollState.viewportSize, tween(300)) + } } Scaffold( topBar = { CenterAlignedTopAppBar( title = { when (isLoading) { - true -> Text("Loading") + true -> Text(text = "Loading") false -> when (isEndOfList) { false -> Text("${currentCardIndex + 1}/${flashCardList.size}") - true -> Text("Finished") + true -> Text(text = "Finished") } } }, @@ -185,7 +190,7 @@ fun LearnByWrite( ) { Icon( imageVector = Default.RestartAlt, - contentDescription = "Restart", + contentDescription = stringResource(R.string.txt_restart), tint = studySetColor ) } @@ -221,159 +226,158 @@ fun LearnByWrite( ) when (isEndOfList) { false -> { - LazyColumn( - modifier = Modifier.padding(horizontal = 16.dp) + Column( + modifier = Modifier + .fillMaxWidth() + .verticalScroll(scrollState) + .imePadding() ) { - item { - Card( + Card( + modifier = Modifier + .fillMaxWidth() + .requiredHeight(300.dp), + colors = CardDefaults.cardColors( + containerColor = MaterialTheme.colorScheme.surface + ), + shape = MaterialTheme.shapes.small + ) { + Column( modifier = Modifier - .fillMaxWidth() - .height(300.dp), - colors = CardDefaults.cardColors( - containerColor = MaterialTheme.colorScheme.surface - ), - shape = MaterialTheme.shapes.small + .fillMaxSize() + .padding(8.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center ) { - Column( + Text( + text = writeQuestion?.definition ?: "", + style = MaterialTheme.typography.bodyMedium.copy( + fontSize = when (writeQuestion?.definition?.length + ?: 0) { + in 0..10 -> 16.sp + in 11..20 -> 14.sp + else -> 12.sp + } + ), modifier = Modifier - .fillMaxSize() - .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center - ) { - Text( - text = writeQuestion?.definition ?: "", - style = MaterialTheme.typography.bodyMedium.copy( - fontSize = when (writeQuestion?.definition?.length - ?: 0) { - in 0..10 -> 16.sp - in 11..20 -> 14.sp - else -> 12.sp - } - ), + .padding(8.dp) + .padding(bottom = 8.dp) + ) + if (writeQuestion?.definitionImageUrl?.isNotEmpty() == true) { + AsyncImage( + model = writeQuestion.definitionImageUrl, + contentDescription = "Definition Image", + contentScale = ContentScale.Crop, modifier = Modifier - .padding(8.dp) - .padding(bottom = 8.dp) + .size(80.dp) + .clickable { + isImageViewerOpen = true + definitionImageUri = + writeQuestion.definitionImageUrl + } ) - if (writeQuestion?.definitionImageUrl?.isNotEmpty() == true) { - AsyncImage( - model = writeQuestion.definitionImageUrl, - contentDescription = "Definition Image", - contentScale = ContentScale.Crop, - modifier = Modifier - .size(80.dp) - .clickable { - isImageViewerOpen = true - definitionImageUri = - writeQuestion.definitionImageUrl - } - ) - } } } } - item { - Row( - modifier = Modifier - .fillMaxWidth() - .padding(top = 16.dp), - horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically - ) { - TextField( - value = userAnswer, - maxLines = 1, - keyboardActions = KeyboardActions( - onDone = { - userAnswer = "" + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 16.dp), + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically + ) { + TextField( + value = userAnswer, + maxLines = 1, + keyboardActions = KeyboardActions( + onDone = { + userAnswer = "" + } + ), + keyboardOptions = KeyboardOptions( + autoCorrectEnabled = false, + imeAction = ImeAction.Done, + showKeyboardOnFocus = true + ), + placeholder = { + Text( + text = "Enter your answer", + style = MaterialTheme.typography.bodyMedium.copy( + fontWeight = FontWeight.Bold + ) + ) + }, + trailingIcon = { + TextButton( + onClick = { + debounceJob?.cancel() + debounceJob = scope.launch { + delay(500) + onSubmitAnswer( + writeQuestion?.id ?: "", + WriteStatus.SKIPPED, + "" + ) + } } - ), - keyboardOptions = KeyboardOptions( - autoCorrectEnabled = false, - imeAction = ImeAction.Done, - showKeyboardOnFocus = true - ), - placeholder = { + ) { Text( - text = "Enter your answer", + text = "Don't know", style = MaterialTheme.typography.bodyMedium.copy( + color = studySetColor, fontWeight = FontWeight.Bold ) ) - }, - trailingIcon = { - TextButton( - onClick = { - debounceJob?.cancel() - debounceJob = scope.launch { - delay(500) - onSubmitAnswer( - writeQuestion?.id ?: "", - WriteStatus.SKIPPED, - "" - ) - } - } - ) { - Text( - text = "Don't know", - style = MaterialTheme.typography.bodyMedium.copy( - color = studySetColor, - fontWeight = FontWeight.Bold - ) + } + }, + onValueChange = { + userAnswer = it + }, + colors = TextFieldDefaults.colors( + unfocusedContainerColor = Color.Transparent, + focusedContainerColor = Color.Transparent, + focusedIndicatorColor = studySetColor, + unfocusedIndicatorColor = studySetColor + ), + modifier = Modifier + .weight(1f) + .padding(horizontal = 8.dp), + ) + + IconButton( + onClick = { + debounceJob?.cancel() + debounceJob = scope.launch { + delay(500) + if (userAnswer.isNotEmpty() && writeQuestion?.term == userAnswer) { + onSubmitAnswer( + writeQuestion.id, + WriteStatus.CORRECT, + userAnswer + ) + userAnswer = "" + } else { + onSubmitAnswer( + writeQuestion?.id ?: "", + WriteStatus.WRONG, + userAnswer ) + userAnswer = "" } - }, - onValueChange = { - userAnswer = it - }, - colors = TextFieldDefaults.colors( - unfocusedContainerColor = Color.Transparent, - focusedContainerColor = Color.Transparent, - focusedIndicatorColor = studySetColor, - unfocusedIndicatorColor = studySetColor + } + }, + enabled = userAnswer.isNotEmpty(), + colors = IconButtonDefaults.iconButtonColors( + disabledContentColor = MaterialTheme.colorScheme.onSurface.copy( + alpha = 0.5f ), - modifier = Modifier - .weight(1f) - .focusRequester(focusRequester) - .padding(end = 8.dp), + contentColor = studySetColor + ) + ) { + Icon( + imageVector = Default.ArrowCircleUp, + contentDescription = "Submit", ) - - IconButton( - onClick = { - debounceJob?.cancel() - debounceJob = scope.launch { - delay(500) - if (userAnswer.isNotEmpty() && writeQuestion?.term == userAnswer) { - onSubmitAnswer( - writeQuestion.id, - WriteStatus.CORRECT, - userAnswer - ) - userAnswer = "" - } else { - onSubmitAnswer( - writeQuestion?.id ?: "", - WriteStatus.WRONG, - userAnswer - ) - userAnswer = "" - } - } - }, - enabled = userAnswer.isNotEmpty(), - colors = IconButtonDefaults.iconButtonColors( - disabledContentColor = MaterialTheme.colorScheme.onSurface.copy( - alpha = 0.5f - ), - contentColor = studySetColor - ) - ) { - Icon( - imageVector = Default.ArrowCircleUp, - contentDescription = "Submit", - ) - } } } } diff --git a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/component/WriteFlashcardFinish.kt b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/component/WriteFlashcardFinish.kt index adfdc07e..c9cc355e 100644 --- a/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/component/WriteFlashcardFinish.kt +++ b/app/src/main/java/com/pwhs/quickmem/presentation/app/study_set/studies/write/component/WriteFlashcardFinish.kt @@ -1,7 +1,6 @@ package com.pwhs.quickmem.presentation.app.study_set.studies.write.component import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -20,6 +19,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -111,8 +111,8 @@ fun WriteFlashcardFinish( modifier = Modifier .size(200.dp) .padding(16.dp), - studySetsStillLearn = wrongAnswerCount, - studySetsMastered = correctAnswerCount, + studySetsStillLearn = wrongAnswerCount.coerceAtLeast(0), + studySetsMastered = correctAnswerCount.coerceAtLeast(0), color = studySetColor ) @@ -125,7 +125,6 @@ fun WriteFlashcardFinish( ) Card( - onClick = {}, modifier = Modifier .fillMaxWidth() .padding(bottom = 16.dp), @@ -143,10 +142,9 @@ fun WriteFlashcardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( painter = painterResource(id = R.drawable.ic_card), contentDescription = "Card", - contentScale = ContentScale.Crop ) Text( text = "Flashcards learned", @@ -170,7 +168,7 @@ fun WriteFlashcardFinish( fontWeight = FontWeight.Bold ) ) { - append(correctAnswerCount.toString()) + append(correctAnswerCount.coerceAtLeast(0).toString()) } append("/${flashCardSize}") }, @@ -181,7 +179,6 @@ fun WriteFlashcardFinish( } } Card( - onClick = {}, modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors( containerColor = Color.White @@ -197,7 +194,7 @@ fun WriteFlashcardFinish( .fillMaxWidth() .padding(16.dp) ) { - Image( + Icon( imageVector = Icons.Default.AccessTime, contentDescription = "Time", ) diff --git a/app/src/main/res/drawable/ic_card.xml b/app/src/main/res/drawable/ic_card.xml index 99a21289..6eab2b29 100644 --- a/app/src/main/res/drawable/ic_card.xml +++ b/app/src/main/res/drawable/ic_card.xml @@ -5,7 +5,7 @@ android:viewportHeight="32"> diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 9c53cb05..c1503178 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -161,8 +161,8 @@ Bộ học, thư mục, lớp học,.. Nhập một chủ đề hoặc từ khóa Mẹo: Càng cụ thể càng tốt! - Tài liệu - Tiến trình + Tài liệub + Tiến trình học Xem bộ học này: %1$s\n%2$s Xem folder này: %1$s\n%2$s Xóa bộ học @@ -184,7 +184,7 @@ Thêm tài liệu Chọn cách học của bạn Lật thẻ học - Bài kiểm tra + Trắc nghiệm Đúng/Sai Viết Thuật ngữ @@ -359,4 +359,5 @@ Không tìm thấy người dùng nào có username mà bạn cung cấp Vui lòng đăng ký hoặc đăng nhập vào ứng dụng Không tìm thấy class + Restart \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 02522aae..83ff4192 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -362,4 +362,5 @@ No members found Unauthorized Class not found + Restart \ No newline at end of file