Browse Source

android: connect channel reply navigation and camera context

master
evgeny 4 days ago
parent
commit
161af93347
  1. 20
      tools/chatgui-android/app/src/main/java/com/utun/chat/MainActivity.kt
  2. 27
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/ChatScreen.kt

20
tools/chatgui-android/app/src/main/java/com/utun/chat/MainActivity.kt

@ -206,6 +206,7 @@ class MainActivity : AppCompatActivity() {
if (it.startsWith("dm:")) ConversationTarget.Pm(it.removePrefix("dm:")) else ConversationTarget.Channel(it)
}
var photoMessage by remember { mutableStateOf<Message?>(null) }
var photoTargetId by rememberSaveable { mutableStateOf<String?>(null) }
var hadCall by rememberSaveable { mutableStateOf(false) }
var screenBeforeCall by rememberSaveable { mutableStateOf<Screen?>(null) }
val snackbarHostState = remember { SnackbarHostState() }
@ -371,8 +372,14 @@ class MainActivity : AppCompatActivity() {
onBack = { screen = Screen.ChannelList },
onPlayVideo = { msg -> videoMessage = msg },
onViewPhoto = { msg -> photoMessage = msg },
onRecordVideo = { videoTargetId = ConversationTarget.Channel(channel.id).nativeId; screen = Screen.VideoRecord },
onCapturePhoto = { screen = Screen.PhotoRecord }
onRecordVideo = {
val target = ConversationTarget.Channel(channel.id)
videoTargetId = target.nativeId; vm.captureCameraReply(target); screen = Screen.VideoRecord
},
onCapturePhoto = {
photoTargetId = channel.id
vm.captureCameraReply(ConversationTarget.Channel(channel.id)); screen = Screen.PhotoRecord
}
)
}
}
@ -399,7 +406,10 @@ class MainActivity : AppCompatActivity() {
messages = dmMessages,
viewModel = vm,
onSendMessage = { vm.sendDmMessage(it) },
onRecordVideo = { videoTargetId = ConversationTarget.Pm(dm.convId).nativeId; screen = Screen.VideoRecord },
onRecordVideo = {
val target = ConversationTarget.Pm(dm.convId)
videoTargetId = target.nativeId; vm.captureCameraReply(target); screen = Screen.VideoRecord
},
onPlayVideo = { videoMessage = it },
onBack = { vm.closeDm(); screen = Screen.ChannelList }
)
@ -417,7 +427,7 @@ class MainActivity : AppCompatActivity() {
if (target != null) {
VideoRecordScreen(
onSend = { path ->
vm.sendVideoMessage(path, target)
vm.sendVideoMessage(path, target, vm.cameraReply)
screen = if (target is ConversationTarget.Pm) Screen.Dm else Screen.Chat
},
onClose = { screen = if (target is ConversationTarget.Pm) Screen.Dm else Screen.Chat }
@ -429,7 +439,7 @@ class MainActivity : AppCompatActivity() {
if (channel != null) {
PhotoRecordScreen(
onSend = { path, width, height ->
vm.sendPhotoMessage(path, width, height)
vm.sendPhotoMessage(path, width, height, photoTargetId ?: channel.id, vm.cameraReply)
screen = Screen.Chat
},
onClose = { screen = Screen.Chat }

27
tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/ChatScreen.kt

@ -117,10 +117,30 @@ fun ChatScreen(
}
val playbackState by viewModel.playbackState.collectAsState()
val originals by viewModel.replyOriginals.collectAsState()
val anchor by viewModel.historyAnchor.collectAsState()
val jump by viewModel.messageJump.collectAsState()
val originalMissing by viewModel.originalMissing.collectAsState()
var highlighted by remember(channel.id) { mutableStateOf("") }
if (originalMissing) AlertDialog(onDismissRequest = viewModel::dismissOriginalMissing,
text = { Text(stringResource(R.string.reply_original_missing)) },
confirmButton = { TextButton(onClick = viewModel::dismissOriginalMissing) { Text(stringResource(R.string.close)) } })
LaunchedEffect(jump) {
val destination = jump ?: return@LaunchedEffect
val index = if (destination.messageId.isEmpty()) 0
else messages.asReversed().indexOfFirst { it.messageId == destination.messageId }.let { if (it < 0) -1 else it + 1 }
if (index >= 0) {
listState.scrollToItem(index)
highlighted = destination.messageId
kotlinx.coroutines.delay(1500)
highlighted = ""
}
}
/* своё сообщение — подтягиваемся вниз (в reverseLayout индекс 0 — это низ) */
LaunchedEffect(messages.size) {
if (messages.lastOrNull()?.isOutgoing == true) {
if (anchor.isEmpty() && messages.lastOrNull()?.isOutgoing == true) {
listState.scrollToItem(0)
}
}
@ -196,8 +216,11 @@ fun ChatScreen(
onDownloadFile = { viewModel.downloadAttachment(it) },
onOpenFile = { if (it.filePath.isNotEmpty()) { pendingSaveFilePath = it.filePath; saveFileLauncher.launch(it.text) } },
onOpenImage = onViewPhoto, onPlayVideo = onPlayVideo, onInviteLink = viewModel::openInviteLink,
reactionCatalog = reactionCatalog, onVote = viewModel::vote, onReact = viewModel::react, authorName = viewModel::radioName
reactionCatalog = reactionCatalog, onVote = viewModel::vote, onReact = viewModel::react, authorName = viewModel::radioName,
onReply = viewModel::selectReply, onOriginal = viewModel::showOriginal, originals = originals, highlightedId = highlighted
)
if (anchor.isNotEmpty()) FilledTonalButton(onClick = viewModel::showLatestMessages,
modifier = Modifier.align(Alignment.BottomEnd).padding(12.dp)) { Text(stringResource(R.string.reply_latest)) }
if (radioActive && !overlayShown) {
RadioPttButton(
modifier = Modifier.align(Alignment.TopCenter).padding(top = 12.dp),

Loading…
Cancel
Save