fix(nests): NestChatPanel takes weight(1) so chat fills the screen
Previously the room screen wrapped EVERYTHING — title, summary,
participants, talk row, action row, AND chat — in a single
verticalScroll Column. The chat panel sat at the bottom with a fixed
NEST_CHAT_PANEL_HEIGHT (420dp), which meant on tall phones the chat
left blank space below it and on small phones the chat was cramped.
Restructure NestFullScreen's body:
- Outer Column.fillMaxSize, no scroll, owns safeDrawing inset.
- Top metadata: Column with weight(1f, fill=false), internal
verticalScroll, horizontal+top padding. Caps at half the screen
so an over-tall participants list scrolls internally instead of
pushing the chat off-screen.
- NestChatPanel: Column-scoped weight(1f, fill=true), horizontal
padding + bottom inset. Always takes its full allocation —
chat dominates the screen, fixed-height fallback gone.
NestChatPanel is now a `ColumnScope.NestChatPanel` extension so its
modifier can use `weight()` from the caller. Inside the panel, the
message list Box also uses weight(1f, fill=true) of the panel's own
Column, so the LazyColumn fills everything except the composer.
NEST_CHAT_PANEL_HEIGHT constant removed — it was the source of the
fixed-height behavior the user explicitly didn't want.
https://claude.ai/code/session_01RDpuki4t8StSg1CZcXnV5b
This commit is contained in:
+3
-4
@@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.nests.room
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
@@ -97,7 +98,7 @@ import kotlinx.coroutines.launch
|
|||||||
* which are pinned to the channel-VM model — out of scope here.
|
* which are pinned to the channel-VM model — out of scope here.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
internal fun NestChatPanel(
|
internal fun ColumnScope.NestChatPanel(
|
||||||
event: MeetingSpaceEvent,
|
event: MeetingSpaceEvent,
|
||||||
viewModel: NestViewModel,
|
viewModel: NestViewModel,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
@@ -120,7 +121,7 @@ internal fun NestChatPanel(
|
|||||||
val routeForLastRead = remember(event) { "NestChat/${event.address().toValue()}" }
|
val routeForLastRead = remember(event) { "NestChat/${event.address().toValue()}" }
|
||||||
|
|
||||||
Column(modifier = modifier.fillMaxWidth()) {
|
Column(modifier = modifier.fillMaxWidth()) {
|
||||||
Box(modifier = Modifier.fillMaxWidth().height(NEST_CHAT_PANEL_HEIGHT)) {
|
Box(modifier = Modifier.fillMaxWidth().weight(1f, fill = true)) {
|
||||||
if (messages.isEmpty()) {
|
if (messages.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
text = stringRes(R.string.nest_chat_empty),
|
text = stringRes(R.string.nest_chat_empty),
|
||||||
@@ -266,6 +267,4 @@ private fun NestChatComposer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val NEST_CHAT_PANEL_HEIGHT = 420.dp
|
|
||||||
|
|
||||||
private val NEST_CHAT_NO_OP_NOTE: (com.vitorpamplona.amethyst.model.Note) -> Unit = {}
|
private val NEST_CHAT_NO_OP_NOTE: (com.vitorpamplona.amethyst.model.Note) -> Unit = {}
|
||||||
|
|||||||
+222
-208
@@ -98,19 +98,20 @@ internal fun NestFullScreen(
|
|||||||
) {
|
) {
|
||||||
val roomTheme = androidx.compose.runtime.remember(event) { RoomTheme.from(event) }
|
val roomTheme = androidx.compose.runtime.remember(event) { RoomTheme.from(event) }
|
||||||
NestThemedScope(theme = roomTheme, accountViewModel = accountViewModel) {
|
NestThemedScope(theme = roomTheme, accountViewModel = accountViewModel) {
|
||||||
// Inset the room content inside the system bars so the title
|
// Outer column owns the safeDrawing inset; the top metadata
|
||||||
// doesn't slide under the status bar and the Leave / chat
|
// section and the chat panel are weighted siblings.
|
||||||
// composer don't sit beneath the gesture / nav bar. The
|
//
|
||||||
// themed background color and `bg` image still paint
|
// The top section uses `weight(1f, fill = false)` so it never
|
||||||
// edge-to-edge — they live on NestThemedScope's outer Box,
|
// exceeds half the screen and scrolls internally if it would.
|
||||||
// which is intentionally outside this padding.
|
// The chat uses `weight(1f, fill = true)` so it always takes
|
||||||
|
// its full allocation — the user explicitly wanted chat to
|
||||||
|
// dominate the screen rather than ride a fixed-height box at
|
||||||
|
// the bottom of the metadata scroll.
|
||||||
Column(
|
Column(
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.windowInsetsPadding(WindowInsets.safeDrawing)
|
.windowInsetsPadding(WindowInsets.safeDrawing),
|
||||||
.padding(16.dp)
|
|
||||||
.verticalScroll(rememberScrollState()),
|
|
||||||
) {
|
) {
|
||||||
var showEditSheet by rememberSaveable { mutableStateOf(false) }
|
var showEditSheet by rememberSaveable { mutableStateOf(false) }
|
||||||
var showHostMenu by rememberSaveable { mutableStateOf(false) }
|
var showHostMenu by rememberSaveable { mutableStateOf(false) }
|
||||||
@@ -118,226 +119,239 @@ internal fun NestFullScreen(
|
|||||||
val isHost = accountViewModel.account.signer.pubKey == event.pubKey
|
val isHost = accountViewModel.account.signer.pubKey == event.pubKey
|
||||||
val leaveScope = rememberCoroutineScope()
|
val leaveScope = rememberCoroutineScope()
|
||||||
|
|
||||||
Row(
|
Column(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier =
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
Modifier
|
||||||
verticalAlignment = Alignment.Top,
|
.weight(1f, fill = false)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.padding(top = 16.dp),
|
||||||
) {
|
) {
|
||||||
event.room()?.let {
|
Row(
|
||||||
Text(
|
modifier = Modifier.fillMaxWidth(),
|
||||||
text = it,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
style = MaterialTheme.typography.headlineSmall,
|
verticalAlignment = Alignment.Top,
|
||||||
modifier = Modifier.weight(1f),
|
) {
|
||||||
)
|
event.room()?.let {
|
||||||
}
|
Text(
|
||||||
// Overflow menu — visible to everyone (Share); host-only
|
text = it,
|
||||||
// rows (Edit) are gated inside.
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
Box {
|
modifier = Modifier.weight(1f),
|
||||||
androidx.compose.material3.IconButton(onClick = { showHostMenu = true }) {
|
|
||||||
Icon(
|
|
||||||
symbol = MaterialSymbols.MoreVert,
|
|
||||||
contentDescription = stringRes(R.string.nest_overflow_menu),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val context = androidx.compose.ui.platform.LocalContext.current
|
// Overflow menu — visible to everyone (Share); host-only
|
||||||
androidx.compose.material3.DropdownMenu(
|
// rows (Edit) are gated inside.
|
||||||
expanded = showHostMenu,
|
Box {
|
||||||
onDismissRequest = { showHostMenu = false },
|
androidx.compose.material3.IconButton(onClick = { showHostMenu = true }) {
|
||||||
) {
|
Icon(
|
||||||
androidx.compose.material3.DropdownMenuItem(
|
symbol = MaterialSymbols.MoreVert,
|
||||||
text = { Text(stringRes(R.string.nest_share_action)) },
|
contentDescription = stringRes(R.string.nest_overflow_menu),
|
||||||
onClick = {
|
|
||||||
showHostMenu = false
|
|
||||||
shareRoomNaddr(context, event)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if (isHost) {
|
|
||||||
androidx.compose.material3.DropdownMenuItem(
|
|
||||||
text = { Text(stringRes(R.string.nest_edit_title)) },
|
|
||||||
onClick = {
|
|
||||||
showHostMenu = false
|
|
||||||
showEditSheet = true
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val context = androidx.compose.ui.platform.LocalContext.current
|
||||||
|
androidx.compose.material3.DropdownMenu(
|
||||||
|
expanded = showHostMenu,
|
||||||
|
onDismissRequest = { showHostMenu = false },
|
||||||
|
) {
|
||||||
|
androidx.compose.material3.DropdownMenuItem(
|
||||||
|
text = { Text(stringRes(R.string.nest_share_action)) },
|
||||||
|
onClick = {
|
||||||
|
showHostMenu = false
|
||||||
|
shareRoomNaddr(context, event)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if (isHost) {
|
||||||
|
androidx.compose.material3.DropdownMenuItem(
|
||||||
|
text = { Text(stringRes(R.string.nest_edit_title)) },
|
||||||
|
onClick = {
|
||||||
|
showHostMenu = false
|
||||||
|
showEditSheet = true
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (showEditSheet) {
|
||||||
if (showEditSheet) {
|
EditNestSheet(
|
||||||
EditNestSheet(
|
accountViewModel = accountViewModel,
|
||||||
accountViewModel = accountViewModel,
|
event = event,
|
||||||
event = event,
|
onDismiss = { showEditSheet = false },
|
||||||
onDismiss = { showEditSheet = false },
|
)
|
||||||
)
|
}
|
||||||
}
|
event.summary()?.let {
|
||||||
event.summary()?.let {
|
Text(
|
||||||
Text(
|
text = it,
|
||||||
text = it,
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
modifier = Modifier.padding(top = 4.dp),
|
||||||
modifier = Modifier.padding(top = 4.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listener counter — counts every active kind-10312 presence
|
|
||||||
// in the room. Hidden until the aggregator has at least one
|
|
||||||
// entry so the placeholder doesn't flash on entry.
|
|
||||||
val presences by viewModel.presences.collectAsState()
|
|
||||||
val listenerCount = presences.size
|
|
||||||
if (listenerCount > 0) {
|
|
||||||
Text(
|
|
||||||
text =
|
|
||||||
androidx.compose.ui.res.pluralStringResource(
|
|
||||||
R.plurals.nest_listener_count,
|
|
||||||
listenerCount,
|
|
||||||
listenerCount,
|
|
||||||
),
|
|
||||||
style = MaterialTheme.typography.bodySmall,
|
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
modifier = Modifier.padding(top = 4.dp),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val reactionsByPubkey by viewModel.recentReactions.collectAsState()
|
|
||||||
var hostMenuTarget by rememberSaveable { mutableStateOf<String?>(null) }
|
|
||||||
// Long-press opens the participant context sheet for ANYONE
|
|
||||||
// (T2 #2). The sheet's own gating decides which rows to show
|
|
||||||
// (follow/mute always; promote/demote/kick host-only).
|
|
||||||
val onLongPressParticipant: ((String) -> Unit) = { target ->
|
|
||||||
if (target != accountViewModel.account.signer.pubKey) hostMenuTarget = target
|
|
||||||
}
|
|
||||||
// Tier-2 #1: replace the two LazyRow sections with a single
|
|
||||||
// pure-projection ParticipantGrid. The `absent` flag (member
|
|
||||||
// promoted in the kind-30312 but never emitted a kind-10312)
|
|
||||||
// greys out at 50 % alpha, matching nostrnests' web client.
|
|
||||||
val participantGrid =
|
|
||||||
androidx.compose.runtime.remember(event, presences) {
|
|
||||||
com.vitorpamplona.amethyst.commons.viewmodels.buildParticipantGrid(
|
|
||||||
participants = event.participants(),
|
|
||||||
presences = presences,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ParticipantsGrid(
|
|
||||||
grid = participantGrid,
|
|
||||||
speakingNow = ui.speakingNow,
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
onStageLabel = stringRes(R.string.nest_stage),
|
|
||||||
audienceLabel = stringRes(R.string.nest_audience),
|
|
||||||
reactionsByPubkey = reactionsByPubkey,
|
|
||||||
connectingSpeakers = ui.connectingSpeakers,
|
|
||||||
onLongPressParticipant = onLongPressParticipant,
|
|
||||||
)
|
|
||||||
val speakerCatalogs by viewModel.speakerCatalogs.collectAsState()
|
|
||||||
hostMenuTarget?.let { target ->
|
|
||||||
ParticipantHostActionsSheet(
|
|
||||||
target = target,
|
|
||||||
event = event,
|
|
||||||
accountViewModel = accountViewModel,
|
|
||||||
onDismiss = { hostMenuTarget = null },
|
|
||||||
catalog = speakerCatalogs[target],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isHost) {
|
// Listener counter — counts every active kind-10312 presence
|
||||||
HandRaiseQueueSection(
|
// in the room. Hidden until the aggregator has at least one
|
||||||
event = event,
|
// entry so the placeholder doesn't flash on entry.
|
||||||
viewModel = viewModel,
|
val presences by viewModel.presences.collectAsState()
|
||||||
accountViewModel = accountViewModel,
|
val listenerCount = presences.size
|
||||||
)
|
if (listenerCount > 0) {
|
||||||
}
|
Text(
|
||||||
|
text =
|
||||||
ConnectionRow(viewModel = viewModel, ui = ui)
|
androidx.compose.ui.res.pluralStringResource(
|
||||||
|
R.plurals.nest_listener_count,
|
||||||
val myPubkey = accountViewModel.account.signer.pubKey
|
listenerCount,
|
||||||
if (viewModel.canBroadcast && onStage.any { it.pubKey == myPubkey }) {
|
listenerCount,
|
||||||
TalkRow(viewModel = viewModel, ui = ui, speakerPubkeyHex = myPubkey)
|
|
||||||
}
|
|
||||||
|
|
||||||
var showReactionPicker by rememberSaveable { mutableStateOf(false) }
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
FilledTonalIconToggleButton(
|
|
||||||
checked = handRaised,
|
|
||||||
onCheckedChange = onHandRaisedChange,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
symbol = MaterialSymbols.PanTool,
|
|
||||||
contentDescription =
|
|
||||||
stringRes(
|
|
||||||
if (handRaised) R.string.nest_lower_hand else R.string.nest_raise_hand,
|
|
||||||
),
|
),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
modifier = Modifier.padding(top = 4.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
OutlinedButton(onClick = { showReactionPicker = true }) {
|
|
||||||
Text(stringRes(R.string.nest_reactions_button))
|
|
||||||
}
|
|
||||||
OutlinedButton(
|
|
||||||
onClick = {
|
|
||||||
if (isHost) {
|
|
||||||
showHostLeaveConfirm = true
|
|
||||||
} else {
|
|
||||||
onLeave()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Text(stringRes(R.string.nest_leave))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (showReactionPicker) {
|
|
||||||
RoomReactionPickerSheet(
|
|
||||||
onPick = { emoji ->
|
|
||||||
accountViewModel.reactToOrDelete(roomNote, emoji)
|
|
||||||
},
|
|
||||||
onDismiss = { showReactionPicker = false },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (showHostLeaveConfirm) {
|
val reactionsByPubkey by viewModel.recentReactions.collectAsState()
|
||||||
AlertDialog(
|
var hostMenuTarget by rememberSaveable { mutableStateOf<String?>(null) }
|
||||||
onDismissRequest = { showHostLeaveConfirm = false },
|
// Long-press opens the participant context sheet for ANYONE
|
||||||
title = { Text(stringRes(R.string.nest_leave_host_title)) },
|
// (T2 #2). The sheet's own gating decides which rows to show
|
||||||
text = { Text(stringRes(R.string.nest_leave_host_body)) },
|
// (follow/mute always; promote/demote/kick host-only).
|
||||||
confirmButton = {
|
val onLongPressParticipant: ((String) -> Unit) = { target ->
|
||||||
TextButton(
|
if (target != accountViewModel.account.signer.pubKey) hostMenuTarget = target
|
||||||
colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error),
|
}
|
||||||
onClick = {
|
// Tier-2 #1: replace the two LazyRow sections with a single
|
||||||
showHostLeaveConfirm = false
|
// pure-projection ParticipantGrid. The `absent` flag (member
|
||||||
leaveScope.launch {
|
// promoted in the kind-30312 but never emitted a kind-10312)
|
||||||
val ok = closeMeetingSpace(accountViewModel, event)
|
// greys out at 50 % alpha, matching nostrnests' web client.
|
||||||
if (!ok) {
|
val participantGrid =
|
||||||
accountViewModel.toastManager.toast(
|
androidx.compose.runtime.remember(event, presences) {
|
||||||
R.string.nests,
|
com.vitorpamplona.amethyst.commons.viewmodels.buildParticipantGrid(
|
||||||
R.string.nest_leave_host_close_failed,
|
participants = event.participants(),
|
||||||
)
|
presences = presences,
|
||||||
}
|
)
|
||||||
onLeave()
|
}
|
||||||
}
|
ParticipantsGrid(
|
||||||
},
|
grid = participantGrid,
|
||||||
) {
|
speakingNow = ui.speakingNow,
|
||||||
Text(stringRes(R.string.nest_leave_host_close))
|
accountViewModel = accountViewModel,
|
||||||
}
|
onStageLabel = stringRes(R.string.nest_stage),
|
||||||
},
|
audienceLabel = stringRes(R.string.nest_audience),
|
||||||
dismissButton = {
|
reactionsByPubkey = reactionsByPubkey,
|
||||||
TextButton(
|
connectingSpeakers = ui.connectingSpeakers,
|
||||||
onClick = {
|
onLongPressParticipant = onLongPressParticipant,
|
||||||
showHostLeaveConfirm = false
|
|
||||||
onLeave()
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Text(stringRes(R.string.nest_leave_host_just_leave))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
val speakerCatalogs by viewModel.speakerCatalogs.collectAsState()
|
||||||
|
hostMenuTarget?.let { target ->
|
||||||
|
ParticipantHostActionsSheet(
|
||||||
|
target = target,
|
||||||
|
event = event,
|
||||||
|
accountViewModel = accountViewModel,
|
||||||
|
onDismiss = { hostMenuTarget = null },
|
||||||
|
catalog = speakerCatalogs[target],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isHost) {
|
||||||
|
HandRaiseQueueSection(
|
||||||
|
event = event,
|
||||||
|
viewModel = viewModel,
|
||||||
|
accountViewModel = accountViewModel,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
ConnectionRow(viewModel = viewModel, ui = ui)
|
||||||
|
|
||||||
|
val myPubkey = accountViewModel.account.signer.pubKey
|
||||||
|
if (viewModel.canBroadcast && onStage.any { it.pubKey == myPubkey }) {
|
||||||
|
TalkRow(viewModel = viewModel, ui = ui, speakerPubkeyHex = myPubkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
var showReactionPicker by rememberSaveable { mutableStateOf(false) }
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
FilledTonalIconToggleButton(
|
||||||
|
checked = handRaised,
|
||||||
|
onCheckedChange = onHandRaisedChange,
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
symbol = MaterialSymbols.PanTool,
|
||||||
|
contentDescription =
|
||||||
|
stringRes(
|
||||||
|
if (handRaised) R.string.nest_lower_hand else R.string.nest_raise_hand,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
OutlinedButton(onClick = { showReactionPicker = true }) {
|
||||||
|
Text(stringRes(R.string.nest_reactions_button))
|
||||||
|
}
|
||||||
|
OutlinedButton(
|
||||||
|
onClick = {
|
||||||
|
if (isHost) {
|
||||||
|
showHostLeaveConfirm = true
|
||||||
|
} else {
|
||||||
|
onLeave()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringRes(R.string.nest_leave))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (showReactionPicker) {
|
||||||
|
RoomReactionPickerSheet(
|
||||||
|
onPick = { emoji ->
|
||||||
|
accountViewModel.reactToOrDelete(roomNote, emoji)
|
||||||
|
},
|
||||||
|
onDismiss = { showReactionPicker = false },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showHostLeaveConfirm) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { showHostLeaveConfirm = false },
|
||||||
|
title = { Text(stringRes(R.string.nest_leave_host_title)) },
|
||||||
|
text = { Text(stringRes(R.string.nest_leave_host_body)) },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(
|
||||||
|
colors = ButtonDefaults.textButtonColors(contentColor = MaterialTheme.colorScheme.error),
|
||||||
|
onClick = {
|
||||||
|
showHostLeaveConfirm = false
|
||||||
|
leaveScope.launch {
|
||||||
|
val ok = closeMeetingSpace(accountViewModel, event)
|
||||||
|
if (!ok) {
|
||||||
|
accountViewModel.toastManager.toast(
|
||||||
|
R.string.nests,
|
||||||
|
R.string.nest_leave_host_close_failed,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onLeave()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringRes(R.string.nest_leave_host_close))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dismissButton = {
|
||||||
|
TextButton(
|
||||||
|
onClick = {
|
||||||
|
showHostLeaveConfirm = false
|
||||||
|
onLeave()
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
Text(stringRes(R.string.nest_leave_host_just_leave))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NestChatPanel(
|
NestChatPanel(
|
||||||
event = event,
|
event = event,
|
||||||
viewModel = viewModel,
|
viewModel = viewModel,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
modifier = Modifier.padding(top = 12.dp),
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.weight(1f, fill = true)
|
||||||
|
.padding(horizontal = 16.dp)
|
||||||
|
.padding(top = 12.dp, bottom = 16.dp),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user