From 2aa58f4dd6c62ec712715a24cf86272c0990a7af Mon Sep 17 00:00:00 2001 From: alansley Date: Wed, 28 Aug 2024 08:27:03 +1000 Subject: [PATCH] WIP compose openURL dialog --- .../v2/messages/VisibleMessageContentView.kt | 52 ++++++++++- .../thoughtcrime/securesms/ui/AlertDialog.kt | 86 ++++++++++++++++--- 2 files changed, 126 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt index 1d193bd745..f5773b27db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageContentView.kt @@ -11,8 +11,12 @@ import android.text.util.Linkify import android.util.AttributeSet import android.view.MotionEvent import android.view.View +import android.widget.Toast import androidx.annotation.ColorInt 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.core.graphics.ColorUtils import androidx.core.text.getSpans @@ -40,7 +44,14 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.SmsMessageRecord import com.bumptech.glide.Glide import com.bumptech.glide.RequestManager +import org.thoughtcrime.securesms.copyURLToClipboard +import org.thoughtcrime.securesms.openUrl 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.SearchUtil import org.thoughtcrime.securesms.util.getAccentColor @@ -60,6 +71,7 @@ class VisibleMessageContentView : ConstraintLayout { // endregion // region Updating + @Composable fun bind( message: MessageRecord, isStartOfMessageCluster: Boolean = true, @@ -273,6 +285,7 @@ class VisibleMessageContentView : ConstraintLayout { // region Convenience companion object { + @Composable fun getBodySpans(context: Context, message: MessageRecord, searchQuery: String?): Spannable { var body = message.body.toSpannable() @@ -293,8 +306,14 @@ class VisibleMessageContentView : ConstraintLayout { body.getSpans(0, body.length).toList().forEach { urlSpan -> val updatedUrl = urlSpan.url.let { it.toHttpUrlOrNull().toString() } 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 end = body.getSpanEnd(urlSpan) @@ -305,6 +324,35 @@ class VisibleMessageContentView : ConstraintLayout { 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 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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt index 1dd1df46cb..9c16f7119b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.ExperimentalMaterial3Api 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.stringResource 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.unit.dp import network.loki.messenger.R @@ -57,7 +57,8 @@ fun AlertDialog( text: String? = null, buttons: List? = null, showCloseButton: Boolean = false, - content: @Composable () -> Unit = {} + content: @Composable () -> Unit = {}, + optionalURL: String = "" ) { BasicAlertDialog( modifier = modifier, @@ -88,19 +89,32 @@ fun AlertDialog( ) { title?.let { Text( - it, + text = it, textAlign = TextAlign.Center, style = LocalType.current.h7, modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing) ) } text?.let { - Text( - it, - textAlign = TextAlign.Center, - style = LocalType.current.large, - modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing) - ) + if (optionalURL.isNotEmpty()) { + // If this is an open URL dialog it should have a maximum height of 5 lines and truncate long URLs with an ellipsis + Text( + text = it, + 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() } @@ -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? = 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 fun DialogButton( text: String, @@ -224,7 +262,8 @@ fun PreviewSimpleDialog() { DialogButtonModel( 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 @Composable fun PreviewLoadingDialog() {