Refactor VocabularyCard into specialized VocabularyDisplayCard and VocabularyExerciseCard components.
This commit is contained in:
@@ -126,7 +126,8 @@ dependencies {
|
|||||||
implementation(libs.androidx.room.runtime) // ADDED: Explicitly add runtime
|
implementation(libs.androidx.room.runtime) // ADDED: Explicitly add runtime
|
||||||
implementation(libs.androidx.room.ktx)
|
implementation(libs.androidx.room.ktx)
|
||||||
implementation(libs.core.ktx)
|
implementation(libs.core.ktx)
|
||||||
ksp(libs.room.compiler) // CHANGED: Use ksp instead of implementation
|
implementation(libs.androidx.compose.foundation)
|
||||||
|
ksp(libs.room.compiler)
|
||||||
|
|
||||||
// Networking
|
// Networking
|
||||||
implementation(libs.retrofit)
|
implementation(libs.retrofit)
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
package eu.gaudian.translator.view.vocabulary
|
package eu.gaudian.translator.view.vocabulary
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -41,7 +50,8 @@ import eu.gaudian.translator.view.composable.AppTopAppBar
|
|||||||
import eu.gaudian.translator.view.dialogs.CategorySelectionDialog
|
import eu.gaudian.translator.view.dialogs.CategorySelectionDialog
|
||||||
import eu.gaudian.translator.view.dialogs.ImportVocabularyDialog
|
import eu.gaudian.translator.view.dialogs.ImportVocabularyDialog
|
||||||
import eu.gaudian.translator.view.dialogs.StageSelectionDialog
|
import eu.gaudian.translator.view.dialogs.StageSelectionDialog
|
||||||
import eu.gaudian.translator.view.vocabulary.card.VocabularyCard
|
import eu.gaudian.translator.view.vocabulary.card.VocabularyDisplayCard
|
||||||
|
import eu.gaudian.translator.view.vocabulary.card.VocabularyExerciseCard
|
||||||
import eu.gaudian.translator.viewmodel.LanguageViewModel
|
import eu.gaudian.translator.viewmodel.LanguageViewModel
|
||||||
import eu.gaudian.translator.viewmodel.VocabularyViewModel
|
import eu.gaudian.translator.viewmodel.VocabularyViewModel
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -71,6 +81,10 @@ fun VocabularyCardHost(
|
|||||||
vocabularyItem = vocabularyViewModel.getVocabularyItemById(itemId)
|
vocabularyItem = vocabularyViewModel.getVocabularyItemById(itemId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isEditing by remember { mutableStateOf(false) }
|
||||||
|
var onSaveEdit by remember { mutableStateOf<(() -> Unit)?>(null) }
|
||||||
|
var onCancelEdit by remember { mutableStateOf<(() -> Unit)?>(null) }
|
||||||
|
|
||||||
AppScaffold(
|
AppScaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
AppTopAppBar(
|
AppTopAppBar(
|
||||||
@@ -78,42 +92,44 @@ fun VocabularyCardHost(
|
|||||||
title = stringResource(R.string.item_details),
|
title = stringResource(R.string.item_details),
|
||||||
onNavigateBack = { navController.popBackStack() },
|
onNavigateBack = { navController.popBackStack() },
|
||||||
actions = {
|
actions = {
|
||||||
// Previous button
|
if (!isEditing) {
|
||||||
if (navigationPosition > 0) {
|
// Previous button
|
||||||
IconButton(onClick = {
|
if (navigationPosition > 0) {
|
||||||
if (vocabularyViewModel.navigateToPreviousItem()) {
|
IconButton(onClick = {
|
||||||
val prevItem = navigationItems[navigationPosition - 1]
|
if (vocabularyViewModel.navigateToPreviousItem()) {
|
||||||
scope.launch {
|
val prevItem = navigationItems[navigationPosition - 1]
|
||||||
|
scope.launch {
|
||||||
|
|
||||||
@Suppress("AssignedValueIsNeverRead")
|
@Suppress("AssignedValueIsNeverRead")
|
||||||
vocabularyItem = vocabularyViewModel.getVocabularyItemById(prevItem.id)
|
vocabularyItem = vocabularyViewModel.getVocabularyItemById(prevItem.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
AppIcons.ArrowLeft,
|
||||||
|
contentDescription = stringResource(R.string.previous_item),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
AppIcons.ArrowLeft,
|
|
||||||
contentDescription = stringResource(R.string.previous_item),
|
|
||||||
tint = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Next button
|
// Next button
|
||||||
if (navigationPosition < navigationItems.size - 1) {
|
if (navigationPosition < navigationItems.size - 1) {
|
||||||
IconButton(onClick = {
|
IconButton(onClick = {
|
||||||
if (vocabularyViewModel.navigateToNextItem()) {
|
if (vocabularyViewModel.navigateToNextItem()) {
|
||||||
val nextItem = navigationItems[navigationPosition + 1]
|
val nextItem = navigationItems[navigationPosition + 1]
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@Suppress("AssignedValueIsNeverRead")
|
@Suppress("AssignedValueIsNeverRead")
|
||||||
vocabularyItem = vocabularyViewModel.getVocabularyItemById(nextItem.id)
|
vocabularyItem = vocabularyViewModel.getVocabularyItemById(nextItem.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}) {
|
||||||
|
Icon(
|
||||||
|
AppIcons.ArrowRight,
|
||||||
|
contentDescription = stringResource(R.string.next_item),
|
||||||
|
tint = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}) {
|
|
||||||
Icon(
|
|
||||||
AppIcons.ArrowRight,
|
|
||||||
contentDescription = stringResource(R.string.next_item),
|
|
||||||
tint = MaterialTheme.colorScheme.primary
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +151,11 @@ fun VocabularyCardHost(
|
|||||||
var showStageDialog by remember { mutableStateOf(false) }
|
var showStageDialog by remember { mutableStateOf(false) }
|
||||||
var showImportDialog by remember { mutableStateOf(false) }
|
var showImportDialog by remember { mutableStateOf(false) }
|
||||||
var showDeleteDialog by remember { mutableStateOf(false) }
|
var showDeleteDialog by remember { mutableStateOf(false) }
|
||||||
|
LaunchedEffect(currentVocabularyItem.id) {
|
||||||
|
isEditing = false
|
||||||
|
onSaveEdit = null
|
||||||
|
onCancelEdit = null
|
||||||
|
}
|
||||||
|
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
val lifecycleOwner = LocalLifecycleOwner.current
|
||||||
val stats by vocabularyViewModel
|
val stats by vocabularyViewModel
|
||||||
@@ -186,18 +207,66 @@ fun VocabularyCardHost(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Main content
|
// Main content
|
||||||
VocabularyCard(
|
Column(
|
||||||
vocabularyItem = currentVocabularyItem,
|
modifier = Modifier.fillMaxSize(),
|
||||||
exerciseMode = exerciseMode,
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
switchOrder = switchOrder == true,
|
) {
|
||||||
isFlipped = isFlipped,
|
if (!exerciseMode && isEditing) {
|
||||||
onStatisticsClick = { showStatisticsDialog = true },
|
Row(
|
||||||
onMoveToCategoryClick = { showCategoryDialog = true },
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onMoveToStageClick = { showStageDialog = true },
|
horizontalArrangement = Arrangement.Center,
|
||||||
onDeleteClick = { showDeleteDialog = true },
|
verticalAlignment = Alignment.CenterVertically
|
||||||
navController = navController,
|
) {
|
||||||
isUserSpellingCorrect = false,
|
OutlinedButton(
|
||||||
)
|
onClick = { onCancelEdit?.invoke() },
|
||||||
|
shape = RoundedCornerShape(16.dp)
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(R.string.label_cancel))
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.width(8.dp))
|
||||||
|
Button(
|
||||||
|
onClick = { onSaveEdit?.invoke() },
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(text = stringResource(R.string.label_save))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exerciseMode) {
|
||||||
|
VocabularyExerciseCard(
|
||||||
|
vocabularyItem = currentVocabularyItem,
|
||||||
|
switchOrder = switchOrder == true,
|
||||||
|
isFlipped = isFlipped,
|
||||||
|
navController = navController,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
VocabularyDisplayCard(
|
||||||
|
vocabularyItem = currentVocabularyItem,
|
||||||
|
switchOrder = switchOrder == true,
|
||||||
|
isFlipped = isFlipped,
|
||||||
|
onStatisticsClick = { showStatisticsDialog = true },
|
||||||
|
onMoveToCategoryClick = { showCategoryDialog = true },
|
||||||
|
onMoveToStageClick = { showStageDialog = true },
|
||||||
|
onDeleteClick = { showDeleteDialog = true },
|
||||||
|
navController = navController,
|
||||||
|
onEditStateChange = { editing ->
|
||||||
|
isEditing = editing
|
||||||
|
if (!editing) {
|
||||||
|
onSaveEdit = null
|
||||||
|
onCancelEdit = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onEditActionHandlersReady = { onSave, onCancel ->
|
||||||
|
onSaveEdit = onSave
|
||||||
|
onCancelEdit = onCancel
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Dialogs are unaffected by the layout change
|
// Dialogs are unaffected by the layout change
|
||||||
if (showQuitDialog) {
|
if (showQuitDialog) {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ import eu.gaudian.translator.ui.theme.semanticColors
|
|||||||
import eu.gaudian.translator.utils.findActivity
|
import eu.gaudian.translator.utils.findActivity
|
||||||
import eu.gaudian.translator.view.composable.AppButton
|
import eu.gaudian.translator.view.composable.AppButton
|
||||||
import eu.gaudian.translator.view.composable.ComponentDefaults
|
import eu.gaudian.translator.view.composable.ComponentDefaults
|
||||||
import eu.gaudian.translator.view.vocabulary.card.VocabularyCard
|
import eu.gaudian.translator.view.vocabulary.card.VocabularyExerciseCard
|
||||||
import eu.gaudian.translator.viewmodel.LanguageViewModel
|
import eu.gaudian.translator.viewmodel.LanguageViewModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,11 +141,10 @@ fun GuessingExercise(
|
|||||||
navController: NavController,
|
navController: NavController,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
VocabularyCard(
|
VocabularyExerciseCard(
|
||||||
vocabularyItem = state.item,
|
vocabularyItem = state.item,
|
||||||
isFlipped = state.isRevealed,
|
isFlipped = state.isRevealed,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
exerciseMode = true,
|
|
||||||
switchOrder = state.isSwitched,
|
switchOrder = state.isSwitched,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -158,13 +157,12 @@ fun SpellingExercise(
|
|||||||
navController: NavController,
|
navController: NavController,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
VocabularyCard(
|
VocabularyExerciseCard(
|
||||||
vocabularyItem = state.item,
|
vocabularyItem = state.item,
|
||||||
isFlipped = state.isRevealed,
|
isFlipped = state.isRevealed,
|
||||||
userSpellingAnswer = state.userAnswer,
|
userSpellingAnswer = state.userAnswer,
|
||||||
isUserSpellingCorrect = state.isCorrect,
|
isUserSpellingCorrect = state.isCorrect,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
exerciseMode = true,
|
|
||||||
switchOrder = state.isSwitched,
|
switchOrder = state.isSwitched,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ internal fun DraggableActionPanel(
|
|||||||
onDismiss: () -> Unit,
|
onDismiss: () -> Unit,
|
||||||
isEditing: Boolean,
|
isEditing: Boolean,
|
||||||
onEditClick: () -> Unit,
|
onEditClick: () -> Unit,
|
||||||
onSaveClick: () -> Unit,
|
|
||||||
onCancelClick: () -> Unit,
|
|
||||||
onStatisticsClick: () -> Unit,
|
onStatisticsClick: () -> Unit,
|
||||||
onMoveToCategoryClick: () -> Unit,
|
onMoveToCategoryClick: () -> Unit,
|
||||||
onMoveToStageClick: () -> Unit,
|
onMoveToStageClick: () -> Unit,
|
||||||
@@ -175,13 +173,8 @@ internal fun DraggableActionPanel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEditing) {
|
|
||||||
ActionItem(icon = AppIcons.Check, label = stringResource(R.string.label_save), isExtended = isExtended, onClick = actionClickHandler(onSaveClick))
|
|
||||||
ActionItem(icon = AppIcons.Close, stringResource(R.string.label_cancel), isExtended = isExtended, onClick = actionClickHandler(onCancelClick))
|
|
||||||
} else {
|
|
||||||
ActionItem(icon = AppIcons.Edit, label = stringResource(R.string.edit), isExtended = isExtended, onClick = actionClickHandler(onEditClick))
|
|
||||||
}
|
|
||||||
if (!isEditing) {
|
if (!isEditing) {
|
||||||
|
ActionItem(icon = AppIcons.Edit, label = stringResource(R.string.edit), isExtended = isExtended, onClick = actionClickHandler(onEditClick))
|
||||||
|
|
||||||
if (showAnalyzeGrammarButton) {
|
if (showAnalyzeGrammarButton) {
|
||||||
ActionItem(
|
ActionItem(
|
||||||
@@ -252,8 +245,6 @@ fun DraggableActionPanelPreview() {
|
|||||||
onDismiss = {},
|
onDismiss = {},
|
||||||
isEditing = false,
|
isEditing = false,
|
||||||
onEditClick = {},
|
onEditClick = {},
|
||||||
onSaveClick = {},
|
|
||||||
onCancelClick = {},
|
|
||||||
|
|
||||||
onStatisticsClick = {},
|
onStatisticsClick = {},
|
||||||
onMoveToCategoryClick = {},
|
onMoveToCategoryClick = {},
|
||||||
|
|||||||
@@ -86,6 +86,54 @@ import eu.gaudian.translator.viewmodel.VocabularyViewModel
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun VocabularyDisplayCard(
|
||||||
|
vocabularyItem: VocabularyItem,
|
||||||
|
navController: NavController,
|
||||||
|
isFlipped: Boolean,
|
||||||
|
switchOrder: Boolean,
|
||||||
|
onStatisticsClick: () -> Unit = {},
|
||||||
|
onMoveToCategoryClick: () -> Unit = {},
|
||||||
|
onMoveToStageClick: () -> Unit = {},
|
||||||
|
onDeleteClick: () -> Unit = {},
|
||||||
|
onEditStateChange: ((Boolean) -> Unit)? = null,
|
||||||
|
onEditActionHandlersReady: ((onSave: () -> Unit, onCancel: () -> Unit) -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
VocabularyCardContent(
|
||||||
|
vocabularyItem = vocabularyItem,
|
||||||
|
navController = navController,
|
||||||
|
isExerciseMode = false,
|
||||||
|
isFlipped = isFlipped,
|
||||||
|
switchOrder = switchOrder,
|
||||||
|
onStatisticsClick = onStatisticsClick,
|
||||||
|
onMoveToCategoryClick = onMoveToCategoryClick,
|
||||||
|
onMoveToStageClick = onMoveToStageClick,
|
||||||
|
onDeleteClick = onDeleteClick,
|
||||||
|
onEditStateChange = onEditStateChange,
|
||||||
|
onEditActionHandlersReady = onEditActionHandlersReady,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun VocabularyExerciseCard(
|
||||||
|
vocabularyItem: VocabularyItem,
|
||||||
|
navController: NavController,
|
||||||
|
isFlipped: Boolean,
|
||||||
|
switchOrder: Boolean,
|
||||||
|
userSpellingAnswer: String? = null,
|
||||||
|
isUserSpellingCorrect: Boolean? = null,
|
||||||
|
) {
|
||||||
|
VocabularyCardContent(
|
||||||
|
vocabularyItem = vocabularyItem,
|
||||||
|
navController = navController,
|
||||||
|
isExerciseMode = true,
|
||||||
|
isFlipped = isFlipped,
|
||||||
|
switchOrder = switchOrder,
|
||||||
|
userSpellingAnswer = userSpellingAnswer,
|
||||||
|
isUserSpellingCorrect = isUserSpellingCorrect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated("We need to seperate this into two: one for display and one for exercises")
|
@Deprecated("We need to seperate this into two: one for display and one for exercises")
|
||||||
@Composable
|
@Composable
|
||||||
fun VocabularyCard(
|
fun VocabularyCard(
|
||||||
@@ -101,6 +149,37 @@ fun VocabularyCard(
|
|||||||
userSpellingAnswer: String? = null,
|
userSpellingAnswer: String? = null,
|
||||||
isUserSpellingCorrect: Boolean? = null,
|
isUserSpellingCorrect: Boolean? = null,
|
||||||
) {
|
) {
|
||||||
|
VocabularyCardContent(
|
||||||
|
vocabularyItem = vocabularyItem,
|
||||||
|
navController = navController,
|
||||||
|
isExerciseMode = exerciseMode,
|
||||||
|
isFlipped = isFlipped,
|
||||||
|
switchOrder = switchOrder,
|
||||||
|
onStatisticsClick = onStatisticsClick,
|
||||||
|
onMoveToCategoryClick = onMoveToCategoryClick,
|
||||||
|
onMoveToStageClick = onMoveToStageClick,
|
||||||
|
onDeleteClick = onDeleteClick,
|
||||||
|
userSpellingAnswer = userSpellingAnswer,
|
||||||
|
isUserSpellingCorrect = isUserSpellingCorrect,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun VocabularyCardContent(
|
||||||
|
vocabularyItem: VocabularyItem,
|
||||||
|
navController: NavController,
|
||||||
|
isExerciseMode: Boolean,
|
||||||
|
isFlipped: Boolean,
|
||||||
|
switchOrder: Boolean,
|
||||||
|
onStatisticsClick: () -> Unit = {},
|
||||||
|
onMoveToCategoryClick: () -> Unit = {},
|
||||||
|
onMoveToStageClick: () -> Unit = {},
|
||||||
|
onDeleteClick: () -> Unit = {},
|
||||||
|
userSpellingAnswer: String? = null,
|
||||||
|
isUserSpellingCorrect: Boolean? = null,
|
||||||
|
onEditStateChange: ((Boolean) -> Unit)? = null,
|
||||||
|
onEditActionHandlersReady: ((onSave: () -> Unit, onCancel: () -> Unit) -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
|
||||||
val activity = LocalContext.current.findActivity()
|
val activity = LocalContext.current.findActivity()
|
||||||
val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
|
val vocabularyViewModel: VocabularyViewModel = hiltViewModel(viewModelStoreOwner = activity)
|
||||||
@@ -202,6 +281,7 @@ fun VocabularyCard(
|
|||||||
)
|
)
|
||||||
vocabularyViewModel.editVocabularyItem(updatedItem)
|
vocabularyViewModel.editVocabularyItem(updatedItem)
|
||||||
isEditing = false
|
isEditing = false
|
||||||
|
onEditStateChange?.invoke(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,6 +294,7 @@ fun VocabularyCard(
|
|||||||
editedLangSecondId = item.languageSecondId
|
editedLangSecondId = item.languageSecondId
|
||||||
editedFeatures = item.features?.let { jsonParser.decodeFromString<VocabularyFeatures>(it) } ?: VocabularyFeatures()
|
editedFeatures = item.features?.let { jsonParser.decodeFromString<VocabularyFeatures>(it) } ?: VocabularyFeatures()
|
||||||
isEditing = false
|
isEditing = false
|
||||||
|
onEditStateChange?.invoke(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,13 +368,13 @@ fun VocabularyCard(
|
|||||||
onWordChange = { if (!switchOrder) editedWordFirst = it else editedWordSecond = it },
|
onWordChange = { if (!switchOrder) editedWordFirst = it else editedWordSecond = it },
|
||||||
language = if (!switchOrder) languageFirst else languageSecond,
|
language = if (!switchOrder) languageFirst else languageSecond,
|
||||||
onLanguageIdChange = { if (!switchOrder) editedLangFirstId = it else editedLangSecondId = it },
|
onLanguageIdChange = { if (!switchOrder) editedLangFirstId = it else editedLangSecondId = it },
|
||||||
isRevealed = isFrontFace || exerciseMode,
|
isRevealed = isFrontFace || isExerciseMode,
|
||||||
userSpellingAnswer = userSpellingAnswer,
|
userSpellingAnswer = userSpellingAnswer,
|
||||||
isUserSpellingCorrect = isUserSpellingCorrect,
|
isUserSpellingCorrect = isUserSpellingCorrect,
|
||||||
correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
|
correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
|
||||||
wordDetails = if (!switchOrder) editedFeatures.first else editedFeatures.second,
|
wordDetails = if (!switchOrder) editedFeatures.first else editedFeatures.second,
|
||||||
onEditGrammarClick = { showGrammarDialogFor = "first" },
|
onEditGrammarClick = { showGrammarDialogFor = "first" },
|
||||||
isExerciseMode = exerciseMode,
|
isExerciseMode = isExerciseMode,
|
||||||
vocabularyItem = item,
|
vocabularyItem = item,
|
||||||
onMoreClick = {
|
onMoreClick = {
|
||||||
@Suppress("HardCodedStringLiteral")
|
@Suppress("HardCodedStringLiteral")
|
||||||
@@ -318,7 +399,7 @@ fun VocabularyCard(
|
|||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
|
color = MaterialTheme.colorScheme.outline.copy(alpha = 0.3f)
|
||||||
)
|
)
|
||||||
if (!exerciseMode && !isFlipped) {
|
if (!isExerciseMode && !isEditing && !isFlipped) {
|
||||||
IconButton(onClick = { showActionPanel = true }) {
|
IconButton(onClick = { showActionPanel = true }) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = AppIcons.MoreVert,
|
imageVector = AppIcons.MoreVert,
|
||||||
@@ -340,7 +421,7 @@ fun VocabularyCard(
|
|||||||
onWordChange = { if (switchOrder) editedWordFirst = it else editedWordSecond = it },
|
onWordChange = { if (switchOrder) editedWordFirst = it else editedWordSecond = it },
|
||||||
language = if (switchOrder) languageFirst else languageSecond,
|
language = if (switchOrder) languageFirst else languageSecond,
|
||||||
onLanguageIdChange = { if (switchOrder) editedLangFirstId = it else editedLangSecondId = it },
|
onLanguageIdChange = { if (switchOrder) editedLangFirstId = it else editedLangSecondId = it },
|
||||||
isRevealed = !(!isFlipped && exerciseMode),
|
isRevealed = !(!isFlipped && isExerciseMode),
|
||||||
userSpellingAnswer = userSpellingAnswer,
|
userSpellingAnswer = userSpellingAnswer,
|
||||||
isUserSpellingCorrect = isUserSpellingCorrect,
|
isUserSpellingCorrect = isUserSpellingCorrect,
|
||||||
correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
|
correctWord = if (switchOrder) item.wordFirst else item.wordSecond,
|
||||||
@@ -349,7 +430,7 @@ fun VocabularyCard(
|
|||||||
@Suppress("HardCodedStringLiteral")
|
@Suppress("HardCodedStringLiteral")
|
||||||
showGrammarDialogFor = "second"
|
showGrammarDialogFor = "second"
|
||||||
},
|
},
|
||||||
isExerciseMode = exerciseMode,
|
isExerciseMode = isExerciseMode,
|
||||||
vocabularyItem = item,
|
vocabularyItem = item,
|
||||||
onMoreClick = {
|
onMoreClick = {
|
||||||
@Suppress("HardCodedStringLiteral")
|
@Suppress("HardCodedStringLiteral")
|
||||||
@@ -362,7 +443,7 @@ fun VocabularyCard(
|
|||||||
|
|
||||||
|
|
||||||
!switchOrder
|
!switchOrder
|
||||||
if(isFlipped || !exerciseMode)
|
if(isFlipped || !isExerciseMode)
|
||||||
DraggableActionPanel(
|
DraggableActionPanel(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.CenterEnd)
|
.align(Alignment.CenterEnd)
|
||||||
@@ -370,9 +451,14 @@ fun VocabularyCard(
|
|||||||
isOpen = showActionPanel,
|
isOpen = showActionPanel,
|
||||||
onDismiss = { showActionPanel = false },
|
onDismiss = { showActionPanel = false },
|
||||||
isEditing = isEditing,
|
isEditing = isEditing,
|
||||||
onEditClick = { isEditing = true },
|
onEditClick = {
|
||||||
onSaveClick = { handleSave() },
|
isEditing = true
|
||||||
onCancelClick = handleCancel,
|
onEditStateChange?.invoke(true)
|
||||||
|
onEditActionHandlersReady?.invoke(
|
||||||
|
{ handleSave() },
|
||||||
|
{ handleCancel() }
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
onStatisticsClick = onStatisticsClick,
|
onStatisticsClick = onStatisticsClick,
|
||||||
onMoveToCategoryClick = onMoveToCategoryClick,
|
onMoveToCategoryClick = onMoveToCategoryClick,
|
||||||
@@ -439,18 +525,15 @@ fun VocabularyCardPreview() {
|
|||||||
languageSecondId = R.string.language_2
|
languageSecondId = R.string.language_2
|
||||||
)
|
)
|
||||||
val navController = NavController(LocalContext.current)
|
val navController = NavController(LocalContext.current)
|
||||||
VocabularyCard(
|
VocabularyDisplayCard(
|
||||||
vocabularyItem = item,
|
vocabularyItem = item,
|
||||||
navController = navController,
|
navController = navController,
|
||||||
exerciseMode = false,
|
|
||||||
isFlipped = false,
|
isFlipped = false,
|
||||||
switchOrder = false,
|
switchOrder = false,
|
||||||
onStatisticsClick = {},
|
onStatisticsClick = {},
|
||||||
onMoveToCategoryClick = {},
|
onMoveToCategoryClick = {},
|
||||||
onMoveToStageClick = {},
|
onMoveToStageClick = {},
|
||||||
onDeleteClick = {},
|
onDeleteClick = {},
|
||||||
userSpellingAnswer = null,
|
|
||||||
isUserSpellingCorrect = null
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,7 +559,7 @@ private fun FrequencyPill(zipfFrequency: Float?) {
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = 4.dp)
|
.padding(horizontal = 4.dp)
|
||||||
.width(80.dp),
|
.width(100.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Surface(
|
Surface(
|
||||||
|
|||||||
@@ -120,7 +120,7 @@
|
|||||||
<string-array name="changelog_entries">
|
<string-array name="changelog_entries">
|
||||||
<item>Version 0.3.0 \n• Enabled CSV Import for Vocabulary\n• Option to use a translation server for translations instead of AI models for some supported langugaes\n• UI bug fixes \n• Show word frequency \n• Performance optimizations \n• Improved translations (German and Portuguese)</item>
|
<item>Version 0.3.0 \n• Enabled CSV Import for Vocabulary\n• Option to use a translation server for translations instead of AI models for some supported langugaes\n• UI bug fixes \n• Show word frequency \n• Performance optimizations \n• Improved translations (German and Portuguese)</item>
|
||||||
<item>Version 0.4.0 \n• Added dictionary download (beta) \n• UI enhancements \n• Bugfixes \n• Re-designed vocabulary card with improved UI \n• More pre-configured providers \n• Improved performance</item>
|
<item>Version 0.4.0 \n• Added dictionary download (beta) \n• UI enhancements \n• Bugfixes \n• Re-designed vocabulary card with improved UI \n• More pre-configured providers \n• Improved performance</item>
|
||||||
<item>Version 0.5.0 \n• Reworked UI with new focus on Flashcards and Exercises \n• Adding vocabulary is easier and more intuitive now </item>
|
<item>Version 0.5.0 \n• Reworked UI with new focus on Flashcards and Exercises \n• Adding vocabulary is easier and more intuitive now \n• Exercises are more fun now </item>
|
||||||
<item> </item>
|
<item> </item>
|
||||||
|
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ truth = "1.4.5"
|
|||||||
zstdJni = "1.5.7-7"
|
zstdJni = "1.5.7-7"
|
||||||
composeMarkdown = "0.5.8"
|
composeMarkdown = "0.5.8"
|
||||||
jitpack = "1.0.10"
|
jitpack = "1.0.10"
|
||||||
|
foundationVersion = "1.10.3"
|
||||||
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
@@ -103,6 +104,7 @@ hilt-android-compiler = { module = "com.google.dagger:hilt-android-compiler", ve
|
|||||||
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version = "1.3.0" }
|
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version = "1.3.0" }
|
||||||
mockk = { module = "io.mockk:mockk", version = "1.14.9" }
|
mockk = { module = "io.mockk:mockk", version = "1.14.9" }
|
||||||
compose-markdown = { module = "com.github.jeziellago:compose-markdown", version.ref = "composeMarkdown" }
|
compose-markdown = { module = "com.github.jeziellago:compose-markdown", version.ref = "composeMarkdown" }
|
||||||
|
androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "foundationVersion" }
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Reference in New Issue
Block a user