diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 2f701d5a55..183158ef11 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -22,7 +22,7 @@ android {
defaultConfig {
applicationId = "eu.kanade.tachiyomi"
- versionCode = 111
+ versionCode = 112
versionName = "0.14.7"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
diff --git a/app/src/main/java/eu/kanade/presentation/more/onboarding/GuidesStep.kt b/app/src/main/java/eu/kanade/presentation/more/onboarding/GuidesStep.kt
index 8976a00d28..5899dae554 100644
--- a/app/src/main/java/eu/kanade/presentation/more/onboarding/GuidesStep.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/onboarding/GuidesStep.kt
@@ -6,11 +6,14 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.HorizontalDivider
+import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
+import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.unit.dp
+import eu.kanade.presentation.theme.TachiyomiTheme
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
@@ -32,7 +35,9 @@ internal fun GuidesStep(
Text(stringResource(MR.strings.getting_started_guide))
}
- HorizontalDivider()
+ HorizontalDivider(
+ color = MaterialTheme.colorScheme.onPrimaryContainer,
+ )
Text(stringResource(MR.strings.onboarding_guides_returning_user, stringResource(MR.strings.app_name)))
Button(
@@ -45,3 +50,13 @@ internal fun GuidesStep(
}
const val GETTING_STARTED_URL = "https://tachiyomi.org/docs/guides/getting-started"
+
+@PreviewLightDark
+@Composable
+private fun GuidesStepPreview() {
+ TachiyomiTheme {
+ GuidesStep(
+ onRestoreBackup = {},
+ )
+ }
+}
diff --git a/app/src/main/java/eu/kanade/presentation/more/onboarding/OnboardingScreen.kt b/app/src/main/java/eu/kanade/presentation/more/onboarding/OnboardingScreen.kt
index 7facba4033..b426961051 100644
--- a/app/src/main/java/eu/kanade/presentation/more/onboarding/OnboardingScreen.kt
+++ b/app/src/main/java/eu/kanade/presentation/more/onboarding/OnboardingScreen.kt
@@ -16,7 +16,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.platform.LocalContext
import eu.kanade.domain.ui.UiPreferences
+import eu.kanade.tachiyomi.util.system.toast
import soup.compose.material.motion.animation.materialSharedAxisX
import soup.compose.material.motion.animation.rememberSlideDistance
import tachiyomi.domain.storage.service.StoragePreferences
@@ -32,16 +34,20 @@ fun OnboardingScreen(
onComplete: () -> Unit,
onRestoreBackup: () -> Unit,
) {
- var currentStep by remember { mutableIntStateOf(0) }
- val steps: List<@Composable () -> Unit> = listOf(
- { ThemeStep(uiPreferences = uiPreferences) },
- { StorageStep(storagePref = storagePreferences.baseStorageDirectory()) },
- // TODO: prompt for notification permissions when bumping target to Android 13
- { GuidesStep(onRestoreBackup = onRestoreBackup) },
- )
- val isLastStep = currentStep == steps.size - 1
+ val context = LocalContext.current
val slideDistance = rememberSlideDistance()
+ var currentStep by remember { mutableIntStateOf(0) }
+ val steps: List<@Composable () -> Unit> = remember {
+ listOf(
+ { ThemeStep(uiPreferences = uiPreferences) },
+ { StorageStep(storagePref = storagePreferences.baseStorageDirectory()) },
+ // TODO: prompt for notification permissions when bumping target to Android 13
+ { GuidesStep(onRestoreBackup = onRestoreBackup) },
+ )
+ }
+ val isLastStep = currentStep == steps.size - 1
+
BackHandler(enabled = currentStep != 0, onBack = { currentStep-- })
InfoScreen(
@@ -56,10 +62,15 @@ fun OnboardingScreen(
},
),
onAcceptClick = {
- if (!isLastStep) {
- currentStep++
- } else {
+ if (isLastStep) {
onComplete()
+ } else {
+ // TODO: this is kind of janky
+ if (currentStep == 1 && !storagePreferences.baseStorageDirectory().isSet()) {
+ context.toast(MR.strings.onboarding_storage_selection_required)
+ } else {
+ currentStep++
+ }
}
},
rejectText = stringResource(MR.strings.onboarding_action_skip),
diff --git a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
index 1c7887dca1..f5f6c4f81c 100644
--- a/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
+++ b/app/src/main/java/eu/kanade/tachiyomi/Migrations.kt
@@ -396,7 +396,12 @@ object Migrations {
newKey = { Preference.privateKey(it) },
)
}
- if (oldVersion < 110) {
+ if (oldVersion < 111) {
+ File(context.cacheDir, "dl_index_cache")
+ .takeIf { it.exists() }
+ ?.delete()
+ }
+ if (oldVersion < 112) {
val prefsToReplace = listOf(
"pref_download_only",
"incognito_mode",
@@ -409,6 +414,7 @@ object Migrations {
"last_app_check",
"last_ext_check",
"last_version_code",
+ "storage_dir",
)
replacePreferences(
preferenceStore = preferenceStore,
@@ -416,11 +422,6 @@ object Migrations {
newKey = { Preference.appStateKey(it) },
)
}
- if (oldVersion < 111) {
- File(context.cacheDir, "dl_index_cache")
- .takeIf { it.exists() }
- ?.delete()
- }
return true
}
diff --git a/domain/src/main/java/tachiyomi/domain/storage/service/StoragePreferences.kt b/domain/src/main/java/tachiyomi/domain/storage/service/StoragePreferences.kt
index 8f7c3fcc6b..a49a54e3ce 100644
--- a/domain/src/main/java/tachiyomi/domain/storage/service/StoragePreferences.kt
+++ b/domain/src/main/java/tachiyomi/domain/storage/service/StoragePreferences.kt
@@ -1,5 +1,6 @@
package tachiyomi.domain.storage.service
+import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.core.storage.FolderProvider
@@ -8,5 +9,5 @@ class StoragePreferences(
private val preferenceStore: PreferenceStore,
) {
- fun baseStorageDirectory() = preferenceStore.getString("storage_dir", folderProvider.path())
+ fun baseStorageDirectory() = preferenceStore.getString(Preference.appStateKey("storage_dir"), folderProvider.path())
}
diff --git a/i18n/src/commonMain/resources/MR/base/strings.xml b/i18n/src/commonMain/resources/MR/base/strings.xml
index 9b86c899a0..1714d16c45 100644
--- a/i18n/src/commonMain/resources/MR/base/strings.xml
+++ b/i18n/src/commonMain/resources/MR/base/strings.xml
@@ -182,6 +182,7 @@
Skip
Select a folder where %1$s will store chapter downloads, backups, and more.\n\nA dedicated folder is recommended.\n\nSelected folder: %2$s
Select a folder
+ A folder must be selected
New to %s? We recommend checking out the getting started guide.
Already used %s before?