Skip to content
Merged
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
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ android {
}

namespace = "be.scri"
ndkVersion = "27.1.12297006"

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

}

tasks.register<Copy>("moveFromi18n") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ class AboutUtilInstrumentedTest {
fun testGetFeedbackAndSupportList() {
println("Testing getFeedbackAndSupportList...")

var tutorialClicked = false
var rateClicked = false
var mailClicked = false
var resetHintsClicked = false
Expand All @@ -177,6 +178,7 @@ class AboutUtilInstrumentedTest {
CompositionLocalProvider(LocalContext provides context) {
val feedbackList =
AboutUtil.getFeedbackAndSupportList(
onTutorialClick = { tutorialClicked = true },
onRateScribeClick = { rateClicked = true },
onMailClick = { mailClicked = true },
onResetHintsClick = { resetHintsClicked = true },
Expand All @@ -191,7 +193,7 @@ class AboutUtilInstrumentedTest {

// Test list is not empty.
assertThat(extractedItems).isNotEmpty()
assertThat(extractedItems).hasSize(5)
assertThat(extractedItems).hasSize(6) // Fixed: size is now 6

// Test each item has required fields.
extractedItems.forEach { item ->
Expand All @@ -204,25 +206,30 @@ class AboutUtilInstrumentedTest {
assertThat(linkItem.onClick).isNotNull()
}

// Test specific items.
val rateItem = extractedItems[0] as ScribeItem.ExternalLinkItem
// Test specific items
val tutorialItem = extractedItems[0] as ScribeItem.ExternalLinkItem
assertThat(tutorialItem.title).isEqualTo(R.string.i18n_app_installation_button_quick_tutorial)

val rateItem = extractedItems[1] as ScribeItem.ExternalLinkItem
assertThat(rateItem.leadingIcon).isEqualTo(R.drawable.star)
assertThat(rateItem.title).isEqualTo(R.string.i18n_app_about_feedback_rate_scribe)

val mailItem = extractedItems[2] as ScribeItem.ExternalLinkItem
val mailItem = extractedItems[3] as ScribeItem.ExternalLinkItem
assertThat(mailItem.leadingIcon).isEqualTo(R.drawable.mail_icon)
assertThat(mailItem.title).isEqualTo(R.string.i18n_app_about_feedback_send_email)

val hintsItem = extractedItems[4] as ScribeItem.ExternalLinkItem
val hintsItem = extractedItems[5] as ScribeItem.ExternalLinkItem
assertThat(hintsItem.leadingIcon).isEqualTo(R.drawable.light_bulb_icon)
assertThat(hintsItem.title).isEqualTo(R.string.i18n_app_about_feedback_reset_app_hints)

// Test onClick callbacks OUTSIDE of setContent
tutorialItem.onClick()
rateItem.onClick()
mailItem.onClick()
hintsItem.onClick()

// Verify callbacks were triggered.
assertThat(tutorialClicked).isTrue()
assertThat(rateClicked).isTrue()
assertThat(mailClicked).isTrue()
assertThat(resetHintsClicked).isTrue()
Expand Down
24 changes: 24 additions & 0 deletions app/src/main/java/be/scri/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import be.scri.ui.screens.download.DataDownloadViewModel
import be.scri.ui.screens.download.DownloadActions
import be.scri.ui.screens.download.DownloadDataScreen
import be.scri.ui.screens.settings.SettingsScreen
import be.scri.ui.screens.tutorial.TutorialNavigator
import be.scri.ui.theme.ScribeTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -173,6 +174,17 @@ fun ScribeApp(
onNavigateToDownloadData = {
navController.navigate("download_data")
},
onTutorialClick = {
navController.navigate("tutorial")

coroutineScope.launch {
kotlinx.coroutines.delay(400)
val aboutIndex = screens.indexOfFirst { it is BottomBarScreen.About }
if (aboutIndex != -1) {
pagerState.scrollToPage(aboutIndex)
}
}
},
)
HintDialog(
pagerState = pagerState,
Expand Down Expand Up @@ -245,6 +257,9 @@ fun ScribeApp(
onWikiClick = {
navController.navigate(Screen.WikimediaScribe.route)
},
onTutorialClick = {
navController.navigate("tutorial")
},
resetHints = { resetHints() },
context = context,
)
Expand All @@ -264,6 +279,15 @@ fun ScribeApp(
}
}

composable("tutorial") {
TutorialNavigator(
onTutorialExit = {
navController.popBackStack()
},
modifier = Modifier.padding(innerPadding),
)
}

composable("download_data") {
DownloadDataScreen(
onBackNavigation = {
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/be/scri/ui/screens/InstallationScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ fun InstallationScreen(
isDark: Boolean,
context: Context,
onNavigateToDownloadData: () -> Unit,
onTutorialClick: () -> Unit,
modifier: Modifier = Modifier,
) {
var showTutorial by remember { mutableStateOf(false) }
Expand Down Expand Up @@ -305,7 +306,7 @@ fun InstallationScreen(

OutlinedButton(
onClick = {
showTutorial = true
onTutorialClick()
},
modifier =
Modifier
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/be/scri/ui/screens/about/AboutScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ fun AboutScreen(
onPrivacyPolicyClick: () -> Unit,
onThirdPartyLicensesClick: () -> Unit,
onWikiClick: () -> Unit,
onTutorialClick: () -> Unit,
resetHints: () -> Unit,
context: Context,
modifier: Modifier = Modifier,
Expand All @@ -60,6 +61,7 @@ fun AboutScreen(
resetHints()
},
context = context,
onTutorialClick = onTutorialClick,
isConjugateApp = isConjugateApp,
)

Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/be/scri/ui/screens/about/AboutUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,17 @@ fun feedbackAndSupportList(
onRateScribeClick: () -> Unit,
onMailClick: () -> Unit,
onResetHintsClick: () -> Unit,
onTutorialClick: () -> Unit,
isConjugateApp: Boolean = false,
): List<ScribeItem.ExternalLinkItem> =
listOf(
ScribeItem.ExternalLinkItem(
leadingIcon = R.drawable.tutorial,
title = R.string.i18n_app_installation_button_quick_tutorial,
trailingIcon = R.drawable.right_arrow,
url = null,
onClick = { onTutorialClick() },
),
ScribeItem.ExternalLinkItem(
leadingIcon = R.drawable.star,
title =
Expand Down Expand Up @@ -276,6 +284,7 @@ object AboutUtil {
onRateScribeClick: () -> Unit,
onMailClick: () -> Unit,
onResetHintsClick: () -> Unit,
onTutorialClick: () -> Unit,
context: Context,
isConjugateApp: Boolean = false,
): ScribeItemList =
Expand All @@ -287,6 +296,7 @@ object AboutUtil {
onRateScribeClick,
onMailClick,
onResetHintsClick,
onTutorialClick,
isConjugateApp,
),
)
Expand Down
43 changes: 14 additions & 29 deletions app/src/main/java/be/scri/ui/screens/tutorial/TutorialHomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fun TutorialHomeScreen(
val textColor = MaterialTheme.colorScheme.onSurface
val secondaryTextColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.6f)
val dividerColor = MaterialTheme.colorScheme.outlineVariant

val headerColor = MaterialTheme.colorScheme.onBackground
val chapters =
listOf(
TutorialChapter("Noun annotation", 0),
Expand All @@ -81,41 +81,24 @@ fun TutorialHomeScreen(
Icon(
imageVector = Icons.AutoMirrored.Filled.KeyboardArrowLeft,
contentDescription = "Back",
tint = MaterialTheme.colorScheme.primary,
tint = MaterialTheme.colorScheme.onBackground,
modifier = Modifier.size(24.dp),
)
Text(
text = "Home",
color = MaterialTheme.colorScheme.primary,
text = "About",
color = MaterialTheme.colorScheme.onBackground,
fontSize = 16.sp,
)
}

Spacer(modifier = Modifier.height(24.dp))

// Info banner
Card(
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = cardBackground),
modifier = Modifier.fillMaxWidth(),
) {
Row(
modifier = Modifier.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = "\uD83D\uDCA1",
fontSize = 20.sp,
modifier = Modifier.padding(end = 12.dp),
)
Text(
text = "Make sure you select the desired Scribe keyboard by pressing \uD83C\uDF10 when typing.",
color = textColor,
fontSize = 14.sp,
modifier = Modifier.weight(1f),
)
}
}
Text(
text = "Quick tutorial",
color = headerColor,
fontSize = 28.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(horizontal = 8.dp),
)

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

Expand All @@ -126,7 +109,9 @@ fun TutorialHomeScreen(
modifier = Modifier.fillMaxWidth(),
) {
Text(
text = "This quick tutorial will show you how to use Scribe to support writing in your second language.",
text =
"This quick tutorial will show you how to use Scribe to support writing in your second language. " +
"\nMake sure you select the desired Scribe keyboard by pressing \uD83C\uDF10 when typing.",
color = textColor,
fontSize = 14.sp,
modifier = Modifier.padding(16.dp),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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

/**
* The main tutorial navigation controller.
Expand All @@ -18,7 +19,10 @@ import androidx.compose.runtime.setValue
* @param onTutorialExit Callback when the user exits the tutorial (back to About tab).
*/
@Composable
fun TutorialNavigator(onTutorialExit: () -> Unit) {
fun TutorialNavigator(
onTutorialExit: () -> Unit,
modifier: Modifier = Modifier,
) {
var currentScreen by remember { mutableStateOf("home") }
var currentChapterIndex by remember { mutableIntStateOf(0) }
var currentStepIndex by remember { mutableIntStateOf(0) }
Expand Down Expand Up @@ -49,6 +53,7 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
when (currentScreen) {
"home" -> {
TutorialHomeScreen(
modifier = modifier,
onBackPress = onTutorialExit,
onChapterSelect = { chapterIndex ->
currentChapterIndex = chapterIndex
Expand All @@ -73,10 +78,10 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
val isLastStep = isLastStepInChapter && (isLastChapter || !isFullTutorial)

TutorialStepScreen(
modifier = modifier,
chapterTitle = chapterTitle,
step = step,
isLastStep = isLastStep,
showQuickTutorialHeader = !isFullTutorial && currentStepIndex == 0,
onBackPress = {
when {
currentStepIndex > 0 -> {
Expand All @@ -92,9 +97,6 @@ fun TutorialNavigator(onTutorialExit: () -> Unit) {
}
}
},
onClosePress = {
currentScreen = "home"
},
onNextPress = {
when {
!isLastStepInChapter -> {
Expand Down
Loading
Loading