mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-06 03:18:23 +00:00
Decouple error message display from AccountStateViewModel
Extract toast/error infrastructure into a standalone ToastManager singleton so composables and background services no longer need to reference AccountStateViewModel just to show error dialogs. - Add ToastManager.kt with ToastMsg sealed class hierarchy and MutableSharedFlow - Remove toast methods and ToastMsg types from AccountStateViewModel - Update DisplayErrorMessages() to take no parameter and collect from ToastManager - Replace AmberListenerSingleton.accountStateViewModel field with direct ToastManager calls - Update Amber.kt and BunkerRequestUtils.kt to use ToastManager directly - Remove accountStateViewModel parameter from composables that only used it for toasts: NewApplicationScreen, ConfirmPinScreen, FeedbackScreen, IntentSingleEventHomeScreen, NewNsecBunkerScreen, EditConfigurationScreen, DefaultProfileRelaysScreen, EditRelaysDialog, IncomingRequestScreen, and update MainScreen callers accordingly https://claude.ai/code/session_01Jk3XjYxVsPZrT88aH6c6cP
This commit is contained in:
@@ -33,6 +33,7 @@ import com.greenart7c3.nostrsigner.service.NotificationSubscription
|
||||
import com.greenart7c3.nostrsigner.service.ProfileSubscription
|
||||
import com.greenart7c3.nostrsigner.service.crashreports.CrashReportCache
|
||||
import com.greenart7c3.nostrsigner.service.crashreports.UnexpectedCrashSaver
|
||||
import com.greenart7c3.nostrsigner.ui.ToastManager
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.NostrClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.sendAndWaitForResponse
|
||||
@@ -134,9 +135,9 @@ class Amber :
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
if (e.message?.contains("EACCES (Permission denied)") == true) {
|
||||
AmberListenerSingleton.accountStateViewModel?.toast(getString(R.string.warning), getString(R.string.network_permission_message))
|
||||
ToastManager.toast(getString(R.string.warning), getString(R.string.network_permission_message))
|
||||
} else if (e.message?.contains("socket failed: EPERM (Operation not permitted)") == true) {
|
||||
AmberListenerSingleton.accountStateViewModel?.toast(getString(R.string.warning), getString(R.string.network_permission_message))
|
||||
ToastManager.toast(getString(R.string.warning), getString(R.string.network_permission_message))
|
||||
}
|
||||
Log.e(TAG, "Failed to connect to proxy", e)
|
||||
return false
|
||||
|
||||
@@ -7,7 +7,7 @@ import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.database.LogEntity
|
||||
import com.greenart7c3.nostrsigner.service.NotificationUtils.sendErrorNotification
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.ToastManager
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.Message
|
||||
@@ -16,16 +16,14 @@ import com.vitorpamplona.quartz.nip01Core.relay.commands.toRelay.Command
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object AmberListenerSingleton {
|
||||
var accountStateViewModel: AccountStateViewModel? = null
|
||||
val latestErrorMessages = mutableListOf<String>()
|
||||
|
||||
fun showErrorMessage() {
|
||||
if (latestErrorMessages.isEmpty()) return
|
||||
if (latestErrorMessages.last().isBlank()) return
|
||||
if (Amber.isAppInForeground) {
|
||||
accountStateViewModel?.toast("Error", latestErrorMessages.last())
|
||||
ToastManager.toast("Error", latestErrorMessages.last())
|
||||
} else {
|
||||
val notificationManager: NotificationManager =
|
||||
Amber.instance.applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.relays.AmberListenerSingleton
|
||||
import com.greenart7c3.nostrsigner.service.model.AmberEvent
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.greenart7c3.nostrsigner.ui.ToastManager
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.jackson.JacksonMapper
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.accessories.sendAndWaitForResponse
|
||||
@@ -77,7 +78,7 @@ object BunkerRequestUtils {
|
||||
if (Amber.instance.settings.useProxy) {
|
||||
val isProxyWorking = Amber.instance.isSocksProxyAlive("127.0.0.1", Amber.instance.settings.proxyPort)
|
||||
if (!isProxyWorking) {
|
||||
AmberListenerSingleton.accountStateViewModel?.toast(context.getString(R.string.warning), context.getString(R.string.failed_to_connect_to_tor_orbot))
|
||||
ToastManager.toast(context.getString(R.string.warning), context.getString(R.string.failed_to_connect_to_tor_orbot))
|
||||
onDone(false)
|
||||
onLoading(false)
|
||||
return
|
||||
|
||||
@@ -36,7 +36,6 @@ import com.greenart7c3.nostrsigner.MainViewModel
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.IntentResultType
|
||||
import com.greenart7c3.nostrsigner.relays.AmberListenerSingleton
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
|
||||
@@ -89,9 +88,7 @@ fun AccountScreen(
|
||||
} ?: state.route,
|
||||
)
|
||||
|
||||
AmberListenerSingleton.accountStateViewModel = accountStateViewModel
|
||||
|
||||
DisplayErrorMessages(accountStateViewModel)
|
||||
DisplayErrorMessages()
|
||||
MainScreen(
|
||||
account = state.account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
@@ -121,8 +118,8 @@ fun AccountScreen(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
val openDialogMsg = accountViewModel.toasts.collectAsState(null)
|
||||
private fun DisplayErrorMessages() {
|
||||
val openDialogMsg = ToastManager.toasts.collectAsState(null)
|
||||
|
||||
openDialogMsg.value?.let { obj ->
|
||||
when (obj) {
|
||||
@@ -134,7 +131,7 @@ private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
title,
|
||||
content,
|
||||
) {
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
}
|
||||
} else {
|
||||
val title = stringResource(obj.titleResId)
|
||||
@@ -143,7 +140,7 @@ private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
title,
|
||||
content,
|
||||
) {
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +149,7 @@ private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
obj.title,
|
||||
obj.msg,
|
||||
) {
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
}
|
||||
is ConfirmationToastMsg ->
|
||||
InformationDialog(
|
||||
@@ -160,7 +157,7 @@ private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
obj.msg,
|
||||
) {
|
||||
obj.onOk()
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
}
|
||||
is AcceptRejectToastMsg ->
|
||||
InformationDialog(
|
||||
@@ -168,11 +165,11 @@ private fun DisplayErrorMessages(accountViewModel: AccountStateViewModel) {
|
||||
obj.msg,
|
||||
onAccept = {
|
||||
obj.onAccept()
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
},
|
||||
onReject = {
|
||||
obj.onReject()
|
||||
accountViewModel.clearToasts()
|
||||
ToastManager.clearToasts()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.LocalPreferences
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
@@ -18,71 +16,21 @@ import com.vitorpamplona.quartz.nip49PrivKeyEnc.Nip49
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Immutable
|
||||
open class ToastMsg
|
||||
|
||||
@Immutable
|
||||
class StringToastMsg(val title: String, val msg: String) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class ConfirmationToastMsg(val title: String, val msg: String, val onOk: () -> Unit) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class AcceptRejectToastMsg(val title: String, val msg: String, val onAccept: () -> Unit, val onReject: () -> Unit) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class ResourceToastMsg(
|
||||
val titleResId: Int,
|
||||
val resourceId: Int,
|
||||
val params: Array<out String>? = null,
|
||||
) : ToastMsg()
|
||||
|
||||
@Stable
|
||||
class AccountStateViewModel(npub: String?) : ViewModel() {
|
||||
private val _accountContent = MutableStateFlow<AccountState>(AccountState.LoggedOff)
|
||||
val accountContent = _accountContent.asStateFlow()
|
||||
val toasts = MutableSharedFlow<ToastMsg?>(0, 3, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
private var observerJob: Job? = null
|
||||
|
||||
init {
|
||||
tryLoginExistingAccount(null, npub)
|
||||
}
|
||||
|
||||
fun clearToasts() {
|
||||
viewModelScope.launch { toasts.emit(null) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
) {
|
||||
viewModelScope.launch { toasts.emit(StringToastMsg(title, message)) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
onOk: () -> Unit,
|
||||
) {
|
||||
viewModelScope.launch { toasts.emit(ConfirmationToastMsg(title, message, onOk)) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
onAccept: () -> Unit,
|
||||
onReject: () -> Unit,
|
||||
) {
|
||||
viewModelScope.launch { toasts.emit(AcceptRejectToastMsg(title, message, onAccept, onReject)) }
|
||||
}
|
||||
|
||||
private fun tryLoginExistingAccount(
|
||||
route: String?,
|
||||
npub: String?,
|
||||
|
||||
@@ -40,7 +40,6 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun DefaultProfileRelaysScreen(
|
||||
modifier: Modifier,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -116,7 +115,6 @@ fun DefaultProfileRelaysScreen(
|
||||
isLoading,
|
||||
relays2,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
shouldCheckForBunker = false,
|
||||
@@ -153,7 +151,6 @@ fun DefaultProfileRelaysScreen(
|
||||
isLoading,
|
||||
relays2,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
shouldCheckForBunker = false,
|
||||
|
||||
@@ -68,7 +68,6 @@ import kotlinx.coroutines.launch
|
||||
fun EditConfigurationScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
key: String,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
navController: NavController,
|
||||
) {
|
||||
@@ -188,7 +187,6 @@ fun EditConfigurationScreen(
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {},
|
||||
@@ -211,7 +209,6 @@ fun EditConfigurationScreen(
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {},
|
||||
|
||||
@@ -46,7 +46,6 @@ import kotlinx.coroutines.launch
|
||||
fun FeedbackScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
account: Account,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
onDismiss: () -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
@@ -152,14 +151,14 @@ fun FeedbackScreen(
|
||||
account,
|
||||
)
|
||||
if (result) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
Amber.instance.getString(R.string.warning),
|
||||
Amber.instance.getString(R.string.feedback_sent),
|
||||
)
|
||||
onLoading(false)
|
||||
onDismiss()
|
||||
} else {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
Amber.instance.getString(R.string.warning),
|
||||
Amber.instance.getString(R.string.failed_to_send_event),
|
||||
)
|
||||
|
||||
@@ -36,7 +36,6 @@ fun IncomingRequestScreen(
|
||||
packageName: String?,
|
||||
applicationName: String?,
|
||||
account: Account,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
navController: NavController,
|
||||
onRemoveIntentData: (List<IntentData>, IntentResultType) -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
@@ -70,7 +69,6 @@ fun IncomingRequestScreen(
|
||||
applicationName = applicationName,
|
||||
intentData = intents.first(),
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
onRemoveIntentData = onRemoveIntentData,
|
||||
onLoading = onLoading,
|
||||
)
|
||||
|
||||
@@ -381,7 +381,6 @@ fun MainScreen(
|
||||
packageName = packageName,
|
||||
applicationName = appName,
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
navController = navController,
|
||||
onRemoveIntentData = onRemoveIntentData,
|
||||
onLoading = {
|
||||
@@ -563,7 +562,6 @@ fun MainScreen(
|
||||
.padding(padding)
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -608,7 +606,6 @@ fun MainScreen(
|
||||
val scrollState = rememberScrollState()
|
||||
NewApplicationScreen(
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
navController = navController,
|
||||
modifier =
|
||||
Modifier
|
||||
@@ -628,7 +625,6 @@ fun MainScreen(
|
||||
val scrollState = rememberScrollState()
|
||||
NewNsecBunkerScreen(
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
navController = navController,
|
||||
modifier =
|
||||
Modifier
|
||||
@@ -746,7 +742,6 @@ fun MainScreen(
|
||||
.padding(top = verticalPadding * 1.5f)
|
||||
.imePadding(),
|
||||
key = key,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
account = account,
|
||||
navController = navController,
|
||||
)
|
||||
@@ -779,7 +774,6 @@ fun MainScreen(
|
||||
.padding(padding)
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
pin = pin,
|
||||
navController = navController,
|
||||
)
|
||||
@@ -832,7 +826,6 @@ fun MainScreen(
|
||||
.verticalScroll(scrollState)
|
||||
.padding(horizontal = verticalPadding)
|
||||
.padding(top = verticalPadding * 1.5f),
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
account = account,
|
||||
)
|
||||
},
|
||||
@@ -908,7 +901,6 @@ fun MainScreen(
|
||||
.padding(top = verticalPadding * 1.5f)
|
||||
.imePadding(),
|
||||
account = account,
|
||||
accountStateViewModel = accountStateViewModel,
|
||||
onDismiss = {
|
||||
Amber.instance.applicationIOScope.launch(Dispatchers.Main) {
|
||||
navController.navigateUp()
|
||||
|
||||
@@ -34,7 +34,6 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun NewApplicationScreen(
|
||||
modifier: Modifier,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
navController: NavController,
|
||||
) {
|
||||
@@ -49,7 +48,7 @@ fun NewApplicationScreen(
|
||||
dialogOpen.value = false
|
||||
|
||||
if (it.isNullOrBlank()) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
message,
|
||||
)
|
||||
@@ -57,7 +56,7 @@ fun NewApplicationScreen(
|
||||
}
|
||||
|
||||
if (!it.startsWith("nostrconnect://")) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
message,
|
||||
)
|
||||
@@ -90,7 +89,7 @@ fun NewApplicationScreen(
|
||||
scope.launch {
|
||||
val clipboardText = clipboardManager.getClipEntry()?.clipData?.getItemAt(0)
|
||||
if (clipboardText == null) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
message,
|
||||
)
|
||||
@@ -98,14 +97,14 @@ fun NewApplicationScreen(
|
||||
}
|
||||
|
||||
if (clipboardText.text.isBlank()) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
message,
|
||||
)
|
||||
return@launch
|
||||
}
|
||||
if (!clipboardText.text.startsWith("nostrconnect://")) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
message,
|
||||
)
|
||||
|
||||
@@ -63,7 +63,6 @@ import kotlinx.coroutines.launch
|
||||
fun NewNsecBunkerScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
account: Account,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
navController: NavController,
|
||||
) {
|
||||
val secret = remember { mutableStateOf(UUID.randomUUID().toString()) }
|
||||
@@ -163,7 +162,6 @@ fun NewNsecBunkerScreen(
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account = account,
|
||||
context,
|
||||
onDone = {
|
||||
@@ -187,7 +185,6 @@ fun NewNsecBunkerScreen(
|
||||
isLoading,
|
||||
relays,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account = account,
|
||||
context,
|
||||
onDone = {
|
||||
@@ -226,7 +223,7 @@ fun NewNsecBunkerScreen(
|
||||
text = stringResource(R.string.create),
|
||||
onClick = {
|
||||
if (relays.isEmpty()) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
noRelaysMessage,
|
||||
)
|
||||
@@ -235,7 +232,7 @@ fun NewNsecBunkerScreen(
|
||||
}
|
||||
|
||||
if (name.text.isBlank()) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title,
|
||||
noNameMessage,
|
||||
)
|
||||
|
||||
@@ -28,7 +28,6 @@ fun SetupPinScreen(
|
||||
@Composable
|
||||
fun ConfirmPinScreen(
|
||||
modifier: Modifier = Modifier,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
pin: String,
|
||||
navController: NavController,
|
||||
) {
|
||||
@@ -39,7 +38,7 @@ fun ConfirmPinScreen(
|
||||
RandomPinInput(
|
||||
onPinEntered = { enteredPin ->
|
||||
if (enteredPin != pin) {
|
||||
accountStateViewModel.toast(context.getString(R.string.pin), context.getString(R.string.pin_does_not_match))
|
||||
ToastManager.toast(context.getString(R.string.pin), context.getString(R.string.pin_does_not_match))
|
||||
} else {
|
||||
val usePin = Amber.instance.settings.usePin
|
||||
if (usePin) {
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.greenart7c3.nostrsigner.ui
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Immutable
|
||||
open class ToastMsg
|
||||
|
||||
@Immutable
|
||||
class StringToastMsg(val title: String, val msg: String) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class ConfirmationToastMsg(val title: String, val msg: String, val onOk: () -> Unit) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class AcceptRejectToastMsg(
|
||||
val title: String,
|
||||
val msg: String,
|
||||
val onAccept: () -> Unit,
|
||||
val onReject: () -> Unit,
|
||||
) : ToastMsg()
|
||||
|
||||
@Immutable
|
||||
class ResourceToastMsg(
|
||||
val titleResId: Int,
|
||||
val resourceId: Int,
|
||||
val params: Array<out String>? = null,
|
||||
) : ToastMsg()
|
||||
|
||||
object ToastManager {
|
||||
val toasts = MutableSharedFlow<ToastMsg?>(0, 3, onBufferOverflow = BufferOverflow.DROP_OLDEST)
|
||||
|
||||
fun clearToasts() {
|
||||
Amber.instance.applicationIOScope.launch { toasts.emit(null) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
) {
|
||||
Amber.instance.applicationIOScope.launch { toasts.emit(StringToastMsg(title, message)) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
onOk: () -> Unit,
|
||||
) {
|
||||
Amber.instance.applicationIOScope.launch { toasts.emit(ConfirmationToastMsg(title, message, onOk)) }
|
||||
}
|
||||
|
||||
fun toast(
|
||||
title: String,
|
||||
message: String,
|
||||
onAccept: () -> Unit,
|
||||
onReject: () -> Unit,
|
||||
) {
|
||||
Amber.instance.applicationIOScope.launch { toasts.emit(AcceptRejectToastMsg(title, message, onAccept, onReject)) }
|
||||
}
|
||||
}
|
||||
@@ -57,8 +57,8 @@ import com.greenart7c3.nostrsigner.models.TimeUtils.formatLongToCustomDateTimeWi
|
||||
import com.greenart7c3.nostrsigner.models.defaultAppRelays
|
||||
import com.greenart7c3.nostrsigner.relays.AmberListenerSingleton
|
||||
import com.greenart7c3.nostrsigner.service.TrustScoreService
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.CenterCircularProgressIndicator
|
||||
import com.greenart7c3.nostrsigner.ui.ToastManager
|
||||
import com.greenart7c3.nostrsigner.ui.RelayCard
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberButton
|
||||
import com.greenart7c3.nostrsigner.ui.components.TrustScoreBadge
|
||||
@@ -92,7 +92,6 @@ import kotlinx.coroutines.withTimeoutOrNull
|
||||
@Composable
|
||||
fun DefaultRelaysScreen(
|
||||
modifier: Modifier,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
) {
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -187,7 +186,6 @@ fun DefaultRelaysScreen(
|
||||
isLoading,
|
||||
relays2,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {
|
||||
@@ -223,7 +221,6 @@ fun DefaultRelaysScreen(
|
||||
isLoading,
|
||||
relays2,
|
||||
scope,
|
||||
accountStateViewModel,
|
||||
account,
|
||||
context,
|
||||
onDone = {
|
||||
@@ -288,7 +285,6 @@ fun onAddRelay(
|
||||
isLoading: MutableState<Boolean>,
|
||||
relays2: SnapshotStateList<NormalizedRelayUrl>,
|
||||
scope: CoroutineScope,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
account: Account,
|
||||
context: Context,
|
||||
shouldCheckForBunker: Boolean = true,
|
||||
@@ -373,7 +369,7 @@ fun onAddRelay(
|
||||
}
|
||||
|
||||
override fun onCannotConnect(relay: IRelayClient, errorMessage: String) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
context.getString(R.string.relay),
|
||||
context.getString(R.string.could_not_connect_to_relay),
|
||||
onAccept = {
|
||||
@@ -419,7 +415,7 @@ fun onAddRelay(
|
||||
}
|
||||
|
||||
if (canContinue == null) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
context.getString(R.string.relay),
|
||||
context.getString(R.string.could_not_connect_to_relay),
|
||||
onAccept = {
|
||||
@@ -472,7 +468,7 @@ fun onAddRelay(
|
||||
relays2.add(addedWSS)
|
||||
onDone()
|
||||
} else if (!filterResult) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
context.getString(R.string.relay),
|
||||
context.getString(R.string.relay_filter_failed),
|
||||
onAccept = {
|
||||
|
||||
+2
-3
@@ -31,7 +31,7 @@ import com.greenart7c3.nostrsigner.models.kindToNip
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.isPrivateEvent
|
||||
import com.greenart7c3.nostrsigner.service.toShortenHex
|
||||
import com.greenart7c3.nostrsigner.ui.AccountStateViewModel
|
||||
import com.greenart7c3.nostrsigner.ui.ToastManager
|
||||
import com.vitorpamplona.quartz.nip01Core.core.toHexKey
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.bechToBytes
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
@@ -47,7 +47,6 @@ fun IntentSingleEventHomeScreen(
|
||||
applicationName: String?,
|
||||
intentData: IntentData,
|
||||
account: Account,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
onRemoveIntentData: (List<IntentData>, IntentResultType) -> Unit,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
@@ -260,7 +259,7 @@ fun IntentSingleEventHomeScreen(
|
||||
account = account,
|
||||
onAccept = {
|
||||
if (intentData.unsignedEventKey.isNotBlank() && intentData.unsignedEventKey != account.hexKey && !isPrivateEvent(event.kind, event.tags)) {
|
||||
accountStateViewModel.toast(
|
||||
ToastManager.toast(
|
||||
title = context.getString(R.string.warning),
|
||||
message = context.getString(R.string.event_pubkey_is_not_equal_to_current_logged_in_user),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user