feat: screener for message requests #24

Merged
reya merged 6 commits from feat/screening into master 2026-06-19 09:06:50 +00:00
4 changed files with 32 additions and 12 deletions
Showing only changes of commit e13f72d03d - Show all commits

View File

@@ -184,7 +184,7 @@ fun App(viewModel: NostrViewModel) {
NewChatScreen() NewChatScreen()
} }
entry<Screen.Profile> { key -> entry<Screen.Profile> { key ->
ProfileScreen(pubkey = key.pubkey) ProfileScreen(pubkey = key.pubkey, screening = key.screening)
} }
entry<Screen.UpdateProfile> { entry<Screen.UpdateProfile> {
UpdateProfileScreen() UpdateProfileScreen()

View File

@@ -30,7 +30,7 @@ sealed interface Screen : NavKey {
data class Chat(val id: Long) : Screen data class Chat(val id: Long) : Screen
@Serializable @Serializable
data class Profile(val pubkey: String) : Screen data class Profile(val pubkey: String, val screening: Boolean = false) : Screen
@Serializable @Serializable
data object ContactList : Screen data object ContactList : Screen

View File

@@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.height
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.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
@@ -23,7 +24,6 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.SegmentedListItem import androidx.compose.material3.SegmentedListItem
import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.toShape import androidx.compose.material3.toShape
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -54,27 +54,28 @@ import su.reya.coop.short
@OptIn(ExperimentalMaterial3ExpressiveApi::class) @OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable @Composable
fun ProfileScreen(pubkey: String) { fun ProfileScreen(pubkey: String, screening: Boolean = false) {
val pubkey = runCatching { PublicKey.parse(pubkey) }.getOrNull() ?: return
val context = LocalContext.current val context = LocalContext.current
val snackbarHostState = LocalSnackbarHostState.current val snackbarHostState = LocalSnackbarHostState.current
val navigator = LocalNavigator.current val navigator = LocalNavigator.current
val viewModel = LocalNostrViewModel.current val viewModel = LocalNostrViewModel.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val pubkey = runCatching { PublicKey.parse(pubkey) }.getOrNull() ?: return
val metadataFlow = remember(pubkey) { viewModel.getMetadata(pubkey) } val metadataFlow = remember(pubkey) { viewModel.getMetadata(pubkey) }
val metadata by metadataFlow.collectAsState(initial = null) val metadata by metadataFlow.collectAsState(initial = null)
val profile = metadata?.asRecord() val profile = metadata?.asRecord()
val displayName = profile?.displayName ?: profile?.name ?: "No name" val displayName = profile?.displayName ?: profile?.name ?: "No name"
val nip05 = profile?.nip05 ?: pubkey.short() val nip05 = profile?.nip05 ?: pubkey.short()
val picture = profile?.picture val picture = profile?.picture
val details = remember(profile) { val details = remember(profile) {
listOf( listOf(
"Username:" to (profile?.name ?: "None"), "Username:" to (profile?.name ?: "None"),
"Website:" to (profile?.website ?: "None"), "Website:" to (profile?.website ?: "None"),
"Lightning Address:" to (profile?.lud16 ?: "None"), "Lightning Address:" to (profile?.lud16 ?: "None"),
) )
} }
@@ -82,8 +83,15 @@ fun ProfileScreen(pubkey: String) {
containerColor = MaterialTheme.colorScheme.surfaceContainer, containerColor = MaterialTheme.colorScheme.surfaceContainer,
snackbarHost = { SnackbarHost(snackbarHostState) }, snackbarHost = { SnackbarHost(snackbarHostState) },
topBar = { topBar = {
TopAppBar( CenterAlignedTopAppBar(
title = { }, title = {
if (screening) {
Text(
text = "Screening",
style = MaterialTheme.typography.titleMediumEmphasized
)
}
},
navigationIcon = { navigationIcon = {
IconButton(onClick = { navigator.goBack() }) { IconButton(onClick = { navigator.goBack() }) {
Icon( Icon(
@@ -233,6 +241,15 @@ fun ProfileScreen(pubkey: String) {
) )
} }
} }
if (screening) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(ListItemDefaults.SegmentedGap),
) {
// TODO
}
}
} }
} }
} }

View File

@@ -71,7 +71,10 @@ fun RequestListScreen() {
containerColor = MaterialTheme.colorScheme.surfaceContainer, containerColor = MaterialTheme.colorScheme.surfaceContainer,
), ),
title = { title = {
Text("New Requests", style = MaterialTheme.typography.titleMediumEmphasized) Text(
text = "New Requests",
style = MaterialTheme.typography.titleMediumEmphasized
)
}, },
navigationIcon = { navigationIcon = {
IconButton(onClick = { navigator.goBack() }) { IconButton(onClick = { navigator.goBack() }) {