mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-21 15:05:19 +00:00
WIP compose openURL dialog
This commit is contained in:
parent
5df981bc7a
commit
2aa58f4dd6
@ -11,8 +11,12 @@ import android.text.util.Linkify
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import androidx.core.text.getSpans
|
import androidx.core.text.getSpans
|
||||||
@ -40,7 +44,14 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
|||||||
import org.thoughtcrime.securesms.database.model.SmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.SmsMessageRecord
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.RequestManager
|
import com.bumptech.glide.RequestManager
|
||||||
|
import org.thoughtcrime.securesms.copyURLToClipboard
|
||||||
|
import org.thoughtcrime.securesms.openUrl
|
||||||
import org.thoughtcrime.securesms.showOpenUrlDialog
|
import org.thoughtcrime.securesms.showOpenUrlDialog
|
||||||
|
import org.thoughtcrime.securesms.ui.AlertDialog
|
||||||
|
import org.thoughtcrime.securesms.ui.DialogButtonModel
|
||||||
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
|
import org.thoughtcrime.securesms.ui.OpenURLAlertDialog
|
||||||
|
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||||
import org.thoughtcrime.securesms.util.GlowViewUtilities
|
import org.thoughtcrime.securesms.util.GlowViewUtilities
|
||||||
import org.thoughtcrime.securesms.util.SearchUtil
|
import org.thoughtcrime.securesms.util.SearchUtil
|
||||||
import org.thoughtcrime.securesms.util.getAccentColor
|
import org.thoughtcrime.securesms.util.getAccentColor
|
||||||
@ -60,6 +71,7 @@ class VisibleMessageContentView : ConstraintLayout {
|
|||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Updating
|
// region Updating
|
||||||
|
@Composable
|
||||||
fun bind(
|
fun bind(
|
||||||
message: MessageRecord,
|
message: MessageRecord,
|
||||||
isStartOfMessageCluster: Boolean = true,
|
isStartOfMessageCluster: Boolean = true,
|
||||||
@ -273,6 +285,7 @@ class VisibleMessageContentView : ConstraintLayout {
|
|||||||
// region Convenience
|
// region Convenience
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
@Composable
|
||||||
fun getBodySpans(context: Context, message: MessageRecord, searchQuery: String?): Spannable {
|
fun getBodySpans(context: Context, message: MessageRecord, searchQuery: String?): Spannable {
|
||||||
var body = message.body.toSpannable()
|
var body = message.body.toSpannable()
|
||||||
|
|
||||||
@ -293,8 +306,14 @@ class VisibleMessageContentView : ConstraintLayout {
|
|||||||
body.getSpans<URLSpan>(0, body.length).toList().forEach { urlSpan ->
|
body.getSpans<URLSpan>(0, body.length).toList().forEach { urlSpan ->
|
||||||
val updatedUrl = urlSpan.url.let { it.toHttpUrlOrNull().toString() }
|
val updatedUrl = urlSpan.url.let { it.toHttpUrlOrNull().toString() }
|
||||||
val replacementSpan = ModalURLSpan(updatedUrl) { url ->
|
val replacementSpan = ModalURLSpan(updatedUrl) { url ->
|
||||||
val activity = context as AppCompatActivity
|
|
||||||
activity.showOpenUrlDialog(url)
|
// @Thomas - PREVIOUS CODE WAS:
|
||||||
|
//val activity = context as AppCompatActivity
|
||||||
|
//activity.showOpenUrlDialog(url)
|
||||||
|
|
||||||
|
// Now attempting to use compose for the dialog - but it's not happy =/
|
||||||
|
OpenURLWarningDialog(url)
|
||||||
|
|
||||||
}
|
}
|
||||||
val start = body.getSpanStart(urlSpan)
|
val start = body.getSpanStart(urlSpan)
|
||||||
val end = body.getSpanEnd(urlSpan)
|
val end = body.getSpanEnd(urlSpan)
|
||||||
@ -305,6 +324,35 @@ class VisibleMessageContentView : ConstraintLayout {
|
|||||||
return body
|
return body
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun OpenURLWarningDialog(url: String) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
OpenURLAlertDialog(
|
||||||
|
title = stringResource(R.string.urlOpen),
|
||||||
|
text = stringResource(R.string.urlOpenDescription),
|
||||||
|
showCloseButton = true, // display the 'x' button
|
||||||
|
buttons = listOf(
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(R.string.open),
|
||||||
|
contentDescription = GetString(R.string.AccessibilityId_urlOpenBrowser),
|
||||||
|
color = LocalColors.current.danger,
|
||||||
|
onClick = { context.openUrl(url) }
|
||||||
|
),
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(android.R.string.copyUrl),
|
||||||
|
contentDescription = GetString(R.string.AccessibilityId_copy),
|
||||||
|
onClick = {
|
||||||
|
context.copyURLToClipboard(url)
|
||||||
|
Toast.makeText(context, R.string.copied, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
url = url,
|
||||||
|
onDismissRequest = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@ColorInt
|
@ColorInt
|
||||||
fun getTextColor(context: Context, message: MessageRecord): Int = context.getColorFromAttr(
|
fun getTextColor(context: Context, message: MessageRecord): Int = context.getColorFromAttr(
|
||||||
if (message.isOutgoing) R.attr.message_sent_text_color else R.attr.message_received_text_color
|
if (message.isOutgoing) R.attr.message_sent_text_color else R.attr.message_received_text_color
|
||||||
|
@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
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.material3.BasicAlertDialog
|
import androidx.compose.material3.BasicAlertDialog
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@ -29,6 +28,7 @@ import androidx.compose.ui.graphics.takeOrElse
|
|||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
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.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
@ -57,7 +57,8 @@ fun AlertDialog(
|
|||||||
text: String? = null,
|
text: String? = null,
|
||||||
buttons: List<DialogButtonModel>? = null,
|
buttons: List<DialogButtonModel>? = null,
|
||||||
showCloseButton: Boolean = false,
|
showCloseButton: Boolean = false,
|
||||||
content: @Composable () -> Unit = {}
|
content: @Composable () -> Unit = {},
|
||||||
|
optionalURL: String = ""
|
||||||
) {
|
) {
|
||||||
BasicAlertDialog(
|
BasicAlertDialog(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
@ -88,19 +89,32 @@ fun AlertDialog(
|
|||||||
) {
|
) {
|
||||||
title?.let {
|
title?.let {
|
||||||
Text(
|
Text(
|
||||||
it,
|
text = it,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
style = LocalType.current.h7,
|
style = LocalType.current.h7,
|
||||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
text?.let {
|
text?.let {
|
||||||
Text(
|
if (optionalURL.isNotEmpty()) {
|
||||||
it,
|
// If this is an open URL dialog it should have a maximum height of 5 lines and truncate long URLs with an ellipsis
|
||||||
textAlign = TextAlign.Center,
|
Text(
|
||||||
style = LocalType.current.large,
|
text = it,
|
||||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
textAlign = TextAlign.Center,
|
||||||
)
|
style = LocalType.current.large,
|
||||||
|
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing),
|
||||||
|
maxLines = 5,
|
||||||
|
overflow = TextOverflow.Ellipsis
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// Otherwise it should be a regular, non-open-URL dialog
|
||||||
|
Text(
|
||||||
|
text = it,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
style = LocalType.current.large,
|
||||||
|
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
content()
|
content()
|
||||||
}
|
}
|
||||||
@ -127,6 +141,30 @@ fun AlertDialog(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun OpenURLAlertDialog(
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String? = null,
|
||||||
|
text: String? = null,
|
||||||
|
buttons: List<DialogButtonModel>? = null,
|
||||||
|
showCloseButton: Boolean = false,
|
||||||
|
content: @Composable () -> Unit = {},
|
||||||
|
url: String = ""
|
||||||
|
) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
modifier = modifier,
|
||||||
|
title = title,
|
||||||
|
text = text,
|
||||||
|
buttons = buttons,
|
||||||
|
showCloseButton = showCloseButton,
|
||||||
|
content = content,
|
||||||
|
optionalURL = url
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun DialogButton(
|
fun DialogButton(
|
||||||
text: String,
|
text: String,
|
||||||
@ -224,7 +262,8 @@ fun PreviewSimpleDialog() {
|
|||||||
DialogButtonModel(
|
DialogButtonModel(
|
||||||
GetString(stringResource(R.string.cancel))
|
GetString(stringResource(R.string.cancel))
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
optionalURL = "https://slashdot.org"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,6 +293,33 @@ fun PreviewXCloseDialog() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewOpenURLDialog() {
|
||||||
|
PreviewTheme {
|
||||||
|
OpenURLAlertDialog(
|
||||||
|
title = stringResource(R.string.urlOpen),
|
||||||
|
text = stringResource(R.string.urlOpenDescription),
|
||||||
|
showCloseButton = true, // display the 'x' button
|
||||||
|
buttons = listOf(
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(R.string.open),
|
||||||
|
contentDescription = GetString(R.string.AccessibilityId_urlOpenBrowser),
|
||||||
|
color = LocalColors.current.danger,
|
||||||
|
onClick = {}
|
||||||
|
),
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(android.R.string.copyUrl),
|
||||||
|
contentDescription = GetString(R.string.AccessibilityId_copy),
|
||||||
|
onClick = {}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
url = "http://slashdot.org",
|
||||||
|
onDismissRequest = {}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewLoadingDialog() {
|
fun PreviewLoadingDialog() {
|
||||||
|
Loading…
Reference in New Issue
Block a user