Merge branch 'vitorpamplona:main' into custom-media-servers

This commit is contained in:
KotlinGeekDev
2024-06-21 13:55:16 +00:00
committed by GitHub
17 changed files with 181 additions and 147 deletions
+2 -2
View File
@@ -12,8 +12,8 @@ android {
applicationId "com.vitorpamplona.amethyst" applicationId "com.vitorpamplona.amethyst"
minSdk 26 minSdk 26
targetSdk 34 targetSdk 34
versionCode 377 versionCode 379
versionName "0.88.0" versionName "0.88.2"
buildConfigField "String", "RELEASE_NOTES_ID", "\"2a34cbadd03212c8162e1ff896ba12641821088a2ec8d5e40d54aa80c0510800\"" buildConfigField "String", "RELEASE_NOTES_ID", "\"2a34cbadd03212c8162e1ff896ba12641821088a2ec8d5e40d54aa80c0510800\""
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -99,14 +99,7 @@ private object PrefKeys {
const val WARN_ABOUT_REPORTS = "warn_about_reports" const val WARN_ABOUT_REPORTS = "warn_about_reports"
const val FILTER_SPAM_FROM_STRANGERS = "filter_spam_from_strangers" const val FILTER_SPAM_FROM_STRANGERS = "filter_spam_from_strangers"
const val LAST_READ_PER_ROUTE = "last_read_route_per_route" const val LAST_READ_PER_ROUTE = "last_read_route_per_route"
const val AUTOMATICALLY_SHOW_IMAGES = "automatically_show_images"
const val AUTOMATICALLY_START_PLAYBACK = "automatically_start_playback"
const val THEME = "theme"
const val PREFERRED_LANGUAGE = "preferred_Language"
const val AUTOMATICALLY_LOAD_URL_PREVIEW = "automatically_load_url_preview"
const val AUTOMATICALLY_HIDE_NAV_BARS = "automatically_hide_nav_bars"
const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer" const val LOGIN_WITH_EXTERNAL_SIGNER = "login_with_external_signer"
const val AUTOMATICALLY_SHOW_PROFILE_PICTURE = "automatically_show_profile_picture"
const val SIGNER_PACKAGE_NAME = "signer_package_name" const val SIGNER_PACKAGE_NAME = "signer_package_name"
const val HAS_DONATED_IN_VERSION = "has_donated_in_version" const val HAS_DONATED_IN_VERSION = "has_donated_in_version"
const val PENDING_ATTESTATIONS = "pending_attestations" const val PENDING_ATTESTATIONS = "pending_attestations"
@@ -148,7 +141,7 @@ object LocalPreferences {
Event.mapper.readValue<List<AccountInfo>>(it) Event.mapper.readValue<List<AccountInfo>>(it)
} }
if (newSystemOfAccounts != null && newSystemOfAccounts.isNotEmpty()) { if (!newSystemOfAccounts.isNullOrEmpty()) {
savedAccounts = newSystemOfAccounts savedAccounts = newSystemOfAccounts
} else { } else {
val oldAccounts = getString(PrefKeys.SAVED_ACCOUNTS, null)?.split(COMMA) ?: listOf() val oldAccounts = getString(PrefKeys.SAVED_ACCOUNTS, null)?.split(COMMA) ?: listOf()
@@ -164,6 +157,8 @@ object LocalPreferences {
} }
savedAccounts = migrated savedAccounts = migrated
edit().apply { putString(PrefKeys.ALL_ACCOUNT_INFO, Event.mapper.writeValueAsString(savedAccounts)) }.apply()
} }
} }
} }
@@ -265,9 +260,7 @@ object LocalPreferences {
saveToEncryptedStorage(account) saveToEncryptedStorage(account)
} }
fun allSavedAccounts(): List<AccountInfo> { fun allSavedAccounts(): List<AccountInfo> = savedAccounts()
return savedAccounts()
}
suspend fun saveToEncryptedStorage(account: Account) { suspend fun saveToEncryptedStorage(account: Account) {
Log.d("LocalPreferences", "Saving to encrypted storage") Log.d("LocalPreferences", "Saving to encrypted storage")
@@ -345,14 +338,11 @@ object LocalPreferences {
PrefKeys.PENDING_ATTESTATIONS, PrefKeys.PENDING_ATTESTATIONS,
Event.mapper.writeValueAsString(account.pendingAttestations.value), Event.mapper.writeValueAsString(account.pendingAttestations.value),
) )
} }.apply()
.apply()
} }
} }
suspend fun loadCurrentAccountFromEncryptedStorage(): Account? { suspend fun loadCurrentAccountFromEncryptedStorage(): Account? = currentAccount()?.let { loadCurrentAccountFromEncryptedStorage(it) }
return currentAccount()?.let { loadCurrentAccountFromEncryptedStorage(it) }
}
suspend fun saveSharedSettings( suspend fun saveSharedSettings(
sharedSettings: Settings, sharedSettings: Settings,
@@ -27,6 +27,7 @@ import com.vitorpamplona.amethyst.service.relays.COMMON_FEED_TYPES
import com.vitorpamplona.amethyst.service.relays.Client import com.vitorpamplona.amethyst.service.relays.Client
import com.vitorpamplona.amethyst.service.relays.EOSEAccount import com.vitorpamplona.amethyst.service.relays.EOSEAccount
import com.vitorpamplona.amethyst.service.relays.EOSETime import com.vitorpamplona.amethyst.service.relays.EOSETime
import com.vitorpamplona.amethyst.service.relays.EVENT_FINDER_TYPES
import com.vitorpamplona.amethyst.service.relays.JsonFilter import com.vitorpamplona.amethyst.service.relays.JsonFilter
import com.vitorpamplona.amethyst.service.relays.Relay import com.vitorpamplona.amethyst.service.relays.Relay
import com.vitorpamplona.amethyst.service.relays.TypedFilter import com.vitorpamplona.amethyst.service.relays.TypedFilter
@@ -76,8 +77,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
val latestEOSEs = EOSEAccount() val latestEOSEs = EOSEAccount()
val hasLoadedTheBasics = mutableMapOf<User, Boolean>() val hasLoadedTheBasics = mutableMapOf<User, Boolean>()
fun createAccountContactListFilter(): TypedFilter { fun createAccountContactListFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -86,10 +87,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
limit = 1, limit = 1,
), ),
) )
}
fun createAccountMetadataFilter(): TypedFilter { fun createAccountMetadataFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -98,10 +98,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
limit = 1, limit = 1,
), ),
) )
}
fun createAccountRelayListFilter(): TypedFilter { fun createAccountRelayListFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -110,12 +109,11 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
limit = 10, limit = 10,
), ),
) )
}
fun createOtherAccountsBaseFilter(): TypedFilter? { fun createOtherAccountsBaseFilter(): TypedFilter? {
if (otherAccounts.isEmpty()) return null if (otherAccounts.isEmpty()) return null
return TypedFilter( return TypedFilter(
types = COMMON_FEED_TYPES, types = EVENT_FINDER_TYPES,
filter = filter =
JsonFilter( JsonFilter(
kinds = kinds =
@@ -136,8 +134,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
) )
} }
fun createAccountSettingsFilter(): TypedFilter { fun createAccountSettingsFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -146,10 +144,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
limit = 100, limit = 100,
), ),
) )
}
fun createAccountReportsFilter(): TypedFilter { fun createAccountReportsFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -162,10 +159,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
?.relayList, ?.relayList,
), ),
) )
}
fun createAccountLastPostsListFilter(): TypedFilter { fun createAccountLastPostsListFilter(): TypedFilter =
return TypedFilter( TypedFilter(
types = COMMON_FEED_TYPES, types = COMMON_FEED_TYPES,
filter = filter =
JsonFilter( JsonFilter(
@@ -173,7 +169,6 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
limit = 400, limit = 400,
), ),
) )
}
fun createNotificationFilter(): TypedFilter { fun createNotificationFilter(): TypedFilter {
val since = val since =
@@ -404,8 +399,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
} }
} }
override fun updateChannelFilters() { override fun updateChannelFilters() =
return if (hasLoadedTheBasics[account.userProfile()] != null) { if (hasLoadedTheBasics[account.userProfile()] != null) {
// gets everything about the user logged in // gets everything about the user logged in
accountChannel.typedFilters = accountChannel.typedFilters =
listOfNotNull( listOfNotNull(
@@ -419,8 +414,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
createAccountSettingsFilter(), createAccountSettingsFilter(),
createAccountLastPostsListFilter(), createAccountLastPostsListFilter(),
createOtherAccountsBaseFilter(), createOtherAccountsBaseFilter(),
) ).ifEmpty { null }
.ifEmpty { null }
} else { } else {
// just the basics. // just the basics.
accountChannel.typedFilters = accountChannel.typedFilters =
@@ -429,10 +423,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
createAccountContactListFilter(), createAccountContactListFilter(),
createAccountRelayListFilter(), createAccountRelayListFilter(),
createAccountSettingsFilter(), createAccountSettingsFilter(),
) ).ifEmpty { null }
.ifEmpty { null }
} }
}
override fun auth( override fun auth(
relay: Relay, relay: Relay,
@@ -96,6 +96,7 @@ object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") {
JsonFilter( JsonFilter(
kinds = listOf(LnZapEvent.KIND), kinds = listOf(LnZapEvent.KIND),
tags = mapOf("p" to listOf(it.pubkeyHex)), tags = mapOf("p" to listOf(it.pubkeyHex)),
limit = 200,
), ),
) )
} }
@@ -178,7 +179,6 @@ object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") {
createAcceptedAwardsFilter(), createAcceptedAwardsFilter(),
createReceivedAwardsFilter(), createReceivedAwardsFilter(),
createBookmarksFilter(), createBookmarksFilter(),
) ).ifEmpty { null }
.ifEmpty { null }
} }
} }
@@ -40,6 +40,7 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
@@ -112,6 +113,8 @@ fun AllRelayListView(
Text( Text(
text = stringRes(R.string.relay_settings), text = stringRes(R.string.relay_settings),
style = MaterialTheme.typography.titleLarge, style = MaterialTheme.typography.titleLarge,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
) )
SaveButton( SaveButton(
@@ -408,7 +408,15 @@ fun GetMediaItem(
authorName: String?, authorName: String?,
inner: @Composable (State<MediaItem>) -> Unit, inner: @Composable (State<MediaItem>) -> Unit,
) { ) {
val data = remember(videoUri) { MediaItemData(videoUri, title, artworkUri, authorName) } val data =
remember(videoUri) {
MediaItemData(
videoUri = videoUri,
authorName = authorName,
title = title,
artworkUri = artworkUri,
)
}
val mediaItem by produceCachedState(cache = mediaItemCache, key = data) val mediaItem by produceCachedState(cache = mediaItemCache, key = data)
mediaItem?.let { mediaItem?.let {
@@ -34,6 +34,8 @@ import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.animation.togetherWith import androidx.compose.animation.togetherWith
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@@ -47,10 +49,13 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ripple.rememberRipple import androidx.compose.material.ripple.rememberRipple
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.LinearProgressIndicator import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ProgressIndicatorDefaults import androidx.compose.material3.ProgressIndicatorDefaults
@@ -1323,16 +1328,25 @@ fun ReactionChoicePopup(
offset = IntOffset(0, iconSizePx), offset = IntOffset(0, iconSizePx),
onDismissRequest = { onDismiss() }, onDismissRequest = { onDismiss() },
) { ) {
FlowRow(horizontalArrangement = Arrangement.Center) { ElevatedCard(
account.reactionChoices.forEach { reactionType -> Modifier
ActionableReactionButton( .border(width = 1.dp, color = MaterialTheme.colorScheme.outline, shape = RoundedCornerShape(5.dp)),
baseNote, elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp),
reactionType, colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
accountViewModel, ) {
onDismiss, Box(modifier = Modifier.padding(5.dp)) {
onChangeAmount, FlowRow(horizontalArrangement = Arrangement.Center) {
toRemove, account.reactionChoices.forEach { reactionType ->
) ActionableReactionButton(
baseNote,
reactionType,
accountViewModel,
onDismiss,
onChangeAmount,
toRemove,
)
}
}
} }
} }
} }
@@ -1348,24 +1362,11 @@ private fun ActionableReactionButton(
onChangeAmount: () -> Unit, onChangeAmount: () -> Unit,
toRemove: ImmutableSet<String>, toRemove: ImmutableSet<String>,
) { ) {
Button( val thisModifier =
modifier = Modifier.padding(horizontal = 3.dp), remember(reactionType) {
onClick = { Modifier
accountViewModel.reactToOrDelete( .padding(horizontal = 3.dp)
baseNote, .combinedClickable(
reactionType,
)
onDismiss()
},
shape = ButtonBorder,
colors =
ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
),
) {
val thisModifier =
remember(reactionType) {
Modifier.combinedClickable(
onClick = { onClick = {
accountViewModel.reactToOrDelete( accountViewModel.reactToOrDelete(
baseNote, baseNote,
@@ -1375,59 +1376,60 @@ private fun ActionableReactionButton(
}, },
onLongClick = { onChangeAmount() }, onLongClick = { onChangeAmount() },
) )
.padding(5.dp)
}
val removeSymbol =
remember(reactionType) {
if (reactionType in toRemove) {
""
} else {
""
} }
}
val removeSymbol = if (reactionType.startsWith(":")) {
remember(reactionType) { val noStartColon = reactionType.removePrefix(":")
if (reactionType in toRemove) { val url = noStartColon.substringAfter(":")
""
} else {
""
}
}
if (reactionType.startsWith(":")) { val renderable =
val noStartColon = reactionType.removePrefix(":") persistentListOf(
val url = noStartColon.substringAfter(":") Nip30CustomEmoji.ImageUrlType(url),
Nip30CustomEmoji.TextType(removeSymbol),
val renderable =
persistentListOf(
Nip30CustomEmoji.ImageUrlType(url),
Nip30CustomEmoji.TextType(removeSymbol),
)
InLineIconRenderer(
renderable,
style = SpanStyle(color = Color.White),
maxLines = 1,
) )
} else {
when (reactionType) {
"+" -> {
LikedIcon(modifier = thisModifier.size(16.dp), tint = Color.White)
Text( InLineIconRenderer(
text = removeSymbol, renderable,
color = Color.White, style = SpanStyle(color = Color.White),
textAlign = TextAlign.Center, maxLines = 1,
modifier = thisModifier, modifier = thisModifier,
) )
} } else {
"-" -> when (reactionType) {
Text( "+" -> {
text = "\uD83D\uDC4E$removeSymbol", LikedIcon(modifier = thisModifier.size(16.dp), tint = Color.White)
color = Color.White,
textAlign = TextAlign.Center, Text(
modifier = thisModifier, text = removeSymbol,
) color = Color.White,
else -> textAlign = TextAlign.Center,
Text( modifier = thisModifier,
"$reactionType$removeSymbol", )
color = Color.White,
textAlign = TextAlign.Center,
modifier = thisModifier,
)
} }
"-" ->
Text(
text = "\uD83D\uDC4E$removeSymbol",
color = Color.White,
textAlign = TextAlign.Center,
modifier = thisModifier,
)
else ->
Text(
"$reactionType$removeSymbol",
color = Color.White,
textAlign = TextAlign.Center,
modifier = thisModifier,
)
} }
} }
} }
@@ -21,12 +21,14 @@
package com.vitorpamplona.amethyst.ui.note package com.vitorpamplona.amethyst.ui.note
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@@ -38,6 +40,7 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button import androidx.compose.material3.Button
@@ -265,15 +268,17 @@ private fun RenderReactionOption(
reactionType: String, reactionType: String,
postViewModel: UpdateReactionTypeViewModel, postViewModel: UpdateReactionTypeViewModel,
) { ) {
Button( Box(
modifier = Modifier.padding(horizontal = 3.dp), modifier =
shape = ButtonBorder, Modifier
colors = .padding(3.dp)
ButtonDefaults.buttonColors( .clickable { postViewModel.removeChoice(reactionType) }
containerColor = MaterialTheme.colorScheme.primary, .border(
), width = 1.dp,
onClick = { postViewModel.removeChoice(reactionType) }, color = MaterialTheme.colorScheme.surfaceDim,
contentPadding = PaddingValues(horizontal = 5.dp), shape = RoundedCornerShape(8.dp),
)
.padding(8.dp),
) { ) {
if (reactionType.startsWith(":")) { if (reactionType.startsWith(":")) {
val noStartColon = reactionType.removePrefix(":") val noStartColon = reactionType.removePrefix(":")
@@ -287,30 +292,30 @@ private fun RenderReactionOption(
InLineIconRenderer( InLineIconRenderer(
renderable, renderable,
style = SpanStyle(color = Color.White), style = SpanStyle(color = MaterialTheme.colorScheme.onBackground),
maxLines = 1, maxLines = 1,
) )
} else { } else {
when (reactionType) { when (reactionType) {
"+" -> { "+" -> {
LikedIcon(modifier = Modifier.size(16.dp), tint = Color.White) LikedIcon(modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onBackground)
Text( Text(
text = "", text = "",
color = Color.White, color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }
"-" -> "-" ->
Text( Text(
text = "\uD83D\uDC4E", text = "\uD83D\uDC4E",
color = Color.White, color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
else -> else ->
Text( Text(
text = "$reactionType", text = "$reactionType",
color = Color.White, color = MaterialTheme.colorScheme.onBackground,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
) )
} }
@@ -113,6 +113,7 @@
<string name="website_url">Dirección web</string> <string name="website_url">Dirección web</string>
<string name="ln_address">Dirección LN</string> <string name="ln_address">Dirección LN</string>
<string name="ln_url_outdated">Dirección LN (antigua)</string> <string name="ln_url_outdated">Dirección LN (antigua)</string>
<string name="save_to_gallery">Guardar en la galería</string>
<string name="image_saved_to_the_gallery">Imagen guardada en la galería</string> <string name="image_saved_to_the_gallery">Imagen guardada en la galería</string>
<string name="failed_to_save_the_image">Error al guardar la imagen</string> <string name="failed_to_save_the_image">Error al guardar la imagen</string>
<string name="upload_image">Cargar imagen</string> <string name="upload_image">Cargar imagen</string>
@@ -407,6 +408,7 @@
<string name="languages">Idiomas</string> <string name="languages">Idiomas</string>
<string name="tags">Etiquetas</string> <string name="tags">Etiquetas</string>
<string name="posting_policy">Política de publicación</string> <string name="posting_policy">Política de publicación</string>
<string name="relay_error_messages">Errores y avisos de este relé</string>
<string name="message_length">Longitud del mensaje</string> <string name="message_length">Longitud del mensaje</string>
<string name="subscriptions">Suscripciones</string> <string name="subscriptions">Suscripciones</string>
<string name="filters">Filtros</string> <string name="filters">Filtros</string>
@@ -449,6 +451,7 @@
<string name="connectivity_type_never">Nunca</string> <string name="connectivity_type_never">Nunca</string>
<string name="ui_feature_set_type_complete">Completo</string> <string name="ui_feature_set_type_complete">Completo</string>
<string name="ui_feature_set_type_simplified">Simplificado</string> <string name="ui_feature_set_type_simplified">Simplificado</string>
<string name="ui_feature_set_type_performance">Rendimiento</string>
<string name="system">Sistema</string> <string name="system">Sistema</string>
<string name="light">Claro</string> <string name="light">Claro</string>
<string name="dark">Oscuro</string> <string name="dark">Oscuro</string>
@@ -500,6 +503,7 @@
<string name="load_image_description">Cuándo cargar imágenes</string> <string name="load_image_description">Cuándo cargar imágenes</string>
<string name="copy_to_clipboard">Copiar al portapapeles</string> <string name="copy_to_clipboard">Copiar al portapapeles</string>
<string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string> <string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string>
<string name="share_or_save">Compartir o guardar</string>
<string name="copy_url_to_clipboard">Copiar URL al portapapeles</string> <string name="copy_url_to_clipboard">Copiar URL al portapapeles</string>
<string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string> <string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string>
<string name="created_at">Creado</string> <string name="created_at">Creado</string>
@@ -512,6 +516,10 @@
<string name="error_dialog_talk_to_user">Mensaje para el usuario</string> <string name="error_dialog_talk_to_user">Mensaje para el usuario</string>
<string name="error_dialog_button_ok">OK</string> <string name="error_dialog_button_ok">OK</string>
<string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_assemble_url">Error al ensamblar la url NIP-11 para %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_reach_server">No se pudo contactar %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_parse_response">Error al analizar la respuesta de %1$s: %2$s</string>
<string name="relay_information_document_error_failed_with_http">El relé rechazó la solicitud %1$s: %2$s</string>
<string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string> <string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string>
<string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string> <string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string>
@@ -113,6 +113,7 @@
<string name="website_url">URL del sitio web</string> <string name="website_url">URL del sitio web</string>
<string name="ln_address">Dirección de Lightning</string> <string name="ln_address">Dirección de Lightning</string>
<string name="ln_url_outdated">URL de Lightning (obsoleta)</string> <string name="ln_url_outdated">URL de Lightning (obsoleta)</string>
<string name="save_to_gallery">Guardar en la galería</string>
<string name="image_saved_to_the_gallery">Imagen guardada en la galería</string> <string name="image_saved_to_the_gallery">Imagen guardada en la galería</string>
<string name="failed_to_save_the_image">Error al guardar la imagen</string> <string name="failed_to_save_the_image">Error al guardar la imagen</string>
<string name="upload_image">Subir imagen</string> <string name="upload_image">Subir imagen</string>
@@ -407,6 +408,7 @@
<string name="languages">Idiomas</string> <string name="languages">Idiomas</string>
<string name="tags">Etiquetas</string> <string name="tags">Etiquetas</string>
<string name="posting_policy">Política de publicación</string> <string name="posting_policy">Política de publicación</string>
<string name="relay_error_messages">Errores y avisos de este relé</string>
<string name="message_length">Longitud del mensaje</string> <string name="message_length">Longitud del mensaje</string>
<string name="subscriptions">Suscripciones</string> <string name="subscriptions">Suscripciones</string>
<string name="filters">Filtros</string> <string name="filters">Filtros</string>
@@ -449,6 +451,7 @@
<string name="connectivity_type_never">Nunca</string> <string name="connectivity_type_never">Nunca</string>
<string name="ui_feature_set_type_complete">Completo</string> <string name="ui_feature_set_type_complete">Completo</string>
<string name="ui_feature_set_type_simplified">Simplificado</string> <string name="ui_feature_set_type_simplified">Simplificado</string>
<string name="ui_feature_set_type_performance">Rendimiento</string>
<string name="system">Sistema</string> <string name="system">Sistema</string>
<string name="light">Claro</string> <string name="light">Claro</string>
<string name="dark">Oscuro</string> <string name="dark">Oscuro</string>
@@ -500,6 +503,7 @@
<string name="load_image_description">Cuándo cargar imágenes</string> <string name="load_image_description">Cuándo cargar imágenes</string>
<string name="copy_to_clipboard">Copiar al portapapeles</string> <string name="copy_to_clipboard">Copiar al portapapeles</string>
<string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string> <string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string>
<string name="share_or_save">Compartir o guardar</string>
<string name="copy_url_to_clipboard">Copiar URL al portapapeles</string> <string name="copy_url_to_clipboard">Copiar URL al portapapeles</string>
<string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string> <string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string>
<string name="created_at">Creado</string> <string name="created_at">Creado</string>
@@ -512,6 +516,10 @@
<string name="error_dialog_talk_to_user">Mensaje para el usuario</string> <string name="error_dialog_talk_to_user">Mensaje para el usuario</string>
<string name="error_dialog_button_ok">OK</string> <string name="error_dialog_button_ok">OK</string>
<string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_assemble_url">Error al ensamblar la url NIP-11 para %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_reach_server">No se pudo contactar %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_parse_response">Error al analizar la respuesta de %1$s: %2$s</string>
<string name="relay_information_document_error_failed_with_http">El relé rechazó la solicitud %1$s: %2$s</string>
<string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string> <string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string>
<string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string> <string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string>
@@ -113,6 +113,7 @@
<string name="website_url">URL del sitio web</string> <string name="website_url">URL del sitio web</string>
<string name="ln_address">Dirección de Lightning</string> <string name="ln_address">Dirección de Lightning</string>
<string name="ln_url_outdated">URL de Lightning (obsoleta)</string> <string name="ln_url_outdated">URL de Lightning (obsoleta)</string>
<string name="save_to_gallery">Guardar en la galería</string>
<string name="image_saved_to_the_gallery">Imagen guardada en la galería</string> <string name="image_saved_to_the_gallery">Imagen guardada en la galería</string>
<string name="failed_to_save_the_image">Error al guardar la imagen</string> <string name="failed_to_save_the_image">Error al guardar la imagen</string>
<string name="upload_image">Subir imagen</string> <string name="upload_image">Subir imagen</string>
@@ -407,6 +408,7 @@
<string name="languages">Idiomas</string> <string name="languages">Idiomas</string>
<string name="tags">Etiquetas</string> <string name="tags">Etiquetas</string>
<string name="posting_policy">Política de publicación</string> <string name="posting_policy">Política de publicación</string>
<string name="relay_error_messages">Errores y avisos de este relé</string>
<string name="message_length">Longitud del mensaje</string> <string name="message_length">Longitud del mensaje</string>
<string name="subscriptions">Suscripciones</string> <string name="subscriptions">Suscripciones</string>
<string name="filters">Filtros</string> <string name="filters">Filtros</string>
@@ -449,6 +451,7 @@
<string name="connectivity_type_never">Nunca</string> <string name="connectivity_type_never">Nunca</string>
<string name="ui_feature_set_type_complete">Completo</string> <string name="ui_feature_set_type_complete">Completo</string>
<string name="ui_feature_set_type_simplified">Simplificado</string> <string name="ui_feature_set_type_simplified">Simplificado</string>
<string name="ui_feature_set_type_performance">Rendimiento</string>
<string name="system">Sistema</string> <string name="system">Sistema</string>
<string name="light">Claro</string> <string name="light">Claro</string>
<string name="dark">Oscuro</string> <string name="dark">Oscuro</string>
@@ -500,6 +503,7 @@
<string name="load_image_description">Cuándo cargar imágenes</string> <string name="load_image_description">Cuándo cargar imágenes</string>
<string name="copy_to_clipboard">Copiar al portapapeles</string> <string name="copy_to_clipboard">Copiar al portapapeles</string>
<string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string> <string name="copy_npub_to_clipboard">Copiar npub al portapapeles</string>
<string name="share_or_save">Compartir o guardar</string>
<string name="copy_url_to_clipboard">Copiar URL al portapapeles</string> <string name="copy_url_to_clipboard">Copiar URL al portapapeles</string>
<string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string> <string name="copy_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</string>
<string name="created_at">Creado</string> <string name="created_at">Creado</string>
@@ -512,6 +516,10 @@
<string name="error_dialog_talk_to_user">Mensaje para el usuario</string> <string name="error_dialog_talk_to_user">Mensaje para el usuario</string>
<string name="error_dialog_button_ok">OK</string> <string name="error_dialog_button_ok">OK</string>
<string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_assemble_url">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_assemble_url">Error al ensamblar la url NIP-11 para %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_reach_server">No se pudo contactar %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_parse_response">Error al analizar la respuesta de %1$s: %2$s</string>
<string name="relay_information_document_error_failed_with_http">El relé rechazó la solicitud %1$s: %2$s</string>
<string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string> <string name="relay_information_document_error_reach_server">No se pudo llegar a %1$s: %2$s</string>
<string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string> <string name="relay_information_document_error_parse_result">Error al analizar el resultado de %1$s: %2$s</string>
<string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string> <string name="relay_information_document_error_http_status">%1$s falló con el código %2$s</string>
+2 -1
View File
@@ -8,7 +8,7 @@
<string name="show_anyway">Montrer quand même</string> <string name="show_anyway">Montrer quand même</string>
<string name="post_was_hidden">Ce message a été masqué car il mentionne vos utilisateurs ou mots cachés</string> <string name="post_was_hidden">Ce message a été masqué car il mentionne vos utilisateurs ou mots cachés</string>
<string name="post_was_flagged_as_inappropriate_by">Post signalé inapproprié par</string> <string name="post_was_flagged_as_inappropriate_by">Post signalé inapproprié par</string>
<string name="post_not_found">Post non trouvé</string> <string name="post_not_found">L\'événement est en cours de chargement ou ne peut pas être trouvé dans votre liste de relais</string>
<string name="channel_image">Image du canal</string> <string name="channel_image">Image du canal</string>
<string name="referenced_event_not_found">référence de l\'évènement non trouvée</string> <string name="referenced_event_not_found">référence de l\'évènement non trouvée</string>
<string name="could_not_decrypt_the_message">Impossible de déchiffrer le message</string> <string name="could_not_decrypt_the_message">Impossible de déchiffrer le message</string>
@@ -451,6 +451,7 @@
<string name="connectivity_type_never">Jamais</string> <string name="connectivity_type_never">Jamais</string>
<string name="ui_feature_set_type_complete">Complet</string> <string name="ui_feature_set_type_complete">Complet</string>
<string name="ui_feature_set_type_simplified">Simplifié</string> <string name="ui_feature_set_type_simplified">Simplifié</string>
<string name="ui_feature_set_type_performance">Performance</string>
<string name="system">Système</string> <string name="system">Système</string>
<string name="light">Clair</string> <string name="light">Clair</string>
<string name="dark">Sombre</string> <string name="dark">Sombre</string>
+7
View File
@@ -113,6 +113,7 @@
<string name="website_url">Oldalam URL-je</string> <string name="website_url">Oldalam URL-je</string>
<string name="ln_address">LN Cím</string> <string name="ln_address">LN Cím</string>
<string name="ln_url_outdated">LN URL (elavult)</string> <string name="ln_url_outdated">LN URL (elavult)</string>
<string name="save_to_gallery">Mentés a galériába</string>
<string name="image_saved_to_the_gallery">A kép a galériába mentve</string> <string name="image_saved_to_the_gallery">A kép a galériába mentve</string>
<string name="failed_to_save_the_image">Nem sikerült menteni a képet</string> <string name="failed_to_save_the_image">Nem sikerült menteni a képet</string>
<string name="upload_image">Kép feltöltése</string> <string name="upload_image">Kép feltöltése</string>
@@ -449,6 +450,7 @@
<string name="connectivity_type_never">Soha</string> <string name="connectivity_type_never">Soha</string>
<string name="ui_feature_set_type_complete">Teljes</string> <string name="ui_feature_set_type_complete">Teljes</string>
<string name="ui_feature_set_type_simplified">Egyszerűsített</string> <string name="ui_feature_set_type_simplified">Egyszerűsített</string>
<string name="ui_feature_set_type_performance">Teljesítmény-beállítások</string>
<string name="system">Rendszer</string> <string name="system">Rendszer</string>
<string name="light">Világos</string> <string name="light">Világos</string>
<string name="dark">Sötét</string> <string name="dark">Sötét</string>
@@ -500,6 +502,7 @@
<string name="load_image_description">Mikor kell a képeket betölteni</string> <string name="load_image_description">Mikor kell a képeket betölteni</string>
<string name="copy_to_clipboard">Másolás a vágólapra</string> <string name="copy_to_clipboard">Másolás a vágólapra</string>
<string name="copy_npub_to_clipboard">Npub másolása a vágólapra</string> <string name="copy_npub_to_clipboard">Npub másolása a vágólapra</string>
<string name="share_or_save">Megosztás vagy Mentés</string>
<string name="copy_url_to_clipboard">Az URL vágólapra másolása</string> <string name="copy_url_to_clipboard">Az URL vágólapra másolása</string>
<string name="copy_the_note_id_to_the_clipboard">A bejegyzésazonosító vágólapra másolása</string> <string name="copy_the_note_id_to_the_clipboard">A bejegyzésazonosító vágólapra másolása</string>
<string name="created_at">Létrehozva</string> <string name="created_at">Létrehozva</string>
@@ -512,6 +515,10 @@
<string name="error_dialog_talk_to_user">Üzenet a Felhasználónak</string> <string name="error_dialog_talk_to_user">Üzenet a Felhasználónak</string>
<string name="error_dialog_button_ok">Ok</string> <string name="error_dialog_button_ok">Ok</string>
<string name="relay_information_document_error_assemble_url">Nem sikerült elérni %1$s: %2$s</string> <string name="relay_information_document_error_assemble_url">Nem sikerült elérni %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_assemble_url">Nem sikerült összeállítani a NIP-11 URL-t a következőhöz: %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_reach_server">Nem sikerült elérni %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_parse_response">Nem sikerült a válasz elemzése a %1$s: %2$s</string>
<string name="relay_information_document_error_failed_with_http">A csomópont elutasította a(z) %1$s kérést: %2$s</string>
<string name="relay_information_document_error_reach_server">Nem sikerült elérni %1$s: %2$s</string> <string name="relay_information_document_error_reach_server">Nem sikerült elérni %1$s: %2$s</string>
<string name="relay_information_document_error_parse_result">Nem sikerült az eredmény elemzése a %1$s: %2$s</string> <string name="relay_information_document_error_parse_result">Nem sikerült az eredmény elemzése a %1$s: %2$s</string>
<string name="relay_information_document_error_http_status">%1$s hiba a következő kóddal %2$s</string> <string name="relay_information_document_error_http_status">%1$s hiba a következő kóddal %2$s</string>
+5
View File
@@ -451,6 +451,7 @@
<string name="connectivity_type_never">Nooit</string> <string name="connectivity_type_never">Nooit</string>
<string name="ui_feature_set_type_complete">Voltooid</string> <string name="ui_feature_set_type_complete">Voltooid</string>
<string name="ui_feature_set_type_simplified">Vereenvoudigd</string> <string name="ui_feature_set_type_simplified">Vereenvoudigd</string>
<string name="ui_feature_set_type_performance">Prestaties</string>
<string name="system">Systeem</string> <string name="system">Systeem</string>
<string name="light">Licht</string> <string name="light">Licht</string>
<string name="dark">Donker</string> <string name="dark">Donker</string>
@@ -515,6 +516,10 @@
<string name="error_dialog_talk_to_user">Bericht de gebruiker</string> <string name="error_dialog_talk_to_user">Bericht de gebruiker</string>
<string name="error_dialog_button_ok">Ok</string> <string name="error_dialog_button_ok">Ok</string>
<string name="relay_information_document_error_assemble_url">Mislukt om %1$s te bereiken: %2$s</string> <string name="relay_information_document_error_assemble_url">Mislukt om %1$s te bereiken: %2$s</string>
<string name="relay_information_document_error_failed_to_assemble_url">Fout bij het verzamelen van de NIP-11 url voor %1$s: %2$s</string>
<string name="relay_information_document_error_failed_to_reach_server">Mislukt om %1$s te bereiken: %2$s</string>
<string name="relay_information_document_error_failed_to_parse_response">Mislukt om het resultaat van %1$s te parsen: %2$s</string>
<string name="relay_information_document_error_failed_with_http">Relay wijst aanvraag %1$s af: %2$s</string>
<string name="relay_information_document_error_reach_server">Mislukt om %1$s te bereiken: %2$s</string> <string name="relay_information_document_error_reach_server">Mislukt om %1$s te bereiken: %2$s</string>
<string name="relay_information_document_error_parse_result">Mislukt om het resultaat van %1$s te parsen: %2$s</string> <string name="relay_information_document_error_parse_result">Mislukt om het resultaat van %1$s te parsen: %2$s</string>
<string name="relay_information_document_error_http_status">%1$s mislukt met code %2$s</string> <string name="relay_information_document_error_http_status">%1$s mislukt met code %2$s</string>
+1 -3
View File
@@ -57,9 +57,7 @@ dependencies {
implementation 'net.java.dev.jna:jna:5.14.0@aar' implementation 'net.java.dev.jna:jna:5.14.0@aar'
// Performant Parser of JSONs into Events // Performant Parser of JSONs into Events
api(libs.jackson.module.kotlin) { api(libs.jackson.module.kotlin)
exclude(module: 'byte-buddy') // Workaround https://github.com/FasterXML/jackson-databind/issues/4428 until Jackson 2.17.1
}
// immutable collections to avoid recomposition // immutable collections to avoid recomposition
api libs.kotlinx.collections.immutable api libs.kotlinx.collections.immutable
@@ -60,17 +60,14 @@ class LiveActivitiesEvent(
fun hosts() = tags.filter { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }.map { it[1] } fun hosts() = tags.filter { it.size > 3 && it[0] == "p" && it[3].equals("Host", true) }.map { it[1] }
fun checkStatus(eventStatus: String?): String? { fun checkStatus(eventStatus: String?): String? =
return if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) { if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) {
STATUS_ENDED STATUS_ENDED
} else { } else {
eventStatus eventStatus
} }
}
fun participantsIntersect(keySet: Set<String>): Boolean { fun participantsIntersect(keySet: Set<String>): Boolean = keySet.contains(pubKey) || tags.any { it.size > 1 && it[0] == "p" && it[1] in keySet }
return tags.any { it.size > 1 && it[0] == "p" && it[1] in keySet }
}
companion object { companion object {
const val KIND = 30311 const val KIND = 30311
@@ -55,5 +55,7 @@ object TimeUtils {
fun oneWeekAgo() = now() - ONE_WEEK fun oneWeekAgo() = now() - ONE_WEEK
fun oneMonthAgo() = now() - ONE_MONTH
fun randomWithTwoDays() = System.currentTimeMillis() / 1000 - CryptoUtils.randomInt(twoDays()) fun randomWithTwoDays() = System.currentTimeMillis() / 1000 - CryptoUtils.randomInt(twoDays())
} }