feat(ui): initial impl of guilds in channel browser

This commit is contained in:
Cilly Leang 2026-01-29 02:23:01 +11:00
parent 30c1ba5780
commit 83f13d4b5c
Signed by: cilly
GPG key ID: 6500251E087653C9

View file

@ -19,6 +19,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialExpressiveTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MotionScheme
import androidx.compose.material3.SegmentedListItem
import androidx.compose.material3.SheetValue
import androidx.compose.material3.Text
@ -33,7 +34,8 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import moe.lava.neon.resources.Res
import moe.lava.neon.resources.arrow_drop_down
@ -43,6 +45,7 @@ import moe.lava.neon.resources.volume_up
import org.jetbrains.compose.resources.painterResource
data class ChannelBrowserModel(
val guildPosition: GuildPosition,
val guildName: String,
val channels: List<Category>,
) {
@ -58,6 +61,10 @@ data class ChannelBrowserModel(
Text,
Voice
}
enum class GuildPosition {
LeftSidebar,
BottomSheet
}
}
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@ -155,93 +162,110 @@ fun ChannelBrowser(
}
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@PreviewScreenSizes
@Preview
@Composable
internal fun ChannelBrowserPreview() {
MaterialExpressiveTheme {
ChannelBrowser(
ChannelBrowserModel(
guildName = "My Awesome Guild",
internal fun ChannelBrowserPreview(
@PreviewParameter(ChannelBrowserPreviewProvider::class) model: ChannelBrowserModel
) {
MaterialExpressiveTheme(
// This will break live previews
// colorScheme = getColorScheme(),
motionScheme = MotionScheme.expressive(),
) {
ChannelBrowser(model)
}
}
internal class ChannelBrowserPreviewProvider : PreviewParameterProvider<ChannelBrowserModel> {
private val base = ChannelBrowserModel(
guildPosition = ChannelBrowserModel.GuildPosition.BottomSheet,
guildName = "My Awesome Guild",
channels = listOf(
ChannelBrowserModel.Category(
name = "Text Channels",
channels = listOf(
ChannelBrowserModel.Category(
name = "Text Channels",
channels = listOf(
ChannelBrowserModel.Channel(
"general",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"random",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"music-discussion",
ChannelBrowserModel.ChannelType.Text
)
)
ChannelBrowserModel.Channel(
"general",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Category(
name = "Voice Channels",
channels = listOf(
ChannelBrowserModel.Channel(
"General",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"Gaming",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"dev-voice",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"chill",
ChannelBrowserModel.ChannelType.Voice
)
)
ChannelBrowserModel.Channel(
"random",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Category(
name = "Development",
channels = listOf(
ChannelBrowserModel.Channel(
"neon",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"compose",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"dev-voice-chat",
ChannelBrowserModel.ChannelType.Voice
)
)
ChannelBrowserModel.Channel(
"music-discussion",
ChannelBrowserModel.ChannelType.Text
)
)
),
ChannelBrowserModel.Category(
name = "Voice Channels",
channels = listOf(
ChannelBrowserModel.Channel(
"General",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Category(
name = "Off-topic",
channels = listOf(
ChannelBrowserModel.Channel(
"memes",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"music",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"anime",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"gaming-chat",
ChannelBrowserModel.ChannelType.Text
)
)
ChannelBrowserModel.Channel(
"Gaming",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"dev-voice",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"chill",
ChannelBrowserModel.ChannelType.Voice
)
)
),
ChannelBrowserModel.Category(
name = "Development",
channels = listOf(
ChannelBrowserModel.Channel(
"neon",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"compose",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"dev-voice-chat",
ChannelBrowserModel.ChannelType.Voice
)
)
),
ChannelBrowserModel.Category(
name = "Off-topic",
channels = listOf(
ChannelBrowserModel.Channel(
"memes",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"music",
ChannelBrowserModel.ChannelType.Voice
),
ChannelBrowserModel.Channel(
"anime",
ChannelBrowserModel.ChannelType.Text
),
ChannelBrowserModel.Channel(
"gaming-chat",
ChannelBrowserModel.ChannelType.Text
)
)
)
)
}
)
private val models = listOf(
base.copy(guildPosition = ChannelBrowserModel.GuildPosition.BottomSheet),
base.copy(guildPosition = ChannelBrowserModel.GuildPosition.LeftSidebar),
)
override val values: Sequence<ChannelBrowserModel> = models.asSequence()
override fun getDisplayName(index: Int): String =
models[index].guildPosition.toString()
}