Browse Source

Open Android web links from shared channel and PM message UI

master
evgeny 6 days ago
parent
commit
2e41610693
  1. 38
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/ConversationMessages.kt

38
tools/chatgui-android/app/src/main/java/com/utun/chat/ui/components/ConversationMessages.kt

@ -2,8 +2,14 @@ package com.utun.chat.ui.components
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.* import androidx.compose.foundation.lazy.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.LaunchedEffect import android.content.Intent
import android.content.ActivityNotFoundException
import android.net.Uri
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
@ -14,11 +20,13 @@ import androidx.compose.ui.graphics.ShaderBrush
import androidx.compose.ui.graphics.TileMode import androidx.compose.ui.graphics.TileMode
import androidx.compose.ui.graphics.drawscope.scale import androidx.compose.ui.graphics.drawscope.scale
import androidx.compose.ui.res.imageResource import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.utun.chat.R import com.utun.chat.R
import com.utun.chat.data.ConversationTarget import com.utun.chat.data.ConversationTarget
import com.utun.chat.data.LogManager import com.utun.chat.data.LogManager
import com.utun.chat.data.Message import com.utun.chat.data.Message
import com.utun.chat.data.MessageLinks
import com.utun.chat.viewmodel.ChatViewModel import com.utun.chat.viewmodel.ChatViewModel
/** Общий список; направление включено в ключ, поскольку PM имеет два потока seq. */ /** Общий список; направление включено в ключ, поскольку PM имеет два потока seq. */
@ -29,6 +37,30 @@ fun ConversationMessages(target: ConversationTarget, messages: List<Message>, st
onOpenFile: (Message) -> Unit, onPlayVideo: (Message) -> Unit, onOpenFile: (Message) -> Unit, onPlayVideo: (Message) -> Unit,
onDownloadFile: (Message) -> Unit = {}, onOpenImage: (Message) -> Unit = {}, onDownloadFile: (Message) -> Unit = {}, onOpenImage: (Message) -> Unit = {},
onInviteLink: (String) -> Unit = {}) { onInviteLink: (String) -> Unit = {}) {
val context = LocalContext.current
var openFailed by remember { mutableStateOf(false) }
val onLink: (String) -> Unit = { link ->
if (link.startsWith("utun://")) onInviteLink(link)
else if (!MessageLinks.isWebUrl(link)) {
LogManager.addLog("ERROR", "LINK", "invalid external message link: bytes=${link.length}")
openFailed = true
} else {
val uri = Uri.parse(link)
try {
context.startActivity(Intent(Intent.ACTION_VIEW, uri))
LogManager.addLog("INFO", "LINK", "external open requested: scheme=${uri.scheme} host=${uri.host}")
} catch (e: ActivityNotFoundException) {
LogManager.addLog("ERROR", "LINK", "no URL handler: scheme=${uri.scheme} host=${uri.host} error=${e.message}")
openFailed = true
} catch (e: SecurityException) {
LogManager.addLog("ERROR", "LINK", "URL handler denied: scheme=${uri.scheme} host=${uri.host} error=${e.message}")
openFailed = true
}
}
}
if (openFailed) AlertDialog(onDismissRequest = { openFailed = false },
text = { Text(stringResource(R.string.link_open_failed)) },
confirmButton = { TextButton(onClick = { openFailed = false }) { Text(stringResource(R.string.close)) } })
val background = ImageBitmap.imageResource(R.drawable.chat_background) val background = ImageBitmap.imageResource(R.drawable.chat_background)
LaunchedEffect(background) { LaunchedEffect(background) {
LogManager.addLog("DEBUG", "UI", "Chat background ready: desktop bg.png tile=${background.width}x${background.height}") LogManager.addLog("DEBUG", "UI", "Chat background ready: desktop bg.png tile=${background.width}x${background.height}")
@ -45,7 +77,7 @@ fun ConversationMessages(target: ConversationTarget, messages: List<Message>, st
LazyColumn(modifier = modifier.then(backgroundModifier), state = state, reverseLayout = true) { LazyColumn(modifier = modifier.then(backgroundModifier), state = state, reverseLayout = true) {
item { Spacer(Modifier.height(8.dp)) } item { Spacer(Modifier.height(8.dp)) }
items(messages.reversed(), key = { "${target.nativeId}:${it.isOutgoing}:${it.id}" }) { message -> items(messages.reversed(), key = { "${target.nativeId}:${it.isOutgoing}:${it.id}" }) { message ->
MessageBubble(message, playbackState, onPlayVoice, onSeekVoice, onDownloadFile, onOpenFile, onOpenImage, onPlayVideo, onInviteLink) MessageBubble(message, playbackState, onPlayVoice, onSeekVoice, onDownloadFile, onOpenFile, onOpenImage, onPlayVideo, onLink)
} }
} }
} }

Loading…
Cancel
Save