chore: update m3 and migrate bottom sheets to m3
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
7fcc93219e
commit
f845c72b23
|
|
@ -12,7 +12,6 @@ import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.IntSize
|
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.navigation.compose.dialog
|
import androidx.navigation.compose.dialog
|
||||||
import chat.revolt.BuildConfig
|
import chat.revolt.BuildConfig
|
||||||
|
|
@ -57,7 +56,6 @@ class MainActivity : FragmentActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo)
|
val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo)
|
||||||
val RevoltTweenIntSize: FiniteAnimationSpec<IntSize> = tween(400, easing = EaseInOutExpo)
|
|
||||||
val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo)
|
val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo)
|
||||||
val RevoltTweenDp: FiniteAnimationSpec<Dp> = tween(400, easing = EaseInOutExpo)
|
val RevoltTweenDp: FiniteAnimationSpec<Dp> = tween(400, easing = EaseInOutExpo)
|
||||||
|
|
||||||
|
|
@ -78,25 +76,25 @@ fun AppEntrypoint() {
|
||||||
startDestination = "splash",
|
startDestination = "splash",
|
||||||
enterTransition = {
|
enterTransition = {
|
||||||
slideIntoContainer(
|
slideIntoContainer(
|
||||||
AnimatedContentScope.SlideDirection.Left,
|
AnimatedContentTransitionScope.SlideDirection.Left,
|
||||||
animationSpec = RevoltTweenInt
|
animationSpec = RevoltTweenInt
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
exitTransition = {
|
exitTransition = {
|
||||||
slideOutOfContainer(
|
slideOutOfContainer(
|
||||||
AnimatedContentScope.SlideDirection.Left,
|
AnimatedContentTransitionScope.SlideDirection.Left,
|
||||||
animationSpec = RevoltTweenInt
|
animationSpec = RevoltTweenInt
|
||||||
) + fadeOut(animationSpec = RevoltTweenFloat)
|
) + fadeOut(animationSpec = RevoltTweenFloat)
|
||||||
},
|
},
|
||||||
popEnterTransition = {
|
popEnterTransition = {
|
||||||
slideIntoContainer(
|
slideIntoContainer(
|
||||||
AnimatedContentScope.SlideDirection.Right,
|
AnimatedContentTransitionScope.SlideDirection.Right,
|
||||||
animationSpec = RevoltTweenInt
|
animationSpec = RevoltTweenInt
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
popExitTransition = {
|
popExitTransition = {
|
||||||
slideOutOfContainer(
|
slideOutOfContainer(
|
||||||
AnimatedContentScope.SlideDirection.Right,
|
AnimatedContentTransitionScope.SlideDirection.Right,
|
||||||
animationSpec = RevoltTweenInt
|
animationSpec = RevoltTweenInt
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -127,24 +127,20 @@ object RealtimeSocket {
|
||||||
)
|
)
|
||||||
|
|
||||||
Log.d("RealtimeSocket", "Adding users to cache.")
|
Log.d("RealtimeSocket", "Adding users to cache.")
|
||||||
readyFrame.users.forEach { user ->
|
val userMap = readyFrame.users.associateBy { it.id!! }
|
||||||
RevoltAPI.userCache[user.id!!] = user
|
RevoltAPI.userCache.putAll(userMap)
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("RealtimeSocket", "Adding servers to cache.")
|
Log.d("RealtimeSocket", "Adding servers to cache.")
|
||||||
readyFrame.servers.forEach { server ->
|
val serverMap = readyFrame.servers.associateBy { it.id!! }
|
||||||
RevoltAPI.serverCache[server.id!!] = server
|
RevoltAPI.serverCache.putAll(serverMap)
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("RealtimeSocket", "Adding channels to cache.")
|
Log.d("RealtimeSocket", "Adding channels to cache.")
|
||||||
readyFrame.channels.forEach { channel ->
|
val channelMap = readyFrame.channels.associateBy { it.id!! }
|
||||||
RevoltAPI.channelCache[channel.id!!] = channel
|
RevoltAPI.channelCache.putAll(channelMap)
|
||||||
}
|
|
||||||
|
|
||||||
Log.d("RealtimeSocket", "Adding emojis to cache.")
|
Log.d("RealtimeSocket", "Adding emojis to cache.")
|
||||||
readyFrame.emojis.forEach { emoji ->
|
val emojiMap = readyFrame.emojis.associateBy { it.id!! }
|
||||||
RevoltAPI.emojiCache[emoji.id!!] = emoji
|
RevoltAPI.emojiCache.putAll(emojiMap)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"Message" -> {
|
"Message" -> {
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ fun MessageField(
|
||||||
keyboardOptions = KeyboardOptions.Default,
|
keyboardOptions = KeyboardOptions.Default,
|
||||||
keyboardActions = KeyboardActions.Default,
|
keyboardActions = KeyboardActions.Default,
|
||||||
decorationBox = @Composable { innerTextField ->
|
decorationBox = @Composable { innerTextField ->
|
||||||
TextFieldDefaults.TextFieldDecorationBox(
|
TextFieldDefaults.DecorationBox(
|
||||||
value = messageContent,
|
value = messageContent,
|
||||||
innerTextField = innerTextField,
|
innerTextField = innerTextField,
|
||||||
enabled = !disabled,
|
enabled = !disabled,
|
||||||
|
|
@ -90,13 +90,17 @@ fun MessageField(
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
colors = TextFieldDefaults.textFieldColors(
|
colors = TextFieldDefaults.colors(
|
||||||
focusedIndicatorColor = Color.Transparent,
|
focusedIndicatorColor = Color.Transparent,
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
disabledIndicatorColor = Color.Transparent,
|
disabledIndicatorColor = Color.Transparent,
|
||||||
errorIndicatorColor = Color.Transparent,
|
errorIndicatorColor = Color.Transparent,
|
||||||
placeholderColor = Color.Gray,
|
unfocusedPlaceholderColor = Color.Gray,
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)
|
focusedPlaceholderColor = Color.Gray,
|
||||||
|
unfocusedContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(
|
||||||
|
1.dp
|
||||||
|
),
|
||||||
|
focusedContainerColor = Color.Transparent,
|
||||||
),
|
),
|
||||||
contentPadding = PaddingValues(16.dp),
|
contentPadding = PaddingValues(16.dp),
|
||||||
leadingIcon = {
|
leadingIcon = {
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,16 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.DrawerState
|
import androidx.compose.material3.DrawerState
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
|
@ -26,6 +32,7 @@ import chat.revolt.R
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
import chat.revolt.api.schemas.ChannelType
|
import chat.revolt.api.schemas.ChannelType
|
||||||
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
|
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
|
||||||
|
import chat.revolt.sheets.ChannelContextSheet
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|
@ -35,10 +42,31 @@ fun RowScope.ChannelList(
|
||||||
drawerState: DrawerState,
|
drawerState: DrawerState,
|
||||||
currentChannel: String?,
|
currentChannel: String?,
|
||||||
onChannelClick: (String) -> Unit,
|
onChannelClick: (String) -> Unit,
|
||||||
onChannelLongClick: (String) -> Unit,
|
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
var channelContextSheetShown by remember { mutableStateOf(false) }
|
||||||
|
var channelContextSheetTarget by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
if (channelContextSheetShown) {
|
||||||
|
val channelContextSheetState = rememberModalBottomSheetState()
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = channelContextSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
channelContextSheetShown = false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
ChannelContextSheet(
|
||||||
|
channelId = channelContextSheetTarget,
|
||||||
|
onHideSheet = {
|
||||||
|
channelContextSheetState.hide()
|
||||||
|
channelContextSheetShown = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Surface(
|
Surface(
|
||||||
tonalElevation = 1.dp,
|
tonalElevation = 1.dp,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -74,7 +102,8 @@ fun RowScope.ChannelList(
|
||||||
coroutineScope.launch { drawerState.close() }
|
coroutineScope.launch { drawerState.close() }
|
||||||
},
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
onChannelLongClick(channel.id ?: return@DrawerChannel)
|
channelContextSheetTarget = channel.id ?: return@DrawerChannel
|
||||||
|
channelContextSheetShown = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -132,7 +161,8 @@ fun RowScope.ChannelList(
|
||||||
coroutineScope.launch { drawerState.close() }
|
coroutineScope.launch { drawerState.close() }
|
||||||
},
|
},
|
||||||
onLongClick = {
|
onLongClick = {
|
||||||
onChannelLongClick(ch.id ?: return@DrawerChannel)
|
channelContextSheetTarget = ch.id ?: return@DrawerChannel
|
||||||
|
channelContextSheetShown = true
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
|
|
@ -22,10 +21,11 @@ import androidx.compose.material3.DismissibleNavigationDrawer
|
||||||
import androidx.compose.material3.DrawerValue
|
import androidx.compose.material3.DrawerValue
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.ModalBottomSheet
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextButton
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.material3.rememberDrawerState
|
import androidx.compose.material3.rememberDrawerState
|
||||||
|
import androidx.compose.material3.rememberModalBottomSheetState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
|
@ -62,23 +62,16 @@ import chat.revolt.components.screens.chat.drawer.server.DrawerServerlikeIcon
|
||||||
import chat.revolt.components.screens.chat.drawer.server.ServerDrawerSeparator
|
import chat.revolt.components.screens.chat.drawer.server.ServerDrawerSeparator
|
||||||
import chat.revolt.persistence.KVStorage
|
import chat.revolt.persistence.KVStorage
|
||||||
import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog
|
import chat.revolt.screens.chat.dialogs.safety.ReportMessageDialog
|
||||||
import chat.revolt.screens.chat.sheets.AddServerSheet
|
|
||||||
import chat.revolt.screens.chat.sheets.ChannelContextSheet
|
|
||||||
import chat.revolt.screens.chat.sheets.ChannelInfoSheet
|
|
||||||
import chat.revolt.screens.chat.sheets.MessageContextSheet
|
|
||||||
import chat.revolt.screens.chat.sheets.StatusSheet
|
|
||||||
import chat.revolt.screens.chat.views.HomeScreen
|
import chat.revolt.screens.chat.views.HomeScreen
|
||||||
import chat.revolt.screens.chat.views.NoCurrentChannelScreen
|
import chat.revolt.screens.chat.views.NoCurrentChannelScreen
|
||||||
import chat.revolt.screens.chat.views.channel.ChannelScreen
|
import chat.revolt.screens.chat.views.channel.ChannelScreen
|
||||||
|
import chat.revolt.sheets.AddServerSheet
|
||||||
|
import chat.revolt.sheets.StatusSheet
|
||||||
import com.airbnb.lottie.RenderMode
|
import com.airbnb.lottie.RenderMode
|
||||||
import com.airbnb.lottie.compose.LottieAnimation
|
import com.airbnb.lottie.compose.LottieAnimation
|
||||||
import com.airbnb.lottie.compose.LottieCompositionSpec
|
import com.airbnb.lottie.compose.LottieCompositionSpec
|
||||||
import com.airbnb.lottie.compose.animateLottieCompositionAsState
|
import com.airbnb.lottie.compose.animateLottieCompositionAsState
|
||||||
import com.airbnb.lottie.compose.rememberLottieComposition
|
import com.airbnb.lottie.compose.rememberLottieComposition
|
||||||
import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi
|
|
||||||
import com.google.accompanist.navigation.material.ModalBottomSheetLayout
|
|
||||||
import com.google.accompanist.navigation.material.bottomSheet
|
|
||||||
import com.google.accompanist.navigation.material.rememberBottomSheetNavigator
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -163,7 +156,6 @@ class ChatRouterViewModel @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(
|
@OptIn(
|
||||||
ExperimentalMaterialNavigationApi::class,
|
|
||||||
ExperimentalComposeUiApi::class,
|
ExperimentalComposeUiApi::class,
|
||||||
ExperimentalMaterial3Api::class
|
ExperimentalMaterial3Api::class
|
||||||
)
|
)
|
||||||
|
|
@ -173,8 +165,7 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val keyboardController = LocalSoftwareKeyboardController.current
|
val keyboardController = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
val bottomSheetNavigator = rememberBottomSheetNavigator()
|
val navController = rememberNavController()
|
||||||
val navController = rememberNavController(bottomSheetNavigator)
|
|
||||||
|
|
||||||
val showSidebarSpark = remember { mutableStateOf(false) }
|
val showSidebarSpark = remember { mutableStateOf(false) }
|
||||||
val sidebarSparkComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.open_settings_tutorial))
|
val sidebarSparkComposition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.open_settings_tutorial))
|
||||||
|
|
@ -182,6 +173,9 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
composition = sidebarSparkComposition,
|
composition = sidebarSparkComposition,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var showStatusSheet by remember { mutableStateOf(false) }
|
||||||
|
var showAddServerSheet by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
BackHandler(enabled = drawerState.isClosed) {
|
BackHandler(enabled = drawerState.isClosed) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
drawerState.open()
|
drawerState.open()
|
||||||
|
|
@ -230,215 +224,210 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ModalBottomSheetLayout(
|
if (showSidebarSpark.value) {
|
||||||
sheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),
|
AlertDialog(
|
||||||
sheetBackgroundColor = MaterialTheme.colorScheme.surface,
|
onDismissRequest = {},
|
||||||
bottomSheetNavigator = bottomSheetNavigator,
|
title = {
|
||||||
) {
|
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial))
|
||||||
if (showSidebarSpark.value) {
|
},
|
||||||
AlertDialog(
|
text = {
|
||||||
onDismissRequest = {},
|
Column {
|
||||||
title = {
|
LottieAnimation(
|
||||||
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial))
|
composition = sidebarSparkComposition,
|
||||||
},
|
progress = { sidebarSparkProgress },
|
||||||
text = {
|
modifier = Modifier
|
||||||
Column {
|
.fillMaxWidth()
|
||||||
LottieAnimation(
|
.aspectRatio(1f),
|
||||||
composition = sidebarSparkComposition,
|
renderMode = RenderMode.HARDWARE
|
||||||
progress = { sidebarSparkProgress },
|
)
|
||||||
modifier = Modifier
|
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_description_1))
|
||||||
.fillMaxWidth()
|
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_description_2))
|
||||||
.aspectRatio(1f),
|
}
|
||||||
renderMode = RenderMode.HARDWARE
|
},
|
||||||
)
|
confirmButton = {
|
||||||
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_description_1))
|
TextButton(onClick = {
|
||||||
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_description_2))
|
scope.launch {
|
||||||
|
viewModel.setSettingsHintDisplayed()
|
||||||
|
}
|
||||||
|
showSidebarSpark.value = false
|
||||||
|
}) {
|
||||||
|
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_acknowledge))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showStatusSheet) {
|
||||||
|
val statusSheetState = rememberModalBottomSheetState()
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = statusSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
showStatusSheet = false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
StatusSheet(
|
||||||
|
onBeforeNavigation = {
|
||||||
|
scope.launch {
|
||||||
|
statusSheetState.hide()
|
||||||
|
showStatusSheet = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
onGoSettings = {
|
||||||
TextButton(onClick = {
|
topNav.navigate("settings")
|
||||||
scope.launch {
|
|
||||||
viewModel.setSettingsHintDisplayed()
|
|
||||||
}
|
|
||||||
showSidebarSpark.value = false
|
|
||||||
}) {
|
|
||||||
Text(stringResource(id = R.string.spark_sidebar_settings_tutorial_acknowledge))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
if (showAddServerSheet) {
|
||||||
AnimatedVisibility(visible = RealtimeSocket.disconnectionState != DisconnectionState.Connected) {
|
val addServerSheetState = rememberModalBottomSheetState()
|
||||||
DisconnectedNotice(
|
|
||||||
state = RealtimeSocket.disconnectionState,
|
|
||||||
onReconnect = {
|
|
||||||
RealtimeSocket.updateDisconnectionState(DisconnectionState.Reconnecting)
|
|
||||||
scope.launch { RevoltAPI.connectWS() }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
DismissibleNavigationDrawer(
|
ModalBottomSheet(
|
||||||
drawerState = drawerState,
|
sheetState = addServerSheetState,
|
||||||
drawerContent = {
|
onDismissRequest = {
|
||||||
DismissibleDrawerSheet(
|
showAddServerSheet = false
|
||||||
drawerContainerColor = Color.Transparent,
|
},
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth()) {
|
AddServerSheet()
|
||||||
Row {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxHeight()
|
|
||||||
.verticalScroll(rememberScrollState()),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
|
||||||
) {
|
|
||||||
UserAvatar(
|
|
||||||
username = RevoltAPI.userCache[RevoltAPI.selfId]?.username
|
|
||||||
?: "",
|
|
||||||
presence = presenceFromStatus(
|
|
||||||
RevoltAPI.userCache[RevoltAPI.selfId]?.status?.presence
|
|
||||||
?: ""
|
|
||||||
),
|
|
||||||
userId = RevoltAPI.selfId ?: "",
|
|
||||||
avatar = RevoltAPI.userCache[RevoltAPI.selfId]?.avatar,
|
|
||||||
size = 48.dp,
|
|
||||||
presenceSize = 16.dp,
|
|
||||||
onClick = {
|
|
||||||
viewModel.navigateToServer("home", navController)
|
|
||||||
},
|
|
||||||
onLongClick = {
|
|
||||||
navController.navigate("status")
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(8.dp)
|
|
||||||
.size(48.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
ServerDrawerSeparator()
|
|
||||||
|
|
||||||
RevoltAPI.serverCache.values
|
|
||||||
.sortedBy { it.id }
|
|
||||||
.forEach { server ->
|
|
||||||
if (server.id == null || server.name == null) return@forEach
|
|
||||||
|
|
||||||
DrawerServer(
|
|
||||||
iconId = server.icon?.id,
|
|
||||||
serverName = server.name,
|
|
||||||
hasUnreads = RevoltAPI.unreads.serverHasUnread(
|
|
||||||
server.id
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
viewModel.navigateToServer(
|
|
||||||
server.id,
|
|
||||||
navController
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawerServerlikeIcon(
|
|
||||||
onClick = {
|
|
||||||
navController.navigate("add_server")
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
Icons.Default.Add,
|
|
||||||
contentDescription = stringResource(id = R.string.server_plus_alt),
|
|
||||||
modifier = Modifier.padding(4.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Crossfade(
|
|
||||||
targetState = viewModel.currentServer,
|
|
||||||
label = "Channel List"
|
|
||||||
) {
|
|
||||||
ChannelList(
|
|
||||||
serverId = it,
|
|
||||||
drawerState = drawerState,
|
|
||||||
currentChannel = viewModel.currentChannel,
|
|
||||||
onChannelClick = { channelId ->
|
|
||||||
viewModel.navigateToChannel(channelId, navController)
|
|
||||||
},
|
|
||||||
onChannelLongClick = { channelId ->
|
|
||||||
navController.navigate("channel/$channelId/info")
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content = {
|
|
||||||
Column(Modifier.fillMaxSize()) {
|
|
||||||
NavHost(navController = navController, startDestination = "home") {
|
|
||||||
composable("home") {
|
|
||||||
HomeScreen(navController = topNav)
|
|
||||||
}
|
|
||||||
composable("channel/{channelId}") { backStackEntry ->
|
|
||||||
val channelId = backStackEntry.arguments?.getString("channelId")
|
|
||||||
if (channelId != null) {
|
|
||||||
ChannelScreen(
|
|
||||||
navController = navController,
|
|
||||||
channelId = channelId,
|
|
||||||
onToggleDrawer = {
|
|
||||||
scope.launch {
|
|
||||||
if (drawerState.isOpen) drawerState.close()
|
|
||||||
else drawerState.open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
composable("no_current_channel") {
|
|
||||||
NoCurrentChannelScreen()
|
|
||||||
}
|
|
||||||
|
|
||||||
bottomSheet("channel/{channelId}/info") { backStackEntry ->
|
|
||||||
val channelId = backStackEntry.arguments?.getString("channelId")
|
|
||||||
if (channelId != null) {
|
|
||||||
ChannelInfoSheet(
|
|
||||||
navController = navController,
|
|
||||||
channelId = channelId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomSheet("channel/{channelId}/menu") { backStackEntry ->
|
|
||||||
val channelId = backStackEntry.arguments?.getString("channelId")
|
|
||||||
if (channelId != null) {
|
|
||||||
ChannelContextSheet(
|
|
||||||
navController = navController,
|
|
||||||
channelId = channelId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomSheet("message/{messageId}/menu") { backStackEntry ->
|
|
||||||
val messageId = backStackEntry.arguments?.getString("messageId")
|
|
||||||
if (messageId != null) {
|
|
||||||
MessageContextSheet(
|
|
||||||
navController = navController,
|
|
||||||
messageId = messageId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bottomSheet("status") {
|
|
||||||
StatusSheet(navController = navController, topNav = topNav)
|
|
||||||
}
|
|
||||||
bottomSheet("add_server") {
|
|
||||||
AddServerSheet()
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog("report/message/{messageId}") { backStackEntry ->
|
|
||||||
val messageId = backStackEntry.arguments?.getString("messageId")
|
|
||||||
if (messageId != null) {
|
|
||||||
ReportMessageDialog(
|
|
||||||
navController = navController,
|
|
||||||
messageId = messageId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
AnimatedVisibility(visible = RealtimeSocket.disconnectionState != DisconnectionState.Connected) {
|
||||||
|
DisconnectedNotice(
|
||||||
|
state = RealtimeSocket.disconnectionState,
|
||||||
|
onReconnect = {
|
||||||
|
RealtimeSocket.updateDisconnectionState(DisconnectionState.Reconnecting)
|
||||||
|
scope.launch { RevoltAPI.connectWS() }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
DismissibleNavigationDrawer(
|
||||||
|
drawerState = drawerState,
|
||||||
|
drawerContent = {
|
||||||
|
DismissibleDrawerSheet(
|
||||||
|
drawerContainerColor = Color.Transparent,
|
||||||
|
) {
|
||||||
|
Column(Modifier.fillMaxWidth()) {
|
||||||
|
Row {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxHeight()
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
UserAvatar(
|
||||||
|
username = RevoltAPI.userCache[RevoltAPI.selfId]?.username
|
||||||
|
?: "",
|
||||||
|
presence = presenceFromStatus(
|
||||||
|
RevoltAPI.userCache[RevoltAPI.selfId]?.status?.presence
|
||||||
|
?: ""
|
||||||
|
),
|
||||||
|
userId = RevoltAPI.selfId ?: "",
|
||||||
|
avatar = RevoltAPI.userCache[RevoltAPI.selfId]?.avatar,
|
||||||
|
size = 48.dp,
|
||||||
|
presenceSize = 16.dp,
|
||||||
|
onClick = {
|
||||||
|
viewModel.navigateToServer("home", navController)
|
||||||
|
},
|
||||||
|
onLongClick = {
|
||||||
|
showStatusSheet = true
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(8.dp)
|
||||||
|
.size(48.dp)
|
||||||
|
)
|
||||||
|
|
||||||
|
ServerDrawerSeparator()
|
||||||
|
|
||||||
|
RevoltAPI.serverCache.values
|
||||||
|
.sortedBy { it.id }
|
||||||
|
.forEach { server ->
|
||||||
|
if (server.id == null || server.name == null) return@forEach
|
||||||
|
|
||||||
|
DrawerServer(
|
||||||
|
iconId = server.icon?.id,
|
||||||
|
serverName = server.name,
|
||||||
|
hasUnreads = RevoltAPI.unreads.serverHasUnread(
|
||||||
|
server.id
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
viewModel.navigateToServer(
|
||||||
|
server.id,
|
||||||
|
navController
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawerServerlikeIcon(
|
||||||
|
onClick = {
|
||||||
|
showAddServerSheet = true
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Default.Add,
|
||||||
|
contentDescription = stringResource(id = R.string.server_plus_alt),
|
||||||
|
modifier = Modifier.padding(4.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Crossfade(
|
||||||
|
targetState = viewModel.currentServer,
|
||||||
|
label = "Channel List"
|
||||||
|
) {
|
||||||
|
ChannelList(
|
||||||
|
serverId = it,
|
||||||
|
drawerState = drawerState,
|
||||||
|
currentChannel = viewModel.currentChannel,
|
||||||
|
onChannelClick = { channelId ->
|
||||||
|
viewModel.navigateToChannel(channelId, navController)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = {
|
||||||
|
Column(Modifier.fillMaxSize()) {
|
||||||
|
NavHost(navController = navController, startDestination = "home") {
|
||||||
|
composable("home") {
|
||||||
|
HomeScreen(navController = topNav)
|
||||||
|
}
|
||||||
|
|
||||||
|
composable("channel/{channelId}") { backStackEntry ->
|
||||||
|
val channelId = backStackEntry.arguments?.getString("channelId")
|
||||||
|
if (channelId != null) {
|
||||||
|
ChannelScreen(
|
||||||
|
navController = navController,
|
||||||
|
channelId = channelId,
|
||||||
|
onToggleDrawer = {
|
||||||
|
scope.launch {
|
||||||
|
if (drawerState.isOpen) drawerState.close()
|
||||||
|
else drawerState.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
composable("no_current_channel") {
|
||||||
|
NoCurrentChannelScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog("report/message/{messageId}") { backStackEntry ->
|
||||||
|
val messageId = backStackEntry.arguments?.getString("messageId")
|
||||||
|
if (messageId != null) {
|
||||||
|
ReportMessageDialog(
|
||||||
|
navController = navController,
|
||||||
|
messageId = messageId
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
package chat.revolt.screens.chat.sheets
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Settings
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import chat.revolt.R
|
|
||||||
import chat.revolt.api.RevoltAPI
|
|
||||||
import chat.revolt.components.generic.SheetClickable
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun StatusSheet(
|
|
||||||
navController: NavController,
|
|
||||||
topNav: NavController,
|
|
||||||
) {
|
|
||||||
if (RevoltAPI.selfId == null || RevoltAPI.userCache[RevoltAPI.selfId] == null) {
|
|
||||||
navController.popBackStack()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val selfUser = RevoltAPI.userCache[RevoltAPI.selfId]!!
|
|
||||||
|
|
||||||
Surface {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
|
||||||
.verticalScroll(rememberScrollState())
|
|
||||||
) {
|
|
||||||
Text(text = "Logged in as @${selfUser.username} (${selfUser.id})")
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
SheetClickable(
|
|
||||||
icon = { modifier ->
|
|
||||||
Icon(
|
|
||||||
imageVector = Icons.Default.Settings,
|
|
||||||
contentDescription = null,
|
|
||||||
modifier = modifier
|
|
||||||
)
|
|
||||||
},
|
|
||||||
label = { style ->
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.settings),
|
|
||||||
style = style
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
topNav.navigate("settings")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -43,6 +43,8 @@ import chat.revolt.internals.markdown.MarkdownState
|
||||||
import chat.revolt.internals.markdown.UserMentionRule
|
import chat.revolt.internals.markdown.UserMentionRule
|
||||||
import chat.revolt.internals.markdown.createCodeRule
|
import chat.revolt.internals.markdown.createCodeRule
|
||||||
import chat.revolt.internals.markdown.createInlineCodeRule
|
import chat.revolt.internals.markdown.createInlineCodeRule
|
||||||
|
import chat.revolt.sheets.ChannelInfoSheet
|
||||||
|
import chat.revolt.sheets.MessageContextSheet
|
||||||
import com.discord.simpleast.core.simple.SimpleMarkdownRules
|
import com.discord.simpleast.core.simple.SimpleMarkdownRules
|
||||||
import com.discord.simpleast.core.simple.SimpleRenderer
|
import com.discord.simpleast.core.simple.SimpleRenderer
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
|
|
@ -50,6 +52,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ChannelScreen(
|
fun ChannelScreen(
|
||||||
navController: NavController,
|
navController: NavController,
|
||||||
|
|
@ -65,6 +68,11 @@ fun ChannelScreen(
|
||||||
|
|
||||||
val codeBlockColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
val codeBlockColor = MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp)
|
||||||
|
|
||||||
|
var channelInfoSheetShown by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
var messageContextSheetShown by remember { mutableStateOf(false) }
|
||||||
|
var messageContextSheetTarget by remember { mutableStateOf("") }
|
||||||
|
|
||||||
val pickFileLauncher = rememberLauncherForActivityResult(
|
val pickFileLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.OpenMultipleDocuments()
|
contract = ActivityResultContracts.OpenMultipleDocuments()
|
||||||
) { uriList ->
|
) { uriList ->
|
||||||
|
|
@ -108,6 +116,43 @@ fun ChannelScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (channelInfoSheetShown) {
|
||||||
|
val channelInfoSheetState = rememberModalBottomSheetState()
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = channelInfoSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
channelInfoSheetShown = false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
ChannelInfoSheet(
|
||||||
|
channelId = channelId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageContextSheetShown) {
|
||||||
|
val messageContextSheetState = rememberModalBottomSheetState()
|
||||||
|
|
||||||
|
ModalBottomSheet(
|
||||||
|
sheetState = messageContextSheetState,
|
||||||
|
onDismissRequest = {
|
||||||
|
messageContextSheetShown = false
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
MessageContextSheet(
|
||||||
|
messageId = messageContextSheetTarget,
|
||||||
|
onHideSheet = {
|
||||||
|
messageContextSheetState.hide()
|
||||||
|
messageContextSheetShown = false
|
||||||
|
},
|
||||||
|
onReportMessage = {
|
||||||
|
navController.navigate("report/message/$messageContextSheetTarget")
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (channel?.channelType == null) {
|
if (channel?.channelType == null) {
|
||||||
CircularProgressIndicator()
|
CircularProgressIndicator()
|
||||||
return
|
return
|
||||||
|
|
@ -117,11 +162,11 @@ fun ChannelScreen(
|
||||||
ChannelHeader(
|
ChannelHeader(
|
||||||
channel = channel,
|
channel = channel,
|
||||||
onChannelClick = {
|
onChannelClick = {
|
||||||
navController.navigate("channel/${channel.id}/info")
|
channelInfoSheetShown = true
|
||||||
},
|
},
|
||||||
onToggleDrawer = onToggleDrawer
|
onToggleDrawer = onToggleDrawer
|
||||||
)
|
)
|
||||||
|
|
||||||
val isScrolledToBottom = remember(lazyListState) {
|
val isScrolledToBottom = remember(lazyListState) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
lazyListState.firstVisibleItemIndex <= 6
|
lazyListState.firstVisibleItemIndex <= 6
|
||||||
|
|
@ -202,7 +247,8 @@ fun ChannelScreen(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onMessageContextMenu = {
|
onMessageContextMenu = {
|
||||||
navController.navigate("message/${message.id}/menu")
|
messageContextSheetShown = true
|
||||||
|
messageContextSheetTarget = message.id ?: ""
|
||||||
},
|
},
|
||||||
canReply = true,
|
canReply = true,
|
||||||
onReply = {
|
onReply = {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package chat.revolt.screens.chat.sheets
|
package chat.revolt.sheets
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
|
@ -1,17 +1,23 @@
|
||||||
package chat.revolt.screens.chat.sheets
|
package chat.revolt.sheets
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.navigation.NavController
|
import androidx.compose.ui.unit.dp
|
||||||
import chat.revolt.R
|
import chat.revolt.R
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
import chat.revolt.components.generic.SheetClickable
|
import chat.revolt.components.generic.SheetClickable
|
||||||
|
|
@ -19,12 +25,18 @@ import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChannelContextSheet(
|
fun ChannelContextSheet(
|
||||||
navController: NavController,
|
|
||||||
channelId: String,
|
channelId: String,
|
||||||
|
onHideSheet: suspend () -> Unit,
|
||||||
) {
|
) {
|
||||||
val channel = RevoltAPI.channelCache[channelId]
|
val channel = RevoltAPI.channelCache[channelId]
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
navController.popBackStack()
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(200.dp)
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +69,10 @@ fun ChannelContextSheet(
|
||||||
context.getString(R.string.channel_context_sheet_actions_copy_id_copied),
|
context.getString(R.string.channel_context_sheet_actions_copy_id_copied),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -79,8 +94,8 @@ fun ChannelContextSheet(
|
||||||
channel.lastMessageID?.let {
|
channel.lastMessageID?.let {
|
||||||
RevoltAPI.unreads.markAsRead(channelId, it, sync = true)
|
RevoltAPI.unreads.markAsRead(channelId, it, sync = true)
|
||||||
}
|
}
|
||||||
|
onHideSheet()
|
||||||
}
|
}
|
||||||
navController.popBackStack()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package chat.revolt.screens.chat.sheets
|
package chat.revolt.sheets
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
|
@ -10,26 +12,32 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.List
|
import androidx.compose.material.icons.filled.List
|
||||||
import androidx.compose.material.icons.filled.Notifications
|
import androidx.compose.material.icons.filled.Notifications
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
|
||||||
import chat.revolt.R
|
import chat.revolt.R
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
import chat.revolt.components.generic.SheetClickable
|
import chat.revolt.components.generic.SheetClickable
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChannelInfoSheet(
|
fun ChannelInfoSheet(
|
||||||
navController: NavController,
|
|
||||||
channelId: String,
|
channelId: String,
|
||||||
) {
|
) {
|
||||||
val channel = RevoltAPI.channelCache[channelId]
|
val channel = RevoltAPI.channelCache[channelId]
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
navController.popBackStack()
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(200.dp)
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
package chat.revolt.screens.chat.sheets
|
package chat.revolt.sheets
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
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.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
|
@ -12,12 +13,14 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.surfaceColorAtElevation
|
import androidx.compose.material3.surfaceColorAtElevation
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.platform.LocalClipboardManager
|
import androidx.compose.ui.platform.LocalClipboardManager
|
||||||
|
|
@ -26,7 +29,6 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavController
|
|
||||||
import chat.revolt.R
|
import chat.revolt.R
|
||||||
import chat.revolt.api.REVOLT_APP
|
import chat.revolt.api.REVOLT_APP
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
|
|
@ -37,12 +39,19 @@ import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessageContextSheet(
|
fun MessageContextSheet(
|
||||||
navController: NavController,
|
|
||||||
messageId: String,
|
messageId: String,
|
||||||
|
onHideSheet: suspend () -> Unit,
|
||||||
|
onReportMessage: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val message = RevoltAPI.messageCache[messageId]
|
val message = RevoltAPI.messageCache[messageId]
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
navController.popBackStack()
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(200.dp)
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,8 +98,8 @@ fun MessageContextSheet(
|
||||||
) {
|
) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
UiCallbacks.replyToMessage(messageId)
|
UiCallbacks.replyToMessage(messageId)
|
||||||
|
onHideSheet()
|
||||||
}
|
}
|
||||||
navController.popBackStack()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -113,7 +122,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.comingsoon_toast),
|
context.getString(R.string.comingsoon_toast),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -132,22 +144,27 @@ fun MessageContextSheet(
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (message.content.isNullOrEmpty()) {
|
if (message.content.isNullOrEmpty()) {
|
||||||
Toast.makeText(
|
coroutineScope.launch {
|
||||||
context,
|
onHideSheet()
|
||||||
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
Toast.makeText(
|
||||||
Toast.LENGTH_SHORT
|
context,
|
||||||
).show()
|
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
||||||
navController.popBackStack()
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
return@SheetClickable
|
return@SheetClickable
|
||||||
}
|
}
|
||||||
|
|
||||||
clipboardManager.setText(AnnotatedString(message.content))
|
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context.getString(R.string.copied),
|
context.getString(R.string.copied),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
clipboardManager.setText(AnnotatedString(message.content))
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -171,7 +188,11 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
context.getString(R.string.message_context_sheet_actions_copy_failed_empty),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
|
|
||||||
return@SheetClickable
|
return@SheetClickable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,7 +208,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.message_context_sheet_actions_copy_link_copied),
|
context.getString(R.string.message_context_sheet_actions_copy_link_copied),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -213,7 +237,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.message_context_sheet_actions_copy_id_copied),
|
context.getString(R.string.message_context_sheet_actions_copy_id_copied),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -237,7 +264,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.comingsoon_toast),
|
context.getString(R.string.comingsoon_toast),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -260,7 +290,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.comingsoon_toast),
|
context.getString(R.string.comingsoon_toast),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -283,7 +316,10 @@ fun MessageContextSheet(
|
||||||
context.getString(R.string.comingsoon_toast),
|
context.getString(R.string.comingsoon_toast),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
navController.popBackStack()
|
|
||||||
|
coroutineScope.launch {
|
||||||
|
onHideSheet()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SheetClickable(
|
SheetClickable(
|
||||||
|
|
@ -301,7 +337,9 @@ fun MessageContextSheet(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
navController.navigate("report/message/${message.id}")
|
coroutineScope.launch {
|
||||||
|
onReportMessage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
package chat.revolt.sheets
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.Settings
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import chat.revolt.R
|
||||||
|
import chat.revolt.api.RevoltAPI
|
||||||
|
import chat.revolt.components.generic.SheetClickable
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun StatusSheet(
|
||||||
|
onBeforeNavigation: () -> Unit,
|
||||||
|
onGoSettings: () -> Unit
|
||||||
|
) {
|
||||||
|
val selfUser = RevoltAPI.userCache[RevoltAPI.selfId]!!
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||||
|
.verticalScroll(rememberScrollState())
|
||||||
|
) {
|
||||||
|
Text(text = "Logged in as @${selfUser.username} (${selfUser.id})")
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
SheetClickable(
|
||||||
|
icon = { modifier ->
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.Settings,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = modifier
|
||||||
|
)
|
||||||
|
},
|
||||||
|
label = { style ->
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.settings),
|
||||||
|
style = style
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
onBeforeNavigation()
|
||||||
|
onGoSettings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
buildscript {
|
buildscript {
|
||||||
ext {
|
ext {
|
||||||
compose_version = '1.4.0'
|
compose_version = '1.4.0'
|
||||||
compose_bom_version = '2023.01.00'
|
compose_bom_version = '2023.05.01'
|
||||||
accompanist_version = '0.28.0'
|
accompanist_version = '0.31.2-alpha'
|
||||||
okhttp_version = '4.10.0'
|
okhttp_version = '4.10.0'
|
||||||
nav_version = '2.5.3'
|
nav_version = '2.5.3'
|
||||||
hilt_version = '2.44'
|
hilt_version = '2.44'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue