Share active stream button across Android group and home headers

This commit is contained in:
evgeny committed 2026-10-20 19:56:50 +02:00
1 parent c4da659dcb
commit 59858a726a
3 files changed
+35 -14

No files matched your search

@@ -0,0 +1,29 @@
package com.utun.chat.ui.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Videocam
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import com.utun.chat.R
import com.utun.chat.data.LogManager
import com.utun.chat.data.StreamController
/** Общая кнопка локального publisher: доступна из любого канала и главного экрана до окончания публикации. */
@Composable
fun OwnStreamButton(location: String, onOpen: (Long) -> Unit) {
val state by StreamController.state.collectAsState()
val publisher = state?.takeIf { it.ongoing }
LaunchedEffect(location, publisher?.id, publisher?.phase) {
LogManager.addLog("INFO", "stream", "own stream header location=$location publisher=${publisher?.id} " +
"group=${publisher?.group} phase=${publisher?.phase} visible=${publisher != null}")
}
if (publisher != null) IconButton(onClick = {
LogManager.addLog("INFO", "stream", "own stream header clicked location=$location publisher=${publisher.id} group=${publisher.group}")
onOpen(publisher.group)
}) {
Icon(Icons.Filled.Videocam, stringResource(R.string.stream_manage), tint = Color(0xFFE53935))
}
}
@@ -23,6 +23,7 @@ import androidx.lifecycle.compose.LifecycleResumeEffect
import com.utun.chat.ui.components.GroupAvatar
import com.utun.chat.ui.components.UserAvatar
import com.utun.chat.ui.components.GroupPropertiesDialog
import com.utun.chat.ui.components.OwnStreamButton
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -59,6 +60,7 @@ fun ChannelListScreen(
onDeleteChannel: (Channel) -> Unit,
onSettings: () -> Unit,
onLogs: () -> Unit,
onOwnStream: (Long) -> Unit = {},
onRefresh: () -> Unit = {}
) {
LifecycleResumeEffect(Unit) {
@@ -87,6 +89,7 @@ fun ChannelListScreen(
.background(if (isStuck) Color(0xFFFFB4AB) else Color(0xFF81C784), CircleShape)
)
Spacer(Modifier.width(4.dp))
OwnStreamButton("channel-list", onOwnStream)
IconButton(onClick = onJoinChannel) { Icon(Icons.Default.QrCode, stringResource(R.string.join)) }
IconButton(onClick = onLogs) { Icon(Icons.Default.Build, stringResource(R.string.logs)) }
IconButton(onClick = onSettings) { Icon(Icons.Default.Settings, stringResource(R.string.settings)) }
@@ -69,12 +69,11 @@ import com.utun.chat.ui.components.ConversationComposer
import com.utun.chat.ui.components.PortableRadioIcon
import com.utun.chat.ui.components.GroupAvatar
import com.utun.chat.ui.components.GroupPropertiesDialog
import com.utun.chat.ui.components.OwnStreamButton
import com.utun.chat.data.ConversationTarget
import com.utun.chat.viewmodel.ChatViewModel
import com.utun.chat.data.StreamController
import com.utun.chat.data.StreamSource
import androidx.compose.material.icons.filled.LiveTv
import androidx.compose.material.icons.filled.Videocam
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -94,6 +93,7 @@ fun ChatScreen(
onRecordVideo: () -> Unit = {},
onCapturePhoto: () -> Unit = {},
onStreams: () -> Unit = {},
onOwnStream: (Long) -> Unit = {},
onWatchStream: (StreamSource) -> Unit = {},
onWatchAllStreams: () -> Unit = {}
) {
@@ -106,12 +106,6 @@ fun ChatScreen(
var menu by remember(channel.id) { mutableStateOf(false) }
val streams by viewModel.streamSources.collectAsState()
val watchSources = streams.filterNot { it.self }
val publisher by StreamController.state.collectAsState()
val ownStream = publisher?.takeIf { it.ongoing && it.group.toULong().toString() == channel.id }
LaunchedEffect(channel.id, ownStream?.id, ownStream?.phase) {
LogManager.addLog("INFO", "stream", "own stream header channel=${channel.id} publisher=${ownStream?.id} " +
"phase=${ownStream?.phase} visible=${ownStream != null}")
}
var chooseStream by remember(channel.id) { mutableStateOf(false) }
if (chooseStream) AlertDialog(
onDismissRequest = { chooseStream = false },
@@ -216,12 +210,7 @@ fun ChatScreen(
Icon(Icons.Filled.LiveTv, stringResource(R.string.stream_available, watchSources.size), tint = Color(0xFFE53935))
}
}
if (ownStream != null) IconButton(onClick = {
LogManager.addLog("INFO", "stream", "own stream header clicked channel=${channel.id} publisher=${ownStream.id}")
onStreams()
}) {
Icon(Icons.Filled.Videocam, stringResource(R.string.stream_manage), tint = Color(0xFFE53935))
}
OwnStreamButton("channel=${channel.id}", onOwnStream)
IconButton(
onClick = { viewModel.toggleRadio() },
modifier = Modifier.background(