From e5de2c45de098d1bf0070aec47859f6ce794f04a Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 6 May 2023 21:58:25 -0400 Subject: [PATCH] Moving withContext to scope.launch to avoid waiting the results. --- .../amethyst/ui/components/UrlPreview.kt | 6 ++-- .../amethyst/ui/navigation/AppBottomBar.kt | 6 ++-- .../amethyst/ui/note/BadgeCompose.kt | 31 +++++++++++++------ .../amethyst/ui/note/ChatroomCompose.kt | 9 ++++-- .../ui/note/ChatroomMessageCompose.kt | 6 ++-- .../amethyst/ui/note/MessageSetCompose.kt | 7 +++-- .../amethyst/ui/note/MultiSetCompose.kt | 10 ++++-- .../amethyst/ui/note/NoteCompose.kt | 5 ++- .../amethyst/ui/note/ReactionsRow.kt | 6 ++-- .../amethyst/ui/note/ZapNoteCompose.kt | 3 +- .../components/TranslatableRichTextViewer.kt | 7 +++-- 11 files changed, 63 insertions(+), 33 deletions(-) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt index fd012bc0b4..14fb7bd9f0 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt @@ -7,6 +7,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext import com.baha.url.preview.IUrlPreviewCallback @@ -14,7 +15,7 @@ import com.baha.url.preview.UrlInfoItem import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.UrlCachedPreviewer import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch @Composable fun UrlPreview(url: String, urlText: String) { @@ -28,11 +29,12 @@ fun UrlPreview(url: String, urlText: String) { val context = LocalContext.current var urlPreviewState by remember { mutableStateOf(default) } + val scope = rememberCoroutineScope() // Doesn't use a viewModel because of viewModel reusing issues (too many UrlPreview are created). LaunchedEffect(url) { if (urlPreviewState == UrlPreviewState.Loading) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { UrlCachedPreviewer.previewInfo( url, object : IUrlPreviewCallback { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt index 95048de58f..26f8721111 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppBottomBar.kt @@ -41,7 +41,6 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import kotlin.time.ExperimentalTime val bottomNavigationItems = listOf( @@ -159,15 +158,16 @@ private fun NotifiableIcon(route: Route, selected: Boolean, accountViewModel: Ac val notif = notifState.value ?: return var hasNewItems by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() LaunchedEffect(key1 = notif) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { hasNewItems = route.hasNewItems(account, notif.cache, emptySet()) } } LaunchedEffect(key1 = db) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { hasNewItems = route.hasNewItems(account, notif.cache, db) } } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt index 85325fc6cc..3f71245ce6 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/BadgeCompose.kt @@ -23,6 +23,7 @@ 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 @@ -37,7 +38,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.screen.BadgeCard import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @Composable @@ -48,6 +49,7 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL val context = LocalContext.current.applicationContext var popupExpanded by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() if (note == null) { BlankNote(Modifier, isInnerNote) @@ -55,7 +57,7 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL var isNew by remember { mutableStateOf(false) } LaunchedEffect(key1 = likeSetCard) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { isNew = likeSetCard.createdAt() > NotificationCache.load(routeForLastRead) NotificationCache.markAsRead(routeForLastRead, likeSetCard.createdAt()) @@ -69,12 +71,17 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL } Column( - modifier = Modifier.background(backgroundColor).combinedClickable( - onClick = { - routeFor(note, accountViewModel.userProfile())?.let { navController.navigate(it) } - }, - onLongClick = { popupExpanded = true } - ) + modifier = Modifier + .background(backgroundColor) + .combinedClickable( + onClick = { + routeFor( + note, + accountViewModel.userProfile() + )?.let { navController.navigate(it) } + }, + onLongClick = { popupExpanded = true } + ) ) { Row( modifier = Modifier @@ -94,7 +101,9 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL Icon( imageVector = Icons.Default.MilitaryTech, null, - modifier = Modifier.size(25.dp).align(Alignment.TopEnd), + modifier = Modifier + .size(25.dp) + .align(Alignment.TopEnd), tint = MaterialTheme.colors.primary ) } @@ -105,7 +114,9 @@ fun BadgeCompose(likeSetCard: BadgeCard, isInnerNote: Boolean = false, routeForL Text( stringResource(R.string.new_badge_award_notif), fontWeight = FontWeight.Bold, - modifier = Modifier.padding(bottom = 5.dp).weight(1f) + modifier = Modifier + .padding(bottom = 5.dp) + .weight(1f) ) Text( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomCompose.kt index 246b1fef2a..f51a778992 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ChatroomCompose.kt @@ -22,6 +22,7 @@ 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 @@ -50,7 +51,7 @@ import com.vitorpamplona.amethyst.ui.components.ResizeImage import com.vitorpamplona.amethyst.ui.components.RobohashAsyncImageProxy import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch @Composable fun ChatroomCompose( @@ -64,6 +65,8 @@ fun ChatroomCompose( val notificationCacheState = NotificationCache.live.observeAsState() val notificationCache = notificationCacheState.value ?: return + val scope = rememberCoroutineScope() + if (note?.event == null) { BlankNote(Modifier) } else if (note.channel() != null) { @@ -86,7 +89,7 @@ fun ChatroomCompose( var hasNewMessages by remember { mutableStateOf(false) } LaunchedEffect(key1 = notificationCache, key2 = note) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { note.createdAt()?.let { timestamp -> hasNewMessages = timestamp > notificationCache.cache.load("Channel/${chan.idHex}") @@ -148,7 +151,7 @@ fun ChatroomCompose( var hasNewMessages by remember { mutableStateOf(false) } LaunchedEffect(key1 = notificationCache, key2 = note) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { noteEvent?.let { hasNewMessages = it.createdAt() > notificationCache.cache.load( "Room/${userToComposeOn.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 2909885014..21e7bb60c3 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 @@ -31,6 +31,7 @@ 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 @@ -63,7 +64,7 @@ import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch val ChatBubbleShapeMe = RoundedCornerShape(15.dp, 15.dp, 3.dp, 15.dp) val ChatBubbleShapeThem = RoundedCornerShape(3.dp, 15.dp, 15.dp, 15.dp) @@ -94,6 +95,7 @@ fun ChatroomMessageCompose( var showHiddenNote by remember { mutableStateOf(false) } val context = LocalContext.current.applicationContext + val scope = rememberCoroutineScope() if (note?.event == null) { BlankNote(Modifier) @@ -135,7 +137,7 @@ fun ChatroomMessageCompose( LaunchedEffect(key1 = routeForLastRead) { routeForLastRead?.let { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { val lastTime = NotificationCache.load(it) val createdAt = note.createdAt() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt index f7f41e3cd5..1557a09b0c 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MessageSetCompose.kt @@ -17,6 +17,7 @@ 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 @@ -29,7 +30,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.screen.MessageSetCard import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @Composable @@ -40,13 +41,15 @@ fun MessageSetCompose(messageSetCard: MessageSetCard, isInnerNote: Boolean = fal val noteEvent = note?.event var popupExpanded by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() + if (note == null) { BlankNote(Modifier, isInnerNote) } else { var isNew by remember { mutableStateOf(false) } LaunchedEffect(key1 = messageSetCard.createdAt()) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { isNew = messageSetCard.createdAt() > NotificationCache.load(routeForLastRead) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt index 38f4932b32..c23b48d834 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/MultiSetCompose.kt @@ -22,6 +22,7 @@ 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 @@ -44,7 +45,7 @@ import com.vitorpamplona.amethyst.ui.screen.MultiSetCard import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @Composable @@ -57,13 +58,15 @@ fun MultiSetCompose(multiSetCard: MultiSetCard, routeForLastRead: String, accoun var popupExpanded by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() + if (note == null) { BlankNote(Modifier, false) } else { var isNew by remember { mutableStateOf(false) } LaunchedEffect(key1 = multiSetCard.createdAt()) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { isNew = multiSetCard.createdAt > NotificationCache.load(routeForLastRead) NotificationCache.markAsRead(routeForLastRead, multiSetCard.createdAt) @@ -209,9 +212,10 @@ private fun AuthorPictureAndComment( val author = zapRequest.author ?: return var content by remember { mutableStateOf>(Pair(author, null)) } + val scope = rememberCoroutineScope() LaunchedEffect(key1 = zapRequest.idHex) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { (zapRequest.event as? LnZapRequestEvent)?.let { val decryptedContent = accountViewModel.decryptZap(zapRequest) if (decryptedContent != 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 7c37b71e99..4913cb79c9 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 @@ -59,6 +59,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.ReportNoteDialog import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import com.vitorpamplona.amethyst.ui.theme.Following import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.File import java.math.BigDecimal @@ -174,8 +175,10 @@ fun NoteComposeInner( } else { var isNew by remember { mutableStateOf(false) } + val scope = rememberCoroutineScope() + LaunchedEffect(key1 = routeForLastRead) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { routeForLastRead?.let { val lastTime = NotificationCache.load(it) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index cc3591e3ef..03371eda70 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -61,7 +61,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.math.BigDecimal import java.math.RoundingMode import kotlin.math.roundToInt @@ -322,7 +321,7 @@ fun ZapReaction( var zapAmount by remember { mutableStateOf(null) } LaunchedEffect(key1 = zapsState) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { if (!wasZappedByLoggedInUser) { wasZappedByLoggedInUser = accountViewModel.calculateIfNoteWasZappedByAccount(zappedNote) } @@ -333,7 +332,8 @@ fun ZapReaction( Row( verticalAlignment = CenterVertically, - modifier = Modifier.size(iconSize) + modifier = Modifier + .size(iconSize) .combinedClickable( role = Role.Button, interactionSource = remember { MutableInteractionSource() }, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt index 9801bf21c1..aa881b1f0a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapNoteCompose.kt @@ -34,7 +34,6 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.UnfollowButton import com.vitorpamplona.amethyst.ui.theme.BitcoinOrange import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import java.math.BigDecimal @Composable @@ -95,7 +94,7 @@ fun ZapNoteCompose(baseNote: Pair, accountViewModel: AccountViewMode var zapAmount by remember { mutableStateOf(null) } LaunchedEffect(key1 = noteZap) { - withContext(Dispatchers.IO) { + coroutineScope.launch(Dispatchers.IO) { zapAmount = (noteZap.event as? LnZapEvent)?.amount } } diff --git a/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt b/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt index 8100a3e9b1..7c4c044574 100644 --- a/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt +++ b/app/src/play/java/com/vitorpamplona/amethyst/ui/components/TranslatableRichTextViewer.kt @@ -18,6 +18,7 @@ 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.Modifier import androidx.compose.ui.graphics.Color @@ -34,7 +35,7 @@ import com.vitorpamplona.amethyst.service.lang.LanguageTranslatorService import com.vitorpamplona.amethyst.service.lang.ResultOrError import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext +import kotlinx.coroutines.launch import java.util.Locale @Composable @@ -57,8 +58,10 @@ fun TranslatableRichTextViewer( val accountState by accountViewModel.accountLanguagesLiveData.observeAsState() val account = accountState?.account ?: return + val scope = rememberCoroutineScope() + LaunchedEffect(accountState) { - withContext(Dispatchers.IO) { + scope.launch(Dispatchers.IO) { LanguageTranslatorService.autoTranslate( content, account.dontTranslateFrom,