basic home screen
This commit is contained in:
@@ -1,7 +1,12 @@
|
|||||||
package su.reya.coop
|
package su.reya.coop
|
||||||
|
|
||||||
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
import androidx.compose.material3.MaterialExpressiveTheme
|
import androidx.compose.material3.MaterialExpressiveTheme
|
||||||
|
import androidx.compose.material3.darkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
|
import androidx.compose.material3.dynamicLightColorScheme
|
||||||
|
import androidx.compose.material3.lightColorScheme
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
@@ -29,11 +34,23 @@ fun App(dbPath: String) {
|
|||||||
val secretStore = remember { SecretStore(context) }
|
val secretStore = remember { SecretStore(context) }
|
||||||
val viewModel: NostrViewModel = viewModel { NostrViewModel(nostr, secretStore) }
|
val viewModel: NostrViewModel = viewModel { NostrViewModel(nostr, secretStore) }
|
||||||
|
|
||||||
|
val darkMode = isSystemInDarkTheme()
|
||||||
|
val colorScheme = when {
|
||||||
|
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S -> {
|
||||||
|
if (darkMode) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
darkMode -> darkColorScheme()
|
||||||
|
else -> lightColorScheme()
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
viewModel.initAndConnect(dbPath)
|
viewModel.initAndConnect(dbPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialExpressiveTheme {
|
MaterialExpressiveTheme(
|
||||||
|
colorScheme = colorScheme,
|
||||||
|
) {
|
||||||
rememberCoroutineScope()
|
rememberCoroutineScope()
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
val hasSecret by viewModel.hasSecret.collectAsState(initial = null)
|
val hasSecret by viewModel.hasSecret.collectAsState(initial = null)
|
||||||
@@ -65,7 +82,14 @@ fun App(dbPath: String) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
composable<Screen.Import> { backStackEntry ->
|
composable<Screen.Import> { backStackEntry ->
|
||||||
ImportScreen()
|
val isCreating by viewModel.isCreating.collectAsState()
|
||||||
|
|
||||||
|
ImportScreen(
|
||||||
|
isLoading = isCreating,
|
||||||
|
onSave = { secret ->
|
||||||
|
viewModel.import(secret)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
composable<Screen.NewIdentity> { backStackEntry ->
|
composable<Screen.NewIdentity> { backStackEntry ->
|
||||||
val isCreating by viewModel.isCreating.collectAsState()
|
val isCreating by viewModel.isCreating.collectAsState()
|
||||||
|
|||||||
@@ -1,26 +1,73 @@
|
|||||||
package su.reya.coop.screens
|
package su.reya.coop.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.text.input.rememberTextFieldState
|
||||||
|
import androidx.compose.material3.AppBarWithSearch
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.SearchBarDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.rememberSearchBarState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(onOpenChat: (String) -> Unit) {
|
fun HomeScreen(onOpenChat: (String) -> Unit) {
|
||||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
val scope = rememberCoroutineScope()
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
val searchState = rememberSearchBarState()
|
||||||
Text("Home Screen")
|
val textState = rememberTextFieldState()
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
|
||||||
Button(onClick = { onOpenChat("123") }) {
|
val scrollBehavior = SearchBarDefaults.enterAlwaysSearchBarScrollBehavior()
|
||||||
Text("Open Chat 123")
|
|
||||||
}
|
val inputField =
|
||||||
|
@Composable {
|
||||||
|
SearchBarDefaults.InputField(
|
||||||
|
textFieldState = textState,
|
||||||
|
searchBarState = searchState,
|
||||||
|
onSearch = { scope.launch { searchState.animateToCollapsed() } },
|
||||||
|
placeholder = {
|
||||||
|
Text(modifier = Modifier.clearAndSetSemantics() {}, text = "Search")
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
Scaffold(
|
||||||
|
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
|
topBar = {
|
||||||
|
AppBarWithSearch(
|
||||||
|
state = searchState,
|
||||||
|
inputField = inputField,
|
||||||
|
scrollBehavior = scrollBehavior,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
content = { innerPadding ->
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(innerPadding),
|
||||||
|
) {
|
||||||
|
items(count = 100) { index ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(50.dp)
|
||||||
|
) {
|
||||||
|
Text("Chat $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,63 @@
|
|||||||
package su.reya.coop.screens
|
package su.reya.coop.screens
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||||
|
import androidx.compose.material3.LoadingIndicator
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
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.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.unit.dp
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun ImportScreen() {
|
fun ImportScreen(
|
||||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
isLoading: Boolean,
|
||||||
Text("Import Screen")
|
onSave: (secret: String) -> Unit
|
||||||
|
) {
|
||||||
|
var secret by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = secret,
|
||||||
|
onValueChange = { secret = it },
|
||||||
|
label = { Text("Enter nsec or bunker") },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
singleLine = true,
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
onSave(secret)
|
||||||
|
},
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
enabled = secret.isNotBlank() && !isLoading,
|
||||||
|
) {
|
||||||
|
if (isLoading) {
|
||||||
|
LoadingIndicator()
|
||||||
|
} else {
|
||||||
|
Text("Save & Continue")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,23 +56,23 @@ class Nostr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
suspend fun connect() {
|
suspend fun connect() {
|
||||||
client?.addRelay(
|
try {
|
||||||
url = RelayUrl.parse("wss://relay.damus.io"),
|
client?.addRelay(
|
||||||
capabilities = RelayCapabilities.none()
|
url = RelayUrl.parse("wss://relay.primal.net"),
|
||||||
)
|
capabilities = RelayCapabilities.none()
|
||||||
client?.addRelay(
|
)
|
||||||
url = RelayUrl.parse("wss://relay.primal.net"),
|
client?.addRelay(
|
||||||
capabilities = RelayCapabilities.none()
|
url = RelayUrl.parse("wss://user.kindpag.es"),
|
||||||
)
|
capabilities = RelayCapabilities.none()
|
||||||
client?.addRelay(
|
)
|
||||||
url = RelayUrl.parse("wss://user.kindpag.es"),
|
client?.addRelay(
|
||||||
capabilities = RelayCapabilities.none()
|
url = RelayUrl.parse("wss://indexer.coracle.social"),
|
||||||
)
|
capabilities = RelayCapabilities.gossip()
|
||||||
client?.addRelay(
|
)
|
||||||
url = RelayUrl.parse("https://indexer.coracle.social"),
|
client?.connect()
|
||||||
capabilities = RelayCapabilities.gossip()
|
} catch (e: Exception) {
|
||||||
)
|
println("Failed to connect to relays: ${e.message}")
|
||||||
client?.connect()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun disconnect() {
|
suspend fun disconnect() {
|
||||||
|
|||||||
@@ -119,6 +119,10 @@ class NostrViewModel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun import(secret: String) {
|
||||||
|
// TODO: Implement import
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
super.onCleared()
|
super.onCleared()
|
||||||
// Ensure all relays are disconnect
|
// Ensure all relays are disconnect
|
||||||
|
|||||||
Reference in New Issue
Block a user