Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 85 additions & 27 deletions app/src/main/java/be/scri/ui/screens/tutorial/TutorialContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,75 +12,133 @@ object TutorialContent {
* Chapter 1: Noun Annotation.
* Teaches users about gender tags that appear when typing nouns.
*/
val nounAnnotationSteps =
listOf(
fun getNounAnnotationSteps(languageCode: String): List<TutorialStep> {
val (fatherWord, fatherTag, fatherGender) =
when (languageCode) {
"en" -> Triple("father", "M", "Masculine")
"es" -> Triple("padre", "M", "Masculino")
"fr" -> Triple("père", "M", "Masculin")
"it" -> Triple("padre", "M", "Maschile")
"pt" -> Triple("pai", "M", "Masculino")
"ru" -> Triple("отец", "M", "Мужской")
"sv" -> Triple("far", "C", "Common")
else -> Triple("Vater", "M", "Maskulin")
}

val (motherWord, motherTag, motherGender) =
when (languageCode) {
"en" -> Triple("mother", "F", "Feminine")
"es" -> Triple("madre", "F", "Femenino")
"fr" -> Triple("mère", "F", "Féminin")
"it" -> Triple("madre", "F", "Femminile")
"pt" -> Triple("mãe", "F", "Feminino")
"ru" -> Triple("мать", "F", "Женский")
"sv" -> Triple("mor", "C", "Common")
else -> Triple("Mutter", "F", "Feminin")
}

return listOf(
TutorialStep(
instruction =
"Write the word \"Vater\". Notice the word suggestions " +
"Write the word \"$motherWord\". Notice the word suggestions " +
"that appear on the keyboard's top bar.\n\n" +
"Then, press space. You will see the word's gender " +
"tag on the keyboard's top bar \u2013 in this case, \"M\" for Maskulin.",
expectedWord = "Vater",
"tag on the keyboard's top bar \u2013 in this case, \"$motherTag\" for $motherGender.",
expectedWord = motherWord,
),
TutorialStep(
instruction =
"Now write the word \"Mutter\" and then press space. " +
"The gender tag will be \"F\", for Feminin.",
expectedWord = "Mutter",
"Now write the word \"$fatherWord\" and then press space. " +
"The gender tag will be \"$fatherTag\", for $fatherGender.",
expectedWord = fatherWord,
),
)
}

/**
* Chapter 2: Word Translation.
* Teaches users how to use the Translate command via the Scribe key.
*/
val wordTranslationSteps =
listOf(
fun wordTranslationSteps(languageCode: String): List<TutorialStep> {
val translation =
when (languageCode) {
"en" -> "Translate"
"es" -> "Traducir"
"fr" -> "Traduire"
"it" -> "Tradurre"
"pt" -> "Traduzir"
"ru" -> "Перевести"
"sv" -> "Översätt"
else -> "Übersetzen"
}
return listOf(
TutorialStep(
instruction =
"Let's translate! Tap the \u27A1 Scribe key on the top-left " +
"corner of your keyboard, and select \u00DCbersetzen.\n\n" +
"Let's translate! Tap the pencil-like Scribe key on the top-left " +
"corner of your keyboard, and select $translation.\n\n" +
"Then write the word you want to translate, press \u25B6, " +
"and the translation will be returned to you.",
hint = "If your second language is not German, change the language in your keyboard.",
requiresValidation = false,
),
)
}

val verbConjugationSteps =
listOf(
fun verbConjugationSteps(languageCode: String): List<TutorialStep> {
val conjugation =
when (languageCode) {
"en" -> "Conjugate"
"es" -> "Conjugar"
"fr" -> "Conjuguer"
"it" -> "Coniugare"
"pt" -> "Conjugar"
"ru" -> "Спрягать"
"sv" -> "Konjugera"
else -> "Konjugieren"
}
return listOf(
TutorialStep(
instruction =
"On to the verbs. Tap the \u27A1 Scribe key on the top-left " +
"corner of your keyboard, and select Konjugieren.\n\n" +
"On to the verbs. Tap the pencil-like Scribe key on the top-left " +
"corner of your keyboard, and select $conjugation.\n\n" +
"Write the verb you want to conjugate, press \u25B6, and " +
"you will see a table with all the verb tenses. Select " +
"the one you need and it will be inserted!",
hint = "If your second language is not German, change the language in your keyboard.",
requiresValidation = false,
),
)
}

val nounPluralsSteps =
listOf(
fun nounPluralsSteps(languageCode: String): List<TutorialStep> {
val plural =
when (languageCode) {
"en" -> "Plural"
"es" -> "Plural"
"fr" -> "Pluriel"
"it" -> "Plurale"
"pt" -> "Plural"
"ru" -> "Множ-ое"
"sv" -> "Plural"
else -> "Plural"
}
return listOf(
TutorialStep(
instruction =
"Finding the plural of a noun with Scribe is easy. Tap " +
"the \u27A1 Scribe key on the top-left corner of your " +
"keyboard, and select Plural.\n\n" +
"keyboard, and select $plural.\n\n" +
"Then write the noun you want the plural for, press " +
"\u25B6, and the plural will be returned to you.",
hint = "If your second language is not German, change the language in your keyboard.",
requiresValidation = false,
),
)
}

/** Returns all chapters as a list of pairs (title, steps). */
fun getAllChapters(): List<Pair<String, List<TutorialStep>>> =
fun getAllChapters(languageCode: String = "de"): List<Pair<String, List<TutorialStep>>> =
listOf(
"Noun annotation" to nounAnnotationSteps,
"Word translation" to wordTranslationSteps,
"Verb conjugation" to verbConjugationSteps,
"Noun plurals" to nounPluralsSteps,
"Noun annotation" to getNounAnnotationSteps(languageCode),
"Word translation" to wordTranslationSteps(languageCode),
"Verb conjugation" to verbConjugationSteps(languageCode),
"Noun plurals" to nounPluralsSteps(languageCode),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,40 @@

package be.scri.ui.screens.tutorial

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.provider.Settings
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext

private fun getCurrentScribeLanguage(context: Context): String {
val currentImeId =
Settings.Secure.getString(
context.contentResolver,
Settings.Secure.DEFAULT_INPUT_METHOD,
) ?: ""

return when {
currentImeId.contains("EnglishKeyboardIME") -> "en"
currentImeId.contains("SpanishKeyboardIME") -> "es"
currentImeId.contains("FrenchKeyboardIME") -> "fr"
currentImeId.contains("ItalianKeyboardIME") -> "it"
currentImeId.contains("PortugueseKeyboardIME") -> "pt"
currentImeId.contains("RussianKeyboardIME") -> "ru"
currentImeId.contains("SwedishKeyboardIME") -> "sv"
else -> "de"
}
}

/**
* The main tutorial navigation controller.
Expand All @@ -28,7 +54,39 @@ fun TutorialNavigator(
var currentStepIndex by remember { mutableIntStateOf(0) }
var isFullTutorial by remember { mutableStateOf(false) }

val allChapters = TutorialContent.getAllChapters()
val context = LocalContext.current

var activeLanguageCode by remember {
mutableStateOf(getCurrentScribeLanguage(context))
}

DisposableEffect(context) {
val receiver =
object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent,
) {
if (intent.action == Intent.ACTION_INPUT_METHOD_CHANGED) {
activeLanguageCode = getCurrentScribeLanguage(context)
}
}
}

context.registerReceiver(
receiver,
IntentFilter(Intent.ACTION_INPUT_METHOD_CHANGED),
)

onDispose {
context.unregisterReceiver(receiver)
}
}

val allChapters =
remember(activeLanguageCode) {
TutorialContent.getAllChapters(activeLanguageCode)
}

BackHandler {
if (currentScreen == "home") {
Expand Down
34 changes: 18 additions & 16 deletions app/src/main/java/be/scri/ui/screens/tutorial/TutorialStepScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ enum class InputValidationState {
data class TutorialStep(
val instruction: String,
val expectedWord: String = "",
val hint: String = "If your second language is not German, change the language in your keyboard.",
val hint: String = "",
val successMessage: String = "Great! Press Next to continue.",
val errorMessage: String = "",
val requiresValidation: Boolean = true,
Expand Down Expand Up @@ -171,7 +171,7 @@ fun TutorialStepScreen(
when {
!step.requiresValidation -> InputValidationState.CORRECT
userInput.isEmpty() -> InputValidationState.EMPTY
userInput.trim().equals(step.expectedWord, ignoreCase = false) -> InputValidationState.CORRECT
userInput.trim().equals(step.expectedWord, ignoreCase = true) -> InputValidationState.CORRECT
else -> InputValidationState.INCORRECT
}

Expand Down Expand Up @@ -254,19 +254,21 @@ fun TutorialStepScreen(
Spacer(modifier = Modifier.height(12.dp))

// Language hint
Row(
verticalAlignment = Alignment.Top,
) {
Text(
text = "\uD83C\uDF10 ",
fontSize = 14.sp,
)
Text(
text = step.hint,
color = textSecondaryColor,
fontSize = 13.sp,
lineHeight = 18.sp,
)
if (step.hint.isNotEmpty()) {
Row(
verticalAlignment = Alignment.Top,
) {
Text(
text = "\uD83C\uDF10 ",
fontSize = 14.sp,
)
Text(
text = step.hint,
color = textSecondaryColor,
fontSize = 13.sp,
lineHeight = 18.sp,
)
}
}

Spacer(modifier = Modifier.height(16.dp))
Expand Down Expand Up @@ -325,7 +327,7 @@ fun TutorialStepScreen(
}
}

Spacer(modifier = Modifier.weight(1f))
Spacer(modifier = Modifier.height(32.dp))

// Next / Finish button
Button(
Expand Down
Loading