mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-05 19:08:23 +00:00
Use ImmutableList for request list parameters through the composable chain
Plain List<T> has runtime-determined stability in Compose, preventing compile-time skip optimizations. Switching to ImmutableList<T> (which is @Immutable-annotated) lets the compiler guarantee that composables receiving unchanged list references can be safely skipped. Also fix redundant smart-cast in BunkerMultiEventHomeScreen. https://claude.ai/code/session_01PRSKjmFms1Tj1QJ5FhfqZm
This commit is contained in:
@@ -38,6 +38,7 @@ import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -110,7 +111,7 @@ class MainActivity : AppCompatActivity() {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
val bunkerRequests = BunkerRequestUtils.state.collectAsStateWithLifecycle(emptyList())
|
||||
val bunkerRequests = BunkerRequestUtils.state.collectAsStateWithLifecycle(persistentListOf())
|
||||
val npub = remember { mainViewModel.getAccount(intent?.getStringExtra("current_user")) }
|
||||
|
||||
val accountStateViewModel: AccountStateViewModel =
|
||||
|
||||
@@ -16,6 +16,9 @@ import com.vitorpamplona.quartz.nip19Bech32.Nip19Parser
|
||||
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -24,21 +27,21 @@ import kotlinx.coroutines.launch
|
||||
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
class MainViewModel(val context: Context) : ViewModel() {
|
||||
private val _intents = MutableStateFlow<List<IntentData>>(listOf())
|
||||
private val _intents = MutableStateFlow<ImmutableList<IntentData>>(persistentListOf())
|
||||
val intents = _intents.asStateFlow()
|
||||
var navController: NavHostController? = null
|
||||
|
||||
fun addAll(list: List<IntentData>) {
|
||||
val newList = list.filter { !intents.value.contains(it) }
|
||||
_intents.value += newList
|
||||
_intents.value = (_intents.value + newList).toPersistentList()
|
||||
}
|
||||
|
||||
fun removeAll(intents: List<IntentData>) {
|
||||
_intents.value -= intents.toSet()
|
||||
_intents.value = (_intents.value - intents.toSet()).toPersistentList()
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
_intents.value = emptyList()
|
||||
_intents.value = persistentListOf()
|
||||
}
|
||||
|
||||
fun getAccount(userFromIntent: String?): String? {
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import com.greenart7c3.nostrsigner.ui.theme.NostrSignerTheme
|
||||
import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -126,7 +127,7 @@ class SignerActivity : AppCompatActivity() {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
val bunkerRequests = BunkerRequestUtils.state.collectAsStateWithLifecycle(emptyList())
|
||||
val bunkerRequests = BunkerRequestUtils.state.collectAsStateWithLifecycle(persistentListOf())
|
||||
val npub = remember { mainViewModel.getAccount(intent?.getStringExtra("current_user")) }
|
||||
|
||||
val accountStateViewModel: AccountStateViewModel =
|
||||
|
||||
@@ -28,25 +28,28 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlin.collections.toSet
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
object BunkerRequestUtils {
|
||||
val state = MutableStateFlow(listOf<AmberBunkerRequest>())
|
||||
val state = MutableStateFlow<ImmutableList<AmberBunkerRequest>>(persistentListOf())
|
||||
|
||||
fun addRequest(request: AmberBunkerRequest) {
|
||||
if (state.value.any { it.request.id == request.request.id }) return
|
||||
state.tryEmit(state.value + request)
|
||||
state.tryEmit((state.value + request).toPersistentList())
|
||||
}
|
||||
|
||||
fun clearRequests() {
|
||||
state.tryEmit(emptyList())
|
||||
state.tryEmit(persistentListOf())
|
||||
}
|
||||
|
||||
fun remove(id: String) {
|
||||
state.tryEmit(state.value.filter { it.request.id != id })
|
||||
state.tryEmit(state.value.filter { it.request.id != id }.toPersistentList())
|
||||
}
|
||||
|
||||
fun getBunkerRequests(): List<AmberBunkerRequest> = state.value
|
||||
|
||||
@@ -38,6 +38,8 @@ import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.IntentResultType
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@SuppressLint("StateFlowValueCalledInComposition", "UnrememberedMutableState")
|
||||
@Composable
|
||||
@@ -47,7 +49,7 @@ fun AccountScreen(
|
||||
packageName: String?,
|
||||
appName: String?,
|
||||
mainViewModel: MainViewModel,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
navController: NavHostController,
|
||||
isExternalRequest: Boolean = false,
|
||||
) {
|
||||
@@ -66,7 +68,7 @@ fun AccountScreen(
|
||||
MainLoginPage(accountStateViewModel, newNavController)
|
||||
}
|
||||
is AccountState.LoggedIn -> {
|
||||
val intents by mainViewModel.intents.collectAsState(initial = emptyList())
|
||||
val intents by mainViewModel.intents.collectAsState(initial = persistentListOf())
|
||||
LaunchedEffect(intent) {
|
||||
intent?.let {
|
||||
IntentUtils.getIntentData(
|
||||
|
||||
@@ -26,12 +26,13 @@ import com.greenart7c3.nostrsigner.models.IntentResultType
|
||||
import com.greenart7c3.nostrsigner.ui.components.BunkerSingleEventHomeScreen
|
||||
import com.greenart7c3.nostrsigner.ui.components.IntentSingleEventHomeScreen
|
||||
import com.greenart7c3.nostrsigner.ui.components.MultiEventHomeScreen
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
fun IncomingRequestScreen(
|
||||
modifier: Modifier,
|
||||
intents: List<IntentData>,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
intents: ImmutableList<IntentData>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
packageName: String?,
|
||||
applicationName: String?,
|
||||
account: Account,
|
||||
|
||||
@@ -81,6 +81,7 @@ import com.greenart7c3.nostrsigner.ui.components.AmberFloatingButton
|
||||
import com.greenart7c3.nostrsigner.ui.components.AmberTopAppBar
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import java.util.Base64
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -131,8 +132,8 @@ fun requestIgnoreBatteryOptimizations(context: Context) {
|
||||
fun MainScreen(
|
||||
account: Account,
|
||||
accountStateViewModel: AccountStateViewModel,
|
||||
intents: List<IntentData>,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
intents: ImmutableList<IntentData>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
packageName: String?,
|
||||
appName: String?,
|
||||
route: MutableState<String?>,
|
||||
|
||||
@@ -50,6 +50,7 @@ import com.greenart7c3.nostrsigner.ui.navigation.Route
|
||||
import com.greenart7c3.nostrsigner.ui.navigation.routes
|
||||
import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect
|
||||
import java.util.Base64
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -63,8 +64,8 @@ fun AmberTopAppBar(
|
||||
context: Context,
|
||||
navBackStackEntry: NavBackStackEntry?,
|
||||
account: Account,
|
||||
intents: List<IntentData>,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
intents: ImmutableList<IntentData>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
packageName: String?,
|
||||
) {
|
||||
if (intents.isEmpty() || packageName == null || destinationRoute != Route.IncomingRequest.route) {
|
||||
|
||||
+3
-2
@@ -64,19 +64,20 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.set
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun BunkerMultiEventHomeScreen(
|
||||
modifier: Modifier,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
packageName: String?,
|
||||
accountParam: Account,
|
||||
onLoading: (Boolean) -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val hasRelayAuthEvents = bunkerRequests.any { it.request is BunkerRequestSign && (it.request as BunkerRequestSign).event.kind == 22242 }
|
||||
val hasRelayAuthEvents = bunkerRequests.any { it.request is BunkerRequestSign && it.request.event.kind == 22242 }
|
||||
var localAccount by remember { mutableStateOf("") }
|
||||
val key = bunkerRequests.first().localKey
|
||||
var rememberType by remember { mutableStateOf(RememberType.NEVER) }
|
||||
|
||||
@@ -16,7 +16,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -39,6 +38,7 @@ import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.PrivateZapEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import kotlin.collections.forEach
|
||||
|
||||
@Composable
|
||||
|
||||
+2
-1
@@ -64,13 +64,14 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.set
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun IntentMultiEventHomeScreen(
|
||||
modifier: Modifier,
|
||||
intents: List<IntentData>,
|
||||
intents: ImmutableList<IntentData>,
|
||||
packageName: String?,
|
||||
accountParam: Account,
|
||||
onRemoveIntentData: (List<IntentData>, IntentResultType) -> Unit,
|
||||
|
||||
@@ -6,12 +6,13 @@ import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.AmberBunkerRequest
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.models.IntentResultType
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
fun MultiEventHomeScreen(
|
||||
modifier: Modifier,
|
||||
intents: List<IntentData>,
|
||||
bunkerRequests: List<AmberBunkerRequest>,
|
||||
intents: ImmutableList<IntentData>,
|
||||
bunkerRequests: ImmutableList<AmberBunkerRequest>,
|
||||
packageName: String?,
|
||||
accountParam: Account,
|
||||
onRemoveIntentData: (List<IntentData>, IntentResultType) -> Unit,
|
||||
|
||||
@@ -16,7 +16,6 @@ import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -39,6 +38,7 @@ import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.models.PrivateZapEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TagArrayEncryptedDataKind
|
||||
import com.greenart7c3.nostrsigner.service.MultiEventScreenIntents
|
||||
import kotlin.collections.forEach
|
||||
|
||||
@Composable
|
||||
|
||||
Reference in New Issue
Block a user