Skip to content

Commit 2e48680

Browse files
committed
- tutorial UI changes
1 parent d06436e commit 2e48680

10 files changed

Lines changed: 99 additions & 84 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ android {
167167
}
168168

169169
namespace = "be.scri"
170+
ndkVersion = "27.1.12297006"
170171

171172
applicationVariants.all {
172173
val variantName = this.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
@@ -333,6 +334,7 @@ dependencies {
333334
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.10.2")
334335
implementation("com.charleskorn.kaml:kaml:0.57.0")
335336
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7")
337+
336338
}
337339

338340
tasks.register<Copy>("moveFromi18n") {

app/src/main/java/be/scri/App.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import be.scri.ui.screens.settings.SettingsScreen
5252
import be.scri.ui.theme.ScribeTheme
5353
import kotlinx.coroutines.CoroutineScope
5454
import kotlinx.coroutines.launch
55+
import be.scri.ui.screens.tutorial.TutorialNavigator
5556

5657
/**
5758
* The root composable function that sets up the app's theme, navigation, and screen layout.
@@ -173,6 +174,17 @@ fun ScribeApp(
173174
onNavigateToDownloadData = {
174175
navController.navigate("download_data")
175176
},
177+
onTutorialClick = {
178+
navController.navigate("tutorial")
179+
180+
coroutineScope.launch {
181+
kotlinx.coroutines.delay(400)
182+
val aboutIndex = screens.indexOfFirst { it is BottomBarScreen.About }
183+
if (aboutIndex != -1) {
184+
pagerState.scrollToPage(aboutIndex)
185+
}
186+
}
187+
}
176188
)
177189
HintDialog(
178190
pagerState = pagerState,
@@ -245,6 +257,9 @@ fun ScribeApp(
245257
onWikiClick = {
246258
navController.navigate(Screen.WikimediaScribe.route)
247259
},
260+
onTutorialClick = {
261+
navController.navigate("tutorial")
262+
},
248263
resetHints = { resetHints() },
249264
context = context,
250265
)
@@ -264,6 +279,15 @@ fun ScribeApp(
264279
}
265280
}
266281

282+
composable("tutorial") {
283+
TutorialNavigator(
284+
onTutorialExit = {
285+
navController.popBackStack()
286+
},
287+
modifier = Modifier.padding(innerPadding)
288+
)
289+
}
290+
267291
composable("download_data") {
268292
DownloadDataScreen(
269293
onBackNavigation = {

app/src/main/java/be/scri/ui/screens/InstallationScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ fun InstallationScreen(
6464
isDark: Boolean,
6565
context: Context,
6666
onNavigateToDownloadData: () -> Unit,
67+
onTutorialClick: () -> Unit,
6768
modifier: Modifier = Modifier,
6869
) {
6970
var showTutorial by remember { mutableStateOf(false) }
@@ -305,7 +306,7 @@ fun InstallationScreen(
305306

306307
OutlinedButton(
307308
onClick = {
308-
showTutorial = true
309+
onTutorialClick()
309310
},
310311
modifier =
311312
Modifier

app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fun AboutScreen(
3434
onPrivacyPolicyClick: () -> Unit,
3535
onThirdPartyLicensesClick: () -> Unit,
3636
onWikiClick: () -> Unit,
37+
onTutorialClick: () -> Unit,
3738
resetHints: () -> Unit,
3839
context: Context,
3940
modifier: Modifier = Modifier,
@@ -60,6 +61,7 @@ fun AboutScreen(
6061
resetHints()
6162
},
6263
context = context,
64+
onTutorialClick = onTutorialClick,
6365
isConjugateApp = isConjugateApp,
6466
)
6567

app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,17 @@ fun feedbackAndSupportList(
118118
onRateScribeClick: () -> Unit,
119119
onMailClick: () -> Unit,
120120
onResetHintsClick: () -> Unit,
121+
onTutorialClick: () -> Unit,
121122
isConjugateApp: Boolean = false,
122123
): List<ScribeItem.ExternalLinkItem> =
123124
listOf(
125+
ScribeItem.ExternalLinkItem(
126+
leadingIcon = R.drawable.tutorial,
127+
title = R.string.i18n_app_installation_button_quick_tutorial,
128+
trailingIcon = R.drawable.right_arrow,
129+
url = null,
130+
onClick = { onTutorialClick() },
131+
),
124132
ScribeItem.ExternalLinkItem(
125133
leadingIcon = R.drawable.star,
126134
title =
@@ -276,6 +284,7 @@ object AboutUtil {
276284
onRateScribeClick: () -> Unit,
277285
onMailClick: () -> Unit,
278286
onResetHintsClick: () -> Unit,
287+
onTutorialClick : () -> Unit,
279288
context: Context,
280289
isConjugateApp: Boolean = false,
281290
): ScribeItemList =
@@ -287,6 +296,7 @@ object AboutUtil {
287296
onRateScribeClick,
288297
onMailClick,
289298
onResetHintsClick,
299+
onTutorialClick,
290300
isConjugateApp,
291301
),
292302
)

app/src/main/java/be/scri/ui/screens/tutorial/TutorialHomeScreen.kt

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fun TutorialHomeScreen(
5757
val textColor = MaterialTheme.colorScheme.onSurface
5858
val secondaryTextColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
5959
val dividerColor = MaterialTheme.colorScheme.outlineVariant
60-
60+
val headerColor = MaterialTheme.colorScheme.onBackground
6161
val chapters =
6262
listOf(
6363
TutorialChapter("Noun annotation", 0),
@@ -81,52 +81,40 @@ fun TutorialHomeScreen(
8181
Icon(
8282
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
8383
contentDescription = "Back",
84-
tint = MaterialTheme.colorScheme.primary,
84+
tint = MaterialTheme.colorScheme.onBackground,
8585
modifier = Modifier.size(24.dp),
8686
)
8787
Text(
88-
text = "Home",
89-
color = MaterialTheme.colorScheme.primary,
88+
text = "About",
89+
color = MaterialTheme.colorScheme.onBackground,
9090
fontSize = 16.sp,
9191
)
92-
}
9392

94-
Spacer(modifier = Modifier.height(24.dp))
9593

96-
// Info banner
97-
Card(
98-
shape = RoundedCornerShape(12.dp),
99-
colors = CardDefaults.cardColors(containerColor = cardBackground),
100-
modifier = Modifier.fillMaxWidth(),
101-
) {
102-
Row(
103-
modifier = Modifier.padding(16.dp),
104-
verticalAlignment = Alignment.CenterVertically,
105-
) {
106-
Text(
107-
text = "\uD83D\uDCA1",
108-
fontSize = 20.sp,
109-
modifier = Modifier.padding(end = 12.dp),
110-
)
111-
Text(
112-
text = "Make sure you select the desired Scribe keyboard by pressing \uD83C\uDF10 when typing.",
113-
color = textColor,
114-
fontSize = 14.sp,
115-
modifier = Modifier.weight(1f),
116-
)
117-
}
11894
}
95+
Spacer(modifier = Modifier.height(24.dp))
96+
97+
Text(
98+
text = "Quick tutorial",
99+
color = headerColor,
100+
fontSize = 28.sp,
101+
fontWeight = FontWeight.Bold,
102+
modifier = Modifier.padding(horizontal = 8.dp),
103+
)
119104

120105
Spacer(modifier = Modifier.height(16.dp))
121106

107+
108+
122109
// Intro text
123110
Card(
124111
shape = RoundedCornerShape(12.dp),
125112
colors = CardDefaults.cardColors(containerColor = cardBackground),
126113
modifier = Modifier.fillMaxWidth(),
127114
) {
128115
Text(
129-
text = "This quick tutorial will show you how to use Scribe to support writing in your second language.",
116+
text = "This quick tutorial will show you how to use Scribe to support writing in your second language. " +
117+
"\nMake sure you select the desired Scribe keyboard by pressing \uD83C\uDF10 when typing.",
130118
color = textColor,
131119
fontSize = 14.sp,
132120
modifier = Modifier.padding(16.dp),

app/src/main/java/be/scri/ui/screens/tutorial/TutorialNavigator.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.compose.runtime.mutableIntStateOf
99
import androidx.compose.runtime.mutableStateOf
1010
import androidx.compose.runtime.remember
1111
import androidx.compose.runtime.setValue
12+
import androidx.compose.ui.Modifier
1213

1314
/**
1415
* The main tutorial navigation controller.
@@ -18,7 +19,8 @@ import androidx.compose.runtime.setValue
1819
* @param onTutorialExit Callback when the user exits the tutorial (back to About tab).
1920
*/
2021
@Composable
21-
fun TutorialNavigator(onTutorialExit: () -> Unit) {
22+
fun TutorialNavigator(onTutorialExit: () -> Unit,
23+
modifier: Modifier = Modifier) {
2224
var currentScreen by remember { mutableStateOf("home") }
2325
var currentChapterIndex by remember { mutableIntStateOf(0) }
2426
var currentStepIndex by remember { mutableIntStateOf(0) }
@@ -49,6 +51,7 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
4951
when (currentScreen) {
5052
"home" -> {
5153
TutorialHomeScreen(
54+
modifier = modifier,
5255
onBackPress = onTutorialExit,
5356
onChapterSelect = { chapterIndex ->
5457
currentChapterIndex = chapterIndex
@@ -73,10 +76,10 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
7376
val isLastStep = isLastStepInChapter && (isLastChapter || !isFullTutorial)
7477

7578
TutorialStepScreen(
79+
modifier = modifier,
7680
chapterTitle = chapterTitle,
7781
step = step,
7882
isLastStep = isLastStep,
79-
showQuickTutorialHeader = !isFullTutorial && currentStepIndex == 0,
8083
onBackPress = {
8184
when {
8285
currentStepIndex > 0 -> {
@@ -92,9 +95,6 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
9295
}
9396
}
9497
},
95-
onClosePress = {
96-
currentScreen = "home"
97-
},
9898
onNextPress = {
9999
when {
100100
!isLastStepInChapter -> {

app/src/main/java/be/scri/ui/screens/tutorial/TutorialStepScreen.kt

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import android.content.Context
66
import android.provider.Settings
77
import androidx.compose.foundation.background
88
import androidx.compose.foundation.border
9+
import androidx.compose.foundation.clickable
910
import androidx.compose.foundation.isSystemInDarkTheme
1011
import androidx.compose.foundation.layout.Arrangement
1112
import androidx.compose.foundation.layout.Column
@@ -20,14 +21,12 @@ import androidx.compose.foundation.shape.RoundedCornerShape
2021
import androidx.compose.foundation.text.BasicTextField
2122
import androidx.compose.material.icons.Icons
2223
import androidx.compose.material.icons.automirrored.filled.KeyboardArrowLeft
23-
import androidx.compose.material.icons.filled.Close
2424
import androidx.compose.material3.Button
2525
import androidx.compose.material3.ButtonDefaults
2626
import androidx.compose.material3.Card
2727
import androidx.compose.material3.CardDefaults
2828
import androidx.compose.material3.HorizontalDivider
2929
import androidx.compose.material3.Icon
30-
import androidx.compose.material3.IconButton
3130
import androidx.compose.material3.MaterialTheme
3231
import androidx.compose.material3.Text
3332
import androidx.compose.runtime.Composable
@@ -111,22 +110,18 @@ fun isScribeKeyboardActive(context: Context): Boolean {
111110
* @param chapterTitle The title of the current chapter (e.g., "Noun annotation").
112111
* @param step The [TutorialStep] data for the current step.
113112
* @param onBackPress Callback when the back button is pressed.
114-
* @param onClosePress Callback when the close (X) button is pressed.
115113
* @param onNextPress Callback when the Next/Finish button is pressed.
116114
* @param modifier Modifier for this composable.
117115
* @param isLastStep Whether this is the final step in the entire tutorial.
118-
* @param showQuickTutorialHeader Whether to show "Quick tutorial" back link instead of back arrow.
119116
*/
120117
@Composable
121118
fun TutorialStepScreen(
122119
chapterTitle: String,
123120
step: TutorialStep,
124121
onBackPress: () -> Unit,
125-
onClosePress: () -> Unit,
126122
onNextPress: () -> Unit,
127123
modifier: Modifier = Modifier,
128124
isLastStep: Boolean = false,
129-
showQuickTutorialHeader: Boolean = false,
130125
) {
131126
val context = LocalContext.current
132127
var isScribeActive by remember { mutableStateOf(isScribeKeyboardActive(context)) }
@@ -155,7 +150,6 @@ fun TutorialStepScreen(
155150
if (!isScribeActive) {
156151
WrongKeyboardScreen(
157152
onBackPress = onBackPress,
158-
onClosePress = onClosePress,
159153
)
160154
return
161155
}
@@ -200,39 +194,24 @@ fun TutorialStepScreen(
200194
Modifier
201195
.fillMaxWidth()
202196
.padding(horizontal = 8.dp, vertical = 12.dp),
203-
horizontalArrangement = Arrangement.SpaceBetween,
197+
horizontalArrangement = Arrangement.Start,
204198
verticalAlignment = Alignment.CenterVertically,
205199
) {
206-
IconButton(onClick = onBackPress) {
207-
if (showQuickTutorialHeader) {
208-
Row(verticalAlignment = Alignment.CenterVertically) {
209-
Icon(
210-
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
211-
contentDescription = "Back",
212-
tint = headerColor,
213-
)
214-
Text(
215-
text = "Quick tutorial",
216-
color = headerColor,
217-
fontSize = 14.sp,
218-
)
219-
}
220-
} else {
221-
Icon(
222-
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
223-
contentDescription = "Back",
224-
tint = headerColor,
225-
modifier = Modifier.size(28.dp),
226-
)
227-
}
228-
}
229-
IconButton(onClick = onClosePress) {
200+
Row(
201+
verticalAlignment = Alignment.CenterVertically,
202+
modifier = Modifier.clickable { onBackPress() }.padding(8.dp)
203+
) {
230204
Icon(
231-
imageVector = Icons.Filled.Close,
232-
contentDescription = "Close tutorial",
205+
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
206+
contentDescription = "Back",
233207
tint = headerColor,
234208
modifier = Modifier.size(24.dp),
235209
)
210+
Text(
211+
text = "Quick tutorial",
212+
color = headerColor,
213+
fontSize = 16.sp,
214+
)
236215
}
237216
}
238217

@@ -257,7 +236,7 @@ fun TutorialStepScreen(
257236
.padding(horizontal = 20.dp)
258237
.border(
259238
width = 2.dp,
260-
color = primaryColor,
239+
color = Color.Transparent,
261240
shape = RoundedCornerShape(12.dp),
262241
),
263242
) {

0 commit comments

Comments
 (0)