diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt index 707b98219d..dee33b33c8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/AppModules.kt @@ -1034,6 +1034,8 @@ class AppModules( ) } + // androidx.security.crypto's EncryptedSharedPreferences is deprecated with no drop-in successor. + @Suppress("DEPRECATION") fun encryptedStorage(npub: String? = null): EncryptedSharedPreferences = EncryptedStorage.preferences(appContext, npub) fun initiate(appContext: Context) { @@ -1092,9 +1094,11 @@ class AppModules( uiState } - // LRUCache should not be instanciated in the Main thread due to blocking + // LRUCache should not be instanciated in the Main thread due to blocking. + // trimToSize is a no-op on the empty cache; it just forces the object's + // (blocking) initialization to happen off the main thread. applicationIOScope.launch { - CachedRobohash + CachedRobohash.trimToSize(100) resourceCacheInit() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/EncryptedStorage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/EncryptedStorage.kt index 52f3045b5d..324abea1e1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/EncryptedStorage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/EncryptedStorage.kt @@ -31,6 +31,9 @@ class EncryptedStorage { // returns the preferences for each account or a global file if null. fun prefsFileName(npub: String? = null): String = if (npub == null) PREFERENCES_NAME else "${PREFERENCES_NAME}_$npub" + // androidx.security.crypto is deprecated with no drop-in successor; migrating the + // on-disk key store is a separate, security-sensitive effort. + @Suppress("DEPRECATION") fun preferences( applicationContext: Context, npub: String? = null, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/ExoPlayerBuilder.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/ExoPlayerBuilder.kt index c92252150a..ae2c4d0964 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/ExoPlayerBuilder.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/playerPool/ExoPlayerBuilder.kt @@ -50,6 +50,7 @@ class ExoPlayerBuilder( val renderersFactory = object : DefaultRenderersFactory(context) { + @Suppress("DEPRECATION") // media3 DefaultAudioSink.Builder.setEnableAudioTrackPlaybackParams is deprecated. override fun buildAudioSink( context: Context, enableFloatOutput: Boolean, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/ResourceUsageAccountant.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/ResourceUsageAccountant.kt index 778532c29a..eaa90e8d10 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/ResourceUsageAccountant.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/resourceusage/ResourceUsageAccountant.kt @@ -75,7 +75,7 @@ class ResourceUsageAccountant( ) { if (amount <= 0) return live.computeIfAbsent(key) { AtomicLong() }.addAndGet(amount) - if (inHookRun.get()) return + if (inHookRun.get() == true) return if (flushScheduled.compareAndSet(false, true)) { scope.launch { delay(flushDebounceMs) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt index 0aab8e2fce..69afaddab3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/actions/mediaServers/BlossomBlobManagerScreen.kt @@ -57,16 +57,16 @@ 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.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.pluralStringResource -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.style.TextOverflow @@ -79,6 +79,7 @@ import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarExtensibleWithBackButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -86,6 +87,7 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.allGoodColor import com.vitorpamplona.amethyst.ui.theme.grayText import com.vitorpamplona.quartz.nip56Reports.ReportType +import kotlinx.coroutines.launch @Composable fun BlossomBlobManagerScreen( @@ -235,7 +237,8 @@ private fun BlobCard( ) { var menuOpen by remember { mutableStateOf(false) } var reportOpen by remember { mutableStateOf(false) } - val clipboard = LocalClipboardManager.current + val clipboard = LocalClipboard.current + val scope = rememberCoroutineScope() val context = LocalContext.current Column( @@ -276,7 +279,8 @@ private fun BlobCard( leadingIcon = { MenuIcon(MaterialSymbols.ContentCopy) }, onClick = { menuOpen = false - clipboard.setText(AnnotatedString(row.url)) + val url = row.url + scope.launch { clipboard.setText(url) } }, ) DropdownMenuItem( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/EmbeddedWebAppController.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/EmbeddedWebAppController.kt index 84976ecaec..2e615a33d2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/EmbeddedWebAppController.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/browser/EmbeddedWebAppController.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.ui.screen.loggedIn.browser import android.content.ComponentName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt index 72acad2890..04cfbd615e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/AgentConsoleScreen.kt @@ -39,8 +39,8 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Scaffold +import androidx.compose.material3.SecondaryTabRow import androidx.compose.material3.Tab -import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect @@ -125,7 +125,7 @@ fun AgentConsoleScreen( }, ) { padding -> Column(modifier = Modifier.padding(padding).fillMaxSize()) { - TabRow(selectedTabIndex = selectedTab) { + SecondaryTabRow(selectedTabIndex = selectedTab) { tabs.forEachIndexed { index, title -> Tab( selected = selectedTab == index, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzCanvasScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzCanvasScreen.kt index 91c8cd45bc..5899bb3cd3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzCanvasScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzCanvasScreen.kt @@ -108,7 +108,7 @@ fun BuzzCanvasScreen( } }, ) { padding -> - if (content.isNullOrBlank() || canvas == null) { + if (content.isNullOrBlank()) { Box( modifier = Modifier.padding(padding).fillMaxSize().padding(32.dp), contentAlignment = Alignment.Center, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt index 7c9738f5a6..02772811db 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/buzz/BuzzWorkspaceOverflowMenu.kt @@ -38,16 +38,15 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.unit.dp -import androidx.core.content.ContextCompat import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.service.buzz.BuzzInviteMinter +import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl @@ -73,7 +72,7 @@ fun BuzzWorkspaceOverflowMenu( var error by remember { mutableStateOf(null) } val scope = rememberCoroutineScope() val context = LocalContext.current - val clipboard = LocalClipboardManager.current + val clipboard = LocalClipboard.current IconButton(onClick = { menuOpen = true }) { Icon( @@ -145,13 +144,13 @@ fun BuzzWorkspaceOverflowMenu( type = "text/plain" putExtra(Intent.EXTRA_TEXT, minted.url) } - ContextCompat.startActivity(context, Intent.createChooser(send, null), null) + context.startActivity(Intent.createChooser(send, null)) result = null }) { Text(stringRes(R.string.buzz_invite_share)) } }, dismissButton = { TextButton(onClick = { - clipboard.setText(AnnotatedString(minted.url)) + scope.launch { clipboard.setText(minted.url) } result = null }) { Text(stringRes(R.string.buzz_invite_copy)) } }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageActionSheet.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageActionSheet.kt index df73e0d147..e1f14b5bce 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageActionSheet.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/ChatMessageActionSheet.kt @@ -278,7 +278,7 @@ fun ChatMessageActionSheet( SectionDivider() TileRow { ActionTile(MaterialSymbols.Edit, stringRes(R.string.buzz_edit_message)) { - onWantsToEditBuzz!!(note) + onWantsToEditBuzz(note) onDismiss() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderBuzzNotes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderBuzzNotes.kt index 2d10c310c4..d20e48679d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderBuzzNotes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/feed/types/RenderBuzzNotes.kt @@ -228,7 +228,7 @@ fun RenderBuzzDiff(note: Note) { it.language?.let { lang -> append(if (isEmpty()) lang else " · $lang") } it.prNumber?.let { pr -> append(" · PR #$pr") } it.commitSha - ?.takeIf { sha -> sha.isNotBlank() } + .takeIf { sha -> sha.isNotBlank() } ?.let { sha -> append(" · ${sha.take(8)}") } }.ifBlank { null } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedSurfaceController.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedSurfaceController.kt index dd0225649e..8f38e10ac9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedSurfaceController.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedSurfaceController.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.ui.screen.loggedIn.embed import android.os.Build diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedTabLayer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedTabLayer.kt index e1974d6e54..77021fa742 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedTabLayer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/EmbeddedTabLayer.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.ui.screen.loggedIn.embed import android.content.ClipData diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/RemoteImeView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/RemoteImeView.kt index 19fdac7055..2feb4901e8 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/RemoteImeView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/embed/RemoteImeView.kt @@ -153,6 +153,7 @@ class RemoteImeView( fun selectAllText(): Boolean = onTextContextMenuItem(android.R.id.selectAll) /** A page field focused: configure the keyboard, seed the buffer, and raise the IME. */ + @Suppress("DEPRECATION") // InputMethodManager.SHOW_IMPLICIT is deprecated; no equivalent flag on the newer API. fun onPageFocus(focus: ImeEvent.Focus) { configureFor(focus) // Focus the EditText BEFORE seeding text/selection. An EditText jumps its caret to the end when it diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/favorites/EmbeddedNostrAppController.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/favorites/EmbeddedNostrAppController.kt index 8eb3ea1e2a..9e6ea3531c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/favorites/EmbeddedNostrAppController.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/favorites/EmbeddedNostrAppController.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.ui.screen.loggedIn.favorites import android.content.ComponentName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt index 54e211f4db..2d52b3617b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/nip46/Nip46SignerScreen.kt @@ -72,11 +72,10 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.pluralStringResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -87,6 +86,7 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.model.nip46Signer.Nip46ActivityEntry import com.vitorpamplona.amethyst.model.nip46Signer.Nip46SignerState +import com.vitorpamplona.amethyst.ui.components.util.setText import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton @@ -107,7 +107,7 @@ fun Nip46SignerScreen( val signer = account.nip46Signer val scope = rememberCoroutineScope() val context = LocalContext.current - val clipboard = LocalClipboardManager.current + val clipboard = LocalClipboard.current val enabled by account.settings.nip46SignerEnabled.collectAsStateWithLifecycle() val secret by account.settings.nip46BunkerSecret.collectAsStateWithLifecycle() @@ -187,7 +187,7 @@ fun Nip46SignerScreen( QrHeroCard( uri = uri, onCopy = { - clipboard.setText(AnnotatedString(uri)) + scope.launch { clipboard.setText(uri) } Toast.makeText(context, R.string.nip46_signer_copied, Toast.LENGTH_SHORT).show() }, onRegenerate = { confirmRotate = true }, diff --git a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationUtils.kt b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationUtils.kt index fb355c45cf..20a410b170 100644 --- a/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationUtils.kt +++ b/amethyst/src/play/java/com/vitorpamplona/amethyst/service/notifications/PushNotificationUtils.kt @@ -33,6 +33,7 @@ object PushNotificationUtils { var lastToken: String? = null var hasInit: List? = null + @Suppress("DEPRECATION") // FirebaseMessaging.token is deprecated in the current SDK. suspend fun checkAndInit( accounts: List, okHttpClient: (String) -> OkHttpClient, diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt index 6fe7308eff..f37c1b5509 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/Context.kt @@ -300,7 +300,7 @@ class Context( .header("Accept", "application/nostr+json") .build() okhttp.newCall(request).execute().use { resp -> - resp.body?.string()?.let { Nip11RelayInformation.fromJson(it) } + resp.body.string().let { Nip11RelayInformation.fromJson(it) } } }.getOrNull() } diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/BuzzCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/BuzzCommands.kt index 7e3c37b289..60562864dc 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/BuzzCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/BuzzCommands.kt @@ -380,7 +380,7 @@ object BuzzCommands { .get() .build(), ).execute() - .use { it.code to (it.body?.string() ?: "") } + .use { it.code to it.body.string() } } private suspend fun httpPost( @@ -392,7 +392,7 @@ object BuzzCommands { withContext(Dispatchers.IO) { val builder = Request.Builder().url(url).post(body.toRequestBody(jsonMedia)) if (auth != null) builder.header("Authorization", auth) - http.newCall(builder.build()).execute().use { it.code to (it.body?.string() ?: "") } + http.newCall(builder.build()).execute().use { it.code to it.body.string() } } /** `buzz post RELAY GID ` → publishes a kind-40002 stream message with an `h` tag. */ @@ -578,7 +578,7 @@ object BuzzCommands { .groupBy { it.slug() } .values .mapNotNull { versions -> versions.maxByOrNull { it.createdAt } } - .sortedBy { it.personaOrNull()?.displayName ?: it.slug() ?: "" } + .sortedBy { it.personaOrNull()?.displayName ?: it.slug() } .map { val content = it.personaOrNull() mapOf( diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitPatchCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitPatchCommands.kt index 11ac0dd2aa..8dbf63890c 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitPatchCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitPatchCommands.kt @@ -113,7 +113,7 @@ object GitPatchCommands { "event_id" to signed.id, "kind" to signed.kind, "repository" to Address.assemble(addr.kind, addr.pubKeyHex, addr.dTag), - "subject" to (signed as? GitPatchEvent)?.subject(), + "subject" to signed.subject(), ) + RawEventSupport.ackFields(ack), ) return 0 diff --git a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitReadCommands.kt b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitReadCommands.kt index 02e5a6655c..e1c9664660 100644 --- a/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitReadCommands.kt +++ b/cli/src/main/kotlin/com/vitorpamplona/amethyst/cli/commands/GitReadCommands.kt @@ -133,6 +133,7 @@ object GitReadCommands { * comment trees and PR-update (1619) events (which use NIP-22 uppercase `E`) * are out of scope here. */ + @Suppress("DEPRECATION") // legacy kind:1622 GitReplyEvent is read for backward compatibility. suspend fun thread( dataDir: DataDir, rest: Array, diff --git a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt index bc603dacb0..74b279d621 100644 --- a/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt +++ b/commons/src/androidMain/kotlin/com/vitorpamplona/amethyst/commons/keystorage/SecureKeyStorage.kt @@ -64,6 +64,9 @@ actual class SecureKeyStorage private actual constructor() { } } + // androidx.security.crypto is deprecated with no drop-in successor; migrating the + // on-disk key store is a separate, security-sensitive effort. + @Suppress("DEPRECATION") private val masterKey: MasterKey by lazy { MasterKey .Builder(appContext, MasterKey.DEFAULT_MASTER_KEY_ALIAS) @@ -71,6 +74,7 @@ actual class SecureKeyStorage private actual constructor() { .build() } + @Suppress("DEPRECATION") private val encryptedPrefs by lazy { EncryptedSharedPreferences.create( appContext, diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzAgentActivityState.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzAgentActivityState.kt index dd56aa77a8..c31ae3e38c 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzAgentActivityState.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzAgentActivityState.kt @@ -57,7 +57,7 @@ object BuzzAgentActivityState { ) = lock.withLock { val prev = mutableActivity.value[agent] if (prev != null && atSecs <= prev) return@withLock - mutableActivity.value = mutableActivity.value.put(agent, atSecs) + mutableActivity.value = mutableActivity.value.putting(agent, atSecs) } /** Test-only: clears all activity so unit tests don't leak into each other. */ diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzPresenceState.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzPresenceState.kt index dc86b33b31..739532689b 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzPresenceState.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/model/buzz/BuzzPresenceState.kt @@ -65,8 +65,8 @@ object BuzzPresenceState { ) = lock.withLock { val prev = stampByUser[subject] if (prev != null && atSecs <= prev) return@withLock - stampByUser = stampByUser.put(subject, atSecs) - mutablePresence.value = mutablePresence.value.put(subject, status) + stampByUser = stampByUser.putting(subject, atSecs) + mutablePresence.value = mutablePresence.value.putting(subject, status) } /** The latest known status string for [subject], or `null` if none has arrived. */ diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/auth/AuthApprovalRequests.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/auth/AuthApprovalRequests.kt index b13d10c1d8..aafc7c431a 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/auth/AuthApprovalRequests.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/relayClient/auth/AuthApprovalRequests.kt @@ -52,7 +52,7 @@ class AuthApprovalRequests { /** Track a newly surfaced tier-2 challenge. Last write per relay wins. */ fun add(approval: PendingAuthApproval) { - _pending.update { it.put(approval.relayUrl, approval) } + _pending.update { it.putting(approval.relayUrl, approval) } } /** @@ -65,7 +65,7 @@ class AuthApprovalRequests { scope: AuthApprovalScope, ): Boolean { val approval = _pending.value[relayUrl] ?: return false - _pending.update { it.remove(relayUrl) } + _pending.update { it.removing(relayUrl) } return approval.decision.complete(scope) } diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/feeds/DmHistoryLoadingCard.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/feeds/DmHistoryLoadingCard.kt index bc308cc97b..2a606b1c93 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/feeds/DmHistoryLoadingCard.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/feeds/DmHistoryLoadingCard.kt @@ -391,7 +391,7 @@ fun RelayReachDetailDialog( confirmButton = { if (showRetry) { TextButton(onClick = { - onRetry?.invoke() + onRetry() onDismiss() }) { Text(stringResource(Res.string.action_try_again)) } } else { diff --git a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/service/georelay/GeoRelayCsvLoader.kt b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/service/georelay/GeoRelayCsvLoader.kt index 94eda65544..87c27914ea 100644 --- a/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/service/georelay/GeoRelayCsvLoader.kt +++ b/commons/src/jvmAndroid/kotlin/com/vitorpamplona/amethyst/commons/service/georelay/GeoRelayCsvLoader.kt @@ -46,7 +46,7 @@ class GeoRelayCsvLoader( .build() okHttpClient(url).newCall(request).execute().use { response -> if (response.isSuccessful) { - GeoRelayDirectory.parseCsv(response.body?.string().orEmpty()) + GeoRelayDirectory.parseCsv(response.body.string()) } else { emptyList() } diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/ShareMenu.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/ShareMenu.kt index f18a2645d2..701de331e7 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/ShareMenu.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/note/ShareMenu.kt @@ -99,7 +99,7 @@ fun rememberNoteMenuActions( scope.launch { snackbar?.showSnackbar("Broadcast to relays") } }, ) - if (canModerate && account != null) { + if (canModerate) { add( NoteMenuAction("Mute user") { scope.launch { diff --git a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/wallet/WalletColumnScreen.kt b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/wallet/WalletColumnScreen.kt index 3027d35da4..90fd06b871 100644 --- a/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/wallet/WalletColumnScreen.kt +++ b/desktopApp/src/jvmMain/kotlin/com/vitorpamplona/amethyst/desktop/ui/wallet/WalletColumnScreen.kt @@ -275,31 +275,6 @@ fun WalletColumnScreen( if (showReceiveDialog && nwcConnection != null) { ReceiveDialog( onDismiss = { showReceiveDialog = false }, - onGenerate = { amountSats, description -> - scope.launch { - val result = - paymentHandler.makeInvoice( - nwcConnection = nwcConnection, - amountMsats = amountSats * 1000, - description = description.ifBlank { null }, - ) - when (result) { - is NwcPaymentHandler.InvoiceResult.Success -> { - result.invoice - } - - is NwcPaymentHandler.InvoiceResult.Error -> { - snackbarHostState.showSnackbar("Error: ${result.message}") - null - } - - is NwcPaymentHandler.InvoiceResult.Timeout -> { - snackbarHostState.showSnackbar("Invoice request timed out") - null - } - } - } - }, paymentHandler = paymentHandler, nwcConnection = nwcConnection, snackbarHostState = snackbarHostState, @@ -833,7 +808,6 @@ private fun SendDialog( @Composable private fun ReceiveDialog( onDismiss: () -> Unit, - onGenerate: (Long, String) -> Unit, paymentHandler: NwcPaymentHandler, nwcConnection: Nip47URINorm, snackbarHostState: SnackbarHostState, diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt index 8d5cb59f9d..00a86c8969 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserActivity.kt @@ -299,6 +299,7 @@ class NappletBrowserActivity : ComponentActivity() { wv.settings.apply { javaScriptEnabled = true domStorageEnabled = true + @Suppress("DEPRECATION") databaseEnabled = false allowFileAccess = false allowContentAccess = false diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt index 27456bcc10..fea6262e94 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserService.kt @@ -245,6 +245,7 @@ class NappletBrowserService : Service() { } /** Builds the SandboxedUiAdapter for [tab] and ships its cross-process handle (coreLibInfo) to the client. */ + @Suppress("DEPRECATION") // androidx.privacysandbox.ui toCoreLibInfo is deprecated with no successor. private fun replyWithAdapter(tab: BrowserTab) { val adapter = NappletBrowserUiAdapter(this, tab.sessionId) val coreLibInfo = adapter.toCoreLibInfo(this) @@ -306,6 +307,7 @@ class NappletBrowserService : Service() { wv.settings.apply { javaScriptEnabled = true domStorageEnabled = true + @Suppress("DEPRECATION") databaseEnabled = false allowFileAccess = false allowContentAccess = false diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserUiAdapter.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserUiAdapter.kt index bbb2ed68fa..2ffb2b097e 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserUiAdapter.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletBrowserUiAdapter.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.napplethost import android.content.Context diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostActivity.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostActivity.kt index ef27bed471..d061653f72 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostActivity.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostActivity.kt @@ -504,6 +504,7 @@ class NappletHostActivity : ComponentActivity() { // per-applet origin (a napplet.local subdomain) — storage is scoped to that origin, isolated // from other applets and from the shell. SPAs need it at boot; without it they crash-loop. domStorageEnabled = true + @Suppress("DEPRECATION") databaseEnabled = false allowFileAccess = false allowContentAccess = false diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt index 51c8064a3b..ceaf53b6e2 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostService.kt @@ -270,6 +270,7 @@ class NappletHostService : Service() { } /** Builds the SandboxedUiAdapter for [tab] and ships its cross-process handle (coreLibInfo) to the client. */ + @Suppress("DEPRECATION") // androidx.privacysandbox.ui toCoreLibInfo is deprecated with no successor. private fun replyWithAdapter(tab: NappletTab) { val adapter = NappletHostUiAdapter(this, tab.sessionId) val coreLibInfo = adapter.toCoreLibInfo(this) @@ -330,6 +331,7 @@ class NappletHostService : Service() { wv.settings.apply { javaScriptEnabled = true domStorageEnabled = true + @Suppress("DEPRECATION") databaseEnabled = false allowFileAccess = false allowContentAccess = false diff --git a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostUiAdapter.kt b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostUiAdapter.kt index 1fe4c18942..356cb58027 100644 --- a/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostUiAdapter.kt +++ b/nappletHost/src/main/kotlin/com/vitorpamplona/amethyst/napplethost/NappletHostUiAdapter.kt @@ -18,6 +18,8 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +@file:Suppress("DEPRECATION") + package com.vitorpamplona.amethyst.napplethost import android.content.Context diff --git a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nipBEBle/transport/AndroidBleTransport.kt b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nipBEBle/transport/AndroidBleTransport.kt index 40962e564f..5aa3e11e61 100644 --- a/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nipBEBle/transport/AndroidBleTransport.kt +++ b/quartz/src/androidMain/kotlin/com/vitorpamplona/quartz/nipBEBle/transport/AndroidBleTransport.kt @@ -205,6 +205,10 @@ class AndroidBleTransport( readCharacteristic = null } + // The 5-arg connectGatt(context, autoConnect, callback, transport, phy) overload is deprecated + // in favor of the variant that also takes a Handler; keep this one to avoid changing BLE + // callback threading. + @Suppress("DEPRECATION") override fun connectToPeer(peer: BlePeer) { val device = peer.platformHandle as? BluetoothDevice ?: run { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord04Roles/AuthorityResolver.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord04Roles/AuthorityResolver.kt index 04fa0176c2..bff6b54070 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord04Roles/AuthorityResolver.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord04Roles/AuthorityResolver.kt @@ -44,6 +44,7 @@ import com.vitorpamplona.quartz.nip01Core.core.toHexKey * assigned Role and holds [ConcordPermissions.MANAGE_ROLES]. Cycles that never * touch the owner can never bootstrap themselves. */ +@ConsistentCopyVisibility data class AuthorityResolver private constructor( private val ownerLower: String, private val roles: Map, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord05Invites/ConcordInviteLink.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord05Invites/ConcordInviteLink.kt index ef85bd6852..27495bc878 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord05Invites/ConcordInviteLink.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/concord/cord05Invites/ConcordInviteLink.kt @@ -86,7 +86,7 @@ object ConcordInviteLink { if (useStock) { out.add(FLAG_STOCK_RELAYS.toByte()) } else { - require(relays!!.size <= MAX_RELAYS) { "at most $MAX_RELAYS relays, was ${relays.size}" } + require(relays.size <= MAX_RELAYS) { "at most $MAX_RELAYS relays, was ${relays.size}" } out.add(0) out.add(relays.size.toByte()) for (r in relays) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterIndex.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterIndex.kt index bee08fc159..4cd54f7594 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterIndex.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/filters/FilterIndex.kt @@ -210,11 +210,11 @@ class FilterIndex { is AuthorKey -> authors = authors.removeSub(key.author, subscriber) is KindKey -> kinds = kinds.removeSub(key.kind, subscriber) is TagKey -> tags = tags.removeTagSub(key.letter, key.value, subscriber) - Unindexed -> unindexed = unindexed.remove(subscriber) + Unindexed -> unindexed = unindexed.removing(subscriber) } } val next = - State(ids, authors, tags, kinds, unindexed, current.assignments.remove(subscriber)) + State(ids, authors, tags, kinds, unindexed, current.assignments.removing(subscriber)) if (state.compareAndSet(current, next)) return } } @@ -275,12 +275,12 @@ class FilterIndex { is AuthorKey -> authors = authors.addSub(key.author, subscriber) is KindKey -> kinds = kinds.addSub(key.kind, subscriber) is TagKey -> tags = tags.addTagSub(key.letter, key.value, subscriber) - Unindexed -> unindexed = unindexed.add(subscriber) + Unindexed -> unindexed = unindexed.adding(subscriber) } } val existing = current.assignments[subscriber] - val merged = existing?.addAll(keySet) ?: keySet - val next = State(ids, authors, tags, kinds, unindexed, current.assignments.put(subscriber, merged)) + val merged = existing?.addingAll(keySet) ?: keySet + val next = State(ids, authors, tags, kinds, unindexed, current.assignments.putting(subscriber, merged)) if (state.compareAndSet(current, next)) return } } @@ -292,8 +292,8 @@ class FilterIndex { sub: S, ): PersistentMap> { val cur = this[key] ?: persistentHashSetOf() - val next = cur.add(sub) - return if (next === cur) this else put(key, next) + val next = cur.adding(sub) + return if (next === cur) this else putting(key, next) } private fun PersistentMap>.removeSub( @@ -301,11 +301,11 @@ class FilterIndex { sub: S, ): PersistentMap> { val cur = this[key] ?: return this - val next = cur.remove(sub) + val next = cur.removing(sub) return when { next === cur -> this - next.isEmpty() -> remove(key) - else -> put(key, next) + next.isEmpty() -> removing(key) + else -> putting(key, next) } } @@ -316,7 +316,7 @@ class FilterIndex { ): PersistentMap>> { val inner = this[letter] ?: persistentHashMapOf() val newInner = inner.addSub(value, sub) - return if (newInner === inner) this else put(letter, newInner) + return if (newInner === inner) this else putting(letter, newInner) } private fun PersistentMap>>.removeTagSub( @@ -328,8 +328,8 @@ class FilterIndex { val newInner = inner.removeSub(value, sub) return when { newInner === inner -> this - newInner.isEmpty() -> remove(letter) - else -> put(letter, newInner) + newInner.isEmpty() -> removing(letter) + else -> putting(letter, newInner) } }