feat: placeholder media channel overlay

Signed-off-by: Infi <infi@infi.sh>
This commit is contained in:
Infi 2024-04-06 00:07:34 +02:00
parent 4784bb3f3f
commit 67881fefb7
8 changed files with 132 additions and 10 deletions

View File

@ -17,6 +17,19 @@ sealed class LabsAccessControlVariates {
data class Restricted(val predicate: () -> Boolean) : LabsAccessControlVariates()
}
@FeatureFlag("MediaConversations")
sealed class MediaConversationsVariates {
@Treatment(
"Enable voice, video and screen conversations for all users"
)
object Enabled : MediaConversationsVariates()
@Treatment(
"Enable voice, video and screen conversations for users that meet certain or all criteria (implementation-specific)"
)
data class Restricted(val predicate: () -> Boolean) : MediaConversationsVariates()
}
object FeatureFlags {
@FeatureFlag("LabsAccessControl")
var labsAccessControl by mutableStateOf<LabsAccessControlVariates>(
@ -24,4 +37,22 @@ object FeatureFlags {
RevoltAPI.selfId == SpecialUsers.JENNIFER
}
)
val labsAccessControlGranted: Boolean
get() = when (labsAccessControl) {
is LabsAccessControlVariates.Restricted -> (labsAccessControl as LabsAccessControlVariates.Restricted).predicate()
}
@FeatureFlag("MediaConversations")
var mediaConversations by mutableStateOf<MediaConversationsVariates>(
MediaConversationsVariates.Restricted {
RevoltAPI.selfId == SpecialUsers.JENNIFER
}
)
val mediaConversationsGranted: Boolean
get() = when (mediaConversations) {
is MediaConversationsVariates.Enabled -> true
is MediaConversationsVariates.Restricted -> (mediaConversations as MediaConversationsVariates.Restricted).predicate()
}
}

View File

@ -10,6 +10,7 @@ sealed class Action {
data class MessageReactionInfo(val messageId: String, val emoji: String) : Action()
data class TopNavigate(val route: String) : Action()
data class ChatNavigate(val route: String) : Action()
data class OpenVoiceChannelOverlay(val channelId: String) : Action()
}
val ActionChannel = Channel<Action>(

View File

@ -0,0 +1,64 @@
package chat.revolt.components.screens.voice
import android.content.Context
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
@Composable
fun VoiceChannelOverlay(channelId: String, onCollapse: () -> Unit) {
val context = LocalContext.current
val windowManager =
remember { context.getSystemService(Context.WINDOW_SERVICE) as WindowManager }
val metrics = DisplayMetrics().apply {
@Suppress("DEPRECATION") // We *need* the real metrics here, not the window metrics
windowManager.defaultDisplay.getRealMetrics(this)
}
val (width, height) = with(LocalDensity.current) {
Pair(metrics.widthPixels.toDp(), metrics.heightPixels.toDp())
}
Dialog(
onDismissRequest = {
onCollapse()
},
properties = DialogProperties(
usePlatformDefaultWidth = false,
decorFitsSystemWindows = true,
dismissOnClickOutside = false,
dismissOnBackPress = true
)
) {
Column(
Modifier
.requiredSize(width, height)
.background(MaterialTheme.colorScheme.background),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterVertically)
) {
Text(text = "Voice channel overlay for $channelId", textAlign = TextAlign.Center)
Button(onClick = {
onCollapse()
}) {
Text("Close")
}
}
}
}

View File

@ -87,6 +87,7 @@ import chat.revolt.components.screens.chat.drawer.channel.ChannelList
import chat.revolt.components.screens.chat.drawer.server.DrawerServer
import chat.revolt.components.screens.chat.drawer.server.DrawerServerlikeIcon
import chat.revolt.components.screens.chat.drawer.server.ServerDrawerSeparator
import chat.revolt.components.screens.voice.VoiceChannelOverlay
import chat.revolt.internals.Changelogs
import chat.revolt.persistence.KVStorage
import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog
@ -290,6 +291,9 @@ fun ChatRouterScreen(
var useTabletAwareUI by remember { mutableStateOf(false) }
var voiceChannelOverlay by remember { mutableStateOf(false) }
var voiceChannelOverlayChannelId by remember { mutableStateOf("") }
val toggleDrawerLambda = remember {
{
scope.launch {
@ -410,6 +414,11 @@ fun ChatRouterScreen(
is Action.ChatNavigate -> {
navController.navigate(action.route)
}
is Action.OpenVoiceChannelOverlay -> {
voiceChannelOverlayChannelId = action.channelId
voiceChannelOverlay = true
}
}
}
}
@ -671,6 +680,12 @@ fun ChatRouterScreen(
}
}
if (voiceChannelOverlay) {
VoiceChannelOverlay(voiceChannelOverlayChannelId) {
voiceChannelOverlay = false
}
}
Column(
modifier = Modifier
.fillMaxWidth()

View File

@ -31,6 +31,7 @@ import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
@ -72,6 +73,9 @@ import chat.revolt.api.routes.channel.react
import chat.revolt.api.routes.microservices.autumn.FileArgs
import chat.revolt.api.schemas.Channel
import chat.revolt.api.schemas.ChannelType
import chat.revolt.api.settings.FeatureFlags
import chat.revolt.callbacks.Action
import chat.revolt.callbacks.ActionChannel
import chat.revolt.components.chat.Message
import chat.revolt.components.chat.NativeMessageField
import chat.revolt.components.chat.SystemMessage
@ -267,6 +271,20 @@ fun ChannelScreen(
useDrawer = useDrawer
)
if (FeatureFlags.mediaConversationsGranted && channel?.channelType == ChannelType.VoiceChannel) {
Button(onClick = {
coroutineScope.launch {
ActionChannel.send(
Action.OpenVoiceChannelOverlay(
channelId
)
)
}
}) {
Text("Open voice channel overlay")
}
}
val isScrolledToBottom = remember(lazyListState) {
derivedStateOf {
lazyListState.firstVisibleItemIndex <= 6

View File

@ -12,16 +12,13 @@ import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import chat.revolt.api.settings.FeatureFlags
import chat.revolt.api.settings.LabsAccessControlVariates
import chat.revolt.screens.labs.ui.mockups.CallScreenMockup
annotation class LabsFeature
@Composable
fun LabsGuard(onTurnBack: () -> Unit = {}, content: @Composable () -> Unit) {
if (FeatureFlags.labsAccessControl is LabsAccessControlVariates.Restricted &&
(FeatureFlags.labsAccessControl as LabsAccessControlVariates.Restricted).predicate().not()
) {
if (!FeatureFlags.labsAccessControlGranted) {
AlertDialog(
onDismissRequest = { onTurnBack() },
confirmButton = {

View File

@ -45,7 +45,6 @@ import chat.revolt.activities.InviteActivity
import chat.revolt.api.RevoltAPI
import chat.revolt.api.settings.FeatureFlags
import chat.revolt.api.settings.GlobalState
import chat.revolt.api.settings.LabsAccessControlVariates
import chat.revolt.components.generic.ListHeader
import chat.revolt.components.screens.settings.SelfUserOverview
import chat.revolt.persistence.KVStorage
@ -241,9 +240,7 @@ fun SettingsScreen(
)
}
if (FeatureFlags.labsAccessControl is LabsAccessControlVariates.Restricted &&
(FeatureFlags.labsAccessControl as LabsAccessControlVariates.Restricted).predicate()
) {
if (FeatureFlags.labsAccessControlGranted) {
ListItem(
headlineContent = {
Text(

View File

@ -47,7 +47,6 @@ import chat.revolt.api.internals.hasPermission
import chat.revolt.api.routes.channel.leaveDeleteOrCloseChannel
import chat.revolt.api.schemas.ChannelType
import chat.revolt.api.settings.FeatureFlags
import chat.revolt.api.settings.LabsAccessControlVariates
import chat.revolt.internals.extensions.rememberChannelPermissions
import kotlinx.coroutines.launch
@ -151,7 +150,7 @@ fun ChannelSettingsHome(navController: NavController, channelId: String) {
}
// TODO Implement permissions UI and remove the predicate check
if (permissions.hasPermission(PermissionBit.ManageRole) && (FeatureFlags.labsAccessControl is LabsAccessControlVariates.Restricted && (FeatureFlags.labsAccessControl as LabsAccessControlVariates.Restricted).predicate())) {
if (permissions.hasPermission(PermissionBit.ManageRole) && FeatureFlags.labsAccessControlGranted) {
ListItem(
headlineContent = {
Text(