Merge branch 'vitorpamplona:main' into custom-media-servers
This commit is contained in:
+2
-2
@@ -12,8 +12,8 @@ android {
|
||||
applicationId "com.vitorpamplona.amethyst"
|
||||
minSdk 26
|
||||
targetSdk 34
|
||||
versionCode 377
|
||||
versionName "0.88.0"
|
||||
versionCode 379
|
||||
versionName "0.88.2"
|
||||
buildConfigField "String", "RELEASE_NOTES_ID", "\"2a34cbadd03212c8162e1ff896ba12641821088a2ec8d5e40d54aa80c0510800\""
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
@@ -99,14 +99,7 @@ private object PrefKeys {
|
||||
const val WARN_ABOUT_REPORTS = "warn_about_reports"
|
||||
const val FILTER_SPAM_FROM_STRANGERS = "filter_spam_from_strangers"
|
||||
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 AUTOMATICALLY_SHOW_PROFILE_PICTURE = "automatically_show_profile_picture"
|
||||
const val SIGNER_PACKAGE_NAME = "signer_package_name"
|
||||
const val HAS_DONATED_IN_VERSION = "has_donated_in_version"
|
||||
const val PENDING_ATTESTATIONS = "pending_attestations"
|
||||
@@ -148,7 +141,7 @@ object LocalPreferences {
|
||||
Event.mapper.readValue<List<AccountInfo>>(it)
|
||||
}
|
||||
|
||||
if (newSystemOfAccounts != null && newSystemOfAccounts.isNotEmpty()) {
|
||||
if (!newSystemOfAccounts.isNullOrEmpty()) {
|
||||
savedAccounts = newSystemOfAccounts
|
||||
} else {
|
||||
val oldAccounts = getString(PrefKeys.SAVED_ACCOUNTS, null)?.split(COMMA) ?: listOf()
|
||||
@@ -164,6 +157,8 @@ object LocalPreferences {
|
||||
}
|
||||
|
||||
savedAccounts = migrated
|
||||
|
||||
edit().apply { putString(PrefKeys.ALL_ACCOUNT_INFO, Event.mapper.writeValueAsString(savedAccounts)) }.apply()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -265,9 +260,7 @@ object LocalPreferences {
|
||||
saveToEncryptedStorage(account)
|
||||
}
|
||||
|
||||
fun allSavedAccounts(): List<AccountInfo> {
|
||||
return savedAccounts()
|
||||
}
|
||||
fun allSavedAccounts(): List<AccountInfo> = savedAccounts()
|
||||
|
||||
suspend fun saveToEncryptedStorage(account: Account) {
|
||||
Log.d("LocalPreferences", "Saving to encrypted storage")
|
||||
@@ -345,14 +338,11 @@ object LocalPreferences {
|
||||
PrefKeys.PENDING_ATTESTATIONS,
|
||||
Event.mapper.writeValueAsString(account.pendingAttestations.value),
|
||||
)
|
||||
}
|
||||
.apply()
|
||||
}.apply()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadCurrentAccountFromEncryptedStorage(): Account? {
|
||||
return currentAccount()?.let { loadCurrentAccountFromEncryptedStorage(it) }
|
||||
}
|
||||
suspend fun loadCurrentAccountFromEncryptedStorage(): Account? = currentAccount()?.let { loadCurrentAccountFromEncryptedStorage(it) }
|
||||
|
||||
suspend fun saveSharedSettings(
|
||||
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.EOSEAccount
|
||||
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.Relay
|
||||
import com.vitorpamplona.amethyst.service.relays.TypedFilter
|
||||
@@ -76,8 +77,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
val latestEOSEs = EOSEAccount()
|
||||
val hasLoadedTheBasics = mutableMapOf<User, Boolean>()
|
||||
|
||||
fun createAccountContactListFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountContactListFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -86,10 +87,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
limit = 1,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createAccountMetadataFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountMetadataFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -98,10 +98,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
limit = 1,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createAccountRelayListFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountRelayListFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -110,12 +109,11 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
limit = 10,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createOtherAccountsBaseFilter(): TypedFilter? {
|
||||
if (otherAccounts.isEmpty()) return null
|
||||
return TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
types = EVENT_FINDER_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
kinds =
|
||||
@@ -136,8 +134,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
)
|
||||
}
|
||||
|
||||
fun createAccountSettingsFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountSettingsFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -146,10 +144,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
limit = 100,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createAccountReportsFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountReportsFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -162,10 +159,9 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
?.relayList,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createAccountLastPostsListFilter(): TypedFilter {
|
||||
return TypedFilter(
|
||||
fun createAccountLastPostsListFilter(): TypedFilter =
|
||||
TypedFilter(
|
||||
types = COMMON_FEED_TYPES,
|
||||
filter =
|
||||
JsonFilter(
|
||||
@@ -173,7 +169,6 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
limit = 400,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun createNotificationFilter(): TypedFilter {
|
||||
val since =
|
||||
@@ -404,8 +399,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateChannelFilters() {
|
||||
return if (hasLoadedTheBasics[account.userProfile()] != null) {
|
||||
override fun updateChannelFilters() =
|
||||
if (hasLoadedTheBasics[account.userProfile()] != null) {
|
||||
// gets everything about the user logged in
|
||||
accountChannel.typedFilters =
|
||||
listOfNotNull(
|
||||
@@ -419,8 +414,7 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
createAccountSettingsFilter(),
|
||||
createAccountLastPostsListFilter(),
|
||||
createOtherAccountsBaseFilter(),
|
||||
)
|
||||
.ifEmpty { null }
|
||||
).ifEmpty { null }
|
||||
} else {
|
||||
// just the basics.
|
||||
accountChannel.typedFilters =
|
||||
@@ -429,10 +423,8 @@ object NostrAccountDataSource : NostrDataSource("AccountData") {
|
||||
createAccountContactListFilter(),
|
||||
createAccountRelayListFilter(),
|
||||
createAccountSettingsFilter(),
|
||||
)
|
||||
.ifEmpty { null }
|
||||
).ifEmpty { null }
|
||||
}
|
||||
}
|
||||
|
||||
override fun auth(
|
||||
relay: Relay,
|
||||
|
||||
@@ -96,6 +96,7 @@ object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") {
|
||||
JsonFilter(
|
||||
kinds = listOf(LnZapEvent.KIND),
|
||||
tags = mapOf("p" to listOf(it.pubkeyHex)),
|
||||
limit = 200,
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -178,7 +179,6 @@ object NostrUserProfileDataSource : NostrDataSource("UserProfileFeed") {
|
||||
createAcceptedAwardsFilter(),
|
||||
createReceivedAwardsFilter(),
|
||||
createBookmarksFilter(),
|
||||
)
|
||||
.ifEmpty { null }
|
||||
).ifEmpty { null }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
@@ -112,6 +113,8 @@ fun AllRelayListView(
|
||||
Text(
|
||||
text = stringRes(R.string.relay_settings),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
)
|
||||
|
||||
SaveButton(
|
||||
|
||||
@@ -408,7 +408,15 @@ fun GetMediaItem(
|
||||
authorName: String?,
|
||||
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)
|
||||
|
||||
mediaItem?.let {
|
||||
|
||||
@@ -34,6 +34,8 @@ import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ProgressIndicatorDefaults
|
||||
@@ -1323,16 +1328,25 @@ fun ReactionChoicePopup(
|
||||
offset = IntOffset(0, iconSizePx),
|
||||
onDismissRequest = { onDismiss() },
|
||||
) {
|
||||
FlowRow(horizontalArrangement = Arrangement.Center) {
|
||||
account.reactionChoices.forEach { reactionType ->
|
||||
ActionableReactionButton(
|
||||
baseNote,
|
||||
reactionType,
|
||||
accountViewModel,
|
||||
onDismiss,
|
||||
onChangeAmount,
|
||||
toRemove,
|
||||
)
|
||||
ElevatedCard(
|
||||
Modifier
|
||||
.border(width = 1.dp, color = MaterialTheme.colorScheme.outline, shape = RoundedCornerShape(5.dp)),
|
||||
elevation = CardDefaults.elevatedCardElevation(defaultElevation = 8.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surfaceVariant),
|
||||
) {
|
||||
Box(modifier = Modifier.padding(5.dp)) {
|
||||
FlowRow(horizontalArrangement = Arrangement.Center) {
|
||||
account.reactionChoices.forEach { reactionType ->
|
||||
ActionableReactionButton(
|
||||
baseNote,
|
||||
reactionType,
|
||||
accountViewModel,
|
||||
onDismiss,
|
||||
onChangeAmount,
|
||||
toRemove,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1348,24 +1362,11 @@ private fun ActionableReactionButton(
|
||||
onChangeAmount: () -> Unit,
|
||||
toRemove: ImmutableSet<String>,
|
||||
) {
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
onClick = {
|
||||
accountViewModel.reactToOrDelete(
|
||||
baseNote,
|
||||
reactionType,
|
||||
)
|
||||
onDismiss()
|
||||
},
|
||||
shape = ButtonBorder,
|
||||
colors =
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
) {
|
||||
val thisModifier =
|
||||
remember(reactionType) {
|
||||
Modifier.combinedClickable(
|
||||
val thisModifier =
|
||||
remember(reactionType) {
|
||||
Modifier
|
||||
.padding(horizontal = 3.dp)
|
||||
.combinedClickable(
|
||||
onClick = {
|
||||
accountViewModel.reactToOrDelete(
|
||||
baseNote,
|
||||
@@ -1375,59 +1376,60 @@ private fun ActionableReactionButton(
|
||||
},
|
||||
onLongClick = { onChangeAmount() },
|
||||
)
|
||||
.padding(5.dp)
|
||||
}
|
||||
|
||||
val removeSymbol =
|
||||
remember(reactionType) {
|
||||
if (reactionType in toRemove) {
|
||||
" ✖"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
|
||||
val removeSymbol =
|
||||
remember(reactionType) {
|
||||
if (reactionType in toRemove) {
|
||||
" ✖"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
}
|
||||
if (reactionType.startsWith(":")) {
|
||||
val noStartColon = reactionType.removePrefix(":")
|
||||
val url = noStartColon.substringAfter(":")
|
||||
|
||||
if (reactionType.startsWith(":")) {
|
||||
val noStartColon = reactionType.removePrefix(":")
|
||||
val url = noStartColon.substringAfter(":")
|
||||
|
||||
val renderable =
|
||||
persistentListOf(
|
||||
Nip30CustomEmoji.ImageUrlType(url),
|
||||
Nip30CustomEmoji.TextType(removeSymbol),
|
||||
)
|
||||
|
||||
InLineIconRenderer(
|
||||
renderable,
|
||||
style = SpanStyle(color = Color.White),
|
||||
maxLines = 1,
|
||||
val renderable =
|
||||
persistentListOf(
|
||||
Nip30CustomEmoji.ImageUrlType(url),
|
||||
Nip30CustomEmoji.TextType(removeSymbol),
|
||||
)
|
||||
} else {
|
||||
when (reactionType) {
|
||||
"+" -> {
|
||||
LikedIcon(modifier = thisModifier.size(16.dp), tint = Color.White)
|
||||
|
||||
Text(
|
||||
text = 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,
|
||||
)
|
||||
InLineIconRenderer(
|
||||
renderable,
|
||||
style = SpanStyle(color = Color.White),
|
||||
maxLines = 1,
|
||||
modifier = thisModifier,
|
||||
)
|
||||
} else {
|
||||
when (reactionType) {
|
||||
"+" -> {
|
||||
LikedIcon(modifier = thisModifier.size(16.dp), tint = Color.White)
|
||||
|
||||
Text(
|
||||
text = 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
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
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.rememberLazyListState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.Button
|
||||
@@ -265,15 +268,17 @@ private fun RenderReactionOption(
|
||||
reactionType: String,
|
||||
postViewModel: UpdateReactionTypeViewModel,
|
||||
) {
|
||||
Button(
|
||||
modifier = Modifier.padding(horizontal = 3.dp),
|
||||
shape = ButtonBorder,
|
||||
colors =
|
||||
ButtonDefaults.buttonColors(
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
),
|
||||
onClick = { postViewModel.removeChoice(reactionType) },
|
||||
contentPadding = PaddingValues(horizontal = 5.dp),
|
||||
Box(
|
||||
modifier =
|
||||
Modifier
|
||||
.padding(3.dp)
|
||||
.clickable { postViewModel.removeChoice(reactionType) }
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MaterialTheme.colorScheme.surfaceDim,
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
)
|
||||
.padding(8.dp),
|
||||
) {
|
||||
if (reactionType.startsWith(":")) {
|
||||
val noStartColon = reactionType.removePrefix(":")
|
||||
@@ -287,30 +292,30 @@ private fun RenderReactionOption(
|
||||
|
||||
InLineIconRenderer(
|
||||
renderable,
|
||||
style = SpanStyle(color = Color.White),
|
||||
style = SpanStyle(color = MaterialTheme.colorScheme.onBackground),
|
||||
maxLines = 1,
|
||||
)
|
||||
} else {
|
||||
when (reactionType) {
|
||||
"+" -> {
|
||||
LikedIcon(modifier = Modifier.size(16.dp), tint = Color.White)
|
||||
LikedIcon(modifier = Modifier.size(16.dp), tint = MaterialTheme.colorScheme.onBackground)
|
||||
|
||||
Text(
|
||||
text = " ✖",
|
||||
color = Color.White,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
"-" ->
|
||||
Text(
|
||||
text = "\uD83D\uDC4E ✖",
|
||||
color = Color.White,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
else ->
|
||||
Text(
|
||||
text = "$reactionType ✖",
|
||||
color = Color.White,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<string name="website_url">Dirección web</string>
|
||||
<string name="ln_address">Dirección LN</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="failed_to_save_the_image">Error al guardar la imagen</string>
|
||||
<string name="upload_image">Cargar imagen</string>
|
||||
@@ -407,6 +408,7 @@
|
||||
<string name="languages">Idiomas</string>
|
||||
<string name="tags">Etiquetas</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="subscriptions">Suscripciones</string>
|
||||
<string name="filters">Filtros</string>
|
||||
@@ -449,6 +451,7 @@
|
||||
<string name="connectivity_type_never">Nunca</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_performance">Rendimiento</string>
|
||||
<string name="system">Sistema</string>
|
||||
<string name="light">Claro</string>
|
||||
<string name="dark">Oscuro</string>
|
||||
@@ -500,6 +503,7 @@
|
||||
<string name="load_image_description">Cuándo cargar imágenes</string>
|
||||
<string name="copy_to_clipboard">Copiar 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_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</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_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_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_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>
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<string name="website_url">URL del sitio web</string>
|
||||
<string name="ln_address">Dirección de Lightning</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="failed_to_save_the_image">Error al guardar la imagen</string>
|
||||
<string name="upload_image">Subir imagen</string>
|
||||
@@ -407,6 +408,7 @@
|
||||
<string name="languages">Idiomas</string>
|
||||
<string name="tags">Etiquetas</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="subscriptions">Suscripciones</string>
|
||||
<string name="filters">Filtros</string>
|
||||
@@ -449,6 +451,7 @@
|
||||
<string name="connectivity_type_never">Nunca</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_performance">Rendimiento</string>
|
||||
<string name="system">Sistema</string>
|
||||
<string name="light">Claro</string>
|
||||
<string name="dark">Oscuro</string>
|
||||
@@ -500,6 +503,7 @@
|
||||
<string name="load_image_description">Cuándo cargar imágenes</string>
|
||||
<string name="copy_to_clipboard">Copiar 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_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</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_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_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_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>
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<string name="website_url">URL del sitio web</string>
|
||||
<string name="ln_address">Dirección de Lightning</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="failed_to_save_the_image">Error al guardar la imagen</string>
|
||||
<string name="upload_image">Subir imagen</string>
|
||||
@@ -407,6 +408,7 @@
|
||||
<string name="languages">Idiomas</string>
|
||||
<string name="tags">Etiquetas</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="subscriptions">Suscripciones</string>
|
||||
<string name="filters">Filtros</string>
|
||||
@@ -449,6 +451,7 @@
|
||||
<string name="connectivity_type_never">Nunca</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_performance">Rendimiento</string>
|
||||
<string name="system">Sistema</string>
|
||||
<string name="light">Claro</string>
|
||||
<string name="dark">Oscuro</string>
|
||||
@@ -500,6 +503,7 @@
|
||||
<string name="load_image_description">Cuándo cargar imágenes</string>
|
||||
<string name="copy_to_clipboard">Copiar 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_the_note_id_to_the_clipboard">Copiar ID de la nota al portapapeles</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_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_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_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>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<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_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="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>
|
||||
@@ -451,6 +451,7 @@
|
||||
<string name="connectivity_type_never">Jamais</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_performance">Performance</string>
|
||||
<string name="system">Système</string>
|
||||
<string name="light">Clair</string>
|
||||
<string name="dark">Sombre</string>
|
||||
|
||||
@@ -113,6 +113,7 @@
|
||||
<string name="website_url">Oldalam URL-je</string>
|
||||
<string name="ln_address">LN Cím</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="failed_to_save_the_image">Nem sikerült menteni a képet</string>
|
||||
<string name="upload_image">Kép feltöltése</string>
|
||||
@@ -449,6 +450,7 @@
|
||||
<string name="connectivity_type_never">Soha</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_performance">Teljesítmény-beállítások</string>
|
||||
<string name="system">Rendszer</string>
|
||||
<string name="light">Világos</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="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="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_the_note_id_to_the_clipboard">A bejegyzésazonosító vágólapra másolása</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_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_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_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>
|
||||
|
||||
@@ -451,6 +451,7 @@
|
||||
<string name="connectivity_type_never">Nooit</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_performance">Prestaties</string>
|
||||
<string name="system">Systeem</string>
|
||||
<string name="light">Licht</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_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_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_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>
|
||||
|
||||
+1
-3
@@ -57,9 +57,7 @@ dependencies {
|
||||
implementation 'net.java.dev.jna:jna:5.14.0@aar'
|
||||
|
||||
// Performant Parser of JSONs into Events
|
||||
api(libs.jackson.module.kotlin) {
|
||||
exclude(module: 'byte-buddy') // Workaround https://github.com/FasterXML/jackson-databind/issues/4428 until Jackson 2.17.1
|
||||
}
|
||||
api(libs.jackson.module.kotlin)
|
||||
|
||||
// immutable collections to avoid recomposition
|
||||
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 checkStatus(eventStatus: String?): String? {
|
||||
return if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) {
|
||||
fun checkStatus(eventStatus: String?): String? =
|
||||
if (eventStatus == STATUS_LIVE && createdAt < TimeUtils.eightHoursAgo()) {
|
||||
STATUS_ENDED
|
||||
} else {
|
||||
eventStatus
|
||||
}
|
||||
}
|
||||
|
||||
fun participantsIntersect(keySet: Set<String>): Boolean {
|
||||
return tags.any { it.size > 1 && it[0] == "p" && it[1] in keySet }
|
||||
}
|
||||
fun participantsIntersect(keySet: Set<String>): Boolean = keySet.contains(pubKey) || tags.any { it.size > 1 && it[0] == "p" && it[1] in keySet }
|
||||
|
||||
companion object {
|
||||
const val KIND = 30311
|
||||
|
||||
@@ -55,5 +55,7 @@ object TimeUtils {
|
||||
|
||||
fun oneWeekAgo() = now() - ONE_WEEK
|
||||
|
||||
fun oneMonthAgo() = now() - ONE_MONTH
|
||||
|
||||
fun randomWithTwoDays() = System.currentTimeMillis() / 1000 - CryptoUtils.randomInt(twoDays())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user