Skip to content

Commit 4ac1c6b

Browse files
- New BoggleTypography class implemented to centralize typography used.
- FoundWordsList Composable created.
1 parent 5e61098 commit 4ac1c6b

9 files changed

Lines changed: 178 additions & 74 deletions

File tree

composeApp/src/commonMain/composeResources/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@
2020
<string name="word_counter_7">7</string>
2121
<string name="word_counter_more">8+</string>
2222
<string name="game_progress">%1$d%</string>
23+
<string name="definition_body">%1$s: %2$s</string>
2324
</resources>

composeApp/src/commonMain/kotlin/com/alejandrorios/bogglemultiplatform/ui/components/BoggleDie.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,9 @@ import androidx.compose.ui.Modifier
1515
import androidx.compose.ui.draw.clip
1616
import androidx.compose.ui.graphics.Color
1717
import androidx.compose.ui.layout.layout
18-
import androidx.compose.ui.text.font.FontWeight
19-
import androidx.compose.ui.text.style.TextAlign
2018
import androidx.compose.ui.unit.dp
21-
import androidx.compose.ui.unit.sp
2219
import com.alejandrorios.bogglemultiplatform.ui.theme.BoggleTheme
20+
import com.alejandrorios.bogglemultiplatform.ui.theme.boardLetter
2321
import com.alejandrorios.bogglemultiplatform.utils.cardElevationZero
2422
import com.alejandrorios.bogglemultiplatform.utils.isQ
2523
import org.jetbrains.compose.ui.tooling.preview.Preview
@@ -62,10 +60,8 @@ fun BoggleDie(
6260
) {
6361
Text(
6462
text = letter,
65-
fontSize = if (letter.isQ()) 32.sp else 38.sp,
63+
style = BoggleTheme.typography.boardLetter(letter.isQ()),
6664
color = getLetterColor(selected),
67-
fontWeight = FontWeight.Bold,
68-
textAlign = TextAlign.Center,
6965
modifier = Modifier.padding(BoggleTheme.dimensions.spacing.xxs)
7066
)
7167
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.alejandrorios.bogglemultiplatform.ui.components
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.interaction.MutableInteractionSource
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.heightIn
8+
import androidx.compose.foundation.lazy.LazyColumn
9+
import androidx.compose.foundation.lazy.items
10+
import androidx.compose.material3.Text
11+
import androidx.compose.runtime.Composable
12+
import androidx.compose.runtime.remember
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.graphics.Color
15+
import androidx.compose.ui.unit.dp
16+
import com.alejandrorios.bogglemultiplatform.ui.theme.BoggleTheme
17+
18+
@Composable
19+
fun FoundWordsList(
20+
words: List<String>,
21+
onWordClick: (String) -> Unit,
22+
modifier: Modifier = Modifier,
23+
maxHeight: Int = 300
24+
) {
25+
LazyColumn(
26+
modifier = modifier
27+
.fillMaxWidth()
28+
.heightIn(max = maxHeight.dp),
29+
verticalArrangement = Arrangement.spacedBy(BoggleTheme.dimensions.spacing.xs)
30+
) {
31+
items(
32+
items = words,
33+
key = { word -> word }
34+
) { word ->
35+
FoundWordItem(
36+
word = word,
37+
onClick = { onWordClick(word) }
38+
)
39+
}
40+
}
41+
}
42+
43+
@Composable
44+
private fun FoundWordItem(
45+
word: String,
46+
onClick: () -> Unit,
47+
modifier: Modifier = Modifier
48+
) {
49+
Text(
50+
text = word,
51+
style = BoggleTheme.typography.foundWord,
52+
color = Color.Black,
53+
modifier = modifier
54+
.fillMaxWidth()
55+
.clickable(
56+
onClick = onClick,
57+
indication = null,
58+
interactionSource = remember { MutableInteractionSource() }
59+
)
60+
)
61+
}
62+

composeApp/src/commonMain/kotlin/com/alejandrorios/bogglemultiplatform/ui/components/WordCounter.kt

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,19 @@ package com.alejandrorios.bogglemultiplatform.ui.components
33
import androidx.compose.animation.AnimatedVisibility
44
import androidx.compose.animation.core.animateFloatAsState
55
import androidx.compose.foundation.background
6-
import androidx.compose.foundation.clickable
7-
import androidx.compose.foundation.interaction.MutableInteractionSource
6+
import androidx.compose.foundation.layout.Arrangement
87
import androidx.compose.foundation.layout.Box
98
import androidx.compose.foundation.layout.Column
109
import androidx.compose.foundation.layout.padding
1110
import androidx.compose.foundation.shape.RoundedCornerShape
12-
import androidx.compose.foundation.text.BasicText
1311
import androidx.compose.material3.CircularProgressIndicator
1412
import androidx.compose.material3.ProgressIndicatorDefaults
1513
import androidx.compose.material3.Text
1614
import androidx.compose.runtime.Composable
17-
import androidx.compose.runtime.remember
1815
import androidx.compose.ui.Alignment
1916
import androidx.compose.ui.Modifier
2017
import androidx.compose.ui.graphics.Color
2118
import androidx.compose.ui.graphics.StrokeCap
22-
import androidx.compose.ui.text.SpanStyle
23-
import androidx.compose.ui.text.TextStyle
24-
import androidx.compose.ui.text.buildAnnotatedString
25-
import androidx.compose.ui.text.style.TextAlign
26-
import androidx.compose.ui.text.withStyle
27-
import androidx.compose.ui.unit.sp
2819
import com.alejandrorios.bogglemultiplatform.data.models.WordPair
2920
import com.alejandrorios.bogglemultiplatform.ui.theme.BoggleTheme
3021

@@ -45,13 +36,13 @@ fun WordCounter(
4536

4637
Column(
4738
modifier = Modifier.padding(horizontal = BoggleTheme.dimensions.spacing.md),
39+
verticalArrangement = Arrangement.spacedBy(BoggleTheme.dimensions.spacing.sm),
4840
horizontalAlignment = Alignment.CenterHorizontally,
4941
) {
5042
Text(
5143
text = numberOfLetters,
52-
fontSize = 14.sp
44+
style = BoggleTheme.typography.counter,
5345
)
54-
VerticalSpacer()
5546
Box(
5647
modifier = Modifier.background(
5748
color = Color(0xFFEBEBEB),
@@ -61,7 +52,7 @@ fun WordCounter(
6152
) {
6253
Text(
6354
text = "${wordPair.wordsTotal - wordPair.wordsFound.size}",
64-
fontSize = 14.sp
55+
style = BoggleTheme.typography.counter,
6556
)
6657
CircularProgressIndicator(
6758
progress = { animatedProgress },
@@ -70,23 +61,10 @@ fun WordCounter(
7061
strokeCap = StrokeCap.Round
7162
)
7263
}
73-
VerticalSpacer()
74-
for (word in wordPair.wordsFound) {
75-
BasicText(
76-
text = buildAnnotatedString {
77-
pushStringAnnotation(tag = "get_word_definition", annotation = word)
78-
withStyle(style = SpanStyle(fontSize = 13.sp, color = Color.Black)) {
79-
append(word)
80-
}
81-
pop()
82-
},
83-
style = TextStyle(textAlign = TextAlign.Start),
84-
modifier = Modifier.clickable(
85-
indication = null,
86-
interactionSource = remember { MutableInteractionSource() }
87-
) { onWordClick(word) }
88-
)
89-
}
64+
FoundWordsList(
65+
words = wordPair.wordsFound,
66+
onWordClick = onWordClick,
67+
)
9068
}
9169
}
9270
}

composeApp/src/commonMain/kotlin/com/alejandrorios/bogglemultiplatform/ui/screen/BoggleScreen.kt

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.alejandrorios.bogglemultiplatform.ui.screen
22

3+
import androidx.compose.foundation.layout.Arrangement
34
import androidx.compose.foundation.layout.Box
45
import androidx.compose.foundation.layout.Column
56
import androidx.compose.foundation.layout.PaddingValues
@@ -16,7 +17,6 @@ import androidx.compose.material.icons.outlined.Plagiarism
1617
import androidx.compose.material.icons.outlined.Rotate90DegreesCw
1718
import androidx.compose.material3.AlertDialog
1819
import androidx.compose.material3.Button
19-
import androidx.compose.material3.ButtonDefaults
2020
import androidx.compose.material3.Checkbox
2121
import androidx.compose.material3.CircularProgressIndicator
2222
import androidx.compose.material3.FilledIconButton
@@ -34,8 +34,8 @@ import androidx.compose.ui.Alignment
3434
import androidx.compose.ui.Modifier
3535
import androidx.compose.ui.graphics.Color
3636
import androidx.compose.ui.unit.dp
37-
import androidx.compose.ui.unit.sp
3837
import boggle_multiplatform.composeapp.generated.resources.Res
38+
import boggle_multiplatform.composeapp.generated.resources.definition_body
3939
import boggle_multiplatform.composeapp.generated.resources.game_progress
4040
import boggle_multiplatform.composeapp.generated.resources.label_definition
4141
import boggle_multiplatform.composeapp.generated.resources.label_game_finished
@@ -103,9 +103,11 @@ fun BoggleScreen(
103103
title = { Text(stringResource(Res.string.label_definition)) },
104104
text = {
105105
Text(
106-
"${uiState.definition.word}: ${
107-
uiState.definition.meanings.first().definitions.first().definition
108-
}"
106+
stringResource(
107+
Res.string.definition_body,
108+
uiState.definitionWord,
109+
uiState.firstDefinition
110+
)
109111
)
110112
},
111113
)
@@ -146,8 +148,7 @@ fun BoggleScreen(
146148
Column(
147149
modifier = modifier
148150
.padding(innerPadding)
149-
.fillMaxWidth()
150-
.verticalScroll(rememberScrollState()),
151+
.fillMaxWidth(),
151152
horizontalAlignment = Alignment.CenterHorizontally
152153
) {
153154
Column(
@@ -157,18 +158,18 @@ fun BoggleScreen(
157158
Row {
158159
Text(
159160
text = stringResource(Res.string.total_words, uiState.result.size),
160-
fontSize = 24.sp
161+
style = BoggleTheme.typography.gameStatsLarge
161162
)
162163
HorizontalSpacer(spacing = BoggleTheme.dimensions.spacing.lg)
163164
Text(
164165
text = stringResource(Res.string.score, uiState.score),
165-
fontSize = 24.sp
166+
style = BoggleTheme.typography.gameStatsLarge
166167
)
167168
}
168169
VerticalSpacer(spacing = BoggleTheme.dimensions.spacing.md)
169170
Text(
170171
text = stringResource(Res.string.game_progress, uiState.progress),
171-
fontSize = 20.sp
172+
style = BoggleTheme.typography.gameStatsMedium
172173
)
173174
VerticalSpacer(spacing = BoggleTheme.dimensions.spacing.lg)
174175
BoggleBoard(
@@ -181,25 +182,34 @@ fun BoggleScreen(
181182
onRotateTriggered.value = false
182183
}
183184
VerticalSpacer(spacing = BoggleTheme.dimensions.spacing.xl)
184-
Row(verticalAlignment = Alignment.CenterVertically) {
185+
Row(
186+
verticalAlignment = Alignment.CenterVertically,
187+
horizontalArrangement = Arrangement.spacedBy(BoggleTheme.dimensions.spacing.sm),
188+
) {
185189
Checkbox(
186190
modifier = Modifier.size(BoggleTheme.dimensions.spacing.lg),
187191
checked = uiState.useAPI,
188192
onCheckedChange = onUseAPI
189193
)
190-
HorizontalSpacer()
191-
Text(text = stringResource(Res.string.use_api), fontSize = 20.sp)
192-
HorizontalSpacer()
194+
Text(
195+
text = stringResource(Res.string.use_api),
196+
style = BoggleTheme.typography.button,
197+
)
193198
Switch(
194199
checked = uiState.isEnglish,
195200
enabled = !uiState.useAPI,
196201
onCheckedChange = onChangeLanguage
197202
)
198-
HorizontalSpacer()
199-
Text(text = stringResource(Res.string.language), fontSize = 20.sp)
203+
Text(
204+
text = stringResource(Res.string.language),
205+
style = BoggleTheme.typography.button,
206+
)
200207
}
201208
VerticalSpacer()
202-
Row(verticalAlignment = Alignment.CenterVertically) {
209+
Row(
210+
verticalAlignment = Alignment.CenterVertically,
211+
horizontalArrangement = Arrangement.spacedBy(BoggleTheme.dimensions.spacing.sm),
212+
) {
203213
Button(
204214
onClick = onCreateNewGame,
205215
contentPadding = PaddingValues(
@@ -209,11 +219,10 @@ fun BoggleScreen(
209219
) {
210220
Text(
211221
text = stringResource(Res.string.new_game),
212-
fontSize = 20.sp,
222+
style = BoggleTheme.typography.button,
213223
color = Color.White
214224
)
215225
}
216-
HorizontalSpacer()
217226
FilledIconButton(
218227
enabled = !onRotateTriggered.value,
219228
onClick = {
@@ -226,7 +235,6 @@ fun BoggleScreen(
226235
)
227236
}
228237
)
229-
HorizontalSpacer()
230238
FilledIconButton(
231239
onClick = onGetHint,
232240
content = {

composeApp/src/commonMain/kotlin/com/alejandrorios/bogglemultiplatform/ui/screen/BoggleUiState.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,10 @@ data class BoggleUiState(
3737

3838
"${if (number.toFloat() % 1 == 0f) number.toInt() else number}"
3939
}
40+
41+
val definitionWord: String
42+
get() = definition?.word ?: ""
43+
44+
val firstDefinition: String
45+
get() = definition?.meanings?.first()?.definitions?.first()?.definition ?: ""
4046
}

composeApp/src/commonMain/kotlin/com/alejandrorios/bogglemultiplatform/ui/screen/BoggleViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ class BoggleViewModel(
261261
viewModelScope.launch(appCoroutineDispatchers.io + coroutineExceptionHandler) {
262262
repository.getDefinition(word).collect { result ->
263263
when (result) {
264-
is Failure -> {}
264+
is Failure -> println("Definition not found for $word")
265265
is Success -> _uiState.update { currentState ->
266266
if (isFromHint) {
267267
currentState.copy(hintDefinition = result.data[0])
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package com.alejandrorios.bogglemultiplatform.ui.theme
2+
3+
import androidx.compose.runtime.Immutable
4+
import androidx.compose.runtime.staticCompositionLocalOf
5+
import androidx.compose.ui.text.TextStyle
6+
import androidx.compose.ui.text.font.FontWeight
7+
import androidx.compose.ui.text.style.TextAlign
8+
import androidx.compose.ui.unit.sp
9+
10+
@Immutable
11+
data class BoggleTypography(
12+
val boardLetterLarge: TextStyle,
13+
val boardLetterMedium: TextStyle,
14+
val gameStatsLarge: TextStyle,
15+
val gameStatsMedium: TextStyle,
16+
val button: TextStyle,
17+
val counter: TextStyle,
18+
val foundWord: TextStyle
19+
)
20+
21+
fun BoggleTypography.boardLetter(isQ: Boolean = false): TextStyle {
22+
return if (isQ) boardLetterMedium else boardLetterLarge
23+
}
24+
25+
internal fun typography(): BoggleTypography {
26+
return BoggleTypography(
27+
boardLetterLarge = TextStyle(
28+
fontSize = 38.sp,
29+
fontWeight = FontWeight.Bold,
30+
textAlign = TextAlign.Center
31+
),
32+
boardLetterMedium = TextStyle(
33+
fontSize = 32.sp,
34+
fontWeight = FontWeight.Bold,
35+
textAlign = TextAlign.Center
36+
),
37+
gameStatsLarge = TextStyle(
38+
fontSize = 24.sp,
39+
fontWeight = FontWeight.Normal
40+
),
41+
gameStatsMedium = TextStyle(
42+
fontSize = 20.sp,
43+
fontWeight = FontWeight.Normal
44+
),
45+
button = TextStyle(
46+
fontSize = 20.sp,
47+
fontWeight = FontWeight.Medium
48+
),
49+
counter = TextStyle(
50+
fontSize = 14.sp,
51+
fontWeight = FontWeight.Normal
52+
),
53+
foundWord = TextStyle(
54+
fontSize = 13.sp,
55+
fontWeight = FontWeight.Normal,
56+
textAlign = TextAlign.Start
57+
)
58+
)
59+
}
60+
61+
internal val LocalTypography = staticCompositionLocalOf { typography() }

0 commit comments

Comments
 (0)