.
This commit is contained in:
@@ -39,14 +39,12 @@ import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.toRoute
|
||||
import kotlinx.coroutines.launch
|
||||
import su.reya.coop.coop.storage.SecretStore
|
||||
import su.reya.coop.screens.ChatScreen
|
||||
import su.reya.coop.screens.HomeScreen
|
||||
import su.reya.coop.screens.ImportScreen
|
||||
@@ -72,7 +70,10 @@ val LocalNavController = staticCompositionLocalOf<NavController> {
|
||||
|
||||
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun App(openRoomId: Long? = null) {
|
||||
fun App(
|
||||
viewModel: NostrViewModel,
|
||||
openRoomId: Long? = null
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val navController = rememberNavController()
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -81,10 +82,6 @@ fun App(openRoomId: Long? = null) {
|
||||
// Snackbar
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
|
||||
// Initialize Nostr View Model and Secret Store
|
||||
val secretStore = remember { SecretStore(context) }
|
||||
val viewModel: NostrViewModel = viewModel { NostrViewModel(NostrManager.instance, secretStore) }
|
||||
|
||||
// Enabled the dynamic color scheme
|
||||
val colorScheme = when {
|
||||
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S -> {
|
||||
@@ -101,12 +98,6 @@ fun App(openRoomId: Long? = null) {
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(openRoomId) {
|
||||
if (openRoomId != null) {
|
||||
navController.navigate(Screen.Chat(openRoomId))
|
||||
}
|
||||
}
|
||||
|
||||
MaterialExpressiveTheme(
|
||||
colorScheme = colorScheme,
|
||||
typography = Typography(),
|
||||
@@ -123,15 +114,20 @@ fun App(openRoomId: Long? = null) {
|
||||
|
||||
LaunchedEffect(emptySecret) {
|
||||
// Navigate to the home screen if the secret is already set
|
||||
if (emptySecret == false) {
|
||||
if (emptySecret == false && openRoomId == null) {
|
||||
navController.navigate(Screen.Home) {
|
||||
popUpTo(Screen.Onboarding) { inclusive = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show loading screen while initializing
|
||||
if (emptySecret == null) return@CompositionLocalProvider
|
||||
LaunchedEffect(openRoomId) {
|
||||
if (openRoomId != null) {
|
||||
navController.navigate(Screen.Chat(openRoomId)) {
|
||||
popUpTo(Screen.Home) { saveState = true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show the relay setup dialog if the msg relay list is empty
|
||||
if (isRelayListEmpty) {
|
||||
|
||||
@@ -7,26 +7,40 @@ import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import su.reya.coop.coop.storage.SecretStore
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
installSplashScreen()
|
||||
val splashScreen = installSplashScreen()
|
||||
enableEdgeToEdge()
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val intent = Intent(this, NostrForegroundService::class.java)
|
||||
|
||||
val serviceIntent = Intent(this, NostrForegroundService::class.java)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
startForegroundService(intent)
|
||||
startForegroundService(serviceIntent)
|
||||
} else {
|
||||
startService(intent)
|
||||
startService(serviceIntent)
|
||||
}
|
||||
|
||||
val roomId = intent.getLongExtra("room_id", -1L)
|
||||
val secretStore = SecretStore(this)
|
||||
val viewModel = NostrViewModel(NostrManager.instance, secretStore)
|
||||
|
||||
splashScreen.setKeepOnScreenCondition {
|
||||
viewModel.emptySecret.value == null
|
||||
}
|
||||
|
||||
setContent {
|
||||
App(openRoomId = if (roomId != -1L) roomId else null)
|
||||
App(
|
||||
viewModel = viewModel,
|
||||
openRoomId = if (roomId != -1L) roomId else null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
setIntent(intent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ import io.ktor.client.plugins.websocket.WebSockets
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.supervisorScope
|
||||
import rust.nostr.sdk.AckPolicy
|
||||
import rust.nostr.sdk.Alphabet
|
||||
import rust.nostr.sdk.AsyncNostrSigner
|
||||
@@ -170,8 +170,6 @@ class Nostr {
|
||||
suspend fun setSigner(new: AsyncNostrSigner) {
|
||||
try {
|
||||
signer.switch(new)
|
||||
// Fetch metadata for current user
|
||||
getUserMetadata()
|
||||
} catch (e: Exception) {
|
||||
throw IllegalStateException("Failed to set signer: ${e.message}", e)
|
||||
}
|
||||
@@ -244,10 +242,10 @@ class Nostr {
|
||||
onContactListUpdate: (List<PublicKey>) -> Unit,
|
||||
onNewMessage: (UnsignedEvent) -> Unit,
|
||||
onSubscriptionClose: () -> Unit,
|
||||
) = coroutineScope {
|
||||
) = supervisorScope {
|
||||
val now = Timestamp.now()
|
||||
val processedEvent = mutableSetOf<EventId>()
|
||||
val notifications = client?.notifications() ?: return@coroutineScope
|
||||
val notifications = client?.notifications() ?: return@supervisorScope
|
||||
|
||||
var eoseTrackerJob: Job? = null
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class NostrViewModel(
|
||||
|
||||
// Observe new events from the Nostr client
|
||||
runObserver()
|
||||
|
||||
|
||||
// Wait and merge metadata requests into a single batch
|
||||
runMetadataBatching()
|
||||
}
|
||||
@@ -201,9 +201,6 @@ class NostrViewModel(
|
||||
|
||||
private fun login() {
|
||||
viewModelScope.launch {
|
||||
// Wait until the client is ready
|
||||
nostr.waitUntilInitialized()
|
||||
|
||||
// Get user's signer secret
|
||||
val secret = secretStore.get("user_signer")
|
||||
|
||||
@@ -249,6 +246,9 @@ class NostrViewModel(
|
||||
_isPartialProcessedGiftWrap.value = true
|
||||
}
|
||||
|
||||
// Get all metadata for the current user
|
||||
nostr.getUserMetadata()
|
||||
|
||||
// Small delay to ensure all relays are connected
|
||||
delay(3000)
|
||||
|
||||
@@ -261,7 +261,7 @@ class NostrViewModel(
|
||||
break
|
||||
}
|
||||
|
||||
delay(1000)
|
||||
delay(500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user