From 67881fefb79b17196042cbad5feee5f3c19f5cd3 Mon Sep 17 00:00:00 2001 From: Infi Date: Sat, 6 Apr 2024 00:07:34 +0200 Subject: [PATCH] feat: placeholder media channel overlay Signed-off-by: Infi --- .../chat/revolt/api/settings/FeatureFlags.kt | 31 +++++++++ .../chat/revolt/callbacks/ActionChannel.kt | 1 + .../screens/voice/VoiceChannelOverlay.kt | 64 +++++++++++++++++++ .../revolt/screens/chat/ChatRouterScreen.kt | 15 +++++ .../chat/views/channel/ChannelScreen.kt | 18 ++++++ .../revolt/screens/labs/LabsRootScreen.kt | 5 +- .../revolt/screens/settings/SettingsScreen.kt | 5 +- .../settings/channel/ChannelSettingsHome.kt | 3 +- 8 files changed, 132 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/chat/revolt/components/screens/voice/VoiceChannelOverlay.kt diff --git a/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt b/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt index cc273411..da014bcb 100644 --- a/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt +++ b/app/src/main/java/chat/revolt/api/settings/FeatureFlags.kt @@ -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( @@ -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.Restricted { + RevoltAPI.selfId == SpecialUsers.JENNIFER + } + ) + + val mediaConversationsGranted: Boolean + get() = when (mediaConversations) { + is MediaConversationsVariates.Enabled -> true + is MediaConversationsVariates.Restricted -> (mediaConversations as MediaConversationsVariates.Restricted).predicate() + } } diff --git a/app/src/main/java/chat/revolt/callbacks/ActionChannel.kt b/app/src/main/java/chat/revolt/callbacks/ActionChannel.kt index 127158e6..04d935a0 100644 --- a/app/src/main/java/chat/revolt/callbacks/ActionChannel.kt +++ b/app/src/main/java/chat/revolt/callbacks/ActionChannel.kt @@ -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( diff --git a/app/src/main/java/chat/revolt/components/screens/voice/VoiceChannelOverlay.kt b/app/src/main/java/chat/revolt/components/screens/voice/VoiceChannelOverlay.kt new file mode 100644 index 00000000..d326d44b --- /dev/null +++ b/app/src/main/java/chat/revolt/components/screens/voice/VoiceChannelOverlay.kt @@ -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") + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt b/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt index 17d76afc..a0287f8c 100644 --- a/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/ChatRouterScreen.kt @@ -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() diff --git a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt index bc1c925b..db99faf3 100644 --- a/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt +++ b/app/src/main/java/chat/revolt/screens/chat/views/channel/ChannelScreen.kt @@ -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 diff --git a/app/src/main/java/chat/revolt/screens/labs/LabsRootScreen.kt b/app/src/main/java/chat/revolt/screens/labs/LabsRootScreen.kt index 69d244a1..626768b3 100644 --- a/app/src/main/java/chat/revolt/screens/labs/LabsRootScreen.kt +++ b/app/src/main/java/chat/revolt/screens/labs/LabsRootScreen.kt @@ -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 = { diff --git a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt index fff7e24f..495d4147 100644 --- a/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt +++ b/app/src/main/java/chat/revolt/screens/settings/SettingsScreen.kt @@ -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( diff --git a/app/src/main/java/chat/revolt/screens/settings/channel/ChannelSettingsHome.kt b/app/src/main/java/chat/revolt/screens/settings/channel/ChannelSettingsHome.kt index 330e6ff5..2e167be4 100644 --- a/app/src/main/java/chat/revolt/screens/settings/channel/ChannelSettingsHome.kt +++ b/app/src/main/java/chat/revolt/screens/settings/channel/ChannelSettingsHome.kt @@ -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(