unify error handler
This commit is contained in:
@@ -52,6 +52,10 @@ val LocalNostrViewModel = staticCompositionLocalOf<NostrViewModel> {
|
||||
error("No NostrViewModel provided")
|
||||
}
|
||||
|
||||
val LocalAuthViewModel = staticCompositionLocalOf<AuthViewModel> {
|
||||
error("No AuthViewModel provided")
|
||||
}
|
||||
|
||||
val LocalSnackbarHostState = staticCompositionLocalOf<SnackbarHostState> {
|
||||
error("No SnackbarHostState provided")
|
||||
}
|
||||
@@ -68,6 +72,7 @@ val LocalScanResult = staticCompositionLocalOf<QrScanResult> {
|
||||
@Composable
|
||||
fun App(
|
||||
nostrViewModel: NostrViewModel,
|
||||
authViewModel: AuthViewModel,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val activity = context as? ComponentActivity
|
||||
@@ -76,7 +81,8 @@ fun App(
|
||||
val qrScanResult = remember { QrScanResult() }
|
||||
|
||||
// Get the signer required state
|
||||
val signerRequired by nostrViewModel.signerRequired.collectAsStateWithLifecycle()
|
||||
val authState by authViewModel.state.collectAsStateWithLifecycle()
|
||||
val signerRequired = authState.signerRequired
|
||||
|
||||
// Snackbar
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
@@ -103,7 +109,7 @@ fun App(
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
nostrViewModel.errorEvents.collect { message ->
|
||||
ErrorManager.errors.collect { message ->
|
||||
snackbarHostState.showSnackbar(message)
|
||||
}
|
||||
}
|
||||
@@ -147,6 +153,7 @@ fun App(
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalNostrViewModel provides nostrViewModel,
|
||||
LocalAuthViewModel provides authViewModel,
|
||||
LocalSnackbarHostState provides snackbarHostState,
|
||||
LocalNavigator provides navigator,
|
||||
LocalScanResult provides qrScanResult,
|
||||
|
||||
@@ -27,11 +27,14 @@ class MainActivity : ComponentActivity() {
|
||||
AndroidExternalSigner(this@MainActivity, externalSignerLauncher)
|
||||
private val secretStore = SecretStore(this@MainActivity)
|
||||
private val nostrViewModel =
|
||||
NostrViewModel(NostrManager.instance, secretStore, androidSigner)
|
||||
NostrViewModel(NostrManager.instance)
|
||||
private val authViewModel =
|
||||
AuthViewModel(NostrManager.instance, secretStore, androidSigner)
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return when {
|
||||
modelClass.isAssignableFrom(NostrViewModel::class.java) -> nostrViewModel
|
||||
modelClass.isAssignableFrom(AuthViewModel::class.java) -> authViewModel
|
||||
else -> throw IllegalArgumentException("Unknown ViewModel class")
|
||||
} as T
|
||||
}
|
||||
@@ -39,6 +42,7 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
private val nostrViewModel: NostrViewModel by viewModels { factory }
|
||||
private val authViewModel: AuthViewModel by viewModels { factory }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
|
||||
@@ -77,12 +81,13 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
// Keep the splash screen visible until the signer check is complete
|
||||
splashScreen.setKeepOnScreenCondition {
|
||||
nostrViewModel.signerRequired.value == null
|
||||
authViewModel.state.value.signerRequired == null
|
||||
}
|
||||
|
||||
setContent {
|
||||
App(
|
||||
nostrViewModel = nostrViewModel,
|
||||
authViewModel = authViewModel,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ import coop.composeapp.generated.resources.ic_scanner
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import rust.nostr.sdk.PublicKey
|
||||
import su.reya.coop.LocalAuthViewModel
|
||||
import su.reya.coop.LocalNavigator
|
||||
import su.reya.coop.LocalNostrViewModel
|
||||
import su.reya.coop.LocalScanResult
|
||||
@@ -111,6 +112,7 @@ fun HomeScreen() {
|
||||
val snackbarHostState = LocalSnackbarHostState.current
|
||||
val clipboardManager = LocalClipboard.current
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
val sheetState = rememberModalBottomSheetState(true)
|
||||
@@ -123,7 +125,9 @@ fun HomeScreen() {
|
||||
val isRelayListEmpty by nostrViewModel.isRelayListEmpty.collectAsStateWithLifecycle()
|
||||
val isSyncing by nostrViewModel.isSyncing.collectAsStateWithLifecycle()
|
||||
val isPartialProcessedGiftWrap by nostrViewModel.isPartialProcessedGiftWrap.collectAsStateWithLifecycle()
|
||||
val isBannerDismissed by nostrViewModel.isNotificationBannerDismissed.collectAsState()
|
||||
|
||||
val authState by authViewModel.state.collectAsStateWithLifecycle()
|
||||
val isBannerDismissed = authState.isNotificationBannerDismissed
|
||||
|
||||
val expandedFab by remember { derivedStateOf { listState.firstVisibleItemIndex == 0 } }
|
||||
var showBottomSheet by remember { mutableStateOf(false) }
|
||||
@@ -275,7 +279,7 @@ fun HomeScreen() {
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
TextButton(
|
||||
onClick = { nostrViewModel.dismissNotificationBanner() },
|
||||
onClick = { authViewModel.dismissNotificationBanner() },
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text(text = "Maybe later")
|
||||
@@ -615,6 +619,7 @@ fun HomeScreen() {
|
||||
fun NewRequests(requests: List<Room>) {
|
||||
val navigator = LocalNavigator.current
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
|
||||
val total = requests.size
|
||||
val firstRoom = requests.getOrNull(0)
|
||||
@@ -693,6 +698,7 @@ fun NewRequests(requests: List<Room>) {
|
||||
@Composable
|
||||
fun ChatRoom(room: Room, onClick: () -> Unit) {
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
val roomState by room.rememberUiState(nostrViewModel)
|
||||
|
||||
ListItem(
|
||||
@@ -740,6 +746,7 @@ fun BottomMenuList(
|
||||
) {
|
||||
val navigator = LocalNavigator.current
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
|
||||
val defaultMenuList = listOf(
|
||||
"Update Profile" to { navigator.navigate(Screen.UpdateProfile) },
|
||||
@@ -769,7 +776,7 @@ fun BottomMenuList(
|
||||
}
|
||||
Spacer(modifier = Modifier.size(16.dp))
|
||||
FilledTonalButton(
|
||||
onClick = { onDismiss { nostrViewModel.logout() } },
|
||||
onClick = { onDismiss { authViewModel.logout(onLogout = nostrViewModel::resetInternalState) } },
|
||||
colors = ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = MaterialTheme.colorScheme.error,
|
||||
contentColor = MaterialTheme.colorScheme.onError
|
||||
|
||||
@@ -58,6 +58,7 @@ import org.jetbrains.compose.resources.painterResource
|
||||
import rust.nostr.sdk.Keys
|
||||
import rust.nostr.sdk.NostrConnectUri
|
||||
import rust.nostr.sdk.PublicKey
|
||||
import su.reya.coop.LocalAuthViewModel
|
||||
import su.reya.coop.LocalNavigator
|
||||
import su.reya.coop.LocalNostrViewModel
|
||||
import su.reya.coop.LocalScanResult
|
||||
@@ -74,10 +75,12 @@ fun ImportScreen() {
|
||||
val qrScanResult = LocalScanResult.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val isBusy by nostrViewModel.isBusy.collectAsStateWithLifecycle(false)
|
||||
val authState by authViewModel.state.collectAsStateWithLifecycle()
|
||||
val isBusy = authState.isBusy
|
||||
var secret by remember { mutableStateOf("") }
|
||||
var pubkey by remember { mutableStateOf<PublicKey?>(null) }
|
||||
|
||||
@@ -240,10 +243,10 @@ fun ImportScreen() {
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (pubkey == null) {
|
||||
nostrViewModel.verifyIdentity(secret).let { pubkey = it }
|
||||
authViewModel.verifyIdentity(secret).let { pubkey = it }
|
||||
} else {
|
||||
// Import the identity
|
||||
nostrViewModel.importIdentity(secret)
|
||||
authViewModel.importIdentity(secret)
|
||||
// Navigate to the home screen
|
||||
navigator.navigate(Screen.Home)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import kotlinx.coroutines.launch
|
||||
import su.reya.coop.LocalAuthViewModel
|
||||
import su.reya.coop.LocalNavigator
|
||||
import su.reya.coop.LocalNostrViewModel
|
||||
import su.reya.coop.Screen
|
||||
@@ -13,9 +14,12 @@ import su.reya.coop.shared.ProfileEditor
|
||||
@Composable
|
||||
fun NewIdentityScreen() {
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
val navigator = LocalNavigator.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val isBusy by nostrViewModel.isBusy.collectAsStateWithLifecycle(false)
|
||||
|
||||
val authState by authViewModel.state.collectAsStateWithLifecycle()
|
||||
val isBusy = authState.isBusy
|
||||
|
||||
ProfileEditor(
|
||||
title = "Create a new identity",
|
||||
@@ -24,7 +28,7 @@ fun NewIdentityScreen() {
|
||||
onBack = { navigator.goBack() },
|
||||
onConfirm = { name, bio, bytes, type ->
|
||||
scope.launch {
|
||||
nostrViewModel.createIdentity(name, bio, bytes, type)
|
||||
authViewModel.createIdentity(name, bio, bytes, type)
|
||||
navigator.navigate(Screen.Home)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import coop.composeapp.generated.resources.Res
|
||||
import coop.composeapp.generated.resources.coop
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import su.reya.coop.LocalAuthViewModel
|
||||
import su.reya.coop.LocalNavigator
|
||||
import su.reya.coop.LocalNostrViewModel
|
||||
import su.reya.coop.LocalSnackbarHostState
|
||||
@@ -58,6 +59,7 @@ fun OnboardingScreen() {
|
||||
val snackbarHostState = LocalSnackbarHostState.current
|
||||
val navigator = LocalNavigator.current
|
||||
val nostrViewModel = LocalNostrViewModel.current
|
||||
val authViewModel = LocalAuthViewModel.current
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
val logoPainter = painterResource(Res.drawable.coop)
|
||||
@@ -158,9 +160,9 @@ fun OnboardingScreen() {
|
||||
FilledTonalButton(
|
||||
onClick = {
|
||||
scope.launch {
|
||||
if (nostrViewModel.isExternalSignerAvailable()) {
|
||||
if (authViewModel.isExternalSignerAvailable()) {
|
||||
try {
|
||||
nostrViewModel.connectExternalSigner()
|
||||
authViewModel.connectExternalSigner()
|
||||
navigator.navigate(Screen.Home)
|
||||
} catch (e: Exception) {
|
||||
e.message?.let { snackbarHostState.showSnackbar(it) }
|
||||
|
||||
Reference in New Issue
Block a user