feat: add privacyPolicyStep to the onboarding.

closes #10379

Signed-off-by: KaiserBh <kaiserbh@proton.me>
This commit is contained in:
KaiserBh 2024-01-12 16:21:24 +11:00
parent c65a9aecf5
commit 14a3f805fb
No known key found for this signature in database
GPG Key ID: 14D73B142042BBA9
2 changed files with 229 additions and 0 deletions

View File

@ -0,0 +1,222 @@
package eu.kanade.presentation.more.onboarding
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Checkbox
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.material3.Text
import androidx.compose.runtime.derivedStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.sp
import tachiyomi.i18n.MR
import tachiyomi.presentation.core.i18n.stringResource
class PrivacyPolicyStep : OnboardingStep {
private var _isComplete by mutableStateOf(false)
override val isComplete: Boolean
get() = _isComplete
@Composable
override fun Content() {
var isAgreed by remember { mutableStateOf(false) }
val scrollState = rememberScrollState()
val isScrolledToEnd = remember(scrollState) {
derivedStateOf {
val maxScroll = scrollState.maxValue
scrollState.value >= maxScroll
}
}
Column(modifier = Modifier.fillMaxSize()) {
Box(modifier = Modifier
.height(500.dp)
.padding(16.dp)
.verticalScroll(scrollState)) {
Column {
PrivacyPolicyIntro()
PrivacyInformationCollectionUse()
}
}
// Agreement Checkbox
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
stringResource(resource = MR.strings.onboarding_privacy_agree_to_terms),
style = TextStyle(
fontSize = 18.sp,
),
)
Checkbox(
enabled = isScrolledToEnd.value,
checked = isAgreed,
onCheckedChange = {
isAgreed = it
_isComplete = it
}
)
}
}
}
@Composable
fun HeadingText(text: String, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
text = text,
style = TextStyle(fontSize = 20.sp, fontWeight = FontWeight.Bold)
)
}
@Composable
fun BodyText(text: String, modifier: Modifier = Modifier) {
Text(
modifier = modifier,
text = text,
style = TextStyle(fontSize = 16.sp)
)
}
@Composable
fun HorizontalDivider() {
HorizontalDivider(color = Color.Gray)
}
@Composable
fun Spacer(size: Int, modifier: Modifier = Modifier) {
Spacer(modifier = modifier.height(size.dp))
}
@Composable
fun BulletPoint(text: String, url: String, modifier: Modifier= Modifier) {
val uriHandler = LocalUriHandler.current
val annotatedString = buildAnnotatedString {
withStyle(style = SpanStyle(color = Color(0xFF0645AD), fontSize = 16.sp)) {
append("$text")
}
addStringAnnotation(
tag = "URL",
annotation = url,
start = 2,
end = 2 + text.length
)
}
ClickableText(
modifier = modifier,
text = annotatedString,
onClick = { offset ->
annotatedString.getStringAnnotations(tag = "URL", start = offset, end = offset)
.firstOrNull()?.let { annotation ->
uriHandler.openUri(annotation.item)
}
},
style = TextStyle(fontSize = 16.sp)
)
}
@Composable
fun MoreInfoText(url: String, modifier: Modifier = Modifier) {
val uriHandler = LocalUriHandler.current
val annotatedString = buildAnnotatedString {
withStyle(style = SpanStyle(color = Color(0xFF0645AD), fontSize = 16.sp)) {
append(stringResource(resource = MR.strings.learn_more))
}
addStringAnnotation(
tag = "URL",
annotation = url,
start = 0,
end = stringResource(resource = MR.strings.learn_more).length,
)
}
ClickableText(
text = annotatedString,
modifier = modifier,
onClick = { offset ->
annotatedString.getStringAnnotations(tag = "URL", start = offset, end = offset)
.firstOrNull()?.let { annotation ->
uriHandler.openUri(annotation.item)
}
},
style = TextStyle(fontSize = 16.sp)
)
}
@Composable
fun PrivacyPolicyIntro(modifier: Modifier = Modifier) {
Column(modifier = modifier) {
HeadingText(stringResource(resource = MR.strings.privacy_policy))
Spacer(20)
BodyText(stringResource(resource = MR.strings.onboarding_privacy_intro))
Spacer(10)
BodyText(stringResource(resource = MR.strings.onboarding_privacy_info_overview))
Spacer(10)
BodyText(stringResource(resource = MR.strings.onboarding_privacy_agreement_acknowledgement))
Spacer(20)
HorizontalDivider()
Spacer(20)
}
}
@Composable
fun PrivacyInformationCollectionUse(modifier: Modifier = Modifier) {
Column(modifier = modifier) {
HeadingText(stringResource(resource = MR.strings.onboarding_privacy_information_collection_use))
Spacer(20)
BodyText(stringResource(resource = MR.strings.onboarding_privacy_information_collection_use_intro))
Spacer(10)
BodyText( stringResource(resource = MR.strings.onboarding_privacy_information_collection_use_data))
Spacer(10)
BulletPoint("Sentry", "https://sentry.io/privacy/")
BulletPoint("Firebase Analytics", "https://www.google.com/analytics/terms/")
Spacer(20)
HorizontalDivider()
Spacer(20)
MoreInfoText("https://tachiyomi.org/privacy/")
}
}
}

View File

@ -189,6 +189,13 @@
<string name="onboarding_permission_action_grant">Grant</string> <string name="onboarding_permission_action_grant">Grant</string>
<string name="onboarding_guides_new_user">New to %s? We recommend checking out the getting started guide.</string> <string name="onboarding_guides_new_user">New to %s? We recommend checking out the getting started guide.</string>
<string name="onboarding_guides_returning_user">Reinstalling %s?</string> <string name="onboarding_guides_returning_user">Reinstalling %s?</string>
<string name="onboarding_privacy_agree_to_terms">I agree to the Privacy Policy</string>
<string name="onboarding_privacy_intro">Tachiyomi is an Open Source app. This SERVICE is provided at no cost and is intended for use as is.</string>
<string name="onboarding_privacy_info_overview">This page details our policies with the collection, use, and disclosure of Personal Information if anyone decided to use our Service.</string>
<string name="onboarding_privacy_agreement_acknowledgement">If you choose to use our Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that we collect is used for providing and improving the Service. We will not use or share your information with anyone except as described in this Privacy Policy.</string>
<string name="onboarding_privacy_information_collection_use">Information Collection and Use</string>
<string name="onboarding_privacy_information_collection_use_intro">For a better experience, while using our Service, we may require you to provide us with certain personally identifiable information. The information that we request will be retained by us and used as described in this privacy policy.</string>
<string name="onboarding_privacy_information_collection_use_data">Links to the privacy policy of third-party service providers used by the app:</string>
<!-- Preferences --> <!-- Preferences -->
<!-- Subsections --> <!-- Subsections -->