diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 992f7c726..131c7b226 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -39,7 +39,7 @@ jobs: keyPassword: ${{ secrets.KEY_PASSWORD }} env: # override default build-tools version (29.0.3) -- optional - BUILD_TOOLS_VERSION: "34.0.0" + BUILD_TOOLS_VERSION: "36.0.0" - name: Sign AAB (F-Droid) uses: r0adkll/sign-android-release@v1 @@ -51,7 +51,7 @@ jobs: keyPassword: ${{ secrets.KEY_PASSWORD }} env: # override default build-tools version (29.0.3) -- optional - BUILD_TOOLS_VERSION: "34.0.0" + BUILD_TOOLS_VERSION: "36.0.0" - name: Build APK run: ./gradlew assembleRelease --stacktrace @@ -66,7 +66,7 @@ jobs: keyPassword: ${{ secrets.KEY_PASSWORD }} env: # override default build-tools version (29.0.3) -- optional - BUILD_TOOLS_VERSION: "34.0.0" + BUILD_TOOLS_VERSION: "36.0.0" - name: Sign APK (F-Droid) uses: r0adkll/sign-android-release@v1 @@ -78,7 +78,7 @@ jobs: keyPassword: ${{ secrets.KEY_PASSWORD }} env: # override default build-tools version (29.0.3) -- optional - BUILD_TOOLS_VERSION: "34.0.0" + BUILD_TOOLS_VERSION: "36.0.0" - name: Create Release id: create_release diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index ff8a4e7df..94c476b8a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -1375,7 +1375,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeAndUpdateIndexes(it, relay, false) + checkDeletionAndConsume(it, relay, false) } refreshNewNoteObservers(note) @@ -1405,7 +1405,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeAndUpdateIndexes(it, relay, false) + checkDeletionAndConsume(it, relay, false) } refreshNewNoteObservers(note) @@ -1440,7 +1440,7 @@ object LocalCache : ILocalCache { repliesTo.forEach { it.addBoost(note) } event.containedPost()?.let { - justConsumeAndUpdateIndexes(it, relay, false) + checkDeletionAndConsume(it, relay, false) } refreshNewNoteObservers(note) @@ -1683,7 +1683,7 @@ object LocalCache : ILocalCache { if (existingZapRequest == null || existingZapRequest.event == null) { // tries to add it event.zapRequest?.let { - justConsumeAndUpdateIndexes(it, relay, false) + checkDeletionAndConsume(it, relay, false) } } @@ -2552,21 +2552,7 @@ object LocalCache : ILocalCache { event: DraftEvent, relay: NormalizedRelayUrl?, wasVerified: Boolean, - ): Boolean { - if (!event.isDeleted()) { - if (consumeBaseReplaceable(event, relay, wasVerified)) { - return true - } - } else { - // passes to the AccountViewModel for further delete. - val note = Note(event.id) - note.loadEvent(event, getOrCreateUser(event.pubKey), emptyList()) - relay?.let { note.addRelay(it) } - refreshNewNoteObservers(note) - } - - return false - } + ): Boolean = !event.isDeleted() && consumeBaseReplaceable(event, relay, wasVerified) fun consume(nip19: Entity) { when (nip19) { @@ -2647,6 +2633,17 @@ object LocalCache : ILocalCache { return justConsumeAndUpdateIndexes(event, relay?.url, wasVerified) } + private fun checkDeletionAndConsume( + event: Event, + relay: NormalizedRelayUrl?, + wasVerified: Boolean, + ): Boolean = + if (!deletionIndex.hasBeenDeleted(event)) { + justConsumeAndUpdateIndexes(event, relay, wasVerified) + } else { + false + } + private fun justConsumeAndUpdateIndexes( event: Event, relay: NormalizedRelayUrl?, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt index 9fe8e2c36..3e6cb052b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/AppNavigation.kt @@ -179,8 +179,9 @@ fun AppNavigation( composableFromBottomArgs { NewPublicMessageScreen( to = it.toKey(), - accountViewModel, - nav, + reply = it.replyId?.let { hex -> accountViewModel.getNoteIfExists(hex) }, + accountViewModel = accountViewModel, + nav = nav, ) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt index a51df6440..292541708 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/RouteMaker.kt @@ -201,7 +201,11 @@ fun routeReplyTo( ): Route? { val noteEvent = note.event return when (noteEvent) { - is PublicMessageEvent -> Route.NewPublicMessage(noteEvent.groupKeySet() - account.userProfile().pubkeyHex) + is PublicMessageEvent -> + Route.NewPublicMessage( + users = noteEvent.groupKeySet() - account.userProfile().pubkeyHex, + parentId = noteEvent.id, + ) is TextNoteEvent -> Route.NewPost(baseReplyTo = note.idHex) is PrivateDmEvent -> routeToMessage( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt index 5aa91270f..f7fd7ea07 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/routes/Routes.kt @@ -142,9 +142,11 @@ sealed class Route { @Serializable data class NewPublicMessage( val to: String, + val replyId: HexKey? = null, ) : Route() { - constructor(users: Set) : this( + constructor(users: Set, parentId: HexKey) : this( to = users.joinToString(","), + replyId = parentId, ) fun toKey(): Set = to.split(",").toSet() @@ -253,6 +255,7 @@ fun getRouteWithArguments(navController: NavHostController): Route? { dest.hasRoute() -> entry.toRoute() dest.hasRoute() -> entry.toRoute() dest.hasRoute() -> entry.toRoute() + dest.hasRoute() -> entry.toRoute() else -> { null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 8c8576e6d..78a86633a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -399,17 +399,17 @@ fun calculateBackgroundColor( newItemColor.compositeOver(defaultBackgroundColor) } } else { - parentBackgroundColor?.value ?: Color.Transparent + parentBackgroundColor?.value ?: defaultBackgroundColor.copy(alpha = 0f) } } else { - parentBackgroundColor?.value ?: Color.Transparent + parentBackgroundColor?.value ?: defaultBackgroundColor.copy(alpha = 0f) }, ) } LaunchedEffect(createdAt) { delay(5000) - bgColor.value = parentBackgroundColor?.value ?: Color.Transparent + bgColor.value = parentBackgroundColor?.value ?: defaultBackgroundColor.copy(alpha = 0f) } return bgColor diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt index 2ff50fbc2..d3f432cf3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayUncitedHashtags.kt @@ -29,6 +29,7 @@ import androidx.compose.runtime.produceState import com.vitorpamplona.amethyst.commons.richtext.HashTagSegment import com.vitorpamplona.amethyst.service.CachedRichTextParser import com.vitorpamplona.amethyst.ui.components.ClickableTextColor +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav.nav import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -37,8 +38,6 @@ import com.vitorpamplona.amethyst.ui.theme.lessImportantLink import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hashtags import com.vitorpamplona.quartz.nip02FollowList.toImmutableListOfLists -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch @Composable fun DisplayUncitedHashtags( @@ -59,37 +58,34 @@ fun DisplayUncitedHashtags( accountViewModel: AccountViewModel, nav: INav, ) { - @Suppress("ProduceStateDoesNotAssignValue") val unusedHashtags by produceState(initialValue = emptyList()) { val tagsInEvent = event.hashtags() if (tagsInEvent.isNotEmpty()) { - launch(Dispatchers.Default) { - val state = CachedRichTextParser.parseText(content, event.tags.toImmutableListOfLists(), callbackUri) + val state = CachedRichTextParser.parseText(content, event.tags.toImmutableListOfLists(), callbackUri) - val tagsInContent = - state - .paragraphs - .map { - it.words.mapNotNull { - if (it is HashTagSegment) { - it.hashtag - } else { - null - } + val tagsInContent = + state + .paragraphs + .map { + it.words.mapNotNull { + if (it is HashTagSegment) { + it.hashtag + } else { + null } - }.flatten() - - val unusedHashtags = - tagsInEvent.filterNot { eventTag -> - tagsInContent.any { contentTag -> - eventTag.equals(contentTag, true) } - } + }.flatten() - if (unusedHashtags.isNotEmpty()) { - value = unusedHashtags + val unusedHashtags = + tagsInEvent.filterNot { eventTag -> + tagsInContent.any { contentTag -> + eventTag.equals(contentTag, true) + } } + + if (unusedHashtags.isNotEmpty()) { + value = unusedHashtags } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicMessage.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicMessage.kt index 69dd2052c..a8bb45c9d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicMessage.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/PublicMessage.kt @@ -20,22 +20,29 @@ */ package com.vitorpamplona.amethyst.ui.note.types +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.getValue +import androidx.compose.runtime.produceState import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextOverflow import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.model.User +import com.vitorpamplona.amethyst.ui.components.RenderUserAsClickableText import com.vitorpamplona.amethyst.ui.components.SensitivityWarning import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav.nav import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.elements.DisplayUncitedHashtags import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.theme.HalfHalfTopPadding import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.nip01Core.tags.hashtags.hasHashtags @@ -52,10 +59,11 @@ fun RenderPublicMessage( nav: INav, ) { val noteEvent = note.event as? PublicMessageEvent ?: return + val content = remember(noteEvent) { noteEvent.peopleAndContent() } if (makeItShort && accountViewModel.isLoggedUser(note.author)) { Text( - text = noteEvent.content, + text = content, color = MaterialTheme.colorScheme.placeholderText, maxLines = 2, overflow = TextOverflow.Ellipsis, @@ -68,7 +76,7 @@ fun RenderPublicMessage( accountViewModel = accountViewModel, ) { TranslatableRichTextViewer( - content = noteEvent.content, + content = content, canPreview = canPreview && !makeItShort, quotesLeft = quotesLeft, modifier = Modifier.fillMaxWidth(), @@ -86,3 +94,31 @@ fun RenderPublicMessage( } } } + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun DisplayUncitedUsers( + event: PublicMessageEvent, + accountViewModel: AccountViewModel, + nav: INav, +) { + @Suppress("ProduceStateDoesNotAssignValue") + val uncitedUsers by produceState(initialValue = emptyList()) { + val users = event.groupKeySetWithoutOwner() - event.citedUsers() + if (users.isNotEmpty()) { + val newUsers = accountViewModel.loadUsersSync(users.toList()) + + if (newUsers.isNotEmpty()) { + value = newUsers + } + } + } + + if (uncitedUsers.isNotEmpty()) { + FlowRow(HalfHalfTopPadding) { + uncitedUsers.forEach { user -> + RenderUserAsClickableText(user, "", accountViewModel, nav) + } + } + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt index 49867e15e..8226daeda 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/types/Text.kt @@ -53,6 +53,7 @@ import com.vitorpamplona.quartz.nip10Notes.BaseThreadedEvent import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip14Subject.subject import com.vitorpamplona.quartz.nip72ModCommunities.definition.CommunityDefinitionEvent +import org.apache.commons.lang3.StringUtils.startsWith @Composable fun RenderTextEvent( @@ -118,7 +119,7 @@ fun RenderTextEvent( } val eventContent = - if (!subject.isNullOrBlank() && !newBody.split("\n")[0].startsWith(subject)) { + if (!subject.isNullOrBlank() && !newBody.startsWith(subject)) { "### $subject\n$newBody" } else { newBody diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt index 4a7d181be..539483d1e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/AccountViewModel.kt @@ -1249,7 +1249,7 @@ class AccountViewModel( if (isDebug) { Log.d( "Rendering Metrics", - "Update feeds ${this@AccountViewModel} for ${account.userProfile().toBestDisplayName()} with ${newNotes.size} new notes", + "Delete feeds ${this@AccountViewModel} for ${account.userProfile().toBestDisplayName()} with ${newNotes.size} new notes", ) } logTime("AccountViewModel deletedEventBundle Update with ${newNotes.size} new notes") { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/ChatroomView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/ChatroomView.kt index a5f198c9a..ec87784ec 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/ChatroomView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/ChatroomView.kt @@ -91,11 +91,7 @@ fun ChatroomView( if (room.users.size == 1) { // Activates NIP-17 if the user has DM relays ObserveRelayListForDMs(pubkey = room.users.first(), accountViewModel = accountViewModel) { - if (it?.relays().isNullOrEmpty()) { - newPostModel.nip17 = false - } else { - newPostModel.nip17 = true - } + newPostModel.nip17 = !it?.relays().isNullOrEmpty() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt index 0b079e56d..4d785f670 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/privateDM/send/NewGroupDMScreen.kt @@ -315,6 +315,7 @@ fun GroupDMScreenContent( fun MessageFieldRow( postViewModel: IMessageField, accountViewModel: AccountViewModel, + requestFocus: Boolean = false, ) { Row { BaseUserPicture( @@ -322,7 +323,7 @@ fun MessageFieldRow( Size35dp, accountViewModel, ) - MessageField(R.string.write_a_message, postViewModel, false) + MessageField(R.string.write_a_message, postViewModel, requestFocus) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeConversationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeConversationsFeedFilter.kt index babb01e4d..441404d44 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeConversationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeConversationsFeedFilter.kt @@ -28,6 +28,7 @@ import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthors import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder import com.vitorpamplona.amethyst.ui.dal.FilterByListParams +import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent @@ -81,6 +82,7 @@ class HomeConversationsFeedFilter( event is ChannelMessageEvent || event is CommentEvent || event is VoiceReplyEvent || + event is PublicMessageEvent || event is LiveActivitiesChatMessageEvent ) && filterParams.match(event) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeNewThreadFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeNewThreadFeedFilter.kt index 534697268..1f9b199ee 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeNewThreadFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/home/dal/HomeNewThreadFeedFilter.kt @@ -31,7 +31,6 @@ import com.vitorpamplona.amethyst.ui.dal.FilterByListParams import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent -import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent @@ -99,7 +98,6 @@ class HomeNewThreadFeedFilter( (noteEvent is WikiNoteEvent && noteEvent.content.isNotEmpty()) || noteEvent is PollNoteEvent || noteEvent is HighlightEvent || - (noteEvent is PublicMessageEvent && noteEvent.content.isNotEmpty() && noteEvent.isIncluded(account.signer.pubKey)) || noteEvent is InteractiveStoryPrologueEvent || noteEvent is CommentEvent || noteEvent is AudioTrackEvent || diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt index f8279cc1f..29fa178c2 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageScreen.kt @@ -56,6 +56,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.actions.UrlUserTagTransformation import com.vitorpamplona.amethyst.ui.actions.mediaServers.ServerType import com.vitorpamplona.amethyst.ui.actions.uploads.SelectFromGallery @@ -64,6 +65,7 @@ import com.vitorpamplona.amethyst.ui.components.ThinPaddingTextField import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.navs.Nav import com.vitorpamplona.amethyst.ui.navigation.topbars.PostingTopBar +import com.vitorpamplona.amethyst.ui.note.NoteCompose import com.vitorpamplona.amethyst.ui.note.creators.contentWarning.ContentSensitivityExplainer import com.vitorpamplona.amethyst.ui.note.creators.contentWarning.MarkAsSensitiveButton import com.vitorpamplona.amethyst.ui.note.creators.emojiSuggestions.ShowEmojiSuggestionList @@ -89,6 +91,7 @@ import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.Font14SP import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size5dp +import com.vitorpamplona.amethyst.ui.theme.imageModifier import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.quartz.nip01Core.core.HexKey import kotlinx.coroutines.Dispatchers @@ -101,6 +104,7 @@ import kotlinx.coroutines.withContext @Composable fun NewPublicMessageScreen( to: Set? = null, + reply: Note? = null, accountViewModel: AccountViewModel, nav: Nav, ) { @@ -112,6 +116,9 @@ fun NewPublicMessageScreen( to?.let { postViewModel.load(it) } + reply?.let { + postViewModel.reply(it) + } } } @@ -171,9 +178,26 @@ fun PublicMessageScreenContent( Modifier.fillMaxWidth().verticalScroll(scrollState), verticalArrangement = spacedBy(Size10dp), ) { - SendDirectMessageTo(postViewModel, accountViewModel) + val replyTo = postViewModel.replyingTo - MessageFieldRow(postViewModel, accountViewModel) + if (replyTo == null) { + SendDirectMessageTo(postViewModel, accountViewModel) + } else { + Row { + NoteCompose( + baseNote = replyTo, + modifier = MaterialTheme.colorScheme.imageModifier, + isQuotedNote = true, + unPackReply = false, + makeItShort = true, + quotesLeft = 1, + accountViewModel = accountViewModel, + nav = nav, + ) + } + } + + MessageFieldRow(postViewModel, accountViewModel, postViewModel.toUsers.text.isNotBlank()) DisplayPreviews(postViewModel.urlPreviews, accountViewModel, nav) @@ -327,9 +351,11 @@ fun SendDirectMessageTo( val keyboardController = LocalSoftwareKeyboardController.current LaunchedEffect(Unit) { - launch { - delay(200) - focusRequester.requestFocus() + if (postViewModel.toUsers.text.isBlank()) { + launch { + delay(200) + focusRequester.requestFocus() + } } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt index 948affe69..9b0a7c945 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/notifications/publicMessages/NewPublicMessageViewModel.kt @@ -133,6 +133,8 @@ class NewPublicMessageViewModel : } } + var replyingTo: Note? by mutableStateOf(null) + val iMetaAttachments = IMetaAttachments() var nip95attachments by mutableStateOf>>(emptyList()) @@ -203,6 +205,10 @@ class NewPublicMessageViewModel : ) } + fun reply(post: Note) { + this.replyingTo = post + } + fun quote(quote: Note) { message = TextFieldValue(message.text + "\nnostr:${quote.toNEvent()}") urlPreviews.update(message) @@ -332,7 +338,7 @@ class NewPublicMessageViewModel : } } - private suspend fun createTemplate(): EventTemplate? { + private suspend fun createTemplate(): EventTemplate? { val toUsersTagger = NewMessageTagger(this@NewPublicMessageViewModel.toUsers.text, null, null, accountViewModel) toUsersTagger.run() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/conversations/dal/UserProfileConversationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/conversations/dal/UserProfileConversationsFeedFilter.kt index 61ea85b95..8ecaead08 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/conversations/dal/UserProfileConversationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/conversations/dal/UserProfileConversationsFeedFilter.kt @@ -26,6 +26,7 @@ import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder +import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent @@ -67,6 +68,7 @@ class UserProfileConversationsFeedFilter( it.event is LiveActivitiesChatMessageEvent || it.event is CommentEvent || it.event is VoiceReplyEvent || + it.event is PublicMessageEvent || it.event is TorrentCommentEvent ) && !it.isNewThread() && diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/datasource/FilterUserProfilePosts.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/datasource/FilterUserProfilePosts.kt index 05f1534b0..57b533a36 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/datasource/FilterUserProfilePosts.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/datasource/FilterUserProfilePosts.kt @@ -23,6 +23,7 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.datasource import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -50,6 +51,7 @@ val UserProfilePostKinds1 = HighlightEvent.KIND, WikiNoteEvent.KIND, VoiceEvent.KIND, + PublicMessageEvent.KIND, ) val UserProfilePostKinds2 = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/mutual/dal/UserProfileMutualFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/mutual/dal/UserProfileMutualFeedFilter.kt index 3a5d403eb..22a90a03e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/mutual/dal/UserProfileMutualFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/mutual/dal/UserProfileMutualFeedFilter.kt @@ -30,6 +30,7 @@ import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder import com.vitorpamplona.quartz.experimental.audio.header.AudioHeaderEvent import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.interactiveStories.InteractiveStoryPrologueEvent +import com.vitorpamplona.quartz.experimental.publicMessages.PublicMessageEvent import com.vitorpamplona.quartz.experimental.zapPolls.PollNoteEvent import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent import com.vitorpamplona.quartz.nip01Core.tags.people.isTaggedUser @@ -80,6 +81,7 @@ class UserProfileMutualFeedFilter( it.event is InteractiveStoryPrologueEvent || it.event is AudioTrackEvent || it.event is AudioHeaderEvent || + it.event is PublicMessageEvent || it.event is TorrentEvent ) && it.event?.isTaggedUser(user.pubkeyHex) == true diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedViewModel.kt index 607d494b9..8c9d93545 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/settings/StringFeedViewModel.kt @@ -107,7 +107,7 @@ open class StringFeedViewModel( } viewModelScope.launch(Dispatchers.Default) { LocalCache.live.deletedEventBundles.collect { newNotes -> - Log.d("Rendering Metrics", "Update feeds: ${this@StringFeedViewModel.javaClass.simpleName} with ${newNotes.size}") + Log.d("Rendering Metrics", "Delete feeds: ${this@StringFeedViewModel.javaClass.simpleName} with ${newNotes.size}") invalidateData() } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt index 27a25348e..629abf341 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Shape.kt @@ -122,6 +122,7 @@ val HalfStartPadding = Modifier.padding(start = 5.dp) val StdStartPadding = Modifier.padding(start = 10.dp) val StdTopPadding = Modifier.padding(top = 10.dp) val HalfTopPadding = Modifier.padding(top = 5.dp) +val HalfHalfTopPadding = Modifier.padding(top = 3.dp) val HalfHalfVertPadding = Modifier.padding(vertical = 3.dp) val HalfHalfHorzModifier = Modifier.padding(horizontal = 3.dp) diff --git a/amethyst/src/main/res/values-es-rES/strings.xml b/amethyst/src/main/res/values-es-rES/strings.xml index c0f9ae00b..096e9ab2c 100644 --- a/amethyst/src/main/res/values-es-rES/strings.xml +++ b/amethyst/src/main/res/values-es-rES/strings.xml @@ -51,6 +51,13 @@ Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder dejar de seguir a otros usuarios. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder ocultar una palabra o frase. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder mostrar una palabra o frase. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder cambiar la configuración. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder subir contenido. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder firmar eventos. + Descifrado no autorizado + El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo + No se ha encontrado el firmante. + ¿Se ha desinstalado la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si ha cambiado. Zaps Total de visualizaciones Impulsar @@ -71,6 +78,8 @@ Error al analizar el mensaje de error " Siguiendo" " Seguidores" + "%1$s siguiendo" + "%1$s seguidores" Perfil Filtros de seguridad Cerrar sesión @@ -96,6 +105,7 @@ Mi grupo genial URL de imagen Descripción + No se ha encontrado la descripción "Sobre nosotros…" ¿Qué tienes en mente? Escribir un mensaje… @@ -137,6 +147,10 @@ Video guardado en la galería de videos del teléfono Error al guardar el video Cargar imagen + Hacer una foto + Grabar un mensaje + Grabar un mensaje + Haz clic y mantén pulsado para grabar un mensaje Cargando… El usuario no tiene una configuración de dirección Lightning para recibir sats "responde aquí… " @@ -155,6 +169,7 @@ Galería "Siguiendo" "Reportes" + "%1$s informes" Más opciones " Retransmisores" Sitio web @@ -213,6 +228,13 @@ Dejar de seguir Canal creado "La información del canal cambió a" + Chat temporal + Chat en relé + Chats en relé + Los chats en relé son grupos de chat controlados por su relé de origen. + Son visibles para todos los usuarios de Nostr y cualquiera puede participar en ellos. + Son ideales para comunidades abiertas en torno a temas específicos. Algunos de estos grupos son efímeros + y, por lo tanto, los mensajes del chat desaparecen con el tiempo Chat público Metadatos públicos del chat Los chats públicos son visibles para todos en Nostr y cualquiera @@ -221,6 +243,8 @@ Relés Inserta entre 1 y 3 relés que alojan este grupo. Los clientes de Nostr utilizan esta configuración para saber de dónde descargar y adónde enviar los mensajes. + Relé de pago + Fuerza Tor al conectar publicaciones recibidas Eliminar Automático @@ -265,6 +289,7 @@ Error "Credo por %1$s" "Imagen del Badge para %1$s" + \"Imagen de premio de insignia Has recibido un nuevo Badge Badge otorgado a Texto de nota copiado al portapapeles @@ -290,6 +315,7 @@ Dejar de seguir Seguir Eliminar de la galería + Elimina este contenido multimedia de la galería. Solicitar eliminación Amethyst solicitará que se elimine su nota de los relays a los que está conectado actualmente. No hay garantía de que su nota se elimine permanentemente de esos relays, o de otros relays donde pueda almacenarse. Bloquear @@ -411,6 +437,7 @@ No Lista de seguidos Todos los seguidos + Siguiendo a través de proxy A mi alrededor Global Lista de silenciados @@ -485,9 +512,18 @@ Ocultar siempre el contenido delicado Mostrar siempre el contenido delicado Mostrar siempre advertencias sobre contenido + Ocultar + Mostrar + Advertir Recomendaciones: Filtrar el spam de desconocidos Avisar cuando las publicaciones tengan reportes de tus seguidos + Filtrar spam + Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. + Advertir sobre reportes + Muestra un mensaje de advertencia cuando los mensajes tienen 5 o más reportes de los usuarios que sigues. + Mostrar contenido delicado + Muestra un mensaje de advertencia cuando el autor de la publicación la marca como contenido delicado. Nuevo símbolo de reacción No hay tipos de reacción preseleccionados para este usuario. Deja presionado el botón de corazón para cambiarlos. Recaudación de zaps @@ -539,7 +575,12 @@ Al cerrar la sesión se borra toda tu información local. Asegúrate de tener una copia de seguridad de tus claves privadas para que no pierdas la cuenta. ¿Quieres continuar? Etiquetas seguidas Relés + Paquetes de seguimiento + Lecturas + Algoritmos del feed Mercado + Transmisiones en vivo + Comunidades Chats Publicaciones aprobadas Este grupo no tiene descripción ni reglas. Habla con el propietario para agregar una. @@ -547,6 +588,7 @@ Contenido delicado Agrega una advertencia de contenido sensible antes de mostrarlo Preferencias de la app + Preferencias de usuario Configuración Siempre Solo Wi-Fi @@ -591,6 +633,8 @@ Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. + Publicación exclusiva de hashtag + Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. @@ -599,6 +643,7 @@ Activar Público Nuevo grupo público o privado + Relé Privado Para Asunto @@ -664,6 +709,7 @@ Monedero %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. + Solicitud de firma rechazada Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron monederos para pagar una factura de Lightning (error: %1$s). Instala un monedero de Lightning para usar zaps. @@ -791,6 +837,8 @@ Nueva publicación Nuevos cortos: imágenes o vídeos Nueva nota comunitaria + Nuevo producto + Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -845,12 +893,29 @@ Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. Relés generales Amethyst usa estos relés para descargar publicaciones por ti. + Relés conectados + Lista actual de relés en uso Relés recomendados Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales Lista de relés que se utilizan en este dispositivo. + Relés de confianza + Relés de confianza + Relés en que confías para no necesitar una conexión Tor para + Relés de proxy + Relés de proxy + Relés recopiladores que la app debe usar para descargar tus feeds, como filter.nostr.wine. Esto reemplaza el modelo de bandeja de salida y hará que la app se conecte solo a los relés de tus listas. + Relés de transmisión + Relés de transmisión + Relés que se especializan en enviar tus notas a todos los demás relés, como sendit.nosflare.com. Amethyst agregará este relé a todos los eventos nuevos que crees. + Relés de indexador + Relés de indexador + Relés que se especializan en alojar los metadatos y las listas de retransmisión de todos, como purplepag.es. Amethyst usará estos relés para encontrar usuarios que no estén en tus listas. + Relés bloqueados + Relés bloqueados + Amethyst nunca se conectará a estos relés ¡Zapea a los desarrolladores! Tu donación nos ayuda a marcar la diferencia. ¡Cada sat cuenta! Donar ahora @@ -940,4 +1005,11 @@ Selecciona una lista para filtrar el tablón Cerrar sesión al bloquear dispositivo Mensaje privado + Mensaje público + Relé de chat + Relé al que todos los usuarios de este chat se conectan + Compartir imagen… + Buscar hashtag: #%1$s + No traducir del + Los idiomas que se muestran aquí no se traducirán. Selecciona un idioma para eliminarlo y traducirlo de nuevo. diff --git a/amethyst/src/main/res/values-es-rMX/strings.xml b/amethyst/src/main/res/values-es-rMX/strings.xml index 8498d3866..7a07b168f 100644 --- a/amethyst/src/main/res/values-es-rMX/strings.xml +++ b/amethyst/src/main/res/values-es-rMX/strings.xml @@ -51,6 +51,12 @@ Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder dejar de seguir a otros usuarios. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder ocultar una palabra o frase. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder mostrar una palabra o frase. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder subir contenido. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder firmar eventos. + Descifrado no autorizado + El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo + No se ha encontrado el firmante. + ¿Se desinstaló la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si cambió. Zaps Total de visualizaciones Impulsar @@ -71,6 +77,8 @@ Error al analizar el mensaje de error " Siguiendo" " Seguidores" + "%1$s siguiendo" + "%1$s seguidores" Perfil Filtros de seguridad Cerrar sesión @@ -96,6 +104,7 @@ Mi grupo genial URL de imagen Descripción + No se encontró la descripción "Quiénes somos…" ¿Qué estás pensando? Escribir un mensaje… @@ -137,6 +146,10 @@ Video guardado en la galería de videos del teléfono Error al guardar el video Subir imagen + Tomar una foto + Grabar un mensaje + Grabar un mensaje + Haz clic y mantén presionado para grabar un mensaje Subiendo… El usuario no tiene configurada una dirección de Lightning para recibir sats "responde aquí… " @@ -155,6 +168,7 @@ Galería "Seguidos" "Reportes" + "%1$s informes" Más opciones " Relés" Sitio web @@ -213,6 +227,13 @@ Dejar de seguir Canal creado "La información del canal cambió a" + Chat temporal + Chat en relé + Chats en relé + Los chats en relé son grupos de chat controlados por su relé de origen. + Son visibles para todos los usuarios de Nostr y cualquiera puede participar en ellos. + Son ideales para comunidades abiertas en torno a temas específicos. Algunos de estos grupos son efímeros + y, por lo tanto, los mensajes del chat desaparecen con el tiempo Chat público Metadatos públicos del chat Los chats públicos son visibles para todos en Nostr y cualquiera @@ -221,6 +242,8 @@ Relés Inserta entre 1 y 3 relés que alojan este grupo. Los clientes de Nostr utilizan esta configuración para saber de dónde descargar y adónde enviar los mensajes. + Relé de pago + Fuerza Tor al conectarse publicaciones recibidas Eliminar Automático @@ -265,6 +288,7 @@ Error "Creado por %1$s" "Imagen de premio de insignia por %1$s" + \"Imagen de premio de insignia Recibiste un nuevo premio de insignia Premio de insignia otorgado a Texto de la nota copiado al portapapeles @@ -290,6 +314,7 @@ Dejar de seguir Seguir Eliminar de la galería + Elimina este contenido multimedia de la galería. Solicitar eliminación Amethyst solicitará que se elimine la nota de los relés con los que tienes conexión actualmente. No hay garantía de que la nota se elimine permanentemente de esos relés o de otros donde pueda estar guardada. Bloquear @@ -411,6 +436,7 @@ No Lista de seguidos Todos los seguidos + Siguiendo a través de proxy A mi alrededor Global Lista de silenciados @@ -485,9 +511,18 @@ Ocultar siempre el contenido delicado Mostrar siempre el contenido delicado Mostrar siempre advertencias sobre contenido + Ocultar + Mostrar + Advertir Recomendaciones: Filtrar el spam de desconocidos Avisar cuando las publicaciones tengan reportes de tus seguidos + Filtrar spam + Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. + Advertir sobre reportes + Muestra un mensaje de advertencia cuando los mensajes tienen 5 o más reportes de los usuarios que sigues. + Mostrar contenido delicado + Muestra un mensaje de advertencia cuando el autor de la publicación la marca como contenido delicado. Nuevo símbolo de reacción No hay tipos de reacción preseleccionados para este usuario. Deja presionado el botón de corazón para cambiarlos. Recaudación de zaps @@ -539,7 +574,12 @@ Al cerrar la sesión se borra toda tu información local. Asegúrate de tener una copia de seguridad de tus claves privadas para que no pierdas la cuenta. ¿Quieres continuar? Etiquetas seguidas Relés + Paquetes de seguimiento + Lecturas + Algoritmos del feed Mercado + Transmisiones en vivo + Comunidades Chats Publicaciones aprobadas Este grupo no tiene descripción ni reglas. Habla con el propietario para agregar una. @@ -547,6 +587,7 @@ Contenido delicado Agrega una advertencia de contenido sensible antes de mostrarlo Preferencias de la app + Preferencias de usuario Configuración Siempre Solo Wi-Fi @@ -591,6 +632,8 @@ Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. + Publicación exclusiva de hashtag + Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. @@ -599,6 +642,7 @@ Activar Público Nuevo grupo público o privado + Relé Privado Para Asunto @@ -664,6 +708,7 @@ Billetera %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. + Solicitud de firma rechazada Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron billeteras para pagar una factura de Lightning (error: %1$s). Instala una billetera de Lightning para usar zaps. @@ -791,6 +836,8 @@ Nueva publicación Nuevos cortos: imágenes o videos Nueva nota comunitaria + Nuevo producto + Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -845,12 +892,29 @@ Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. Relés generales Amethyst usa estos relés para descargar publicaciones por ti. + Relés conectados + Lista actual de relés en uso Relés recomendados Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales Lista de relés que se utilizan en este dispositivo. + Relés de confianza + Relés de confianza + Relés en que confías para no necesitar una conexión Tor para + Relés de proxy + Relés de proxy + Relés recopiladores que la app debe usar para descargar tus feeds, como filter.nostr.wine. Esto reemplaza el modelo de bandeja de salida y hará que la app se conecte solo a los relés de tus listas. + Relés de transmisión + Relés de transmisión + Relés que se especializan en enviar tus notas a todos los demás relés, como sendit.nosflare.com. Amethyst agregará este relé a todos los eventos nuevos que crees. + Relés de indexador + Relés de indexador + Relés que se especializan en alojar los metadatos y las listas de retransmisión de todos, como purplepag.es. Amethyst usará estos relés para encontrar usuarios que no estén en tus listas. + Relés bloqueados + Relés bloqueados + Amethyst nunca se conectará a estos relés ¡Zapea a los desarrolladores! Tu donación nos ayuda a marcar la diferencia. ¡Cada sat cuenta! Donar ahora @@ -940,4 +1004,11 @@ Selecciona una lista para filtrar el feed Cerrar sesión al bloquear dispositivo Mensaje privado + Mensaje público + Relé de chat + Relé al que todos los usuarios de este chat se conectan + Compartir imagen… + Buscar hashtag: #%1$s + No traducir del + Los idiomas que se muestran aquí no se traducirán. Selecciona un idioma para eliminarlo y traducirlo de nuevo. diff --git a/amethyst/src/main/res/values-es-rUS/strings.xml b/amethyst/src/main/res/values-es-rUS/strings.xml index e28620633..d9be7f50f 100644 --- a/amethyst/src/main/res/values-es-rUS/strings.xml +++ b/amethyst/src/main/res/values-es-rUS/strings.xml @@ -51,6 +51,12 @@ Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder dejar de seguir a otros usuarios. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder ocultar una palabra o frase. Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder mostrar una palabra o frase. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder subir contenido. + Estás usando una clave pública, que es solo de lectura. Inicia sesión con una clave privada para poder firmar eventos. + Descifrado no autorizado + El firmante no autorizó un descifrado necesario para realizar esta operación. Activa el descifrado NIP-44 en tu aplicación de firmante e inténtalo de nuevo + No se ha encontrado el firmante. + ¿Se desinstaló la app del firmante? Comprueba si el firmante está instalado y tiene esta cuenta. Cierra sesión y vuelve a iniciar sesión en la app del firmante si cambió. Zaps Total vistas Impulsar @@ -71,6 +77,8 @@ Error al analizar el mensaje de error " Siguiendo" " Seguidores" + "%1$s siguiendo" + "%1$s seguidores" Perfil Filtros de seguridad Cerrar sesión @@ -96,6 +104,7 @@ Mi grupo genial URL de imagen Descripción + No se encontró la descripción "Quiénes somos…" ¿Qué estás pensando? Escribir un mensaje… @@ -137,6 +146,10 @@ Video guardado en la galería de videos del teléfono Error al guardar el video Subir imagen + Tomar una foto + Grabar un mensaje + Grabar un mensaje + Haz clic y mantén presionado para grabar un mensaje Subiendo… El usuario no tiene configurada una dirección de Lightning para recibir sats "responde aquí… " @@ -155,6 +168,7 @@ Galería "Seguidos" "Reportes" + "%1$s informes" Más opciones " Relés" Sitio web @@ -213,6 +227,13 @@ Dejar de seguir Canal creado "La información del canal cambió a" + Chat temporal + Chat en relé + Chats en relé + Los chats en relé son grupos de chat controlados por su relé de origen. + Son visibles para todos los usuarios de Nostr y cualquiera puede participar en ellos. + Son ideales para comunidades abiertas en torno a temas específicos. Algunos de estos grupos son efímeros + y, por lo tanto, los mensajes del chat desaparecen con el tiempo Chat público Metadatos públicos del chat Los chats públicos son visibles para todos en Nostr y cualquiera @@ -221,6 +242,8 @@ Relés Inserta entre 1 y 3 relés que alojan este grupo. Los clientes de Nostr utilizan esta configuración para saber de dónde descargar y adónde enviar los mensajes. + Relé de pago + Fuerza Tor al conectarse publicaciones recibidas Eliminar Automático @@ -265,6 +288,7 @@ Error "Creado por %1$s" "Imagen de premio de insignia por %1$s" + \"Imagen de premio de insignia Recibiste un nuevo premio de insignia Premio de insignia otorgado a Texto de la nota copiado al portapapeles @@ -290,6 +314,7 @@ Dejar de seguir Seguir Eliminar de la galería + Elimina este contenido multimedia de la galería. Solicitar eliminación Amethyst solicitará que se elimine la nota de los relés con los que tienes conexión actualmente. No hay garantía de que la nota se elimine permanentemente de esos relés o de otros donde pueda estar guardada. Bloquear @@ -411,6 +436,7 @@ No Lista de seguidos Todos los seguidos + Siguiendo a través de proxy A mi alrededor Global Lista de silenciados @@ -485,9 +511,18 @@ Ocultar siempre el contenido delicado Mostrar siempre el contenido delicado Mostrar siempre advertencias sobre contenido + Ocultar + Mostrar + Advertir Recomendaciones: Filtrar el spam de desconocidos Avisar cuando las publicaciones tengan reportes de tus seguidos + Filtrar spam + Oculta las publicaciones de desconocidos que sean exactamente iguales 5 o más veces. + Advertir sobre reportes + Muestra un mensaje de advertencia cuando los mensajes tienen 5 o más reportes de los usuarios que sigues. + Mostrar contenido delicado + Muestra un mensaje de advertencia cuando el autor de la publicación la marca como contenido delicado. Nuevo símbolo de reacción No hay tipos de reacción preseleccionados para este usuario. Deja presionado el botón de corazón para cambiarlos. Recaudación de zaps @@ -539,7 +574,12 @@ Al cerrar la sesión se borra toda tu información local. Asegúrate de tener una copia de seguridad de tus claves privadas para que no pierdas la cuenta. ¿Quieres continuar? Etiquetas seguidas Relés + Paquetes de seguimiento + Lecturas + Algoritmos del feed Mercado + Transmisiones en vivo + Comunidades Chats Publicaciones aprobadas Este grupo no tiene descripción ni reglas. Habla con el propietario para agregar una. @@ -547,6 +587,7 @@ Contenido delicado Agrega una advertencia de contenido sensible antes de mostrarlo Preferencias de la app + Preferencias de usuario Configuración Siempre Solo Wi-Fi @@ -591,6 +632,8 @@ Agrega un Geohash de tu ubicación al mensaje. El público sabrá que te encuentras a menos de 5 km (3 mi) de la ubicación actual. Publicación con ubicación exclusiva Solo los seguidores de la ubicación la verán. Tus seguidores generales no la verán. + Publicación exclusiva de hashtag + Solo los seguidores del hashtag la verán. Tus seguidores generales no la verán. Cargando ubicación Sin permisos de ubicación Agrega una advertencia de contenido delicado antes de mostrarlo. Esto es ideal para cualquier contenido NSFW o que a algunas personas les pueda resultar ofensivo o perturbador. @@ -599,6 +642,7 @@ Activar Público Nuevo grupo público o privado + Relé Privado Para Asunto @@ -664,6 +708,7 @@ Billetera %1$s Error al abrir la aplicación firmante No se pudo encontrar la aplicación firmante. Comprueba si no se desinstaló la aplicación. + Solicitud de firma rechazada Solicitud de firma rechazada Asegúrate de que la aplicación firmante haya autorizado esta transacción. No se encontraron billeteras para pagar una factura de Lightning (error: %1$s). Instala una billetera de Lightning para usar zaps. @@ -791,6 +836,8 @@ Nueva publicación Nuevos cortos: imágenes o videos Nueva nota comunitaria + Nuevo producto + Nueva publicación geoexclusiva Abrir todas las reacciones a esta publicación Cerrar todas las reacciones a esta publicación Responder @@ -845,12 +892,29 @@ Inserta entre 1 y 3 relés para almacenar eventos que nadie más pueda ver, como los borradores o la configuración de la app. Lo ideal es que estos relés sean locales o requieran autenticación antes de descargar el contenido de cada usuario. Relés generales Amethyst usa estos relés para descargar publicaciones por ti. + Relés conectados + Lista actual de relés en uso Relés recomendados Agrega los siguientes relés a la lista de relés generales para recibir publicaciones de los usuarios de la lista. Relés de búsqueda Lista de relés que se usarán al buscar contenido o usuarios. El etiquetado y la búsqueda no funcionarán si no hay opciones disponibles. Asegúrate de que implementen NIP-50. Relés locales Lista de relés que se utilizan en este dispositivo. + Relés de confianza + Relés de confianza + Relés en que confías para no necesitar una conexión Tor para + Relés de proxy + Relés de proxy + Relés recopiladores que la app debe usar para descargar tus feeds, como filter.nostr.wine. Esto reemplaza el modelo de bandeja de salida y hará que la app se conecte solo a los relés de tus listas. + Relés de transmisión + Relés de transmisión + Relés que se especializan en enviar tus notas a todos los demás relés, como sendit.nosflare.com. Amethyst agregará este relé a todos los eventos nuevos que crees. + Relés de indexador + Relés de indexador + Relés que se especializan en alojar los metadatos y las listas de retransmisión de todos, como purplepag.es. Amethyst usará estos relés para encontrar usuarios que no estén en tus listas. + Relés bloqueados + Relés bloqueados + Amethyst nunca se conectará a estos relés ¡Zapea a los desarrolladores! Tu donación nos ayuda a marcar la diferencia. ¡Cada sat cuenta! Donar ahora @@ -940,4 +1004,11 @@ Selecciona una lista para filtrar el feed Cerrar sesión al bloquear dispositivo Mensaje privado + Mensaje público + Relé de chat + Relé al que todos los usuarios de este chat se conectan + Compartir imagen… + Buscar hashtag: #%1$s + No traducir del + Los idiomas que se muestran aquí no se traducirán. Selecciona un idioma para eliminarlo y traducirlo de nuevo. diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index 769da570c..88760ed37 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -51,6 +51,13 @@ आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। अनुचरण रोकने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। शब्द अथवा वाक्य छिपाने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। शब्द अथवा वाक्य आच्छादन हटाने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें + आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। स्थापना विकल्पों का परिवर्तन करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें + आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। आरोहण करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें + आप ख्याप्य कुंचिका का प्रयोग कर रहे हैं जिससे केवल पढ सकते हैं। घटनाओं पर हस्ताक्षर करने के लिए गुप्त कुंचिका के साथ प्रवेशांकन करें + अनधिकृत अपरहस्यीकरण + हस्ताक्षरकर्ता ने इस कार्य करने के लिए अपरहस्यीकरण का अधिकार नहीं दिया। आपके हस्ताक्षर क्रमक में निप॰-४४ अपरहस्यीकरण सक्रिय करें तथा पुनः प्रयास करें + हस्ताक्षरकर्ता अप्राप्त + क्या हस्ताक्षर क्रमक अस्थापित किया गया। जाँच करें कि यदि हस्ताक्षरकर्ता स्थापित है तथा यह लेखा वहाँ है। यदि हस्ताक्षर क्रमक में परिवर्तन है तो निर्गमनांकन तथा प्रवेशांकन पुनः करें। ज्साप दृष्ट संख्या उद्धृत करें @@ -98,6 +105,7 @@ मेरा बढिया झुण्ड चित्र जालपता विवरण + विवरण अप्राप्त "हमारा परिचय…" आपके मन में क्या है? सन्देश लिखें … @@ -139,6 +147,10 @@ चलचित्र को संचारयन्त्र के चलचित्रालय में सुरक्षित रखा गया चलचित्र को सुरक्षित रखने में असफल चित्र आरोहण + एक चित्र लें + ऐक संदेश का अभिलेखन करें + ऐक संदेश का अभिलेखन करें + टाँकें तथा दबाए रखें संदेश का अभिलेखन करने के लिए आरोहण चल रहा है… उपयोगकर्ता का कोई लैटनिंग पता स्थापित नहीं जिसपर साट्स प्राप्त कर सके "उत्तर यहाँ दें.. " @@ -231,6 +243,8 @@ पुनःप्रसारक इस समुदाय के निवास के लिए १ - ३ पुनःप्रसारकों को जोडें। नोस्टर ग्राहक इस स्थापना विकल्प का प्रयोग करेंगे यह जानने के लिए कि कहाँ से सन्देशों का अवरोहण करना है तथा कहाँ आपके सन्देश भेजने हैं। + सशुल्क पुनःप्रसारक + संयोजन के समय टोर का प्रयोग अवश्य करें पत्र प्राप्त हटाएँ स्वचालित @@ -275,6 +289,7 @@ अपक्रम "%1$s के द्वारा बनाया गया" "पदक पुरस्कार चित्र %1$s के लिए" + \"पदक पुरस्कार चित्र आपको नया पदक पुरस्कार प्राप्त हुआ पदक पुरस्कार इनको दिया गया टीका लेख की अनुकृति किया गया टाँकाफलक में @@ -422,6 +437,7 @@ नहीं अनुचरण सूची सभी अनुचरित + प्रतिनिधि द्वारा अनुचरित मेरे आसपास वैश्विक मौन सूची @@ -693,6 +709,7 @@ धनकोष %1$s हस्ताक्षर क्रमक खोलने में अपक्रम हस्ताक्षर क्रमक ढूँढने में असफल। जाँच करें यदि क्रमक को अस्थापित नहीं किया गया हो + हस्ताक्षर अनुरोध अस्वीकृत हस्ताक्षर क्रमक अस्वीकार किया सुनिश्चित करें हस्ताक्षर क्रमक ने इस व्यापार को अनुमति दिया कोई धनकोष प्राप्त नहीं लैटनिंग चालान चुकाने के लिए (अपक्रम : %1$s)। कृपया एक लैटनिंग धनकोष की स्थापना करें ज्सापों का प्रयोग करने के लिए @@ -876,12 +893,29 @@ १ - ३ पुनःप्रसारकों को जोडें उन घटनाओं को रखने के लिए जो कोई अन्य नहीं देख सकता जैसे कि पाण्डुलिपियाँ अथवा क्रमक के स्थापना विकल्प। आदर्शतः ये पुनःप्रसारक स्थानीय होने चाहिए अथवा प्रत्येक उपयोगकर्ता के विषयवस्तु अवरोहण के पूर्व परिचय प्रमाणीकरण अनिवार्य होना चाहिए। सामान्य पुनःप्रसारक अमेथिस्ट इन पुनःप्रसारकों का प्रयोग करता है आपके पत्रों का अवरोहण करने के लिए। + संयोजित पुनःप्रसारक + वर्तमान उपयुक्त पुनःप्रसारकों की सूची अनुशंसित पुनःप्रसारक सूचित उपयोगकर्ताओं के पत्र प्राप्त करने के लिए निम्नलिखित पुनःप्रसारकों को अपने सामान्य पुनःप्रसारक सूची में जोडें। खोज पुनःप्रसारक पुनःप्रसारकों की सूची जिनको किसी विषयवस्तु अथवा उपयोगकर्ताओं को खोजने में प्रयोग करना चाहिए। कोई विकल्प नहीं तो उपयोगकर्ता सूचक जोडना तथा खोज निष्क्रिय होंगे। सुनिश्चित करें कि वे निप॰-५० को कार्यान्वित किये हैं। स्थानीय पुनःप्रसारक पुनःप्रसारकों की सूची जो इस यन्त्र पर चल रहे हैं। + विश्वसनीय पुनःप्रसारक + विश्वसनीय पुनःप्रसारक + विश्वसनीय पुनःप्रसारक जिनके लिए टोर संयोजन आवश्यक नहीं + प्रतिनिधि पुनःप्रसारक + प्रतिनिधि पुनःप्रसारक + संग्रहकर्ता पुनःप्रसारक जो क्रमक द्वारा उपयुक्त होना चाहिए आपके सूचनावलियों का अवरोहण करने के लिए। जैसे कि filter.nostr.wine । यह निर्गतपेटिका प्रतिरूप को प्रतिस्थापित करेगा तथा क्रमक आपके सूचियों में पुनःप्रसारकों के साथ ही जुडेगा। + प्रसारण पुनःप्रसारक + प्रसारण पुनःप्रसारक + पुनःप्रसारक जो आपके पत्रों को अन्य सभी पुनःप्रसारकों को भेजने का विशेष कार्य करते हैं। जैसे कि sendit.nosflare.com । अमेथिस्ट इस पुनःप्रसारक को जोडेगा आपके द्वारा कृत सभी नए घटनाओं के लिए + अनुक्रमणीकार पुनःप्रसारक + अनुक्रमणीकार पुनःप्रसारक + पुनःप्रसारक जो सभी के उपतथ्य तथा पुनःप्रसारक सूचियों की जानकारी रखने का विशेष कार्य करते हैं। जैसे कि purplepag.es । अमेथिस्ट इन पुनःप्रसारकों का उपयोग करेगा उन प्रयोक्ताओं को ढूँढने के लिए जो आपके सूचियों में नहीं हैं। + बाधित पुनःप्रसारक + बाधित पुनःप्रसारक + अमेथिस्ट इन पुनःप्रसारकों से कभी नहीं जुडेगा क्रमलेखकों को ज्साप करें! आपका दान हमारा सहायक है परिवर्तन लाने में। प्रत्येक साट गणनीय है! दान करें अभी @@ -971,6 +1005,7 @@ सूचनावली छानने के लिए सूची चुनें यन्त्र ताला लगने पर निर्गमनांकन करें निजी सन्देश + सार्वजनिक संदेश चर्चा पुनःप्रसारक वह पुनःप्रसारक जिससे इस चर्चा के सभी उपयोगकर्ता जुडते हैं चित्र बाँटें… diff --git a/amethyst/src/main/res/values-nl-rNL/strings.xml b/amethyst/src/main/res/values-nl-rNL/strings.xml index 24b0d6576..d4e9229b7 100644 --- a/amethyst/src/main/res/values-nl-rNL/strings.xml +++ b/amethyst/src/main/res/values-nl-rNL/strings.xml @@ -51,6 +51,13 @@ Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om te ontvolgen Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om woorden en zinnen te verbergen Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om woorden of zinnen te tonen + Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om instellingen aan te passen + Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om te uploaden + Je gebruikt een publieke sleutel en publieke sleutels zijn alleen-lezen. Login met een geheime sleutel om events te tekenen + Ongeautoriseerde decodering + De ondertekenaar heeft geen decodering toegestaan die nodig is om dit in werking te stellen. Activeer NIP-44 decodering in uw signer app en probeer het opnieuw + Signer niet gevonden + Is de signer app gedeïnstalleerd? Controleer of de ondertekenaar is geïnstalleerd en dit account heeft. Log opnieuw in want de signer app is gewijzigd. Zaps Aantal keer bekeken Boost @@ -71,6 +78,8 @@ Fout bij het parsen van foutberichten " Volgend" " Volgers" + "%1$s volgend" + "%1$s volgers" Profiel Veiligheidsfilter Uitloggen @@ -96,6 +105,7 @@ Mijn geweldige groep Afbeelding URL Omschrijving + Beschrijving niet gevonden "Over ons…" Waar denk je aan? Schrijf een bericht… @@ -137,6 +147,10 @@ Video\'s opgeslagen in galerij De video is niet opgeslagen Afbeelding uploaden + Neem een foto + Neem een bericht op + Neem een bericht op + Klik en houd vast om een bericht te opnemen Uploaden… Gebruiker heeft geen Lightning Adress ingesteld om sats te ontvangen "hier reageren.. " @@ -155,6 +169,7 @@ Galerij "Volgend" "Rapporten" + "%1$s rapporten" Meer opties "Relays" Website @@ -213,6 +228,13 @@ Ontvolgen Kanaal gemaakt "Kanaalinformatie veranderd naar" + Verdwijnende chat + Relay chat + Relay chats + Relay chats zijn chatgroepen die beheerd worden door hun thuisrelay. + Ze zijn zichtbaar voor iedereen op Nostr en iedereen kan eraan deelnemen. + Ze zijn geschikt voor open communities rond specifieke onderwerpen. Sommige van deze groepen zijn tijdelijk + en daardoor verdwijnen berichten na verloop van tijd Publieke chat Publieke chat metadata Publieke chats zijn zichtbaar voor iedereen op Nostr en iedereen @@ -221,6 +243,8 @@ Relays Voeg een 1–3 relays toe die deze groep hosten. Nostr clients gebruiken deze instelling om te weten waar berichten van moeten worden gedownload en waarnaar uw berichten worden verzonden. + Betaald relays + Forceert Tor tijdens verbinden berichten ontvangen verwijderen Automatisch @@ -265,6 +289,7 @@ Fout "Gemaakt door %1$s" "Badge award afbeelding voor %1$s" + \"Badge award afbeelding Je hebt een nieuwe Badge award ontvangen Badge award gegeven aan Note tekst gekopieerd naar klembord @@ -290,6 +315,7 @@ Ontvolgen Volgen Verwijderen uit galerij + Verwijder deze media uit je galerij. Verzoek om te verwijderen Amethyst zal vragen om uw note te verwijderen van de relays waarmee u momenteel verbonden bent. Er is geen garantie dat uw note permanent wordt verwijderd van deze relays, of van andere relays waar het kan worden opgeslagen. Blokkeren @@ -411,6 +437,7 @@ Nee Volgerslijst Iedereen + Volgt via proxy In de buurt Globaal Mute-lijst @@ -485,9 +512,18 @@ Verberg altijd gevoelige inhoud Toon altijd gevoelige inhoud Toon altijd content waarshuwingen + Verberg + Tonen + Waarschuwen Raadt aan: Filter spam van onbekenden Waarschuw wanneer berichten meldingen hebben van je volgers + Spam filteren + Verbergt posts van onbekenden die 5 of meer keer precies hetzelfde waren + Waarschuwen bij meldingen + Toont een waarschuwingsbericht wanneer berichten 5 of meer meldingen heeft van je volgers + Toon gevoelige inhoud + Toont een waarschuwingsbericht wanneer de auteur van het bericht als gevoelig gemarkeerd heeft Nieuwe reactie symbool Geen reactietypes geselecteerd. Lang indrukken om te wijzigen Zapraiser @@ -539,7 +575,12 @@ Uitloggen verwijdert al je lokale informatie. Zorg ervoor dat je een back-up hebt van je geheime sleutels om te voorkomen dat je je account kwijtraakt. Wilt u doorgaan? Gevolgde tags Relays + Volg pakketten + Gelezen + Feed algoritmes Marktplaats + Livestream + Communities Chats Goedgekeurde berichten Deze groep heeft geen beschrijving of regels. Praat met de eigenaar om er een toe te voegen @@ -547,6 +588,7 @@ Gevoelige content Voegt waarschuwing voor gevoelige content toe voordat deze content wordt weergegeven App-voorkeuren + Gebruikersvoorkeuren Instellingen Altijd Alleen wifi @@ -591,6 +633,8 @@ Voegt een Geohash van je locatie toe aan het bericht. Het publiek weet dat je binnen 5 km (3mi) van de huidige locatie bent. Locatie-exclusief bericht Alleen volgers van de locatie zien het. Je volgers zien het niet. + Hastag exclusieve post + Alleen volgers van de hashtag zullen het zien. Je normale volgers zien het niet. Locatie laden Geen locatiemachtigingen Voegt een waarschuwing voor gevoelige inhoud toe voordat je inhoud wordt weergegeven. Dit is ideaal voor NSFW-inhoud of inhoud die sommige mensen beledigend of verontrustend vinden. @@ -599,6 +643,7 @@ Activeren Publiek Nieuwe openbare of besloten groep + Relay Privé Aan Onderwerp @@ -664,6 +709,7 @@ Wallet %1$s Fout bij openen ondertekenapp De teken-app kan niet worden gevonden. Controleer of de app niet is verwijderd + Ondertekenverzoek afgewezen Ondertekenverzoek afgewezen Zorg ervoor dat de teken-app deze transactie heeft geautoriseerd Geen wallets gevonden om een Lightning Invoice te betalen (Error: %1$s). Installeer een Lightning wallet om zaps te gebruiken @@ -791,6 +837,8 @@ Nieuw bericht Nieuwe shorts: afbeeldingen of video\'s Nieuwe community note + Nieuw product + Nieuw Geo-exclusieve post Open alle reacties op dit bericht Sluit alle reacties op dit bericht Antwoorden @@ -845,12 +893,29 @@ Plaats tussen de 1 tot 3 relays om gebeurtenissen op te slaan die niemand anders kan zien, zoals uw Concepten en/of app instellingen. Idealiter zijn deze relays lokaal of vereist authenticatie voordat de inhoud van elke gebruiker wordt gedownload. Algemene relays Amethyst gebruikt deze relays om berichten voor jou te downloaden. + Verbonden relays + Huidige lijst van relays die worden gebruikt Aanbevolen relays Voeg de volgende relays toe aan je algemene relay-lijst om berichten van de vermelde gebruikers te ontvangen. Relays zoeken Lijst van relays om te gebruiken bij het zoeken naar inhoud of gebruikers. Taggen en zoeken werkt niet als er geen opties beschikbaar zijn. Zorg ervoor dat ze NIP-50 implementeren. Lokale relays Lijst van relays die worden uitgevoerd op dit apparaat. + Vertrouwde relays + Vertrouwde relays + Relays die je vertrouwd om geen Tor te gebruiken + Proxy relays + Proxy relays + Aggregator relays die de app moet gebruiken om je feeds te downloaden, zoals filter.nostr.wine. Dit vervangt het outbox-model en zorgt ervoor dat de app alleen verbinding maakt met de relays in jouw lijsten. + Verzend relays + Verzend relays + Relays die gespecialiseerd zijn in het doorsturen van jouw notities naar alle andere relays, zoals sendit.nosflare.com. Amethyst zal dit relays toevoegen aan alle nieuwe evenementen die door jou worden gemaakt + Indexeer relays + Indexeer relays + Relays die gespecialiseerd zijn in het hosten van ieders metadata en relaylijsten, zoals purplepag.es. Amethyst zal deze relays gebruiken om gebruikers te vinden die niet in jouw lijsten staan. + Geblokkeerde relays + Geblokkeerde relays + Amethyst zal nooit verbinding maken met deze relays Zap de devs! Jouw donatie helpt ons om een verschil te maken. Elke sat telt! Nu doneren @@ -940,4 +1005,11 @@ Selecteer een lijst om de feed te filteren Afmelden bij apparaatvergrendeling Privébericht + Openbaar bericht + Chat relay + De relay die alle gebruikers van deze chat gebruiken om verbinding te maken + Afbeelding delen… + Zoek hashtag: #%1$s + Niet vertalen van + Talen die hier getoond worden worden worden niet vertaald. Selecteer een taal om te verwijderen en het opnieuw te laten vertalen. diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/publicMessages/PublicMessageEvent.kt b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/publicMessages/PublicMessageEvent.kt index f688b42df..28dbb7451 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/experimental/publicMessages/PublicMessageEvent.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/experimental/publicMessages/PublicMessageEvent.kt @@ -28,6 +28,7 @@ import com.vitorpamplona.quartz.nip01Core.core.any import com.vitorpamplona.quartz.nip01Core.hints.PubKeyHintProvider import com.vitorpamplona.quartz.nip01Core.signers.eventTemplate import com.vitorpamplona.quartz.nip10Notes.BaseNoteEvent +import com.vitorpamplona.quartz.nip19Bech32.entities.NProfile import com.vitorpamplona.quartz.nip19Bech32.pubKeyHints import com.vitorpamplona.quartz.nip19Bech32.pubKeys import com.vitorpamplona.quartz.nip31Alts.alt @@ -59,6 +60,19 @@ class PublicMessageEvent( fun groupKeySet() = tags.mapNotNullTo(mutableSetOf(this.pubKey), ReceiverTag::parseKey) + fun groupKeySetWithoutOwner() = tags.mapNotNullTo(mutableSetOf(), ReceiverTag::parseKey) - this.pubKey + + fun groupAsNProfileList() = + tags + .mapNotNull(ReceiverTag::parse) + .joinToString { + "nostr:" + NProfile.create(it.pubKey, it.relayHint) + } + + fun chatroomKey(user: HexKey) = groupKeySet() - user + + fun peopleAndContent() = groupAsNProfileList() + " " + content + companion object { const val KIND = 24 const val ALT_DESCRIPTION = "Public Message" diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NProfile.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NProfile.kt index 55c84758f..fe62fd4be 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NProfile.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip19Bech32/entities/NProfile.kt @@ -51,6 +51,19 @@ data class NProfile( return NProfile(hex, relay.mapNotNull { RelayUrlNormalizer.normalizeOrNull(it) }) } + fun create( + authorPubKeyHex: String, + relay: NormalizedRelayUrl?, + ): String = + TlvBuilder() + .apply { + addHex(TlvTypes.SPECIAL, authorPubKeyHex) + if (relay != null) { + addStringIfNotNull(TlvTypes.RELAY, relay.url) + } + }.build() + .toNProfile() + fun create( authorPubKeyHex: String, relays: List,