Skip to content

Commit

Permalink
Small refactoring of naming and states on writing screen
Browse files Browse the repository at this point in the history
  • Loading branch information
syt0r committed May 1, 2024
1 parent 709bcfa commit 9231e68
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@ import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.neverEqualPolicy
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
Expand Down Expand Up @@ -71,6 +69,8 @@ class StrokeInputState(
) {

val internalShowStroke = mutableStateOf(keepLastDrawnStroke)
val internalPath = mutableStateOf(Path(), neverEqualPolicy())
val internalDrawAreaSize = mutableStateOf(0)

fun hideStroke() {
internalShowStroke.value = false
Expand All @@ -94,34 +94,33 @@ fun StrokeInput(
stokeWidth: Float = StrokeWidth
) {

val drawPathState = remember { mutableStateOf(Path(), neverEqualPolicy()) }
var areaSize by remember { mutableStateOf(0) }

Canvas(
modifier = modifier
.then(ExcludeNavigationGesturesModifier)
.onGloballyPositioned { areaSize = it.size.height }
.onGloballyPositioned { state.internalDrawAreaSize.value = it.size.height }
.pointerInput(Unit) {
detectDragGestures(
onDragStart = {
state.internalShowStroke.value = true
drawPathState.value = Path().apply {
val areaSize = state.internalDrawAreaSize.value
state.internalPath.value = Path().apply {
moveTo(
it.x / areaSize * KanjiSize,
it.y / areaSize * KanjiSize
)
}
state.internalShowStroke.value = true
},
onDrag = { _, dragAmount ->
drawPathState.value = drawPathState.value.apply {
val areaSize = state.internalDrawAreaSize.value
state.internalPath.value = state.internalPath.value.apply {
relativeLineTo(
dragAmount.x / areaSize * KanjiSize,
dragAmount.y / areaSize * KanjiSize
)
}
},
onDragEnd = {
onUserPathDrawn(drawPathState.value)
onUserPathDrawn(state.internalPath.value)
if (!state.keepLastDrawnStroke) {
state.internalShowStroke.value = false
}
Expand All @@ -131,8 +130,11 @@ fun StrokeInput(
) {
if (state.internalShowStroke.value) {
clipRect {
val path = drawPathState.value
drawKanjiStroke(path, color, stokeWidth)
drawKanjiStroke(
path = state.internalPath.value,
color = color,
width = stokeWidth
)
}
}
}
Expand Down Expand Up @@ -165,19 +167,3 @@ fun parseKanjiStrokes(strokes: List<String>): List<Path> {
return strokes.map { SvgCommandParser.parse(it) }
.map { SvgPathCreator.convert(it) }
}

//@Preview(showBackground = true, showSystemUi = true)
//@Composable
//private fun KanjiPreview() {
// AppTheme {
// Column {
// Kanji(
// modifier = Modifier
// .size(200.dp)
// .background(MaterialTheme.colorScheme.background),
// strokes = PreviewKanji.strokes
// )
// }
//
// }
//}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ContentTransform
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.animation.core.updateTransition
import androidx.compose.animation.fadeIn
Expand All @@ -15,11 +14,9 @@ import androidx.compose.animation.togetherWith
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.focusable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
Expand Down Expand Up @@ -52,7 +49,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
Expand Down Expand Up @@ -174,7 +170,7 @@ fun WritingPracticeInputSection(

is WritingReviewState.SingleStrokeInput -> {
SingleStrokeInputContent(
data = data,
reviewState = data,
onStrokeDrawn = onSingleStrokeSubmit,
hintClicksFlow = hintClicksSharedFlow
)
Expand Down Expand Up @@ -307,7 +303,7 @@ private fun BoxScope.MultipleStrokeInputContent(

@Composable
private fun SingleStrokeInputContent(
data: WritingReviewState.SingleStrokeInput,
reviewState: WritingReviewState.SingleStrokeInput,
onStrokeDrawn: (SingleStrokeInputData) -> Unit,
hintClicksFlow: Flow<Unit>
) {
Expand All @@ -322,49 +318,49 @@ private fun SingleStrokeInputContent(
derivedStateOf {
max(
a = 0,
b = data.drawnStrokesCount.value - if (isAnimatingCorrectStroke.value) 1 else 0
b = reviewState.drawnStrokesCount.value - if (isAnimatingCorrectStroke.value) 1 else 0
)
}
}

Kanji(
strokes = data.characterDetails.strokes.take(adjustedDrawnStrokesCount.value),
strokes = reviewState.characterDetails.strokes.take(adjustedDrawnStrokesCount.value),
modifier = Modifier.fillMaxSize()
)

when (data.isStudyMode) {
when (reviewState.isStudyMode) {
true -> {
StudyStroke(
strokes = data.characterDetails.strokes,
strokes = reviewState.characterDetails.strokes,
drawnStrokesCount = adjustedDrawnStrokesCount,
hintClicksFlow = hintClicksFlow
)
}

false -> {
HintStroke(
inputState = data,
reviewState = reviewState,
hintClicksFlow = hintClicksFlow
)
}
}

ErrorFadeOutStroke(
data = remember { mistakeStrokeAnimations.consumeAsFlow() },
mistakeFlow = remember { mistakeStrokeAnimations.consumeAsFlow() },
onAnimationEnd = { }
)

CorrectMovingStroke(
data = remember { correctStrokeAnimations.consumeAsFlow() },
correctFlow = remember { correctStrokeAnimations.consumeAsFlow() },
onAnimationEnd = { isAnimatingCorrectStroke.value = false }
)

val shouldShowStrokeInput by remember {
derivedStateOf { data.characterDetails.strokes.size > data.drawnStrokesCount.value }
derivedStateOf { reviewState.characterDetails.strokes.size > reviewState.drawnStrokesCount.value }
}

LaunchedEffect(Unit) {
data.inputProcessingResults.collect {
reviewState.inputProcessingResults.collect {
inputState.hideStroke()
when (it) {
is StrokeProcessingResult.Correct -> {
Expand All @@ -385,7 +381,7 @@ private fun SingleStrokeInputContent(
onStrokeDrawn(
SingleStrokeInputData(
userPath = drawnPath,
kanjiPath = data.characterDetails.strokes[data.drawnStrokesCount.value]
kanjiPath = reviewState.characterDetails.strokes[reviewState.drawnStrokesCount.value]
)
)

Expand Down Expand Up @@ -539,11 +535,11 @@ private fun InputDecorations(

@Composable
fun HintStroke(
inputState: WritingReviewState.SingleStrokeInput,
reviewState: WritingReviewState.SingleStrokeInput,
hintClicksFlow: Flow<Unit>
) {

val currentState by rememberUpdatedState(inputState)
val currentState by rememberUpdatedState(reviewState)

val stroke = remember { mutableStateOf<Path?>(null, neverEqualPolicy()) }
val strokeDrawProgress = remember { Animatable(initialValue = 0f) }
Expand Down Expand Up @@ -581,15 +577,15 @@ fun HintStroke(

@Composable
fun ErrorFadeOutStroke(
data: Flow<StrokeProcessingResult.Mistake>,
mistakeFlow: Flow<StrokeProcessingResult.Mistake>,
onAnimationEnd: () -> Unit
) {

val lastData = remember { mutableStateOf<StrokeProcessingResult.Mistake?>(null) }
val strokeAlpha = remember { Animatable(initialValue = 0f) }

LaunchedEffect(Unit) {
data.collect {
mistakeFlow.collect {
lastData.value = it
strokeAlpha.snapTo(1f)
strokeAlpha.animateTo(0f, tween(600))
Expand All @@ -611,15 +607,15 @@ fun ErrorFadeOutStroke(

@Composable
fun CorrectMovingStroke(
data: Flow<StrokeProcessingResult.Correct>,
correctFlow: Flow<StrokeProcessingResult.Correct>,
onAnimationEnd: () -> Unit
) {

val lastData = remember { mutableStateOf<StrokeProcessingResult.Correct?>(null) }
val strokeLength = remember { Animatable(initialValue = 0f) }

LaunchedEffect(Unit) {
data.collect {
correctFlow.collect {
lastData.value = it
strokeLength.snapTo(0f)
strokeLength.animateTo(1f)
Expand Down

0 comments on commit 9231e68

Please sign in to comment.