Converts old ClickableTexts into new Compose Texts with clickable spans
This commit is contained in:
@@ -23,13 +23,8 @@ package com.vitorpamplona.amethyst.ui.components
|
|||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -37,10 +32,9 @@ fun ClickableEmail(email: String) {
|
|||||||
val stripped = email.replaceFirst("mailto:", "")
|
val stripped = email.replaceFirst("mailto:", "")
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = remember { AnnotatedString(stripped) },
|
text = stripped,
|
||||||
onClick = { runCatching { context.sendMail(stripped) } },
|
onClick = { runCatching { context.sendMail(stripped) } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to use,
|
|
||||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
||||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package com.vitorpamplona.amethyst.ui.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
|
||||||
import com.vitorpamplona.amethyst.ui.note.toShortenHex
|
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ClickableNoteTag(
|
|
||||||
baseNote: Note,
|
|
||||||
accountViewModel: AccountViewModel,
|
|
||||||
nav: INav,
|
|
||||||
) {
|
|
||||||
ClickableText(
|
|
||||||
text = AnnotatedString("@${baseNote.idNote().toShortenHex()}"),
|
|
||||||
onClick = { routeFor(baseNote, accountViewModel.userProfile())?.let { nav.nav(it) } },
|
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -23,22 +23,16 @@ package com.vitorpamplona.amethyst.ui.components
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClickablePhone(phone: String) {
|
fun ClickablePhone(phone: String) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = remember { AnnotatedString(phone) },
|
text = phone,
|
||||||
onClick = { runCatching { context.dial(phone) } },
|
onClick = { context.dial(phone) },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.gestures.detectTapGestures
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.foundation.text.InlineTextContent
|
import androidx.compose.foundation.text.InlineTextContent
|
||||||
import androidx.compose.foundation.text.appendInlineContent
|
import androidx.compose.foundation.text.appendInlineContent
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
@@ -41,18 +39,18 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.takeOrElse
|
import androidx.compose.ui.graphics.takeOrElse
|
||||||
import androidx.compose.ui.input.pointer.pointerInput
|
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.LinkAnnotation
|
||||||
import androidx.compose.ui.text.Placeholder
|
import androidx.compose.ui.text.Placeholder
|
||||||
import androidx.compose.ui.text.PlaceholderVerticalAlign
|
import androidx.compose.ui.text.PlaceholderVerticalAlign
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
import androidx.compose.ui.text.TextLayoutResult
|
import androidx.compose.ui.text.TextLinkStyles
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.text.withLink
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withStyle
|
||||||
import androidx.compose.ui.unit.TextUnit
|
import androidx.compose.ui.unit.TextUnit
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -367,7 +365,7 @@ fun CreateClickableText(
|
|||||||
overrideColor: Color? = null,
|
overrideColor: Color? = null,
|
||||||
fontWeight: FontWeight? = null,
|
fontWeight: FontWeight? = null,
|
||||||
fontSize: TextUnit = TextUnit.Unspecified,
|
fontSize: TextUnit = TextUnit.Unspecified,
|
||||||
onClick: (Int) -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val primaryColor = MaterialTheme.colorScheme.primary
|
val primaryColor = MaterialTheme.colorScheme.primary
|
||||||
val onBackgroundColor = MaterialTheme.colorScheme.onBackground
|
val onBackgroundColor = MaterialTheme.colorScheme.onBackground
|
||||||
@@ -381,61 +379,34 @@ fun CreateClickableText(
|
|||||||
fontWeight = fontWeight,
|
fontWeight = fontWeight,
|
||||||
)
|
)
|
||||||
|
|
||||||
val nonClickablePartStyle =
|
|
||||||
SpanStyle(
|
|
||||||
fontSize = fontSize,
|
|
||||||
color = overrideColor ?: onBackgroundColor,
|
|
||||||
fontWeight = fontWeight,
|
|
||||||
)
|
|
||||||
|
|
||||||
buildAnnotatedString {
|
buildAnnotatedString {
|
||||||
withStyle(clickablePartStyle) { append(clickablePart) }
|
withLink(
|
||||||
if (!suffix.isNullOrBlank()) {
|
LinkAnnotation.Clickable(
|
||||||
withStyle(nonClickablePartStyle) { append(suffix) }
|
tag = "clickable",
|
||||||
|
styles = TextLinkStyles(clickablePartStyle),
|
||||||
|
) {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
append(clickablePart)
|
||||||
}
|
}
|
||||||
}
|
if (!suffix.isNullOrBlank()) {
|
||||||
}
|
val nonClickablePartStyle =
|
||||||
|
SpanStyle(
|
||||||
|
fontSize = fontSize,
|
||||||
|
color = overrideColor ?: onBackgroundColor,
|
||||||
|
fontWeight = fontWeight,
|
||||||
|
)
|
||||||
|
|
||||||
ClickableText(
|
withStyle(nonClickablePartStyle) { append(suffix) }
|
||||||
text = text,
|
|
||||||
maxLines = maxLines,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
onClick = onClick,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ClickableText(
|
|
||||||
text: AnnotatedString,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
style: TextStyle = LocalTextStyle.current,
|
|
||||||
softWrap: Boolean = true,
|
|
||||||
overflow: TextOverflow = TextOverflow.Clip,
|
|
||||||
maxLines: Int = Int.MAX_VALUE,
|
|
||||||
onTextLayout: (TextLayoutResult) -> Unit = {},
|
|
||||||
onClick: (Int) -> Unit,
|
|
||||||
) {
|
|
||||||
val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
|
|
||||||
val pressIndicator =
|
|
||||||
Modifier.pointerInput(onClick) {
|
|
||||||
detectTapGestures { pos ->
|
|
||||||
layoutResult.value?.let { layoutResult ->
|
|
||||||
onClick(layoutResult.getOffsetForPosition(pos))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
modifier = modifier.then(pressIndicator),
|
|
||||||
style = style,
|
|
||||||
softWrap = softWrap,
|
|
||||||
overflow = overflow,
|
|
||||||
maxLines = maxLines,
|
maxLines = maxLines,
|
||||||
onTextLayout = {
|
overflow = TextOverflow.Ellipsis,
|
||||||
layoutResult.value = it
|
|
||||||
onTextLayout(it)
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -611,21 +582,29 @@ fun CreateClickableTextWithEmoji(
|
|||||||
maxLines: Int = Int.MAX_VALUE,
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
tags: ImmutableListOfLists<String>?,
|
tags: ImmutableListOfLists<String>?,
|
||||||
style: TextStyle,
|
style: TextStyle,
|
||||||
onClick: (Int) -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
CustomEmojiChecker(
|
CustomEmojiChecker(
|
||||||
text = clickablePart,
|
text = clickablePart,
|
||||||
tags = tags,
|
tags = tags,
|
||||||
onRegularText = {
|
onRegularText = {
|
||||||
ClickableText(
|
Text(
|
||||||
text = AnnotatedString(clickablePart),
|
text =
|
||||||
|
buildAnnotatedString {
|
||||||
|
withLink(
|
||||||
|
LinkAnnotation.Clickable("me") {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
append(clickablePart)
|
||||||
|
}
|
||||||
|
},
|
||||||
style = style,
|
style = style,
|
||||||
maxLines = maxLines,
|
maxLines = maxLines,
|
||||||
onClick = onClick,
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onEmojiText = {
|
onEmojiText = {
|
||||||
ClickableInLineIconRenderer(it, maxLines, style.toSpanStyle()) { onClick(it) }
|
ClickableInLineIconRenderer(it, maxLines, style.toSpanStyle(), onClick = onClick)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -683,15 +662,11 @@ fun ClickableInLineIconRenderer(
|
|||||||
style: SpanStyle,
|
style: SpanStyle,
|
||||||
suffix: String? = null,
|
suffix: String? = null,
|
||||||
nonClickableStype: SpanStyle? = null,
|
nonClickableStype: SpanStyle? = null,
|
||||||
onClick: (Int) -> Unit,
|
onClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val placeholderSize =
|
val placeholderSize =
|
||||||
remember(style) {
|
remember(style) {
|
||||||
if (style.fontSize == TextUnit.Unspecified) {
|
if (style.fontSize == TextUnit.Unspecified) 22.sp else style.fontSize.times(1.1f)
|
||||||
22.sp
|
|
||||||
} else {
|
|
||||||
style.fontSize.times(1.1f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val inlineContent =
|
val inlineContent =
|
||||||
@@ -725,8 +700,10 @@ fun ClickableInLineIconRenderer(
|
|||||||
val annotatedText =
|
val annotatedText =
|
||||||
buildAnnotatedString {
|
buildAnnotatedString {
|
||||||
wordsInOrder.forEachIndexed { idx, value ->
|
wordsInOrder.forEachIndexed { idx, value ->
|
||||||
withStyle(
|
withLink(
|
||||||
style,
|
LinkAnnotation.Clickable("link", TextLinkStyles(style)) {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
if (value is CustomEmoji.TextType) {
|
if (value is CustomEmoji.TextType) {
|
||||||
append(value.text)
|
append(value.text)
|
||||||
@@ -743,20 +720,10 @@ fun ClickableInLineIconRenderer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val layoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }
|
|
||||||
val pressIndicator =
|
|
||||||
Modifier.pointerInput(onClick) {
|
|
||||||
detectTapGestures { pos ->
|
|
||||||
layoutResult.value?.let { layoutResult -> onClick(layoutResult.getOffsetForPosition(pos)) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = annotatedText,
|
text = annotatedText,
|
||||||
modifier = pressIndicator,
|
|
||||||
inlineContent = inlineContent,
|
inlineContent = inlineContent,
|
||||||
maxLines = maxLines,
|
maxLines = maxLines,
|
||||||
onTextLayout = { layoutResult.value = it },
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -771,11 +738,7 @@ fun InLineIconRenderer(
|
|||||||
) {
|
) {
|
||||||
val placeholderSize =
|
val placeholderSize =
|
||||||
remember(fontSize) {
|
remember(fontSize) {
|
||||||
if (fontSize == TextUnit.Unspecified) {
|
if (fontSize == TextUnit.Unspecified) 22.sp else fontSize.times(1.1f)
|
||||||
22.sp
|
|
||||||
} else {
|
|
||||||
fontSize.times(1.1f)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val inlineContent =
|
val inlineContent =
|
||||||
|
|||||||
@@ -0,0 +1,151 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Vitor Pamplona
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||||
|
* Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.material3.LocalTextStyle
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
|
import androidx.compose.ui.text.AnnotatedString.Builder
|
||||||
|
import androidx.compose.ui.text.LinkAnnotation
|
||||||
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.TextLinkStyles
|
||||||
|
import androidx.compose.ui.text.TextStyle
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import androidx.compose.ui.text.withLink
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ClickableTextPrimary(
|
||||||
|
text: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
style: TextStyle = LocalTextStyle.current,
|
||||||
|
softWrap: Boolean = true,
|
||||||
|
overflow: TextOverflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
ClickableTextColor(
|
||||||
|
text,
|
||||||
|
modifier,
|
||||||
|
style,
|
||||||
|
softWrap,
|
||||||
|
overflow,
|
||||||
|
maxLines,
|
||||||
|
MaterialTheme.colorScheme.primary,
|
||||||
|
onClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ClickableTextColor(
|
||||||
|
text: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
style: TextStyle = LocalTextStyle.current,
|
||||||
|
softWrap: Boolean = true,
|
||||||
|
overflow: TextOverflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
|
linkColor: Color = MaterialTheme.colorScheme.primary,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text =
|
||||||
|
remember(text) {
|
||||||
|
buildAnnotatedString {
|
||||||
|
appendLink(text, linkColor, onClick)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = modifier,
|
||||||
|
style = style,
|
||||||
|
softWrap = softWrap,
|
||||||
|
overflow = overflow,
|
||||||
|
maxLines = maxLines,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ClickableTextNormal(
|
||||||
|
text: String,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
style: TextStyle = LocalTextStyle.current,
|
||||||
|
softWrap: Boolean = true,
|
||||||
|
overflow: TextOverflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines: Int = Int.MAX_VALUE,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text =
|
||||||
|
remember(text) {
|
||||||
|
buildAnnotatedString {
|
||||||
|
appendLink(text, onClick)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = modifier,
|
||||||
|
style = style,
|
||||||
|
softWrap = softWrap,
|
||||||
|
overflow = overflow,
|
||||||
|
maxLines = maxLines,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun Builder.appendLink(
|
||||||
|
text: String,
|
||||||
|
color: Color,
|
||||||
|
crossinline onClick: () -> Unit,
|
||||||
|
) = withLink(
|
||||||
|
LinkAnnotation.Clickable(
|
||||||
|
"clickable",
|
||||||
|
TextLinkStyles(SpanStyle(color)),
|
||||||
|
) {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
append(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun Builder.appendLink(
|
||||||
|
text: String,
|
||||||
|
crossinline onClick: () -> Unit,
|
||||||
|
) = withLink(
|
||||||
|
LinkAnnotation.Clickable("clickable") {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
append(text)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun buildLinkString(
|
||||||
|
text: String,
|
||||||
|
crossinline onClick: () -> Unit,
|
||||||
|
): AnnotatedString =
|
||||||
|
buildAnnotatedString {
|
||||||
|
withLink(
|
||||||
|
LinkAnnotation.Clickable("link") {
|
||||||
|
onClick()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
append(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,13 +20,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
import android.R.attr.maxLines
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import android.R.attr.onClick
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -36,10 +33,8 @@ fun ClickableUrl(
|
|||||||
) {
|
) {
|
||||||
val uri = LocalUriHandler.current
|
val uri = LocalUriHandler.current
|
||||||
|
|
||||||
val text = remember(urlText) { AnnotatedString(urlText) }
|
ClickableTextPrimary(
|
||||||
|
text = urlText,
|
||||||
ClickableText(
|
|
||||||
text = text,
|
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
onClick = {
|
onClick = {
|
||||||
@@ -48,6 +43,5 @@ fun ClickableUrl(
|
|||||||
uri.openUri(doubleCheckedUrl)
|
uri.openUri(doubleCheckedUrl)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2024 Vitor Pamplona
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
* this software and associated documentation files (the "Software"), to deal in
|
|
||||||
* the Software without restriction, including without limitation the rights to use,
|
|
||||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
|
||||||
* Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
* subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in all
|
|
||||||
* copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
|
||||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
package com.vitorpamplona.amethyst.ui.components
|
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import com.vitorpamplona.amethyst.model.User
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun ClickableUserTag(
|
|
||||||
user: User,
|
|
||||||
nav: INav,
|
|
||||||
) {
|
|
||||||
val route = remember(user) { routeFor(user) }
|
|
||||||
|
|
||||||
val innerUserState by user.live().metadata.observeAsState()
|
|
||||||
|
|
||||||
val userName =
|
|
||||||
remember(innerUserState) { AnnotatedString("@${innerUserState?.user?.toBestDisplayName()}") }
|
|
||||||
|
|
||||||
ClickableText(
|
|
||||||
text = userName,
|
|
||||||
onClick = { nav.nav(route) },
|
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
+2
-8
@@ -20,9 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.components
|
package com.vitorpamplona.amethyst.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -31,7 +29,6 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.text.style.TextDirection
|
import androidx.compose.ui.text.style.TextDirection
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
@@ -70,8 +67,6 @@ fun MayBeWithdrawal(
|
|||||||
fun ClickableWithdrawal(withdrawalString: String) {
|
fun ClickableWithdrawal(withdrawalString: String) {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val withdraw = remember(withdrawalString) { AnnotatedString("$withdrawalString ") }
|
|
||||||
|
|
||||||
var showErrorMessageDialog by remember { mutableStateOf<String?>(null) }
|
var showErrorMessageDialog by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
if (showErrorMessageDialog != null) {
|
if (showErrorMessageDialog != null) {
|
||||||
@@ -82,9 +77,8 @@ fun ClickableWithdrawal(withdrawalString: String) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = withdraw,
|
text = "$withdrawalString ",
|
||||||
onClick = { payViaIntent(withdrawalString, context, { }) { showErrorMessageDialog = it } },
|
onClick = { payViaIntent(withdrawalString, context, { }) { showErrorMessageDialog = it } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,7 +762,10 @@ private fun DisplayNoteFromTag(
|
|||||||
nav = nav,
|
nav = nav,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ClickableNoteTag(baseNote, accountViewModel, nav)
|
ClickableTextPrimary(
|
||||||
|
text = "@${baseNote.idNote().toShortenHex()}",
|
||||||
|
onClick = { routeFor(baseNote, accountViewModel.userProfile())?.let { nav.nav(it) } },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
addedChars?.ifBlank { null }?.let { Text(text = it) }
|
addedChars?.ifBlank { null }?.let { Text(text = it) }
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.navigation
|
package com.vitorpamplona.amethyst.ui.navigation
|
||||||
|
|
||||||
|
import android.R.attr.maxLines
|
||||||
import android.R.attr.onClick
|
import android.R.attr.onClick
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -73,13 +74,15 @@ import androidx.compose.ui.layout.ContentScale
|
|||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.LinkAnnotation
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.SpanStyle
|
||||||
|
import androidx.compose.ui.text.TextLinkStyles
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withLink
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@@ -90,7 +93,6 @@ import com.vitorpamplona.amethyst.model.Account
|
|||||||
import com.vitorpamplona.amethyst.model.FeatureSetType
|
import com.vitorpamplona.amethyst.model.FeatureSetType
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.ui.actions.mediaServers.MediaServersListView
|
import com.vitorpamplona.amethyst.ui.actions.mediaServers.MediaServersListView
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||||
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadStatuses
|
import com.vitorpamplona.amethyst.ui.note.LoadStatuses
|
||||||
@@ -740,23 +742,33 @@ fun BottomContent(
|
|||||||
.padding(horizontal = 15.dp),
|
.padding(horizontal = 15.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
) {
|
) {
|
||||||
ClickableText(
|
val string =
|
||||||
text =
|
remember {
|
||||||
buildAnnotatedString {
|
buildAnnotatedString {
|
||||||
withStyle(
|
withLink(
|
||||||
SpanStyle(
|
LinkAnnotation.Clickable(
|
||||||
fontSize = 12.sp,
|
"clickable",
|
||||||
fontWeight = FontWeight.Bold,
|
TextLinkStyles(
|
||||||
),
|
SpanStyle(
|
||||||
|
fontSize = 12.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
nav.nav(Route.Note(BuildConfig.RELEASE_NOTES_ID))
|
||||||
|
nav.closeDrawer()
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
append("v" + BuildConfig.VERSION_NAME + "-" + BuildConfig.FLAVOR.uppercase())
|
append("v12" + BuildConfig.VERSION_NAME + "-" + BuildConfig.FLAVOR.uppercase())
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
onClick = {
|
}
|
||||||
nav.nav(Route.Note(BuildConfig.RELEASE_NOTES_ID))
|
|
||||||
nav.closeDrawer()
|
Text(
|
||||||
},
|
text = string,
|
||||||
modifier = Modifier.padding(start = 16.dp),
|
modifier = Modifier.padding(start = 16.dp),
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1,
|
||||||
)
|
)
|
||||||
Box(modifier = Modifier.weight(1F))
|
Box(modifier = Modifier.weight(1F))
|
||||||
IconButton(
|
IconButton(
|
||||||
|
|||||||
+5
-7
@@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.Column
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.OpenInNew
|
import androidx.compose.material.icons.filled.OpenInNew
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -390,8 +389,8 @@ fun DisplayNIP05(
|
|||||||
|
|
||||||
NIP05VerifiedSymbol(nip05Verified, NIP05IconSize, accountViewModel)
|
NIP05VerifiedSymbol(nip05Verified, NIP05IconSize, accountViewModel)
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = remember(nip05) { AnnotatedString(domain) },
|
text = domain,
|
||||||
onClick = { runCatching { uri.openUri("https://$domain") } },
|
onClick = { runCatching { uri.openUri("https://$domain") } },
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.nip05, fontSize = Font14SP),
|
LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.nip05, fontSize = Font14SP),
|
||||||
@@ -441,7 +440,7 @@ fun DisplayNip05ProfileStatus(
|
|||||||
|
|
||||||
if (user != "_") {
|
if (user != "_") {
|
||||||
Text(
|
Text(
|
||||||
text = remember { AnnotatedString(user + "@") },
|
text = "$user@",
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
@@ -450,10 +449,9 @@ fun DisplayNip05ProfileStatus(
|
|||||||
domainPadStart = 0.dp
|
domainPadStart = 0.dp
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(domain),
|
text = domain,
|
||||||
onClick = { nip05.let { runCatching { uri.openUri("https://${it.split("@")[1]}") } } },
|
onClick = { nip05.let { runCatching { uri.openUri("https://${it.split("@")[1]}") } } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = domainPadStart),
|
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = domainPadStart),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
|||||||
+2
-9
@@ -24,13 +24,10 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
|||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextPrimary
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
import com.vitorpamplona.amethyst.ui.note.UserPicture
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -76,11 +73,7 @@ fun DisplayZapSplits(
|
|||||||
list.forEach {
|
list.forEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is ZapSplitSetupLnAddress ->
|
is ZapSplitSetupLnAddress ->
|
||||||
ClickableText(
|
ClickableTextPrimary(it.lnAddress) { }
|
||||||
text = AnnotatedString(it.lnAddress),
|
|
||||||
onClick = {},
|
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
|
||||||
is ZapSplitSetup ->
|
is ZapSplitSetup ->
|
||||||
UserPicture(
|
UserPicture(
|
||||||
userHex = it.pubKeyHex,
|
userHex = it.pubKeyHex,
|
||||||
|
|||||||
+8
-6
@@ -20,16 +20,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.elements
|
package com.vitorpamplona.amethyst.ui.note.elements
|
||||||
|
|
||||||
|
import android.R.attr.maxLines
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.buildLinkString
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -57,12 +58,13 @@ private fun DisplayCommunity(
|
|||||||
val communityTag =
|
val communityTag =
|
||||||
remember(note) { note.event?.getTagOfAddressableKind(CommunityDefinitionEvent.KIND) } ?: return
|
remember(note) { note.event?.getTagOfAddressableKind(CommunityDefinitionEvent.KIND) } ?: return
|
||||||
|
|
||||||
val displayTag = remember(note) { AnnotatedString(getCommunityShortName(communityTag)) }
|
val displayTag =
|
||||||
val route = remember(note) { Route.Community(communityTag.toTag()) }
|
remember(note) {
|
||||||
|
buildLinkString(getCommunityShortName(communityTag)) { nav.nav(Route.Community(communityTag.toTag())) }
|
||||||
|
}
|
||||||
|
|
||||||
ClickableText(
|
Text(
|
||||||
text = displayTag,
|
text = displayTag,
|
||||||
onClick = { nav.nav(route) },
|
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(
|
LocalTextStyle.current.copy(
|
||||||
color =
|
color =
|
||||||
|
|||||||
+13
-15
@@ -20,12 +20,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.elements
|
package com.vitorpamplona.amethyst.ui.note.elements
|
||||||
|
|
||||||
|
import android.R.attr.maxLines
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@@ -33,9 +34,10 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.buildLinkString
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -70,19 +72,15 @@ private fun DisplayTagList(
|
|||||||
firstTag: String,
|
firstTag: String,
|
||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
val displayTag = remember(firstTag) { AnnotatedString(" #$firstTag") }
|
Text(
|
||||||
val route = remember(firstTag) { Route.Hashtag(firstTag) }
|
text =
|
||||||
|
remember(firstTag) {
|
||||||
ClickableText(
|
buildLinkString(" #$firstTag") {
|
||||||
text = displayTag,
|
nav.nav(Route.Hashtag(firstTag))
|
||||||
onClick = { nav.nav(route) },
|
}
|
||||||
style =
|
},
|
||||||
LocalTextStyle.current.copy(
|
style = LocalTextStyle.current.copy(MaterialTheme.colorScheme.primary.copy(alpha = 0.52f)),
|
||||||
color =
|
overflow = TextOverflow.Ellipsis,
|
||||||
MaterialTheme.colorScheme.primary.copy(
|
|
||||||
alpha = 0.52f,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-5
@@ -20,12 +20,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.elements
|
package com.vitorpamplona.amethyst.ui.note.elements
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.LinkAnnotation
|
||||||
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.withLink
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName
|
import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName
|
||||||
@@ -37,9 +39,15 @@ fun DisplayLocation(
|
|||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
LoadCityName(geohashStr) { cityName ->
|
LoadCityName(geohashStr) { cityName ->
|
||||||
ClickableText(
|
Text(
|
||||||
text = AnnotatedString(cityName),
|
text =
|
||||||
onClick = { nav.nav(Route.Geohash(geohashStr)) },
|
buildAnnotatedString {
|
||||||
|
withLink(
|
||||||
|
LinkAnnotation.Clickable("cityname") { nav.nav(Route.Geohash(geohashStr)) },
|
||||||
|
) {
|
||||||
|
append(cityName)
|
||||||
|
}
|
||||||
|
},
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(
|
LocalTextStyle.current.copy(
|
||||||
color =
|
color =
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.elements
|
package com.vitorpamplona.amethyst.ui.note.elements
|
||||||
|
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -29,10 +28,10 @@ import androidx.compose.runtime.getValue
|
|||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.buildLinkString
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadOts
|
import com.vitorpamplona.amethyst.ui.note.LoadOts
|
||||||
import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot
|
import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
@@ -61,26 +60,15 @@ fun DisplayOts(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickableText(
|
Text(
|
||||||
text =
|
text =
|
||||||
buildAnnotatedString {
|
buildLinkString(stringRes(R.string.existed_since, timeStr)) {
|
||||||
append(
|
accountViewModel.toastManager.toast(
|
||||||
stringRes(
|
R.string.ots_info_title,
|
||||||
id = R.string.existed_since,
|
R.string.ots_info_description,
|
||||||
timeStr,
|
SimpleDateFormat.getDateTimeInstance().format(Date(unixtimestamp * 1000)),
|
||||||
),
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onClick = {
|
|
||||||
val fullDateTime =
|
|
||||||
SimpleDateFormat.getDateTimeInstance().format(Date(unixtimestamp * 1000))
|
|
||||||
|
|
||||||
accountViewModel.toastManager.toast(
|
|
||||||
R.string.ots_info_title,
|
|
||||||
R.string.ots_info_description,
|
|
||||||
fullDateTime,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(
|
LocalTextStyle.current.copy(
|
||||||
color = MaterialTheme.colorScheme.lessImportantLink,
|
color = MaterialTheme.colorScheme.lessImportantLink,
|
||||||
|
|||||||
+7
-14
@@ -30,9 +30,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
@@ -48,7 +46,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
@@ -61,6 +58,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
|||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextColor
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.note.ZapIcon
|
import com.vitorpamplona.amethyst.ui.note.ZapIcon
|
||||||
@@ -95,17 +93,12 @@ fun DisplayReward(
|
|||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier.clickable { popupExpanded = true },
|
modifier = Modifier.clickable { popupExpanded = true },
|
||||||
) {
|
) {
|
||||||
ClickableText(
|
ClickableTextColor(
|
||||||
text = AnnotatedString("#bounty"),
|
"#bounty",
|
||||||
onClick = { nav.nav(Route.Hashtag("bounty")) },
|
linkColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.52f),
|
||||||
style =
|
) {
|
||||||
LocalTextStyle.current.copy(
|
nav.nav(Route.Hashtag("bounty"))
|
||||||
color =
|
}
|
||||||
MaterialTheme.colorScheme.primary.copy(
|
|
||||||
alpha = 0.52f,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
RenderPledgeAmount(baseNote, baseReward, accountViewModel)
|
RenderPledgeAmount(baseNote, baseReward, accountViewModel)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-12
@@ -22,16 +22,13 @@ package com.vitorpamplona.amethyst.ui.note.elements
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment
|
import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment
|
||||||
import com.vitorpamplona.amethyst.service.CachedRichTextParser
|
import com.vitorpamplona.amethyst.service.CachedRichTextParser
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextColor
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding
|
import com.vitorpamplona.amethyst.ui.theme.HalfTopPadding
|
||||||
@@ -95,19 +92,14 @@ fun DisplayUncitedHashtags(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unusedHashtags.isNotEmpty()) {
|
if (unusedHashtags.isNotEmpty()) {
|
||||||
val style =
|
|
||||||
LocalTextStyle.current.copy(
|
|
||||||
color = MaterialTheme.colorScheme.lessImportantLink,
|
|
||||||
)
|
|
||||||
|
|
||||||
FlowRow(
|
FlowRow(
|
||||||
modifier = HalfTopPadding,
|
modifier = HalfTopPadding,
|
||||||
) {
|
) {
|
||||||
unusedHashtags.forEach { hashtag ->
|
unusedHashtags.forEach { hashtag ->
|
||||||
ClickableText(
|
ClickableTextColor(
|
||||||
text = remember { AnnotatedString("#$hashtag ") },
|
text = "#$hashtag ",
|
||||||
onClick = { nav.nav(Route.Hashtag(hashtag)) },
|
onClick = { nav.nav(Route.Hashtag(hashtag)) },
|
||||||
style = style,
|
linkColor = MaterialTheme.colorScheme.lessImportantLink,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.note.elements
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -37,6 +36,7 @@ import com.vitorpamplona.amethyst.R
|
|||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
||||||
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.appendLink
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
import com.vitorpamplona.amethyst.ui.navigation.routeFor
|
||||||
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
import com.vitorpamplona.amethyst.ui.note.LoadAddressableNote
|
||||||
@@ -87,13 +87,13 @@ fun ForkInformationRowLightColor(
|
|||||||
|
|
||||||
if (route != null) {
|
if (route != null) {
|
||||||
Row(modifier) {
|
Row(modifier) {
|
||||||
ClickableText(
|
Text(
|
||||||
text =
|
text =
|
||||||
buildAnnotatedString {
|
buildAnnotatedString {
|
||||||
append(stringRes(id = R.string.forked_from))
|
appendLink(stringRes(id = R.string.forked_from) + " ") {
|
||||||
append(" ")
|
nav.nav(route)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onClick = { nav.nav(route) },
|
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(
|
LocalTextStyle.current.copy(
|
||||||
color = MaterialTheme.colorScheme.nip05,
|
color = MaterialTheme.colorScheme.nip05,
|
||||||
|
|||||||
+14
-16
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.note.elements
|
package com.vitorpamplona.amethyst.ui.note.elements
|
||||||
|
|
||||||
|
import android.R.attr.onClick
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -49,11 +50,11 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.SpanStyle
|
import androidx.compose.ui.text.LinkAnnotation
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.withStyle
|
import androidx.compose.ui.text.withLink
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@@ -65,8 +66,8 @@ import com.vitorpamplona.amethyst.model.Note
|
|||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.ZapPaymentHandler
|
import com.vitorpamplona.amethyst.service.ZapPaymentHandler
|
||||||
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
|
||||||
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
import com.vitorpamplona.amethyst.ui.components.LoadNote
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.appendLink
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
import com.vitorpamplona.amethyst.ui.navigation.EmptyNav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.Route
|
import com.vitorpamplona.amethyst.ui.navigation.Route
|
||||||
@@ -222,16 +223,12 @@ fun ZapTheDevsCard(
|
|||||||
|
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
|
|
||||||
ClickableText(
|
Text(
|
||||||
text =
|
buildAnnotatedString {
|
||||||
buildAnnotatedString {
|
append(stringRes(id = R.string.zap_the_devs_description, BuildConfig.VERSION_NAME))
|
||||||
append(stringRes(id = R.string.zap_the_devs_description, BuildConfig.VERSION_NAME))
|
append(" ")
|
||||||
append(" ")
|
appendLink("#value4value", MaterialTheme.colorScheme.primary) { nav.nav(Route.Hashtag("value4value")) }
|
||||||
withStyle(SpanStyle(color = MaterialTheme.colorScheme.primary)) {
|
},
|
||||||
append("#value4value")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onClick = { nav.nav(Route.Hashtag("value4value")) },
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = StdVertSpacer)
|
Spacer(modifier = StdVertSpacer)
|
||||||
@@ -244,15 +241,16 @@ fun ZapTheDevsCard(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (route != null) {
|
if (route != null) {
|
||||||
ClickableText(
|
Text(
|
||||||
text =
|
text =
|
||||||
buildAnnotatedString {
|
buildAnnotatedString {
|
||||||
withStyle(SpanStyle(color = MaterialTheme.colorScheme.primary)) {
|
withLink(
|
||||||
|
LinkAnnotation.Clickable("clickable") { nav.nav(route) },
|
||||||
|
) {
|
||||||
append(stringRes(id = R.string.version_name, BuildConfig.VERSION_NAME.substringBefore("-")))
|
append(stringRes(id = R.string.version_name, BuildConfig.VERSION_NAME.substringBefore("-")))
|
||||||
}
|
}
|
||||||
append(" " + stringRes(id = R.string.brought_to_you_by))
|
append(" " + stringRes(id = R.string.brought_to_you_by))
|
||||||
},
|
},
|
||||||
onClick = { nav.nav(route) },
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Text(stringRes(id = R.string.this_version_brought_to_you_by))
|
Text(stringRes(id = R.string.this_version_brought_to_you_by))
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ import androidx.compose.foundation.layout.height
|
|||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -60,6 +58,7 @@ import coil3.compose.AsyncImage
|
|||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
import com.vitorpamplona.amethyst.commons.richtext.RichTextParser
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextPrimary
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||||
import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog
|
import com.vitorpamplona.amethyst.ui.components.ZoomableImageDialog
|
||||||
@@ -210,10 +209,9 @@ fun RenderAppDefinition(
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
LinkIcon(Size16Modifier, MaterialTheme.colorScheme.placeholderText)
|
LinkIcon(Size16Modifier, MaterialTheme.colorScheme.placeholderText)
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(website.removePrefix("https://")),
|
text = website.removePrefix("https://"),
|
||||||
onClick = { website.let { runCatching { uri.openUri(it) } } },
|
onClick = { website.let { runCatching { uri.openUri(it) } } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,7 @@ import androidx.compose.foundation.layout.Arrangement
|
|||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -40,10 +38,10 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import com.vitorpamplona.amethyst.model.AddressableNote
|
import com.vitorpamplona.amethyst.model.AddressableNote
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextPrimary
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
import com.vitorpamplona.amethyst.ui.components.ClickableUrl
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji
|
||||||
import com.vitorpamplona.amethyst.ui.components.DisplayEvent
|
import com.vitorpamplona.amethyst.ui.components.DisplayEvent
|
||||||
@@ -253,10 +251,9 @@ fun DisplayEntryForNote(
|
|||||||
Text("-", maxLines = 1)
|
Text("-", maxLines = 1)
|
||||||
|
|
||||||
if (description != null) {
|
if (description != null) {
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(description),
|
text = description,
|
||||||
onClick = { routeFor(note, accountViewModel.userProfile())?.let { nav.nav(it) } },
|
onClick = { routeFor(note, accountViewModel.userProfile())?.let { nav.nav(it) } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
DisplayEvent(noteEvent.id, noteEvent.kind, note.toNostrUri(), null, accountViewModel, nav)
|
DisplayEvent(noteEvent.id, noteEvent.kind, note.toNostrUri(), null, accountViewModel, nav)
|
||||||
|
|||||||
+3
-7
@@ -22,8 +22,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@@ -33,11 +31,10 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.actions.InformationDialog
|
import com.vitorpamplona.amethyst.ui.actions.InformationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextPrimary
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.INav
|
import com.vitorpamplona.amethyst.ui.navigation.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.routeToMessage
|
import com.vitorpamplona.amethyst.ui.navigation.routeToMessage
|
||||||
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
|
import com.vitorpamplona.amethyst.ui.note.ErrorMessageDialog
|
||||||
@@ -91,10 +88,9 @@ fun DisplayLNAddress(
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
LightningAddressIcon(modifier = Size16Modifier, tint = BitcoinOrange)
|
LightningAddressIcon(modifier = Size16Modifier, tint = BitcoinOrange)
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(lud16),
|
text = lud16,
|
||||||
onClick = { zapExpanded = !zapExpanded },
|
onClick = { zapExpanded = !zapExpanded },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.padding(top = 1.dp, bottom = 1.dp, start = 5.dp)
|
.padding(top = 1.dp, bottom = 1.dp, start = 5.dp)
|
||||||
|
|||||||
+5
-8
@@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.ContentCopy
|
|||||||
import androidx.compose.material.icons.filled.Link
|
import androidx.compose.material.icons.filled.Link
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.LocalTextStyle
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -50,7 +49,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
import com.vitorpamplona.amethyst.ui.components.ClickableTextPrimary
|
||||||
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji
|
||||||
import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus
|
import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus
|
||||||
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer
|
||||||
@@ -171,8 +170,8 @@ fun DrawAdditionalInfo(
|
|||||||
modifier = Modifier.size(16.dp),
|
modifier = Modifier.size(16.dp),
|
||||||
)
|
)
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(website.removePrefix("https://")),
|
text = website.removePrefix("https://"),
|
||||||
onClick = {
|
onClick = {
|
||||||
website.let {
|
website.let {
|
||||||
runCatching {
|
runCatching {
|
||||||
@@ -184,7 +183,6 @@ fun DrawAdditionalInfo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
modifier = Modifier.padding(top = 1.dp, bottom = 1.dp, start = 5.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -205,10 +203,9 @@ fun DrawAdditionalInfo(
|
|||||||
modifier = Modifier.size(16.dp),
|
modifier = Modifier.size(16.dp),
|
||||||
)
|
)
|
||||||
|
|
||||||
ClickableText(
|
ClickableTextPrimary(
|
||||||
text = AnnotatedString(identity.identity),
|
text = identity.identity,
|
||||||
onClick = { runCatching { uri.openUri(identity.toProofUrl()) } },
|
onClick = { runCatching { uri.openUri(identity.toProofUrl()) } },
|
||||||
style = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.primary),
|
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.padding(top = 1.dp, bottom = 1.dp, start = 5.dp)
|
.padding(top = 1.dp, bottom = 1.dp, start = 5.dp)
|
||||||
|
|||||||
+9
-24
@@ -23,14 +23,13 @@ package com.vitorpamplona.amethyst.ui.screen.loggedOff
|
|||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.platform.LocalUriHandler
|
import androidx.compose.ui.platform.LocalUriHandler
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.withStyle
|
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
import com.vitorpamplona.amethyst.ui.components.appendLink
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -44,32 +43,18 @@ fun AcceptTerms(
|
|||||||
onCheckedChange = onCheckedChange,
|
onCheckedChange = onCheckedChange,
|
||||||
)
|
)
|
||||||
|
|
||||||
val regularText = SpanStyle(color = MaterialTheme.colorScheme.onBackground)
|
|
||||||
val clickableTextStyle = SpanStyle(color = MaterialTheme.colorScheme.primary)
|
|
||||||
|
|
||||||
val annotatedTermsString =
|
|
||||||
buildAnnotatedString {
|
|
||||||
withStyle(regularText) { append(stringRes(R.string.i_accept_the)) }
|
|
||||||
|
|
||||||
withStyle(clickableTextStyle) {
|
|
||||||
pushStringAnnotation("openTerms", "")
|
|
||||||
append(stringRes(R.string.terms_of_use))
|
|
||||||
pop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val uri = LocalUriHandler.current
|
val uri = LocalUriHandler.current
|
||||||
|
val primary = MaterialTheme.colorScheme.primary
|
||||||
|
|
||||||
ClickableText(
|
Text(
|
||||||
annotatedTermsString,
|
buildAnnotatedString {
|
||||||
) { spanOffset ->
|
append(stringRes(R.string.i_accept_the))
|
||||||
annotatedTermsString.getStringAnnotations(spanOffset, spanOffset).firstOrNull()?.also { span ->
|
appendLink(stringRes(R.string.terms_of_use), primary) {
|
||||||
if (span.tag == "openTerms") {
|
|
||||||
runCatching {
|
runCatching {
|
||||||
uri.openUri("https://github.com/vitorpamplona/amethyst/blob/main/PRIVACY.md")
|
uri.openUri("https://github.com/vitorpamplona/amethyst/blob/main/PRIVACY.md")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-15
@@ -22,18 +22,17 @@ package com.vitorpamplona.amethyst.ui.screen.loggedOff
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.withStyle
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.components.ClickableText
|
import com.vitorpamplona.amethyst.ui.components.appendLink
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.tor.ConnectTorDialog
|
import com.vitorpamplona.amethyst.ui.tor.ConnectTorDialog
|
||||||
import com.vitorpamplona.amethyst.ui.tor.TorSettings
|
import com.vitorpamplona.amethyst.ui.tor.TorSettings
|
||||||
@@ -48,20 +47,16 @@ fun TorSettingsSetup(
|
|||||||
var connectOrbotDialogOpen by remember { mutableStateOf(false) }
|
var connectOrbotDialogOpen by remember { mutableStateOf(false) }
|
||||||
var activeTor by remember { mutableStateOf(false) }
|
var activeTor by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
val text =
|
val primary = MaterialTheme.colorScheme.primary
|
||||||
buildAnnotatedString {
|
|
||||||
append(stringRes(R.string.connect_via_tor1) + " ")
|
|
||||||
withStyle(SpanStyle(color = MaterialTheme.colorScheme.primary)) {
|
|
||||||
append(stringRes(R.string.connect_via_tor2))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClickableText(
|
Text(
|
||||||
text = text,
|
text =
|
||||||
|
buildAnnotatedString {
|
||||||
|
append(stringRes(R.string.connect_via_tor1) + " ")
|
||||||
|
appendLink(stringRes(R.string.connect_via_tor2), primary) { connectOrbotDialogOpen = true }
|
||||||
|
},
|
||||||
modifier = Modifier.padding(vertical = 10.dp),
|
modifier = Modifier.padding(vertical = 10.dp),
|
||||||
) {
|
)
|
||||||
connectOrbotDialogOpen = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectOrbotDialogOpen) {
|
if (connectOrbotDialogOpen) {
|
||||||
ConnectTorDialog(
|
ConnectTorDialog(
|
||||||
|
|||||||
+12
-44
@@ -27,7 +27,6 @@ import androidx.compose.foundation.layout.Spacer
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.text.ClickableText
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
@@ -49,10 +48,8 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.SpanStyle
|
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
import androidx.compose.ui.text.buildAnnotatedString
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.text.withStyle
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.core.os.ConfigurationCompat
|
import androidx.core.os.ConfigurationCompat
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
@@ -178,54 +175,25 @@ private fun TranslationMessage(
|
|||||||
Row(
|
Row(
|
||||||
modifier = Modifier.fillMaxWidth().padding(top = 5.dp),
|
modifier = Modifier.fillMaxWidth().padding(top = 5.dp),
|
||||||
) {
|
) {
|
||||||
val clickableTextStyle = SpanStyle(color = MaterialTheme.colorScheme.lessImportantLink)
|
val textColor = MaterialTheme.colorScheme.lessImportantLink
|
||||||
|
|
||||||
val annotatedTranslationString =
|
Text(
|
||||||
buildAnnotatedString {
|
text =
|
||||||
withStyle(clickableTextStyle) {
|
buildAnnotatedString {
|
||||||
pushStringAnnotation("langSettings", true.toString())
|
appendLink(stringRes(R.string.translations_auto), textColor) { langSettingsPopupExpanded = !langSettingsPopupExpanded }
|
||||||
append(stringRes(R.string.translations_auto))
|
append("-${stringRes(R.string.translations_translated_from)} ")
|
||||||
pop()
|
appendLink(Locale(source).displayName, textColor) { onChangeWhatToShow(true) }
|
||||||
}
|
append(" ${stringRes(R.string.translations_to)} ")
|
||||||
|
appendLink(Locale(target).displayName, textColor) { onChangeWhatToShow(false) }
|
||||||
append("-${stringRes(R.string.translations_translated_from)} ")
|
},
|
||||||
|
|
||||||
withStyle(clickableTextStyle) {
|
|
||||||
pushStringAnnotation("showOriginal", true.toString())
|
|
||||||
append(Locale(source).displayName)
|
|
||||||
pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
append(" ${stringRes(R.string.translations_to)} ")
|
|
||||||
|
|
||||||
withStyle(clickableTextStyle) {
|
|
||||||
pushStringAnnotation("showOriginal", false.toString())
|
|
||||||
append(Locale(target).displayName)
|
|
||||||
pop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClickableText(
|
|
||||||
text = annotatedTranslationString,
|
|
||||||
style =
|
style =
|
||||||
LocalTextStyle.current.copy(
|
LocalTextStyle.current.copy(
|
||||||
color =
|
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.32f),
|
||||||
MaterialTheme.colorScheme.onSurface.copy(
|
|
||||||
alpha = 0.32f,
|
|
||||||
),
|
|
||||||
fontSize = Font14SP,
|
fontSize = Font14SP,
|
||||||
),
|
),
|
||||||
overflow = TextOverflow.Visible,
|
overflow = TextOverflow.Visible,
|
||||||
maxLines = 3,
|
maxLines = 3,
|
||||||
) { spanOffset ->
|
)
|
||||||
annotatedTranslationString.getStringAnnotations(spanOffset, spanOffset).firstOrNull()?.also { span ->
|
|
||||||
if (span.tag == "showOriginal") {
|
|
||||||
onChangeWhatToShow(span.item.toBoolean())
|
|
||||||
} else {
|
|
||||||
langSettingsPopupExpanded = !langSettingsPopupExpanded
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DropdownMenu(
|
DropdownMenu(
|
||||||
expanded = langSettingsPopupExpanded,
|
expanded = langSettingsPopupExpanded,
|
||||||
|
|||||||
Reference in New Issue
Block a user