Update dependencies, GoogleLoginFragment: use clickableText instead of legacy TextView

This commit is contained in:
Ricki Hirner 2023-12-06 13:06:58 +01:00
parent c3e980cabf
commit 7a259383be
No known key found for this signature in database
GPG key ID: 79A019FCAAEDD3AA
4 changed files with 49 additions and 25 deletions

View file

@ -56,7 +56,7 @@ android {
composeOptions {
// Keep this in sync with Kotlin version:
// https://developer.android.com/jetpack/androidx/releases/compose-kotlin
kotlinCompilerExtensionVersion = "1.5.4"
kotlinCompilerExtensionVersion = "1.5.5"
}
// Java namespace for our classes (not to be confused with Android package ID)
@ -193,7 +193,7 @@ dependencies {
implementation 'commons-io:commons-io:2.8.0'
//noinspection GradleDependency - dnsjava 3.x requires Android 8 [https://github.com/bitfireAT/davx5/issues/453]
implementation 'dnsjava:dnsjava:2.1.9'
implementation "io.github.nsk90:kstatemachine-jvm:0.22.1"
implementation 'io.github.nsk90:kstatemachine-jvm:0.23.0'
implementation 'net.openid:appauth:0.11.1'
implementation "org.apache.commons:commons-collections4:${versions.commonsCollections}"
implementation "org.apache.commons:commons-lang3:${versions.commonsLang}"
@ -215,4 +215,4 @@ dependencies {
testImplementation "com.squareup.okhttp3:mockwebserver:${versions.okhttp}"
testImplementation 'junit:junit:4.13.2'
}
}

View file

@ -16,6 +16,7 @@ import android.net.Uri
import android.os.Build
import android.text.Spanned
import android.text.style.StyleSpan
import android.text.style.URLSpan
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.appcompat.app.AppCompatDelegate
@ -26,10 +27,13 @@ import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.UrlAnnotation
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.core.content.getSystemService
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap
@ -120,6 +124,7 @@ object UiUtils {
}
@OptIn(ExperimentalTextApi::class)
@Composable
fun Spanned.toAnnotatedString() = buildAnnotatedString {
val spanned = this@toAnnotatedString
@ -139,6 +144,18 @@ object UiUtils {
start = start, end = end
)
}
is URLSpan -> {
addUrlAnnotation(
UrlAnnotation(span.url),
start = start, end = end
)
addStyle(
SpanStyle(textDecoration = TextDecoration.Underline),
start = start, end = end
)
}
else ->
Logger.log.warning("Ignoring unknown span type ${span.javaClass.name}")
}
}
}

View file

@ -10,11 +10,9 @@ import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.method.LinkMovementMethod
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.activity.result.contract.ActivityResultContract
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
@ -24,6 +22,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
@ -44,12 +43,13 @@ import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.ExperimentalTextApi
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.net.toUri
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
@ -63,6 +63,7 @@ import at.bitfire.davdroid.R
import at.bitfire.davdroid.db.Credentials
import at.bitfire.davdroid.log.Logger
import at.bitfire.davdroid.ui.UiUtils
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
import com.google.accompanist.themeadapter.material.MdcTheme
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
@ -217,6 +218,7 @@ class GoogleLoginFragment(private val defaultEmail: String? = null): Fragment()
}
@OptIn(ExperimentalTextApi::class)
@Composable
fun GoogleLogin(
defaultEmail: String?,
@ -326,25 +328,30 @@ fun GoogleLogin(
)
}
AndroidView({ context ->
TextView(context, null, 0, com.google.accompanist.themeadapter.material.R.style.TextAppearance_MaterialComponents_Body2).apply {
text = HtmlCompat.fromHtml(context.getString(R.string.login_google_client_privacy_policy,
context.getString(R.string.app_name),
App.homepageUrl(context, App.HOMEPAGE_PRIVACY)
), 0)
movementMethod = LinkMovementMethod.getInstance()
val privacyPolicyNote = HtmlCompat.fromHtml(
stringResource(R.string.login_google_client_privacy_policy, context.getString(R.string.app_name), App.homepageUrl(context, App.HOMEPAGE_PRIVACY)), 0).toAnnotatedString()
ClickableText(
privacyPolicyNote,
style = MaterialTheme.typography.body2,
onClick = { position ->
privacyPolicyNote.getUrlAnnotations(position, position).firstOrNull()?.let {
UiUtils.launchUri(context, it.item.url.toUri())
}
}
}, modifier = Modifier.padding(top = 12.dp))
)
AndroidView({ context ->
TextView(context, null, 0, com.google.accompanist.themeadapter.material.R.style.TextAppearance_MaterialComponents_Body2).apply {
text = HtmlCompat.fromHtml(context.getString(R.string.login_google_client_limited_use,
context.getString(R.string.app_name),
GoogleLoginFragment.GOOGLE_POLICY_URL
), 0)
movementMethod = LinkMovementMethod.getInstance()
val limitedUseNote = HtmlCompat.fromHtml(
stringResource(R.string.login_google_client_limited_use, context.getString(R.string.app_name), GoogleLoginFragment.GOOGLE_POLICY_URL), 0).toAnnotatedString()
ClickableText(
limitedUseNote,
style = MaterialTheme.typography.body2,
modifier = Modifier.padding(top = 12.dp),
onClick = { position ->
limitedUseNote.getUrlAnnotations(position, position).firstOrNull()?.let {
UiUtils.launchUri(context, it.item.url.toUri())
}
}
}, modifier = Modifier.padding(top = 12.dp))
)
}
}
}

View file

@ -4,11 +4,11 @@
buildscript {
ext.versions = [
aboutLibraries: '10.9.1',
accompanist: '0.30.1',
aboutLibraries: '10.9.2',
accompanist: '0.32.0',
appIntro: '7.0.0-beta02',
composeBom: '2023.10.01',
hilt: '2.48.1',
hilt: '2.49',
kotlin: '1.9.20', // keep in sync with * app/build.gradle composeOptions.kotlinCompilerExtensionVersion
// * com.google.devtools.ksp at the end of this file
okhttp: '4.12.0',