From a64c941f36555a5c8767d6284e1b46e03c5ba2c1 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 6 Sep 2023 09:21:55 -0300 Subject: [PATCH] add cache to decrypted dms --- .../amethyst/service/AmberUtils.kt | 1 + .../amethyst/ui/note/ChatroomHeaderCompose.kt | 49 ++++++++++++++- .../ui/note/ChatroomMessageCompose.kt | 61 +++++++++++++------ .../amethyst/ui/note/NoteCompose.kt | 9 +-- 4 files changed, 94 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt index 3bbf32915..ea02263d0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/AmberUtils.kt @@ -11,6 +11,7 @@ import com.vitorpamplona.quartz.events.EventInterface object AmberUtils { var content: String = "" var isActivityRunning: Boolean = false + val cachedDecryptedContent = mutableMapOf() fun openAmber( data: String, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt index f0a2c050f..92e1b7210 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomHeaderCompose.kt @@ -1,5 +1,9 @@ package com.vitorpamplona.amethyst.ui.note +import android.app.Activity +import android.widget.Toast +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.Crossfade import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -21,11 +25,13 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -45,11 +51,14 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.distinctUntilChanged import androidx.lifecycle.map import com.patrykandpatrick.vico.core.extension.forEachIndexedExtended +import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Channel import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User +import com.vitorpamplona.amethyst.service.AmberUtils +import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -68,6 +77,7 @@ import com.vitorpamplona.quartz.events.ChannelCreateEvent import com.vitorpamplona.quartz.events.ChannelMetadataEvent import com.vitorpamplona.quartz.events.ChatroomKey import com.vitorpamplona.quartz.events.ChatroomKeyable +import com.vitorpamplona.quartz.events.PrivateDmEvent import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -245,6 +255,7 @@ private fun UserRoomCompose( accountViewModel: AccountViewModel, nav: (String) -> Unit ) { + val scope = rememberCoroutineScope() val hasNewMessages = remember { mutableStateOf(false) } val route = remember(room) { @@ -256,10 +267,42 @@ private fun UserRoomCompose( note.createdAt() } } + val decryptedContent = remember(note) { if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] } + var content by remember(note) { + mutableStateOf( + decryptedContent ?: accountViewModel.decrypt(note) + ) + } - val content by remember(note) { - derivedStateOf { - accountViewModel.decrypt(note) + val activityLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult(), + onResult = { + if (it.resultCode != Activity.RESULT_OK) { + scope.launch(Dispatchers.Main) { + Toast.makeText( + Amethyst.instance, + "Sign request rejected", + Toast.LENGTH_SHORT + ).show() + } + return@rememberLauncherForActivityResult + } + val event = note.event + + AmberUtils.cachedDecryptedContent[event!!.id()] = it.data?.getStringExtra("signature") ?: "" + content = AmberUtils.cachedDecryptedContent[event.id()] + } + ) + + if (accountViewModel.loggedInWithAmber() && decryptedContent == null && note.event is PrivateDmEvent) { + val event = note.event + SideEffect { + AmberUtils.openAmber( + event?.content() ?: "", + SignerType.NIP04_DECRYPT, + activityLauncher, + (event as PrivateDmEvent).talkingWith(accountViewModel.userProfile().pubkeyHex) + ) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt index 382838292..da488fc3d 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomMessageCompose.kt @@ -1,5 +1,9 @@ package com.vitorpamplona.amethyst.ui.note +import android.app.Activity +import android.widget.Toast +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.animation.Crossfade import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.clickable @@ -22,11 +26,13 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -41,10 +47,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.map +import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.ui.actions.SignerDialog +import com.vitorpamplona.amethyst.service.AmberUtils import com.vitorpamplona.amethyst.ui.actions.SignerType import com.vitorpamplona.amethyst.ui.components.CreateClickableTextWithEmoji import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji @@ -65,7 +72,6 @@ import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.mediumImportanceLink import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.amethyst.ui.theme.subtleBorder -import com.vitorpamplona.quartz.encoders.toHexKey import com.vitorpamplona.quartz.events.ChannelCreateEvent import com.vitorpamplona.quartz.events.ChannelMetadataEvent import com.vitorpamplona.quartz.events.ChatMessageEvent @@ -630,24 +636,41 @@ private fun RenderRegularTextNote( nav: (String) -> Unit ) { val tags = remember(note.event) { note.event?.tags()?.toImmutableListOfLists() ?: ImmutableListOfLists() } - var eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) } + val decryptedContent = remember(note.event) { if (note.event == null) null else AmberUtils.cachedDecryptedContent[note.event!!.id()] } + var eventContent by remember { mutableStateOf(decryptedContent ?: accountViewModel.decrypt(note)) } val modifier = remember { Modifier.padding(top = 5.dp) } - val loggedInWithAmber = accountViewModel.loggedInWithAmber() - var triedToDecrypt by remember { mutableStateOf(false) } - if (loggedInWithAmber && !triedToDecrypt && note.event is PrivateDmEvent) { - SignerDialog( - onClose = { - triedToDecrypt = true - eventContent = accountViewModel.decrypt(note) - }, - onPost = { - eventContent = it - triedToDecrypt = true - }, - data = eventContent ?: "", - type = SignerType.NIP04_DECRYPT, - pubKey = (note.event as PrivateDmEvent).talkingWith(accountViewModel.account.keyPair.pubKey.toHexKey()) ?: "" - ) + val scope = rememberCoroutineScope() + + val activityLauncher = rememberLauncherForActivityResult( + contract = ActivityResultContracts.StartActivityForResult(), + onResult = { + if (it.resultCode != Activity.RESULT_OK) { + scope.launch(Dispatchers.Main) { + Toast.makeText( + Amethyst.instance, + "Sign request rejected", + Toast.LENGTH_SHORT + ).show() + } + return@rememberLauncherForActivityResult + } + val event = note.event + + AmberUtils.cachedDecryptedContent[event!!.id()] = it.data?.getStringExtra("signature") ?: "" + eventContent = AmberUtils.cachedDecryptedContent[event.id()] + } + ) + + if (accountViewModel.loggedInWithAmber() && decryptedContent == null && note.event is PrivateDmEvent) { + val event = note.event + SideEffect { + AmberUtils.openAmber( + event?.content() ?: "", + SignerType.NIP04_DECRYPT, + activityLauncher, + (event as PrivateDmEvent).talkingWith(accountViewModel.userProfile().pubkeyHex) + ) + } } if (eventContent != null) { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 04f3eb872..1c0d12fca 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -1570,7 +1570,8 @@ private fun RenderPrivateMessage( val scope = rememberCoroutineScope() if (withMe) { - var eventContent by remember { mutableStateOf(accountViewModel.decrypt(note)) } + val decryptedContent = AmberUtils.cachedDecryptedContent[noteEvent.id] + var eventContent by remember { mutableStateOf(decryptedContent ?: accountViewModel.decrypt(note)) } val activityLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult(), onResult = { @@ -1584,11 +1585,11 @@ private fun RenderPrivateMessage( } return@rememberLauncherForActivityResult } - - eventContent = it.data?.getStringExtra("signature") ?: "" + AmberUtils.cachedDecryptedContent[noteEvent.id] = it.data?.getStringExtra("signature") ?: "" + eventContent = AmberUtils.cachedDecryptedContent[noteEvent.id] } ) - if (accountViewModel.loggedInWithAmber()) { + if (accountViewModel.loggedInWithAmber() && decryptedContent == null) { val event = note.event SideEffect { AmberUtils.openAmber(