From 93c6010e192a798ae4769308752fd28fef759fd2 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 14 May 2026 12:05:17 -0400 Subject: [PATCH] liniting --- .../mainVideo/VideoPlayerActiveMutex.kt | 9 ++++++--- .../amethyst/ui/call/CallActivity.kt | 1 - .../amethyst/ui/components/pdf/PdfPreviewCard.kt | 16 ++++------------ .../amethyst/ui/note/elements/NowProvider.kt | 4 ++-- .../chats/marmotGroup/MarmotGroupListScreen.kt | 3 ++- .../loggedIn/nests/room/lobby/NestLobbyScreen.kt | 4 ++-- .../loggedIn/nests/room/screen/NestFullScreen.kt | 3 ++- .../nests/room/stage/ParticipantsGrid.kt | 3 ++- .../nests/room/stage/SpeakerZapOverlay.kt | 4 ++-- amethyst/src/main/res/values-pt-rBR/strings.xml | 12 ++++++++++++ amethyst/src/main/res/xml/locales_config.xml | 1 + 11 files changed, 35 insertions(+), 25 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/mainVideo/VideoPlayerActiveMutex.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/mainVideo/VideoPlayerActiveMutex.kt index ac8ab8d12c..231745dc8c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/mainVideo/VideoPlayerActiveMutex.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/mainVideo/VideoPlayerActiveMutex.kt @@ -35,6 +35,7 @@ import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalView import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.service.playback.composable.MediaControllerState +import java.lang.ref.WeakReference import kotlin.math.abs /** @@ -58,8 +59,10 @@ private var winner: TrackedVideo? = null // Cached result of view.getGlobalVisibleRect. The compose root rarely changes // across a scroll burst; caching avoids N native calls per frame. +// The view is held weakly: it is only used for an identity check, never +// dereferenced, and a strong static reference would leak the Activity. private val cachedRootRect = Rect() -private var cachedRootRectView: View? = null +private var cachedRootRectView: WeakReference? = null private var cachedRootRectVisible: Boolean = false private var cachedRootRectTimeNs: Long = 0L private const val ROOT_RECT_CACHE_TTL_NS = 8_000_000L // ~half a frame at 60fps @@ -191,11 +194,11 @@ private fun electNewWinner() { */ private fun cachedGlobalVisibleRect(view: View): Rect? { val now = System.nanoTime() - if (cachedRootRectView === view && (now - cachedRootRectTimeNs) < ROOT_RECT_CACHE_TTL_NS) { + if (cachedRootRectView?.get() === view && (now - cachedRootRectTimeNs) < ROOT_RECT_CACHE_TTL_NS) { return if (cachedRootRectVisible) cachedRootRect else null } cachedRootRectVisible = view.getGlobalVisibleRect(cachedRootRect) - cachedRootRectView = view + cachedRootRectView = WeakReference(view) cachedRootRectTimeNs = now return if (cachedRootRectVisible) cachedRootRect else null } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt index 165d634c17..640d9d546c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/call/CallActivity.kt @@ -285,7 +285,6 @@ class CallActivity : AppCompatActivity() { } private fun enterPipIfActive() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return val callManager = CallSessionBridge.callManager ?: return val state = callManager.state.value val isActive = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfPreviewCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfPreviewCard.kt index 027222f3c6..4dce82a5e1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfPreviewCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/pdf/PdfPreviewCard.kt @@ -45,8 +45,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.FilterQuality import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalWindowInfo import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.commons.icons.symbols.Icon @@ -107,17 +106,10 @@ private fun LoadedPdfPreviewCard( ) { val sharePopupExpanded = remember { mutableStateOf(false) } - val density = LocalDensity.current - val configuration = LocalConfiguration.current + val containerWidthPx = LocalWindowInfo.current.containerSize.width val targetWidthPx = - remember(density, configuration) { - val screenPx = - with(density) { - configuration.screenWidthDp.dp - .toPx() - .toInt() - } - screenPx.coerceAtMost(THUMBNAIL_MAX_DIM_PX).coerceAtLeast(1) + remember(containerWidthPx) { + containerWidthPx.coerceAtMost(THUMBNAIL_MAX_DIM_PX).coerceAtLeast(1) } @Suppress("ProduceStateDoesNotAssignValue") diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NowProvider.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NowProvider.kt index 9944d64cdb..f3e7a65ee6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NowProvider.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NowProvider.kt @@ -24,7 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.State import androidx.compose.runtime.compositionLocalOf -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.produceState import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.coroutines.delay @@ -35,7 +35,7 @@ private const val TICK_INTERVAL_MS = 30_000L // every TimeAgo on screen reads from it. Because TimeAgo wraps the formatted string in // `derivedStateOf`, the Text only recomposes when the displayed string actually changes // (e.g. crossing 1m → 2m) — not on every tick. -val LocalNowSeconds = compositionLocalOf> { mutableStateOf(TimeUtils.now()) } +val LocalNowSeconds = compositionLocalOf> { mutableLongStateOf(TimeUtils.now()) } @Composable fun NowProvider(content: @Composable () -> Unit) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt index b0be747f75..dc91f269fc 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/marmotGroup/MarmotGroupListScreen.kt @@ -46,6 +46,7 @@ import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue @@ -76,7 +77,7 @@ fun MarmotGroupListScreen( nav: INav, ) { var groupList by remember { mutableStateOf(listOf>()) } - var selectedTab by remember { mutableStateOf(0) } + var selectedTab by remember { mutableIntStateOf(0) } // Load group list LaunchedEffect(Unit) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt index 2e44feb771..2942f58db0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/lobby/NestLobbyScreen.kt @@ -48,7 +48,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -435,7 +435,7 @@ private fun RoomHeader( */ @Composable private fun CachedListenerCount(roomATag: String) { - var count by remember(roomATag) { mutableStateOf(0) } + var count by remember(roomATag) { mutableIntStateOf(0) } LaunchedEffect(roomATag) { val filter = Filter( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt index fbe2b6e2f6..0c3824e690 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/screen/NestFullScreen.kt @@ -47,6 +47,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -129,7 +130,7 @@ internal fun NestFullScreen( // Tab selection survives configuration changes and PIP transitions. // Stored as ordinal so rememberSaveable can persist it without a // custom Saver. - var selectedTabIndex by rememberSaveable { mutableStateOf(0) } + var selectedTabIndex by rememberSaveable { mutableIntStateOf(0) } val isHost = accountViewModel.account.signer.pubKey == event.pubKey val myPubkey = accountViewModel.account.signer.pubKey diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/ParticipantsGrid.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/ParticipantsGrid.kt index a06a2ada0a..a6d824114b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/ParticipantsGrid.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/ParticipantsGrid.kt @@ -63,6 +63,7 @@ import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon @@ -672,7 +673,7 @@ private fun HandRaiseBadge(modifier: Modifier = Modifier) { Box( modifier = modifier - .offset(x = 2.dp, y = (-2).dp + offsetY.dp) + .offset { IntOffset(2.dp.roundToPx(), ((-2).dp + offsetY.dp).roundToPx()) } .size(MAX_BADGE_SIZE) .background(MaterialTheme.colorScheme.tertiary, CircleShape), contentAlignment = Alignment.Center, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerZapOverlay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerZapOverlay.kt index ccbc735b27..cbfa35db99 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerZapOverlay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/nests/room/stage/SpeakerZapOverlay.kt @@ -38,7 +38,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier @@ -93,7 +93,7 @@ private fun ZapChip(zap: RoomZap) { // + fade in lockstep with how close it is to being evicted. Re-key // on the event id so the animation restarts whenever a fresh zap // replaces the value at this slot. - var progress by remember(zap.eventId) { mutableStateOf(0f) } + var progress by remember(zap.eventId) { mutableFloatStateOf(0f) } LaunchedEffect(zap.eventId) { val ageMs = (System.currentTimeMillis() / 1000L - zap.createdAtSec).coerceAtLeast(0L) * 1000L val remaining = (ZAP_WINDOW_MS - ageMs).coerceAtLeast(0L) diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index 46c018826a..5cba6e077d 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -428,6 +428,7 @@ Desconectado Desconectado · %d post agendado excluído + Desconectado · %d de posts agendados excluídos Desconectado · %d posts agendados excluídos Post agendado publicado @@ -445,18 +446,22 @@ Cancelado Você tem %d post agendado que ainda não foi publicado. Sair excluirá esse post permanentemente. + Você tem %d de posts agendados que ainda não foram publicados. Sair excluirá esses posts permanentemente. Você tem %d posts agendados que ainda não foram publicados. Sair excluirá esses posts permanentemente. %d na fila + %d na fila %d na fila · %d em 1h + · %d em 1h · %d em 1h para %d relay + para %d de relays para %d relays ID do post copiado @@ -616,6 +621,7 @@ Não foi possível marcar a sala como fechada. Saindo mesmo assim — a sala será fechada automaticamente. %1$d ouvinte + %1$d de ouvintes %1$d ouvintes AO VIVO @@ -2266,26 +2272,32 @@ Nunca visto %1$d minuto + %1$d de minutos %1$d minutos %1$d hora + %1$d de horas %1$d horas %1$d dia + %1$d de dias %1$d dias %1$d semana + %1$d de semanas %1$d semanas %1$d mês + %1$d de meses %1$d meses %1$d ano + %1$d de anos %1$d anos <%1$s diff --git a/amethyst/src/main/res/xml/locales_config.xml b/amethyst/src/main/res/xml/locales_config.xml index c33cc296db..217b6f15d2 100644 --- a/amethyst/src/main/res/xml/locales_config.xml +++ b/amethyst/src/main/res/xml/locales_config.xml @@ -42,6 +42,7 @@ +