feat: show on server icon whether a server has active voice channels or streams
This commit is contained in:
parent
4a51c7c212
commit
bcd8c11498
|
|
@ -108,7 +108,7 @@ fun PresenceBadge(presence: Presence, size: Dp = 16.dp) {
|
|||
|
||||
private val PresenceCutoutPadding = 2.dp
|
||||
|
||||
private fun Modifier.presenceCutout(diameter: Dp): Modifier =
|
||||
internal fun Modifier.bottomEndCircleCutout(diameter: Dp): Modifier =
|
||||
graphicsLayer {
|
||||
compositingStrategy = CompositingStrategy.Offscreen
|
||||
}.drawWithCache {
|
||||
|
|
@ -161,7 +161,7 @@ fun UserAvatar(
|
|||
.size(size)
|
||||
.then(
|
||||
if (presence != null) {
|
||||
Modifier.presenceCutout(presenceSize)
|
||||
Modifier.bottomEndCircleCutout(presenceSize)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
|
|
@ -188,7 +188,7 @@ fun UserAvatar(
|
|||
.size(size)
|
||||
.then(
|
||||
if (presence != null) {
|
||||
Modifier.presenceCutout(presenceSize)
|
||||
Modifier.bottomEndCircleCutout(presenceSize)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ import chat.stoat.composables.generic.GroupIcon
|
|||
import chat.stoat.composables.generic.IconPlaceholder
|
||||
import chat.stoat.composables.generic.RemoteImage
|
||||
import chat.stoat.composables.generic.UserAvatar
|
||||
import chat.stoat.composables.generic.bottomEndCircleCutout
|
||||
import chat.stoat.composables.generic.presenceFromStatus
|
||||
import chat.stoat.composables.screens.chat.ChannelIcon
|
||||
import chat.stoat.core.model.data.STOAT_FILES
|
||||
|
|
@ -111,6 +112,9 @@ import logcat.LogPriority
|
|||
import logcat.asLog
|
||||
import logcat.logcat
|
||||
|
||||
private val ServerVoiceBadgeSize = 16.dp
|
||||
private val ServerVoiceBadgeIconSize = 12.dp
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun ChannelSideDrawer(
|
||||
|
|
@ -336,6 +340,15 @@ fun ChannelSideDrawer(
|
|||
val serverHasUnread =
|
||||
serverInList.id?.let { srvId -> StoatAPI.unreads.serverHasUnread(srvId) }
|
||||
?: false
|
||||
val voiceParticipants = serverInList.channels.orEmpty().flatMap { channelId ->
|
||||
StoatAPI.voiceStateCache[channelId]?.participants.orEmpty()
|
||||
}
|
||||
val hasScreenShare = voiceParticipants.any { it.screensharing }
|
||||
val voiceBadgeIcon = when {
|
||||
hasScreenShare -> R.drawable.ic_screen_share_24dp
|
||||
voiceParticipants.isNotEmpty() -> R.drawable.ic_volume_up_24dp
|
||||
else -> null
|
||||
}
|
||||
val leftIndicatorHeight = animateDpAsState(
|
||||
targetValue = if (serverInList.id == currentServer) 32.dp
|
||||
else if (serverHasUnread) 8.dp
|
||||
|
|
@ -364,33 +377,61 @@ fun ChannelSideDrawer(
|
|||
Box(
|
||||
Modifier
|
||||
.padding(8.dp)
|
||||
.size(48.dp),
|
||||
contentAlignment = Alignment.BottomEnd
|
||||
) {
|
||||
val icon = serverInList.icon?.id?.let { iconId ->
|
||||
"$STOAT_FILES/icons/$iconId"
|
||||
}
|
||||
val iconModifier = Modifier
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
.then(
|
||||
if (voiceBadgeIcon != null) {
|
||||
Modifier.bottomEndCircleCutout(ServerVoiceBadgeSize)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
)
|
||||
.clickable {
|
||||
serverInList.id?.let { srvId -> navigateToServer(srvId) }
|
||||
scope.launch {
|
||||
drawerState?.close()
|
||||
}
|
||||
}) {
|
||||
val icon = serverInList.icon?.id?.let { iconId ->
|
||||
"$STOAT_FILES/icons/$iconId"
|
||||
}
|
||||
}
|
||||
if (icon != null) {
|
||||
RemoteImage(
|
||||
url = icon,
|
||||
allowAnimation = false,
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.clip(CircleShape),
|
||||
modifier = iconModifier,
|
||||
description = serverInList.name ?: stringResource(R.string.unknown)
|
||||
)
|
||||
} else {
|
||||
IconPlaceholder(
|
||||
name = serverInList.name ?: stringResource(R.string.unknown),
|
||||
modifier = Modifier
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
modifier = iconModifier
|
||||
)
|
||||
}
|
||||
|
||||
if (voiceBadgeIcon != null) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = Modifier.size(ServerVoiceBadgeSize)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(voiceBadgeIcon),
|
||||
contentDescription = stringResource(
|
||||
if (hasScreenShare) {
|
||||
R.string.voice_screen_sharing
|
||||
} else {
|
||||
R.string.voice_notification_ongoing_call
|
||||
}
|
||||
),
|
||||
tint = MaterialTheme.colorScheme.onSurface,
|
||||
modifier = Modifier.size(ServerVoiceBadgeIconSize)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
|
|
|
|||
Loading…
Reference in New Issue