From b80f24b5870a4421f700b16d24bcc46e74d23bcb Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 08:42:07 -0500 Subject: [PATCH 01/60] Upgrades dependencies --- gradle/libs.versions.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 16dcbe64f..f5313db7e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] accompanistAdaptive = "0.37.3" activityCompose = "1.11.0" -agp = "8.13.0" +agp = "8.13.1" android-compileSdk = "36" android-minSdk = "26" android-targetSdk = "36" @@ -13,7 +13,7 @@ benchmark = "1.4.1" benchmarkJunit4 = "1.4.1" biometricKtx = "1.2.0-alpha05" coil = "3.3.0" -composeBom = "2025.10.01" +composeBom = "2025.11.00" coreKtx = "1.17.0" datastore = "1.1.7" espressoCore = "3.7.0" @@ -38,7 +38,7 @@ markdown = "f92ef49c9d" media3 = "1.8.0" mockk = "1.14.6" kotlinx-coroutines-test = "1.10.2" -navigationCompose = "2.9.5" +navigationCompose = "2.9.6" okhttp = "5.3.0" runner = "1.7.0" rfc3986 = "0.1.2" @@ -49,10 +49,10 @@ torAndroid = "0.4.8.19" translate = "17.0.3" unifiedpush = "3.0.10" urlDetector = "0.1.23" -vico-charts = "2.3.0" +vico-charts = "2.3.4" zelory = "3.0.1" -zoomable = "2.8.2" -zxing = "3.5.3" +zoomable = "2.9.0" +zxing = "3.5.4" zxingAndroidEmbedded = "4.3.0" windowCoreAndroid = "1.5.0" androidxCamera = "1.5.1" From 9f66cd0660f5f9c6c3128aa797dd251c1c94f394 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 09:10:56 -0500 Subject: [PATCH 02/60] Opens Follow Packs on following.space --- .../com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index 3ca426f39..df45d9c93 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -93,6 +93,7 @@ import com.vitorpamplona.amethyst.ui.theme.isLight import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward +import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import kotlinx.coroutines.launch @@ -125,6 +126,8 @@ val externalLinkForNote = { note: Note -> "https://listr.lol/a/${note.toNAddr()}" } else if (note.event is AudioTrackEvent) { "https://zapstr.live/?track=${note.toNAddr()}" + } else if (note.event is FollowListEvent) { + "https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}" } else { njumpLink(note.toNAddr()) } From 43fbf4f40f2de96645f703c5970bd60fe14097cd Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 09:11:09 -0500 Subject: [PATCH 03/60] Removes filestr --- .../vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index df45d9c93..18716dd0f 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -95,7 +95,6 @@ import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent -import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent import kotlinx.coroutines.launch private fun lightenColor( @@ -132,11 +131,7 @@ val externalLinkForNote = { note: Note -> njumpLink(note.toNAddr()) } } else { - if (note.event is FileHeaderEvent) { - "https://filestr.vercel.app/e/${note.toNEvent()}" - } else { - njumpLink(note.toNEvent()) - } + njumpLink(note.toNEvent()) } } From abcaf19d2b4b04ff04ccd3b9c550865d71735db1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 09:11:20 -0500 Subject: [PATCH 04/60] removes zapstr.live --- .../com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt index 18716dd0f..070403e87 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteQuickActionMenu.kt @@ -91,7 +91,6 @@ import com.vitorpamplona.amethyst.ui.theme.QuickActionPopupShadow import com.vitorpamplona.amethyst.ui.theme.SmallestBorder import com.vitorpamplona.amethyst.ui.theme.isLight import com.vitorpamplona.amethyst.ui.theme.secondaryButtonBackground -import com.vitorpamplona.quartz.experimental.audio.track.AudioTrackEvent import com.vitorpamplona.quartz.experimental.bounties.bountyBaseReward import com.vitorpamplona.quartz.nip51Lists.followList.FollowListEvent import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent @@ -123,8 +122,6 @@ val externalLinkForNote = { note: Note -> "https://nostrbounties.com/b/${note.toNAddr()}" } else if (note.event is PeopleListEvent) { "https://listr.lol/a/${note.toNAddr()}" - } else if (note.event is AudioTrackEvent) { - "https://zapstr.live/?track=${note.toNAddr()}" } else if (note.event is FollowListEvent) { "https://following.space/d/${note.address.dTag}?p=${note.address.pubKeyHex}" } else { From f186b78ca92ec91e90bde0c7fd348b749c4880e2 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 10:30:26 -0500 Subject: [PATCH 05/60] Adds test case for empty d-tags in naddr1 --- .../quartz/nip19Bech32/NIP19ParserTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt index 4fc3a33fb..63198581c 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip19Bech32/NIP19ParserTest.kt @@ -147,6 +147,18 @@ class NIP19ParserTest { ) } + @Test + fun nAddrIncompleteParser() { + val result = + Nip19Parser.uriToRoute( + "nostr:naddr1qqqqzxthwden5te0wfjkccte9ejxjanfdejjuanfv3jk7tczyrv4428upmlcujyf2fy4hqrynywj07ukakr99ufvmmw95n5tttj5qqcyqqqgt0qeresua", + ) + assertEquals( + "34236:d95aa8fc0eff8e488952495b8064991d27fb96ed8652f12cdedc5a4e8b5ae540:", + (result?.entity as? NAddress)?.aTag(), + ) + } + @Test fun nAddrParser2() { val result = From c9370f8d02686a828cbb4dbe3a908f230a05eee8 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 10:45:28 -0500 Subject: [PATCH 06/60] Better parse multiple imetas with multiple urls into appropriate properties --- .../vitorpamplona/quartz/nip19Bech32/Nip19Parser.kt | 5 +---- .../com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt | 10 +++------- .../com/vitorpamplona/quartz/nip92IMeta/TagArrayExt.kt | 2 +- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip19Bech32/Nip19Parser.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip19Bech32/Nip19Parser.kt index fdea6b724..4310d65b9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip19Bech32/Nip19Parser.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip19Bech32/Nip19Parser.kt @@ -89,10 +89,7 @@ object Nip19Parser { if (uri == null) return null try { - val matcher = nip19PlusNip46regex.find(uri) - if (matcher == null) { - return null - } + val matcher = nip19PlusNip46regex.find(uri) ?: return null val type = matcher.groups[3]?.value ?: matcher.groups[5]?.value // npub1 val key = matcher.groups[4]?.value ?: matcher.groups[6]?.value // bech32 diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt index 237b11d6b..dc8884856 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/IMetaTag.kt @@ -42,18 +42,14 @@ class IMetaTag( const val TAG_NAME = "imeta" const val ANCHOR_PROPERTY = "url" - fun parse(tag: Array): IMetaTag? { + fun parse(tag: Array): List? { ensure(tag.has(1)) { return null } ensure(tag[0] == TAG_NAME) { return null } ensure(tag[1].isNotEmpty()) { return null } val allTags = parseIMeta(tag) - val url = allTags[ANCHOR_PROPERTY]?.firstOrNull() - - return if (url != null) { - IMetaTag(url, allTags.minus(ANCHOR_PROPERTY)) - } else { - null + return allTags[ANCHOR_PROPERTY]?.map { + IMetaTag(it, allTags.minus(ANCHOR_PROPERTY)) } } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/TagArrayExt.kt index eaee8e5c3..8166224ad 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/TagArrayExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip92IMeta/TagArrayExt.kt @@ -22,6 +22,6 @@ package com.vitorpamplona.quartz.nip92IMeta import com.vitorpamplona.quartz.nip01Core.core.TagArray -fun TagArray.imetas() = this.mapNotNull(IMetaTag::parse) +fun TagArray.imetas() = this.mapNotNull(IMetaTag::parse).flatten() fun TagArray.imetasByUrl() = this.imetas().associateBy { it.url } From 05af3a78e4f229d618498c0e5c80403e921a03f6 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 10:45:58 -0500 Subject: [PATCH 07/60] Increases the contrast of placeholder text --- .../main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 4ffc25515..2ffb582e7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -104,8 +104,8 @@ private val LightMediumImportantLink = LightColorPalette.primary.copy(alpha = 0. private val DarkGrayText = DarkColorPalette.onSurface.copy(alpha = 0.52f) private val LightGrayText = LightColorPalette.onSurface.copy(alpha = 0.52f) -private val DarkPlaceholderText = DarkColorPalette.onSurface.copy(alpha = 0.32f) -private val LightPlaceholderText = LightColorPalette.onSurface.copy(alpha = 0.32f) +private val DarkPlaceholderText = DarkColorPalette.onSurface.copy(alpha = 0.52f) +private val LightPlaceholderText = LightColorPalette.onSurface.copy(alpha = 0.52f) private val DarkOnBackgroundColorFilter = ColorFilter.tint(DarkColorPalette.onBackground) private val LightOnBackgroundColorFilter = ColorFilter.tint(LightColorPalette.onBackground) From 19846e7ff3bd9b2572d53cbc38e040d644a19ca0 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 10:49:29 -0500 Subject: [PATCH 08/60] Improves the composition of NIP-05 lines --- .../ui/note/NIP05VerificationDisplay.kt | 42 ++++++++----------- .../amethyst/ui/note/NoteCompose.kt | 10 +++-- .../loggedIn/threadview/ThreadFeedView.kt | 13 +++--- .../ui/screen/loggedIn/video/VideoScreen.kt | 5 +-- 4 files changed, 33 insertions(+), 37 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt index 238f52c3b..48ad80fbf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NIP05VerificationDisplay.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.amethyst.ui.components -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding @@ -122,19 +121,17 @@ fun nip05VerificationAsAState( @Composable fun ObserveDisplayNip05Status( baseNote: Note, - columnModifier: Modifier = Modifier, accountViewModel: AccountViewModel, nav: INav, ) { WatchAuthor(baseNote = baseNote, accountViewModel) { - ObserveDisplayNip05Status(it, columnModifier, accountViewModel, nav) + ObserveDisplayNip05Status(it, accountViewModel, nav) } } @Composable fun ObserveDisplayNip05Status( baseUser: User, - columnModifier: Modifier = Modifier, accountViewModel: AccountViewModel, nav: INav, ) { @@ -143,14 +140,12 @@ fun ObserveDisplayNip05Status( CrossfadeIfEnabled( targetState = nip05, - modifier = columnModifier, accountViewModel = accountViewModel, ) { VerifyAndDisplayNIP05OrStatusLine( it, statuses, baseUser, - columnModifier, accountViewModel, nav, ) @@ -162,29 +157,26 @@ private fun VerifyAndDisplayNIP05OrStatusLine( nip05: String?, statuses: ImmutableList, baseUser: User, - columnModifier: Modifier = Modifier, accountViewModel: AccountViewModel, nav: INav, ) { - Column(modifier = columnModifier) { - Row(verticalAlignment = Alignment.CenterVertically) { - if (nip05 != null) { - val nip05Verified = - nip05VerificationAsAState(baseUser.info!!, baseUser.pubkeyHex, accountViewModel) + Row(verticalAlignment = Alignment.CenterVertically) { + if (nip05 != null) { + val nip05Verified = + nip05VerificationAsAState(baseUser.info!!, baseUser.pubkeyHex, accountViewModel) - if (nip05Verified.value != true) { - DisplayNIP05(nip05, nip05Verified, accountViewModel) - } else if (!statuses.isEmpty()) { - ObserveRotateStatuses(statuses, accountViewModel, nav) - } else { - DisplayNIP05(nip05, nip05Verified, accountViewModel) - } + if (nip05Verified.value != true) { + DisplayNIP05(nip05, nip05Verified, accountViewModel) + } else if (!statuses.isEmpty()) { + ObserveRotateStatuses(statuses, accountViewModel, nav) } else { - if (!statuses.isEmpty()) { - RotateStatuses(statuses, accountViewModel, nav) - } else { - DisplayUsersNpub(baseUser.pubkeyDisplayHex()) - } + DisplayNIP05(nip05, nip05Verified, accountViewModel) + } + } else { + if (!statuses.isEmpty()) { + RotateStatuses(statuses, accountViewModel, nav) + } else { + DisplayUsersNpub(baseUser.pubkeyDisplayHex()) } } } @@ -253,7 +245,7 @@ fun DisplayStatus( nav: INav, ) { val noteState by observeNote(addressableNote, accountViewModel) - val noteEvent = noteState?.note?.event as? StatusEvent ?: return + val noteEvent = noteState.note.event as? StatusEvent ?: return DisplayStatus(noteEvent, accountViewModel, nav) } 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 8442ffeed..85d2b2a6d 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 @@ -1062,10 +1062,12 @@ fun SecondUserInfoRow( verticalAlignment = CenterVertically, modifier = UserNameMaxRowHeight, ) { - if (noteEvent is BaseThreadedEvent && noteEvent.isAFork()) { - ShowForkInformation(noteEvent, remember(noteEvent) { Modifier.weight(1f) }, accountViewModel, nav) - } else { - ObserveDisplayNip05Status(noteAuthor, remember(noteEvent) { Modifier.weight(1f) }, accountViewModel, nav) + Column(modifier = remember(noteEvent) { Modifier.weight(1f) }) { + if (noteEvent is BaseThreadedEvent && noteEvent.isAFork()) { + ShowForkInformation(noteEvent, remember(noteEvent) { Modifier.weight(1f) }, accountViewModel, nav) + } else { + ObserveDisplayNip05Status(noteAuthor, accountViewModel, nav) + } } val geo = remember(noteEvent) { noteEvent.geoHashOrScope() } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index 9882f0106..e3f5068b9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -505,12 +505,15 @@ private fun FullBleedNoteCompose( } Row(verticalAlignment = Alignment.CenterVertically) { - ObserveDisplayNip05Status( - baseNote, + Column( remember { Modifier.weight(1f) }, - accountViewModel, - nav, - ) + ) { + ObserveDisplayNip05Status( + baseNote, + accountViewModel, + nav, + ) + } val geo = remember { noteEvent.geoHashOrScope() } if (geo != null) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt index 7053278c5..16a001a81 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/VideoScreen.kt @@ -311,7 +311,7 @@ private fun RenderAuthorInformation( nav: INav, accountViewModel: AccountViewModel, ) { - Row(modifier = Modifier.padding(start = 10.dp, end = 10.dp, bottom = 10.dp), verticalAlignment = Alignment.CenterVertically) { + Row(modifier = Modifier.fillMaxWidth().padding(start = 10.dp, end = 10.dp, bottom = 10.dp), verticalAlignment = Alignment.CenterVertically) { NoteAuthorPicture(note, Size55dp, accountViewModel = accountViewModel, nav = nav) Spacer(modifier = DoubleHorzSpacer) @@ -327,10 +327,9 @@ private fun RenderAuthorInformation( VideoUserOptionAction(note, accountViewModel, nav) } if (accountViewModel.settings.isCompleteUIMode()) { - Row(verticalAlignment = Alignment.CenterVertically) { + Row(modifier = Modifier.fillMaxWidth()) { ObserveDisplayNip05Status( note.author!!, - Modifier.weight(1f), accountViewModel, nav = nav, ) From e6a10e07c41828ba122d027d367c35769fc53e87 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 10:50:13 -0500 Subject: [PATCH 09/60] Correctly adding relays to the filters so that the Global feed can filter only events that came from the relays listed in the Global filter. --- .../amethyst/ui/dal/FilterByListParams.kt | 4 ++-- .../nip23LongForm/DiscoverLongFormFeedFilter.kt | 4 ++-- .../discover/nip28Chats/DiscoverChatFeedFilter.kt | 6 +++--- .../nip51FollowSets/DiscoverFollowSetsFeedFilter.kt | 4 ++-- .../nip53LiveActivities/DiscoverLiveFeedFilter.kt | 2 +- .../nip72Communities/DiscoverCommunityFeedFilter.kt | 6 +++--- .../discover/nip90DVMs/DiscoverNIP89FeedFilter.kt | 10 +++++++--- .../nip99Classifieds/DiscoverMarketplaceFeedFilter.kt | 4 ++-- .../feed/dal/FollowPackFeedConversationsFeedFilter.kt | 6 ++++-- .../loggedIn/home/dal/HomeConversationsFeedFilter.kt | 6 ++++-- .../gallery/dal/UserProfileGalleryFeedFilter.kt | 2 +- .../ui/screen/loggedIn/video/dal/VideoFeedFilter.kt | 2 +- 12 files changed, 32 insertions(+), 24 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt index accd8d685..d7b26ea33 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/dal/FilterByListParams.kt @@ -67,14 +67,14 @@ class FilterByListParams( fun match( noteEvent: Event, - comingFrom: List = emptyList(), + comingFrom: List, ) = ((isGlobal(comingFrom)) || isEventInList(noteEvent)) && (isHiddenList || isNotHidden(noteEvent.pubKey)) && isNotInTheFuture(noteEvent) fun match( address: Address?, - comingFrom: List = emptyList(), + comingFrom: List, ) = address != null && (isGlobal(comingFrom) || isAuthorInFollows(address)) && (isHiddenList || isNotHidden(address.pubKeyHex)) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/DiscoverLongFormFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/DiscoverLongFormFeedFilter.kt index ff1110fac..1e9464341 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/DiscoverLongFormFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip23LongForm/DiscoverLongFormFeedFilter.kt @@ -49,7 +49,7 @@ open class DiscoverLongFormFeedFilter( val notes = LocalCache.addressables.filterIntoSet(LongTextNoteEvent.KIND) { _, it -> val noteEvent = it.event - noteEvent is LongTextNoteEvent && params.match(noteEvent) + noteEvent is LongTextNoteEvent && params.match(noteEvent, it.relays) } return sort(notes) } @@ -67,7 +67,7 @@ open class DiscoverLongFormFeedFilter( return collection.filterTo(HashSet()) { val noteEvent = it.event - noteEvent is LongTextNoteEvent && params.match(noteEvent) + noteEvent is LongTextNoteEvent && params.match(noteEvent, it.relays) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip28Chats/DiscoverChatFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip28Chats/DiscoverChatFeedFilter.kt index c3b6a5da7..745f31a8c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip28Chats/DiscoverChatFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip28Chats/DiscoverChatFeedFilter.kt @@ -51,7 +51,7 @@ open class DiscoverChatFeedFilter( val note = LocalCache.getNoteIfExists(channel.idHex) val noteEvent = note?.event - if (noteEvent == null || params.match(noteEvent)) { + if (noteEvent == null || params.match(noteEvent, note.relays)) { note } else { null @@ -75,7 +75,7 @@ open class DiscoverChatFeedFilter( return collection.mapNotNullTo(HashSet()) { note -> // note event here will never be null val noteEvent = note.event - if (noteEvent is ChannelCreateEvent && params.match(noteEvent)) { + if (noteEvent is ChannelCreateEvent && params.match(noteEvent, note.relays)) { if ((LocalCache.getPublicChatChannelIfExists(noteEvent.id)?.notes?.size() ?: 0) > 0) { note } else { @@ -86,7 +86,7 @@ open class DiscoverChatFeedFilter( val channelEvent = channel?.event if (channel != null && - (channelEvent == null || (channelEvent is ChannelCreateEvent && params.match(channelEvent))) + (channelEvent == null || (channelEvent is ChannelCreateEvent && params.match(channelEvent, note.relays))) ) { if ((LocalCache.getPublicChatChannelIfExists(channel.idHex)?.notes?.size() ?: 0) > 0) { channel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/DiscoverFollowSetsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/DiscoverFollowSetsFeedFilter.kt index a6fc6c050..0f29d1b81 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/DiscoverFollowSetsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/DiscoverFollowSetsFeedFilter.kt @@ -48,7 +48,7 @@ open class DiscoverFollowSetsFeedFilter( val notes = LocalCache.addressables.filterIntoSet(FollowListEvent.KIND) { _, it -> val noteEvent = it.event - noteEvent is FollowListEvent && params.match(noteEvent) + noteEvent is FollowListEvent && params.match(noteEvent, it.relays) } return sort(notes) @@ -67,7 +67,7 @@ open class DiscoverFollowSetsFeedFilter( return collection.filterTo(HashSet()) { val noteEvent = it.event - noteEvent is FollowListEvent && params.match(noteEvent) + noteEvent is FollowListEvent && params.match(noteEvent, it.relays) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/DiscoverLiveFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/DiscoverLiveFeedFilter.kt index 2b1d0720c..856de6e36 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/DiscoverLiveFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip53LiveActivities/DiscoverLiveFeedFilter.kt @@ -72,7 +72,7 @@ open class DiscoverLiveFeedFilter( return collection.filterTo(HashSet()) { val noteEvent = it.event - noteEvent is LiveActivitiesEvent && filterParams.match(noteEvent) + noteEvent is LiveActivitiesEvent && filterParams.match(noteEvent, it.relays) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip72Communities/DiscoverCommunityFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip72Communities/DiscoverCommunityFeedFilter.kt index e0648c72f..9ab2c6f8b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip72Communities/DiscoverCommunityFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip72Communities/DiscoverCommunityFeedFilter.kt @@ -60,7 +60,7 @@ open class DiscoverCommunityFeedFilter( if (noteEvent == null && shouldInclude(key, filterParams, note.relays)) { // send unloaded communities to the screen note - } else if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent)) { + } else if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent, note.relays)) { note } else { null @@ -84,7 +84,7 @@ open class DiscoverCommunityFeedFilter( .mapNotNull { note -> // note event here will never be null val noteEvent = note.event - if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent)) { + if (noteEvent is CommunityDefinitionEvent && filterParams.match(noteEvent, note.relays)) { listOf(note) } else if (noteEvent is CommunityPostApprovalEvent) { noteEvent.communityAddresses().mapNotNull { @@ -93,7 +93,7 @@ open class DiscoverCommunityFeedFilter( if (definitionEvent == null && shouldInclude(it, filterParams, definitionNote.relays)) { definitionNote - } else if (definitionEvent is CommunityDefinitionEvent && filterParams.match(definitionEvent)) { + } else if (definitionEvent is CommunityDefinitionEvent && filterParams.match(definitionEvent, definitionNote.relays)) { definitionNote } else { null diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip90DVMs/DiscoverNIP89FeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip90DVMs/DiscoverNIP89FeedFilter.kt index 276a55743..5c3e8ef37 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip90DVMs/DiscoverNIP89FeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip90DVMs/DiscoverNIP89FeedFilter.kt @@ -34,6 +34,7 @@ import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthors import com.vitorpamplona.amethyst.model.topNavFeeds.noteBased.muted.MutedAuthorsByProxyTopNavFilter import com.vitorpamplona.amethyst.ui.dal.AdditiveFeedFilter import com.vitorpamplona.amethyst.ui.dal.FilterByListParams +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip51Lists.muteList.MuteListEvent import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent import com.vitorpamplona.quartz.nip89AppHandlers.definition.AppDefinitionEvent @@ -74,16 +75,19 @@ open class DiscoverNIP89FeedFilter( fun acceptDVM(note: Note): Boolean { val noteEvent = note.event return if (noteEvent is AppDefinitionEvent) { - acceptDVM(noteEvent) + acceptDVM(noteEvent, note.relays) } else { false } } - fun acceptDVM(noteEvent: AppDefinitionEvent): Boolean { + fun acceptDVM( + noteEvent: AppDefinitionEvent, + relays: List, + ): Boolean { val filterParams = buildFilterParams(account) return noteEvent.appMetaData()?.subscription != true && - filterParams.match(noteEvent) && + filterParams.match(noteEvent, relays) && noteEvent.includeKind(5300) && noteEvent.createdAt > lastAnnounced // && params.match(noteEvent) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/DiscoverMarketplaceFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/DiscoverMarketplaceFeedFilter.kt index a4c16b9e3..65b26e890 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/DiscoverMarketplaceFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip99Classifieds/DiscoverMarketplaceFeedFilter.kt @@ -49,7 +49,7 @@ open class DiscoverMarketplaceFeedFilter( val notes = LocalCache.addressables.filterIntoSet(ClassifiedsEvent.KIND) { _, it -> val noteEvent = it.event - noteEvent is ClassifiedsEvent && noteEvent.isWellFormed() && params.match(noteEvent) + noteEvent is ClassifiedsEvent && noteEvent.isWellFormed() && params.match(noteEvent, it.relays) } return sort(notes) @@ -68,7 +68,7 @@ open class DiscoverMarketplaceFeedFilter( return collection.filterTo(HashSet()) { val noteEvent = it.event - noteEvent is ClassifiedsEvent && noteEvent.isWellFormed() && params.match(noteEvent) + noteEvent is ClassifiedsEvent && noteEvent.isWellFormed() && params.match(noteEvent, it.relays) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/followPacks/feed/dal/FollowPackFeedConversationsFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/followPacks/feed/dal/FollowPackFeedConversationsFeedFilter.kt index 8d5e34deb..4895b9f7b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/followPacks/feed/dal/FollowPackFeedConversationsFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/followPacks/feed/dal/FollowPackFeedConversationsFeedFilter.kt @@ -34,6 +34,7 @@ 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.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent @@ -96,6 +97,7 @@ class FollowPackFeedConversationsFeedFilter( fun acceptableEvent( event: Event?, + relays: List, filterParams: FilterByListParams, ): Boolean = ( @@ -107,12 +109,12 @@ class FollowPackFeedConversationsFeedFilter( event is PublicMessageEvent || event is LiveActivitiesChatMessageEvent ) && - filterParams.match(event) + filterParams.match(event, relays) fun acceptableEvent( note: Note, filterParams: FilterByListParams, - ): Boolean = acceptableEvent(note.event, filterParams) && !note.isNewThread() + ): Boolean = acceptableEvent(note.event, note.relays, filterParams) && !note.isNewThread() override fun sort(items: Set): List = items.sortedWith(DefaultFeedOrder) } 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 441404d44..ad9757837 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 @@ -31,6 +31,7 @@ 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.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent import com.vitorpamplona.quartz.nip22Comments.CommentEvent import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent @@ -74,6 +75,7 @@ class HomeConversationsFeedFilter( fun acceptableEvent( event: Event?, + relays: List, filterParams: FilterByListParams, ): Boolean = ( @@ -85,12 +87,12 @@ class HomeConversationsFeedFilter( event is PublicMessageEvent || event is LiveActivitiesChatMessageEvent ) && - filterParams.match(event) + filterParams.match(event, relays) fun acceptableEvent( note: Note, filterParams: FilterByListParams, - ): Boolean = acceptableEvent(note.event, filterParams) && !note.isNewThread() + ): Boolean = acceptableEvent(note.event, note.relays, filterParams) && !note.isNewThread() override fun sort(items: Set): List = items.sortedWith(DefaultFeedOrder) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/dal/UserProfileGalleryFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/dal/UserProfileGalleryFeedFilter.kt index 95c41aae5..63955e745 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/dal/UserProfileGalleryFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/gallery/dal/UserProfileGalleryFeedFilter.kt @@ -72,7 +72,7 @@ class UserProfileGalleryFeedFilter( return ( (it.event?.pubKey == user.pubkeyHex && (noteEvent is PictureEvent || noteEvent is VideoEvent || (noteEvent is ProfileGalleryEntryEvent) && noteEvent.hasUrl() && noteEvent.hasFromEvent())) // && noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET)) ) && - params.match(noteEvent) && + params.match(noteEvent, it.relays) && account.isAcceptable(it) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/dal/VideoFeedFilter.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/dal/VideoFeedFilter.kt index 129fe777d..6646dac18 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/dal/VideoFeedFilter.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/video/dal/VideoFeedFilter.kt @@ -126,7 +126,7 @@ class VideoFeedFilter( (noteEvent is FileStorageHeaderEvent && noteEvent.isOneOf(SUPPORTED_VIDEO_FEED_MIME_TYPES_SET)) || (noteEvent is PictureEvent && acceptanceEvent(noteEvent)) ) && - params.match(noteEvent) && + params.match(noteEvent, note.relays) && (params.isHiddenList || account.isAcceptable(note)) } From e5fe63d63031b69977fbd2374ded16cb09f40dcd Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Thu, 13 Nov 2025 15:53:22 +0000 Subject: [PATCH 10/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-sl-rSI/strings.xml | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index b88552788..b3d58f189 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -21,13 +21,13 @@ Nedovoljeno obnašanje Drugo Nadlegovanje - Neznano + Nepoznano Ikona releja Avtor neznan Kopiraj tekst Kopiraj ID avtorja Kopiraj ID zapiska - Oddajanje + Razpošlji Uporabi časovni žig Časovni žig: Potrditve v obdelavi OTS: V obdelavi @@ -102,11 +102,11 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Najlepša hvala! Vsota v Sat Pošlji Sat - Orodje za emodžije s skrivnostmi - Izberi emodži za pošiljanje s skritim sporočilom - Sprejem skrivnosti - Moja skrita sporočila - Vidni prefiksi + Orodje za emoji s skrivnostmi + Izberi emoji za pošiljanje s skritim sporočilom + Skrivno sporočilo + Moje skrito sporočilo + Vidna predpona 😎 Dodaj v zapisek "Napaka pri razčlembi predogleda za %1$s : %2$s" @@ -173,11 +173,11 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Kopiraj ID kanala (zapisek) v odložišče Uredi metapodatke kanala Pridruži se - Znano + Poznani Nova prošnja Blokirani uporabniki Nove objave - Pogovori + Razprave Vsebine Moderatorska vrsta Zapiski @@ -461,6 +461,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Globalno Spisek utišanih Seznam sledenih + To so seznami sledenih, namenjeni za vašo lastno uporabo. Uporabnike lahko sledite javno ali zasebno Označeni zaznamki Splošni zaznamki Javno @@ -495,6 +496,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Nov seznam s %1$s člani Ustvari nov set sledenih, ter doda %1$s kot %2$s člana. Nov seznam sledenih + Nov paket sledenih Kopiraj/Kloniraj seznam sledenih Spremeni opis Ta seznam nima opisa @@ -645,6 +647,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Spremljana vsebina Releji Paketi sledenih + To so seznami uporabnikov, ki jih priporočate drugim. Dovoljeni so le javni uporabniki. Branje Algoritmi vsebin Tržnica From 23299b5ef3f71078e7e793dd7a2e265236a48140 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Thu, 13 Nov 2025 18:25:49 -0500 Subject: [PATCH 11/60] half-way contrast for placeholder texts --- .../main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index 2ffb582e7..5f876fb25 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -104,8 +104,8 @@ private val LightMediumImportantLink = LightColorPalette.primary.copy(alpha = 0. private val DarkGrayText = DarkColorPalette.onSurface.copy(alpha = 0.52f) private val LightGrayText = LightColorPalette.onSurface.copy(alpha = 0.52f) -private val DarkPlaceholderText = DarkColorPalette.onSurface.copy(alpha = 0.52f) -private val LightPlaceholderText = LightColorPalette.onSurface.copy(alpha = 0.52f) +private val DarkPlaceholderText = DarkColorPalette.onSurface.copy(alpha = 0.42f) +private val LightPlaceholderText = LightColorPalette.onSurface.copy(alpha = 0.42f) private val DarkOnBackgroundColorFilter = ColorFilter.tint(DarkColorPalette.onBackground) private val LightOnBackgroundColorFilter = ColorFilter.tint(LightColorPalette.onBackground) From f400cc60889195d088374c5a3eba63a8635f9ee0 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 14 Nov 2025 19:07:52 -0500 Subject: [PATCH 12/60] Adds a change log --- CHANGELOG.md | 6653 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 6653 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 000000000..ee04cf446 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,6653 @@ + +# [Release v1.04.0: List Management](https://github.com/vitorpamplona/amethyst/releases/tag/v1.04.0) - 2025-11-15 + +#Amethyst v1.04.0: List Management + +This version adds support for creating, managing, deleting, and viewing follow lists, which include +both public and private members. We've also added similar UI to support for creating, managing, +deleting, and viewing follow packs from following.space, allowing you to assemble following lists +not only for yourself,but also as a starter packs for other users. + +This version also introduces significant improvements to the quality of video compression and hash +checks during media upload/download, along with new codecs and a new image gallery for displaying +sequences of images in posts. The startup loading of outbox relay lists and user metadata for large +follow lists (> 1000 people) has been significantly improved with new mechanisms to search for missing +outbox relay lists. + +The Top Bar filter "All Follows" now merges all follow lists, follow packs, following hashtags, +following geotags, and following communities into a single feed. Two new options were also added: +"All User Follows," which includes only the main and other follow lists, and "Default Follow List," +which is the standard follow list used by every client. + +Finally, we completed our Quartz migration to Kotlin Multiplatform, added significant +performance improvements when processing events and running cryptographic procedures, as well +as new ease-of-use extensions. + +New Features: +- People List creation and management by @npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k +- Follow Pack creation, management and feed view +- Image gallery in posts by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Finishes migration of Quartz to Kotlin Multiplatform +- New Filters in the top nav bar +- Performance improvements across all features + +Improvements: +- Adds support to rejection replies from NIP-55 signers by @npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Adds live/offline indicator to live bubbles by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Refines the video compression procedure by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Replaces MP4 parser libraries with native MediaMuxer / MediaCodec by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Adds a H.265/HEVC codec to reduce file size by up to 50% while maintaining the same quality by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Optimizes video file structure by moving metadata to the beginning, so videos start playing more quickly by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Adds "All User Follows" feed filter in the top nav bar that removes hashtags, communities and geotag follows +- Adds "Default Follow List" feed filter in the top nav bar that contains only Kind 3 follows +- Shows a dialog to select a signer when using multiple signers are present by @npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Saves bandwidth by avoiding constant REQ updates before EOSEs come back in a subscription +- Changes the following icon on top of user's pictures to include follows in all lists and follow sets +- Removes non-outbox relays from the outbox lists +- Adds support bigger, up to 4GB, payloads in NIP-44 +- Restructures the default REQ limits from each relay in all feeds +- Adds a guarantee incoming message order to OkHttp websocket implementations to aviod EOSE mismatch +- Only downloads DMs and Drafts if the account is writeable / nsec is present +- Adds support for copying/cloning follow lists in the UI. +- Adds a default relay list for indexers in new accounts with local backup +- Smoothes the disappearing effect for the Top and Bottom navigation. +- Adds support for NWC deep links and removes hardcoded Alby integration +- Adds a missing outbox relay list popup on posting new notes +- Adds a missing inbox relay list check on notification screens +- Migrates to njump.to to disperse shareable links + +Quartz: +- Migrates Quartz from Android to CommonMain (Kotlin Multiplatform) +- Adds a maven publishing to ship quartz +- Fully converts OpenTimestamp Java codebase to Kotlin, migrating the sync and async HTTP call interfaces to OkHttp and coroutines +- Redesigns parsing of relay commands, messages and filters for performance in Jackson. +- Uses KotlinX Serialization when speed is not a requirement +- Migrates all Jackson field annotations to Kotlin Serialization +- Migrates Regex use in Quarts to Kotlin's Regex class +- Migrates Base64 library from Android to Kotlin +- Migrates UUID library from Android/Java to Kotlin +- Migrates LRUCache usage from Android/Java to Kotlin collections +- Migrates all String to bytearray conversions to Kotlin methods +- Migrates all System.arraycopy calls to kotlin native ones. +- Separates parsing code from the data classes in Companion objects +- Exposes Rfc3986 normalizations to each platform. +- Exposes URI parsing classes to each platform. +- Exposes URL Encoders to each platform. +- Exposes BigDecimal to each platform. +- Exposes the Url Detector to each platform. +- Exposes Mac instances to each platform +- Exposes Diggest instances to each platform. +- Exposes BitSet to each platform. +- Exposes GZip to each platform. +- Exposes Secp256k1 to each platform. +- Exposes SecureRandom to each platform. +- Exposes Time in seconds to each platform. +- Exposes the LargeCache to each platform. +- Exposes AES CBC and AES GCM encryption/decryption to each platform +- Migrate test assertions to Kotlin Tests +- Exposes Address class to each platform because of the Parceleable requirement in Android +- Creates our own ByteArrayOutputStream. +- Removes threadsafe features inside our Bloomfilters because we don't need that consistency +- Migrates UserMetadata parser from Jackson to Kotlin serialization +- Removes @Static methods in each tag. +- Adds an EventTemplate serializer +- Removes the need for KotlinX Datetime +- Adds support for LibSodium in the JVM desktop platform +- Creates a shared test build for iOS targets +- Increases the Bloom filter space to better use hints in the app. +- Removes support for iOS in x86 +- Creates a performant JacksonMapper just for NIP-55, which stays in the Android build only. +- Keeps the event store in the android build due to the SQL Lite dependency +- Removes @syncronized tags in favor of Mutexes. +- Improved sendAndWaitForResponse NostrClient method to properly account for returns from each relay. +- Removes the need for GlobalScope and async calls +- Removes the dependency on Jackson's error classes across the codebase. +- Moves the hint to quote tag extension methods to their own packages. +- Migrates NIP-06 and Blossom uploads to use Kotlin Serialization +- Adds ease of use functions for the downloadFirst nostr client extension method +- Refactors error logging in BasicRelayClient +- Starts NostrClient in active instead of waiting for a connect() call +- Adds initial test cases for NostrClient and extensions +- Adds an option to ignore failed reconnection delays that should be used when the network settings change. +- Adds a build template option for NIP-42 AUTHs +- Moves quartz to Java 21 due to binary inconsistencies between the multiple builds of KMP (tests conflicting with main) +- Adds support for COUNT relay messages +- Treat COUNT as query only, not subscriptions in the NostrClient +- Moves statistics collection out of the inner classes to be an external option for app developers instead. +- Restructuring relay classes to maintain order of incoming messages for relay listeners +- Defers all processing of incoming messages to coroutines via channels, freeing OkHttp's thread as soon as possible. +- Simplifies the main relay class by using attached listener modules for each function of the relay client. +- Migrate defaultOnConnect calls to become listener based and moved to NostrClients +- Coordinates REQs so that if an update is required to be sent but the server has not finished processing events, waits for it to finish and sends it later as soon as EOSE or Close arrives +- Correctly maintain the local and server state of each Req. +- Avoid subsequent REQ updates before EOSE or CLOSE calls. +- Refactors NostrClient authenticators to do complete operation as an optional module +- Breaks down Relay Client modules (Auth, Reqs, Counts, Event submissions) in the Relay Pool class. +- Creates listeners just for REQ subscriptions +- Move statistics to outside the base relay class as a listener +- Move logs to outside the base relay class as a listener +- Better structures a Standalone Relay client +- More appropriately communicate errors to the listeners +- Remove relay states on listeners, move each to its own method +- Removes the hardcoded Dispatchers on Quartz +- Adds streaming hash utility function, follow the existing pool/worker design +- Adds fast search for events and addresses in the Deletion Event +- Adds an update method for to create a new event template from an event. + +Fixes and UI Improvements: +- Changes the DVM feed to sort by follows that liked or zapped the DVM +- Changes the icon of account preferences to translation for now +- Improves click and long press interactions with the relay list item and status bar items +- Fixes the visual references to communities and hashtags in the top right of the post +- Removes disappearing top and bottom bars from settings screens +- Fixes tall top bars on Ephemeral and Public Chat rooms +- Fixes lack of live stream name on the top bar +- Fixes animations to navigate from and to list screens +- Fixes cursor behind the keyboard when typing long texts. +- Fixes line wrap in the relay info top nav bar title +- Moves message button to Profile Actions +- Fixes User profile banner being off place in short images +- Also fixes spacing of the Follow button +- Adds an option to render a user gallery from hex keys instead of full User objects +- Adds context to the highlights +- Increases the contrast of placeholder text +- Refines performance of the QuickAction menu bar +- Fixes hidden words not being applied to NIP-04 DMs on notifications +- Fixes not loading some event kinds in notifications +- Fixes crash when updating a metadata with null name +- Fixes crash when attempting to share an image that is still loading by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes disappearing stats on relay screen by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes proper switch between single and two-pane layouts on rotation by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes sendAndWaitForResponse never receiving a response by @npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Fixes NWC URI parsing bug by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes bookmark removal from Private/Public removing from both by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes OutOfMemoryError for large file uploads by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes DecryptZapRequest CommandType by @npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Fixes location being added to note even after deselecting it by @npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Fixes crash when trying to parse unparseable NIP-11s +- Prevents resource leaks with file streams by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Removes any relay url that has a percent-encoded null byte, regardless of size +- Forces streaming url online check when the stream is offline but the user enters the chat +- Fixes duplicated loading of NIP-11 relay info by different parts of the screen +- Fixes the new Video events as non replaceable, while keeping the old ones in the replaceable +- Fixes crash on starting when the contentResolver is not ready yet. +- Fixes addressable deletions deleting not only the past when updating feeds +- Fixes long form previews when missing the author's picture +- Fixes feed filter update when changing the top nav filter +- Fixes crash when sorting with the same createdAt in the discovery feeds +- Fixes reply routes when clicking in the Conversations tab when the event is a PublicChat, LiveStream or Ephemeral Chat +- Fixes livestream chats appearing on home bubbles after the live stream is finished +- Fixes not sending the live stream events anywhere when the stream doesn't have a relay set declared +- Fixes animations when selecting Tor options in the privacy screen +- Fixes animations jumping when loading privacy screen +- Fixes the use of index relays and search relays to load users and events as well as become the default for global feeds. +- Fixes mark as read when drafts are the latest message in the chat +- Fixes showing blog posts in the future in the Discovery reads +- Fixes crashing when comparing int and long in Live Events comparator +- Fixes recompositions of subject add-on to text on rendering +- Fixes crash on trying to change dont translate from options +- Fixes NPE on the ln invoice callback with errors parser +- Fixes parsing encrypted NIP-28 chats +- Fixes disappearing relay stats (larger LRU cache) +- Fixes sendAndWait nostr client coroutine that was waiting forever +- Fixes lack of req by forcing an updateFilter at the start of new subs with the client. +- Fixes bug that skipped loading follow's metadata on startup +- Fixes issues when unfollowing a hashtag from old contact lists +- Fixes relay list flickering bug +- Fixes crash when checking and creating new users from `p` tags. +- Fixes the author of the highlight +- Fixes scope lifecycle of media uploads to avoid cancellation while uploading +- Fixes parser for null and default values from NIP-55 using Jackson +- Fixes relay icons not showing up when sending DMs +- Fixes imeta parsing with multiple urls +- Fixes relay-specific global feed matching incoming note checks +- Fixes video progressive download by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fixes several usages of Reflection when serializing classes +- Fixes a bug on loading event test database for the HintBloom filter test +- Forces relay status updates when connecting and disconnecting +- Only shows live stream bubbles that are not playing 24/7 with active follows in the past 15 minutes. +- Opens Follow Packs on following.space + +Performance: +- Restructures the parser and serialization of the relay messages and commands for performance +- Speeds up the generation of Bech32 addresses +- Migrates memory counters from Long to Int +- Avoids using JSON parsers with DataStore to speed up loading time (loading the parser itself takes ~300ms) +- Adds new benchmarks for NIP-44 operations +- Reduces memory consumption for NIP-44 operations, avoiding GC +- Faster Hkdf functions with less array copying and allocations (which can be impactful if the ciphertext is large) +- Faster Mac calculations by avoiding array assemblies before calling the function +- Faster Hash check calculations avoiding the creation of a separate bytearray to compare ids +- About 30-40% event hashing performance boost by building the json by hand and skipping string encoders when not needed. +- 30% Faster isHex for strings with precisely 32 bytes. +- Loads the main account in parallel faster before the screen needs it +- Merge expanding and checking HMac functions to avoid re-creating the Mac instance. +- Separates EOSE cache for drafts alone. +- Speeds up the loading of users in follow lists on start up +- Speeds up OkHttp startup +- Adds submap index queries to the addressable large cache +- Performance improvement for the address serializer. +- Adds a default cut off for notifications from random relays to 1 week ago. +- Increases local video disk cache to 1GB +- Defers the initialization of disk caches for videos and images to a few seconds after loading +- Only listens to notification feed changes when the UI is visible +- Separates a relay failure tracker to a module +- Caches the User object for each Account to avoid being deleted by the soft reference on Local Cache +- Moves all Dispatchers.Default to the IO threadpool because of the amount of Synchronized code in dependencies blocking heavy threads +- Only download reports from the author's outbox relay if we have it (don't use our default bootstrapping relays for reports) +- Keep a local cache of following geoshahes and hashtags in lowercase. +- Don't intern signatures, content and stringified tags since they are not usually duplicated +- Unifies the parser for the tag array across the app +- Adds simplified extensions to create Requests from NostrClient +- Adds a Start request callback to the request listener +- Adds a req that returns the list of events in order of arrival +- Adds a flatten straight into a set utility +- Adds a decrypted people and follow list cache on the account class and updates TopNav to use the new caching +- Creates slim ListItem composables +- Marks address, user states, edits and channel metadata view models as Compose Stable +- Removes unnecessary list of icons drawer rows, which affected Compose stability +- Improves the composition of NIP-05 lines +- Adds a pre-parser to find image galleries and video links before rendering. +- Adds the user outbox relays when loading addressables by that user. +- Avoids sending CLOSE to subs that are already closed. +- Rejects additional urls with %20 and fixes "Wss" ones. + +Code Quality +- Reduce http max requests when in emulator to avoid crashing by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Resolve intermittent CI build failures by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Fix benchmark apk location by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Change from runBlocking to runTest where appropriate by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Reduce errors in log: concurrent modification exception by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Moves the precision of mills to seconds on the isOnline Check +- Migrates to use suspending routines for OTS, statuses and edit flows +- Unify outbox calculation in the RelayOutbox loader +- Refactors zap the devs card view +- Creates an interface for NostrClient strategies +- Adds an isMobileOrFalse flow in connectivity to speed UI updates +- Removes one of the Application dependencies in viewmodel +- Changes the Theme class to only take the preferred theme directly. +- Adds dependency on NWC to Account to avoid linking directly with the Application class +- Migrates Account management to an Application lifecycle to prepare for multi-account screens +- Establishes a scope for each account loaded so that flows can be killed on sign off +- Moves the event processor to the Account class +- Creates an interface for the DualHttpClientManager to allow IDE previews +- Removing the dependency on an application class from AccountViewModel +- Removes dependency on the viewModel on AccountFeedStates +- Moves account saving from StateViewModel to Account +- Removes dependency on the application class from DecryptAndIndexProcessor +- Changes the name and singleton of the nav to avoid confusing the auto import +- Switches account cache to a flow to allow observers +- Removes dependency in the Amethyst class from Playback calculator +- Removes the dependency on windowSizeClass and displayFeatures to be passed in the global preferences of the app (which is activity independent) +- Moves the OTS processor from Account's decrypt process to Application since it doesn't need the account information. +- Separates Application dependencies into an AppModules class to create only after the OnCreate event. +- Switches TorSettings to be per Application and not per Account anymore +- Since TorSettings is now global, moves the okHttpClient determinations out of the Account-based classes into the Application. +- Since TorSettings is now global, set's up Coil's image loader only once when creating the Application +- Moves UISettings state to App Modules instead of viewmodel +- Migrates TorSettings and UISettings to DataStore +- New tor evaluator service for relay connections now uses all account's trusted relays and dm relays at the same time. +- Migrates composable-state-based UISettings to Flow-based UI settings, while observing connectivity status +- Removes the displayFeatures and windowSizeClass from the shared model +- Fixes not requesting Notification Permissions for APIs older than Tiramisu in the FDroid flavor +- Moves the NIP-11 document cache from singleton to the App Modules +- Avoids using AccountViewModel to check NIP-11 Relay documents +- Moves the UI Settings usage in composables to functions that do not observe the state since they don't need to refresh the screen when changed. +- Refactors UI Settings screen to separate components and remove the sharedViewModel +- Only starts Internal Tor if that option is selected in the TorSettings. +- Turn TorSettings into a data class to observe changes to it +- Drops the SharedPreferences ViewModel to use UISettingsFlow directly from App Modules +- Reorganizes OTS Events after simplification of the OkHttp based on TorSettings. +- Applies memory trimming service to all logged-in accounts at the same time +- Adds a test for native vs libsodium chacha20 +- Added test for emulator to set maxRequests to 128 to prevent crashing emulator by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Dumps the number of relay hints urls in the DB +- Creates our own Coil Logger to minimize trash stacks in the logs +- Adds a declared outbox lists for follows state +- Removes the deprecated hacks to store communities, hashtags and geohashes on Contact Lists +- Updates deprecated Clipboard manager +- Updates emoji and user autocomplete state to use Account and avoid linking AccountViewModel +- Refactors many viewModels to avoid using callback lambdas +- Correctly marks EOSE for filters that are aligned with the Req State from NostrClient +- Changes User loading features in a tentative to make them faster since they are used by all functions in the app. +- Creates an Account follow list per Relay state that only includes shared relays as a better source of functioning relays + +Deprecations: +- Removes fmt.wiz.biz from bootstrap relays +- Removes void.cat from default servers by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Removes filestr share links +- removes zapstr.live share links + +Updated translations: +- Czech, German, Swedish and Portuguese by @npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Hindi by @npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6 +- Slovenian by @npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw +- Polish by @npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm +- Hungarian by @npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp @npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp +- Spanish by @npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903 +- Latvian by @npub1l60stxkwwmkts76kv02vdjppka9uy6y3paztck7paau7g64l687saaw6av +- Dutch by @npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd +- French by @npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz +- Chinese by @npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h +- Thai by @npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e +- Persian by @npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk + +Download: http://amethyst.social + + +# [Release v1.03.0: Built-in video recording](https://github.com/vitorpamplona/amethyst/releases/tag/v1.03.0) - 2025-09-02 + +#Amethyst v1.03.0: Built-in video recording + +New Features: +- Adds "record and post video" button to new Post Screens by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Updates the User Profile's Relay List to an outbox version +- Activates live streams to the top feed bubble +- Enables the use of custom TextToSpeech Engines + +Improvements: +- Improves the list of visible authors on live stream bubbles +- Adds the error status to the URL normalizer to avoid checking it again +- Adds a follow list state from kind 3 to keep following users in memory. +- Moves from RelationshipStatus to ContactCard as per NIP update + +Fixes: +- Removes crashing relay URIs with null-encoded bytes (%00) +- Reverts to using androidLibrary plugin for Quartz until KMP publishing guidance is updated. by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) +- Fixes product title when in a quoted post +- Fixes live flag for streaming when the URL is not available anymore. +- Fixes bug on opening the Relay Settings page with duplicated Trusted and Blocked relays. +- Avoids NPEs in the maxOfOrNull iterator with concurrent lists +- Assemble NIP-17 Crash Report properties as a table and crash as a code block +- Improves the design of the Crash Report permission screen with a cancel button. +- Adds basic support for expirations in DMs + +Updated Translations + +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Hungarian by [@npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp](https://github.com/npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp) + +Download: http://amethyst.social + +[Changes][v1.03.0] + + + +# [Release v1.02.1](https://github.com/vitorpamplona/amethyst/releases/tag/v1.02.1) - 2025-08-29 + +- Upgrade AGP to 8.12.2 +- Sets Quartz to Java 1_8 +- Creates a bootstrap relay list specifically for inbox relays +- Register lists as Account fields to avoid GC of user settings. +- Fixes inability to delete relays from certain relay lists. + +[Changes][v1.02.1] + + + +# [Release v1.02.0 NIP-17 Crash report DMs](https://github.com/vitorpamplona/amethyst/releases/tag/v1.02.0) - 2025-08-28 + +#Amethyst v1.02.0: NIP-17 Crash report DMs + +- Adds a crash interceptor and offers to send crash reports via NIP-17 +- Fixes startup crash on Android 12 or earlier +- Removes old DB migration +- Fixes crash when pasting an invalid NIP-47 URI into the zap settings +- Fixes crash when NWC doesn't return an invoice preimage +- Fixes crash when loading a user with a null name +- Fixes readonly crash on DVM requests +- Speeds up first-time logins by not waiting for Tor +- Fixes a parser benchmark +- Moves test assets to resources to make it work with kmp +- Migrates Quartz to a KMP project +- Converts OpenTimestamps code from Java to Kotlin +- Moves OTS OkHttp setup to Quartz +- Migrates NIP-49 from Java to Kotlin +- Removes nostr.bg from bootstrap relays +- Updates translations + +Download: http://amethyst.social + +[Changes][v1.02.0] + + + +# [Release v1.01.0: New Community Implementation](https://github.com/vitorpamplona/amethyst/releases/tag/v1.01.0) - 2025-08-27 + +Features: +- Upgrades NIP-72 communities to use NIP-22 comments as root posts +- Adds moderation queue feed +- Adds in-app approval procedures +- Adds drafts for community posts +- Redesigns the "about us" section of communities. + +Fixes: +- Fixes accessibility TalkBack issues +- Fixes the edit draft button in the long-press menu +- Fixes the inability to delete relays from some lists. +- Fixes unwanted NOTIFY requests from other people's relay lists +- Fixes some DM push notification issues +- Fixes notification registration for first-time logins +- Avoids sending expired events to the relays +- Fixes draft deletes staying in some feeds +- Intercepts backhandler to save drafts +- Moves draft deletion calculations out of the UI thread + + +[Changes][v1.01.0] + + + +# [Release v1.00.5](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.5) - 2025-08-23 + +- Fixes a crash from multiple relays in the same line when following two specific users +- Updates translations + +[Changes][v1.00.5] + + + +# [Release v1.00.4](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.4) - 2025-08-22 + +- Fixes the new post screen not closing after posting and rejecting drafts. +- Fixes the disappearance of drafts. +- Improving loading speeds by using a separate OkHttp threadpool for DM relays and another for media. +- In case a user does not have an outbox list, it defaults to all hints seen for that user. + +[Changes][v1.00.4] + + + +# [Release v1.00.3: More fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.3) - 2025-08-22 + +- Fixes the lack of feed update for those who didn't follow any community. +- Avoids parsing AI-bad NIP-28 objects +- Don't try to decrypt appData unless it is a writeable account +- streamlines function calls on AccountViewModel +- Removes the HEAD from the release build name + +[Changes][v1.00.3] + + + +# [Release v1.00.2: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.2) - 2025-08-21 + +Fixes follow/unfollow from hashtags and geohashes +Migrates top nav list to hashtag, geohash and community lists +Fixes community join/leave crash +Fixes branch name +Avoids crash when lacking google services in the play version. +Fixes crash when typing a new post without permissions to do a draft post. + +[Changes][v1.00.2] + + + +# [Release v1.00.1: Fix app name](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.1) - 2025-08-21 + +fix app name + +[Changes][v1.00.1] + + + +# [Release v1.00.0: Full Outbox](https://github.com/vitorpamplona/amethyst/releases/tag/v1.00.0) - 2025-08-21 + +#Amethyst v1.00.0: Full Outbox + +This version completes our migration to the outbox model, where the app dynamically manages the relay list used to pull posts from your follows' own relay lists. By default, the app will connect to relays that aren't in your lists through our embedded Tor. Normal usage will connect to hundreds of relays. Many of them will fail, and that's ok. Nostr has baked-in redundancy; these failures won't affect your experience. + +New relay lists were added to the UI to help you manage how the app works. Specifically, you can now block relays and add trusted relays. Trusted relays will connect outside of Tor, which is faster, but allows those relays to see your IP. You should only add relays there if you trust the relay operator. Proxy relays (like filter.nostr.wine) can be added to the proxy list. After that, the app will only use those relays to download the content for your feeds, disabling the outbox model. DMs and other non-outbox functionality will still use their own relays. Broadcasting relays can be added to push your events out there. Every new event from the app will be sent to all broadcasting relays. Finally, the new Indexer list allows you to choose which relays to use to find users, like purplepages.es. + +For users of our Quartz library, we have finished all of the work to change the library's mindset from a fixed list to a dynamic pool of relays. Now, each NIP has its own dedicated folder and defines its own tags and caching structures. This expansion allows us to add diverse functionalities such as relay clients, relay servers, event builders, Nostr filter builders, caching systems, deletion and event hint indexers, helper functions, and more—all specifically tailored to each individual NIP. This modular approach creates the space to develop each NIP independently and integrate them into Amethyst as distinct modules, while still sharing Amethyst's main relay and cache engine when necessary. We expect fewer breaking changes as we move forward with it. At some point, Quartz will move to its own repository and be converted to a Kotlin Multiplatform project for each NIP/module. This will allow us to build demo/testing applications for each NIP in the same repo. + +This version adds support for: +- YakBak Voice Messages +- Picture-in-Picture pop-ups +- Public Messages +- Coolr.chat's Ephemeral Chats +- Follow packs +- Reads feed in the discovery tab +- Hidden cashu tokens in emojis + +Features: +- Reengineered relay, relay pool, and nostr client to manage dynamic pools +- Reengineered note cache for a garbage collector-friendly version +- Reengineered media pre-loading and caching to minimize layout changes +- Reengineered decryption cache, now per account +- Reengineered chat channels cache +- Reengineered the indexing of Addresses to data classes +- Reengineered EOSE cache and managers +- Migrates to a Flow-based design for all account information and services +- Migrates to a Compose subscription model for relay filters +- Adds 90-day expiration to all drafts +- Deprecate stringified JSON in favor of tags on user metadata kind 0 events +- Adds support for live events at the top of the feed. +- Migrates Video events to non-replaceable kinds +- Migrates NIP-51 to use NIP-44 encryptions +- Migrates Chat, Community, Location, and Hashtag follows to their own lists +- Migrates to reply with NIP-22 for everything but kind 1s. +- Massively improves relay hint selections +- Removes relay picker when sending new posts +- Removes general relay list (kind3) +- Adds new relay lists: Trusted, Blocked, Proxy, and Broadcasting +- Moves most of the Dialogs to full-screen routes +- Breaks NewPostScreen and ViewModels into Screens and ViewModels for each supporting NIP +- Adds support for creating and replying to NIP-22 geo scope posts +- Performance Improvements by not re-verifying duplicated events +- Adds Content Sensitivity setting to the Security filter screen +- Adds Translation setting to a new screen. +- Extends AsyncImage to correctly use pre-loaded aspect ratio and avoid jitter +- Adds imeta tags for images and urls inside the content of the Classifieds +- Adds new default banner for empty profiles +- Finishes the migration from LiveData to Flow +- Restructures the old static datasource model into dynamic filter assemblers. +- Moves filter assemblers, viewModels and DAL classes to their own packages. +- Creates Composable observers for Users and Notes +- Unifies all Filter Assembler lifecycle watchers to a few classes +- Moves relay authentication to a coordinator class for all accounts in all relays. +- Moves the relay NOTIFY parser to its own coordinator class for all accounts +- Moves the connection between filters and event cache to its own coordinator class +- Adds support for Tor in push notifications +- Isolated Connectivity services, from Compose to Flow +- Isolated Tor services, from Compose to TorService +- Isolated Memory trimming services, from Compose to Flow +- Isolated Image Caching services, from Compose to Flow +- Isolated Video Caching services +- Isolated Logging services +- Isolated NIP-95 Caching services +- Isolated Pokey receiver services +- Isolated OkHttpClient-building services as flows +- Hold off on all DM attachments until the message is sent. +- Adds previews for any number of urls, events, and media uploads on new post screens. +- Adds zap split, zap raiser, and geolocation symbols for DMs and channel messages +- Adds picture upload for NIP-28 metadata +- Adds support for community relays on NIP-28 +- Adds a pool of ExoPlayers when multiple videos are playing +- Moves DVM's last announcement restriction from 90 days to 365 days + +Quartz: +- Adds a NostrClient with filter and event outbox cache +- Adds a Basic RelayClient and parsers for all relay commands +- Migrates signers from callback to suspending functions +- Migrates event create functions to builders with templates +- Migrates the filter design to a filter per relay +- Migrates hardcoded tag filters in events to the Tag's parser and assembly functions. +- Normalizes all relay URLs +- Formalizes relay hint providers per kind +- Event store support with SQLite +- Reengineered NIP-55 Android signer and its cache +- Reengineered exception handling for signer errors +- Adds support for the Request to Vanish NIP - 62 +- Migrates all NIP-51 lists to the new event-tag structure. +- Migrates Drafts and NIP-04 and NIP-17 DMs to the new structure +- Migrates Bookmarks to the new structure +- Migrates NIP-56 to the newest tag structure +- Adds support for nip70 Protected Tags +- Adds full support for nip73 External Content IDs +- Adds support for NIP-48 proxy tags +- Removes the old "datasource" model +- Adds a Bloom-based hint indexer with MurMur hash +- Adds a PoW miner +- Restructures thread helpers for NIP-10 +- Migrates Zap splits, zapraisers, subject, alts, and content warning to their own packages. + +Dev Team: +- nostr:nprofile1qqsyvrp9u6p0mfur9dfdru3d853tx9mdjuhkphxuxgfwmryja7zsvhqpz9mhxue69uhkummnw3ezuamfdejj7qgswaehxw309ahx7um5wghx6mmd9uq3wamnwvaz7tmkd96x7u3wdehhxarjxyhxxmmd9ukfdvuv +- nostr:nprofile1qqsfnw64j8y3zesqlpz3qlf3lx6eutmu0cy6rluq96z0r4pa54tu5eqpz9mhxue69uhkummnw3ezuamfdejj7qg0waehxw309ajxzmt4wvhxjme0hynkd5 +- nostr:nprofile1qqs827g8dkd07zjvlhh60csytujgd3l9mz7x807xk3fewge7rwlukxgpz9mhxue69uhkummnw3ezumrpdejz772u5wm +- nostr:nprofile1qqswc4nrhvp4lrjct0ayy0ps8f2hvj8e2guucp63dwcx6m6e8pka9fqpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhszrnhwden5te0dehhxtnvdakz7qg7waehxw309ahx7um5wgkhqatz9emk2mrvdaexgetj9ehx2ap00me8jy +- nostr:nprofile1qqsv4zwtz8cuwh2mvc3zdrl5853g365t9j6mn25edlul7uz0eyzt0zcpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpzpmhxue69uhkummnw3ezumt0d5hscc6wyt + +Translations: +- Czech, German, Swedish, and Portuguese by nostr:nprofile1qqsv4zwtz8cuwh2mvc3zdrl5853g365t9j6mn25edlul7uz0eyzt0zcpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpzpmhxue69uhkummnw3ezumt0d5hscc6wyt +- Dutch by nostr:nprofile1qqs82l74z7g3x8j3avpn2wrjrwn855nyvmpxa4v5pftfvtv5lrvrc5cpz9mhxue69uhkummnw3ezuamfdejj7tk0drp +- French by nostr:nprofile1qqs8av5uzf4nv2q80chrmp3mj9a9dd6zjw4fmz56hsn2gzar72rxhtcppemhxue69uhkummn9ekx7mp0qyg8wumn8ghj7mn0wd68ytnddakj7qgawaehxw309ahx7um5wghxy6t5vdhkjmn9wgh8xmmrd9skctcuvd26f +- Polish by nostr:nprofile1qqsdyfz0ewdhmgp3a4r3pxvezx5r8yalrgvjn38v2ml5qrusnv7yywgpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpz9mhxue69uhkwmn0wd68ytnrdakj7qgkwaehxw309ahx7um5wghxx7npwvh8qmr4wvhsrpff27 +- Chinese by nostr:nprofile1qqsyxnuhnymz0u0xru2watmqe25vlh8vzzje9jhlsfgvsff9942gc9gpr9mhxue69uhhyetvv9ujumt0d4hhxarj9ecxjmnt9uq3vamnwvaz7tmjv4kxz7fwd4hhxarj9ec82c30qy28wumn8ghj7atn9ehx7um5wgh8w6twv5hsung0qr +- Slovenian by nostr:nprofile1qqsqqqqqqp0fmkspg7w8d305ln96a0jw0ptwqtuwskkm5pddv2kkjfcpyfmhxue69uhk6atvw35hqmr90pjhytngw4eh5mmwv4nhjtnhdaexcep0qythwumn8ghj7un9d3shjtnswf5k6ctv9ehx2ap0qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj72epxz8 +- Thai by nostr:nprofile1qqsxdhmq2cke8xk6scfyxeyfj3dyancavg6xk0v50r023gec7vsrceqppemhxue69uhkummn9ekx7mp0qyghwumn8ghj7mn0wd68ytnhd9hx2tcpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhskamkgc +- Bengali by nostr:nprofile1qqsgs9hgjw87vz36jf2r83m5zree2q87zvs8s7kty9jljdz7wprytyspremhxue69uhkummnw3ezu6m0de5kueedv3jkwunpv9nzumnv9uq3kamnwvaz7tm5d4cz6un9d3shjtnrv4ekxtn5wfskgef0qy28wumn8ghj7mn0wd68yt3k8quzummjvuhsg63aw2 +- Hindi by nostr:nprofile1qqs88dt78wgnzvaph6fcstfvsd98xc2qs8eg8tllwv2zlutu8ehec2cpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcy8dumx +- Spanish by nostr:nprofile1qqs07tjpyvvlq9ugdpax8h3jfrpwn7kr72k3tc7ky83tggn4et9eangprpmhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0qyghwumn8ghj7mn0wd68ytnhd9hx2tcpzemhxue69uhkumm5d9n8jtnyv9kh2uewd9hj7cn2zey +- Hungarian by nostr:nprofile1qqs88rmfrp9wmfn4qq4kslly0j8futmmrgn86mu3gkc3jvcjl97p3mcpzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpz4mhxue69uhkummnw3ezummcw3ezuer9wchsz9thwden5te0wfjkccte9ejxzmt4wvhxjme0m7mtdy and nostr:nprofile1qqsxekg0s8kxpcrka8ccwztv2m73kz6jy0ur8f7jc04rwr5p44w5acsk5trt8 +- Persian by nostr:nprofile1qqsvq73w5j9kw573rtff6c3fyh953w45328n3625apdwc3548gr49gsppemhxue69uhkummn9ekx7mp0q6fpv8 + +Download: http://amethyst.social + +[Changes][v1.00.0] + + + +# [Release v0.94.3: Adds iMeta tags to GIF urls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.94.3) - 2025-01-05 + +- Adds iMeta tags to GIF urls to optimize GIF previews +- Fixes the extra empty kind 20 post when uploading videos on the media tab +- Fix: Only close the upload screen if the video upload is a success on the Media tab +- Maintains note reaction visibility when scrolling by [@npub1xcl47srtwh4klqd892s6fzwtdfm4y03wzjfl78scmmmxg8wzsf4qftd0en](https://github.com/npub1xcl47srtwh4klqd892s6fzwtdfm4y03wzjfl78scmmmxg8wzsf4qftd0en) + +Download: http://amethyst.social + +[Changes][v0.94.3] + + + +# [Release v0.94.2: Fixes Tor leaks](https://github.com/vitorpamplona/amethyst/releases/tag/v0.94.2) - 2025-01-04 + +This release fixes two Tor leaks introduced during the migration of two APIs in v0.94.0. The new relay API contained a bug that bypassed the user's Tor preference for relays and the migration to Coil3 implemented a one-time cache for the Tor preference, preventing it from reflecting subsequent changes for image loading. + +Thanks to nostr:npub17lmqmq680446scdgvv58snglr3h2phe00thqfe0twa3l8q5mzmusj6c60g for the Tor audit + +Download: http://amethyst.social + +[Changes][v0.94.2] + + + +# [Release v0.94.1 GIFs and Custom Emoji inputs](https://github.com/vitorpamplona/amethyst/releases/tag/v0.94.1) - 2025-01-04 + +This version adds a `:` command to link custom emojis on new posts and chats. Similar to the @ for user search, just start typing to find your custom emojis. When you see the list of emojis, click on the emoji to add it as an inline emoji OR click on the right button to add as a regular URL in the post. + +Create your GIF and rection libraries on emojito.meme . Make sure to bookmark your and/or other people's emoji packs to add them to Amethyst's `:` list. + +Happy shitposting. + +Download: http://amethyst.social + +[Changes][v0.94.1] + + + +# [Release v0.94.0 Encrypted Media on DMs](https://github.com/vitorpamplona/amethyst/releases/tag/v0.94.0) - 2025-01-03 + +Now every upload on DM chats will be encrypted to the destination's pubkey following the same spec 0xChat uses. This offers a massive update in privacy from the common "hidden link" design. The encrypted blobs are sent to NIP-96 and Blossom servers. Make sure your server accepts encrypted blobs. Sattelite and void.cat do accept. We redesigned our upload screens to allow multiple images/videos at the same time on new posts, stories and chats encryption. Error handling was also improved with the screens now allowing you to try again to a different server. + +Features: +- Adds support for encrypted media uploads on NIP-17 DMs +- Integrates with Pokey's Broadcast receiver. +- Expands the Around me filter to 50km +- Shows NIP-22 replies in the replies tab of the user profile +- New upload screen for chats +- When uploads fail, the screen stays live to allow changing the server and trying again. +- Improves the padding in the layout of the gallery +- Allows multi-images posts to be displayed in the Profile gallery +- Refactors zap error message screen to allow sending messages directly to each split receiver with their error +- Adds support for multiple media uploads at the same time. +- Adds support to display PictureEvents with multiple images at the same time +- Adds QR code private key export dialog by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Added Gamestr custom hashtag icon by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Switches to the right account from push notification's click +- Adds new picture and video events to the user profile gallery +- Adds basic support for RelationshipStatus to Quartz + +Fixes: +- Fixes bug that resets localhost relay settings. +- Moves to using cancellable coroutines to avoid cancelling the parent thread all together. +- Fixes the navigation padding on Samsung devices for the Shorts tab. +- Fixes the chat's input field behind Samsung's app bar on tablets +- Fixes notes appearing of replies for some recipes +- Removes the swipe to delete draft from right to left. Only left to right remains available. +- Solves crashing when a p-tag contains only "ffff" +- Fixes edge to edge issues when the keyboard is shown on the Media Server settings. +- Fixes keyboard overriding the relay settings screen +- Fixes double quotes on NIP-28 Channel messages +- Fixes cosine caching on Blurhash +- Fixes download and loading image icon not showing on posts when text overflow by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes lack of notification when a new account is logged into the app and before the app restarts. +- Fixes displaying an old result when coming back to a DVM screen +- Fixes the bugs from migrating video events to imeta tags +- Removes pull to refresh from gallery + +Performance: +- Increases the number of possible active video playbacks on the screen to 20 +- 10x better performance on Blurhash generation +- Improves search by npubs to use all relays. + +UI Improvements: +- Avoids cutting off some of the users in the Pay intent screen +- Adds toast message when the video/image starts downloading by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Remove crossfades and double composition on image loading/success +- Improves Uploading feedback for the NewPost screen +- Optimizes user search to account for names that start with the typed prefix +- Several accessibility improvements by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Simple refactoring to newer versions of the clickable text +- Migrates Video events to imeta tags +- Removes youtu.be links from the video feed. +- Checks for video file types in uppercase as well as lowercase + +Code quality: +- Move relay dialog to a route by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Refactors user tagging lists to generalize them +- Updates zoomable, vico, mockk, kotlin, compose Bom, firebase, navigation compose, android camera libs and adaptive acompanist +- Refactors Ammolite to remove the dependency on OkHttp to prepare for KTor and multiplatform settings. +- Reduces the singleton coupling between Client and RelayPool. +- Removes troublesome dependency on blurhash encoder library +- Restructures contentScale for Images and Video dialogs +- Refactors Media Uploaders to improve code reuse +- Refactors iMeta usage on Quartz to move away from NIP-94 +- Removes the use of nostr: uri for notifications +- Enables a new screen to be routed when new logins happen +- Removes contract of the old image picker +- Simplifies the Gallery stack +- Separates event class that manages general lists and abstracts another intermediary class that manages private tag arrays in its content. + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Chinese by [@npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h](https://github.com/npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h) +- Slovenian by [@npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw](https://github.com/npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) and [@npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp](https://github.com/npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp) +- Persian by [@npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk](https://github.com/npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk) + +Download: http://amethyst.social + +[Changes][v0.94.0] + + + +# [Release v0.93.1 Fixes Satellite's blossom upload](https://github.com/vitorpamplona/amethyst/releases/tag/v0.93.1) - 2024-12-05 + +- Moves to NIP-22 to reply to Interactive Stories. +- Adds amount and personalization labels to the DVM feed +- Fixes Satellite's blossom upload +- Fixes incorrect reply order when the direct reply is also included as a quote. +- Fixes image upload tests +- Fixes the bug of not having the video feed at the top when loading the app from scratch. +- Fixes screen mispositioning when rotating the phone on full-screen video/image dialogs. +- Fixes images on DVM profiles +- Fixes badge crash +- Fixes missing reactions on video feeds +- Improves performance of the Hex encoder. +- Improves the layout of the discovery feed items +- Updates Jackson, secp256k1, and AGP + +Download: http://amethyst.social + +[Changes][v0.93.1] + + + +# [Release v0.93.0: Blossom, Olas, Around Me feeds and Interactive Stories.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.93.0) - 2024-11-27 + +Adds support for displaying NIP-63 Interactive Stories +Adds support for Blossom media servers +Adds support for Olas' Image feeds +Adds support for Around Me feed with posts that only show up in that location + +New Features: +- New Android Image/Video Picker +- Adds support for pronouns on profile +- Migrates Video uploads from NIP-94 to NIP-71 Video events +- Migrates Picture uploads from NIP-94 to NIP-68 Picture events +- Adds support for BUD-01, BUD-02, and BUD-03 +- Adds support for NIP-22 Comments +- Adds nip05 field to the hidden words filtering by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Adds support for q tags with addresses +- Adds search.nos.today to bootstrapping relays for search +- Adds DM and Search default buttons to the relay screens +- Adds hidden words filter to search, hashtag and geotag feeds +- Applies hidden words even to hashtags that were not included in the content of the event. +- Adds support for saving reactions, zaps, translations user preferences on private outbox relays + +UI Improvements: +- Adds animations to the zap, reaction and boost popups by [@npub1xcl47srtwh4klqd892s6fzwtdfm4y03wzjfl78scmmmxg8wzsf4qftd0en](https://github.com/npub1xcl47srtwh4klqd892s6fzwtdfm4y03wzjfl78scmmmxg8wzsf4qftd0en) +- Lighter chat bubbles +- Date separators on chats +- Adds unfollow to note dropdown by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Improves (Show More) presence to only when it actually makes a difference. +- Adds UI for when the location permission is rejected. +- Improves error message for the signup page when the display name is blank +- Adds extra padding for the zap setup screen +- Pre-process search to avoid showing and hiding posts after hidden words were processed by the UI. +- Rotate on full screen video if the device orientation is not locked by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) + +BugFixes: +- Fixes account creation that follows itself +- Fixes translations of http urls +- Fixes search bug that mixed geohashes and hashtags +- Fixes issue with the order of multiple same-author events in a thread +- Fixes drafts appearing for other logged in accounts by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes jumping of scroll when the thread updates +- Fixes app hanging when switching to accounts due to waiting to decrypt the blocked user list that might not exist +- Fixes initial decryption of mutelists when using amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes crash on empty p-tags on new replies [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes translations preferences changes running on the main thread by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes some images being saved as videos [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes missing notifications when multiple accounts tried to decrypt it +- Fixes lack of zap progress updates when there is a private zap the user cannot decrypt or when a nwc payment fails. +- Fixes saving the scrolling position when navigating between multiple threads. +- Fixes rendering cache of notes in thread view which kept replies in the wrong thread level +- Fixes reply level calculation caching +- Fixes poll's background rendering with the right percentages +- Fixes "null" strings on profile fields. + +Code Quality Improvements: +- Refactors FeedStructures to prepare for custom feeds +- Updates Account architecture to operate feeds with location +- Custom Empty Feed Screen for Notifications +- Fully Deprecates note1, removing the last usages of the standard +- Removes unused encryption fields from NIP-94 +- Moves the parallel processing amber calls to a utils class +- Refactors location to operate as a flow +- Unifies location Flows and geoHash Flows into one +- Make location flows react to changing location permissions on the fly +- Moves NIP-44 test model classes to a new file +- Improves GitHub actions to prepare debug apks in every commit +- Upgrades to Coil 3 +- Updates AGP, kotlin, runtime, compose, camera, corektx, media3, firebase, fragment, navigation, jna, jackson, accompanist, kotlin serialization, mockk, coroutines-test and kotlin collections + +Performance: +- Improves thread preloading +- Adds a cache for reply levels when viewing threads. + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Chinese by [@npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h](https://github.com/npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h) +- Slovenian by [@npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw](https://github.com/npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) and [@npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp](https://github.com/npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp) +- Persian by [@npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk](https://github.com/npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk) + + +[Changes][v0.93.0] + + + +# [Release v0.92.7: Mute List fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.7) - 2024-10-19 + +- [Fixes empty mute lists and mute words](https://github.com/vitorpamplona/amethyst/commit/aae2ffebd71d38917fd5f0df96ca2d1fc11c3ee1) + +[Changes][v0.92.7] + + + +# [Release v0.92.6: More UI Fixes for Android 15](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.6) - 2024-10-17 + +- [If the Share target intent opens with the new post screen already active, just updates the post instead of creating a new one.](https://github.com/vitorpamplona/amethyst/commit/c0ba6f5b0071b59f06f63d0264ec9c4aaf2fcc79) +- [Fixes zapraiser progress bar](https://github.com/vitorpamplona/amethyst/commit/cff6ee457d02b6fe4d5a76f61ee9858bc7cea74f) +- [Fixes poll rendering](https://github.com/vitorpamplona/amethyst/commit/25c35326371678c8734691c9eb666cb091e6bd20) +- [Reduces the font size for the translation label](https://github.com/vitorpamplona/amethyst/commit/24b29396cb795bd18fdad92e8a2974e6479be159) +- [Fixes margin of poll options with translation](https://github.com/vitorpamplona/amethyst/commit/67fb3bf488cc24e1bf2bc4a1c74f9523d9540d05) +- [Fixes array too big because strfry blocks more than 20 filters](https://github.com/vitorpamplona/amethyst/commit/26ba75c7c97283a77453462018ebf5bfc7d37df2) + +[Changes][v0.92.6] + + + +# [Release v0.92.5: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.5) - 2024-10-16 + +- [Updates compose, benchmark, navigation, and activity](https://github.com/vitorpamplona/amethyst/commit/724bea6bbb475bc074844c380834e0de200f300e) +- [Fixes recreating the new post screen from intent when switching accounts.](https://github.com/vitorpamplona/amethyst/commit/c5dd2c5651a24d2da7464cd4c683b4b7219e9963) +- [Prevent clicks outside boost popup](https://github.com/vitorpamplona/amethyst/commit/6826db13a4988bee32507500d138595dd3d596fa) + +[Changes][v0.92.5] + + + +# [Release v0.92.4: Text and Media Share target for new posts.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.4) - 2024-10-16 + +- [Makes Amethyst a share target for texts, images and videos.](https://github.com/vitorpamplona/amethyst/commit/13e2546d362794f20f104a1c424f78850054da67) +- [Fixes new media post dialog for the edge to edge borders](https://github.com/vitorpamplona/amethyst/commit/549b9f53e557e50a06f167b01432538bb02003b2) +- [Fixes padding of the new new post screen](https://github.com/vitorpamplona/amethyst/commit/974c022aedabe786aa57bab8871913c613230852) +- [Changes the new post screen to use the non-disappearing version of the scaffold.](https://github.com/vitorpamplona/amethyst/commit/a57566dd8455e69abe5f49b5ce9f9541bfa7e021) +- [Correctly maps the write status of the outbox relays.](https://github.com/vitorpamplona/amethyst/commit/b8112ff1aa7dd40cf437167803fc581173fb23bb) + +[Changes][v0.92.4] + + + +# [Release v0.92.3: Shorts fling behavior bugfix.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.3) - 2024-10-15 + +- [Uses the same Reaction animation to also do Boosts and speeds up animation](https://github.com/vitorpamplona/amethyst/commit/d7c18341cdf98e9def71df58a686188a243a2015) +- [Reverts hack for fling behavior on the Vertical Pager](https://github.com/vitorpamplona/amethyst/commit/d78b55d134f108251e0ec7b62b65ec25c68fc9a2) +- [Updates to AGP 8.7.1 and SDK 35](https://github.com/vitorpamplona/amethyst/commit/5b516f410156be4128d43b4e605fc2aaeeb7c948) +- [Do not bring the keyboard when the search field reappears.](https://github.com/vitorpamplona/amethyst/commit/1fc390c215d85308592372aa3228f1987186e748) +- [Fixes Thread view when loading a reply of a thread that is not cached yet.](https://github.com/vitorpamplona/amethyst/commit/2bb09f583ba1b9ff90c22c9c9fa221ae99435471) + +[Changes][v0.92.3] + + + +# [Release v0.92.2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.2) - 2024-10-11 + +- [Moves the API with amber from `signature` to `result`](https://github.com/vitorpamplona/amethyst/commit/5ef3c8f00ec06e156ab06c1c8605b2a5cefccae1) +- [Fixes the ability to see muted lists in Shorts](https://github.com/vitorpamplona/amethyst/commit/d832351bcd39a43d0b80fb2e00743732bbe5403c) +- [Adds new fields on vision prescriptions](https://github.com/vitorpamplona/amethyst/commit/9ae611831f4777732bc65e7f5ff9cbdda118980f) +- [Prioritise search results that start with the search term](https://github.com/vitorpamplona/amethyst/commit/99641e1a12b483ae2f0e66cf8563b510980eb732) +- [Adds some test cases for video compressions](https://github.com/vitorpamplona/amethyst/commit/76a66e7bd3b2bbcf2b51c56badfc5722aded40d7) +- [Adds Unknown media type test](https://github.com/vitorpamplona/amethyst/commit/a66417ec82040938805dd2b5cb3d7f9f114c78a8) +- [Use "use" blocks to close resources automatically](https://github.com/vitorpamplona/amethyst/commit/fbecc8b6d1585dce3d7d4688aef744e69cc2ea53) +- [Fixes long term issue with the video in the Shorts feed not aligning with the padding of the screen](https://github.com/vitorpamplona/amethyst/commit/d320b951ae02d536eaafeeb483763810fbcdda3d) +- [Fixes intent reopening the Zap Setup screen when coming back from Alby](https://github.com/vitorpamplona/amethyst/commit/c66fa1073bcdf1bd0ffd9084e288ac494c82b5ff) +- [Faster logout processing without closing the account switcher dialog.](https://github.com/vitorpamplona/amethyst/commit/67ea0dcf7fd791d970eaeb64b248d06ea2a587e3) +- [Add animation to notification chart](https://github.com/vitorpamplona/amethyst/commit/a3166f4ff3341e097271570ad68ef9bd4429e144) +- [Add animation to FABs](https://github.com/vitorpamplona/amethyst/commit/9340c440f5f45f68484dc9b6e4d82a27260d2e11) +- [Add animation to zap and reaction popups](https://github.com/vitorpamplona/amethyst/commit/a7343d5b5477ae16dd38f5c49cbfe042b8244b9d) +- [Updates AGP and compose, fragment, navigation, benchmarking and firebase libraries.](https://github.com/vitorpamplona/amethyst/commit/0551b82bd91b720cfc108def82215132f35c9782) +- [Prevent clicks outside reaction and zap popups](https://github.com/vitorpamplona/amethyst/pull/1125) +- [Support for login with hex key when using amber](https://github.com/vitorpamplona/amethyst/commit/baa9ee05626a645d1ea060e78e9231c2624bd666) +- [Video Rotation: actually rotate if the device orientation is not locked.](https://github.com/vitorpamplona/amethyst/commit/7326d6be93ffd8c197d42347ec2311368505ac52) + +[Changes][v0.92.2] + + + +# [Release v0.92.1](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.1) - 2024-09-27 + +- Fixes Access to local Citrine when tor is enabled +- Fixes zap splits on a first time connection to the NWC relay. + +[Changes][v0.92.1] + + + +# [Release v0.92.0: Tor and Transient Accounts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.92.0) - 2024-09-27 + +This version ships with a Tor service enabled by default to access .onion urls and untrusted relays from the Outbox model. It also offers NFC-hosted transient accounts: accounts that log off as soon as the app goes to the background, deleting all traces of the account from the phone. + +Write your ncryptsec to an NFC tag and hide it in your clothing. When you need to use Amethyst, tap the tag, insert your password and login. Lock the screen to delete everything. If you are an activist and if your phone is confiscated, they will never find anything on the phone. Not even your public key. Ncryptsec is a NIP-49-based password-encrypted nsec. If you need, you can destroy and dispose the NFC tag. + +Features: +- Adds tor node +- Adds multiple settings for the use of Tor +- Adds privacy presets to simplify Tor choices +- Adds support for NFC-hosted transient accounts +- Adds button to take and add pictures from camera by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds Uncompressed option when uploading media by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Adds support for Bloom filters +- Adds zapstore yaml setup +- Adds mempool api to verify OTS via Tor + +Bug Fixes +- Fixes the zap options available for the Zap the Devs button +- Fixes edit draft not working when using the quick action menu by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes opengraph url preview tags from substack by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes the parsing of d-tags with colons in them +- Fixes back button not working after opening a nostr link from the web +- Fixes push notifications when using amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes NIP-47 implementation to force relay for the NWC connection. +- Fixes OTS web calls via Tor using mempool's api +- Fixes the loading of localhost urls using Tor +- Fixes .onion urls not using tor even if available +- Fixes show buffering animation when loading videos +- Fixes folowing icon position on chat user pictures + +Performance +- Starts to build all OkHttp clients from a main root client to keep the same thread pool +- Caches OTS web calls to avoid pinging the server repeatedly for the same event. + +Code Quality Improvements: +- Updates navigation compose, lifecycle, fragment, activity, composeBoms and AGP to 8.6.1 +- Improves OTS Verification error messages + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Chinese by [@npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h](https://github.com/npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h) +- Slovenian by [@npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw](https://github.com/npub1qqqqqqz7nhdqz3uuwmzlflxt46lyu7zkuqhcapddhgz66c4ddynswreecw) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.92.0] + + + +# [Release v0.91.0 Edge to edge feeds](https://github.com/vitorpamplona/amethyst/releases/tag/v0.91.0) - 2024-09-06 + +Hidden words now filter by the user's fields as well. You can hide by name, profile picture, banner, lightning and nip-05 addresses and about me fields. + +Features: +- Finishes Edge to Edge transition for Android 15 +- Adds compression settings to the media uploading screen by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Adds sliding animations in all inner screens +- Adds copy stack to clipboard for error messages that have an exception +- Enables the use of hidden words for all visible properties of the user + +Bug Fixes +- Fixes blank alt field when no alt text is provided on NIP-96 +- Fixes missing Private Home/Outbox relay list after loading from backup +- Fixes keyboard padding issues when using physical keyboards on the message screens. +- Fixes token sanitization when using gcompatup with unified push by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes moving top buttons on the full screen dialog for images and videos. +- Fixes weird padding of the key backup screen +- Fixes using npub instead of pubkey in hex when communicating with Amber +- Fixes blinking on crossfades when the system's light/dark theme is different than the app's theme +- Fixes a mix of languages after changing language in Settings +- Fixes disables saving m3u8 files locally (streaming can't be saved) +- Fixes Community tab not loading up with Global filter +- Fixes size of default banner when the profile is not loaded yet. + +Code Quality Improvements: +- Inverts Layouts to place Navigation on top of Scaffold and allow custom scaffolds per route +- Refactors navigation to improve clarity +- Restructures screens into their own packages +- Restructures navigation functions as a single object +- Refactors all TopBars to use default material 3 ones +- Simplifies the "and 2 more" translations for the relay recommendation user lists +- Removes unnecessary observers from the transition in the bottom nav layouts. +- Normalizes cache directories in the Application class +- Fixes text field recompositions because of new keyboard actions +- Moves the profile zap to threads +- Updates to AGP 8.6.0 +- Updates zoomable and kotlin serialization + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Chinese by [@npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h](https://github.com/npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h) + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.91.0] + + + +# [Release v0.90.6: Zap Amount fix on Profile Zaps](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.6) - 2024-09-02 + +[Long press to copy relay url](https://github.com/vitorpamplona/amethyst/commit/53acbd860660dd1f1ba5098a8d1f2819e2806e4a) +[Rename amount to amountInMillisats to give visual clue to calling classes that millisats should be used](https://github.com/vitorpamplona/amethyst/commit/a4a753e7b623da776afeb47d293551c04ece994e) +[long press to copy relay url in the relay icons and relay row](https://github.com/vitorpamplona/amethyst/commit/bba7c257da6d6b978432358e0c738b2ab0455a2c) + +[Changes][v0.90.6] + + + +# [Release v0.90.5: Orbot fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.5) - 2024-09-01 + +- Fixes proxy connection not starting after killing the app + +[Changes][v0.90.5] + + + +# [Release v0.90.4: Fixes relative urls on NIP-96 + Basic NIP46 objects](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.4) - 2024-08-30 + +[- Fixes caching bug of NIP-96 servers](https://github.com/vitorpamplona/amethyst/commit/aeaddf722bf42cc7140f07e36964dcd447a0a1e0) +-- Allow NIP-96 setups with relative URLs +-- Displays error messages if the server has sent in the body +-- Adds a test case for both +[Fixes ZapTheDevs card not disappearing after the donation.](https://github.com/vitorpamplona/amethyst/commit/3ebaf2bf1e49f75aa08b7fe047f18743f7389ff4) +[Fixes push registration with empty token ids](https://github.com/vitorpamplona/amethyst/commit/1407850e81b0ee58c32b9b5ad3be5ac5548555cc) +[Show relay ping with the relay icon](https://github.com/vitorpamplona/amethyst/commit/efde14a3483a467ac03fd08ec00111da36d36847) +[Enables decryption by nip04 and nip44 on NostrWalletConnect objects, NIP-51 lists and NIP-04 messages](https://github.com/vitorpamplona/amethyst/commit/cb4a73bb9c6138d960c543e9b54330be32a4b85f) +[Fix relay icons when using complete ui](https://github.com/vitorpamplona/amethyst/commit/06f37ab81d1428da37cf73b8b642faf2d5523326) +[Adds basic support for NIP-46 events.](https://github.com/vitorpamplona/amethyst/commit/b5709f95271e5b8fed25986da7f109dc8e2b8d43) +[Protects against empty nip04 content](https://github.com/vitorpamplona/amethyst/commit/8be74649ceda39a3bce8e9c32dbed0dabdcc3bb5) +[Basic code for dynamic limits](https://github.com/vitorpamplona/amethyst/commit/255f46404605136f6dd07d6bbf4f98c330683e33) +[Speeds up the filter for NWC zap payments.](https://github.com/vitorpamplona/amethyst/commit/388ccdbe750cba19d1ce579e72a29339d943d29f) +[Typo Fix on Lnaddress TextField](https://github.com/vitorpamplona/amethyst/commit/93e9e2373034c18cdcf6abc4968bb0322c93816d) + +[Changes][v0.90.4] + + + +# [Release v0.90.3: Fixes Unified Push Notifications](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.3) - 2024-08-27 + +- Fixes Unified Push Notifications +- Fixes Lack of notifications for non-primary accounts +- [Adds a small border between the author and the message of a chat bubble](https://github.com/vitorpamplona/amethyst/commit/4665c488d5c340b68708b90d7416802ba0daac03) + +[Changes][v0.90.3] + + + +# [Release v0.90.2: Fixes conversation feed.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.2) - 2024-08-27 + + + +[Changes][v0.90.2] + + + +# [Release v0.90.1: Fixes error messages when zapping devs](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.1) - 2024-08-27 + + + +[Changes][v0.90.1] + + + +# [Release v0.90.0: Torrents and Outbox refactorings](https://github.com/vitorpamplona/amethyst/releases/tag/v0.90.0) - 2024-08-27 + +This version adds support for NIP-35 Torrent files (dtan.xyz), adds significant memory pruning for encrypted payloads and large events (DMs, Notifications, Zaps, etc), and completely restructures the way most of our caching works to facilitate immediate subscription updates using the outbox model on custom feeds by NIP-51 lists. This version also offers new defaults for NIP-65 and DM relay lists for new users and fixes several bugs and inconsistencies. + +Features: +- Adds support for NIP-35 torrents and their comments +- Adds a simplified sync Signer to the Quartz library +- Adds Default lists for NIP-65 inbox and outbox relays +- Adds Default lists for Search relays +- Adds local backup for UserMetadata objects +- Adds local backup for Mute lists +- Adds local backup for NIP-65 relays +- Adds local backup for DM Relays +- Adds local backup for private home relays +- Improves caching of encrypted DMs +- Updates Twitter verification to X +- Improves the rendering of QR Codes +- Adds support to Delete All Drafts + +Code Quality Improvements: +- Separates Account actions from Account state in two objects +- Changes Startup procedures to start with Account state and not the full account object +- Moves scope for flows in Account from an Application-wide scope to ViewModel scope +- Removes all LiveData objects from Account in favor of flows from the state object +- Migrates settings saving logic to flows +- Migrates PushNotification services to work without Account and only Account Settings. +- Migrates the spam filter from LiveData to Flows +- Rewrites state flows initializers to avoid inconsistent startups +- Finishes the migration of the service manager to the Application class +- Moves to hold the all feeds in stateflows +- Updates benchmark, composeBOM and firebaseBOM to the latest versions +- Moves the default zap type to a state flow and avoids passing on to the screen when using the default value +- Removing unecessary livedata objects for translation services +- Moves lastread routes to mutableStateFlow +- Migrating livedata to flow for contact list updates of the user. +- Adds a destroy method to FollowList state for consistency +- Moves follow list states to the AccountViewModel +- Migrates Notification Summary to the new state model +- Moves the notification screen to the new state model instead of viewModels +- Refactoring Moving feed status from ViewModel to State objects + +Interface Improvements: +- Show only 3 users in the recommended relays section +- Creates links to njump when events can't be found on Amethyst +- Adds support for MOD reports +- Displays commitment PoW if present +- Changes relay set kind to be NIP-51 consistent. +- Adds more information to when error messages are not available in the relay stats. +- Adds context to highlight events +- Adds previews to test markdown rendering +- Improves the look of inlinde code in markdown +- Improves badge display + +Performance Improvements: +- Adds pruning for giftwrapped messages +- Fixes clearing of flows and live data object pools before removing notes from the local cache +- Improves stability of composables +- Migrates caching of decrypted value outside of the Event class +- Removes encrypted parts of NIP-17 from the cache +- Removes old NIP-04 messages from the cache +- Avoids deleting new NIP-17 plain text chats from memory +- Avoids bottom nav recompositions +- Simplifies nav bar selected calculations +- Avoids remembering edit lists that will never exist. +- Improves speed of chatlist rendering + +Bug Fixes: +- Fixes lingering cache and threads still active after killing the app +- Fixes crash when opening the Relay screen with empty urls as relays. +- Fixes horizontal padding of the chat messages +- Fixes the download of 1000s of NIP-65 relay lists because some relays consider empty lists as null and return everything. +- Fixes fdroid push registration to re-register even if the saved distributor was already selected. +- Fixes crash when the relay url of a user is duplicated. +- Fixes padding of short quotes +- Fixes slow down when the last message on chat is a base64 image. +- Fixes the centralization of the "and more" part of relay recommendations +- Fixes miscaching flows of the relay lists from follows. +- Fixes miscache of hashtag following button +- Fixes heading sizes on markdown +- Changes Delete all events to use maximum chunks of 200 elements to avoid the 65KB stringified JSON limit of many relays. + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Arabic, Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) and [@npub1tr66yvqghfdgwv9yxhmg7xx6pvgvu5uvdc42tgdhsys8vvzdt8msev06fl](https://github.com/npub1tr66yvqghfdgwv9yxhmg7xx6pvgvu5uvdc42tgdhsys8vvzdt8msev06fl) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Chinese by [@npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h](https://github.com/npub1gd8e0xfkylc7v8c5a6hkpj4gelwwcy99jt90lqjseqjj2t253s2s6ch58h) and [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.90.0] + + + +# [Release v0.89.10: Smaller memory footprint](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.10) - 2024-08-09 + +- [Improved filter for notifications](https://github.com/vitorpamplona/amethyst/commit/fad8b9df0fe28240da967db7b316d92050321e8d) +- [Moves service manager to the Application class](https://github.com/vitorpamplona/amethyst/commit/cc526816353a2919fc95bf459fba8570da2ff70a) +- [Adds protections against filters with empty arrays because some relays consider that null as opposed to empty.](https://github.com/vitorpamplona/amethyst/commit/939c8e95b0a130afaf7818ce601a2b4892f881ac) +- [Delete All Drafts now requires maximum chunks of 200 elements to avoid the 65KB stringified JSON limit of many relays.](https://github.com/vitorpamplona/amethyst/commit/89638ff261c7fccb9c409c49d6efb40fc1c4c922) +- [Updates translate dependencies](https://github.com/vitorpamplona/amethyst/commit/02f7b546613e8d371c2902611b92ba5c26e34c06) +- [Reducing the amount of CPU memory used for images to the default.](https://github.com/vitorpamplona/amethyst/commit/68cad97819d554f672a963cc61604f4a515fe3aa) +- [Improves wording on the name of relay types](https://github.com/vitorpamplona/amethyst/commit/2e7b7c5c000ef9a9ab95b7303d58981c24be68b0) +- [Marks username as deprecated](https://github.com/vitorpamplona/amethyst/commit/8ed78ea38fe1d02d21b33e9a350f21633d9891ff) +- [Adds zap amount cache for the memory space calculations](https://github.com/vitorpamplona/amethyst/commit/282d4614c0b000c82806105dd54c68a89ac4b4ec) +- [Allows users to select and copy the notice from the relay on the relay list dialog](https://github.com/vitorpamplona/amethyst/commit/7eaa553ebe1c12f413b0180f4bc13725146926b2) +- [Fixes the clickable regions to open additional relay info on the relay list dialog.](https://github.com/vitorpamplona/amethyst/commit/27d2e2309a1dbcb657e69c29d8ccc58666d42f40) +- [AGP to 8.5.2](https://github.com/vitorpamplona/amethyst/commit/312501e527a9ce126e9e346994e9ecc4c6e49914) + +[Changes][v0.89.10] + + + +# [Release v0.89.9 Outbox model to filter large follow lists.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.9) - 2024-08-07 + +- [Fixes the order of bookmarks (keeps the order of the event, instead of the created at)](https://github.com/vitorpamplona/amethyst/commit/ed0676a5f53e199fe85f4691f98946fd161fbded) +- [Improves the async rendering of Base64 content](https://github.com/vitorpamplona/amethyst/commit/f731c654b019e4a2f1395f44218e33d62f8e8759) +- [Moves discovery and video lists to Outbox when Follows or relay lists are selected](https://github.com/vitorpamplona/amethyst/commit/b026bffe4a57e8d53cc4b5385dc323caafcdb4bb) +- [Adds support for selecting authors based on their Outbox relays when searching for notes authored by them](https://github.com/vitorpamplona/amethyst/commit/a1aaec0b7d6cc14f5022462a54800e14a76ab396) +- [Aligns default note comparator to NIP-01's created at descending and then by id ascending](https://github.com/vitorpamplona/amethyst/commit/6f59097ac0612d3d236dee4f056e9a2ecb6259ec) +- [Keep them public to allow testing in these particular functions](https://github.com/vitorpamplona/amethyst/commit/e8574c10bbf357e221987c8dc94480ab972ceca3) +- [Refactors to use native contains instead of custom lambdas on Ammolite's Filter](https://github.com/vitorpamplona/amethyst/commit/7cb87ea9c5a115770c402656a10a176f75e1a3ac) +- [Refactors Ammolite Filters to be regular ones and creates a PerRelayFilter for the use on Amethyst.](https://github.com/vitorpamplona/amethyst/commit/07e5132943bf4c93337dd9e36223d7b95ed23669) +- [Renames the MinimumRelayList to RecommendationProcessor](https://github.com/vitorpamplona/amethyst/commit/2b1e3cfc93319c47bd66a728b47003e7aec1b060) +- [Adds haptic feedback to draft deletion swipe](https://github.com/vitorpamplona/amethyst/commit/e88d1d0d002430acf5641a23eb4f24377ec5e0df) +- [Moves the ContactList cache lists to AccountViewModel, where it can be disposed more efficiently.](https://github.com/vitorpamplona/amethyst/commit/5fdff97cf8e8e855e16dbaa0a1e60045887a1812) +- [Improves the accuracy of the Event memory counter.](https://github.com/vitorpamplona/amethyst/commit/e5328d79756dd45ea14605a4fbe606f47553d7e9) +- [Adds event factory performance test](https://github.com/vitorpamplona/amethyst/commit/71b45b96fbfbdcbbe2153812132723febc7d2924) +- [Adds extension possibility to Quartz's event factory](https://github.com/vitorpamplona/amethyst/commit/971c92b27a210c4cbebd1d1a5f23c7e06b0cd1c9) +- [Moves DataSource dispatcher from IO to Default](https://github.com/vitorpamplona/amethyst/commit/4c70065843af72d3963fd063bf3eee0e5d9f5f69) +- [Makes stringRes Stable for compose](https://github.com/vitorpamplona/amethyst/commit/ab772eb65e039f302b9e4d386ef99af2cd307540) +- [Removes Mutiny NWC button :(](https://github.com/vitorpamplona/amethyst/commit/84df86f4b6262870b837f927d60ab502093e4ae7) +- [Moves Relay viewModels to Default thread](https://github.com/vitorpamplona/amethyst/commit/a0289a0cb455846c177a039c6a663450d95b0dbd) + +[Changes][v0.89.9] + + + +# [Release v0.89.8: Delete all drafts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.8) - 2024-08-02 + +- [Add delete all drafts button](https://github.com/vitorpamplona/amethyst/commit/609ccaa63579f3936af8f8d9a71310f5d78fd122) +- [Enables crossfading between image states](https://github.com/vitorpamplona/amethyst/commit/bca941e04595f2e853c8375ab07fa66b1127eae3) +- [Signs for just one auth event to register with the push notification service instead of the dozens of events, one per relay.](https://github.com/vitorpamplona/amethyst/commit/38ba456a223a5197caae1b78b561f91c9d53281f) +- [Adds the highlight quote to the base URL of a highlight event so that when the user opens the link, it highlights on the page.](https://github.com/vitorpamplona/amethyst/commit/b440661e0de387b44035b6728567c2da333ef504) +- [Fix order of Share ImageAction](https://github.com/vitorpamplona/amethyst/commit/cb02955ac601a862016f1db2d7ef7f0afc349364) +- [Fix copying to clipboard edited notes](https://github.com/vitorpamplona/amethyst/commit/25823b1f397f9269e64c8fd0f401fc42a834a30e) +- [Adds tests for `02` and `03` compressed keys to make sure they can encrypt and decrypt from and to each other.](https://github.com/vitorpamplona/amethyst/commit/143c3a14440ee164f09519a27522d1521464417a) +- [Updates depedencies](https://github.com/vitorpamplona/amethyst/commit/a03a11c4cc35473ee2a206b2887f5b8d13c9bedb) +- [Fix Flow Release if not subscribed anymore.](https://github.com/vitorpamplona/amethyst/commit/0258c5aac23bd285fba9a93c8bac2db44ff0a9a5) +- [Adds the mint information to each cashu preview](https://github.com/vitorpamplona/amethyst/commit/bfbcf11fa3a3e7dc0760febb0ed8b1490e8a3082) +- [Fixes Unable to add to media gallery after pressing Show More](https://github.com/vitorpamplona/amethyst/commit/231af1d3d84cc2fc8c2445d7974b9fc1da5ba8db) [#993](https://github.com/vitorpamplona/amethyst/issues/993) +- [Fixes duplicated parsing of content for uncited hashtags](https://github.com/vitorpamplona/amethyst/commit/2b2f04f724397a2f5bfe612a685c378333e0a39b) +- [Better rendering for live streams that are planned but already finished.](https://github.com/vitorpamplona/amethyst/commit/d1278a44771b3bf29ef359881b9b183a2758eee7) +- [Fixes the need for main thread note loading for galleries](https://github.com/vitorpamplona/amethyst/commit/0af0f745bf591818873d28137d2c0e1b77b9b2c1) +- [Simplifies the drawing of gallery entires without e tags.](https://github.com/vitorpamplona/amethyst/commit/3bbb780d2bacbe16a46206f4e468df59012568b5) +- [Adds support for CashuB tokens using CBOR](https://github.com/vitorpamplona/amethyst/commit/fc98442f8b6eb5af817f562f89997a27fa8a2871) +- [Minimizes relay querying when rotating status events for each user.](https://github.com/vitorpamplona/amethyst/commit/63e036a9bbae5de18002989a65f530cd2a72943c) +- [Fixes Client notifications of relay failures after marking them as closed.](https://github.com/vitorpamplona/amethyst/commit/fd06193e938653ef47e667856a9f95df06795d5a) + +[Changes][v0.89.8] + + + +# [Release v0.89.7: minor fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.7) - 2024-07-22 + +- Add sendAndWaitForResponse to Client.kt +- [Avoids recomposition of the entire line when changing user status.](https://github.com/vitorpamplona/amethyst/commit/231ca44e1cd5ccae95e6263fbea1a7d0665cde53) +- Debug: [Prints memory use in descending order by size](https://github.com/vitorpamplona/amethyst/commit/ca00c87a6e3ef597df99fe1be1ce844391cd766d) +- Fix: [updates the EOSE of users even if no user is found in the relay.](https://github.com/vitorpamplona/amethyst/commit/4def80c91433433e7146178340af4e94f1caac1c) +- Fix: Filter renewing [Sorts keys before making the filter.](https://github.com/vitorpamplona/amethyst/commit/3c1f57fac0bea8f2c351936d7c94ecae5d7a0b85) +- Fix: [Remove focus from status text field when closing the drawer](https://github.com/vitorpamplona/amethyst/commit/e166c36731fc94f1b653321a01497d53ac471b32) +- [updates coil and jackson libs](https://github.com/vitorpamplona/amethyst/commit/a636f4a786d745bce3e45a5bc390b428d92250c7) + +[Changes][v0.89.7] + + + +# [Release v0.89.6: Fixes stringResource crash](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.6) - 2024-07-21 + +[Runs faster animations (200ms instead of 400ms)](https://github.com/vitorpamplona/amethyst/commit/52fef33662fd8e0e1e014b4359fab1790ee85e46) +[Adds the key to avoid applying to a separate navcontroller](https://github.com/vitorpamplona/amethyst/commit/2ef2f0d1a585f08e269194b5387b0c8aa7eb443c) +[Fixes stringResource cache](https://github.com/vitorpamplona/amethyst/commit/5a60c3a595869fc9b85ccc6655e3222b30cdfd19) + +[Changes][v0.89.6] + + + +# [Release v0.89.5: Fixes the drawing of screen below the nav bar](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.5) - 2024-07-20 + +- [Fixes screen rendering below the 3-button navigation](https://github.com/vitorpamplona/amethyst/commit/8ed3f84cb77e637b8a8d832ae36925c08e12a34d) +- [increases disk cache to 1GB and adds a memory cache policy.](https://github.com/vitorpamplona/amethyst/commit/fa06aefbf19fab24f0124c84893d08becd5b9e7b) +- [Adds more memory stat dumping for production apps](https://github.com/vitorpamplona/amethyst/commit/b80008d695e27caf900c748ac82c72edf2430218) + +[Changes][v0.89.5] + + + +# [Release v0.89.4: Migrates to edge to edge in preparation for Android 15](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.4) - 2024-07-19 + +- Fixes Darkmode Action bar crash +- Fixes empty relay list not connecting to anything (uses default relays instead) +- Fixes alt text of NIP-96 server lists +- Fixes auth infinite loop with nostr.wine +- Fixes the keyboard overriding parts of the screen +- Migrating to edge to edge in preparation for Android 15 + +[Changes][v0.89.4] + + + +# [Release v0.89.2: Bugfixes for TopNav Lists](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.2) - 2024-07-17 + + + +[Changes][v0.89.2] + + + +# [Release v0.89.1: Bugfix for invalid id crashes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.1) - 2024-07-16 + + + +[Changes][v0.89.1] + + + +# [Release v0.89.0: Profile Galleries, nip96 server setup and relay recommendations](https://github.com/vitorpamplona/amethyst/releases/tag/v0.89.0) - 2024-07-16 + +This version adds Profile Galleries, flexible NIP-96 image server settings and relay recommendations based on the outbox model. To add an image to your Gallery, click on the Share button and hit Add Media to Galery. This works on posts from you or from other people. + +Features: +- Renders Base64 images and gifs by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds NIP-96 image server settings by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) +- Adds Profile Gallery by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Adds outbox cache in order to resend events after relay authentication +- Force-updates relays that are sending old versions of replaceables or events that have been already deleted +- Adds follow-list based relay recommendations to the relay settings. +- Adds Malware Report type + +Performance Improvements: +- Reduces interruptions to the main thread +- Adds performance monitors for framedrops in benchmark mode + +BugFixes: +- Several improvements in the Push Notification API to never miss a Zap +- Fixes lack of text update when switching edited versions +- Fixes poll rendering behavior after deleting an option by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) +- Fixes discovery top nav list watcher staying active when the app goes to the background +- Fixes scoping issues with flattenMerge freezing Top Nav List updates +- Fixes Top Nav lists after a deletion event has been received +- Fixes a bug on clicking the user profile but loading the wrong one +- Fixes the post button disappeering when the Relay Settings top label is too large +- Fixes text cut off for very long posts by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes double auth triggering NOTIFY from inbox.nostr.wine + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Chinese by [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) +- Arabic, Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) and [@npub1tr66yvqghfdgwv9yxhmg7xx6pvgvu5uvdc42tgdhsys8vvzdt8msev06fl](https://github.com/npub1tr66yvqghfdgwv9yxhmg7xx6pvgvu5uvdc42tgdhsys8vvzdt8msev06fl) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) + +Code Quality Improvements: +- Removes decryption for DVM responses since it doesn't encrypt statuses +- Upgrades lifecycle to 2.8.3, Kotlin to 2.0.0, Lint to 1.3.1 and AGP to 8.5.1 +- Migrates sdk requirements to the version catalog +- Removes unnecessary dependencies for Ammolite +- Fixes several memory issues on CI due to Kotlin 2.0 +- Removes the bugfix for reproducible builds since it has been fixed +- Solves build slowdown on spotless dependencies + + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.89.0] + + + +# [Release v0.88.7: Solves Push Error when using 2+ accounts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.7) - 2024-06-29 + + + +[Changes][v0.88.7] + + + +# [Release v0.88.6: Fixes double auth triggering NOTIFY from inbox.nostr.wine](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.6) - 2024-06-28 + + + +[Changes][v0.88.6] + + + +# [Release v0.88.5 Swipe-to-Delete Drafts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.5) - 2024-06-28 + +#Amethyst v0.88.5: Swipe-to-Delete Drafts + +Features: +- Creates Ammolite, a library to host Relay access for other Nostr Clients by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds author picture when writing posts and replies. +- Adds a Swipe to delete action on the Drafts screen. +- Moves to non-deterministic signatures +- Renders relay lists (NIP-65, NIP-17, and Search kinds) as notes in the feed. +- Adds auth.nostr1.com as a recommendation for private inbox relays +- Adds uploading error messages for common HTTP status codes when uploading images/videos + +Performance Improvements: +- Saves a copy of the NIP65 and NIP17 relay lists locally + +BugFixes: +- Fixes not showing relay icons when sending chat messages with Amber. +- Adjusts the size of the reply button on chats +- Fixes the rendering of highlights when no user is present and includes options to render by e tags +- Fixes the position of the hash verification icon on NIP-95 images. +- Avoids using SSL on localhost relays by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes alignment of the close button on Chat's reply preview +- Adjusts default zap amounts for the Zap the Devs button +- Fixes decryption error on the PrivateOutboxRelayList event for an account that is not currently active. +- Fixes extra } when rendering hashtags from Markdown +- Fixes empty filters when the logged-in accounts only include the current account. +- Fixes bug on string resources showing the same Zap amount and message for different Zap notifications. + +Updated translations: +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Chinese by [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) +- Arabic, Bengali by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) + +Code Quality Improvements: +- Logs an error message in the Relay Dialog when the relay does not accept a new event +- Updates dependencies +- Changes "app" directory to "amethyst" due to the amount of libraries we now have in the same repo +- Renames JsonFilter to just Filter and adds a matching function +- Rearranges Quartz's crypto package into separate nips and reduces the amount of circular dependencies. +- Removes old highlight rendering functions +- Refactors PlaybackService + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.88.5] + + + +# [Release v0.88.4: Bigger reaction panel](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.4) - 2024-06-22 + + + +[Changes][v0.88.4] + + + +# [Release v0.88.3: New Reactions Popup](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.3) - 2024-06-21 + + + +[Changes][v0.88.3] + + + +# [Release v0.88.2: Reverting old account structure and migration](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.2) - 2024-06-20 + + + +[Changes][v0.88.2] + + + +# [Release v0.88.1: Solves Inbox.Nostr.wine notification](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.1) - 2024-06-20 + + + +[Changes][v0.88.1] + + + +# [Release v0.88.0: Performance Mode](https://github.com/vitorpamplona/amethyst/releases/tag/v0.88.0) - 2024-06-19 + +#Amethyst v0.88.0: Performance Mode and Performance improvements + +This version adds several performance improvements and includes a new UI mode in Settings that is designed for older phones. On that mode, all CPU-based animations are disabled, the use of transparency is minimized and the individually-generated robots are replaced by a static image. We also recommend disabling the Immersive Scrolling when using older phones. + +Features: +- Adds performance mode on Settings +- Adds login with NIP-05 address +- Adds outbox relays to zap request: sender, receiver and author relays. +- Adds the NIP-65 relay to zap split tag instead of kind3 relays. +- Adds support for AVIF images +- Adds flare.pub videos to the media tab +- Replaces the post view count for a Share icon in the main feed. + +Performance Improvements: +- Centralizes stringResource calls to cache them and avoid disk use +- Removes several unecessary UI states created during rendering +- Moves uncited hashtag parsing to a thread +- Replaces InputButton for ClickableBox to avoid loading colors during rendering +- Switches Social Icons mip-mapped PNGs to faster SVG versions +- Faster calculation of uncited hashtags in content +- Improves the speed of Robohash rendering +- Moves chatroom user group away from immutable sets +- Speeds up long-press Quick Action menus +- Optimizes NIP-11 fetch and avoids requesting twice in the same minute +- Redesigns the UI Components of the relay icons better performance +- Creates a relay flow cache to speed up the relay layout +- Combines hidden and reporting flows in a new cache +- Removes post reports Live data +- Refactors Full Bleed design of the master note +- Unifies Hidden and Report checks between the Video Feed, the Full Bleed Design and the Card layout. +- Adds a hashcode cache to speed up O(1) requests of spam and blocked user public keys +- Minimizes memory alloc by adding a native forEach and Map functions in the event's tag array +- Reduces double launch of co-routines +- Improves memory use of updates to the subscription after EOSE events +- Simplifies intrinsic size calculations for Image Previews and Videos +- Improves rendering time of chat messages + +BugFixes: +- Fixes the inconsistency of button animation size in the reaction row +- Fixes the inconsistency of the Zap button graphics +- Fixes the Giftwraps query by EOSE date mismatch +- Fixes the keyboard's Go Button action on new user screen +- Stops redirecting when resolving nip05 addresses by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fix hidden notes when hidden words is empty by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes Url Preview crop when the image is too small or to big for the preview card. +- Better error messages when NIP-11 queries fail +- Fixes use navigateUp instead of popBackStack to avoid closing the app on double clicks on the back button +- Fixes the centered url on videos without active playback +- Fixes the padding of the reaction row on quotes +- Solves notification dots appearing on the navigation bar due to a hidden post +- Increases the download limit for reactions/zaps to events from 100 to 1000 +- Fixes zap split rounding precision +- Fixes padding of the zap raiser +- Avoids showing error message if devs have removed their lnadress on the Zap the Devs card. +- Fixes padding and border of the zap split section on the master note +- Removes gray border in image urls that couldn't be loaded. +- Fixes alignment of reactions +- Fixes not centered Blank Notes +- Fixes scrollable drawer for all screen sizes +- Fixes search limits for profiles from 100 to 1000 events +- Re-normalizes all relays urls before connecting to reduce duplications +- Fixes the jittering from resizing Videos and Images during loading. +- Fixes landscape video centralization +- Forces relay URLs to be single line. + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Chinese by [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) + +Code Quality Improvements: +- Removes old Robohash bitmap-based generation +- Upgrades Compose, Lifecycle and Fragments + +Download via [Obtainium](http://amethyst.social) or [Zap.Store](https://zap.store/) + +[Changes][v0.88.0] + + + +# [Release v0.87.7: Revert Save button](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.7) - 2024-06-11 + +- Reverts Image dialogs to have a separate save button +- Adds save button to video player. +- [Fixes not centered Blank Notes](https://github.com/vitorpamplona/amethyst/commit/165c3bb852ece90a5fcad676f6710fcd5b356097) +- [Fixes scrollable drawer for all screen sizes](https://github.com/vitorpamplona/amethyst/commit/2e9683491fce9197245f4aef0c1dd6f5534d2bfd) + +[Changes][v0.87.7] + + + +# [Release v0.87.6: AOSP-based keyboard Fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.6) - 2024-06-08 + +- Fixes relay drops and difficulty in connecting when switching WIFI to Mobile +- Fixes the scrolling of the followed hashtags feed on User Profile +- Fixes crashing when tagging users with old AOSP-based keyboards +- Adds query by hashtag in reposted notes +- Fixes inbox.nostr.wine Pay Notification when already paid +- Performance: Moves OTS attestations local cache to a flow instead of live data +- Restructures video and image views and dialogs to avoid some buttons getting on top of one another +- Fixes videos re-starting from 0 when clicking in the Playing Video notification card +- Performance: Moves the video release to a threadsafe procedure +- Fixes fiatjaf search: Adds larger search limits for profiles + +[Changes][v0.87.6] + + + +# [Release v0.87.5: Re-normalizes all relays](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.5) - 2024-06-04 + +- Re-normalizes all relays urls before connecting to reduce duplications ([`d10b4c6bde`](https://github.com/vitorpamplona/amethyst/commit/d10b4c6bdee0f57f6f855b9ec9032059e08d89ba)) +- Normalizes all new relays in the edit screens. +- [Adds flare.pub videos to the media tab on Amethyst](https://github.com/vitorpamplona/amethyst/commit/f1e516662c53c2f72bbed087e0ede168a28ee841) +- Performance Improvements: Simplifies intrinsic size calculations for Image Previews and Videos +- Improves rendering of chat messages +- Fixes the jittering from resizing Videos and Images during loading. +- Fixes video cut off when loading +- Fixes blurhash covering videos in landscape +- Fixes landscape video centralization +- Fixes chat using Two Pane layout for landscape and regular for portrait +- [Improving the detection of image types on the Media Feed.](https://github.com/vitorpamplona/amethyst/commit/1bf81656417ce41e619155394f27ec930fade859) + +[Changes][v0.87.5] + + + +# [Release v0.87.4: Fixes Live Streaming getting stuck](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.4) - 2024-06-03 + + + +[Changes][v0.87.4] + + + +# [Release v0.87.3: Fixes for using the wrong relays for DVMs.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.3) - 2024-06-03 + + + +[Changes][v0.87.3] + + + +# [Release v0.87.2: Relay connection bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.2) - 2024-06-01 + + + +[Changes][v0.87.2] + + + +# [Release v0.87.1: BugFix missing notification dot](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.1) - 2024-06-01 + + + +[Changes][v0.87.1] + + + +# [Release v0.87.0: DVMs and Gossip](https://github.com/vitorpamplona/amethyst/releases/tag/v0.87.0) - 2024-06-01 + +#Amethyst v0.87.0: Data Vending Machines (DVMs) and Gossip Model + +This version adds support for Data Vending Machines for content discovery. You can request a job by simply navigating to the 4th tab and choosing one of the DVMs. It also starts our support for the Inbox/Gossip model. The relay setup screen has been rewritten to support the many types of relays Amethyst will start to use. Please add your relays as you see fit. + +Our video caching system has been improved. Most of the high-bandwidth use of the app in the last month has been due to a faulty caching system for some video types. The app was just downloading them at every playback. In a similar way, the caching system for encrypted events has been massively improved. The app should feel visibly lighter at this point. + +If you generated your keys from NIP-06 seed words you can now type them on the login screen to start the app. We are not generating seeds yet, but this will be available in the upcoming versions. + +We are also moving to deprecate and remove most of the NIP-04 usage in the app. In the future, users won't be able to send new NIP-04 DMs but the history of past DMs will be available for as long as we can support it. + +Features: +- Adds support for NIP-90, data vending machines by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Adds support for discovery content DVMs in the discovery tab by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Adds support for paid DVMs by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Adds support for NIP-06 seed word key derivation (bip32 and bip39) when logging in +- Adds support for NIP-65 relay lists +- Adds support for NIP-17 private DM relay lists +- Adds support for private relay lists to save Draft events +- Adds support for local relays as a separate relay set, saving locally only. +- Adds message + dialog to setup Search relays when searching +- Adds message + dialog to setup DM relays when messaging +- Adds signString method for Amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Prefers NIP-65 relays for zap request relay tags +- Prepares for NIP-96 server list integration +- Adds paste from clipboard button to NWC screen by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Moves video compressing quality to medium instead of low +- Adds recommended amounts for the Zap the Devs +- Reduces default zap amounts due to the change of Bitcoin price +- Allows the new post's relay selection dialog to pick any relays (instead of just writing relays) by [@npub10npj3gydmv40m70ehemmal6vsdyfl7tewgvz043g54p0x23y0s8qzztl5h](https://github.com/npub10npj3gydmv40m70ehemmal6vsdyfl7tewgvz043g54p0x23y0s8qzztl5h) +- Improves Zap efficiency for large zap splits +- Adds a queue of commands while the relay connects +- Makes sure only one connection per URL is made when doing splits +- Removes unnecessary Amber calls when decrypting private zaps +- Improves Zap error messages to include the lnaddress of the error +- Displays Zap Split error messages in sequence instead of in multiple popups. + +Bug Fixes: +- Waits 500ms before restarting all connections when saving new relays +- Automatically deactivate writes for search relays (they are read-only) +- Overrides pubkey to avoid impersonators on seals. +- Fixes the rendering of replies on wikipages. +- Fixes duplicated imeta tags when uploading the same image twice +- Removes reposts from the Dot Notification in the home's bottom bar icon +- Fixes a white space when including an image url after a new line +- Fixes alignment of the like icons after the like event +- Fixes wrong display of original and forked notes +- Improves the rendering of Channels and Communities when quoted +- Slightly better rendering Drafts in the thread +- DecimalFormats are not thread safe, moving them to thread objects +- Block error messages from closing the Zap split payment screen +- Better formats zap amounts (don't show .0 if the previous numbers are large) +- Fixes the offset position of the payment amounts on the Zap the Devs message +- Fixes Copy Text function of DraftEvents +- Fixes top bar lists not updating when following communities and hashtags. +- Show toast error if unable to hide words by [@npub10ug9xs24ay5339agakaqk556t6zvq9qn5vm0vlhc4pu25cx0l32qxhrm9e](https://github.com/npub10ug9xs24ay5339agakaqk556t6zvq9qn5vm0vlhc4pu25cx0l32qxhrm9e) +- Adds Autofocus when entering the search screen by [@npub10ug9xs24ay5339agakaqk556t6zvq9qn5vm0vlhc4pu25cx0l32qxhrm9e](https://github.com/npub10ug9xs24ay5339agakaqk556t6zvq9qn5vm0vlhc4pu25cx0l32qxhrm9e) +- Fixes the use of Global-active relays in the Global Feed +- Fixes special chars on URL previews by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes the lack of refresh when adding hidden words in the Security filters +- Makes sure only one buffering action is run for each video view +- Increases timeout to Tor connections +- Fixes a bug with `signature-null` in the sig of events from Amber + +Updated translations: +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Polish by [@npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm](https://github.com/npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Swahili by [@npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr](https://github.com/npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr) +- Thai by [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Hindi by [@npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6](https://github.com/npub1ww6huwu3xye6r05n3qkjeq62wds5pq0jswhl7uc59lchc0n0ns4sdtw5e6) +- Spanish by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) + +Performance Improvements: +- Optimizes Blurhash generation (4x gains) +- Speeds up the URL finder in the new post edit text (8x gains). +- Reduces the use of background colors to improve rendering speeds (15% gains). +- Refactors Giftwrap caching to delete encrypted text and reload the wrap if necessary (20x savings in memory use). +- Changes message wrap host to a host stub to reduce memory use +- Only download GiftWraps form 2 days past the last EOSE +- Moves the thread formatter and calculator out of Note to avoid memory use +- Slight improvement on the thread view for badges +- Unifies NIP01 Serialization with SHA-256 procedures to reduce the creation of several byte arrays at every verification +- Minimizes costs of keeping track of the number of events received per subscription +- Moves ClientController executor to a thread +- Speeds up ID calculations for Amber's Intent call + +Code Quality Improvements: +- Major refactoring of the Relay List screens +- Refactors Relay URL formatter to Quartz +- Adds new observer structure for the LocalCache +- Moves Blurhash code to the commons module +- Updates UnifiedPush by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) +- Migrates to the latest Kotlin, Compose, and AGP 8.4.1 and several other dependencies + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.87.0/amethyst-googleplay-universal-v0.87.0.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.87.0/amethyst-fdroid-universal-v0.87.0.apk ) + +[Changes][v0.87.0] + + + +# [Release v0.86.5](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.5) - 2024-04-11 + +[Enables Mutiny Wallet NWC](https://github.com/vitorpamplona/amethyst/commit/b90a57220d11e84f068641896bdaf5da941102ea) +[Removes the use of DM relays to find events due to private inbox settings](https://github.com/vitorpamplona/amethyst/commit/a538b66db328229931fd513269f4c323a27b64fe) +[Adds vertical scrolling on the Zap page for collaborators.](https://github.com/vitorpamplona/amethyst/commit/f04631b0dd74df82f4204276ad99d85068b50223) +[Avoids decrypting existing Nostr events just to add the relay into the relay list.](https://github.com/vitorpamplona/amethyst/commit/6e31cff99c179c52cfe586ee64061691035f2850) +[Calculates hash in the IO thread from Compose's scope.](https://github.com/vitorpamplona/amethyst/commit/1553640c1846979a9100c2507e95f36a623b7f7e) +[New Crowdin translations by GitHub Action](https://github.com/vitorpamplona/amethyst/commit/f6cce42028a834037eb1e5cf1538d88c746e6cc4) + +[Changes][v0.86.5] + + + +# [Release v0.86.4: Start up bug fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.4) - 2024-04-11 + +[Updates AGP](https://github.com/vitorpamplona/amethyst/commit/fa7aa3cf241fcc993cf864b57dbbf840d2e9fbbe) +[Updates compose BOM](https://github.com/vitorpamplona/amethyst/commit/d38b57025cd6a2ff3c3d493e7e5e7f80b1cb9db2) +[Updates Kotlin version](https://github.com/vitorpamplona/amethyst/commit/eca5b47ab0a1a302cf4ca29bdbdec802ae0fa2fd) +[Fixes missing Zaps and some DMs on startup](https://github.com/vitorpamplona/amethyst/commit/4722b2a6172a8d706d0f8aafc9af6344520a8608) +[Do not use tor proxy when localhost, fix proxy not being used inside ImageDownloader.kt](https://github.com/vitorpamplona/amethyst/commit/31516964c86e51f2840864314a2a9255680ea376) +[Fixes image downloader not going through Orbot's Proxy](https://github.com/vitorpamplona/amethyst/commit/c4250ccd352d0f059b70e879fb125803142abd2c) + +[Changes][v0.86.4] + + + +# [Release v0.86.3: New Markdown Parser](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.3) - 2024-04-10 + +- Migrates to the new, faster Markdown Parser +- Adds Note previews on Markdown +- Adds Custom hashtag icons to Markdown +- Adds URL preview boxes to Markdown +- Fixes Missing notifications +- Fixes clickable route not showing the user's npub before loading their name +- Fixes max width of hidden notes making them off-centered +- Moves parsing and saving an embed event to the IO thread +- Improves the secondary button design of the encrypted nsec backup page + +[Changes][v0.86.3] + + + +# [Release v0.86.2: Fixes Draft Deletion in Threads bug](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.2) - 2024-04-05 + +#Amethyst v0.86.2: Draft BugFixes + +- Fixes Draft Event not being deleted in threads +- Fixes draft decryption error +- Adds ws:// if not present in .onion relay urls +- Fixes double notifications + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.86.2/amethyst-googleplay-universal-v0.86.2.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.86.2/amethyst-fdroid-universal-v0.86.2.apk ) + +[Changes][v0.86.2] + + + +# [Release v0.86.1: Fixes Draft into Draft infinite loop](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.1) - 2024-04-04 + + + +[Changes][v0.86.1] + + + +# [Release v0.86.0 Draft Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.86.0) - 2024-04-04 + +This version adds support for draft notes autosaved on your relays, a new simplified UI choice on Settings, changes the Discover tab algorithm to show the latest of chats and communities and much more. + +Features: +- Draft notes for feeds, replies, live streams, public chats, NIP-04 DMs, GiftWrap DMs, polls and classifieds by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Adds autosave for Drafts by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Adds edit draft in the dropdown menu and the long press popup by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Adds a Draft feed screen for all posts +- Adds new algorithm to parse OpenGraph tags by nostr:npub168ghgug469n4r2tuyw05dmqhqv5jcwm7nxytn67afmz8qkc4a4zqsu2dlc +- Adds a Simplified UI setting to both feeds and chats +- Moves the username play button to the profile page. +- Adds link to the version notes when clicking in the version in the drawer +- Brings new git Issues and Patches to the Notification +- Filters out too many reposts of the same note when on the main feed +- Updates the bootstrap relay list +- Adds missing classes to support WebServer connections in the Video Playback +- Slightly reduces line height for improved readability +- Reduces the space between chat bubbles. +- Migrates shareable links from habla.news to njump.me +- Restructures the Discover Tab to show the Chats and Communities with the most recent new content. +- Adds a bot field to the user info +- Adds k-tag to the Deletion events +- Adds button to load Zap Splits from the cited users in the text +- Several accessibility improvements by nostr:npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef + +Bug Fixes: +- Fixes the post cut-off when the post has massive string chars without spaces or new lines +- Fixes missing Fhir Classes on Release +- Don't show the button to edit the post if the author of the original post is not the logged in user +- Fixes crash parsing multiple results from Amber by nostr:npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5 +- Fixes the load of edits on a new edit proposal +- Fixes forking information kept from a previous post +- Fixes search on binary content +- Fixes space after clickable user display +- Centers Blank Note when post was hidden by the user. +- Accepts JSON events with escaping errors +- Fixes the parsing of user metadata events several times due to large coroutine backlog +- Fixes Scheduled Tag in LiveStreams +- Fixes the isOnlineCheck for nostr nests. +- Fixes sorting contract issues when follow status and user names are the same between keys +- Fixes tickmarks on dropdowns +- Checks if a Classified is wellformed before rendering +- Fixes size and alignment of the text when the live stream video is not present. +- Fixes some imports for benchmarks +- Fixes infinite Quotation issue (3 quotes are allowed). +- Fixes crashing with too many videos in quoted posts. +- Fixes double Show More when the user has hidden a post and ALSO the user's followers have reported the post. +- Only shows OTS to the respective Edit +- Fixes a bug with the latest version of jackson +- Avoids showing machine-code errors when paying for zaps on external wallets +- Fixes too strict timing constraints for new posts (accepts up to a minute in the future) +- Fixes following of geotags +- Fixes lack of zap amount refresh after zapping a note. +- Fixes videos not being able to seekTo the zero position. +- Fixes layout issues of Blog Post summaries when images are not present. +- Doesn't show edits of blog posts in the User's Profile +- Fixes Amber's deep sleep: Adds a lifeCycleOwner listener to register external signers on resume +- Fixes missing context in some replies to blog posts. +- Adds a space after the Channel header in the reply rows +- Centralizes the counter after the list of participants in a live event. +- Fixes double mention to Community headers when seeing a reply to a community post. +- Fixes Chat preview images when no image has been set. +- Fixes the display or Zap Events when All Follows is selected in Notifications +- Fixes the reply event finder for the reply row of text notes +- Makes hidden cards full width on the discovery feed +- Fixes the width of muted messages on chat feeds. +- Fixes the feed updates after list selections on the Discovery pages. +- Realigns the reaction icons and texts between main feed and video feed. +- Fixes garbled URL preview for non-UTF-8 HTML by nostr:npub168ghgug469n4r2tuyw05dmqhqv5jcwm7nxytn67afmz8qkc4a4zqsu2dlc +- Adjusts icon sizes on the galleries +- Avoids publishing with two equal `t` hashtags when the user already writes them in lowercase +- Limits the size of image previews from opengraph from being too big +- Fixes NPE with the cached state. +- Increases the push notification max delay to 15 minutes +- Fixes controller comparison for keep playing +- Fixes tag markers for replies in DMs +- Fixes layout of the reply row in chats +- Fixes lack of blurhash preview in some videos +- Fixes the lack of following mark on user pictures in chats +- Fixes the UI spacing for channels +- Fixes the use of filters that didn't discriminate the relay type setup +- Holds the state of Show More when switching edits and translations +- Renders DMs and live chats in the feed if they show up there +- Fixes contract violation when sorting users + +Updated translations: +- Spanish by nostr:npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903 +- French by nostr:npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz +- Dutch by nostr:npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd +- Swahili by nostr:npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr +- Chinese by nostr:npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7 +- Bengali by nostr:npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t +- Hungarian by nostr:npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp +- Czech, German, Swedish and Portuguese by nostr:npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef +- Arabic by nostr:npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t +- Thai by nostr:npub1tr66yvqghfdgwv9yxhmg7xx6pvgvu5uvdc42tgdhsys8vvzdt8msev06fl and nostr:npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e + +Performance Improvements: +- Switches Robohash to Precompiled SVGs in order to reduce the memory burned of creating Strings with SVGs on the fly +- Restructures Data Access filters and LocalCache to use a ConcurrentSkipList instead of ConcurrentHashMap +- Only download video, image and audio files in NIP-94 +- Updated hashtag icons for performance +- Avoids checks if a filter has changed before generating JSon strings +- Cleans up User Metadata upon receipt instead of in every rendering +- Simpler/Faster UserDisplay renderings +- Reduces video cache from 10 to 4 videos +- Removes coroutine use for Hashtags +- Brings the ZapForwarding icon to Compose +- Simplifies the algorithm to check if chatroom sender intersects with the follow list +- Avoids serializing temporary fields on Quartz +- Refactors views to the video and chat feeds +- Restructures NoteCompose for performance +- Restructures markAsRead to minimize threading cost +- Adds a large benchmark test for duplicate events +- Optimizing the performance of Highlight rendering +- After memory cleanup, only trigger liveData when it actually changes +- Minimizes memory use to calculate zaps +- Avoids triggering an error when decoding invalid hexes +- Reduces the amount of co-routines being launched in each LiveData update +- Migrates channel list and channel notes to LargeCache +- Removes the use of data classes to speed up comparisons +- Improves Nostr filter to bring public chat messages and avoid public chat creation and metadata updates +- Removes jsoup from dependencies +- Removes the need to observe author changes to event after loaded +- Turns hashtag icons into programmable vectors +- Moves the Following Vector to a native composable +- Removes unnecessary modifier layouts from the top bar +- Uses the cached thread pool instead of the scheduled thread pool for translation services +- Avoids launching coroutines that were just launched +- Makes a cache for Media Items +- Only changes the keep playing status if different +- Reduces recompositions after video/image hash verification +- Avoiding feed jitter when pressing the notification button twice + +Code Quality Improvements: +- Breaks massive NoteCompose down into each event type +- Removes the release drafter plugin on actions. Too buggy +- Removes dependency of the Robohash from CryptoUtils +- Improves Preview helper classes +- Updates secp256k1KmpJniAndroid, compose, zoomable, media3, jackson and firebase libs +- Updates AGP to 8.3.1 +- Deletes the old Settings local db +- Refactors some of the old display name structure +- Refactors Relay classes. +- Isolates the LargeCache forEach method to allow quick time measurements on filters +- Reorganizes classes in the commons lib +- Fixes test cases for nip96 uploaders +- Removes unused addMargin param +- Refactoring caching systems for the Compose layer +- Aligns the BOM between implementation and tests +- Refactors the use of dividers out of components +- Refactors composables to load events, check hidden and check report +- Fix Kotlin encryptDecryptTest to decrypt with swapped private and public keys to follow NIP-44 documentation by nostr:npub1yaul8k059377u9lsu67de7y637w4jtgeuwcmh5n7788l6xnlnrgs3tvjmf +- Finishes the migration of People List updates from LiveData to Flow +- Migrates all Refreshable feeds to the Refreshable box component +- Refactors cache methods in GiftWraps +- Migrates Media3 Videos to the DefaultMediaSourceFactory + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.86.0/amethyst-googleplay-universal-v0.86.0.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.86.0/amethyst-fdroid-universal-v0.86.0.apk ) + +[Changes][v0.86.0] + + + +# [Release v0.85.3](https://github.com/vitorpamplona/amethyst/releases/tag/v0.85.3) - 2024-03-04 + +- [Displaying issues and Patches in the Notification](https://github.com/vitorpamplona/amethyst/commit/5848255e72fae583057da73a1a2f2d295d4e1d04) +- BugFix: [Cleans up the fork information on new posts has been canceled or posted.](https://github.com/vitorpamplona/amethyst/commit/8299f4cfca41333d3ff212ef723bf86e12e6c080) +- [Displaying correct edits on the new edit proposal](https://github.com/vitorpamplona/amethyst/commit/e9fd62dc26bfa66a59b3da613df522fa21b6a10d) +- [Adds link to the version notes from the drawer](https://github.com/vitorpamplona/amethyst/commit/7bc393143c5e590951f8e499b0caed442d274655) +- [fix crash parsing multiple results from amber](https://github.com/vitorpamplona/amethyst/commit/23718f51dd203020035933af88d54e39c415c215) +- [Adds nostr git for issue management software.](https://github.com/vitorpamplona/amethyst/commit/9081d5a54b9f847e4683de3268681e4a15d2eb4c) +- [Don't show button to edit the post if the author of the original post is not the logged in user](https://github.com/vitorpamplona/amethyst/commit/cd2b5d78a182d386d6197c2040e3b6da53a1aa99) + +[Changes][v0.85.3] + + + +# [Release v0.85.1: Medical Data fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.85.1) - 2024-03-04 + + + +[Changes][v0.85.1] + + + +# [Release v0.85.0 Edits, Git, Embed, etc](https://github.com/vitorpamplona/amethyst/releases/tag/v0.85.0) - 2024-03-04 + +Adds support for post edits, post forks, pull requests, open timestamp, git repositories, issues, patches and replies, wiki pages and some medical data. + +New Additions: +- Adds support for editing of notes (NIP-37 / kind: 1010) +- Adds support for sending edit proposals. +- Adds embeded events in NIP-19 uris +- Adds support for NIP-03: OpenTime Stamp attestations (kind: 1040) +- Adds support for Decentralized Wikis (event kind 30818) +- Adds basic support for NIP-34: Git repositories (kind 30617), patches (kind 1617), issues (kind 1621) and replies (kind 1622). +- Adds rendering support for FHIR payloads (kind 82). +- Adds support for the q tag +- Adds early support for Kind1 forks. +- Sets zap splits automatically for quotes and forks +- V4V: Ask for donations in the Notification page +- Adds relay icon rendering from the NIP11 document + +Bug Fixes: +- Fixes the text's vertical alignment when emoji's are present +- Fixes DM Chatroom edit button +- Fixes the crash when images are not being present in the image dialog. +- Inserts uploaded URLs where the cursor is and not at the end of the new post. +- Fixes the rendering of Japanese characters, hashtags and custom emojis in the same line. +- Fixes the dissapearance of some Quartz classes when exporting to maven +- Fixing stack overflow with more than 200 zaps in a single note. +- Fixes image preview visualization on a new post +- Adds support for a new report option as Other +- Fixes missing nsec processing when parsing NIP-29 uris +- Fixes caching issue when creating a Bitcoin invoice for the first time +- Fixes UI issues due to the caching of Polls +- Better aligns post header elements +- Fixes bug with NIP-11s with null `kind` arrays +- Fixes quote and repost notes partially disappearing when they contain hidden users or words. +- Fixes content title for the video playback notification + +Updated translations: +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Spanish, Spanish, Mexico and Spanish, United States by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Swahili by [@npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr](https://github.com/npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr) +- Czech, German, Swedish and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Arabic by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) + +Performance Improvements: +- Improves the speed of the text parser +- Reduced memory footprint of navigation buttons +- Faster hex validation +- Increases the speed of the Robohash SVG to byte buffer function +- Adds Benchmark tests for the content parser +- Adds Benchmark tests for the url detector +- Speeds up image compositions +- Improves relay list NIP-11 caching +- Faster Longform tag filters +- Speeds up the loop through local cache +- Improves the speed of Location services +- Improves the cache of LnInvoices +- Improves cache of cashu tokens +- Reduces memory footprint for parsed posts. + +Code Quality Improvements: +- Moves content parsers and media classes to commons. +- Moves emoji parsers to commons +- Moves Wallet Connect code to Quartz +- Moves Relay information code to Quartz +- Removes dependency on Kotlin serialization +- Adds a release draft generator to CI +- Updates Vico, Compose UI Version, Coil and Google Service dependencies +- Refactors the code to manage extra characters after Bech32 Links +- Moves to Android Studio Iguana | 2023.2.1 +- Moves gradle to 8.4 +- Moves project to version catalogs + +[Changes][v0.85.0] + + + +# [Release v0.84.3: Emoji Passwords in NIP49](https://github.com/vitorpamplona/amethyst/releases/tag/v0.84.3) - 2024-02-16 + +#Amethyst v0.84.3: NIP-49 Emoji Password fix + +If you exported your secret key with any composable Unicode characters as passwords (like an emoji), please export it again. + +Bugfixes: +- Counts any quoted post as retweets in the notification stats +- Avoids the need to p-tag the user to count as a mention +- Normalizes passwords to Unicode's NFKC in NIP49 +- Adapts Scrypt lib to support empty keys + +Code Quality Improvements: +- Refactors clickable text and notification feed filter +- Updates secp256k1 + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.3/amethyst-googleplay-universal-v0.84.3.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.3/amethyst-fdroid-universal-v0.84.3.apk ) + +[Changes][v0.84.3] + + + +# [Release v0.84.2: Fixes text alignment issues](https://github.com/vitorpamplona/amethyst/releases/tag/v0.84.2) - 2024-02-15 + +#Amethyst v0.84.2: Text alignment fix + +Bugfixes: +- Fixes link misalignment in posts + +Updated translations: +- Czech, German, Swedish, and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.2/amethyst-googleplay-universal-v0.84.2.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.2/amethyst-fdroid-universal-v0.84.2.apk ) + +[Changes][v0.84.2] + + + +# [Release v0.84.1 Support for NIP-49](https://github.com/vitorpamplona/amethyst/releases/tag/v0.84.1) - 2024-02-14 + +#Amethyst v0.84.1: ncryptsec support (NIP-49) + +Now you can export and log in with a password-protected version of your private key. This new format starts with **ncryptsec** and requires inputting a password to decrypt the key before loading it into a client. Keep in mind that the new format is not designed to replace your **nsec**, but to work side-by-side with it. Keep your nsec in the safest place you can and use the **ncryptsec** to move your key between devices, deleting it as soon as you are done with the transfer. + +New Additions: +- Adds support for NIP49 to login and back up key screens +- Adds cryptographic support for NIP-49 to Quartz +- Enables citation on chats via @ +- Adds "₿itcoin" to the set of custom hashtags + +Updated translations: +- Portuguese by [@npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6](https://github.com/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Chinese by [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) + +Performance Improvements: +- Avoids the memory use of the flatten operation on Notification counters +- Adds a check for the main thread when pulling opengraph tags. +- No need to crossfade when clicking on Show More + +Code Quality Improvements: +- Updates Compose dependencies + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.1/amethyst-googleplay-universal-v0.84.1.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.84.1/amethyst-fdroid-universal-v0.84.1.apk ) + +[Changes][v0.84.1] + + + +# [Release v0.83.13: Community and Public Chats early support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.13) - 2024-02-12 + +New Additions: +- Adds background support for community and public chat list events from NIP-51 +- Removes the confusing notification dot of the discovery tab + +Bugfixes: +- Fixes thread rendering when `mention` events are added without mentioning any event. +- Unwrapps the reply message if the GiftWrap was tagged as a reply instead of the correct message id. +- Fixes Send to Top in the marketplace +- Fixes text-to-voice accessibility issues in the main feed UI +- Inverts the order of the hidden users in the security screen: last blocked goes first +- Fixes crash when mute list has `e` tags that are not valid hexes +- Fixes crash when opening an incorrect `nostr:` uri + +Updated translations: +- Czech, German, Swedish, and Portuguese by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) + +Performance Improvements: +- Moves language translation cleanup to the IO thread since it clears disk files as well +- Small adjustments in the re-use of modifiers + +Code Quality Improvements: +- Small refactoring to focus the encrypted storage procedures to the application context. + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.13/amethyst-googleplay-universal-v0.83.13.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.13/amethyst-fdroid-universal-v0.83.13.apk ) + +[Changes][v0.83.13] + + + +# [Release v0.83.12](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.12) - 2024-02-06 + +Performance Improvements: +- Improved scroll performance with faster text parsing tools + +[Changes][v0.83.12] + + + +# [Release v0.83.10: Bug Fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.10) - 2024-02-05 + +#Amethyst v0.83.10: Bug Fixes + +New Additions: +- Adds Horizontal Scroll to the action buttons in the New Post screen to partially fix hidden buttons in small/thin screens. + +Bugfixes: +- Fixes crash with an invalid custom Zap Amount +- Fixes relay re-connection issues when the relay closes a connection +- Fixes the top padding of the quoted note in a post +- Optimizes memory use of the visual user and url tagger in new posts + +Updated translations: +- Persian by [@npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk](https://github.com/npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk) +- French and English, United Kingdom by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) + +Performance Improvements: + +Code Quality Improvements: + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.10/amethyst-googleplay-universal-v0.83.10.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.10/amethyst-fdroid-universal-v0.83.10.apk ) + +[Changes][v0.83.10] + + + +# [Release v0.83.9: NIP-92 support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.9) - 2024-02-01 + +#Amethyst v0.83.9: Support for NIP-92 + +New Additions: +- [Includes the product in the first message of the marketplace.](https://github.com/vitorpamplona/amethyst/commit/54155a3c30bbf59849b7f42b0b518a92c0552696) +- [Adds support for NIP-92 in public messages and new DMs. NIP-54 stays in NIP-04 DMs](https://github.com/vitorpamplona/amethyst/commit/e56377f8c3f8e8e53844d1cc56786f3072876e42) + +Updated translations: +- Ukrainian by lizzz +- Spanish, Spanish, Mexico and Spanish, United States by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Arabic by [@npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t](https://github.com/npub13qtw3yu0uc9r4yj5x0rhgy8nj5q0uyeq0pavkgt9ly69uuzxgkfqwvx23t) + +Code Quality Improvements: +- [Updates to Android Studio Hedgehog | 2023.1.1 Patch 2](https://github.com/vitorpamplona/amethyst/commit/34d373c293db368173b66b71bba0c90fe584b389) + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.9/amethyst-googleplay-universal-v0.83.9.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.9/amethyst-fdroid-universal-v0.83.9.apk ) + +[Changes][v0.83.9] + + + +# [Release v0.83.8 Bug Fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.8) - 2024-01-31 + +#Amethyst v0.83.8: Bug Fixes + +New Additions: +- Removes the need for Amber's package name in the androidManifest for the external signer by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds a longpress to copy url to the url preview card by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds support for always rejected permissions from external signer by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds the exception descripton to the Zap error message. + +Bugfixes: +- Fixes secondary buttons theme in the login and signup screens. +- Fixes vertical misalignment of some npubs in the middle of the note. +- Fixes NPE when accounts are not present when resuming the app in a group +- Fixes missing language options for Greek by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes content sensitivity for NIP-54 images. +- Fixes proxy setup when de/activating Tor / changing ports by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes remember of the wrong hashtag because it's a different post. + +Updated translations: +- Czech, German, Swedish and Portuguese, Brazilian by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Spanish, Mexico and Spanish, United States by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- French by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Serbian by [@npub187h9tymz5j6vhyl26kl74yh6yzqzpjec9806w7taey2zefytlmdsttx7v2](https://github.com/npub187h9tymz5j6vhyl26kl74yh6yzqzpjec9806w7taey2zefytlmdsttx7v2) + +Performance Improvements: +- Makes sure cancellation of coroutines stops long processes. + +Code Quality Improvements: +- Makes the benchmark module profileable +- Updates dependencies + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.8/amethyst-googleplay-universal-v0.83.8.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.8/amethyst-fdroid-universal-v0.83.8.apk ) + +[Changes][v0.83.8] + + + +# [Release v0.83.7: New Sign up screen](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.7) - 2024-01-11 + +New Additions: +- [New Signup screen](https://github.com/vitorpamplona/amethyst/commit/7b7e3624acef4f502eb82116098e3fd05f972d6d) +- [Reduces the size of the following icon](https://github.com/vitorpamplona/amethyst/commit/d27b9ae5a84e753b04592daa5b17cacacbd39dca) + +Bugfixes: +- [Fixes the BookmarkScreen update after adding and removing a bookmark to the list](https://github.com/vitorpamplona/amethyst/commit/383d859544d55eae71b41c2be4a4d78b7ebfce11) +- [Solving viewModel creation bug for Public Bookmarks](https://github.com/vitorpamplona/amethyst/commit/81400eb863cdca70ad65f78eeb295e2c3ffd340a) +- [Fixes bug when creating bookmarks for the first time.](https://github.com/vitorpamplona/amethyst/commit/422446f53e15c2ae7e22449d3e4eb4480d8f0769) +- [Fixes bug in checking bookmarks without running the onReady.](https://github.com/vitorpamplona/amethyst/commit/f1e721f32378bd5a9cc512e6801f9dea71235946) +- [Fixes some of the margins in the login screen.](https://github.com/vitorpamplona/amethyst/commit/8f31c60cd1d2c70973ef1e90d89ae7592f652703) + +Updated translations: +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Serbian by [@npub187h9tymz5j6vhyl26kl74yh6yzqzpjec9806w7taey2zefytlmdsttx7v2](https://github.com/npub187h9tymz5j6vhyl26kl74yh6yzqzpjec9806w7taey2zefytlmdsttx7v2) + +Code Quality Improvements: +- [Improves dev previews](https://github.com/vitorpamplona/amethyst/commit/9234f4b7a8f6f069bfa957842da5f5e9b636dbac) +- Updates libraries and build tools on GitHub Actions +- Updates dependencies + +[Changes][v0.83.7] + + + +# [Release v0.83.5: flare.pub support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.5) - 2024-01-06 + +BugFix: [Makes sure the relay list contains unique urls.](https://github.com/vitorpamplona/amethyst/commit/6e99e6f4a241be85cb46aab607b47d0f8b513e9e) +[Fixes the lack of relay icons in the NIP44 messages](https://github.com/vitorpamplona/amethyst/commit/0be1f8936829c0009f33a584a816d84b7e49a520) +[Fixing some of the minification issues.](https://github.com/vitorpamplona/amethyst/commit/5c7e9258c1cbf869bfde4c5f054e4a73bbac3cc1) +[Creating the benchmark build type on the modules as well.](https://github.com/vitorpamplona/amethyst/commit/f877b6ff6805b07ce05c447f992a18c8ae9a8e3c) +[Adds spotless](https://github.com/vitorpamplona/amethyst/commit/ec867ae8a2df0f6afdf05a0aa5512280e2011aa7) +[Improves the speed of contains](https://github.com/vitorpamplona/amethyst/commit/620b2bfa9fee9e25649d1ab3e79db93090885a1e) +[Updates dependencies](https://github.com/vitorpamplona/amethyst/commit/4291a58f85789bea412c27f94b21b9c09a223153) +[Fixes the benchmark for Robohash](https://github.com/vitorpamplona/amethyst/commit/00cffc8b6b35f1c8a76168b1cd5a4958a8d997d9) +[Fixes the giftWrap test cases since the migration to v2](https://github.com/vitorpamplona/amethyst/commit/7143d786635f66d83975305449ee700fcc3774ba) +[Fixes the position of the participant list in live streams.](https://github.com/vitorpamplona/amethyst/commit/eaaa9a6446799237878e767386925f29f2b13077) +[Initializing the isHidden state for the note correctly](https://github.com/vitorpamplona/amethyst/commit/89fb83cd9aa3420bd8328350036ae00f24ee3dcc) +[Avoiding the creation of modifiers.](https://github.com/vitorpamplona/amethyst/commit/2355a95202cc43aa7c3a48505a97543bc4e9e30b) +[no need to remember the showProfilePicture state](https://github.com/vitorpamplona/amethyst/commit/53a320b4dcfaf7caecafd7e20ee801ea5b6c0cb3) +[Adds support for displaying video events.](https://github.com/vitorpamplona/amethyst/commit/2de3d19a34b97c012e39b203070d9c1c0b1f0520) +[Refactoring some of the old nomenclature of Kind 1 tags.](https://github.com/vitorpamplona/amethyst/commit/57430c43662a18d9b5764d920cba6c1e8c6eeca6) +[Add write support for NIP-10 deprecated positional tags in text notes to maximize backwards compatibility](https://github.com/vitorpamplona/amethyst/commit/9101fb1e9ebd69f25b2237fe99361fb0f3b42060) + +[Changes][v0.83.5] + + + +# [Release v0.83.4: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.4) - 2023-12-27 + +- [Fixes reconnecting issue when DataSources were not active and become active later.](https://github.com/vitorpamplona/amethyst/commit/1cedc8a6c83f4e663e3d5b0a898f461ea687f859) +- [Initial support for separate vertical and horizontal videos.](https://github.com/vitorpamplona/amethyst/commit/4afb0027fb7b8f2ab6e6919b1d836899a00203fe) +- [Adds support for NIP-75 Zap Goal events](https://github.com/vitorpamplona/amethyst/commit/48aa9f950dfab7c2b9556b670efb040204cd982a) +- [Fixing the zap of live streams to go to the Host and not the pubkey in the event.](https://github.com/vitorpamplona/amethyst/commit/ec4981852ba651c643308c3a22f761052bf6e53a) +- [Fixes the loading of reactions and zaps to replaceable events.](https://github.com/vitorpamplona/amethyst/commit/77eb0663627a8afc0e87376a2a2fae4e85a5d14c) +- [Improves the design of the discovery cards for Live Activity and Chats.](https://github.com/vitorpamplona/amethyst/commit/abef3d13f27d283305ea428e5a176eb983c456d7) + +[Changes][v0.83.4] + + + +# [Release v0.83.3: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.3) - 2023-12-23 + + + +[Changes][v0.83.3] + + + +# [Release v0.83.1 NIP-44v2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.83.1) - 2023-12-22 + +#Amethyst v0.83.1: NIP-44 DMs are up! + +New Features +- Moves DMs to the audited NIP-44v2 +- Adds support for NIP-31 alt tags +- Adds a k-tag to reactions +- Adds i18n for error messages when uploading images + +Performance Improvements: +- Improves the performance of Robohash +- Add less memory-intensive timeAgo calculations and translations +- Uses primitives instead of the wrapped object in several places +- Moves to a less memory-intensive way to write and send filters to the server. +- Refines recompositions of routes and bottom icons +- Avoids the creation of new sets when looping through cached maps of User and Notes +- Avoids recreating the EOSE array when changing filters +- Reuses SessionToken for all Playback connections +- Improving the memory use of concurrent hashmaps and immutable collections +- Reduces the use of remember for fixed UI modifiers + +Bugfixes: +- Detects URL mime-types by pinging the server instead of relying on the url's extension +- Fixes bug with cropped joinToString assemblies of relay filters +- Avoids Concurrent Modification Exception on the EOSE markups +- Forces nip95 to be under 80Kb to make sure relays can receive it +- Fixes bug that error messages wouldn't show an error when uploading images to the reels page +- Fixes post video dimensions when the user has selected not to load videos automatically +- Updates dependencies + +Updated translations: +- Chinese by [@ra5pvt1n](https://github.com/ra5pvt1n) +- Finnish by [@npub1ust7u0v3qffejwhqee45r49zgcyewrcn99vdwkednd356c9resyqtnn3mj](https://github.com/npub1ust7u0v3qffejwhqee45r49zgcyewrcn99vdwkednd356c9resyqtnn3mj) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Dutch by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Tamil by [@npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr](https://github.com/npub1q6ps7m94jfdastx2tx76sj8sq4nxdhlsgmzns2tr4xt6ydx6grzspm0kxr) + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.1/amethyst-googleplay-universal-v0.83.1.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.83.1/amethyst-fdroid-universal-v0.83.1.apk ) + +[Changes][v0.83.1] + + + +# [Release v0.82.3: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.82.3) - 2023-12-14 + + + +[Changes][v0.82.3] + + + +# [Release v0.82.2: Markdown improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.82.2) - 2023-12-13 + +- Fixes the transition between short preview and full text on markdown +- Adds NIP-44 metatags to markdown rendering. +- Adds background video rendering on markdown +- Performance: Calculates the text width of a space outside a composable. +- Fixes the image preview with uppercase extensions. + +[Changes][v0.82.2] + + + +# [Release v0.82.1: NIP-96, NIP-44, Selling](https://github.com/vitorpamplona/amethyst/releases/tag/v0.82.1) - 2023-12-12 + +Adds support for selling and listing in Amethyst as well as NIP-96 Image Servers and NIP-54 inline metadata. Provides large improvemetns to Cashu's token redemption and fixes several bugs. + +https://image.nostr.build/40ae418ccc5336e17b5949bacc11c31835603437816f8bf867c171f07d34dd54.jpg#m=image%2Fjpeg&dim=720x1612&blurhash=%5BLFFgJMyj%5Bt74TMyoft70LxufiV%5B_Nt7f6WB4TogoMj%5Bxut7ofWAS%7EofbFjtD%25xtWBWBs%2BM%7BjbbH&x=c3a3f49c017f58749226f8ae6021c11a745d2354f52a229cb99eef4a9d20ec39 + +- Adds selling: ShopStr's classified creation +- Migrates old image server uploads to NIP-96 +- Adds support for NIP-54 inline metadata +- Adds a Marketplace tab to Discovery +- New Cashu Redeeming card UI. +- Shows the blurhash with a Download icon instead of the URL when the user chooses to not automatically load images/videos +- Improves the video switching flicker from blurhash to video +- Optimizes the rendering of the drawer +- Updates EOSE status in the same thread of the new event to reduce the amount of coroutine launches. +- Uses just one HTTPClient for the entire app +- Adds a User Agent to all HTTP requests. +- Improves Cashu Redeeming UI feedback +- Adds support for the FileServers kind +- Adds relay information for Replaceable events +- Unifies upload options into NIP-94 images +- Improves the rendering of inline metadata +- Uses nostr.wine instead of filter.nostr.wine as a search relay +- Fixes bottom bar appearing in chats when the keyboard is open +- Fixes uploading crash due to malformed video formats +- Fixes crash when image is an SVG and tries to compress +- Fixes deletion of replaceable events +- Fixes hash calculation from the entire payload to only the bytes in the file +- Fixes bug when updating relay list that used keep the previous list +- Presents better error messages when the image upload fails +- Adds a button to Cashu preview to redeem on external wallet by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Fixes zap splits when using amber with intents by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Updates translations for cs/de/sv/pt by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Updates Hungarian translations by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Updates Finnish translations by [@petrikaj](https://github.com/petrikaj) +- Updates Dutch translations by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) +- Updates French translations by [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Updates dependencies + +[Changes][v0.82.1] + + + +# [Release v0.81.5](https://github.com/vitorpamplona/amethyst/releases/tag/v0.81.5) - 2023-11-30 + +- [Fixes blocked lists on Videos.](https://github.com/vitorpamplona/amethyst/commit/efb9814f1b28b70a2dfdeb879b4bd89b327fa1c8) +- [Pre-loads profile/mute list information for all the logged in accounts in the app.](https://github.com/vitorpamplona/amethyst/commit/b2b7cba352177e1c409883d437e8b815b08d0519) +- [Fixes bug when creating accounts in the background and trying to create the live set](https://github.com/vitorpamplona/amethyst/commit/47ae42e3fed1a45b940df5938cb052665a33f31f) +- [Makes relay pool coordinator thread-safe. Forcing the disconnect of an old relay list before connecting to a new one.](https://github.com/vitorpamplona/amethyst/commit/5db3ede09e8a17899ed61c36e106e7911fc944bd) +- [Avoids sending filters with empty follow lists on Videos](https://github.com/vitorpamplona/amethyst/commit/5347373cdeb5b8756aa8be0035f23634902fafe8) +- [Forces websocket closure onFailure](https://github.com/vitorpamplona/amethyst/commit/05596cb9bf6a4a06490e6e232dad19df65eb176e) +- [Fixes: emitting an empty follow list if it cannot decrypt it](https://github.com/vitorpamplona/amethyst/commit/b021920eaa1f95fb7f35b3d8f61577e9f4236223) +- [Caches zap calculations in notification cards.](https://github.com/vitorpamplona/amethyst/commit/2b27ac3aec64f5c91bef404921abc8d46e1f3d57) +- [Fixes null list names showing before the list is loaded](https://github.com/vitorpamplona/amethyst/commit/c692c9125b846f5f7caeb073ba10233f3e0ad485) +- [Fixes hidden buttons in the Chat floating button](https://github.com/vitorpamplona/amethyst/commit/7322fd7aae3d51817cd288b9220da4c92f17c37b) +- [Fixes all-or-nothing decryption procedure for Zap lists which were failing in a few cases.](https://github.com/vitorpamplona/amethyst/commit/07a92cd70d0e357da050c5e95e4a9ad1acc6c280) + +[Changes][v0.81.5] + + + +# [Release v0.81.3: NIP-88](https://github.com/vitorpamplona/amethyst/releases/tag/v0.81.3) - 2023-11-29 + +#Amethyst v0.81.3: + +- Massive refactoring to unify our internal signer with Amber's signer in all supported events +- Adds [NIP-88](https://github.com/nostr-protocol/nips/pull/901) NOTIFY request support +- Migrates our Block list to kind:10000 +- Fixes the breaking of [@npubs](https://github.com/npubs) when other words are combined with the nostr address +- Adds default encryption and decryption permissions to the Amber login call to avoid multiple Amber screens open at once by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds support for sending/receiving/approving multiple events at once by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds a chat with seller flow to ShopStr's event rendering. +- Reduces the amount of downloads to build the Notification chart of the week +- Immediatly force-closes the WebSocket when leaving the app +- Narrows the re-downloads of event reactions down +- Fixes the blue notification dot appearing when the user receives a notification from a blocked account before downloading the blocklist +- Fixes URL Preview card when websites use a blended version of multiple open graph specs +- Adds a geohash mipmap to event tags +- Reduces multiple reconnections to relays when the app cold starts. +- Adds back arrow button to the top of the Nav bar of the Thread view. +- Fixes race conditions when opening videos at the same time +- Fixes spacing when drawing POW and Geolocation at the same time +- Runs the translation as the UI Scope instead of ViewModel's +- Migrates the event's tag list from List to Array to save some bytes. +- Increases connection timeouts when on mobile data. +- Improves the EOSE logic when creating filters by grouping filter requests with similar `since`clauses +- Fixes video release coroutine being killed by Android, leaving the Video playing in the background +- Adds a cache of the total amount of Zaps per note +- Allows sat amounts up to 4 digits without abbreviation [@vicariousdrama](https://github.com/vicariousdrama) +- Improves the rendering of LN Invoice Previews. +- Fixes error message when parsing LnInvoice +- Updates several dependencies + +Updated translations for: +- Czech, German, Swedish and Portuguese, Brazilian by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Spanish, Mexico and Spanish, United States by [@npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903](https://github.com/npub1luhyzgce7qtcs6r6v00ryjxza8av8u4dzh3avg0zks38tjktnmxspxq903) +- Hungarian by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Chinese Simplified by https://crowdin.com/profile/stella2023 +- Persian by [@npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk](https://github.com/npub1cpazafytvafazxkjn43zjfwtfzatfz508r54f6z6a3rf2ws8223qc3xxpk) + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.81.3/amethyst-googleplay-universal-v0.81.3.apk ) +- [FOSS Edition - No translations](https://github.com/vitorpamplona/amethyst/releases/download/v0.81.3/amethyst-fdroid-universal-v0.81.3.apk ) + +[Changes][v0.81.3] + + + +# [Release v0.80.7](https://github.com/vitorpamplona/amethyst/releases/tag/v0.80.7) - 2023-11-08 + +- Migrates external sharing service to njump.me by @ @[es09l4ps](https://coracle.social/people/nprofile1qqs05qt95rce97cwj8rasugw2ats45nmxu2u55scrak98jdjqvuhqucprpmhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0qy88wumn8ghj7mn0wvhxcmmv9uq3qamnwvaz7tmp9ehx7uewd3hkctc9zwssw) +- Adds support for Greek by @ @[csavastel](https://coracle.social/people/nprofile1qqs8wfdhfs8hvnsg265mngx7vwkvmtg34zglecmqlmc9mzje6cq7sqspzamhxue69uhhyetvv9ujumn0wd68ytnzv9hxgtcpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhszynhwden5te0dehhxarjxgcjucm0d5hsky9vyw) +- Adds support for Indonesian by @ @[Yonle](https://coracle.social/people/nprofile1qqsrg73rwzgq6xd5u36kyg2ef69a5ur2uhrcthsfuk0yvp0ergplf8qpzemhxue69uhkymmnw3ezuemvd96xx6pwd4jj7qfqwaehxw309a3x7um5wgh8jmmwd3jjumr9vd682unfveujumn9wshszxrhwden5te0ve5kcar9wghxummnw3ezuamfdejj7wgxqka) and @ @[3ssspdkl](https://coracle.social/people/nprofile1qqsvxj2am3fs0xunr7rj0elhg2xf8utpyfnzzrq2mnlqjtraag8s5ccprpmhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0qy88wumn8ghj7mn0wvhxcmmv9uq3qamnwvaz7tmp9ehx7uewd3hkctcjw5pr7) +- Updates Spanish translations by @ @[⚡₿it₿y₿it⚡](https://coracle.social/people/nprofile1qqs07tjpyvvlq9ugdpax8h3jfrpwn7kr72k3tc7ky83tggn4et9eangprpmhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0qy88wumn8ghj7mn0wvhxcmmv9uq3qamnwvaz7tmp9ehx7uewd3hkctcw534ek) +- Updates Arabic translations by @ @[fqwvx23t](https://coracle.social/people/nprofile1qqsgs9hgjw87vz36jf2r83m5zree2q87zvs8s7kty9jljdz7wprytysprpmhxue69uhkv6tvw3jhytnwdaehgu3wwa5kuef0qy88wumn8ghj7mn0wvhxcmmv9uq3qamnwvaz7tmp9ehx7uewd3hkctckmawlz) +- Fixes position of video controlling buttons when top bars are present in full screen. +- Fixes bug when the app calls isAcceptable directly, bypassing the other checks in AccountViewModel +- Fixes race condition when pausing and restarting relay connections +- Updates Kotlin compiler version +- Removes a recomposition between the started state and the isOnline state that is already cached. +- Migrates the check if stream is online to a single compose object. +- Forces relay reconnection when a new WIFI service is available +- Fixing translations of the that create the same message but with different character cases +- Refines the layout of Author Pictures for performance +- Refines layout of URL Previews for performance +- Refines the padding of chat messages and reaction row +- Correctly highliting a notification card on touch + +[Changes][v0.80.7] + + + +# [Release v0.80.4: Performance Optimizations](https://github.com/vitorpamplona/amethyst/releases/tag/v0.80.4) - 2023-10-30 + +- Starts videos from Main, but in a thread. +- Fixes new line of Loading Animation and Download buttons for images. +- Minimizes Jittering when loading videos. +- Improving rendering of reaction types +- Only updates notification dots once at every 3 seconds. +- New users now follow themselves by default +- Fixes Floating Action Button not showing again after changing screens by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Updates French, Dutch, Hungarian, Czech, German, Portuguese and Swedish translations by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) [@npub1rq9x6sk86e8ccw2cm8gsm4dyz9l24t823elespupaxjnzdk026fsca2r93](https://github.com/npub1rq9x6sk86e8ccw2cm8gsm4dyz9l24t823elespupaxjnzdk026fsca2r93) and [@npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz](https://github.com/npub106efcyntxc5qwl3w8krrhyt626m59ya2nk9f40px5s968u5xdwhsjsr8fz) +- Fixing colors of edit buttons +- Login and Logout already in IO threads +- Performance: Stable class review. +- Adds images and posts to notes without an extra line. +- Fixes: Direct replies have "reply" marker instead of "root" marker +- Speeds up the boost count method +- Fixes weird alignment of multi-row post titles from highlighter. +- Fixes the update on Profile Feed when Blocking/Unblocking the user. +- Refines Markdown to match Material3 Style +- Reduces the font size of Subject labels +- Fixes the use of decimals on Notification's chart + +[Changes][v0.80.4] + + + +# [Release v0.80.2: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.80.2) - 2023-10-28 + +- [Slight improvement in the performance of Reaction Row's rendering](https://github.com/vitorpamplona/amethyst/commit/2cc9bb8b720ae63716d27d2aa89ba1a3b1a225be) +- [Reducing the size of Subject labels](https://github.com/vitorpamplona/amethyst/commit/553bebb6cf5d362819b3e5c4b17c5b8f9c57d2a5) +- [Refining some of the Markdown to match Material3 Style](https://github.com/vitorpamplona/amethyst/commit/e91e5c366d6d2baaf61eba3df040101bb0a93528) +- [Update Profile Feed when Blocking/Unblocking the user.](https://github.com/vitorpamplona/amethyst/commit/9d32718c1304dd8174bdf22dbb6fc710ae002660) +- [Reverts the New Post button animation due to bugs of not coming back](https://github.com/vitorpamplona/amethyst/commit/64c9505620c55b5085aa3710f88df08b5c072d94) +- [Fixes the use of decimals on Notification's chart](https://github.com/vitorpamplona/amethyst/commit/75dc55858cab5667cd27827b9fd52df1014e38f7) +- [Reverts the hidden note LiveData to make sure the interface doesn't blink with the hidden note that just disappears ms later.](https://github.com/vitorpamplona/amethyst/commit/c6062120434b3c442ff26d0a20ede140837f7179) +- [fix typo in resource string name](https://github.com/vitorpamplona/amethyst/commit/e89384ee6181bc197daa18f0bf2604fc60defdad) [@davotoula](https://github.com/davotoula) +- [Updated translations for cs/de/sv/pt](https://github.com/vitorpamplona/amethyst/commit/bb324776716be5dad4e26f3315b53ee01cd4d076) by [@davotoula](https://github.com/davotoula) + +[Changes][v0.80.2] + + + +# [Release v0.80.1: Foss Push Notifications](https://github.com/vitorpamplona/amethyst/releases/tag/v0.80.1) - 2023-10-27 + +- Adds support for Unified Push in the FOSS edition by [@KotlinGeekDev](https://github.com/KotlinGeekDev) +- BugFix for missing push notifications when using Google's edition +- Creates a ViewModel store for each user, which allows faster memory cleanup when switching accounts. +- Fix crash when uploading images/videos using external signer by [@greenart7c3](https://github.com/greenart7c3) +- Adds Lifecycle to all Flow collects in compose to stop processing new events when the app is paused. +- Avoids creation of the LiveData in every recomposition +- Removing Stop with Task from PushNotifications to make sure the PushService remains active. +- Updated translations to Sweden, Portuguese, Czech and German by [@davotoula](https://github.com/davotoula) + +[Changes][v0.80.1] + + + +# [Release v0.79.13: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.13) - 2023-10-23 + +[Makes sure only one npub is logged in at the same time](https://github.com/vitorpamplona/amethyst/commit/191254d920ce5a78ed141d1387a2785f551996a8) +[Update UI dependencies](https://github.com/vitorpamplona/amethyst/commit/91bfb60613436abb494d02b10f61da9ee94a2027) +[Making sure the UI update from language is in the Main thread.](https://github.com/vitorpamplona/amethyst/commit/9dfb4d1a1b7aa06b903d477f83b8c9416707443b) +[Solves NPE when the TextToSpeech engine isn't ready.](https://github.com/vitorpamplona/amethyst/commit/f92e13270de30f9a063da3b2a9c9740387e4b5c5) +[Fixes status update field when more than one status is available.](https://github.com/vitorpamplona/amethyst/commit/10a0dc7f8aa103013ddd4363e78e2e2ecefc254f) +[Moves Relay and User Metadata update buttons from Post to Save.](https://github.com/vitorpamplona/amethyst/commit/5b0fc7982b86575ee5cad012fb346de63aaa45b4) +[Slight adjustment on the rendering of hashtags.](https://github.com/vitorpamplona/amethyst/commit/6831349f2fe1b9082309865071014cb17d0e2aea) + +[Changes][v0.79.13] + + + +# [Release v0.79.12: Tablet Layouts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.12) - 2023-10-22 + +- Adds a [Tablet view on chats](https://github.com/vitorpamplona/amethyst/commit/80df2eefed1c7cb1174eecacac2c2b632437ba98) +- [TwoPane display for chats in tablets and folds.](https://github.com/vitorpamplona/amethyst/commit/884a124c7e534f18e15ad20c549d5d0b5204f98c) +- [Fixes orientation changes when in full screen](https://github.com/vitorpamplona/amethyst/commit/a284c1b9c665327fa9a80ff521ef11c3e59fbd22) +- [Updates Jsoup](https://github.com/vitorpamplona/amethyst/commit/ccf428eff6bb58145f78ae2a255b63989a512df9) + +[Changes][v0.79.12] + + + +# [Release v0.79.10: Full Blacks](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.10) - 2023-10-21 + + + +[Changes][v0.79.10] + + + +# [Release v0.79.9: Full screen videos/images](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.9) - 2023-10-20 + +- [Solving one of the OutOfMemory errors (too many translators instantiated at the same time)](https://github.com/vitorpamplona/amethyst/commit/3321448dd29a74ca4d91fc2dd08590dcb12d265e) +- [Fixes the spacing of the account switcher to avoid getting too close to navigation buttons.](https://github.com/vitorpamplona/amethyst/commit/8065b942bd6b1c5f0ff714298ded19de4388a775) +- [Fixes full-screen dialog for videos and images](https://github.com/vitorpamplona/amethyst/commit/17e59c5ae882438c463433154e3222a0bd521bf3) +- [Activates single-tap to double zoom when on full-screen dialog](https://github.com/vitorpamplona/amethyst/commit/39d84e33bb2d829db45768db399071b24afef983) +- [Fixes caching issue of the saved list selection in the top bar on cold starts](https://github.com/vitorpamplona/amethyst/commit/87e8948d9ae4ed1419180697ca01e9ff41cc87d7) +- [Fixes one of connectivity issues that kept the app off-line even though the phone is connected to the internet](https://github.com/vitorpamplona/amethyst/commit/1ab93adc22b69db3c181ebe886fe7c0cf15fd205) +- [fix double encryption when sending dms, when login with external signer set privKey to null to be sure we have no private keys](https://github.com/vitorpamplona/amethyst/commit/800c0b0131cdc4124cdfece23159d852db53b60d) by [@greenart7c3](https://github.com/greenart7c3) + +[Changes][v0.79.9] + + + +# [Release v0.79.7](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.7) - 2023-10-18 + +- [Removing bold titles](https://github.com/vitorpamplona/amethyst/commit/27286c7ffeab8239c4925e4a3297c3e9efc47d79) +- fix crash when sending giftwraps with amber +- Moves app startup to an IO thread. +- Upgrades Shared Preferences serialization to a Single JSON object +- Simplifies Shared Preferences state changes +- LazyInitializes Video cache + +[Changes][v0.79.7] + + + +# [Release v0.79.6](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.6) - 2023-10-17 + +[Stops PushNotifications when the app is killed.](https://github.com/vitorpamplona/amethyst/commit/35f6ecad59c8ac90478d535003c196dcb732f4f4) +[Dump memory states to debug OOO](https://github.com/vitorpamplona/amethyst/commit/2a328ca12057769a1c8e8913649802aecea627bb) +[Only changes Username if value changes.](https://github.com/vitorpamplona/amethyst/commit/1e83dbfbe356ef050ac34ffdb3ce094b0d6e8181) +[Added #thenostr hashtag icon by @believethehype ](https://github.com/vitorpamplona/amethyst/commit/3ea7b8194d6f86056962e9d4445b96599cb74b2f) +[Activates color for the zaps in the Notification chart](https://github.com/vitorpamplona/amethyst/commit/1a7ae33fa867ef38b511a8193b5a290d7cc82598) +[Removes configuration cache: was creating a lot of build issues](https://github.com/vitorpamplona/amethyst/commit/2bbe126c8d2d5aab8698e093145c2d02d909be77) +[Improving Git hooks](https://github.com/vitorpamplona/amethyst/commit/f2e6efe2b7761429e56797a2d91e758aabfb8074) +[Moves playback services to a package](https://github.com/vitorpamplona/amethyst/commit/404e6cd8627f8a583e085cb051d28db7aa15b16c) + +[Changes][v0.79.6] + + + +# [Release v0.79.5](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.5) - 2023-10-17 + +- [Forces a filter reset after authentication for inbox.nostr.wine](https://github.com/vitorpamplona/amethyst/commit/611e8f1a6d75068dcc63809414029ce9fc5627b7) +- [BugFix: Resolves a duplicated entry on relay list of Notes](https://github.com/vitorpamplona/amethyst/commit/c619a9000c58d8ddd3a6f582c5c4a90ea822b1e9) +- [Avoids testing the signature when the id or sig fields are blank](https://github.com/vitorpamplona/amethyst/commit/c29b4b8e5f53fccdc2df245aa599f8c68ab5d09c) +- [Improves the feedback to messages from relays.](https://github.com/vitorpamplona/amethyst/commit/4286b64b415813f2f8e61ed1655668d9d4b2c7d8) +- [add exception handling for parsing geohash by @jiftechnify ](https://github.com/vitorpamplona/amethyst/commit/407807d8711fd2d20f1ffd8b66e413f80bc754ba) +- [Only adds a border to video controls when in full screen](https://github.com/vitorpamplona/amethyst/commit/e1e42ed500f5ea4b38a1efcac1af265dd70245fb) +- [Activates images controllers on click](https://github.com/vitorpamplona/amethyst/commit/1767cc74a978bbfd8329393993a0488990dd99db) +- [Adds a border in the image dialog to avoid overriding controllers.](https://github.com/vitorpamplona/amethyst/commit/4028018605461f9e8f209b993b5557453e3c553d) +- [Image bleeding into separate page bugfix](https://github.com/vitorpamplona/amethyst/commit/33f8b6d6d86912fdc04f28a6cda3aff7367cd167) +- [Update dependencies](https://github.com/vitorpamplona/amethyst/commit/f9fed8a04f6a801e5c4597bb1e024eaedda11bbb) +- [Fixes all the other mute list feeds](https://github.com/vitorpamplona/amethyst/commit/ba4a594a41743ef081f66b53ec7260eec212282d) +- [fix double encryption on nip04 by @greenart7c3 ](https://github.com/vitorpamplona/amethyst/commit/173245d9003fd95c619cca4407b6604d0f2402b1) +- [try to fix messages being encrypted twice by @greenart7c3](https://github.com/vitorpamplona/amethyst/commit/5bc4aab8d809303f64485ded74465d65554901bb) +- [change mute test to equality with string including event 30000 and user hex by @davotoula ](https://github.com/vitorpamplona/amethyst/commit/c7861dfac44a58a8b5d574f1c4eb42d10649df4c) +- [Fixes visibility of the bottom and top bar when the user comes back](https://github.com/vitorpamplona/amethyst/commit/275051ed308b4bfeb960bcf859248424579a1573) +- [Fixes failure to load long form content with d tags reserved url chars](https://github.com/vitorpamplona/amethyst/commit/6748abbf70416e36a99a16ba02f819fe2296c6e1) +- [Fixes bug of not immediately loading chat rooms](https://github.com/vitorpamplona/amethyst/commit/e04a35afed3df7d3572e22d23029c2773bbe591f) +- [Moves the Post button on chat screens to a > Button](https://github.com/vitorpamplona/amethyst/commit/f67ff43eb36fe1fdda2afee70c581fb65d04bb42) +- [Hide's the Video Full Screen dialog buttons together with video](https://github.com/vitorpamplona/amethyst/commit/b8b41f840a326c248dc41b838c0d96cffa5988f1) +- [Fixes the saving of the video position between screens](https://github.com/vitorpamplona/amethyst/commit/e8c9e73985d9ef0c64bd9d19e85846f8cfaa26e0) +- [Updated translations for cs/de/sv](https://github.com/vitorpamplona/amethyst/commit/56c67b9ec6c256c35c2296eb4fee1b457befe462) +- [Moves Following icon from crossfade to animatedVisibility.](https://github.com/vitorpamplona/amethyst/commit/7eddf4a12a525f4522c03ce57504506c77119607) +- [Breaks down Compose components in the Discovery tab.](https://github.com/vitorpamplona/amethyst/commit/cec204b7ae1bf625cd923298cdc8fe9320d4ddb8) +- [Allows Base64 images on profiles.](https://github.com/vitorpamplona/amethyst/commit/188ef3762d7c249a52abf1a1d9baa7c9fff797a0) +- [Fixes bug of messages not reappearing after memory trimming.](https://github.com/vitorpamplona/amethyst/commit/0da031fae4952ca8259b52833fe3cce6e4738e9d) +- [Moves activeOnScreen calculations to a LaunchedEffect](https://github.com/vitorpamplona/amethyst/commit/72dff060d2e295324d0c6161f253e261ab556577) +- [Only changes shouldShow if the value is different.](https://github.com/vitorpamplona/amethyst/commit/d6f4ffafa16517f678eb3623b28e4a935c2222f0) +- [Moves audiothumbnail loader to the viewModel scope](https://github.com/vitorpamplona/amethyst/commit/4b362176990deaa39ff0278da070994d598b1277) + + +[Changes][v0.79.5] + + + +# [Release v0.79.2: Performance updates](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.2) - 2023-10-01 + +- Fixes the repeat payment requests on zaps when the NWC is not setup. +- Improves error zap message screens for Material3 +- Uses Lists name/title instead of d-tag on the Top Bar +- Increases the performance of the Bottom bar's Notification dot calculations +- Speeds the composition of the Topbar +- Uses the "host" tag as the creator of the stream. +- Moves check if the stream is online process to the viewModel scope. +- Moves many Toasts to the better designed Information Dialogs. +- Speeds up cold startup. +- Makes sure shared flows don't suspend. +- Updates dependencies + +[Changes][v0.79.2] + + + +# [Release v0.79.0 material 3](https://github.com/vitorpamplona/amethyst/releases/tag/v0.79.0) - 2023-09-29 + + + +[Changes][v0.79.0] + + + +# [Release v0.78.2: BugFix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.78.2) - 2023-09-26 + +Bug fixes for the playback crashing due to video player calls in the wrong thread + +[Changes][v0.78.2] + + + +# [Release v0.78.1: BugFixes and Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.78.1) - 2023-09-25 + +[Updated translations for cs/de/sv](https://github.com/vitorpamplona/amethyst/commit/e1caf40c3aa49c42c1db3b1356be21d223928f1c) +[Updating dependencies](https://github.com/vitorpamplona/amethyst/commit/d966541ea7c954e63e5d1c5e78b650c8a2cc8d2c) +[Forces the presence of the name field in kind 1](https://github.com/vitorpamplona/amethyst/commit/74a2b465084b5af237faf5aa0700a4e7c4186ff0) +[Disable swipe to change page in the hope page](https://github.com/vitorpamplona/amethyst/commit/045699ecd9af273c16b3213e521331025f75fece) +[Performance Improvements to PreviewCards](https://github.com/vitorpamplona/amethyst/commit/35f0b1291fa4bdfd70bfe418a2b94bbc35580094) +[Avoids creating nip94 and nip95 events with blank alts](https://github.com/vitorpamplona/amethyst/commit/f2b6a9bedb61a2c9ccffbabe7d6dd6102c130a70) +[Adds NIP19 parser to the AccountViewModel thread scope](https://github.com/vitorpamplona/amethyst/commit/fc4433e7ae91a05fe206d8b6c1492ced50545986) +[fix contact link in relay information dialog](https://github.com/vitorpamplona/amethyst/commit/b5a0d65f3c37bfdf2d21fc2834ed65a2b24a96c9) +[add notifications for users of amber](https://github.com/vitorpamplona/amethyst/commit/52f600485b16421613c5e3cedb422c6c7de33200) +[moves mark as read to the AccountViewModel scope.](https://github.com/vitorpamplona/amethyst/commit/e89e8e5d010d4d4a9aaea5312aec82e5f0ee6380) +[Fix for not clearing the new post message. It adds a delay to allow the composer to save the viewModel after calling cancel](https://github.com/vitorpamplona/amethyst/commit/af9b0b444c154682497f37100548ad3b63b12ea8) +[Improving the Stability of VideoView](https://github.com/vitorpamplona/amethyst/commit/b1edf4e934fa08dbce8e77be210de81986df75cd) +[only updates reports for a different note](https://github.com/vitorpamplona/amethyst/commit/288d80d1632e687465f1a59685f6d971567ae82b) +[Increasing video cache from 90 to 150MB](https://github.com/vitorpamplona/amethyst/commit/69d7e82b7106e45fbf8fe77c6c4b317cb4c4cade) + +[Changes][v0.78.1] + + + +# [Release v0.78.0 Mute words](https://github.com/vitorpamplona/amethyst/releases/tag/v0.78.0) - 2023-09-24 + +- [Mute keywords](https://github.com/vitorpamplona/amethyst/commit/f4da2ae6be21fcda40bfa499d14d67cf65202290) +- [Adds an option in Settings to disable immersive scrolling](https://github.com/vitorpamplona/amethyst/commit/c6c15c3ec7c36f2c6d7ec502e860e4a1bc8c2447) +- [Only show backup keys if account has a private key](https://github.com/vitorpamplona/amethyst/commit/b3f39434eed8b8fb46f75f62780bc66174580514) +- [Reverts to have videos starting from the IO thread](https://github.com/vitorpamplona/amethyst/commit/57dfe3af8c03a3ba3a475060df278f3de26dc1a1) +- BugFix for restarting the relay filters when switching accounts after Amber's integration. + +[Changes][v0.78.0] + + + +# [Release v0.77.8 BugFixes and Translation Updates](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.8) - 2023-09-22 + +- Filters zap payments outside the established min-max parameters on polls. +- Moves Live streaming video from the top bar to the body of the screen to avoid cancelling the video on immersive scrolling +- Reduces padding of custom emojis +- Refactors markdown parser away from the compose Class +- Fixes inconsistencies in memory management with the LifeCycle object and DispableEffect +- Speeds up the display of unused hashtags +- Moves video playback creation to the main thread +- Fixes profile website URLs without schema (http://, https://, etc) +- Updated translations for cs/de/sv by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fix crash when editing account with Amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Updates pt-br translations by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Updates to Chinese and Hungarian translations by [@npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7](https://github.com/npub1raspu6ag9kfcw9jz0rz4z693qwmqe5sx6jdhhuvkwz5zy8rygztqnwfhd7) and [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) + +[Changes][v0.77.8] + + + +# [Release v0.77.7: Immersive scrolling](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.7) - 2023-09-21 + +- Animates top and bottom bars out of the way when scrolling by [@greenart7c3](https://github.com/greenart7c3) +- Removes the need for the split payment popup for only one invoice +- Removes the flickering on chat screens when the bottom bar disappears +- Fixes video keeps playing in the background bug when pressing the bottom bar twice +- Moves reaction calls to the viewModelScope +- Protects against crashing on null contact lists +- Migrates alt descriptions of NIP-94 and NIP-95 from .content to alt tag +- Adds a new line limit to the char limit of the Show More button by [@davotoula](https://github.com/davotoula) + +[Changes][v0.77.7] + + + +# [Release v0.77.5 Hides Nav and Top Bar when scrolling](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.5) - 2023-09-21 + + + +[Changes][v0.77.5] + + + +# [Release v0.77.3: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.3) - 2023-09-20 + + + +[Changes][v0.77.3] + + + +# [Release v0.77.1: Communities, hashtags, and geotags in the Top Bar list](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.1) - 2023-09-20 + +- Adds communities, hashtags, and geohashes to the lists on the top navigation bar. +- New Repost profile picture arrangement from [@npub1aeh2zw4elewy5682lxc6xnlqzjnxksq303gwu2npfaxd49vmde6qcq4nwx](https://github.com/npub1aeh2zw4elewy5682lxc6xnlqzjnxksq303gwu2npfaxd49vmde6qcq4nwx) +- Adds a Zap Split view to the master node in the Thread View +- Change nav bar color by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Removes the old user migration from the old preferences database +- Sets up default reactions to be Rocket, Hugs, Watching and Laughing +- Starting a Refactoring of LocalCache away from a Singleton instance +- Fixes blank summaries occupying empty spaces in Long Form content +- Improvements to the rendering of long-form content +- Groups notifications by day first to avoid merging multi-day notification events +- Performance improvements on loading users and calculating reports +- Disable buttons if terms are not accepted in the Login Screen with Amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Fixes a crash when login with Amber by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Updates Bengali and Dutch translations +- Removes the follow/unfollow button from the Zap to User view +- Performance improvement by moving zap decryption to run in a group, avoiding multiple co-routines per zap +- Updates Google Play services + +[Changes][v0.77.1] + + + +# [Release v0.77.0: Amber support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.77.0) - 2023-09-18 + +Merging Amber branch + +[Changes][v0.77.0] + + + +# [Release v0.76.2: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.76.2) - 2023-09-18 + +- [Removes the ZapSplit display when the weights are zero or were incorrectly created](https://github.com/vitorpamplona/amethyst/commit/83be43e94efdbe44adac188a8d624520ae9fec14) +- [Adds NIP24 Kind1 create function](https://github.com/vitorpamplona/amethyst/commit/4d1a99d0769d6ebe4550590ecaf01d30f96d0146) +- [AnimatedVisibility seems faster than Crossfade](https://github.com/vitorpamplona/amethyst/commit/b1debd98796a871b6f4e741e9eb494f2f8f47ba9) +- [Makes sure the account is writeable before signing Auth for notifications](https://github.com/vitorpamplona/amethyst/commit/3843917bd1300f89bc5a3b37ff9cc282264b0a37) +- Bengali, French, and Dutch translation updates. + +[Changes][v0.76.2] + + + +# [Release v0.76.1 Zap Splits](https://github.com/vitorpamplona/amethyst/releases/tag/v0.76.1) - 2023-09-15 + +Adds support for Zap Split setup and payment via NWC and manually via wallet calls. + +- Adds zap split setup +- Adds zap split display +- Adds zap split payment +- Fixes bug when verifying the checksum of LNURLs (bech32) in uppercase +- Allows playback to save any position in real-time and not only after 5 seconds +- Removes potential bugs when the list contains an e tag with an a reference +- Moves deletion and report to be the last item on the dropdown menu +- Moves broadcast up in the dropdown menu +- Updating dependencies +- Updated translations for cs/de/sv +- Forces valid hexes in p- and e- tags when receiving the event +- Stops accepting space as a Valid hex char and requires an even number of chars (padding) +- Forces the ZapRequest to exist when processing the LnZapEvent +- Fixes some long NIP-19 cutting off in notes +- Updates to Finnish, Swedish, Czech and German translations +- Adds Bengali, Bangladesh translations +- Adds Italian Translations +- Updates Chinese Translations + +[Changes][v0.76.1] + + + +# [Release v0.76.0: GiftWrapped Push Notifications](https://github.com/vitorpamplona/amethyst/releases/tag/v0.76.0) - 2023-09-08 + +- Migrates to Encrypted Push Notifications +- BugFix with video thumbnails failing to load when using the Android's new Photo Picker +- Improvements to the relay settings UI. +- BugFix for invalid LNURLs highlighting as a link +- Uses the correct observer for the picture profile in the Top bar. +- Adds nostr.wine and noswhere.com as two new NIP-50 relays in the default list. +- Adds SeenOn relays when successfully broadcasting a note. +- Refines relay icon row compose +- Fixes the missing channel header for Live Activity replies in Conversations. +- Upgrades the RelayPoolStatus to a Flow +- Avoids race condition when updating EOSEs +- Adds arm64-v8a and armeabi-v7a build target +- Adds Indonesian translation +- Updates Czech, German, Swahili, Chinese, and Italian translations + +[Changes][v0.76.0] + + + +# [Release v0.75.14: Fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.14) - 2023-09-02 + +- [Fixes thread ordering issues with two notes with the same idHex](https://github.com/vitorpamplona/amethyst/commit/d13e8bacec4eff952a058eeea0ff9e277c96ec35) +- [Improves error message from LN Invoice servers.](https://github.com/vitorpamplona/amethyst/commit/a9ea9ea2aeac5966ce51db035611c1e34f3c9244) +- Error msg grammar adjustment +- [Adds UI Feedback for Custom Zaps](https://github.com/vitorpamplona/amethyst/commit/734dd2e119cc60c968085220040c572efdc93e3d) +- [Remeber should be based on the Note](https://github.com/vitorpamplona/amethyst/commit/d3fa05a4dfd2559aba0ee4fb1f067b635a97fa16) + +[Changes][v0.75.14] + + + +# [Release v0.75.13](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.13) - 2023-09-01 + +- Ignores brb.io if in the relay list to reduce crashes at the WebSocket protocol level +- Only trigger notifications for events within 5minutes from the current time (avoids old notifications when rebroadcasting events) +- Identifies which relays are using zlib compression +- Doesn't notify if the GiftWrap's inner message came from the logged-in user. +- Fixes reply order for two replies made at the exact same second +- Fixes unit tests of thread ordering + +[Changes][v0.75.13] + + + +# [Release v0.75.12: Global Feed bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.12) - 2023-08-31 + +- Fixes global feed +- Removes LiveData Redirections + +[Changes][v0.75.12] + + + +# [Release v0.75.11: New Thread sorting scheme](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.11) - 2023-08-31 + +Replies on each thread level are now ordered by: +1. Parent-level reply author, ascending order by date. +2. My replies, descending by date. +3. My follow's replies, descending by date. +4. Everybody else, descending by date. + +- Removes Zaps without a valid ZapRequest +- Removes unnecessary refresh checks since the dual LiveData structure refactoring +- Fixes wrong EOSE updates. +- Requires minimum 10 sat zaps to trigger notifications +- New Crowdin translations by GitHub Action +- Fixes the grammar in the nip05 error messages +- Improve cohesiveness of the pruning system. +- Reduce the padding space between display name and status in the left drawer +- Reducing the height of the banner in the drawer in the left drawer +- Fixes the report card when the author has been blocked by the loggedin user but the feed has been loaded before the block user list. +- Marks keepScreenOn to false when leaving the video player without pausing the video + +[Changes][v0.75.11] + + + +# [Release v0.75.10](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.10) - 2023-08-29 + +- Fixes app crash when creating note with @ and any url on Samsungs +- Fixes link highligthing off when composing a message with @ and urls at the same time +- Refines zap and report memory pruning procedures +- Fix the mis-deletion of reports +- Lots of new translations from Crowdin collaborators (Thank you all!) + +[Changes][v0.75.10] + + + +# [Release v0.75.8: Status Rotation bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.8) - 2023-08-27 + +- [clears the index cache when changing status fields.](https://github.com/vitorpamplona/amethyst/commit/6c54082a125b3059b0e7dd7bdb4ea9c9bd79c8a0) +- [Do a warning log and not an error log for verification fails](https://github.com/vitorpamplona/amethyst/commit/e1738a25a1244ee81d652a777941a4b72a454bd7) + +[Changes][v0.75.8] + + + +# [Release v0.75.7: Quick Fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.7) - 2023-08-27 + +- Fixes for a crash when receveing a new notification before other logged in accounts get loaded in memory + +[Changes][v0.75.7] + + + +# [Release v0.75.6: Improved Error Handling for Zaps](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.6) - 2023-08-27 + +- Better error handling screens when Zaps fail +- Fixes an app crash when a user has more than 1 status +- Fixes All Follows filter for Live Activities. +- Additional Hungarian translation by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) +- Restructures status filters to minimize duplications. +- Adds polls to the hashtag screen +- Improves User filters by merging lastEOSEs into a single filter +- Faster crossfade animation between navigation screens +- Update French translations by [@anthony-robin](https://github.com/anthony-robin) +- Separates observer cleanup from memory pruning on the app pause +- Migrates to a double-layer observer structure for the memory cache +- Removes prefix filters +- Restructures channel data sources to avoid rebuilding the channel object + +[Changes][v0.75.6] + + + +# [Release v0.75.3: 1 sat 1 vote polls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.3) - 2023-08-25 + +- Activates 1 sat, 1 vote (min/max zap values) for polls +- BugFix for deleting statuses +- Moves isAcceptableNote calculations to viewModel +- Moves coroutine of NIP-05 verification to the viewModel +- Moves zap amount/deryption calculations to a viewModel +- Moves tallie calculations to a viewModel +- Adds a Toast message when no wallet is found to pay the invoice +- BugFix: starts the wallet app in a separate task to allow people to come back to Amethyst by switching apps instead of the back button +- Reduces the icon to the music and adds space before the status +- Adds the keyboard done action to be used as Post in the status field +- BugFix: Moves the User filter invalidation to the right channel +- Updates some dependencies +- BugFix: Adds some padding between the status and the clickable icon +- BugFix: for reloading events that have been deleted crashing the app +- Improves blinking issues when loading a thread. +- Fixes r-tag search in statuses +- BugFix for serialization of the per-relay since attributes in the event filter + +[Changes][v0.75.3] + + + +# [Release v0.75.2: BugFix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.2) - 2023-08-24 + +Removes amethyst.social test code when creating new status updates + +[Changes][v0.75.2] + + + +# [Release v0.75.1: Status updates](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.1) - 2023-08-24 + +https://cdn.nostr.build/i/c56a49811acd3a79a2b9b27d61c867d7132601157d6569f3d4d580446127d212.jpg + +- Adds support for NIP-315: Status Updates +- Adds support for NIP-40: Expiration Timestamp, prunes events accordingly +- Only renders status if the nip05 checks pass +- Updates status on the Drawer +- Reduces font size for statuses and nip05s +- Animates a rotation of statuses if more than 1 is found +- Displays clickable links in the status row if they are present. +- Moves Manifest to target Android API 34 +- Moves livedata creation to long-lived objects + +[Changes][v0.75.1] + + + +# [Release v0.75.0 Replies and Boosts in NIP94/95, Lib Updates](https://github.com/vitorpamplona/amethyst/releases/tag/v0.75.0) - 2023-08-23 + +- Separates NIP24 implementation into the encryption NIP 44 and the messaging NIP 24 +- Migrates to Compose 1.5.0, Updates Gradle plugin, Compose navigation, exoplayer, and vico dependencies to the latest. +- Saves some Notification Tab loading time by adding a check if a notification was already asked and rejected +- BugFix on bundled update dispatchers being on the wrong thread +- Faster daily reaction row compositions in the Notification tab +- Protects contact lists from pruning of all accounts in the device. +- Prunes events that are not from or cite one of the logged-in accounts +- BugFix Force Relay Reconnection when broadcasting new events. +- Small refactoring to create the PrivateZap Event for Quartz +- Activates pull to refresh on the Stories feed. +- Base support for Calendar events +- Migrates Addressable Events to a Base class on Quartz +- Refactors replaceable Event consumers into a single main function +- Activates pruning of old replaceable versions +- Adds replies and boosts buttons to Stories +- Adds Thai translation [@npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e](https://github.com/npub1vm0kq43djwdd4psjgdjgn9z6fm836c35dv7eg7x74z3n3ueq83jqhkxp8e) +- Removes Zap events from search. +- Corrects imePadding of the NewPostView +- Fixes quotes and boost previews for NIP94 and NIP95 content + +[Changes][v0.75.0] + + + +# [Release v0.74.5: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.74.5) - 2023-08-21 + +- Fixes Thread's search for root to go backwards in the etag-stack. +- Fixes TopBar's and extended header's padding issues. +- Fixes the loading of GiftWraps URIs as intents in the app. +- Fixes a crash when not using play services with notifications by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) + +[Changes][v0.74.5] + + + +# [Release v0.74.4: Coroutine Adjustments.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.74.4) - 2023-08-21 + +- Fixes TopBar's and extended header's padding issues. +- Adds user info to the header of single-user chat rooms +- Breaks User + Created At UI line into two +- Moves community description and rules texts to a single Translateable text +- Fixes the copy to clipboard note ID of a GiftWrap message +- Fixes the feed refresh after adding an image on stories +- Fixes the divider presence in the Discover and Notification tabs +- Filter follow lists with the entire list of participants for Live Activities +- Uses KIND3 follows for the discovery tab notification dot +- Fixes issue with unfollowing hashtags written in a different case +- Minimizes the creation of new coroutine scopes +- Moves coroutines of BundledUpdate and BundledInsert to a managed model. +- Broadcasts all replied, quoted, and mentioned events together with the main event. + +[Changes][v0.74.4] + + + +# [Release v0.74.3: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.74.3) - 2023-08-20 + +Adds Copy URL and Copy Note ID popups for images and videos for Gigi +BugFix for empty global feeds +BugFix to re-broadcast GiftWraps +BugFix to include zap events signed by the user's main key in the summary chart +BugFix for Playback services taking too long to start on Samsung phones +Updates media control dependencies to the latest version + +[Changes][v0.74.3] + + + +# [Release v0.74.2: JSON Parser migration, UI Improvements, StemStr, new modules](https://github.com/vitorpamplona/amethyst/releases/tag/v0.74.2) - 2023-08-19 + +- Adds support for Stemstr's kind 1808 +- Adds a waveform visual to audio playback when available +- Creates a Quartz Module for Nostr Events +- Creates a Benchmark Module to test Performance +- Migrates from GSon to Jackson for Performance gains, adapts all serializers accordingly +- Automatically activates NIP24 chats when users have received NIP24 messages from the counterparty +- Implements contextual rounded corners for images and videos +- Caches NIP-44 shared key for performance. +- Improves BechUtils encoding performance. +- Recreates Hex encoding/decoding classes for Performance. +- Migrates NIP24 to the new ByteArray concat encoding. +- Fixes Zap Notifications when the Zap payer is the logged-in user +- Fixes ThreadAssembler when there are two roots to a conversation branch +- Fixes the color of the historical chart to follow the chosen theme in settings +- Fixes chatroom names when clients send the same user twice in the p-tags. +- Removes support for lenient choices in the. events. +- Refactors TLV's, Events, and NIP-19 dependencies. +- Adds a large set of events as a test case for signature validation +- Adds new translations for cs/de/se by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Fixes url regex pattern for URLs with a dash by [@npub1l60d6h2uvdwa9yq0r7r2suhgrnsadcst6nsx2j03xwhxhu2cjyascejxe5](https://github.com/npub1l60d6h2uvdwa9yq0r7r2suhgrnsadcst6nsx2j03xwhxhu2cjyascejxe5) +- Fixes image uploading tests without an account +- Adds account info to image uploads test suites +- Moves navigation's top bar to use the Arrow Back UI Concept +- Trims display names when possible +- Don't display the username if the display name is available. +- Moves Relay List to a composable surface +- Migrates the use of pubkey prefixes in filters from 6 to 8 because more relays seem to work with this +- Adds read support for NIP-65 +- Adds UI Improvements to the Settings Interface +- BugFix: Highlight event builder using the wrong kind +- BugFix: Avoids displaying a NIP-94 event without a url tag +- Updates SDK and dependencies to the latest + +[Changes][v0.74.2] + + + +# [Release v0.73.3: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.73.3) - 2023-08-13 + +- BugFix for the blank screen when pressing the message button on a User Profile without any history of Chats +- BugFix for the crashing route when clicking in the GiftWrap DM Notification +- BugFix: Correctly updates Hashtags on a note after a new follow/unfollow +- Moves Zap Amount calculator from Compose scope to ViewModel Scope +- Avoids account state recompositions +- Moves Show And Hide functions from the Compose Scope to ViewModel Scope +- Moves the creation of the TopBar live data for lists into the AccountViewModel +- Moves HTTP and EMAIL regex compilation to a singleton + +[Changes][v0.73.3] + + + +# [Release v0.73.2: PushNotifications for GiftWraps](https://github.com/vitorpamplona/amethyst/releases/tag/v0.73.2) - 2023-08-12 + +- Adds PushNotification for all GiftWrapped Events +- Fix: Marking All GiftWraped DMs as read +- Fix: Displays GiftWraped DM as Messages in the Notification Screen +- Fix: Menu drawer half open when switching to landscape mode by [@npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k](https://github.com/npub1a3tx8wcrt789skl6gg7rqwj4wey0j53eesr4z6asd4h4jwrd62jq0wkq4k) +- Fix: Forces the creation of Notification Channels to enable toggles in the Settings of Samsung phones +- Fix: Correctly displaying/hiding pictures in Chat Compose + +[Changes][v0.73.2] + + + +# [Release v0.73.1: Private DMs and Group Chats](https://github.com/vitorpamplona/amethyst/releases/tag/v0.73.1) - 2023-08-12 + +This is an **alpha** release of the new GiftWrapped DMs. Please do not consider anything to be private until we have a stable version. This is early and there might be bugs that leak information. + +This implementation is very similar to how Slack manages direct DMs to multiple users. If three users are having a conversation and want to add a forth person, the forth's user will not see the past. This guarantees maximum privacy: only the receivers of a message at the time of writting will ever be able to decrypt it. + +The claims of this new method are: +- Messages are encrypted with a superior XChaCha algorithm to each participant's public key individually. +- Chat participant identities, each message's real date and time, event kinds, and other tags are all hidden from the public. +- Senders and receivers cannot be linked with public information alone. +- Minimal trust in counterparties: Counterparties cannot expose verifiable details of your message, including the metadata, without exposing their entire user and all of their other messages (private key) +- There is no central queue, channel or otherwise converging event id to link or count all messages in the same group. +- There is no moderation role (i.e. no group admins, no invitations or bans) +- There is no chatroom secret that can leak or be mistakently shared +- Messages can be fully recoverable in any client (that implements NIP-24) with the receiver or the sender's private key +- The protocol's messages can flow through public relays without loss of privacy. Private relays can increase privacy further, but they are not needed. +- The protocol is extensible to make any other event kind fully private (private likes, private reports, private long-form content, etc) + +In the near future, we will implement Forward Secrecy +- Users will be able to opt-in for "Disappearing Messages" that are not recoverable with their private key +- Users will be able to also opt-in to sharing messages with a new key exclusive for DM backup and recovery. + +You can activate this mode by clicking in the Incognito icon on the Chat screen. For now, only Amethyst supports this NIP. Thus we recommend only testing with other Amethyst users. Coracle and 0xChat are finishing their implementations in the upcoming days/weeks. + +- Support for NIP-24 Private Messages and Small Groups +- Support for NIP-59 Gift Wraps & Seals +- Support for NIP-44 Versioned Encrypted Payloads +- Support for XChaCha encryption algorithm +- Fix: Loading of Alby's NWC URI +- Fix: Only requests notification permission once. +- Fix: Show reposts and reactions in search +- Fix: Signed byte used for array slice inside the TLV by [@npub1xpuz4qerklyck9evtg40wgrthq5rce2mumwuuygnxcg6q02lz9ms275ams](https://github.com/npub1xpuz4qerklyck9evtg40wgrthq5rce2mumwuuygnxcg6q02lz9ms275ams) +- Fix: Global feed only shows events from Global-active relays by [@npub10npj3gydmv40m70ehemmal6vsdyfl7tewgvz043g54p0x23y0s8qzztl5h](https://github.com/npub10npj3gydmv40m70ehemmal6vsdyfl7tewgvz043g54p0x23y0s8qzztl5h) +- Updates Dutch translations by [@npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd](https://github.com/npub1w4la29u3zv09r6crx5u8yxax0ffxgekzdm2egzjkjckef7xc83fs0ftxcd) + +[Changes][v0.73.1] + + + +# [Release v0.72.2 Small Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.72.2) - 2023-08-05 + +[TimeAgo refactoring](https://github.com/vitorpamplona/amethyst/commit/c2b72f1e45f5f28a8b2ef2e9a043581eb617e62e) +[Puts marked as read on chat to an IO thread](https://github.com/vitorpamplona/amethyst/commit/28e6471adeef567bbbe93716bc17b946cc7d87eb) +[Puts an invalidate data on an IO thread](https://github.com/vitorpamplona/amethyst/commit/c3b8eb508724365cc6484530f30334408b394b9b) +[simple refactoring](https://github.com/vitorpamplona/amethyst/commit/75779e7ddc8dc74315b88ca115be7e94f66764b2) +[Don't invalidate data on channels if it is already invalidating](https://github.com/vitorpamplona/amethyst/commit/118bc7b73c30d25258d334b7e0956a77e9f13c0b) +[Removes unnecessary signing step](https://github.com/vitorpamplona/amethyst/commit/e6a0fdedd9bd78fb3e1057d687f7454cd6d78ea4) +[Don't push to invalidate unless there is an observer.](https://github.com/vitorpamplona/amethyst/commit/28098fafd7c3403bd85414ef70ab59d7b48d3aa6) +[Moves headers to the top nav bar](https://github.com/vitorpamplona/amethyst/commit/0c0e87af21617939933992d17af728f23c09d998) +[Removes the need for .0 when on base sats.](https://github.com/vitorpamplona/amethyst/commit/8abfd7149b62e2c1f9c68adc76fedacffde97331) +[Moves coroutine creation to the viewModel](https://github.com/vitorpamplona/amethyst/commit/674896cea468abe1c9ba24a3b7646b5da70c75c5) +[Makes the New Channel creation scrollable.](https://github.com/vitorpamplona/amethyst/commit/ec514651fcca8678462cf4bcf4afe8b8f7014ee1) +[updates github action to support minified versions of the app](https://github.com/vitorpamplona/amethyst/commit/8071d48911d452364b8ad620e243d2ad94a02b86) + +[Changes][v0.72.2] + + + +# [Release v0.72.1: Caching Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.72.1) - 2023-08-04 + +- Expanded disk cache for images +- Moves NIP95 cache to internal/secure folders +- Fixes the interference between video and image caches +- Adds a cache forever tag to robohashes +- Moves URL Previews into suspend functions +- Adds a little border for Long Form Content +- Updated image upload API for nostr.build to v2 by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Added support for NIP98 for nostr.build. Users with an account at nostr.build will upload files to their personal gallery through amethyst now by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Updated French translations by [@anthony-robin](https://github.com/anthony-robin) +- Fixes new lines after images +- Fixes URL links containing "-" +- Displaying a bytecounter for events in memory when the app pauses. +- Slighly Faster picture galleries +- Avoids null image url errors that might be delaying some of the rendering. +- Uses Lists instead of Sets to reduce memory consumption of pointers. +- Moves onCreate intent evaluation to the App Navigation +- Moves Geolocation search to the IO thread +- Avoids using String.format due to an inner Synchronized block +- Uses a faster method to generate the hex of a url +- Moves to a minified release. + +[Changes][v0.72.1] + + + +# [Release v0.72.0 New Memory Management](https://github.com/vitorpamplona/amethyst/releases/tag/v0.72.0) - 2023-08-01 + +- Adds aggressive memory management to avoid Out of Memory +- Fixes the App losing the back stack of screens +- Interns event strings to avoid duplicating memory with hashes and pubkeys +- Improves search by looking into all tags of all events +- Improves Tamil Translations by @ +- Adds missing translations cs/de/se by [@npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef](https://github.com/npub1e2yuky03caw4ke3zy68lg0fz3r4gkt94hx4fjmlelacyljgyk79svn3eef) +- Adds cryptographic and base event support for NIP-24 (GiftWraps and Sealed Gossip) +- Increases confidence requirements for the Translator +- Refactors the event creation into a Factory +- Adds new kinds to the hashtag and geotag search feeds +- Fixes the explainer text of the geohash addon +- Updates to the latest libraries +- Removes leakcanary due to irrelevance +- Cleans up unused values in strings +- Fix: Ignores past version of addressable content in feeds +- Fix: Avoids showing community definition types in the community feed. +- Fix: Avoids downloading 1000s of Nostr Connect events that some clients are generating. + +[Changes][v0.72.0] + + + +# [Release v0.71.0 Geohash](https://github.com/vitorpamplona/amethyst/releases/tag/v0.71.0) - 2023-07-25 + +- Adds support for the `g` tag with a precision of 5x5km. +- Adds support for the following locations +- Adds support for multiple locations in lists +- Refactors New Post Buttons to make them more similar to one another +- Improves Translation-skip Indexes +- Reviews closing of response.body calls +- Refactors unused elements in VideoView +- Refactors Relay class to remove the Synchronized block +- Improves reachability of the relay screen when the keyboard is visible +- Fixes memory leaks when playback services are destroyed +- Fixes video release leak when double clicking on the Stories tab +- Fixes a crash when the video playback service isn't ready + +[Changes][v0.71.0] + + + +# [Release v0.70.8: Permission Request test](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.8) - 2023-07-24 + +- Adds notification permissions request for Android Tiramisu + +[Changes][v0.70.8] + + + +# [Release v0.70.7: Coding is hard](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.7) - 2023-07-24 + +- Bug fix for encrypting new private messages +- Bug fix for the back button going back in the stack instead of leaving the app + +[Changes][v0.70.7] + + + +# [Release v0.70.6: Refactoring and improvements (Don't use this version)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.6) - 2023-07-24 + +- Fixes a crash when onNewIntent is called before onCreate +- New Post, Relay Choice: Select/Deselect all options by [@greenart7c3](https://github.com/greenart7c3) +- New Post, Relay Choice: Fixes missing switch when url is too long by [@greenart7c3](https://github.com/greenart7c3) +- Adds missing OptIn when using GlobalScope by [@greenart7c3](https://github.com/greenart7c3) +- Refactors Crypto/Hex/Bech classes and dependencies +- Simplifies relay connection status +- Moves to OkHttpClient on URL Preview Queries +- Moves to OkHttpClient on Image uploads +- Refactoring of the Connectivity Settings +- Avoids crossfading animations when loading NIP94 and NIP95 content +- Moves playback service startup to the IO Thread +- Activates Strict mode in debug +- Updates Firebase version +- Updates Hungarian translations by [@ZsZolee](https://github.com/ZsZolee) + +[Changes][v0.70.6] + + + +# [Release v0.70.5: UI Bugfixes and improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.5) - 2023-07-22 + +[Releases the video player on Mutex when destroying the app.](https://github.com/vitorpamplona/amethyst/commit/8a12cc3cce58346773f9cd5e1643258b8db14355) +[Releases the Mutex when stopping the feed.](https://github.com/vitorpamplona/amethyst/commit/7e03870c0be640a5b5dc48855826c5c8feb41ee4) +[Fixes lightning colors](https://github.com/vitorpamplona/amethyst/commit/a6f56416e3f3394401c4221175d9001ba4896774) +[Fixes color of the NIP05 address in the profile](https://github.com/vitorpamplona/amethyst/commit/efe7772135dbb318508da0bc04fff26f8e8c2816) +[Removes extra padding in the video of a live activity mention](https://github.com/vitorpamplona/amethyst/commit/15c96ce00728afd5c7dc8410cd66c697354366bd) + +[Changes][v0.70.5] + + + +# [Release v0.70.4: Wakelock Leak](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.4) - 2023-07-21 + +[Moves wake lock to activate only when the video is actually playing](https://github.com/vitorpamplona/amethyst/commit/2664292993e731012ec351a823cd1203aafbaff5) + +[Changes][v0.70.4] + + + +# [Release v0.70.3: Bugfixes and improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.3) - 2023-07-21 + +- Fix KeepPlayingButton color in light theme by [@greenart7c3](https://github.com/greenart7c3) +- Adds a space when rendering inline images and url previews for [@npub1aeh2zw4elewy5682lxc6xnlqzjnxksq303gwu2npfaxd49vmde6qcq4nwx](https://github.com/npub1aeh2zw4elewy5682lxc6xnlqzjnxksq303gwu2npfaxd49vmde6qcq4nwx) +- [Moves the loading of an Accounts backup contacts to the IO Thread](https://github.com/vitorpamplona/amethyst/commit/5cdceb51942a8ecc8497c1a2e841ba411ba22fd6) +- [Adjustments to Modifiers in the Chatroom screen](https://github.com/vitorpamplona/amethyst/commit/2c82e6c44731b139fca52bc403519e7bcbecf751) +- [Refactors ChatroomHeader compose](https://github.com/vitorpamplona/amethyst/commit/9a517380a0447223c88346e28dffc23983b5c48b) + +[Changes][v0.70.3] + + + +# [Release v0.70.2: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.2) - 2023-07-21 + +- Updated se/de/cs translations by [@davotoula](https://github.com/davotoula) +- Moves the video caching service initialization foreground services. +- Fix boosted notes from blocked users appearing as blank by [@greenart7c3](https://github.com/greenart7c3) + +[Changes][v0.70.2] + + + +# [Release v0.70.1: BugFix for F-Droid](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.1) - 2023-07-21 + +- Restructures the spacing in the first and second rows of a post +- Fixes Wake-Lock permission line that crashes on the F-droid version + +[Changes][v0.70.1] + + + +# [Release v0.70.0: Background Playback](https://github.com/vitorpamplona/amethyst/releases/tag/v0.70.0) - 2023-07-20 + +- Moves Video/Audio player to a foreground service. +- Migrates Feed, Stories, and Live Stream screens to use that service +- Blocks screen from going to sleep if a video is playing. +- Blocks WIFI from going to sleep if an online video is playing. +- Allows the app to pause while listening to media and continue playing +- Manages cache for up to 30 videos in parallel for each of the 3 categories: local, streaming, progressive content +- Activates the use of popups with artwork that points to the screen with the video +- Creates a button to allow any video to play while browsing the app/phone +- Moves app to SingleTop mode. +- Keeps viewed position cached for up to 100 videos. +- Restructures the starting screen from App Navigation + +[Changes][v0.70.0] + + + +# [Release v0.69.3: BugFix NIP05 colors](https://github.com/vitorpamplona/amethyst/releases/tag/v0.69.3) - 2023-07-17 + + + +[Changes][v0.69.3] + + + +# [Release v0.69.2: Updated Verification icons](https://github.com/vitorpamplona/amethyst/releases/tag/v0.69.2) - 2023-07-17 + +Adds [@Niel Liesmons](https://snort.social/p/npub149p5act9a5qm9p47elp8w8h3wpwn2d7s2xecw2ygnrxqp4wgsklq9g722q)'s icons for Following, Nostr Address Verification, and NIP-94 hash verification + +[Changes][v0.69.2] + + + +# [Release v0.69.1: BugFix to view the mute feed](https://github.com/vitorpamplona/amethyst/releases/tag/v0.69.1) - 2023-07-17 + + + +[Changes][v0.69.1] + + + +# [Release v0.69.0: Ad-hoc local lists removed](https://github.com/vitorpamplona/amethyst/releases/tag/v0.69.0) - 2023-07-16 + +This version starts the migration to store a user's following communities, channels, and block/mute list in the Contact List and People List kinds. To migrate, please block (not report) and unblock somebody, follow and unfollow somebody. + +- Moves video player to the brand new Exoplayer package +- Moves Following Communities' local DB to the Contact List +- Moves Following Channels local DB to Contact List +- Moves Following BlockList local DB to Mute List (Private part) +- Migrates all past local lists to their event kinds +- Views Mute Feed (disables hidden authors for that specific list) +- Breaks Security Filters screen in 2 tabs: Blocked and Spammers (automated filter) +- Restructures ContactList to avoid removing unsupported tags +- Restructures PeopleList to avoid removing non-people tags +- Fixes older channels and communities not loading on the discovery tab +- Forces a given event kind to be displayed in the Discovery tab +- BugFix for AppDefinitionEvent updates +- Moves contact list closer to metadata in the Local Cache +- Adds parsing support for NNS Events. +- Moves id hex prefixes from 6 to 8 chars. +- Fixes the profile display for new users without pictures. + +[Changes][v0.69.0] + + + +# [Release v0.68.4: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.68.4) - 2023-07-14 + +- Renames NIP-05 to Nostr Address for [@derekross](https://github.com/derekross) +- Moves UserProfile NewThreads, Conversations, Reports and App Recommendations to be additive filters +- Moves the synchronized Zap allocation block to run only when needed +- Moves badges out of the User class +- Keeping media feed active from the start of the app. +- Only logging pruning and printing stacktraces when it matters +- Adds EOSE limits to the Video tab +- Adds EOSE limits to the Discovery tab. +- Only triggers mutable state of connection if the connection actually changes. +- Reduces profile feed size to 200 and zaps, reports and followers to 400 +- Puts the Wifi signal processing in an IO Thread + +Download: +- [Play Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.68.4/amethyst-googleplay-universal-v0.68.4.apk) +- [F-Droid Edition](https://github.com/vitorpamplona/amethyst/releases/download/v0.68.4/amethyst-fdroid-universal-v0.68.4.apk) + +[Changes][v0.68.4] + + + +# [Release v0.68.3: Bug fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.68.3) - 2023-07-14 + +- Adds [NostrCheck](https://nostrcheck.me/) uploads on the Media Feed +- Adds the title of the blog post to the [highlighter's](https://highlighter.com/) display +- Fixes size of custom reactions on the Stories feed +- Fixes crash when changing setting in android api < 13 by [@greenart7c3](https://github.com/greenart7c3) +- Migrates DropDownMenu to MutableState for performance +- Changes clicks on Community and Channel headers to go to the community/channel screen instead of expanding it inline +- Update Japanese translations by [@akiomik](https://github.com/akiomik) +- Update Portuguese translations by [@greenart7c3](https://github.com/greenart7c3) + +[Changes][v0.68.3] + + + +# [Release v0.68.2: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.68.2) - 2023-07-13 + +- [Fixing Right To Left Text](https://github.com/vitorpamplona/amethyst/commit/0d9399a1a45da32b86c043fa5323866bcd040b18) +- BugFix for Aways show images/videos in the dialog screen + +[Changes][v0.68.2] + + + +# [Release v0.68.1: Settings Page](https://github.com/vitorpamplona/amethyst/releases/tag/v0.68.1) - 2023-07-13 + +- Adds Settings for (by [@greenart7c3](https://github.com/greenart7c3)) + - The default language of the app + - The default theme of the app + - If it loads images automatically or not + - If it loads URL previews automatically or not + - If it plays videos automatically or not +- Updates to the Japanese translations by [@akiomik](https://github.com/akiomik) + +[Changes][v0.68.1] + + + +# [Release v0.68.0 Classifieds](https://github.com/vitorpamplona/amethyst/releases/tag/v0.68.0) - 2023-07-13 + +- Adds Support for Classifieds ([nostr-protocol/nips#662](https://github.com/nostr-protocol/nips/pull/662)) +- Adds Japanese Translations by [@npub1f5uuywemqwlejj2d7he6zjw8jz9wr0r5z6q8lhttxj333ph24cjsymjmug](https://github.com/npub1f5uuywemqwlejj2d7he6zjw8jz9wr0r5z6q8lhttxj333ph24cjsymjmug) +- BugFix to cut multiple emojis from reactions +- BugFix to remove emoji package list selection from Profile threads. + +[Changes][v0.68.0] + + + +# [Release v0.67.1: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.67.1) - 2023-07-12 + +- When clicking in a repost of a note, redirects the user to the note directly, not to the repost +- Adjustments to allow removing of the selected emoji packs from the reaction setup dialog + + +[Changes][v0.67.1] + + + +# [Release v0.67.0: Custom Emoji Reactions](https://github.com/vitorpamplona/amethyst/releases/tag/v0.67.0) - 2023-07-12 + +- Support for Emoji Packs +- Support for Personal Emoji Lists +- Support for Custom emoji Reactions + +[Changes][v0.67.0] + + + +# [Release v0.66.7: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.7) - 2023-07-12 + +- Fixes race condition when deleting a reposted event +- Fixes a crash when a lightning service returns an emtpy pr field. +- Fixes images going over text in a markdown rendering +- Early support for displaying custom emoji reactions +- Updates exoplayer version +- Makes nav(route) threaded operation +- Refactoring of Badge Box codes and Time classes +- Adds rendering of community approval posts to the NoteMaster of a thread +- Updates Tamil translations by [@AutumnSunshine](https://github.com/AutumnSunshine) + +[Changes][v0.66.7] + + + +# [Release v0.66.6: BugFix for content-warning checkbox not working](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.6) - 2023-07-09 + + + +[Changes][v0.66.6] + + + +# [Release v0.66.5: Content-Warning in the video feed](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.5) - 2023-07-09 + +- Adds content-warning toggle when sending an image. +- Toggle marks the media event (NIP-94 or NIP-95) as content-sensitive +- Change renderers in chat, communities, feed, and stores to show a warning before the image is displayed. + +[Changes][v0.66.5] + + + +# [Release v0.66.4](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.4) - 2023-07-08 + + + +[Changes][v0.66.4] + + + +# [Release v0.66.3: Live Notification Bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.3) - 2023-07-07 + +- Avoids triggering the Live Notification bubble when the live event is simply updated with new participants +- Adds content-sensitivity warnings for LiveStreams +- Fixes translations from Japanese with special chars breaking the url +- Adds hashtags to the description of communities and channels +- Displays community/channel descriptions with Translations. +- Slightly faster reactions and zap icon rendering + +[Changes][v0.66.3] + + + +# [Release v0.66.2: BugFixes for Crashes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.2) - 2023-07-07 + +[Creates a fallback for Android9 on OPPO, which doesn't seem able to parse the Japanese regex.](https://github.com/vitorpamplona/amethyst/commit/c93a6dffc4dc56eaee28689af85d1cb915ea8968) +[BugFix for invalid URLs crashing the app.](https://github.com/vitorpamplona/amethyst/commit/60dadc008877de62927c490ed32066e30958c75e) +[Fixes caching of time display.](https://github.com/vitorpamplona/amethyst/commit/a26c7e3d9777210dae4d84a59de0f7cb06b5ae4c) + +[Changes][v0.66.2] + + + +# [Release v0.66.1: Community/Chat headers with reactions/zaps](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.1) - 2023-07-07 + +- Moves communities from /c/name to /n/name +- Adds reactions to owners of Chats and Communities +- Adds zaps reactions to owners of Chats and Communities +- Fixes Emoji combinations for +- Reduces the size of the discovery tab captions +- Increases the most recent downloads per chat from 25 to 50 +- Removes top bar for Community and Hashtag posts +- Adds EOSE treatment for the Discovery datasource +- Allows notification to chat channel headers + +[Changes][v0.66.1] + + + +# [Release v0.66.0: Communities (NIP 172)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.66.0) - 2023-07-06 + +- Breaks the live screen in 3 tabs +- Adds Support for Communities (172) +- Adds Community discovery screen +- Adds Public Chat discovery screen +- Adds Community Follow/Unfollow +- Adds rendering of Community Posts in the feed +- Creates a summary of verified participants in Communities/Chats/Streams +- Restructures Hashtag Screen to the new Screen Building structure +- Remembers scroll position in Live, Community, and Chat discovery +- Displays Approval Notes in the notifications +- Removes the Live bar from the top of the feed +- Adds notification dots in the LiveStream bottom button. +- Updated Swedish/Czech/German translations by [@davotoula](https://github.com/davotoula) +- BugFix for invalid hexes in the hex index +- BugFix for Japanese Url parsing and Text newline breaks by [@ShinoharaTa](https://github.com/ShinoharaTa) + +[Changes][v0.66.0] + + + +# [Release v0.65.1: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.65.1) - 2023-07-05 + +- [Performance updates](https://github.com/vitorpamplona/amethyst/commit/f78ec5cc90e6232531e1322f9161111289eb35a9) +- [Fixes](https://github.com/vitorpamplona/amethyst/commit/fd6a63a76c51ab72b1698d99c1e70c7d82ef36fa) [#487](https://github.com/vitorpamplona/amethyst/issues/487) +- [BugFix for not rendering images on markdown when there is no NIP19 reference in the text.](https://github.com/vitorpamplona/amethyst/commit/e0f186bb94063068d27d14b93b463b66dd79a5bd) + +[Changes][v0.65.1] + + + +# [Release v0.65.0: Live Streaming Browser](https://github.com/vitorpamplona/amethyst/releases/tag/v0.65.0) - 2023-07-04 + +- Live Streaming Browser + +[Changes][v0.65.0] + + + +# [Release v0.64.4: BugFix for chat delay](https://github.com/vitorpamplona/amethyst/releases/tag/v0.64.4) - 2023-07-03 + +- [BugFix for delayed update of the last messages in the Messages screen](https://github.com/vitorpamplona/amethyst/commit/91c47b6e87495dd5f540842579ac396efe8e0c4a) + +[Changes][v0.64.4] + + + +# [Release v0.64.3: New icon for verified follows](https://github.com/vitorpamplona/amethyst/releases/tag/v0.64.3) - 2023-07-02 + +- BugFix for IndexOutOfBoundsException when loading invalid hexes +- Adds New Icon for verified follows +- Fixes the lack of the checkmark in the verification icons +- Adds #Cashu custom tag by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) + +[Changes][v0.64.3] + + + +# [Release v0.64.2: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.64.2) - 2023-07-01 + +- [Shows channel picture on the public chat channel's header instead of the creator's picture](https://github.com/vitorpamplona/amethyst/commit/5a3ea1c25824c2bc3b3f9a5d00eb13f9c325cb84) +- [Adds a Toast message for not having a private key when following/unfollowing](https://github.com/vitorpamplona/amethyst/commit/e4020817775d7e2e215cf22e6e7579a58798c8d7) +- [BugFix for not changing background color on Notes](https://github.com/vitorpamplona/amethyst/commit/ed9c27341f925feb9e3d47d86c0f5b896a42d48c) +- [Performance Improvements: Moves away from `drawBehind` and uses background color instead](https://github.com/vitorpamplona/amethyst/commit/56d9c9a50fbc39177f92931cf14dffdffc2c4c07) +- [Removes the need to draw a background in the verification symbol](https://github.com/vitorpamplona/amethyst/commit/09582fd0b13ec6893d7fbaa9ef944bdd037f4694) +- [Reduces the max grouped reactions on Notifications to 30](https://github.com/vitorpamplona/amethyst/commit/1d5dfbfd29aad9d36813f14be4a75332f3a94018) +- [Moves Note/User updates from 300ms to 500ms](https://github.com/vitorpamplona/amethyst/commit/cd9465c0e755b92d34475afae4d4a2dfb4f02107) +- [New RichText engine to help with testing classes.](https://github.com/vitorpamplona/amethyst/commit/d179c93c0bd19a5e6ba59c8c1a19085641440216) +- [fix relay tab not working in profile page](https://github.com/vitorpamplona/amethyst/commit/53a146d0e54a8b0f33f4869625447b2da6c5894a) +- [BugFix Crashing relay screen on invalid URLs](https://github.com/vitorpamplona/amethyst/commit/b820b6564f5812c28888398b93fdbd577e47f912) +- [Reduces mentions to hex in the UI](https://github.com/vitorpamplona/amethyst/commit/3908c42c7fa940e5f9a5236f6a2c4a4f2f2acce7) + +[Changes][v0.64.2] + + + +# [Release v0.64.0: UI Changes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.64.0) - 2023-06-29 + +- Merges Global into Home as a top-bar List +- Moves Relay Settings info from top bar to left drawer +- Adds search to the top bar +- Slims down the live headers +- Additional checks for main thread in Notifications +- Makes NIP05 work with domain names only (No need for the _@ in the "_@ domain" address) +- Improved AsyncImage loading states +- Logs out the time to display each reaction type +- BugFix: Not showing display name on [n] tags +- BugFix: Trimmed paragraphs losing indentation +- BugFix: Don't show URL previews in quoted notifications and other cases where the preview is not needed. + +[Changes][v0.64.0] + + + +# [Release v0.63.0: Zitron's Logo!](https://github.com/vitorpamplona/amethyst/releases/tag/v0.63.0) - 2023-06-29 + +- Moves to [@npub103vypyhddrad9289zp8lf2dxlkkrmq3e0utx3qg449ea8x2wel6sas2700](https://github.com/npub103vypyhddrad9289zp8lf2dxlkkrmq3e0utx3qg449ea8x2wel6sas2700) 's Logo +- Adds followed tags in profile screen by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adds music note to #tunestr + +[Changes][v0.63.0] + + + +# [Release v0.62.8: More Performance](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.8) - 2023-06-28 + +#Amethyst v0.62.8: More Performance + +- Performance improvements and additional MainThread checks +- Logging rendering performance +- BugFix for rendering url of highlight note by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Add copy token button to Cashu's Preview by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- BugFix better default error message by [@npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8](https://github.com/npub1nxa4tywfz9nqp7z9zp7nr7d4nchhclsf58lcqt5y782rmf2hefjquaa6q8) +- Runs translation chain in the background +- Restructures Multi-Notification Galleries +- BugFix: Avoids blinking the nip05 address +- BugFix: Ignoring case when comparing original and translated versions. +- Moves RichText/Markdown Modifiers to singleton classes. +- Updates URLPreview in the main thread. +- Updates dependencies to the newest version +- Updates Hungarian translation by [@npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp](https://github.com/npub1ww8kjxz2akn82qptdpl7glywnchhkx3x04hez3d3rye397turrhssenvtp) + + +Download: +- Play Edition: https://github.com/vitorpamplona/amethyst/releases/download/v0.62.8/amethyst-googleplay-universal-v0.62.8.apk +- F-Droid Edition: https://github.com/vitorpamplona/amethyst/releases/download/v0.62.8/amethyst-fdroid-universal-v0.62.8.apk + +[Changes][v0.62.8] + + + +# [Release v0.62.7: BugFix for zapraiser](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.7) - 2023-06-27 + +- Fixes the large UI padding in the details of the zapraiser + +[Changes][v0.62.7] + + + +# [Release v0.62.6: Perf improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.6) - 2023-06-27 + +- Moves state assignments to the main thread +- Reduces full-screen updates to once a second +- Minor adjustments in threading +- Moves cashu processing to a state class to account for errors + +[Changes][v0.62.6] + + + +# [Release v0.62.5: Bugfix for crashing on invalid cashu token](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.5) - 2023-06-27 + +- [Minor adjustments in UI threading](https://github.com/vitorpamplona/amethyst/commit/52af109b4eb8ea91716de96090693d584b32e2c4) +- [Moves cashu processing to a state class to account for errors.](https://github.com/vitorpamplona/amethyst/commit/833e6bc3e14534a396a320fe6fa1f0663f3a06b5) + +[Changes][v0.62.5] + + + +# [Release v0.62.4: Cashu Token support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.4) - 2023-06-26 + +- Adds Cashu Token redemption to the User's ln address by [@believethehype](https://github.com/believethehype) +- Video Dialog now go full screen by [@vitorpamplona](https://github.com/vitorpamplona) +- Updates Dutch Translations by [@Bardesss](https://github.com/Bardesss) +- Adds a confirmation dialog before logout by [@greenart7c3](https://github.com/greenart7c3) +- Bugfix for not updating user picture and name after a new message arrives on the Message List by [@vitorpamplona](https://github.com/vitorpamplona) +- Several little performance Improvements across the app by [@vitorpamplona](https://github.com/vitorpamplona) +- Adjusts Profile images to crop and not fit by [@vitorpamplona](https://github.com/vitorpamplona) +- Preloads channel data from LocalCache by [@vitorpamplona](https://github.com/vitorpamplona) +- Removes live thumb and adjusts padding of the live header [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.62.4] + + + +# [Release v0.62.3: BugFixes and Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.3) - 2023-06-25 + +- Adds picture of the User to the Stream's header +- Migrates the UserProfile page to the new ViewModel structure +- Requires an update in the live stream event every two hours to keep live +- Adds a less memory-intensive Hex Checker +- Moves OnlineChecker to a singleton class with a cache +- Moves LocalCache's Synchronized block to Concurrent implementations +- Moves user msg synchronization to its own object +- Crossfades changes in Reactions and Zaps +- Improves the rendering speed of chat messages +- BugFix for new posts by the user not showing up immediately in the feed +- BugFix for duplicated notes in the LocalCache +- BugFix for the Click on UserPicture event + +[Changes][v0.62.3] + + + +# [Release v0.62.2: BugFix for crashing relay screen](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.2) - 2023-06-23 + +- Some relays don't return a JSON when requested and that was crashing the app. + +[Changes][v0.62.2] + + + +# [Release v0.62.1: BugFix for posts with createdAt in the future](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.1) - 2023-06-23 + +- Stops showing posts in the future (Fixes Tony's Highlighter post) +- BugFix on publishedAt date for Longform posts + +[Changes][v0.62.1] + + + +# [Release v0.62.0 NIP-98 Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.62.0) - 2023-06-23 + +- Adds NIP98 Support by [@believethehype](https://github.com/believethehype) +- Adds nostrcheck.me image host by [@believethehype](https://github.com/believethehype) +- Fixes UTF-32 Reactions cutting off +- Adds icon for paid relays in the relay list by [@greenart7c3](https://github.com/greenart7c3) +- Improves rendering time of the Channel header +- Avoids crashing due to illegal zap address +- Making more classes stable for performance reasons. +- Improves relay options rendering performance. +- Review to avoid Synchronized blocks +- Uses derivedOf to protect from updates with the same content +- Generalizes the SensitivityWarning to any Note +- Moves LaunchedEffects to only run if objects haven't yet being loaded +- Checks main thread in preferences +- Moves the image border modifiers to app variable + +[Changes][v0.62.0] + + + +# [Release v0.61.4: Relay Info pages](https://github.com/vitorpamplona/amethyst/releases/tag/v0.61.4) - 2023-06-21 + +- Adds internal Relay Info pages when clicking on relay icons by [@greenart7c3](https://github.com/greenart7c3) +- Removes old image proxy classes by [@vitorpamplona](https://github.com/vitorpamplona) +- Improves rendering performance of Chat screens and messages by [@vitorpamplona](https://github.com/vitorpamplona) +- Updates Hungarian translation for Zapraiser by [@ZsZolee](https://github.com/ZsZolee) + +[Changes][v0.61.4] + + + +# [Release v0.61.3 Too many Live Streams Bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.61.3) - 2023-06-20 + +- BugFix for too many streams (max = 2 for now) +- BugFix for opening the video chat with the video in full screen until it loads. +- Fix margins when the Live Activity summary is not available +- Refreshing stream list when follows change, including Live activities. + +[Changes][v0.61.3] + + + +# [Release v0.61.2: Live streaming in the chat](https://github.com/vitorpamplona/amethyst/releases/tag/v0.61.2) - 2023-06-20 + +- Restructures chat message rendering +- Adds sensitive content warning to chats +- Adds live activities to the main feed +- Adds live activities chats to the conversations tab +- Adds public chat msgs to the conversations tab + +[Changes][v0.61.2] + + + +# [Release v0.61.1: Screen diet](https://github.com/vitorpamplona/amethyst/releases/tag/v0.61.1) - 2023-06-20 + +- Improvements in the use of space of UI elements +- Moves the streaming label to the bottom of the video +- Removes the top bar for streaming and chats +- Adds options to react and zap the author of the streaming +- BugFix for streaming rotation of videos +- BugFix for not updating Notifications quickly + +[Changes][v0.61.1] + + + +# [Release v0.61.0: Live streaming chats](https://github.com/vitorpamplona/amethyst/releases/tag/v0.61.0) - 2023-06-19 + +- Support for Live Chat event kind (1311) +- Renders Channel headers, NIP94 and NIP95 in the thread's master post +- Add toast message to show relay icon description by [@greenart7c3](https://github.com/greenart7c3) +- BugFix for notifications over very old posts not appearing + +[Changes][v0.61.0] + + + +# [Release v0.60.2: Scroll to The top BugFix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.60.2) - 2023-06-19 + +- Restructures feed invalidations to account for changes in the selected top list +- Restructures scroll-to-the-top implementations to avoid using arguments in the navigator +- Restructures Stable elements for minor performance gains. + +[Changes][v0.60.2] + + + +# [Release v0.60.1: Per-Post Zapraisers](https://github.com/vitorpamplona/amethyst/releases/tag/v0.60.1) - 2023-06-18 + +Allows users to add an amount of sats to raise per post. +Displays zap raisers as a progress bar to completion in the post. + +[Changes][v0.60.1] + + + +# [Release v0.60.0: Live Activities & Generic Repost support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.60.0) - 2023-06-18 + +- Basic Support for live activities (NIP-102) +- Adds support for Kind 16 (Generic Repost) +- Activates support for m3u8 streaming +- Migrates `e` citations to replaceable events to their latest version +- Migrates last-seen times saved per route to account management +- Removes original tags from Reposts +- BugFix on restarting the video when pressing mute +- BugFix to not scroll the feed to the top when the new follow list is updated +- BugFix for a background color for messages in notifications +- Increases performance of the follow/follower count + +[Changes][v0.60.0] + + + +# [Release v0.59.1: Name Playback](https://github.com/vitorpamplona/amethyst/releases/tag/v0.59.1) - 2023-06-16 + +https://nostr.build/av/e99f5528e0f18946b171b36da852e7470f84d13956a37fa4dcaae89c010d5d35.mp4 + +- BugFix for Messages being marked as read from Notifications. +- Text to speech for usernames and display names +- Removes some duplicated Boosts +- BugFix for feed not updating after change in follows. +- BugFix for some reposts not showing up in the feed. + +[Changes][v0.59.1] + + + +# [Release v0.58.3: Custom Reaction bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.58.3) - 2023-06-15 + +- BugFixes for the size of emojis on the Video feed. +- BugFixes for the alignment of emojis on the feed of some phones. +- BugFix for deleting a reaction and going back to the Red Heart image + +[Changes][v0.58.3] + + + +# [Release v0.58.2: Like always active Bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.58.2) - 2023-06-15 + + + +[Changes][v0.58.2] + + + +# [Release v0.58.1: Bug Fix for long reaction comments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.58.1) - 2023-06-15 + + + +[Changes][v0.58.1] + + + +# [Release v0.58.0: Custom reactions](https://github.com/vitorpamplona/amethyst/releases/tag/v0.58.0) - 2023-06-14 + +- Custom reactions +- Starts to preload objects before the feed is ready +- Simplifies URL Preview calls +- Hungarian translation updates by [@ZsZolee](https://github.com/ZsZolee) + +[Changes][v0.58.0] + + + +# [Release v0.57.0: Animations for loading posts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.57.0) - 2023-06-13 + +- Uses animateItemPlacement to show new Notes and update the size of current ones as they load +- Adds NIP-10 markers to kind 1s, fixing bug with thread view in other clients +- New Privacy Policy for F-droid +- Adds an option to opt-out from automatic spam and report filters by [@npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5](https://github.com/npub1w4uswmv6lu9yel005l3qgheysmr7tk9uvwluddznju3nuxalevvs2d0jr5) +- Adjusts the size and alignment of relay icons in the video feed +- Refactors some of the Zap Request,Response objects in the interface for performance +- BugFix for emtpy space in Notications when blocked posts are included. +- Updates kotlin dependencies +- Activates build cache + +[Changes][v0.57.0] + + + +# [Release v0.56.5: Support for NIP-14 (Subject Line)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.5) - 2023-06-11 + +- Basic Support for displaying NIP-14 on notes (Subject) +- BugFix for Video Uploads when the video is already compressed to the minimum +- Improves markdown support +- Fixing upstream library issue with images on markdown +- Refactors color objects to avoid recreating them on-demand + +[Changes][v0.56.5] + + + +# [Release v0.56.4: BugFix for a race condition when starting the app](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.4) - 2023-06-09 + + + +[Changes][v0.56.4] + + + +# [Release v0.56.3: Reconnecting after network drop](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.3) - 2023-06-09 + +- Adds a network listener to reconnect when connectivity comes back +- BugFix for duplicated push notifications +- Moves background color changes to IO Threads with Mutable State +- Breaks down the Note Composition stack further +- Fixes border/spacing issues between multiple note types +- Aligns Quick Actions to the center of the note. +- Improves the speed of the highlighter rendering +- Refactoring all shapes to the appropriate file + +[Changes][v0.56.3] + + + +# [Release v0.56.2: BugFixes and Adjustments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.2) - 2023-06-08 + +- Moves channel's sending message from the main thread to the IO thread +- Removes duplicated event-id protections from Notifications +- BugFix for notifications sometimes not reassembling when pressing the bottom button. +- Adds a second rule for short messages in the spam filter to avoid recognizing "@ bot, command" messages spam. +- Moves the creation of the VideoPlayer to its own composition +- Adds #onyx custom tag by [@TonyGiorgio](https://github.com/TonyGiorgio) +- Updates Hungarian translation by [@ZsZolee](https://github.com/ZsZolee) + +[Changes][v0.56.2] + + + +# [Release v0.56.1: Compressed Uploads](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.1) - 2023-06-08 + +- Adds Video Compression on upload +- Adds Image Compression on upload (GIFs not supported yet) +- Adds #weedsstr custom tag from Onyx/[@TonyGiorgio](https://github.com/TonyGiorgio) + +[Changes][v0.56.1] + + + +# [Release v0.56.0: Per-post reaction display](https://github.com/vitorpamplona/amethyst/releases/tag/v0.56.0) - 2023-06-07 + + + +[Changes][v0.56.0] + + + +# [Release v0.55.4: Support for Relay Set Event Type](https://github.com/vitorpamplona/amethyst/releases/tag/v0.55.4) - 2023-06-07 + + + +[Changes][v0.55.4] + + + +# [Release v0.55.3: Refactoring Messages Screen](https://github.com/vitorpamplona/amethyst/releases/tag/v0.55.3) - 2023-06-07 + + + +[Changes][v0.55.3] + + + +# [Release v0.55.2: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.55.2) - 2023-06-05 + + + +[Changes][v0.55.2] + + + +# [Release v0.55.1: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.55.1) - 2023-06-05 + + + +[Changes][v0.55.1] + + + +# [Release v0.55.0: NIP-89 App Recommendation Systems](https://github.com/vitorpamplona/amethyst/releases/tag/v0.55.0) - 2023-06-03 + +- Displays NIP-89 Notes in the feed +- Displays recommendations on profile +- Displays NIP-89-related notifications for your apps. +- BugFix: Making sure video does not restart when pressing the mute button +- BugFix: Keeping the position of the feed in navigation + +[Changes][v0.55.0] + + + +# [Release v0.54.2: More Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.54.2) - 2023-06-03 + +- Adds comment and amount of sats sent directly to the profile in Notifications +- Adds more caching capabilities in content parsing +- Restructures WordRenderer to help recompositions +- Improves performance of custom emojis +- Improves performance of DropDown menus +- Removing outdated version of the FlowRow +- Runs bottom's new notification refresher in the IO thread +- Only refreshes follow lists once per notification event +- Moves post's bounty calculations to the IO thread +- Moves profile DB watchers to their own compose functions +- Adds a new thread call for the notification of reaction rows +- Ignores unloaded notes in the MultiComposeSet renderer. +- Moves UserFeeds to ImmutableLists +- Moves reaction counts to a thread +- Moves channel checks to before a Channel object is loaded. + +[Changes][v0.54.2] + + + +# [Release v0.54.1: More Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.54.1) - 2023-06-01 + +[Fixes Translations bug by previous version](https://github.com/vitorpamplona/amethyst/commit/b0e50e0c00f6cfe7cc4da234675aee281192c1bd) +[Restructuring observables](https://github.com/vitorpamplona/amethyst/commit/92c61f317bef860c0ab2e80ed4f6fb9e0160378c) + +[Changes][v0.54.1] + + + +# [Release v0.54.0: More Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.54.0) - 2023-06-01 + +- [Add support for per-app languange preferences](https://github.com/vitorpamplona/amethyst/commit/a466f33b4e4f9fb420123ce2efb3da38026ab08d) by [@davotoula](https://github.com/davotoula) +- [Avoids notifying twice](https://github.com/vitorpamplona/amethyst/commit/1cc0f4bf80dc750bbace2b156fad2828982c938c) +- [Restructuring ViewModels](https://github.com/vitorpamplona/amethyst/commit/d942c126277d9737c4d67b75b6e341915ca83887) +- [Improves Poll Rendering speed.](https://github.com/vitorpamplona/amethyst/commit/3eb832c4e09cdfa9bd2d33bef74ad904e99f58f2) +- [Reducing recompositions on images.](https://github.com/vitorpamplona/amethyst/commit/6072e5977e8a0d9a95b53004f54ce8812dcfdda9) +- [Improves rendering performance of the ExoPlayer](https://github.com/vitorpamplona/amethyst/commit/91f34000f535230ae198747d90cbaaf2995ffc4c) + +[Changes][v0.54.0] + + + +# [Release v0.53.7: Zap, Reply, etc to Reports](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.7) - 2023-05-30 + + + +[Changes][v0.53.7] + + + +# [Release v0.53.6: Security Filter List bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.6) - 2023-05-30 + +[Sorting blocked users by name](https://github.com/vitorpamplona/amethyst/commit/030064e112ed9e5982bfd7b1e2f32c4943eaa634) +[BugFix for not loading the security filter screen](https://github.com/vitorpamplona/amethyst/commit/d9a392d2c1f3314e6d7ae277e7f4c09228e846ba) + +[Changes][v0.53.6] + + + +# [Release v0.53.5: Videos over Tor bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.5) - 2023-05-30 + +[Restart Video Cache when chancing Tor Setup](https://github.com/vitorpamplona/amethyst/commit/24a6d8a155159884c451638ba614e741643333d5) + +[Changes][v0.53.5] + + + +# [Release v0.53.4: Markdown bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.4) - 2023-05-30 + +- [Fixes bug with rendering of markdown with user citations.](https://github.com/vitorpamplona/amethyst/commit/6ea0972151b9237a4e15f7426b84d5c6f76b2836) +- [Improves rendering of Markdown summaries](https://github.com/vitorpamplona/amethyst/commit/f2db2b88c25595b3b47acdddc640f5d98ae089a1) + +[Changes][v0.53.4] + + + +# [Release v0.53.3: Video Player with Tor Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.3) - 2023-05-29 + +- [adds flavor to the version descriptor in the bottom left of the drawer](https://github.com/vitorpamplona/amethyst/commit/1972297755366bb94d29a2cc24b067756d6cab8e) +- [Moves ExoPlayer to OkHttp in order to enable Tor support.](https://github.com/vitorpamplona/amethyst/commit/ac006946907ef9bf13f8b005056384f7ad128b96) + +[Changes][v0.53.3] + + + +# [Release v0.53.2: Message Notification bubble bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.2) - 2023-05-29 + +- [Correcting the user's room for the notification marker](https://github.com/vitorpamplona/amethyst/commit/43d508ba3366e0f2c205dc6a7d7903496a0d4a36) + +[Changes][v0.53.2] + + + +# [Release v0.53.1: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.1) - 2023-05-29 + +[Filters Message Feed DAL to only take PrivateMessages in the Notification Bubble.](https://github.com/vitorpamplona/amethyst/commit/64f98e4b924e4fe99dee8d42270822ff3c1e19c0) +[Adding immutable tag to ResizeImage class](https://github.com/vitorpamplona/amethyst/commit/c58c20cc541ddd45b684c81d60ae0cbdea28d124) + +[Changes][v0.53.1] + + + +# [Release v0.53.0](https://github.com/vitorpamplona/amethyst/releases/tag/v0.53.0) - 2023-05-29 + +[Updated Persian Translations by @malimahda](https://github.com/vitorpamplona/amethyst/commit/83df639aff159da7b547d7030f72e6f915975b4a) [#430](https://github.com/vitorpamplona/amethyst/pull/430) +[Bugfix case sensitive nip05 by @davotoula ](https://github.com/vitorpamplona/amethyst/commit/0f6bf1cc59c409e880fc8ab831e94723e00a6e8e) [#428](https://github.com/vitorpamplona/amethyst/pull/428) +[Adds separate colors for the newItem background between light and dark themes](https://github.com/vitorpamplona/amethyst/commit/cb92a51191469ad2c480c9bb382cd3bcf1974a00) +[Adds Czech translations by @davotoula](https://github.com/vitorpamplona/amethyst/commit/213b172c32f7ddbf3bdaf2ba917ba14d706cbac0) [#431](https://github.com/vitorpamplona/amethyst/pull/431) +[Moves chatroom list to an additive filter](https://github.com/vitorpamplona/amethyst/commit/a5a3c62edd75bfb36085d1f6b88264455354f3ad) +[Avoids running through the entire filter when collection is Empty](https://github.com/vitorpamplona/amethyst/commit/02ad85a740172b61508e16521cf64acd4127feef) +[Adds mute control per track on the screen.](https://github.com/vitorpamplona/amethyst/commit/446273de80498b665e0d1fb58bb19c20b5a9fd12) +[Optimizing UserProfile status](https://github.com/vitorpamplona/amethyst/commit/b513877552f28b256bc01ba4d49b3768478a1d2a) +[Refreshing user status when added to the transient spam list](https://github.com/vitorpamplona/amethyst/commit/1a477ea1c89dadbf3b94533c7207c25549b6f238) +[Adds some documentation to make sure any NIP05 changes take into account that we are converting the entire json to lowercase.](https://github.com/vitorpamplona/amethyst/commit/f298cc6f13a79234e8fa4dd437636b253f57d207) +[Loading reply from launch and not withContent](https://github.com/vitorpamplona/amethyst/commit/6bc1b6b28ab2d20b77f9a823f1f00f7854757afe) + +[Changes][v0.53.0] + + + +# [Release v0.52.3: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.52.3) - 2023-05-28 + +[Moves all note states to leaf compositors](https://github.com/vitorpamplona/amethyst/commit/5e3703e849adcbf7c881db58a73de68680fd72ff) +[Better recomposition structure for ReactionsRow](https://github.com/vitorpamplona/amethyst/commit/acbd41ce61c8f5e7736c7346cf163139b06748f7) +[Performance Improvements when rendering a channel creation note](https://github.com/vitorpamplona/amethyst/commit/056d00b73b51b9cc467e3f06e15b6260d3b3ea32) + +[Changes][v0.52.3] + + + +# [Release v0.52.2: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.52.2) - 2023-05-27 + +- Sensitive content Hungarian translation by [@ZsZolee](https://github.com/ZsZolee) +- Trims relay urls + +[Changes][v0.52.2] + + + +# [Release v0.52.1](https://github.com/vitorpamplona/amethyst/releases/tag/v0.52.1) - 2023-05-27 + + + +[Changes][v0.52.1] + + + +# [Release v0.52.0 NIP-36 (Sensitive Content)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.52.0) - 2023-05-26 + + + +[Changes][v0.52.0] + + + +# [Release v0.51.4: Zap Amount contrast improvements in light mode](https://github.com/vitorpamplona/amethyst/releases/tag/v0.51.4) - 2023-05-26 + + + +[Changes][v0.51.4] + + + +# [Release v0.51.3: BugFix for changing lists not changing the feed](https://github.com/vitorpamplona/amethyst/releases/tag/v0.51.3) - 2023-05-26 + +Only changing stats for the Reaction Row if the data actually changed. +Improves rendering of messages in the Notification feed +Feed invalidation is necessary for lists +Simplifying Private message rendering scheme +Updates jsoup and activity compose to the latest versions + +[Changes][v0.51.3] + + + +# [Release v0.51.2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.51.2) - 2023-05-25 + +Changes the structure of the notification view to increase speed. +Preserves invalidations of DataSources for Home, Videos and Notificat… +Only removes scrollTop from Uri after 1 second and to avoid changing … +Activates invalidations that can be ignored if another invalidation i… +Only scrolls to the top if not at the top +Remembers formatting for the Notification Reaction Row +Updates Notification lists in intervals of 1 second. +Remember modifiers to avoid recomposition +Moves Home and Video screen invalidations to follow the scrollTop par… +Adds @ stable tag to Notification Card models +Remembering the size of the robohash picture +Removes logs +Removing the procedure to start connecting with relays before logging in. + +[Changes][v0.51.2] + + + +# [Release v0.51.1](https://github.com/vitorpamplona/amethyst/releases/tag/v0.51.1) - 2023-05-24 + + + +[Changes][v0.51.1] + + + +# [Release v0.51.0](https://github.com/vitorpamplona/amethyst/releases/tag/v0.51.0) - 2023-05-24 + + + +[Changes][v0.51.0] + + + +# [Release v0.50.6: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.6) - 2023-05-23 + +- [Adds Immutable and Stable annotations to avoid recomposing](https://github.com/vitorpamplona/amethyst/commit/8898e5d10bf7797a92e08a6ca98ad4a5e173ca44) +- [Improves the speed of updating Notification notes](https://github.com/vitorpamplona/amethyst/commit/15621f16a2e6f945c5aab7aa7b896190b89c6c0b) +- [Adds a cache layer for citations in Notes](https://github.com/vitorpamplona/amethyst/commit/a29d9ad433afccbd04f8b9c0c51234336135845e) +- [Fixes click on the Home to update the feed](https://github.com/vitorpamplona/amethyst/commit/d355f22938b765acefca8cfb8452f711e38071b1) +- [Fixes size for following symbol](https://github.com/vitorpamplona/amethyst/commit/2082c6cb28bab865edbde715faeb29c1f8e1ecbe) +- [Adds Better translations to unfollow in Portuguese](https://github.com/vitorpamplona/amethyst/commit/4b49cc1aab15322df67bf774f6073b056928fbe6) +- [Updates dependencies](https://github.com/vitorpamplona/amethyst/commit/a1da4affeb5ef65cee66b7b94d4bfc7fd24699e6) +- [Moves more variables to remember clauses](https://github.com/vitorpamplona/amethyst/commit/0bf94f316f6b21d4eb132e89e661036cccd715c2) + +[Changes][v0.50.6] + + + +# [Release v0.50.5](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.5) - 2023-05-22 + +- [Moves zapProgress to inside the IO update to make sure it only update…](https://github.com/vitorpamplona/amethyst/commit/6437a2106a8e0ac80322bc86f1d481de78e726e7) +- Stops recomposing the drawer at every new route. +- Adjusts bottombar to not recalculate hasNewItems in every recomposition. +- Moves default state of url previews to the remember function +- Remembering Background color and Text elements for posts. +- Optimizes MultiSetCompose rendering +- Optimizes recomposition of bottom items. +- Optimizes NIP-05 procedures +- Optimizes Drawer for Recomposition +- Removes the time log for Composing a note +- Only updates the refreshing state if it was refreshing. +- Deprecating IMGUR +- Updates relay UI on messages sent by the logged in user in chat +- Migrates notification summary to a new day without having to restart +- Apply fix to profile navigation of the same page by [@KotlinGeekDev](https://github.com/KotlinGeekDev) +- Adds hashtags and #[n] rendering to markdown +- Fixes NWC with Auth +- [Adds nostr: prefix to channel id share.](https://github.com/vitorpamplona/amethyst/commit/330f3503a6961ef1e5c0fcdf55e751f8a41ba810) + +[Changes][v0.50.5] + + + +# [Release v0.50.4](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.4) - 2023-05-17 + +[Bugfix for saving Replaceable notes in Bookmarks.](https://github.com/vitorpamplona/amethyst/commit/323e71c7cbbe27a1716f3c0a20d830866b3f1f02) +[Bugfix for channel metadata messages show up before channel creation](https://github.com/vitorpamplona/amethyst/commit/e41df98920764888199507378e35518eb1269d7e) + +[Changes][v0.50.4] + + + +# [Release v0.50.3 BugFixes and Updates](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.3) - 2023-05-17 + +[Replacing some missing Hungarian translation](https://github.com/vitorpamplona/amethyst/commit/c5176b8c4973be9b2527aadcbbe674c68b6f62b5) +[Add lowercase variant of hashtag when creating event.](https://github.com/vitorpamplona/amethyst/commit/d6c8651f0d46ed205e48788bd4e26daeaa2837dc) +[Fixes Auth for NIP-42 sporadic connections.](https://github.com/vitorpamplona/amethyst/commit/5040350be5ff659d0682f859741061c6e5a224b8) + +[Changes][v0.50.3] + + + +# [Release v0.50.2: Jumping chat post fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.2) - 2023-05-17 + +[Fixes jumping chat screens on hidden posts.](https://github.com/vitorpamplona/amethyst/commit/117446688b0f9d4045a216fad1feaa51c8142b7a) + +[Changes][v0.50.2] + + + +# [Release v0.50.1: Reaction Watch Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.1) - 2023-05-17 + +- UI and Performance improvements +- [Adds Navigation markers to the top panel and reaction watch](https://github.com/vitorpamplona/amethyst/commit/95a21cc08c161b138915c652d324402f404526af) +- BugFixes when switching accounts +- BugFix in the like count +- Better caching system for compiled stats + +[Changes][v0.50.1] + + + +# [Release v0.50.0: Reaction Watch](https://github.com/vitorpamplona/amethyst/releases/tag/v0.50.0) - 2023-05-17 + + + +[Changes][v0.50.0] + + + +# [Release v0.49.4: Colored relay icons](https://github.com/vitorpamplona/amethyst/releases/tag/v0.49.4) - 2023-05-16 + +- [Adds online search when typing the username in the new Post field.](https://github.com/vitorpamplona/amethyst/commit/5a3cf4040210aefd7217e301ad93c7953635f9cc) +- [Increasing size of the "More Options" button in the Video Feed.](https://github.com/vitorpamplona/amethyst/commit/1519e70b24691d127b85f2521dc02ce2016b61d6) +- [Optimizes the code for chat bubble rendering](https://github.com/vitorpamplona/amethyst/commit/135596591a48766d266869dda0a3e4718aade8eb) +- [Fixes Robohash dependency in size](https://github.com/vitorpamplona/amethyst/commit/389afcb6003e31e3c8c39d400d1f459ae8e5322a) +- [Adds color to relay icons](https://github.com/vitorpamplona/amethyst/commit/d6c29667925428e1816dc2e83ead705a458d55b8) +- [Avoiding creating a lnurl link with just those words](https://github.com/vitorpamplona/amethyst/commit/dd8b208a0d6227592f51f123ecb754030784dae5) + +[Changes][v0.49.4] + + + +# [Release v0.49.3: Search improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.49.3) - 2023-05-16 + +- [Improves rendering performance for chats.](https://github.com/vitorpamplona/amethyst/commit/3950517743aa396e9393cf98611708d1abe87c57) +- [Parsing NIP-19 on search to improve search results.](https://github.com/vitorpamplona/amethyst/commit/9e93a35ee7d16aed6b3c1d443d06cbe55a655695) +- [Making sure filters return similar orders when two posts are published by adding idHex as a sorting element](https://github.com/vitorpamplona/amethyst/commit/76df70c6f67880dd552c7671a3969686db83c1d3) + +[Changes][v0.49.3] + + + +# [Release v0.49.2: Custom Emoji for Chats](https://github.com/vitorpamplona/amethyst/releases/tag/v0.49.2) - 2023-05-16 + +[Fixing emoji's on chat handles](https://github.com/vitorpamplona/amethyst/commit/f2d87b78b1b882f048ceb3efde7d02e6d8a1b6e4) + +[Changes][v0.49.2] + + + +# [Release v0.49.1: Custom Emoji Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.49.1) - 2023-05-16 + +- [Better shade for Pins](https://github.com/vitorpamplona/amethyst/commit/d29e6b4d0be69b8a18f683998914cd2ffec14c2d) +- [Avoid color-filtering the emoji](https://github.com/vitorpamplona/amethyst/commit/14e670cd9a953aeedf7690ae88e7621a3bd0577d) +- [Adjustments to Markdown detection and rendering.](https://github.com/vitorpamplona/amethyst/commit/332490376b7ca459cbd6170b3b82613b6f6942aa) +- [BugFix for incorrect caching of NIP95](https://github.com/vitorpamplona/amethyst/commit/17fbf8c01f6d555ce2b57d3c15576016ed7c69aa) + +[Changes][v0.49.1] + + + +# [Release v0.49.0: Pinstr support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.49.0) - 2023-05-16 + + + +[Changes][v0.49.0] + + + +# [Release v0.48.0: NIP-30: Custom Emojis](https://github.com/vitorpamplona/amethyst/releases/tag/v0.48.0) - 2023-05-16 + +- Adds support for NIP-30 in Kind 0 (metadata) and Kind 1s (posts) +- Adds Swedish translations by [@Pextar](https://github.com/Pextar) +- Adds NIP-94 shareable link to filestr +- Adds zapstr.live and listr.lol as shareable links +- Adds a 5 minute expiration time for image loading errors +- Fixes NPE on opening the QuickAction on a "Post Not Found" event. + +[Changes][v0.48.0] + + + +# [Release v0.47.0: Support for Zapstr.live (Audio Tracks)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.47.0) - 2023-05-15 + + + +[Changes][v0.47.0] + + + +# [Release v0.46.6](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.6) - 2023-05-15 + + + +[Changes][v0.46.6] + + + +# [Release v0.46.5](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.5) - 2023-05-15 + + + +[Changes][v0.46.5] + + + +# [Release v0.46.4](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.4) - 2023-05-14 + + + +[Changes][v0.46.4] + + + +# [Release v0.46.3](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.3) - 2023-05-14 + +- [Avoids Notification duplicates](https://github.com/vitorpamplona/amethyst/commit/cf9395d5e3827df2b65eaf498a018a166bc91d79) +- [BugFix for non-english hashtags] by [@vitorpamplona](https://github.com/vitorpamplona) ([`d261003217`](https://github.com/vitorpamplona/amethyst/commit/d2610032172bb26083d61ae2b8a09378b001d565)) by [@vivganes](https://github.com/vivganes) + +[Changes][v0.46.3] + + + +# [Release v0.46.2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.2) - 2023-05-14 + +- Improvements to Poll Caching system (Fixes: [#406](https://github.com/vitorpamplona/amethyst/issues/406)) +- Performance Improvements to Follow Lists - Turn FollowList into a ViewModel +- Allows the RichTextViewer to render before resolving urls. +- BugFix: Protects against exceptions when creating keys with invalid bytearrays. +- BugFix: [Failing to load a video thumbnail](https://github.com/vitorpamplona/amethyst/commit/fc2408b526a4c74c6cbbace43b41774da36b0aaa) +- [French translation](https://github.com/vitorpamplona/amethyst/commit/672380653414520da6a9f2a87f8f9011408fe32b) by [@judemont](https://github.com/judemont) +- [TOR Hungarian translation](https://github.com/vitorpamplona/amethyst/commit/93c3a49ecf3e1952897c1891a35ef4ef65c1ed5f) by [@ZsZolee](https://github.com/ZsZolee) + +[Changes][v0.46.2] + + + +# [Release v0.46.1: Notify buttons on reply](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.1) - 2023-05-11 + +- Displays People Lists as Notes in the Feed +- Improves reply screen to clarify which users will be notified +- Adds action button to join channels/users in the chat screen +- Isolates state changes in the profile page, avoiding recomposition +- General Performance Improvements + +[Changes][v0.46.1] + + + +# [Release v0.46.0: Tor Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.46.0) - 2023-05-11 + +- Tor/Orbot support by [@greenart7c3](https://github.com/greenart7c3) +- Added Farsi translations by [@malimahda](https://github.com/malimahda) +- Updated Ukrainian and Russian translations by [@Radiokot](https://github.com/Radiokot) +- Updated Dutch translations by [@Bardesss](https://github.com/Bardesss) + +[Changes][v0.46.0] + + + +# [Release v0.45.1: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.45.1) - 2023-05-10 + +- [Fixing blank messages and Zapped DM content](https://github.com/vitorpamplona/amethyst/commit/c1d127ac1e251f37a72adec547f32692272ca977) +- [Don't try to decrypt if message is blank](https://github.com/vitorpamplona/amethyst/commit/434c1e9af324cbef64ea0a5c20e55e768c300219) +- [Capitalize notification sentence](https://github.com/vitorpamplona/amethyst/commit/0b2e5de7527384b4efef0d558269fdfdcb25f683) +- Performance Upgrades + +[Changes][v0.45.1] + + + +# [Release v0.45.0](https://github.com/vitorpamplona/amethyst/releases/tag/v0.45.0) - 2023-05-10 + + + +[Changes][v0.45.0] + + + +# [Release v0.44.0: Lists to Notifications](https://github.com/vitorpamplona/amethyst/releases/tag/v0.44.0) - 2023-05-08 + +- [Adding List Choice to Notifications](https://github.com/vitorpamplona/amethyst/commit/04c13003170f452839e2eee73cd364ea33805e0f) +- [Fixing tab sliders from jumping from one state to the other](https://github.com/vitorpamplona/amethyst/commit/4dcf38c492ca1c9ef541dccfe044552224c737cd) +- [Moving follows to the known list in DMs](https://github.com/vitorpamplona/amethyst/commit/81290f2b26b1487f55302a612ab8f0eccd200227) +- Performance upgrades + +[Changes][v0.44.0] + + + +# [Release v0.43.2: BugFix for NostrFiles.dev](https://github.com/vitorpamplona/amethyst/releases/tag/v0.43.2) - 2023-05-08 + + + +[Changes][v0.43.2] + + + +# [Release v0.43.1: NostrFiles.dev support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.43.1) - 2023-05-08 + + + +[Changes][v0.43.1] + + + +# [Release v0.43.0: Performance improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.43.0) - 2023-05-07 + + + +[Changes][v0.43.0] + + + +# [Release v0.42.5: Gradient removal](https://github.com/vitorpamplona/amethyst/releases/tag/v0.42.5) - 2023-05-05 + +- [Testing removing the gradient of quoted posts.](https://github.com/vitorpamplona/amethyst/commit/635279d59af22313d48a7d54509a9f66f5c04973) + +- [BugFix for displaying other people's list after loading them from the…](https://github.com/vitorpamplona/amethyst/commit/0c673e91c6dd8f5930015d20bb58ecb10da15b19) + +- [BugFix for the empty selection](https://github.com/vitorpamplona/amethyst/commit/3519e20a98d7c8191cf964a16a2310a774ea85ba) + +[Changes][v0.42.5] + + + +# [Release v0.42.4: BugFix: Private Zap decrypt without a Private Key](https://github.com/vitorpamplona/amethyst/releases/tag/v0.42.4) - 2023-05-05 + + + +[Changes][v0.42.4] + + + +# [Release v0.42.2: Bookmarks bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.42.2) - 2023-05-05 + + + +[Changes][v0.42.2] + + + +# [Release v0.42.1: BugFix for migration of Account lists](https://github.com/vitorpamplona/amethyst/releases/tag/v0.42.1) - 2023-05-05 + + + +[Changes][v0.42.1] + + + +# [Release v0.42.0: Private & Public Follow Lists](https://github.com/vitorpamplona/amethyst/releases/tag/v0.42.0) - 2023-05-05 + +- Private & Public Follow Lists in the top bar by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix for garden hashtag by [@believethehype](https://github.com/believethehype) + +[Changes][v0.42.0] + + + +# [Release v0.41.0: NFC, nostr.build, img proxy removal](https://github.com/vitorpamplona/amethyst/releases/tag/v0.41.0) - 2023-05-03 + +Amethyst 0.41.0 (alpha): NFC, Nostr.build uploader and Img Proxy removal test + +- Adds nostr.build uploader by [@believethehype](https://github.com/believethehype) +- Adds NFC support for NIP19 URIs by [@vitorpamplona](https://github.com/vitorpamplona) +- Updates Dutch translations by [@Bardesss](https://github.com/Bardesss) +- Removes image proxy for profiles (testing) by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix for tall images bleeding into other posts on Stories by [@vitorpamplona](https://github.com/vitorpamplona) + +Download: +- Play Edition with Translations: https://github.com/vitorpamplona/amethyst/releases/download/v0.41.0/amethyst-googleplay-universal-v0.41.0.apk +- F-Droid Edition without Translations: https://github.com/vitorpamplona/amethyst/releases/download/v0.41.0/amethyst-fdroid-universal-v0.41.0.apk + +[Changes][v0.41.0] + + + +# [Release v0.40.6 Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.6) - 2023-05-02 + +- BugFix to avoid blinking the url while loading images +- BugFix for drawing the border of the image without content +- BugFix on calculating the Zap amount without a Zap Event +- BugFix for video save to gallery tool +- BugFix videos of one page leaking to the next page + +[Changes][v0.40.6] + + + +# [Release v0.40.5: BugFix for volume controls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.5) - 2023-05-02 + + + +[Changes][v0.40.5] + + + +# [Release v0.40.4: MP3 Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.4) - 2023-05-02 + +Increases visibility of buttons in Stories. +Adds basic MP3 Support (regular, chats and stories) +Revamps search filters (it should be easier to find stuff now) +Adds dimensions to NIP-94,-95 Image files. + +[Changes][v0.40.4] + + + +# [Release v0.40.3:Adjustments and BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.3) - 2023-05-02 + +- BugFix for mixing NIP94 and NIP95 selections on the Video Feed +- BugFix for now showing the error message when the phone can't open the File +- Adds language to warn that NIP94 and 95 are new and other clients might not see it. +- Adds tamil translations + +[Changes][v0.40.3] + + + +# [Release v0.40.2: New Video Uploading and Playback](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.2) - 2023-05-01 + +- Adds "Seen on Relay" information for NIP-94 and 95 posts +- Adds custom video playback controls with autoplay starting on mute +- Adds video uploading progress UI +- Adds NIP-95 in-disk caching +- Adds Zap payment confirmations without the receiver having a Zap setup +- Animates to the top after posting in the Video feed +- Keeps position in the Video feed between screen +- Fixes the Crossfade for BlurHash on NIP94 and NIP95 events + +[Changes][v0.40.2] + + + +# [Release v0.40.1: BugFix for the Nostr Report](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.1) - 2023-05-01 + + + +[Changes][v0.40.1] + + + +# [Release v0.40.0: Global Video/Image Feed](https://github.com/vitorpamplona/amethyst/releases/tag/v0.40.0) - 2023-04-29 + + + +[Changes][v0.40.0] + + + +# [Release v0.38.0: Highlighter Events](https://github.com/vitorpamplona/amethyst/releases/tag/v0.38.0) - 2023-04-28 + +Adds support for Highlighter.com + +[Changes][v0.38.0] + + + +# [Release v0.37.4: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.37.4) - 2023-04-27 + +- [Adjusts size of the Zap Forward text.](https://github.com/vitorpamplona/amethyst/commit/f173f3194bedd4e6ab418f0acb04b057553d9dc9) +- [Avoids flickering in the Global Feed](https://github.com/vitorpamplona/amethyst/commit/8ca63f32f45e6b227b2a993eb92fe1115251acb6) + +[Changes][v0.37.4] + + + +# [Release v0.37.3: Trying to solve the random crash](https://github.com/vitorpamplona/amethyst/releases/tag/v0.37.3) - 2023-04-27 + +[Reverting compose to 1.4.2](https://github.com/vitorpamplona/amethyst/commit/1ae785061e81ec9c84c754e6d3af40a26c518fde) +[Add logs for fail to decrypt zap](https://github.com/vitorpamplona/amethyst/commit/ddba4ac5100691244f96aaac7798061580a87f55) +[Bugfix for clickable url](https://github.com/vitorpamplona/amethyst/commit/0fe6bd6c8372f58bebf238ec207479d5bb051e7b) +[Reducing the amount of filters to send to relays to 10](https://github.com/vitorpamplona/amethyst/commit/925289ae64b7921b07dca97e682f65170195c63d) + +[Changes][v0.37.3] + + + +# [Release v0.37.2: non-english hashtags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.37.2) - 2023-04-27 + +- Adds support for non-english hashtags by [@vivganes](https://github.com/vivganes) +- Improves translations of NIP-94/95 servers by [@vitorpamplona](https://github.com/vitorpamplona) +- Correctly copy-pastes NIP94 and NIP95 addresses by [@vitorpamplona](https://github.com/vitorpamplona) +- Updates dependencies by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.37.2] + + + +# [Release v0.37.1: Zap Forwarding](https://github.com/vitorpamplona/amethyst/releases/tag/v0.37.1) - 2023-04-27 + +- Adds Zap Address preference to the `zap` event tag +- Zaps note-tags before user info +- Enables raw URL uploads with warnings. +- Prunes NIP-95 data from memory when pausing the app. + + +[Changes][v0.37.1] + + + +# [Release v0.37.0: NIP-95 (Image upload to relays)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.37.0) - 2023-04-26 + +Adds popup to choose which image server to use by [@vitorpamplona](https://github.com/vitorpamplona) +Adds choice of NostrImg.com by [@vitorpamplona](https://github.com/vitorpamplona) +Adds choice of NIP-95 relays by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix for AUTH w/ Nostr.wine by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.37.0] + + + +# [Release v0.36.0: Support for private relays (NIP-42)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.36.0) - 2023-04-26 + +- Adds automatic authentication for private relays implementing NIP-42 by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.36.0] + + + +# [Release v0.35.1: Private Zaps on Polls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.35.1) - 2023-04-25 + +- Adds support for poll votes with Private Zaps by [@vitorpamplona](https://github.com/vitorpamplona) +- Marks all Zaps to be private by default by [@vitorpamplona](https://github.com/vitorpamplona) +- Activates gif preview and translations in Zap Messages by [@vitorpamplona](https://github.com/vitorpamplona) +- Improves the performance and UI of Private Zap notifications by [@vitorpamplona](https://github.com/vitorpamplona) +- Improves the performance of FileHeader loading by [@vitorpamplona](https://github.com/vitorpamplona) +- Opens image dialog in the page of the current selection by [@vitorpamplona](https://github.com/vitorpamplona) +- Improves configuration screen for Zap types (double click and click and hold) by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds Preview for quote noting by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds New Hungarian translations by [@ZsZolee](https://github.com/ZsZolee) +BugFix for NIP-47 scheme check by [@kiwiidb](https://github.com/kiwiidb) + +[Changes][v0.35.1] + + + +# [Release v0.35.0: Accessible Images/Videos](https://github.com/vitorpamplona/amethyst/releases/tag/v0.35.0) - 2023-04-25 + +Adds support for NIP-94 video and image descriptions for accessibility by [@vitorpamplona](https://github.com/vitorpamplona) +Adds confirmation screen before uploading an image/video by [@vitorpamplona](https://github.com/vitorpamplona) +Deprecates #[n]s tags creation by [@vitorpamplona](https://github.com/vitorpamplona) +Updates Wallet Connect API (JSON-RPC) by [@vitorpamplona](https://github.com/vitorpamplona) +Adds Private zaps notifications with messages by [@believethehype](https://github.com/believethehype) +Adds Basic Private Zap support by [@believethehype](https://github.com/believethehype) +Adds Content previews (any kind: images, videos, posts) on the new post screen by [@vitorpamplona](https://github.com/vitorpamplona) +Adds New custom hashtags for #grownostr and #footstr by [@believethehype](https://github.com/believethehype) +Adds Material You's adaptive icons by [@jltdhome](https://github.com/jltdhome) + +[Changes][v0.35.0] + + + +# [Release v0.34.1: BugFixes for Polls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.34.1) - 2023-04-21 + + + +[Changes][v0.34.1] + + + +# [Release v0.34.0: NIP-94 Support for Uploads](https://github.com/vitorpamplona/amethyst/releases/tag/v0.34.0) - 2023-04-21 + +- All uploads now create NIP-94 events. + +[Changes][v0.34.0] + + + +# [Release v0.33.2: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.33.2) - 2023-04-21 + +BugFix for [#359](https://github.com/vitorpamplona/amethyst/issues/359) +BugFix for [#361](https://github.com/vitorpamplona/amethyst/issues/361) by [@vivganes](https://github.com/vivganes) +Updated NL Translations by [@Bardesss](https://github.com/Bardesss) + + +[Changes][v0.33.2] + + + +# [Release v0.33.1: Notification dots on additive filters](https://github.com/vitorpamplona/amethyst/releases/tag/v0.33.1) - 2023-04-20 + + + +[Changes][v0.33.1] + + + +# [Release v0.33.0: Additive Filters](https://github.com/vitorpamplona/amethyst/releases/tag/v0.33.0) - 2023-04-20 + + + +[Changes][v0.33.0] + + + +# [Release v0.32.3: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.32.3) - 2023-04-07 + +You might see more items (quotes, invoices, reply information) being loaded on-demand, changing the view as it loads. Let me know if this isn't too annoying. + +[Changes][v0.32.3] + + + +# [Release v0.32.2: Create posts with LN Invoice](https://github.com/vitorpamplona/amethyst/releases/tag/v0.32.2) - 2023-04-06 + +- Adds Note preview in Chat and DMs +- Adds tagging for Notes and Users in Chats +- Adds LN invoice creation in new posts +- Adds notifications for profile zaps +- Adds private replies of DMs in Notifications + +[Changes][v0.32.2] + + + +# [Release v0.32.1: BugFixes for Polls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.32.1) - 2023-04-04 + +Adds payment animation to Polls by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes Voted option highlight by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes Poll Color for Light mode by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes margins when images are used in the poll by [@vitorpamplona](https://github.com/vitorpamplona) +Makes sure before and after voting the padding is the same by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.32.1] + + + +# [Release v0.32.0: Polls](https://github.com/vitorpamplona/amethyst/releases/tag/v0.32.0) - 2023-04-04 + +- Adds NIP 69 (Polls) support by [@npub1mgxvsg25hh6vazl5zl4295h6nx4xtjtvw7r86ejklnxmlrncrvvqdrffa5](https://github.com/npub1mgxvsg25hh6vazl5zl4295h6nx4xtjtvw7r86ejklnxmlrncrvvqdrffa5) +- Adds Show QR option to Profile screen by [@npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z](https://github.com/npub1gcxzte5zlkncx26j68ez60fzkvtkm9e0vrwdcvsjakxf9mu9qewqlfnj5z) + +[Changes][v0.32.0] + + + +# [Release v0.31.4: Login with QR](https://github.com/vitorpamplona/amethyst/releases/tag/v0.31.4) - 2023-04-03 + +- Login with QR by [@greenart7c3](https://github.com/greenart7c3) +- Adds full nip19 parsing on key decoding capabilities by [@vitorpamplona](https://github.com/vitorpamplona) +- Speeds up RichText rendering parsers by [@vitorpamplona](https://github.com/vitorpamplona) +- added message to LnZapEvent and interface by [@believethehype](https://github.com/believethehype) +- Faster processing of Contact List events by [@vitorpamplona](https://github.com/vitorpamplona) +- Faster user in follow list algo by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.31.4] + + + +# [Release v0.31.3: Adds post quotes to Notifications](https://github.com/vitorpamplona/amethyst/releases/tag/v0.31.3) - 2023-03-31 + + + +[Changes][v0.31.3] + + + +# [Release v0.31.2: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.31.2) - 2023-03-31 + +BugFixes: +- "author is elon" post with a regex taking over a second to parse. +- thread loading with children of the selected post not loading correctly. + +[Changes][v0.31.2] + + + +# [Release v0.31.0: Wallet Connect onboarding with Alby](https://github.com/vitorpamplona/amethyst/releases/tag/v0.31.0) - 2023-03-31 + +- Avoids reloading information when the app resumes by [@vitorpamplona](https://github.com/vitorpamplona) +- Full Wallet Connect onboarding with Alby by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds PoW Display to the MasterNote of a Thread by [@vitorpamplona](https://github.com/vitorpamplona) +- Changes the download folder to remove Amethyst's version by [@vitorpamplona](https://github.com/vitorpamplona) +- Activates public relays for chats by [@vitorpamplona](https://github.com/vitorpamplona) +- Saves the position of the Notification feed by [@vitorpamplona](https://github.com/vitorpamplona) +- Breaks notification cards in chunks of 50 notifications each by [@vitorpamplona](https://github.com/vitorpamplona) +- Custom Zaps Hungarian Translation by [@ZsZolee](https://github.com/ZsZolee) +- Fixes thread loading issue where the clicked note's children is not loaded by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix for some events not loading by [@vitorpamplona](https://github.com/vitorpamplona) +- Updates search results as new notes come in by [@vitorpamplona](https://github.com/vitorpamplona) +- Refactoring EOSEs to consider account switching in the app by [@vitorpamplona](https://github.com/vitorpamplona) +- Centers the loading icon for image previews by [@vitorpamplona](https://github.com/vitorpamplona) +- Dependency updates by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.31.0] + + + +# [Release v0.30.2: Custom Zap amounts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.30.2) - 2023-03-29 + +- Adds double-click to custom Zap amounts and messages by [@Believethehype](https://github.com/Believethehype) +- Adds image upload on profile editing page by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds PoW Display to notes by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds additional Hungarian Translation by [@ZsZolee](https://github.com/ZsZolee) +- More forgiving Wallet Connect interface by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds image url with loading icon when previews fail/take too long by [@vitorpamplona](https://github.com/vitorpamplona) +- Increases performance of the bottom navigation by [@vitorpamplona](https://github.com/vitorpamplona) +- Increases performance of relay icon rendering by [@vitorpamplona](https://github.com/vitorpamplona) +- Changes relay byte count to count all messages from relays, including errors by [@vitorpamplona](https://github.com/vitorpamplona) +- Makes the Scan QR Button available in smaller screens by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix: Long names/usernames in the Profile Page breaking the layout by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix: Stick reply setup from Gigi by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix: Sticky notifications on account change by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix: vertical position of the text in short messages with expandable content by [@vitorpamplona](https://github.com/vitorpamplona) +- BugFix for cutting links in half when they are the last word in a post by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.30.2] + + + +# [Release v0.30.1: Extra private key for Wallet Connect](https://github.com/vitorpamplona/amethyst/releases/tag/v0.30.1) - 2023-03-27 + +- Adds an extra secret to Zap Payments with Wallet Connect +- Adds a "Follow Back" button on user profiles by [@believethehype](https://github.com/believethehype) + +[Changes][v0.30.1] + + + +# [Release v0.30.0 EOSE and Invalidate Cache refactoring](https://github.com/vitorpamplona/amethyst/releases/tag/v0.30.0) - 2023-03-26 + +- Improves the use of EOSE events to avoid re-downloads +- Refactors invalidate cache to allow immediate and spaced-out screen updates +- Preloads URL Previews to avoid jittering when loading +- Remembers video playback functions to avoid jittering +- Fixes feed position when looking at a note and coming back +- Updated Chinese (Traditional) Translation by [@miseelu](https://github.com/miseelu) +- Refines the look to the Zap animation +- BugFix for nostr: clickable uris +- Videos now go full screen. + +[Changes][v0.30.0] + + + +# [Release v0.29.2 #SkullofSatoshi](https://github.com/vitorpamplona/amethyst/releases/tag/v0.29.2) - 2023-03-24 + +#SkullofSatoshi by [@believethehype](https://github.com/believethehype) + +[Changes][v0.29.2] + + + +# [Release v0.29.1 `R` Tags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.29.1) - 2023-03-24 + +Adds Support for `r` tags by [@vitorpamplona](https://github.com/vitorpamplona) +Adds support for lightning withdrawal links by [@lgleasain](https://github.com/lgleasain) +Adds missing pt-br translations by [@greenart7c3](https://github.com/greenart7c3) +Adds support for Translateable RichText on About Me by [@vitorpamplona](https://github.com/vitorpamplona) +Adds an image carousel to image dialog by [@vitorpamplona](https://github.com/vitorpamplona) +Adds Boosts to Profile Notes by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix for nostr: scheme translations by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix for unknown nevent1 post sending to profile by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix for pledged sats bolt light up by [@vitorpamplona](https://github.com/vitorpamplona) +Migrates per-relay stats from event counter to bytes transmitted by [@vitorpamplona](https://github.com/vitorpamplona) +Simplifes reply view on Notifications by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.29.1] + + + +# [Release v0.29.0: Bounties & Wallet Connect API](https://github.com/vitorpamplona/amethyst/releases/tag/v0.29.0) - 2023-03-23 + +- Support for Bounties by [@vitorpamplona](https://github.com/vitorpamplona) +- Support to Pledge in bounties by [@vitorpamplona](https://github.com/vitorpamplona) +- Support for video uploads by [@vitorpamplona](https://github.com/vitorpamplona) +- Support for Wallet Connect API by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds progress bars when Zapping by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds user's banner and profile picture to LongFormPosts if none is found by [@vitorpamplona](https://github.com/vitorpamplona) +- Displays all hashtags at the bottom of each event by [@vitorpamplona](https://github.com/vitorpamplona) +- Checks if the requested amount to matches the received LN Invoice's amount by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds 2 additional popular community hashtagicons by by [@Believethehype](https://github.com/Believethehype) + +[Changes][v0.29.0] + + + +# [Release v0.28.1: Bug Fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.28.1) - 2023-03-21 + + + +[Changes][v0.28.1] + + + +# [Release v0.28.0: Bookmarks](https://github.com/vitorpamplona/amethyst/releases/tag/v0.28.0) - 2023-03-20 + +NIP-51 Public and Private Bookmarks by [@vitorpamplona](https://github.com/vitorpamplona) +Adds Translations for Estonia by [@chiajlingvoj](https://github.com/chiajlingvoj) +Fixes URL guesser by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes zap amount recalculation by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes disappearing messages in chat by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes tag links that did not end with a space by [@vitorpamplona](https://github.com/vitorpamplona) +User-Agent fix [@hsoc](https://github.com/hsoc) +More custom hashtags by [@Believethehype](https://github.com/Believethehype) +Update on Russian and Ukrainian translations by [@radiokot](https://github.com/radiokot) + +[Changes][v0.28.0] + + + +# [Release v0.27.2: Custom hashtags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.27.2) - 2023-03-17 + +Makes hashtags case insensitive by [@vitorpamplona](https://github.com/vitorpamplona) +Adds special #Bitcoin hashtag icon by [@Believethehype](https://github.com/Believethehype) +Adds special #Nostr hashtag Icon by [@Believethehype](https://github.com/Believethehype) +Minor changes in Hungarian Translations by [@ZsZolee](https://github.com/ZsZolee) +Improves NIP-19 Parsing in content by [@vitorpamplona](https://github.com/vitorpamplona) +Disables online search after leaving the Search screen by [@vitorpamplona](https://github.com/vitorpamplona) +Fixes Background color of the badge's description [@vitorpamplona](https://github.com/vitorpamplona) +Fixes some missing messages on chat by [@vitorpamplona](https://github.com/vitorpamplona) + + +[Changes][v0.27.2] + + + +# [Release v0.27.1: Follow Hashtags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.27.1) - 2023-03-16 + + + +[Changes][v0.27.1] + + + +# [Release v0.27.0: Hashtags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.27.0) - 2023-03-15 + +- Adds Support for Hashtags by [@vitorpamplona](https://github.com/vitorpamplona) +- Shows LongForm Texts on Global by [@vitorpamplona](https://github.com/vitorpamplona) +- Prunes contact lists when pausing by [@vitorpamplona](https://github.com/vitorpamplona) +- Fixes the deletion of private messages by [@vitorpamplona](https://github.com/vitorpamplona) +- Shows url host in link previews by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds the Follow verification icon to the chat header by [@vitorpamplona](https://github.com/vitorpamplona) +- Performance Improments across the app by [@vitorpamplona](https://github.com/vitorpamplona) +- Avoids breaking urls and invoices when cutting an expandable content by [@vitorpamplona](https://github.com/vitorpamplona) +- Implements a faster Author Gallery for notifications by [@vitorpamplona](https://github.com/vitorpamplona) +- Reduces badge size in Profiles by [@vitorpamplona](https://github.com/vitorpamplona) +- Makes the Quick Action menu less starkey in dark theme by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds Block button and Dialog by [@maxmoney21m](https://github.com/maxmoney21m) +- Adds Report Dialog w/ Message by [@maxmoney21m](https://github.com/maxmoney21m) + + +[Changes][v0.27.0] + + + +# [Release v0.26.2: F-Droid Reproducible Build feature](https://github.com/vitorpamplona/amethyst/releases/tag/v0.26.2) - 2023-03-15 + + + +[Changes][v0.26.2] + + + +# [Release v0.26.1: BugFixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.26.1) - 2023-03-14 + +Fixes app crashing when a non-Hex value is found in Contact Lists +Fixes app crashing when a duplicated follow is found in Contact Lists + +[Changes][v0.26.1] + + + +# [Release v0.26.0: Performance Upgrades](https://github.com/vitorpamplona/amethyst/releases/tag/v0.26.0) - 2023-03-14 + +Restructuring User/Note index cache to use less memory, more cpu + +[Changes][v0.26.0] + + + +# [Release v0.25.3: De-Googled F-Droid Flavor](https://github.com/vitorpamplona/amethyst/releases/tag/v0.25.3) - 2023-03-14 + + + +[Changes][v0.25.3] + + + +# [Release v0.25.2: Image Upload in chats](https://github.com/vitorpamplona/amethyst/releases/tag/v0.25.2) - 2023-03-14 + +- Image Upload in Chat by [@believethehype](https://github.com/believethehype) and [@vitorpamplona](https://github.com/vitorpamplona) +- Bug fix for logging off crashing the app. by [@vitorpamplona](https://github.com/vitorpamplona) +- Bug fix to reset conversations tab when switching accounts. by [@maxmoney21m](https://github.com/maxmoney21m) +- Bug fix for the background color of the top bar in light mode by [@maxmoney21m](https://github.com/maxmoney21m) +- Updated Dutch translations by [@Bardesss](https://github.com/Bardesss) + +[Changes][v0.25.2] + + + +# [Release v0.25.1: Performance Upgrades](https://github.com/vitorpamplona/amethyst/releases/tag/v0.25.1) - 2023-03-14 + +- Faster Loading times for placeholders +- Reverted DropDown menu in chats +- Bug fix for the style of the Image Upload button before permissions are granted. + +[Changes][v0.25.1] + + + +# [Release v0.25.0: Multiple account management](https://github.com/vitorpamplona/amethyst/releases/tag/v0.25.0) - 2023-03-13 + +Adds user-agent header to OkHttpClient requests for NIP-05 Verifications by [@maxmoney21m](https://github.com/maxmoney21m) +Adds Multiple account management by [@maxmoney21m](https://github.com/maxmoney21m) +Replaces mlkit with zxing QR scanner by [@maxmoney21m](https://github.com/maxmoney21m) +Adds a way to remember feed positioning [@maxmoney21m](https://github.com/maxmoney21m) +Adds Robohash profile generation using SVGs by [@maxmoney21m](https://github.com/maxmoney21m) +Adds quick action menu in chats and threads by [@maxmoney21m](https://github.com/maxmoney21m) +Updated Dutch translations by [@matata2140](https://github.com/matata2140) and [@Bardesss](https://github.com/Bardesss) +Corrects identity claim for mastodon by [@h3y6e](https://github.com/h3y6e) +Corrects translation files by [@akiomik](https://github.com/akiomik) +Refactorings by [@Chemaclass](https://github.com/Chemaclass) and [@kappaseijin](https://github.com/kappaseijin) + +[Changes][v0.25.0] + + + +# [Release v0.24.2 NIP-39 support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.24.2) - 2023-03-10 + +NIP-39 Support by [@vitorpamplona](https://github.com/vitorpamplona) +Add Taiwanese translations by [@maxmoney21m](https://github.com/maxmoney21m) +BugFix: Scrollable Select screen by [@maxmoney21m](https://github.com/maxmoney21m) +Adds missing ES translations by [@Chemaclass](https://github.com/Chemaclass) +Adds missing Portuguese translations by [@greenart7c3](https://github.com/greenart7c3) +Shows private message notifications by [@vitorpamplona](https://github.com/vitorpamplona) +Upgrades encrypted storage by [@Chemaclass](https://github.com/Chemaclass) +Moves MarkAsRead write and read to IO context by [@vitorpamplona](https://github.com/vitorpamplona) +Moves Zap amount Calculations in cache and into an IO context by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix: Delays in updating UserProfile feeds by [@vitorpamplona](https://github.com/vitorpamplona) +Adds a Reporting menu option to badge notifications by [@vitorpamplona](https://github.com/vitorpamplona) +Uses full banner image sizes on User Profile pages and Drawer by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.24.2] + + + +# [Release v0.24.1: Translations and Share Post](https://github.com/vitorpamplona/amethyst/releases/tag/v0.24.1) - 2023-03-09 + +Adds Chinese (Traditional) Translation by [@miseelu](https://github.com/miseelu) +Adds Chinese (Simplified) Translation by [@miseelu](https://github.com/miseelu) +Adds Hungarian Translation by [@ZsZolee](https://github.com/ZsZolee) +Adds Turkish Translation by [@detherminal](https://github.com/detherminal) +Adds Share Post option with a Snort link by [@maxmoney21m](https://github.com/maxmoney21m) +Adds PubKey display in user profile by [@vitorpamplona](https://github.com/vitorpamplona) +Adds New QuickAction Menu (click and hold) by [@maxmoney21m](https://github.com/maxmoney21m) +Adds Lint enforcement and several code quality improvements by [@Chemaclass](https://github.com/Chemaclass) +Updated Russian and Ukrainian translations by [@Radiokot](https://github.com/Radiokot) +BugFix for Biometric support in older phones by [@maxmoney21m](https://github.com/maxmoney21m) +BugFix for LN invoices previews with under 350 chars by [@maxmoney21m](https://github.com/maxmoney21m) +BugFix for Badges not showing up in some profiles by [@vitorpamplona](https://github.com/vitorpamplona) +BugFix for Clickable addresses (naddr) and support for [@naddr](https://github.com/naddr) when writing a post by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.24.1] + + + +# [Release v0.24.0: Support for Badges (NIP-58)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.24.0) - 2023-03-05 + +Read only support for Badges (NIP-58) [@vitorpamplona](https://github.com/vitorpamplona) +Allow zooming on profile picture and banner [@maxmoney21m](https://github.com/maxmoney21m) +Refactor ui/dal Filters [@Chemaclass](https://github.com/Chemaclass) +Fixes showing the R.string.first id instead of text [@vitorpamplona](https://github.com/vitorpamplona) +Fixes result order in the search screen [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.24.0] + + + +# [Release v0.23.1: Bug Fix for Image Upload crash](https://github.com/vitorpamplona/amethyst/releases/tag/v0.23.1) - 2023-03-05 + + + +[Changes][v0.23.1] + + + +# [Release v0.23.0: Search NIP-50](https://github.com/vitorpamplona/amethyst/releases/tag/v0.23.0) - 2023-03-05 + +- Support for NIP-50: Search by [@vitorpamplona](https://github.com/vitorpamplona), thanks to [@brugeman](https://github.com/brugeman) and [@EvgenyPlaksin](https://github.com/EvgenyPlaksin) for the first draft on this feature +- "Mark all messages as Read" feature by [@maxmoney21m](https://github.com/maxmoney21m). Let's see [@derekross](https://github.com/derekross) approves the feature and bounty +- Refactoring by [@Chemaclass](https://github.com/Chemaclass) +- Small performance improvements by [@vitorpamplona](https://github.com/vitorpamplona) +- Require biometrics to export private keys by [@maxmoney21m](https://github.com/maxmoney21m) +- Support for relative paths on preview card's `OG:IMAGE` tags by [@vitorpamplona](https://github.com/vitorpamplona) +- Changes the navigation bar's magnifying glass icon to globe by [@maxmoney21m](https://github.com/maxmoney21m) +- French translation by [@bkBrunobk](https://github.com/bkBrunobk) +- Add Password Managers autofill support to the login screen by [@Radiokot](https://github.com/Radiokot) + +[Changes][v0.23.0] + + + +# [Release v0.22.3: BugFix for Snort's relay](https://github.com/vitorpamplona/amethyst/releases/tag/v0.22.3) - 2023-03-04 + +- Performance improvements by [@vitorpamplona](https://github.com/vitorpamplona) +- NIP19 Refactoring by [@Chemaclass](https://github.com/Chemaclass) +- Delete Origin Header as a bug fix of the bugfix for Snort's relay by [@vitorpamplona](https://github.com/vitorpamplona) +- RTL Improvements by [@rashedswen](https://github.com/rashedswen) + +[Changes][v0.22.3] + + + +# [Release v0.22.2: Backup Keys](https://github.com/vitorpamplona/amethyst/releases/tag/v0.22.2) - 2023-03-03 + +- Moves nsec backup to Drawer and Dialog, organize Drawer by [@maxmoney21m](https://github.com/maxmoney21m) +- Migrates underlying architecture to avoid using memory-inefficient ByteArrays to store Nostr Events by [@vitorpamplona](https://github.com/vitorpamplona) +- Adds Spanish translations by [@Chemaclass](https://github.com/Chemaclass) and [@JesusValera](https://github.com/JesusValera) +- Displays Group Info in the timeline for quotes of the Creation Event. by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.22.2] + + + +# [Release v0.22.1: Replaceable Events NIP-33](https://github.com/vitorpamplona/amethyst/releases/tag/v0.22.1) - 2023-03-03 + +- Adds a Follow Action in a Note's Menu by [@rashedswen](https://github.com/rashedswen) +- Support for Replaceable Events (NIP-33) by [@vitorpamplona](https://github.com/vitorpamplona) +- Add Ukrainian (uk) translation [@Radiokot](https://github.com/Radiokot) +- Add Russian (ru) translation by [@Radiokot](https://github.com/Radiokot) +- Fixes Preview Error when the url is invalid by [@vitorpamplona](https://github.com/vitorpamplona) +- Brazilian translations correction by [@marioaugustorama](https://github.com/marioaugustorama) + +[Changes][v0.22.1] + + + +# [Release v0.22.0: Markdown & Long Content (NIP-23)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.22.0) - 2023-03-02 + +Markdown Support by [@vitorpamplona](https://github.com/vitorpamplona) +Long-form Content (NIP-23) Support by [@vitorpamplona](https://github.com/vitorpamplona) + +[Changes][v0.22.0] + + + +# [Release v0.21.2: BugFix for Arabic](https://github.com/vitorpamplona/amethyst/releases/tag/v0.21.2) - 2023-03-01 + +- Hides hidden users from main feeds. +- Lowers the speed of the updates of the feed. +- Fix for a String.format on robohash crashing the app in Arabic + +[Changes][v0.21.2] + + + +# [Release v0.21.1](https://github.com/vitorpamplona/amethyst/releases/tag/v0.21.1) - 2023-03-01 + +Amethyst v0.21.1: Peace + +- Reply Notifications only show when: + 1. Reply directly cites the user in the reply note + 2. Reply to an event authored by the user +- Internationalization + 1. Arabic translations [@rashedswen](https://github.com/rashedswen) + 2. Portuguese-Brazil translations by [@greenart7c3](https://github.com/greenart7c3) +- Fixes the size of all pictures using the proxy to 200 +- Adds an Origin header to connect with Snort's relay. + + + +[Changes][v0.21.1] + + + +# [Release v0.20.5: PlayStore Re-submit](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.5) - 2023-03-01 + + + +[Changes][v0.20.5] + + + +# [Release v0.20.4: Updating Reports to the latest spec](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.4) - 2023-03-01 + + + +[Changes][v0.20.4] + + + +# [Release v0.20.3: Merge Notification Types](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.3) - 2023-02-28 + + + +[Changes][v0.20.3] + + + +# [Release v0.20.2: Conversations++](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.2) - 2023-02-27 + +Filtering Notifications to the events that cite the user directly (experimental). +Showing direct reply as a Quote. +Marks as read regardless of note.event status. +ThreadView avoids double loading. +Clearly marks the clicked item on ThreadView +Allows users to delete usernames +Adds nip05 to Chatroom headers. +Adds time of the boost and menu options for the boosted event. + +[Changes][v0.20.2] + + + +# [Release v0.20.1: BugFix for invalid NIP05 addresses crashing the app](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.1) - 2023-02-27 + +1. BugFix for invalid nip05 domain names crashing the app. +2. Removing _ from the display +3. Checks if NIP 05 is an email before starting to verify to avoid crashes. +4. BugFix for long NIP05 taking multiple lines. +5. Adds NIP05 to the main note in a thread + +[Changes][v0.20.1] + + + +# [Release v0.20.0: Nip05 Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.20.0) - 2023-02-27 + + + +[Changes][v0.20.0] + + + +# [Release v0.19.1: Crops reply information to 2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.19.1) - 2023-02-26 + +1. Crops Reply Information to 2, follows first, expandable to see others +2. Hides bottom navigation bar when keyboard is visible. + +[Changes][v0.19.1] + + + +# [Release v0.19.0: NIP-09 Event Deletion support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.19.0) - 2023-02-26 + +Event Deletion works with TextNotes, Likes, Boosts, and Reports. + +[Changes][v0.19.0] + + + +# [Release v0.18.3: Displaying Error messages when Zaps fail](https://github.com/vitorpamplona/amethyst/releases/tag/v0.18.3) - 2023-02-26 + +- Displaying Error messages when Zaps fail +- Animating the appearance of the reply note when replying in chats. + + +[Changes][v0.18.3] + + + +# [Release v0.18.2: Multiple Zaps per post](https://github.com/vitorpamplona/amethyst/releases/tag/v0.18.2) - 2023-02-25 + +- Improvements to ShowMore background gradient and size of bubbles in chat. +- Fixes Ugly Tab Background color in the light theme +- Removes the block on Multiple Zaps in a single post (copy paste from the like button, that has a block to avoid multiple likes) +- Fixes liveSet to delete. | Solves the outofsync error chat has been reporting. +- Synchronizes `Client.connect` to avoid random number in relay status +- Fixes the URL detector for account for 2 special characters in Chinese "," and "。" +- Reverts fixing the English language to avoid issues with translation +- Updating dependencies + + +[Changes][v0.18.2] + + + +# [Release v0.18.1: Know your spammers](https://github.com/vitorpamplona/amethyst/releases/tag/v0.18.1) - 2023-02-24 + +- New Relay Info UI displays the number of messages that were duplicated and deleted per relay. +- Improvements to Home feed update speed (75ms -> 10ms) +- Correctly deletes a slave note +- Updates observers when deleting notes +- Improved timing log +- Home doesn't need isAcceptable filter since all posts are coming from follows. Much faster. +- BugFix Loading one thread after another crashed the app +- Logs Spam count per relay. +- Removing PlayServices tag to import qrcode model +- Using language identification model bundled into the app +- Moving barcode scanning model to ship with the app. + +[Changes][v0.18.1] + + + +# [Release v0.18.0: Zaps, Replies and Likes in Public Chats and Private Messages](https://github.com/vitorpamplona/amethyst/releases/tag/v0.18.0) - 2023-02-24 + +Zaps in Private Messages are still public, though. + +- Zaps, Likes, and Replies in Public Chats and Private Messages +- Fixes bug when the note is not included in the returning set for ThreadView +- Fixing [#149](https://github.com/vitorpamplona/amethyst/issues/149) + +[Changes][v0.18.0] + + + +# [Release v0.17.11: Language Preferences](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.11) - 2023-02-24 + +Save translation preferences between each language pair +Displays App version in the drawer +Makes the Drawer's Name/Follower count clickable +Fixes Zap amount rounding error. + +[Changes][v0.17.11] + + + +# [Release v0.17.10: New Zap Amount Customization screen](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.10) - 2023-02-24 + +New Zap Amount Customization screen +ThreadView: Avoids changing the position of the list when the list updates. +Marking the selected post in the thread view +App Language fixed to English for now ([@Radiokot](https://github.com/Radiokot)) +Properly removes a note from the database on memory trimming +Uses a Name to make the translation layer skip ln addresses +Fixes Channel message deletion bug. + +[Changes][v0.17.10] + + + +# [Release v0.17.9: Blocks users from Reporting themselves](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.9) - 2023-02-22 + +Blocks users from Reporting themselves +Fixes missing Relay Information in Profile Pages +Adds LnZapRequest to the event observer as well to download authors. +Puts Follow and Unfollow Buttons into coroutines. +Makes sure people are only added to the hidden list if 5 or more different Nostr events have the same message. +Fixing remaining Follow/Unfollow issue with an outdated Account object. + +[Changes][v0.17.9] + + + +# [Release v0.17.8: BugFix Translations breaking URLs/Images/Tags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.8) - 2023-02-22 + + + +[Changes][v0.17.8] + + + +# [Release v0.17.7: BugFix for Invalid Hexes in Tags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.7) - 2023-02-22 + + + +[Changes][v0.17.7] + + + +# [Release v0.17.6: BugFix for Alternating Follow/Unfollow](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.6) - 2023-02-22 + + + +[Changes][v0.17.6] + + + +# [Release v0.17.5: 0 Follows no more.](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.5) - 2023-02-21 + +- Fixes issue with overriding follow list to zero (maintains a local copy. It might still override to a previous version) +- Fixes Notification Dot for Zaps +- Faster notification updates +- Refactoring the saving of user preferences +- More caching to increase speed of updating lists +- Potentially fixing Notifications crash on Samsungs + +[Changes][v0.17.5] + + + +# [Release v0.17.4: 5 Strike anti-spam](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.4) - 2023-02-21 + +- Anti-spam filter requires 5 duplicated msgs to temporarily block +- Forces conversion to npub in notes to make sure the Hex key is correct. + +[Changes][v0.17.4] + + + +# [Release v0.17.3: Check Hex keys in Event Tags](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.3) - 2023-02-21 + + + +[Changes][v0.17.3] + + + +# [Release v0.17.2: Quote Note Popup and Rendering](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.2) - 2023-02-20 + +https://nostr.build/i/nostr.build_0cd188713619b44b8f9c214617130db7f11c427dcdc03872fac736d74a594b5a.png + +- Popup to Boost/Quote Notes +- Rendering Notes instead of just presenting the Note ID +- Fixes Movement of the post when Show More is pressed +- Notification Background is now opens note +- Changes keyboard layout to Decimal in Zap amount Setup +- Fixes erasing edited Zap amounts on recomposing +- Resets mentions after writing a reply utxo +- Fixes the "Show Anyway" button in the first element of the threadview. + +[Changes][v0.17.2] + + + +# [Release v0.17.1: Custom Zap Amounts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.1) - 2023-02-20 + + + +[Changes][v0.17.1] + + + +# [Release v0.17.0: Anti-spam de-dup filters](https://github.com/vitorpamplona/amethyst/releases/tag/v0.17.0) - 2023-02-19 + +v0.17.0: Anti-spam filters +- Filters out the duplicated-message type of Spam +- Fixes Reply not showing up in the Thread View after user Posts a new one +- Adds Reports Tab to Profile Page +- Significantly improves the speed of the Follower calculation +- Decreased User/Note object size -> 4x more objects can fit in memory. +- Prunes memory to 1000 messages per public channel +- Improves the speed of rendering long threads and thread level calculation +- Fixes Quoted Post appearing as a Reply +- Fixes Mutex state when Android kills threads. +- Refactors current filter classes into Relay filters and Screen filters +- Moves Notification Dot calculation to background threads. +- Loads new Posts on the Thread view on the fly + +[Changes][v0.17.0] + + + +# [Release v0.16.2](https://github.com/vitorpamplona/amethyst/releases/tag/v0.16.2) - 2023-02-17 + + + +[Changes][v0.16.2] + + + +# [Release v0.16.1: BugFix Release](https://github.com/vitorpamplona/amethyst/releases/tag/v0.16.1) - 2023-02-17 + +1. Fixes the Relay List going back to defaults if the user hasn't setup their relay sets. +2. Fixes crashes from ChannelCreateEvent and ChannelMetadataEvent when the content is not a JSON structure. +3. Removes duplicated Report filters to relays. + +[Changes][v0.16.1] + + + +# [Release v0.16.0: Image Proxy Resizer + CDN](https://github.com/vitorpamplona/amethyst/releases/tag/v0.16.0) - 2023-02-15 + + + +[Changes][v0.16.0] + + + +# [Release v0.15.9: Profile Delay Fix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.9) - 2023-02-15 + + + +[Changes][v0.15.9] + + + +# [Release v0.15.8: Follower Count BugFix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.8) - 2023-02-15 + + + +[Changes][v0.15.8] + + + +# [Release v0.15.7: Performance Adjustments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.7) - 2023-02-14 + + + +[Changes][v0.15.7] + + + +# [Release v0.15.6: Performance Adjustments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.6) - 2023-02-14 + + + +[Changes][v0.15.6] + + + +# [Release v0.15.5: Performance Adjustments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.5) - 2023-02-14 + + + +[Changes][v0.15.5] + + + +# [Release v0.15.4: Performance Adjustments](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.4) - 2023-02-14 + + + +[Changes][v0.15.4] + + + +# [Release v0.15.3: NewPost adjusts to keyboard in long posts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.3) - 2023-02-13 + + + +[Changes][v0.15.3] + + + +# [Release v0.15.2: Image Uploading Feedback](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.2) - 2023-02-13 + +Image Uploading Feedback by [@Radiokot](https://github.com/Radiokot) +Performance Updates +Quick Fix for keeping the Edit Text with the available screen size in case of long posts. + +[Changes][v0.15.2] + + + +# [Release v0.15.1: Zaps](https://github.com/vitorpamplona/amethyst/releases/tag/v0.15.1) - 2023-02-13 + + + +[Changes][v0.15.1] + + + +# [Release v0.14.3: Deactivates Proguard](https://github.com/vitorpamplona/amethyst/releases/tag/v0.14.3) - 2023-02-10 + + + +[Changes][v0.14.3] + + + +# [Release v0.14.2: Activates Proguard / Fixes Image Upload](https://github.com/vitorpamplona/amethyst/releases/tag/v0.14.2) - 2023-02-10 + +1. Fixes Image Upload Permissions for some phones +2. Allows unsecured (`ws://`) relay additions for Umbrel users. +3. Allows the user to leave and join their own groups +4. Fixes bad URI on Users Profile crashing the app +5. Fixes QR Code display and Scan for smaller screens. +6. Fixes a translation not showing up in old phones (dependency issue) +7. Activates ProGuard to minimize code automatically (random bugs expected) +8. Improved Relay-based user search performance. + +[Changes][v0.14.2] + + + +# [Release v0.14.1: Save Images / LNURL edit](https://github.com/vitorpamplona/amethyst/releases/tag/v0.14.1) - 2023-02-09 + +- Save image by [Oleg Koretsky](https://github.com/Radiokot) +- LNURL edit in the profile +- Bugfix crashing the Lightning Tips with nonnumeric values in the amount. + +[Changes][v0.14.1] + + + +# [Release v0.14.0: Lightning Tips](https://github.com/vitorpamplona/amethyst/releases/tag/v0.14.0) - 2023-02-08 + + + +[Changes][v0.14.0] + + + +# [Release v0.13.3: Auto-translation options](https://github.com/vitorpamplona/amethyst/releases/tag/v0.13.3) - 2023-02-08 + + + +[Changes][v0.13.3] + + + +# [Release v0.13.2: Tracks and Displays Relay Info per Event](https://github.com/vitorpamplona/amethyst/releases/tag/v0.13.2) - 2023-02-07 + +Amethyst v0.13.2: Tracks and Displays Relay Info per Event + +1. Users can now see which relays are sending posts, DMs, and public chat messages. This uses the relay's website favicon. Please update your favicons to something relevant to users :) + +2. Changes the default relay set to Paid relays for Chats and Global, making spam less impactful for new users. + +3. Timeline posts are cropped at 350 chars with Show More to expand + +4. Full Profile Pages by Oleg Koretsky + +5. Search improvements by Habib Okanla + +6. Devs can now have 2 Amethysts running by greenart7c3 + +7. Removes the trailing / on relay's setup by middlingphys + +[Changes][v0.13.2] + + + +# [Release v0.13.1: Relay Sets (home, dm, chat, global)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.13.1) - 2023-02-06 + + + +[Changes][v0.13.1] + + + +# [Release v0.13.0: Auto-translate](https://github.com/vitorpamplona/amethyst/releases/tag/v0.13.0) - 2023-02-05 + + + +[Changes][v0.13.0] + + + +# [Release v0.12.1: More Performance!](https://github.com/vitorpamplona/amethyst/releases/tag/v0.12.1) - 2023-02-03 + + + +[Changes][v0.12.1] + + + +# [Release v0.12.0: Performance Upgrades](https://github.com/vitorpamplona/amethyst/releases/tag/v0.12.0) - 2023-02-03 + + + +[Changes][v0.12.0] + + + +# [Release v0.11.7: Relay List View](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.7) - 2023-01-31 + +Relay list view in profile, clickable nostr: elements, and several small improvements across the board. + +[Changes][v0.11.7] + + + +# [Release v0.11.6: Bugfix: Invalid URIs in the Relay list crashing the app](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.6) - 2023-01-30 + + + +[Changes][v0.11.6] + + + +# [Release v0.11.5: NIP 56 Support](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.5) - 2023-01-30 + + + +[Changes][v0.11.5] + + + +# [Release v0.11.4: User QR Code Display & Scan (any NIP21 works)](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.4) - 2023-01-29 + + + +[Changes][v0.11.4] + + + +# [Release v0.11.3: Hide User on Profile page](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.3) - 2023-01-28 + + + +[Changes][v0.11.3] + + + +# [Release v0.11.2: Search includes Public Chats and Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.2) - 2023-01-28 + + + +[Changes][v0.11.2] + + + +# [Release v0.11.1: Accept Terms Login Checkbox](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.1) - 2023-01-27 + + + +[Changes][v0.11.1] + + + +# [Release v0.11.0: Notification Bubbles and Verified Follows](https://github.com/vitorpamplona/amethyst/releases/tag/v0.11.0) - 2023-01-27 + + + +[Changes][v0.11.0] + + + +# [Release v0.10.7](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.7) - 2023-01-26 + + + +[Changes][v0.10.7] + + + +# [Release v0.10.6: Relay List BugFix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.6) - 2023-01-26 + +Fixes: +- Multiple like events +- Relay List loading issue +- Case Sensitive Search box +- Proper RTL ([@KotlinGeekDev](https://github.com/KotlinGeekDev)) +- Proper Navigation in the Thread Views ([@KotlinGeekDev](https://github.com/KotlinGeekDev)) + +[Changes][v0.10.6] + + + +# [Release v0.10.5: BugFix Release](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.5) - 2023-01-25 + + + +[Changes][v0.10.5] + + + +# [Release v0.10.4: NIP-21 and Split home feeds](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.4) - 2023-01-25 + +Support for [NIP-21](https://github.com/nostr-protocol/nips/blob/urlscheme/21.md), split home screen feed between Follows and Follows + Replies and some improvements in Chatroom navigation and Network use. + +[Changes][v0.10.4] + + + +# [Release v0.10.3: Block Users, Report Posts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.3) - 2023-01-24 + + + +[Changes][v0.10.3] + + + +# [Release v0.10.2: BugFix for certain RelayList payloads](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.2) - 2023-01-24 + + + +[Changes][v0.10.2] + + + +# [Release v0.10.1: Version Code bugfix](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.1) - 2023-01-23 + + + +[Changes][v0.10.1] + + + +# [Release v0.10.0: Relay List View/Edit](https://github.com/vitorpamplona/amethyst/releases/tag/v0.10.0) - 2023-01-23 + + + +[Changes][v0.10.0] + + + +# [Release v0.9.6: Unique View Counts](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.6) - 2023-01-22 + + + +[Changes][v0.9.6] + + + +# [Release v0.9.5: Spam Filter for Private Messages](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.5) - 2023-01-21 + +- Spam Filter for Private Messages +- Improvements in Image Caching +- Improvements in Navigation + +[Changes][v0.9.5] + + + +# [Release v0.9.4: Bug Fix Release](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.4) - 2023-01-21 + +Fixes Image Profile Loading + +[Changes][v0.9.4] + + + +# [Release v0.9.3: Profile Edits](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.3) - 2023-01-21 + +- Profile Edit +- Navigation Improvements (Back Button) by https://github.com/KotlinGeekDev +- ~75% smaller apk size by https://github.com/KotlinGeekDev + +[Changes][v0.9.3] + + + +# [Release v0.9.2: Bug Fix Release](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.2) - 2023-01-20 + +fixes a user tagging bug and a like count bug (turns out relays don't do hex id crop in tag search) + +[Changes][v0.9.2] + + + +# [Release v0.9.1: Quote Reply in Chat + small fixes](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9.1) - 2023-01-19 + + + +[Changes][v0.9.1] + + + +# [Release v0.9: Public Chat Management](https://github.com/vitorpamplona/amethyst/releases/tag/v0.9) - 2023-01-19 + +Demo: https://nostr.build/i/6112.gif + + +[Changes][v0.9] + + + +# [Release v0.8.2: Performance Improvements and Searchbar](https://github.com/vitorpamplona/amethyst/releases/tag/v0.8.2) - 2023-01-18 + + + +[Changes][v0.8.2] + + + +# [Release v0.8.1: Performance Improvements](https://github.com/vitorpamplona/amethyst/releases/tag/v0.8.1) - 2023-01-18 + + + +[Changes][v0.8.1] + + + +# [Release v0.8: User Tags / New Logo](https://github.com/vitorpamplona/amethyst/releases/tag/v0.8) - 2023-01-18 + +- New Logo +- User/Search tagging on composing +- Thread safe improvements + + +[Changes][v0.8] + + + +# [Release v0.7: Public Chats](https://github.com/vitorpamplona/amethyst/releases/tag/v0.7) - 2023-01-16 + +Support for: +- Anigma's Public Chat (NIP-28) +- Gifs and SVG Images. +- User Tags on Posts. + + +[Changes][v0.7] + + + +# [Release v0.6: User Profiles](https://github.com/vitorpamplona/amethyst/releases/tag/v0.6) - 2023-01-16 + +Demo: https://i.imgur.com/Kdvl78r.jpg + +Support for: +- User Profiles +- Follow/Unfollow +- Start Message +- List of Followers and Follows +- User banner + +[Changes][v0.6] + + + +# [Release v0.5: Private Messages](https://github.com/vitorpamplona/amethyst/releases/tag/v0.5) - 2023-01-14 + +Demo: https://i.imgur.com/f5vptAv.mp4 + +Amethyst 0.5: +- Adds support for Private Messages +- Removes autoplay from videos (have to figure out how to mute first) +- Click on Image to Zoom +- Blocks double likes + +[Changes][v0.5] + + + +# [Release v0.4: LnInvoices](https://github.com/vitorpamplona/amethyst/releases/tag/v0.4) - 2023-01-13 + +- Lightning Invoice cards +- Url Preview Caching +- Long press to copy Text/NoteID/UserID + +[Changes][v0.4] + + + +# [Release v0.3: Video/Image/Url Previews](https://github.com/vitorpamplona/amethyst/releases/tag/v0.3) - 2023-01-13 + +- Video playback in the timeline +- Direct image upload +- Image and URL previews when writing new posts + +[Changes][v0.3] + + + +# [Release v0.2: Thread View](https://github.com/vitorpamplona/amethyst/releases/tag/v0.2) - 2023-01-12 + +- Post and Thread Views + +[Changes][v0.2] + + + +# [Release v0.1: Basic Social App](https://github.com/vitorpamplona/amethyst/releases/tag/v0.1) - 2023-01-11 + +First public version with: +- Account Management +- Home Feed +- Notifications Feed +- Global Feed +- Reactions (like, boost, reply) +- Image Preview +- Url Preview + +[Changes][v0.1] + + +[v1.03.0]: https://github.com/vitorpamplona/amethyst/compare/v1.02.1...v1.03.0 +[v1.02.1]: https://github.com/vitorpamplona/amethyst/compare/v1.02.0...v1.02.1 +[v1.02.0]: https://github.com/vitorpamplona/amethyst/compare/v1.01.0...v1.02.0 +[v1.01.0]: https://github.com/vitorpamplona/amethyst/compare/v1.00.5...v1.01.0 +[v1.00.5]: https://github.com/vitorpamplona/amethyst/compare/v1.00.4...v1.00.5 +[v1.00.4]: https://github.com/vitorpamplona/amethyst/compare/v1.00.3...v1.00.4 +[v1.00.3]: https://github.com/vitorpamplona/amethyst/compare/v1.00.2...v1.00.3 +[v1.00.2]: https://github.com/vitorpamplona/amethyst/compare/v1.00.1...v1.00.2 +[v1.00.1]: https://github.com/vitorpamplona/amethyst/compare/v1.00.0...v1.00.1 +[v1.00.0]: https://github.com/vitorpamplona/amethyst/compare/v0.94.3...v1.00.0 +[v0.94.3]: https://github.com/vitorpamplona/amethyst/compare/v0.94.2...v0.94.3 +[v0.94.2]: https://github.com/vitorpamplona/amethyst/compare/v0.94.1...v0.94.2 +[v0.94.1]: https://github.com/vitorpamplona/amethyst/compare/v0.94.0...v0.94.1 +[v0.94.0]: https://github.com/vitorpamplona/amethyst/compare/v0.93.1...v0.94.0 +[v0.93.1]: https://github.com/vitorpamplona/amethyst/compare/v0.93.0...v0.93.1 +[v0.93.0]: https://github.com/vitorpamplona/amethyst/compare/v0.92.7...v0.93.0 +[v0.92.7]: https://github.com/vitorpamplona/amethyst/compare/v0.92.6...v0.92.7 +[v0.92.6]: https://github.com/vitorpamplona/amethyst/compare/v0.92.5...v0.92.6 +[v0.92.5]: https://github.com/vitorpamplona/amethyst/compare/v0.92.4...v0.92.5 +[v0.92.4]: https://github.com/vitorpamplona/amethyst/compare/v0.92.3...v0.92.4 +[v0.92.3]: https://github.com/vitorpamplona/amethyst/compare/v0.92.2...v0.92.3 +[v0.92.2]: https://github.com/vitorpamplona/amethyst/compare/v0.92.1...v0.92.2 +[v0.92.1]: https://github.com/vitorpamplona/amethyst/compare/v0.92.0...v0.92.1 +[v0.92.0]: https://github.com/vitorpamplona/amethyst/compare/v0.91.0...v0.92.0 +[v0.91.0]: https://github.com/vitorpamplona/amethyst/compare/v0.90.6...v0.91.0 +[v0.90.6]: https://github.com/vitorpamplona/amethyst/compare/v0.90.5...v0.90.6 +[v0.90.5]: https://github.com/vitorpamplona/amethyst/compare/v0.90.4...v0.90.5 +[v0.90.4]: https://github.com/vitorpamplona/amethyst/compare/v0.90.3...v0.90.4 +[v0.90.3]: https://github.com/vitorpamplona/amethyst/compare/v0.90.2...v0.90.3 +[v0.90.2]: https://github.com/vitorpamplona/amethyst/compare/v0.90.1...v0.90.2 +[v0.90.1]: https://github.com/vitorpamplona/amethyst/compare/v0.90.0...v0.90.1 +[v0.90.0]: https://github.com/vitorpamplona/amethyst/compare/v0.89.10...v0.90.0 +[v0.89.10]: https://github.com/vitorpamplona/amethyst/compare/v0.89.9...v0.89.10 +[v0.89.9]: https://github.com/vitorpamplona/amethyst/compare/v0.89.8...v0.89.9 +[v0.89.8]: https://github.com/vitorpamplona/amethyst/compare/v0.89.7...v0.89.8 +[v0.89.7]: https://github.com/vitorpamplona/amethyst/compare/v0.89.6...v0.89.7 +[v0.89.6]: https://github.com/vitorpamplona/amethyst/compare/v0.89.5...v0.89.6 +[v0.89.5]: https://github.com/vitorpamplona/amethyst/compare/v0.89.4...v0.89.5 +[v0.89.4]: https://github.com/vitorpamplona/amethyst/compare/v0.89.2...v0.89.4 +[v0.89.2]: https://github.com/vitorpamplona/amethyst/compare/v0.89.1...v0.89.2 +[v0.89.1]: https://github.com/vitorpamplona/amethyst/compare/v0.89.0...v0.89.1 +[v0.89.0]: https://github.com/vitorpamplona/amethyst/compare/v0.88.7...v0.89.0 +[v0.88.7]: https://github.com/vitorpamplona/amethyst/compare/v0.88.6...v0.88.7 +[v0.88.6]: https://github.com/vitorpamplona/amethyst/compare/v0.88.5...v0.88.6 +[v0.88.5]: https://github.com/vitorpamplona/amethyst/compare/v0.88.4...v0.88.5 +[v0.88.4]: https://github.com/vitorpamplona/amethyst/compare/v0.88.3...v0.88.4 +[v0.88.3]: https://github.com/vitorpamplona/amethyst/compare/v0.88.2...v0.88.3 +[v0.88.2]: https://github.com/vitorpamplona/amethyst/compare/v0.88.1...v0.88.2 +[v0.88.1]: https://github.com/vitorpamplona/amethyst/compare/v0.88.0...v0.88.1 +[v0.88.0]: https://github.com/vitorpamplona/amethyst/compare/v0.87.7...v0.88.0 +[v0.87.7]: https://github.com/vitorpamplona/amethyst/compare/v0.87.6...v0.87.7 +[v0.87.6]: https://github.com/vitorpamplona/amethyst/compare/v0.87.5...v0.87.6 +[v0.87.5]: https://github.com/vitorpamplona/amethyst/compare/v0.87.4...v0.87.5 +[v0.87.4]: https://github.com/vitorpamplona/amethyst/compare/v0.87.3...v0.87.4 +[v0.87.3]: https://github.com/vitorpamplona/amethyst/compare/v0.87.2...v0.87.3 +[v0.87.2]: https://github.com/vitorpamplona/amethyst/compare/v0.87.1...v0.87.2 +[v0.87.1]: https://github.com/vitorpamplona/amethyst/compare/v0.87.0...v0.87.1 +[v0.87.0]: https://github.com/vitorpamplona/amethyst/compare/v0.86.5...v0.87.0 +[v0.86.5]: https://github.com/vitorpamplona/amethyst/compare/v0.86.4...v0.86.5 +[v0.86.4]: https://github.com/vitorpamplona/amethyst/compare/v0.86.3...v0.86.4 +[v0.86.3]: https://github.com/vitorpamplona/amethyst/compare/v0.86.2...v0.86.3 +[v0.86.2]: https://github.com/vitorpamplona/amethyst/compare/v0.86.1...v0.86.2 +[v0.86.1]: https://github.com/vitorpamplona/amethyst/compare/v0.86.0...v0.86.1 +[v0.86.0]: https://github.com/vitorpamplona/amethyst/compare/v0.85.3...v0.86.0 +[v0.85.3]: https://github.com/vitorpamplona/amethyst/compare/v0.85.1...v0.85.3 +[v0.85.1]: https://github.com/vitorpamplona/amethyst/compare/v0.85.0...v0.85.1 +[v0.85.0]: https://github.com/vitorpamplona/amethyst/compare/v0.84.3...v0.85.0 +[v0.84.3]: https://github.com/vitorpamplona/amethyst/compare/v0.84.2...v0.84.3 +[v0.84.2]: https://github.com/vitorpamplona/amethyst/compare/v0.84.1...v0.84.2 +[v0.84.1]: https://github.com/vitorpamplona/amethyst/compare/v0.83.13...v0.84.1 +[v0.83.13]: https://github.com/vitorpamplona/amethyst/compare/v0.83.12...v0.83.13 +[v0.83.12]: https://github.com/vitorpamplona/amethyst/compare/v0.83.10...v0.83.12 +[v0.83.10]: https://github.com/vitorpamplona/amethyst/compare/v0.83.9...v0.83.10 +[v0.83.9]: https://github.com/vitorpamplona/amethyst/compare/v0.83.8...v0.83.9 +[v0.83.8]: https://github.com/vitorpamplona/amethyst/compare/v0.83.7...v0.83.8 +[v0.83.7]: https://github.com/vitorpamplona/amethyst/compare/v0.83.5...v0.83.7 +[v0.83.5]: https://github.com/vitorpamplona/amethyst/compare/v0.83.4...v0.83.5 +[v0.83.4]: https://github.com/vitorpamplona/amethyst/compare/v0.83.3...v0.83.4 +[v0.83.3]: https://github.com/vitorpamplona/amethyst/compare/v0.83.1...v0.83.3 +[v0.83.1]: https://github.com/vitorpamplona/amethyst/compare/v0.82.3...v0.83.1 +[v0.82.3]: https://github.com/vitorpamplona/amethyst/compare/v0.82.2...v0.82.3 +[v0.82.2]: https://github.com/vitorpamplona/amethyst/compare/v0.82.1...v0.82.2 +[v0.82.1]: https://github.com/vitorpamplona/amethyst/compare/v0.81.5...v0.82.1 +[v0.81.5]: https://github.com/vitorpamplona/amethyst/compare/v0.81.3...v0.81.5 +[v0.81.3]: https://github.com/vitorpamplona/amethyst/compare/v0.80.7...v0.81.3 +[v0.80.7]: https://github.com/vitorpamplona/amethyst/compare/v0.80.4...v0.80.7 +[v0.80.4]: https://github.com/vitorpamplona/amethyst/compare/v0.80.2...v0.80.4 +[v0.80.2]: https://github.com/vitorpamplona/amethyst/compare/v0.80.1...v0.80.2 +[v0.80.1]: https://github.com/vitorpamplona/amethyst/compare/v0.79.13...v0.80.1 +[v0.79.13]: https://github.com/vitorpamplona/amethyst/compare/v0.79.12...v0.79.13 +[v0.79.12]: https://github.com/vitorpamplona/amethyst/compare/v0.79.10...v0.79.12 +[v0.79.10]: https://github.com/vitorpamplona/amethyst/compare/v0.79.9...v0.79.10 +[v0.79.9]: https://github.com/vitorpamplona/amethyst/compare/v0.79.7...v0.79.9 +[v0.79.7]: https://github.com/vitorpamplona/amethyst/compare/v0.79.6...v0.79.7 +[v0.79.6]: https://github.com/vitorpamplona/amethyst/compare/v0.79.5...v0.79.6 +[v0.79.5]: https://github.com/vitorpamplona/amethyst/compare/v0.79.2...v0.79.5 +[v0.79.2]: https://github.com/vitorpamplona/amethyst/compare/v0.79.0...v0.79.2 +[v0.79.0]: https://github.com/vitorpamplona/amethyst/compare/v0.78.2...v0.79.0 +[v0.78.2]: https://github.com/vitorpamplona/amethyst/compare/v0.78.1...v0.78.2 +[v0.78.1]: https://github.com/vitorpamplona/amethyst/compare/v0.78.0...v0.78.1 +[v0.78.0]: https://github.com/vitorpamplona/amethyst/compare/v0.77.8...v0.78.0 +[v0.77.8]: https://github.com/vitorpamplona/amethyst/compare/v0.77.7...v0.77.8 +[v0.77.7]: https://github.com/vitorpamplona/amethyst/compare/v0.77.5...v0.77.7 +[v0.77.5]: https://github.com/vitorpamplona/amethyst/compare/v0.77.3...v0.77.5 +[v0.77.3]: https://github.com/vitorpamplona/amethyst/compare/v0.77.1...v0.77.3 +[v0.77.1]: https://github.com/vitorpamplona/amethyst/compare/v0.77.0...v0.77.1 +[v0.77.0]: https://github.com/vitorpamplona/amethyst/compare/v0.76.2...v0.77.0 +[v0.76.2]: https://github.com/vitorpamplona/amethyst/compare/v0.76.1...v0.76.2 +[v0.76.1]: https://github.com/vitorpamplona/amethyst/compare/v0.76.0...v0.76.1 +[v0.76.0]: https://github.com/vitorpamplona/amethyst/compare/v0.75.14...v0.76.0 +[v0.75.14]: https://github.com/vitorpamplona/amethyst/compare/v0.75.13...v0.75.14 +[v0.75.13]: https://github.com/vitorpamplona/amethyst/compare/v0.75.12...v0.75.13 +[v0.75.12]: https://github.com/vitorpamplona/amethyst/compare/v0.75.11...v0.75.12 +[v0.75.11]: https://github.com/vitorpamplona/amethyst/compare/v0.75.10...v0.75.11 +[v0.75.10]: https://github.com/vitorpamplona/amethyst/compare/v0.75.8...v0.75.10 +[v0.75.8]: https://github.com/vitorpamplona/amethyst/compare/v0.75.7...v0.75.8 +[v0.75.7]: https://github.com/vitorpamplona/amethyst/compare/v0.75.6...v0.75.7 +[v0.75.6]: https://github.com/vitorpamplona/amethyst/compare/v0.75.3...v0.75.6 +[v0.75.3]: https://github.com/vitorpamplona/amethyst/compare/v0.75.2...v0.75.3 +[v0.75.2]: https://github.com/vitorpamplona/amethyst/compare/v0.75.1...v0.75.2 +[v0.75.1]: https://github.com/vitorpamplona/amethyst/compare/v0.75.0...v0.75.1 +[v0.75.0]: https://github.com/vitorpamplona/amethyst/compare/v0.74.5...v0.75.0 +[v0.74.5]: https://github.com/vitorpamplona/amethyst/compare/v0.74.4...v0.74.5 +[v0.74.4]: https://github.com/vitorpamplona/amethyst/compare/v0.74.3...v0.74.4 +[v0.74.3]: https://github.com/vitorpamplona/amethyst/compare/v0.74.2...v0.74.3 +[v0.74.2]: https://github.com/vitorpamplona/amethyst/compare/v0.73.3...v0.74.2 +[v0.73.3]: https://github.com/vitorpamplona/amethyst/compare/v0.73.2...v0.73.3 +[v0.73.2]: https://github.com/vitorpamplona/amethyst/compare/v0.73.1...v0.73.2 +[v0.73.1]: https://github.com/vitorpamplona/amethyst/compare/v0.72.2...v0.73.1 +[v0.72.2]: https://github.com/vitorpamplona/amethyst/compare/v0.72.1...v0.72.2 +[v0.72.1]: https://github.com/vitorpamplona/amethyst/compare/v0.72.0...v0.72.1 +[v0.72.0]: https://github.com/vitorpamplona/amethyst/compare/v0.71.0...v0.72.0 +[v0.71.0]: https://github.com/vitorpamplona/amethyst/compare/v0.70.8...v0.71.0 +[v0.70.8]: https://github.com/vitorpamplona/amethyst/compare/v0.70.7...v0.70.8 +[v0.70.7]: https://github.com/vitorpamplona/amethyst/compare/v0.70.6...v0.70.7 +[v0.70.6]: https://github.com/vitorpamplona/amethyst/compare/v0.70.5...v0.70.6 +[v0.70.5]: https://github.com/vitorpamplona/amethyst/compare/v0.70.4...v0.70.5 +[v0.70.4]: https://github.com/vitorpamplona/amethyst/compare/v0.70.3...v0.70.4 +[v0.70.3]: https://github.com/vitorpamplona/amethyst/compare/v0.70.2...v0.70.3 +[v0.70.2]: https://github.com/vitorpamplona/amethyst/compare/v0.70.1...v0.70.2 +[v0.70.1]: https://github.com/vitorpamplona/amethyst/compare/v0.70.0...v0.70.1 +[v0.70.0]: https://github.com/vitorpamplona/amethyst/compare/v0.69.3...v0.70.0 +[v0.69.3]: https://github.com/vitorpamplona/amethyst/compare/v0.69.2...v0.69.3 +[v0.69.2]: https://github.com/vitorpamplona/amethyst/compare/v0.69.1...v0.69.2 +[v0.69.1]: https://github.com/vitorpamplona/amethyst/compare/v0.69.0...v0.69.1 +[v0.69.0]: https://github.com/vitorpamplona/amethyst/compare/v0.68.4...v0.69.0 +[v0.68.4]: https://github.com/vitorpamplona/amethyst/compare/v0.68.3...v0.68.4 +[v0.68.3]: https://github.com/vitorpamplona/amethyst/compare/v0.68.2...v0.68.3 +[v0.68.2]: https://github.com/vitorpamplona/amethyst/compare/v0.68.1...v0.68.2 +[v0.68.1]: https://github.com/vitorpamplona/amethyst/compare/v0.68.0...v0.68.1 +[v0.68.0]: https://github.com/vitorpamplona/amethyst/compare/v0.67.1...v0.68.0 +[v0.67.1]: https://github.com/vitorpamplona/amethyst/compare/v0.67.0...v0.67.1 +[v0.67.0]: https://github.com/vitorpamplona/amethyst/compare/v0.66.7...v0.67.0 +[v0.66.7]: https://github.com/vitorpamplona/amethyst/compare/v0.66.6...v0.66.7 +[v0.66.6]: https://github.com/vitorpamplona/amethyst/compare/v0.66.5...v0.66.6 +[v0.66.5]: https://github.com/vitorpamplona/amethyst/compare/v0.66.4...v0.66.5 +[v0.66.4]: https://github.com/vitorpamplona/amethyst/compare/v0.66.3...v0.66.4 +[v0.66.3]: https://github.com/vitorpamplona/amethyst/compare/v0.66.2...v0.66.3 +[v0.66.2]: https://github.com/vitorpamplona/amethyst/compare/v0.66.1...v0.66.2 +[v0.66.1]: https://github.com/vitorpamplona/amethyst/compare/v0.66.0...v0.66.1 +[v0.66.0]: https://github.com/vitorpamplona/amethyst/compare/v0.65.1...v0.66.0 +[v0.65.1]: https://github.com/vitorpamplona/amethyst/compare/v0.65.0...v0.65.1 +[v0.65.0]: https://github.com/vitorpamplona/amethyst/compare/v0.64.4...v0.65.0 +[v0.64.4]: https://github.com/vitorpamplona/amethyst/compare/v0.64.3...v0.64.4 +[v0.64.3]: https://github.com/vitorpamplona/amethyst/compare/v0.64.2...v0.64.3 +[v0.64.2]: https://github.com/vitorpamplona/amethyst/compare/v0.64.0...v0.64.2 +[v0.64.0]: https://github.com/vitorpamplona/amethyst/compare/v0.63.0...v0.64.0 +[v0.63.0]: https://github.com/vitorpamplona/amethyst/compare/v0.62.8...v0.63.0 +[v0.62.8]: https://github.com/vitorpamplona/amethyst/compare/v0.62.7...v0.62.8 +[v0.62.7]: https://github.com/vitorpamplona/amethyst/compare/v0.62.6...v0.62.7 +[v0.62.6]: https://github.com/vitorpamplona/amethyst/compare/v0.62.5...v0.62.6 +[v0.62.5]: https://github.com/vitorpamplona/amethyst/compare/v0.62.4...v0.62.5 +[v0.62.4]: https://github.com/vitorpamplona/amethyst/compare/v0.62.3...v0.62.4 +[v0.62.3]: https://github.com/vitorpamplona/amethyst/compare/v0.62.2...v0.62.3 +[v0.62.2]: https://github.com/vitorpamplona/amethyst/compare/v0.62.1...v0.62.2 +[v0.62.1]: https://github.com/vitorpamplona/amethyst/compare/v0.62.0...v0.62.1 +[v0.62.0]: https://github.com/vitorpamplona/amethyst/compare/v0.61.4...v0.62.0 +[v0.61.4]: https://github.com/vitorpamplona/amethyst/compare/v0.61.3...v0.61.4 +[v0.61.3]: https://github.com/vitorpamplona/amethyst/compare/v0.61.2...v0.61.3 +[v0.61.2]: https://github.com/vitorpamplona/amethyst/compare/v0.61.1...v0.61.2 +[v0.61.1]: https://github.com/vitorpamplona/amethyst/compare/v0.61.0...v0.61.1 +[v0.61.0]: https://github.com/vitorpamplona/amethyst/compare/v0.60.2...v0.61.0 +[v0.60.2]: https://github.com/vitorpamplona/amethyst/compare/v0.60.1...v0.60.2 +[v0.60.1]: https://github.com/vitorpamplona/amethyst/compare/v0.60.0...v0.60.1 +[v0.60.0]: https://github.com/vitorpamplona/amethyst/compare/v0.59.1...v0.60.0 +[v0.59.1]: https://github.com/vitorpamplona/amethyst/compare/v0.58.3...v0.59.1 +[v0.58.3]: https://github.com/vitorpamplona/amethyst/compare/v0.58.2...v0.58.3 +[v0.58.2]: https://github.com/vitorpamplona/amethyst/compare/v0.58.1...v0.58.2 +[v0.58.1]: https://github.com/vitorpamplona/amethyst/compare/v0.58.0...v0.58.1 +[v0.58.0]: https://github.com/vitorpamplona/amethyst/compare/v0.57.0...v0.58.0 +[v0.57.0]: https://github.com/vitorpamplona/amethyst/compare/v0.56.5...v0.57.0 +[v0.56.5]: https://github.com/vitorpamplona/amethyst/compare/v0.56.4...v0.56.5 +[v0.56.4]: https://github.com/vitorpamplona/amethyst/compare/v0.56.3...v0.56.4 +[v0.56.3]: https://github.com/vitorpamplona/amethyst/compare/v0.56.2...v0.56.3 +[v0.56.2]: https://github.com/vitorpamplona/amethyst/compare/v0.56.1...v0.56.2 +[v0.56.1]: https://github.com/vitorpamplona/amethyst/compare/v0.56.0...v0.56.1 +[v0.56.0]: https://github.com/vitorpamplona/amethyst/compare/v0.55.4...v0.56.0 +[v0.55.4]: https://github.com/vitorpamplona/amethyst/compare/v0.55.3...v0.55.4 +[v0.55.3]: https://github.com/vitorpamplona/amethyst/compare/v0.55.2...v0.55.3 +[v0.55.2]: https://github.com/vitorpamplona/amethyst/compare/v0.55.1...v0.55.2 +[v0.55.1]: https://github.com/vitorpamplona/amethyst/compare/v0.55.0...v0.55.1 +[v0.55.0]: https://github.com/vitorpamplona/amethyst/compare/v0.54.2...v0.55.0 +[v0.54.2]: https://github.com/vitorpamplona/amethyst/compare/v0.54.1...v0.54.2 +[v0.54.1]: https://github.com/vitorpamplona/amethyst/compare/v0.54.0...v0.54.1 +[v0.54.0]: https://github.com/vitorpamplona/amethyst/compare/v0.53.7...v0.54.0 +[v0.53.7]: https://github.com/vitorpamplona/amethyst/compare/v0.53.6...v0.53.7 +[v0.53.6]: https://github.com/vitorpamplona/amethyst/compare/v0.53.5...v0.53.6 +[v0.53.5]: https://github.com/vitorpamplona/amethyst/compare/v0.53.4...v0.53.5 +[v0.53.4]: https://github.com/vitorpamplona/amethyst/compare/v0.53.3...v0.53.4 +[v0.53.3]: https://github.com/vitorpamplona/amethyst/compare/v0.53.2...v0.53.3 +[v0.53.2]: https://github.com/vitorpamplona/amethyst/compare/v0.53.1...v0.53.2 +[v0.53.1]: https://github.com/vitorpamplona/amethyst/compare/v0.53.0...v0.53.1 +[v0.53.0]: https://github.com/vitorpamplona/amethyst/compare/v0.52.3...v0.53.0 +[v0.52.3]: https://github.com/vitorpamplona/amethyst/compare/v0.52.2...v0.52.3 +[v0.52.2]: https://github.com/vitorpamplona/amethyst/compare/v0.52.1...v0.52.2 +[v0.52.1]: https://github.com/vitorpamplona/amethyst/compare/v0.52.0...v0.52.1 +[v0.52.0]: https://github.com/vitorpamplona/amethyst/compare/v0.51.4...v0.52.0 +[v0.51.4]: https://github.com/vitorpamplona/amethyst/compare/v0.51.3...v0.51.4 +[v0.51.3]: https://github.com/vitorpamplona/amethyst/compare/v0.51.2...v0.51.3 +[v0.51.2]: https://github.com/vitorpamplona/amethyst/compare/v0.51.1...v0.51.2 +[v0.51.1]: https://github.com/vitorpamplona/amethyst/compare/v0.51.0...v0.51.1 +[v0.51.0]: https://github.com/vitorpamplona/amethyst/compare/v0.50.6...v0.51.0 +[v0.50.6]: https://github.com/vitorpamplona/amethyst/compare/v0.50.5...v0.50.6 +[v0.50.5]: https://github.com/vitorpamplona/amethyst/compare/v0.50.4...v0.50.5 +[v0.50.4]: https://github.com/vitorpamplona/amethyst/compare/v0.50.3...v0.50.4 +[v0.50.3]: https://github.com/vitorpamplona/amethyst/compare/v0.50.2...v0.50.3 +[v0.50.2]: https://github.com/vitorpamplona/amethyst/compare/v0.50.1...v0.50.2 +[v0.50.1]: https://github.com/vitorpamplona/amethyst/compare/v0.50.0...v0.50.1 +[v0.50.0]: https://github.com/vitorpamplona/amethyst/compare/v0.49.4...v0.50.0 +[v0.49.4]: https://github.com/vitorpamplona/amethyst/compare/v0.49.3...v0.49.4 +[v0.49.3]: https://github.com/vitorpamplona/amethyst/compare/v0.49.2...v0.49.3 +[v0.49.2]: https://github.com/vitorpamplona/amethyst/compare/v0.49.1...v0.49.2 +[v0.49.1]: https://github.com/vitorpamplona/amethyst/compare/v0.49.0...v0.49.1 +[v0.49.0]: https://github.com/vitorpamplona/amethyst/compare/v0.48.0...v0.49.0 +[v0.48.0]: https://github.com/vitorpamplona/amethyst/compare/v0.47.0...v0.48.0 +[v0.47.0]: https://github.com/vitorpamplona/amethyst/compare/v0.46.6...v0.47.0 +[v0.46.6]: https://github.com/vitorpamplona/amethyst/compare/v0.46.5...v0.46.6 +[v0.46.5]: https://github.com/vitorpamplona/amethyst/compare/v0.46.4...v0.46.5 +[v0.46.4]: https://github.com/vitorpamplona/amethyst/compare/v0.46.3...v0.46.4 +[v0.46.3]: https://github.com/vitorpamplona/amethyst/compare/v0.46.2...v0.46.3 +[v0.46.2]: https://github.com/vitorpamplona/amethyst/compare/v0.46.1...v0.46.2 +[v0.46.1]: https://github.com/vitorpamplona/amethyst/compare/v0.46.0...v0.46.1 +[v0.46.0]: https://github.com/vitorpamplona/amethyst/compare/v0.45.1...v0.46.0 +[v0.45.1]: https://github.com/vitorpamplona/amethyst/compare/v0.45.0...v0.45.1 +[v0.45.0]: https://github.com/vitorpamplona/amethyst/compare/v0.44.0...v0.45.0 +[v0.44.0]: https://github.com/vitorpamplona/amethyst/compare/v0.43.2...v0.44.0 +[v0.43.2]: https://github.com/vitorpamplona/amethyst/compare/v0.43.1...v0.43.2 +[v0.43.1]: https://github.com/vitorpamplona/amethyst/compare/v0.43.0...v0.43.1 +[v0.43.0]: https://github.com/vitorpamplona/amethyst/compare/v0.42.5...v0.43.0 +[v0.42.5]: https://github.com/vitorpamplona/amethyst/compare/v0.42.4...v0.42.5 +[v0.42.4]: https://github.com/vitorpamplona/amethyst/compare/v0.42.2...v0.42.4 +[v0.42.2]: https://github.com/vitorpamplona/amethyst/compare/v0.42.1...v0.42.2 +[v0.42.1]: https://github.com/vitorpamplona/amethyst/compare/v0.42.0...v0.42.1 +[v0.42.0]: https://github.com/vitorpamplona/amethyst/compare/v0.41.0...v0.42.0 +[v0.41.0]: https://github.com/vitorpamplona/amethyst/compare/v0.40.6...v0.41.0 +[v0.40.6]: https://github.com/vitorpamplona/amethyst/compare/v0.40.5...v0.40.6 +[v0.40.5]: https://github.com/vitorpamplona/amethyst/compare/v0.40.4...v0.40.5 +[v0.40.4]: https://github.com/vitorpamplona/amethyst/compare/v0.40.3...v0.40.4 +[v0.40.3]: https://github.com/vitorpamplona/amethyst/compare/v0.40.2...v0.40.3 +[v0.40.2]: https://github.com/vitorpamplona/amethyst/compare/v0.40.1...v0.40.2 +[v0.40.1]: https://github.com/vitorpamplona/amethyst/compare/v0.40.0...v0.40.1 +[v0.40.0]: https://github.com/vitorpamplona/amethyst/compare/v0.38.0...v0.40.0 +[v0.38.0]: https://github.com/vitorpamplona/amethyst/compare/v0.37.4...v0.38.0 +[v0.37.4]: https://github.com/vitorpamplona/amethyst/compare/v0.37.3...v0.37.4 +[v0.37.3]: https://github.com/vitorpamplona/amethyst/compare/v0.37.2...v0.37.3 +[v0.37.2]: https://github.com/vitorpamplona/amethyst/compare/v0.37.1...v0.37.2 +[v0.37.1]: https://github.com/vitorpamplona/amethyst/compare/v0.37.0...v0.37.1 +[v0.37.0]: https://github.com/vitorpamplona/amethyst/compare/v0.36.0...v0.37.0 +[v0.36.0]: https://github.com/vitorpamplona/amethyst/compare/v0.35.1...v0.36.0 +[v0.35.1]: https://github.com/vitorpamplona/amethyst/compare/v0.35.0...v0.35.1 +[v0.35.0]: https://github.com/vitorpamplona/amethyst/compare/v0.34.1...v0.35.0 +[v0.34.1]: https://github.com/vitorpamplona/amethyst/compare/v0.34.0...v0.34.1 +[v0.34.0]: https://github.com/vitorpamplona/amethyst/compare/v0.33.2...v0.34.0 +[v0.33.2]: https://github.com/vitorpamplona/amethyst/compare/v0.33.1...v0.33.2 +[v0.33.1]: https://github.com/vitorpamplona/amethyst/compare/v0.33.0...v0.33.1 +[v0.33.0]: https://github.com/vitorpamplona/amethyst/compare/v0.32.3...v0.33.0 +[v0.32.3]: https://github.com/vitorpamplona/amethyst/compare/v0.32.2...v0.32.3 +[v0.32.2]: https://github.com/vitorpamplona/amethyst/compare/v0.32.1...v0.32.2 +[v0.32.1]: https://github.com/vitorpamplona/amethyst/compare/v0.32.0...v0.32.1 +[v0.32.0]: https://github.com/vitorpamplona/amethyst/compare/v0.31.4...v0.32.0 +[v0.31.4]: https://github.com/vitorpamplona/amethyst/compare/v0.31.3...v0.31.4 +[v0.31.3]: https://github.com/vitorpamplona/amethyst/compare/v0.31.2...v0.31.3 +[v0.31.2]: https://github.com/vitorpamplona/amethyst/compare/v0.31.0...v0.31.2 +[v0.31.0]: https://github.com/vitorpamplona/amethyst/compare/v0.30.2...v0.31.0 +[v0.30.2]: https://github.com/vitorpamplona/amethyst/compare/v0.30.1...v0.30.2 +[v0.30.1]: https://github.com/vitorpamplona/amethyst/compare/v0.30.0...v0.30.1 +[v0.30.0]: https://github.com/vitorpamplona/amethyst/compare/v0.29.2...v0.30.0 +[v0.29.2]: https://github.com/vitorpamplona/amethyst/compare/v0.29.1...v0.29.2 +[v0.29.1]: https://github.com/vitorpamplona/amethyst/compare/v0.29.0...v0.29.1 +[v0.29.0]: https://github.com/vitorpamplona/amethyst/compare/v0.28.1...v0.29.0 +[v0.28.1]: https://github.com/vitorpamplona/amethyst/compare/v0.28.0...v0.28.1 +[v0.28.0]: https://github.com/vitorpamplona/amethyst/compare/v0.27.2...v0.28.0 +[v0.27.2]: https://github.com/vitorpamplona/amethyst/compare/v0.27.1...v0.27.2 +[v0.27.1]: https://github.com/vitorpamplona/amethyst/compare/v0.27.0...v0.27.1 +[v0.27.0]: https://github.com/vitorpamplona/amethyst/compare/v0.26.2...v0.27.0 +[v0.26.2]: https://github.com/vitorpamplona/amethyst/compare/v0.26.1...v0.26.2 +[v0.26.1]: https://github.com/vitorpamplona/amethyst/compare/v0.26.0...v0.26.1 +[v0.26.0]: https://github.com/vitorpamplona/amethyst/compare/v0.25.3...v0.26.0 +[v0.25.3]: https://github.com/vitorpamplona/amethyst/compare/v0.25.2...v0.25.3 +[v0.25.2]: https://github.com/vitorpamplona/amethyst/compare/v0.25.1...v0.25.2 +[v0.25.1]: https://github.com/vitorpamplona/amethyst/compare/v0.25.0...v0.25.1 +[v0.25.0]: https://github.com/vitorpamplona/amethyst/compare/v0.24.2...v0.25.0 +[v0.24.2]: https://github.com/vitorpamplona/amethyst/compare/v0.24.1...v0.24.2 +[v0.24.1]: https://github.com/vitorpamplona/amethyst/compare/v0.24.0...v0.24.1 +[v0.24.0]: https://github.com/vitorpamplona/amethyst/compare/v0.23.1...v0.24.0 +[v0.23.1]: https://github.com/vitorpamplona/amethyst/compare/v0.23.0...v0.23.1 +[v0.23.0]: https://github.com/vitorpamplona/amethyst/compare/v0.22.3...v0.23.0 +[v0.22.3]: https://github.com/vitorpamplona/amethyst/compare/v0.22.2...v0.22.3 +[v0.22.2]: https://github.com/vitorpamplona/amethyst/compare/v0.22.1...v0.22.2 +[v0.22.1]: https://github.com/vitorpamplona/amethyst/compare/v0.22.0...v0.22.1 +[v0.22.0]: https://github.com/vitorpamplona/amethyst/compare/v0.21.2...v0.22.0 +[v0.21.2]: https://github.com/vitorpamplona/amethyst/compare/v0.21.1...v0.21.2 +[v0.21.1]: https://github.com/vitorpamplona/amethyst/compare/v0.20.5...v0.21.1 +[v0.20.5]: https://github.com/vitorpamplona/amethyst/compare/v0.20.4...v0.20.5 +[v0.20.4]: https://github.com/vitorpamplona/amethyst/compare/v0.20.3...v0.20.4 +[v0.20.3]: https://github.com/vitorpamplona/amethyst/compare/v0.20.2...v0.20.3 +[v0.20.2]: https://github.com/vitorpamplona/amethyst/compare/v0.20.1...v0.20.2 +[v0.20.1]: https://github.com/vitorpamplona/amethyst/compare/v0.20.0...v0.20.1 +[v0.20.0]: https://github.com/vitorpamplona/amethyst/compare/v0.19.1...v0.20.0 +[v0.19.1]: https://github.com/vitorpamplona/amethyst/compare/v0.19.0...v0.19.1 +[v0.19.0]: https://github.com/vitorpamplona/amethyst/compare/v0.18.3...v0.19.0 +[v0.18.3]: https://github.com/vitorpamplona/amethyst/compare/v0.18.2...v0.18.3 +[v0.18.2]: https://github.com/vitorpamplona/amethyst/compare/v0.18.1...v0.18.2 +[v0.18.1]: https://github.com/vitorpamplona/amethyst/compare/v0.18.0...v0.18.1 +[v0.18.0]: https://github.com/vitorpamplona/amethyst/compare/v0.17.11...v0.18.0 +[v0.17.11]: https://github.com/vitorpamplona/amethyst/compare/v0.17.10...v0.17.11 +[v0.17.10]: https://github.com/vitorpamplona/amethyst/compare/v0.17.9...v0.17.10 +[v0.17.9]: https://github.com/vitorpamplona/amethyst/compare/v0.17.8...v0.17.9 +[v0.17.8]: https://github.com/vitorpamplona/amethyst/compare/v0.17.7...v0.17.8 +[v0.17.7]: https://github.com/vitorpamplona/amethyst/compare/v0.17.6...v0.17.7 +[v0.17.6]: https://github.com/vitorpamplona/amethyst/compare/v0.17.5...v0.17.6 +[v0.17.5]: https://github.com/vitorpamplona/amethyst/compare/v0.17.4...v0.17.5 +[v0.17.4]: https://github.com/vitorpamplona/amethyst/compare/v0.17.3...v0.17.4 +[v0.17.3]: https://github.com/vitorpamplona/amethyst/compare/v0.17.2...v0.17.3 +[v0.17.2]: https://github.com/vitorpamplona/amethyst/compare/v0.17.1...v0.17.2 +[v0.17.1]: https://github.com/vitorpamplona/amethyst/compare/v0.17.0...v0.17.1 +[v0.17.0]: https://github.com/vitorpamplona/amethyst/compare/v0.16.2...v0.17.0 +[v0.16.2]: https://github.com/vitorpamplona/amethyst/compare/v0.16.1...v0.16.2 +[v0.16.1]: https://github.com/vitorpamplona/amethyst/compare/v0.16.0...v0.16.1 +[v0.16.0]: https://github.com/vitorpamplona/amethyst/compare/v0.15.9...v0.16.0 +[v0.15.9]: https://github.com/vitorpamplona/amethyst/compare/v0.15.8...v0.15.9 +[v0.15.8]: https://github.com/vitorpamplona/amethyst/compare/v0.15.7...v0.15.8 +[v0.15.7]: https://github.com/vitorpamplona/amethyst/compare/v0.15.6...v0.15.7 +[v0.15.6]: https://github.com/vitorpamplona/amethyst/compare/v0.15.5...v0.15.6 +[v0.15.5]: https://github.com/vitorpamplona/amethyst/compare/v0.15.4...v0.15.5 +[v0.15.4]: https://github.com/vitorpamplona/amethyst/compare/v0.15.3...v0.15.4 +[v0.15.3]: https://github.com/vitorpamplona/amethyst/compare/v0.15.2...v0.15.3 +[v0.15.2]: https://github.com/vitorpamplona/amethyst/compare/v0.15.1...v0.15.2 +[v0.15.1]: https://github.com/vitorpamplona/amethyst/compare/v0.14.3...v0.15.1 +[v0.14.3]: https://github.com/vitorpamplona/amethyst/compare/v0.14.2...v0.14.3 +[v0.14.2]: https://github.com/vitorpamplona/amethyst/compare/v0.14.1...v0.14.2 +[v0.14.1]: https://github.com/vitorpamplona/amethyst/compare/v0.14.0...v0.14.1 +[v0.14.0]: https://github.com/vitorpamplona/amethyst/compare/v0.13.3...v0.14.0 +[v0.13.3]: https://github.com/vitorpamplona/amethyst/compare/v0.13.2...v0.13.3 +[v0.13.2]: https://github.com/vitorpamplona/amethyst/compare/v0.13.1...v0.13.2 +[v0.13.1]: https://github.com/vitorpamplona/amethyst/compare/v0.13.0...v0.13.1 +[v0.13.0]: https://github.com/vitorpamplona/amethyst/compare/v0.12.1...v0.13.0 +[v0.12.1]: https://github.com/vitorpamplona/amethyst/compare/v0.12.0...v0.12.1 +[v0.12.0]: https://github.com/vitorpamplona/amethyst/compare/v0.11.7...v0.12.0 +[v0.11.7]: https://github.com/vitorpamplona/amethyst/compare/v0.11.6...v0.11.7 +[v0.11.6]: https://github.com/vitorpamplona/amethyst/compare/v0.11.5...v0.11.6 +[v0.11.5]: https://github.com/vitorpamplona/amethyst/compare/v0.11.4...v0.11.5 +[v0.11.4]: https://github.com/vitorpamplona/amethyst/compare/v0.11.3...v0.11.4 +[v0.11.3]: https://github.com/vitorpamplona/amethyst/compare/v0.11.2...v0.11.3 +[v0.11.2]: https://github.com/vitorpamplona/amethyst/compare/v0.11.1...v0.11.2 +[v0.11.1]: https://github.com/vitorpamplona/amethyst/compare/v0.11.0...v0.11.1 +[v0.11.0]: https://github.com/vitorpamplona/amethyst/compare/v0.10.7...v0.11.0 +[v0.10.7]: https://github.com/vitorpamplona/amethyst/compare/v0.10.6...v0.10.7 +[v0.10.6]: https://github.com/vitorpamplona/amethyst/compare/v0.10.5...v0.10.6 +[v0.10.5]: https://github.com/vitorpamplona/amethyst/compare/v0.10.4...v0.10.5 +[v0.10.4]: https://github.com/vitorpamplona/amethyst/compare/v0.10.3...v0.10.4 +[v0.10.3]: https://github.com/vitorpamplona/amethyst/compare/v0.10.2...v0.10.3 +[v0.10.2]: https://github.com/vitorpamplona/amethyst/compare/v0.10.1...v0.10.2 +[v0.10.1]: https://github.com/vitorpamplona/amethyst/compare/v0.10.0...v0.10.1 +[v0.10.0]: https://github.com/vitorpamplona/amethyst/compare/v0.9.6...v0.10.0 +[v0.9.6]: https://github.com/vitorpamplona/amethyst/compare/v0.9.5...v0.9.6 +[v0.9.5]: https://github.com/vitorpamplona/amethyst/compare/v0.9.4...v0.9.5 +[v0.9.4]: https://github.com/vitorpamplona/amethyst/compare/v0.9.3...v0.9.4 +[v0.9.3]: https://github.com/vitorpamplona/amethyst/compare/v0.9.2...v0.9.3 +[v0.9.2]: https://github.com/vitorpamplona/amethyst/compare/v0.9.1...v0.9.2 +[v0.9.1]: https://github.com/vitorpamplona/amethyst/compare/v0.9...v0.9.1 +[v0.9]: https://github.com/vitorpamplona/amethyst/compare/v0.8.2...v0.9 +[v0.8.2]: https://github.com/vitorpamplona/amethyst/compare/v0.8.1...v0.8.2 +[v0.8.1]: https://github.com/vitorpamplona/amethyst/compare/v0.8...v0.8.1 +[v0.8]: https://github.com/vitorpamplona/amethyst/compare/v0.7...v0.8 +[v0.7]: https://github.com/vitorpamplona/amethyst/compare/v0.6...v0.7 +[v0.6]: https://github.com/vitorpamplona/amethyst/compare/v0.5...v0.6 +[v0.5]: https://github.com/vitorpamplona/amethyst/compare/v0.4...v0.5 +[v0.4]: https://github.com/vitorpamplona/amethyst/compare/v0.3...v0.4 +[v0.3]: https://github.com/vitorpamplona/amethyst/compare/v0.2...v0.3 +[v0.2]: https://github.com/vitorpamplona/amethyst/compare/v0.1...v0.2 +[v0.1]: https://github.com/vitorpamplona/amethyst/tree/v0.1 \ No newline at end of file From 007f512cc4633b07fa0619c559cc6af9f3adf2ac Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 00:20:39 +0000 Subject: [PATCH 13/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-sl-rSI/strings.xml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index b3d58f189..67d4e2f1f 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -509,6 +509,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Ustvari seznam Kopiraj/kloniraj seznam Preimenuj seznam + Uredi seznam Uredi Preimenuješ iz v.. @@ -1141,4 +1142,17 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Odstrani uporabnika iz seznama Paket sledenih Člani + Sledi metapodatkom seznama + Sledenje metapodatkom seznama je lahko vidno vsem na Nostru. Le tvoji zasebni člani so šifrirani. + Metapodatki paketa sledenih + Metapodatki paketa sledenih so lahko vidno vsem na Nostru in redno objavljeni na ostalih spletnih straneh, kot začetni prikaz za nove uporabnike + Uredi paket sledenih + Ime paketa + Novo ime paketa + Opis paketa + Nov opis paketa + Oddajaj seznam + Oddajaj paket + Izbriši seznam + Izbriši paket From cbf9effcf4a55c11018fb6793989e98c8e991eba Mon Sep 17 00:00:00 2001 From: davotoula Date: Sat, 15 Nov 2025 09:38:00 +0100 Subject: [PATCH 14/60] updated cz, de, pt, sv --- .../src/main/res/values-cs-rCZ/strings.xml | 23 +++++++++++++++++++ .../src/main/res/values-de-rDE/strings.xml | 23 +++++++++++++++++++ .../src/main/res/values-pt-rBR/strings.xml | 23 +++++++++++++++++++ .../src/main/res/values-sv-rSE/strings.xml | 22 ++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/amethyst/src/main/res/values-cs-rCZ/strings.xml b/amethyst/src/main/res/values-cs-rCZ/strings.xml index 2226c0bdd..62f22a61a 100644 --- a/amethyst/src/main/res/values-cs-rCZ/strings.xml +++ b/amethyst/src/main/res/values-cs-rCZ/strings.xml @@ -1121,4 +1121,27 @@ Odebrat uživatele ze seznamu Balíček Sledování Členové + + Upravit seznam + Metadata seznamu sledování + Metadata seznamů sledování mohou vidět všichni na Nostr. Pouze vaši soukromí členové jsou šifrovaní. + + Metadata sady doporučení + Metadata sad doporučení mohou vidět všichni na Nostr a často jsou zveřejňována na různých webech jako startovací sady pro nové uživatele. + + Upravit sadu doporučení + Název sady + Nový název sady + Popis sady + Nový popis sady + + Broadcast seznamu + Broadcast sady doporučení + + Smazat seznam + Smazat sadu doporučení + Nová sada doporučení + Toto jsou follow seznamy určené pro vaše vlastní použití. Můžete sledovat uživatele soukromě nebo veřejně. + Toto jsou seznamy uživatelů, které doporučujete ostatním. Jsou povoleni pouze veřejní uživatelé. + diff --git a/amethyst/src/main/res/values-de-rDE/strings.xml b/amethyst/src/main/res/values-de-rDE/strings.xml index 72094a578..8788ca2ed 100644 --- a/amethyst/src/main/res/values-de-rDE/strings.xml +++ b/amethyst/src/main/res/values-de-rDE/strings.xml @@ -1126,4 +1126,27 @@ anz der Bedingungen ist erforderlich Benutzer aus der Liste entfernen Folge Paket Mitglieder + + Liste bearbeiten + Metadaten der Follow-Liste + Metadaten von Follow-Listen können von allen auf Nostr gesehen werden. Nur deine privaten Mitglieder sind verschlüsselt. + + Metadaten des Empfehlungspakets + Metadaten von Empfehlungspaketen können von allen auf Nostr gesehen werden und werden häufig auf Websites als Starterkits für neue Nutzer veröffentlicht. + + Empfehlungspaket bearbeiten + Paketname + Neuer Paketname + Paketbeschreibung + Neue Paketbeschreibung + + Liste veröffentlichen + Empfehlungspaket veröffentlichen + + Liste löschen + Empfehlungspaket löschen + Neues Empfehlungspaket + Dies sind Follow-Listen für deine eigene Nutzung. Du kannst Nutzer privat oder öffentlich folgen. + Dies sind Listen von Nutzern, die du anderen empfiehlst. Nur öffentliche Nutzer sind erlaubt. + diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index 54c8b4fec..7346f533c 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -1121,4 +1121,27 @@ Remover usuário da lista Pacote Seguir Membros + + Editar lista + Metadados da lista de seguidores + Os metadados das listas de seguidores podem ser vistos por qualquer pessoa no Nostr. Apenas os membros privados são criptografados. + + Metadados do pacote de recomendações + Os metadados dos pacotes de recomendações podem ser vistos por qualquer pessoa no Nostr e são frequentemente publicados em sites como kits iniciais para novos usuários. + + Editar pacote de recomendações + Nome do pacote + Novo nome do pacote + Descrição do pacote + Nova descrição do pacote + + Transmitir lista + Transmitir pacote de recomendações + + Excluir lista + Excluir pacote de recomendações + Novo pacote de recomendações + Essas são listas de seguidores criadas para seu próprio uso. Você pode seguir usuários de forma privada ou pública. + Essas são listas de usuários que você recomenda para outras pessoas. Somente usuários públicos são permitidos. + diff --git a/amethyst/src/main/res/values-sv-rSE/strings.xml b/amethyst/src/main/res/values-sv-rSE/strings.xml index d67a72f87..5a23a5716 100644 --- a/amethyst/src/main/res/values-sv-rSE/strings.xml +++ b/amethyst/src/main/res/values-sv-rSE/strings.xml @@ -1120,4 +1120,26 @@ Ta bort användare från listan Följpaket Medlemmar + Redigera lista + Metadata för följlista + Metadata för följlistor kan ses av alla på Nostr. Endast privata medlemmar är krypterade. + + Metadata för rekommendationspaket + Metadata för rekommendationspaket kan ses av alla på Nostr och publiceras ofta på webbplatser som startpaket för nya användare. + + Redigera rekommendationspaket + Paketnamn + Nytt paketnamn + Paketbeskrivning + Ny paketbeskrivning + + Sänd lista + Sänd rekommendationspaket + + Ta bort lista + Ta bort rekommendationspaket + Nytt rekommendationspaket + Detta är följlistor avsedda för ditt eget bruk. Du kan följa användare privat eller offentligt. + Detta är listor med användare som du rekommenderar till andra. Endast offentliga användare är tillåtna. + From 22c8ecefed60b852dcffc0ef196ef4690260c05b Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 12:15:13 +0000 Subject: [PATCH 15/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-cs-rCZ/strings.xml | 14 ++++---------- amethyst/src/main/res/values-de-rDE/strings.xml | 14 ++++---------- amethyst/src/main/res/values-pt-rBR/strings.xml | 14 ++++---------- amethyst/src/main/res/values-sv-rSE/strings.xml | 13 ++++--------- 4 files changed, 16 insertions(+), 39 deletions(-) diff --git a/amethyst/src/main/res/values-cs-rCZ/strings.xml b/amethyst/src/main/res/values-cs-rCZ/strings.xml index 62f22a61a..f6b9d8272 100644 --- a/amethyst/src/main/res/values-cs-rCZ/strings.xml +++ b/amethyst/src/main/res/values-cs-rCZ/strings.xml @@ -448,6 +448,7 @@ Globální Seznam ztlumení Seznamy sledování + Toto jsou follow seznamy určené pro vaše vlastní použití. Můžete sledovat uživatele soukromě nebo veřejně. Označené záložky Obecné záložky Veřejné @@ -480,6 +481,7 @@ Vytvořit nový seznam %1$s s uživatelem Vytvoří %1$s sadu sledování a přidá do ní %2$s. Nový seznam sledování + Nová sada doporučení Kopírovat/Klonovat seznam sledování Upravit popis Tento seznam nemá žádný popis @@ -492,6 +494,7 @@ Vytvořit seznam Kopírovat/Klonovat seznam Přejmenovat seznam + Upravit seznam Upravit Přejmenováváte z na.. @@ -630,6 +633,7 @@ Sledované značky Rele Balíčky Sledování + Toto jsou seznamy uživatelů, které doporučujete ostatním. Jsou povoleni pouze veřejní uživatelé. Přečtené Algoritmy kanálu Trh @@ -1121,27 +1125,17 @@ Odebrat uživatele ze seznamu Balíček Sledování Členové - - Upravit seznam Metadata seznamu sledování Metadata seznamů sledování mohou vidět všichni na Nostr. Pouze vaši soukromí členové jsou šifrovaní. - Metadata sady doporučení Metadata sad doporučení mohou vidět všichni na Nostr a často jsou zveřejňována na různých webech jako startovací sady pro nové uživatele. - Upravit sadu doporučení Název sady Nový název sady Popis sady Nový popis sady - Broadcast seznamu Broadcast sady doporučení - Smazat seznam Smazat sadu doporučení - Nová sada doporučení - Toto jsou follow seznamy určené pro vaše vlastní použití. Můžete sledovat uživatele soukromě nebo veřejně. - Toto jsou seznamy uživatelů, které doporučujete ostatním. Jsou povoleni pouze veřejní uživatelé. - diff --git a/amethyst/src/main/res/values-de-rDE/strings.xml b/amethyst/src/main/res/values-de-rDE/strings.xml index 8788ca2ed..9c1f13bd2 100644 --- a/amethyst/src/main/res/values-de-rDE/strings.xml +++ b/amethyst/src/main/res/values-de-rDE/strings.xml @@ -454,6 +454,7 @@ anz der Bedingungen ist erforderlich Weltweit Stummliste Follower-Listen + Dies sind Follow-Listen für deine eigene Nutzung. Du kannst Nutzer privat oder öffentlich folgen. Markierte Lesezeichen Allgemeine Lesezeichen Öffentlich @@ -486,6 +487,7 @@ anz der Bedingungen ist erforderlich Neue %1$s-Liste mit Benutzer erstellen Erstellt ein %1$s-Folge-Set und fügt %2$s hinzu. Neue Follower-Liste + Neues Empfehlungspaket Follower-Liste kopieren/klonen Beschreibung bearbeiten Diese Liste hat keine Beschreibung @@ -498,6 +500,7 @@ anz der Bedingungen ist erforderlich Liste erstellen Liste kopieren/klonen Liste umbenennen + Liste bearbeiten Bearbeiten Du benennst um von zu.. @@ -635,6 +638,7 @@ anz der Bedingungen ist erforderlich Gefolgte Tags Relais Folge Paketen + Dies sind Listen von Nutzern, die du anderen empfiehlst. Nur öffentliche Nutzer sind erlaubt. Lesungen Feedalgorithmen Marktplatz @@ -1126,27 +1130,17 @@ anz der Bedingungen ist erforderlich Benutzer aus der Liste entfernen Folge Paket Mitglieder - - Liste bearbeiten Metadaten der Follow-Liste Metadaten von Follow-Listen können von allen auf Nostr gesehen werden. Nur deine privaten Mitglieder sind verschlüsselt. - Metadaten des Empfehlungspakets Metadaten von Empfehlungspaketen können von allen auf Nostr gesehen werden und werden häufig auf Websites als Starterkits für neue Nutzer veröffentlicht. - Empfehlungspaket bearbeiten Paketname Neuer Paketname Paketbeschreibung Neue Paketbeschreibung - Liste veröffentlichen Empfehlungspaket veröffentlichen - Liste löschen Empfehlungspaket löschen - Neues Empfehlungspaket - Dies sind Follow-Listen für deine eigene Nutzung. Du kannst Nutzer privat oder öffentlich folgen. - Dies sind Listen von Nutzern, die du anderen empfiehlst. Nur öffentliche Nutzer sind erlaubt. - diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index 7346f533c..253715823 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -448,6 +448,7 @@ Global Lista Silenciada Listas de seguidores + Essas são listas de seguidores criadas para seu próprio uso. Você pode seguir usuários de forma privada ou pública. Favoritos com etiqueta Favoritos gerais Público @@ -480,6 +481,7 @@ Criar nova lista %1$s com usuário Cria um conjunto de seguimento %1$s e adiciona %2$s a ele. Nova lista de seguidores + Novo pacote de recomendações Copiar/Clonar lista de seguidores Modificar descrição Esta lista não tem descrição @@ -492,6 +494,7 @@ Criar lista Copiar/Clonar lista Renomear lista + Editar lista Modificar Você está renomeando de para.. @@ -630,6 +633,7 @@ Tags Seguidas Relés Pacotes Seguir + Essas são listas de usuários que você recomenda para outras pessoas. Somente usuários públicos são permitidos. Leituras Algoritmos de feed Mercado @@ -1121,27 +1125,17 @@ Remover usuário da lista Pacote Seguir Membros - - Editar lista Metadados da lista de seguidores Os metadados das listas de seguidores podem ser vistos por qualquer pessoa no Nostr. Apenas os membros privados são criptografados. - Metadados do pacote de recomendações Os metadados dos pacotes de recomendações podem ser vistos por qualquer pessoa no Nostr e são frequentemente publicados em sites como kits iniciais para novos usuários. - Editar pacote de recomendações Nome do pacote Novo nome do pacote Descrição do pacote Nova descrição do pacote - Transmitir lista Transmitir pacote de recomendações - Excluir lista Excluir pacote de recomendações - Novo pacote de recomendações - Essas são listas de seguidores criadas para seu próprio uso. Você pode seguir usuários de forma privada ou pública. - Essas são listas de usuários que você recomenda para outras pessoas. Somente usuários públicos são permitidos. - diff --git a/amethyst/src/main/res/values-sv-rSE/strings.xml b/amethyst/src/main/res/values-sv-rSE/strings.xml index 5a23a5716..d7d545a47 100644 --- a/amethyst/src/main/res/values-sv-rSE/strings.xml +++ b/amethyst/src/main/res/values-sv-rSE/strings.xml @@ -448,6 +448,7 @@ Global Tyst listan Följelistor + Detta är följlistor avsedda för ditt eget bruk. Du kan följa användare privat eller offentligt. Märkta bokmärken Allmänna bokmärken Offentlig @@ -480,6 +481,7 @@ Skapa ny %1$s-lista med användare Skapar ett %1$s-följ-set och lägger till %2$s i det. Ny följelista + Nytt rekommendationspaket Kopiera/Klona följelista Ändra beskrivning Den här listan har ingen beskrivning @@ -492,6 +494,7 @@ Skapa lista Kopiera/Klona lista Byt namn på lista + Redigera lista Ändra Du byter namn från till.. @@ -629,6 +632,7 @@ Följda taggar Reläer Följpaket + Detta är listor med användare som du rekommenderar till andra. Endast offentliga användare är tillåtna. Läsningar Feed algoritmer Marknadsplats @@ -1120,26 +1124,17 @@ Ta bort användare från listan Följpaket Medlemmar - Redigera lista Metadata för följlista Metadata för följlistor kan ses av alla på Nostr. Endast privata medlemmar är krypterade. - Metadata för rekommendationspaket Metadata för rekommendationspaket kan ses av alla på Nostr och publiceras ofta på webbplatser som startpaket för nya användare. - Redigera rekommendationspaket Paketnamn Nytt paketnamn Paketbeskrivning Ny paketbeskrivning - Sänd lista Sänd rekommendationspaket - Ta bort lista Ta bort rekommendationspaket - Nytt rekommendationspaket - Detta är följlistor avsedda för ditt eget bruk. Du kan följa användare privat eller offentligt. - Detta är listor med användare som du rekommenderar till andra. Endast offentliga användare är tillåtna. - From 78c13a7d29f8ba6bc7b4a6acebeb200d9c792867 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 10:36:44 -0500 Subject: [PATCH 16/60] Minor changes to the change log --- .gitignore | 1 + CHANGELOG.md | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b4386f523..72ba3e1b4 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ /.idea/artifacts/* /.idea/kotlinNotebook.xml /.idea/ChatHistory_schema_v3.xml +/.idea/markdown.xml .DS_Store /build /captures diff --git a/CHANGELOG.md b/CHANGELOG.md index ee04cf446..4e6f60a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,9 @@ This version adds support for creating, managing, deleting, and viewing follow lists, which include both public and private members. We've also added similar UI to support for creating, managing, deleting, and viewing follow packs from following.space, allowing you to assemble following lists -not only for yourself,but also as a starter packs for other users. +not only for yourself, but also as a starter packs for other users. You will find a new "My Lists" +menu option in the side bar and Follow buttons when extended behavior to add users directly into +lists or packs. This version also introduces significant improvements to the quality of video compression and hash checks during media upload/download, along with new codecs and a new image gallery for displaying @@ -46,7 +48,7 @@ Improvements: - Removes non-outbox relays from the outbox lists - Adds support bigger, up to 4GB, payloads in NIP-44 - Restructures the default REQ limits from each relay in all feeds -- Adds a guarantee incoming message order to OkHttp websocket implementations to aviod EOSE mismatch +- Adds a guarantee incoming message order to OkHttp websocket implementations to avoid EOSE mismatch - Only downloads DMs and Drafts if the account is writeable / nsec is present - Adds support for copying/cloning follow lists in the UI. - Adds a default relay list for indexers in new accounts with local backup From 719e34ea8d77ce70ebb2afa92a38fa2931685010 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 11:04:13 -0500 Subject: [PATCH 17/60] Less jarring delete buttons on lists --- .../loggedIn/lists/display/PeopleListView.kt | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/PeopleListView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/PeopleListView.kt index edb1092f6..16560c968 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/PeopleListView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/display/PeopleListView.kt @@ -21,28 +21,25 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.display import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.PersonRemove import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedIconButton import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp +import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.note.UserComposeNoAction import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.HalfHalfHorzModifier @@ -94,22 +91,16 @@ fun PeopleListItem( accountViewModel = accountViewModel, nav = nav, ) - IconButton( + OutlinedIconButton( onClick = { onDeleteUser(user) }, - modifier = - HalfPadding - .align(Alignment.CenterVertically) - .background( - color = MaterialTheme.colorScheme.errorContainer, - shape = RoundedCornerShape(percent = 80), - ), + modifier = HalfPadding, ) { Icon( - imageVector = Icons.Default.Delete, - contentDescription = null, - modifier = Modifier.size(20.dp), + imageVector = Icons.Filled.PersonRemove, + contentDescription = stringRes(R.string.remove_user_from_the_list), + tint = MaterialTheme.colorScheme.onErrorContainer, ) } } From d777e94aad715a086af6e274d5854688552b7081 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 16:09:40 +0000 Subject: [PATCH 18/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-zh-rCN/strings.xml | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/res/values-zh-rCN/strings.xml b/amethyst/src/main/res/values-zh-rCN/strings.xml index bf71c04c4..b56c6d01c 100644 --- a/amethyst/src/main/res/values-zh-rCN/strings.xml +++ b/amethyst/src/main/res/values-zh-rCN/strings.xml @@ -444,11 +444,13 @@ 关注列表 所有关注 所有用户关注 + 默认关注列表 通过代理关注 周围的人 全球 静音列表 关注集 + 这些是为您自己使用设计的关注列表。您可以私下或公开关注用户 有标签的书签 常规书签 公开 @@ -483,6 +485,7 @@ 创建用户新的 %1$s 列表 创建 %1$s 关注集,并添加 %2$s 到其中。 新的 %1$s 列表 + 新的关注包 复制/克隆关注集 修改描述 此列表没有描述 @@ -494,7 +497,8 @@ (原始集合描述) 新建集 复制/克隆集 - 重命名集 + 重命名列表 + 编辑列表 修改 正将集合名称从 改为 @@ -633,6 +637,7 @@ 已关注的标签 中继器 关注包 + 这些是您推荐给其他人的用户列表。只允许公开用户。 次浏览 动态源算法 市场 @@ -1119,5 +1124,23 @@ 已经在列表中 私密成员 公开成员 + 私密成员(%1$s) + 公开成员 (%1$s) 添加用户到列表 + 从列表中删除用户 + 关注包 + 成员 + 关注列表元数据 + 关注列表元数据可以被Nostr上的任何人看到。只有您的私人成员是加密的。 + 关注包元数据 + 关注包元数据可以被Nostr上的任何人看见,并且常作为新用户启动包发布在许多网站上。 + 编辑关注包 + 包名 + 新的包名称 + 包说明 + 新的包说明 + 广播列表 + 广播包 + 删除列表 + 删除包 From f7fd1e79f01d39c81698c8dce5acd6350af98ebc Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 11:26:35 -0500 Subject: [PATCH 19/60] Improves creation of lists for users that had none --- .../lists/list/ListOfPeopleListFeedView.kt | 148 +++++++++--------- .../FollowListAndPackAndUserView.kt | 129 ++++++++------- 2 files changed, 144 insertions(+), 133 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/ListOfPeopleListFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/ListOfPeopleListFeedView.kt index dd66d079d..570492539 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/ListOfPeopleListFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/list/ListOfPeopleListFeedView.kt @@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -46,9 +45,8 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding import com.vitorpamplona.amethyst.ui.theme.MaxWidthWithHorzPadding -import com.vitorpamplona.amethyst.ui.theme.Size40dp +import com.vitorpamplona.amethyst.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp -import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.grayText @Composable @@ -60,40 +58,46 @@ fun AllPeopleListFeedView( val peopleListFeedState by peopleListModel.listFlow().collectAsStateWithLifecycle() val followPackFeedState by followPackModel.listFlow().collectAsStateWithLifecycle() - if (peopleListFeedState.isEmpty() && followPackFeedState.isEmpty()) { - AllPeopleListFeedEmpty( - message = stringRes(R.string.follow_set_empty_feed_msg), - ) - } else { - LazyColumn( - state = rememberLazyListState(), - contentPadding = FeedPadding, - ) { - stickyHeader { - Row( - modifier = MaxWidthWithHorzPadding, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = SpacedBy5dp, - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringRes(R.string.follow_sets), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.titleSmall, - ) - Text( - text = stringRes(R.string.follow_sets_explainer), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - ) - } - NewListButton( - onClick = { - nav.nav(Route.PeopleListMetadataEdit()) - }, + LazyColumn( + state = rememberLazyListState(), + contentPadding = FeedPadding, + ) { + stickyHeader { + Row( + modifier = MaxWidthWithHorzPadding, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = SpacedBy5dp, + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = stringRes(R.string.follow_sets), + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.titleSmall, + ) + Text( + text = stringRes(R.string.follow_sets_explainer), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, ) } + NewListButton( + onClick = { + nav.nav(Route.PeopleListMetadataEdit()) + }, + ) } + } + if (peopleListFeedState.isEmpty()) { + item { + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Text( + text = stringRes(R.string.feed_is_empty), + modifier = Modifier.padding(vertical = Size20dp), + ) + HorizontalDivider(thickness = DividerThickness) + } + } + } else { itemsIndexed(peopleListFeedState, key = { _, item -> item.identifierTag }) { _, followSet -> PeopleListItem( modifier = @@ -108,34 +112,46 @@ fun AllPeopleListFeedView( ) HorizontalDivider(thickness = DividerThickness) } - stickyHeader { - Row( - modifier = - Modifier - .fillMaxWidth() - .padding(start = 10.dp, end = 10.dp, top = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = SpacedBy5dp, - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringRes(R.string.discover_follows), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.titleSmall, - ) - Text( - text = stringRes(R.string.discover_follows_explainer), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - ) - } - NewListButton( - onClick = { - nav.nav(Route.FollowPackMetadataEdit()) - }, + } + stickyHeader { + Row( + modifier = + Modifier + .fillMaxWidth() + .padding(start = 10.dp, end = 10.dp, top = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = SpacedBy5dp, + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = stringRes(R.string.discover_follows), + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.titleSmall, + ) + Text( + text = stringRes(R.string.discover_follows_explainer), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, ) } + NewListButton( + onClick = { + nav.nav(Route.FollowPackMetadataEdit()) + }, + ) } + } + if (followPackFeedState.isEmpty()) { + item { + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Text( + text = stringRes(R.string.feed_is_empty), + modifier = Modifier.padding(vertical = Size20dp), + ) + HorizontalDivider(thickness = DividerThickness) + } + } + } else { itemsIndexed(followPackFeedState, key = { _, item -> item.identifierTag }) { _, followSet -> PeopleListItem( modifier = @@ -153,17 +169,3 @@ fun AllPeopleListFeedView( } } } - -@Composable -fun AllPeopleListFeedEmpty(message: String = stringRes(R.string.feed_is_empty)) { - Column( - Modifier - .fillMaxSize() - .padding(horizontal = Size40dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Text(message) - Spacer(modifier = StdVertSpacer) - } -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserView.kt index cffd299fc..2332c2559 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/memberEdit/FollowListAndPackAndUserView.kt @@ -23,8 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.memberEdit import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -48,8 +46,8 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewListButton import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.MaxWidthWithHorzPadding +import com.vitorpamplona.amethyst.ui.theme.Size20dp import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp -import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer import com.vitorpamplona.amethyst.ui.theme.grayText @Composable @@ -63,44 +61,43 @@ fun FollowListAndPackAndUserView( val followPackFeedState by accountViewModel.account.followLists.uiListFlow .collectAsStateWithLifecycle() - if (followSetsState.isEmpty() && followPackFeedState.isEmpty()) { - Column( - Modifier - .fillMaxWidth() - .fillMaxHeight(0.5f), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Text(text = stringRes(R.string.follow_set_empty_dialog_msg)) - Spacer(modifier = StdVertSpacer) - } - } else { - val userName by observeUserName(userToAddOrRemove, accountViewModel) + val userName by observeUserName(userToAddOrRemove, accountViewModel) - LazyColumn(modifier = Modifier.fillMaxWidth()) { - stickyHeader { - Row( - modifier = MaxWidthWithHorzPadding, - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = SpacedBy5dp, - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringRes(R.string.follow_sets), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.titleSmall, - ) - Text( - text = stringRes(R.string.follow_sets_explainer), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - ) - } - NewListButton( - onClick = { nav.nav(Route.PeopleListMetadataEdit()) }, + LazyColumn(modifier = Modifier.fillMaxWidth()) { + stickyHeader { + Row( + modifier = MaxWidthWithHorzPadding, + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = SpacedBy5dp, + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = stringRes(R.string.follow_sets), + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.titleSmall, + ) + Text( + text = stringRes(R.string.follow_sets_explainer), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, ) } + NewListButton( + onClick = { nav.nav(Route.PeopleListMetadataEdit()) }, + ) } + } + if (followSetsState.isEmpty()) { + item { + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Text( + text = stringRes(R.string.feed_is_empty), + modifier = Modifier.padding(vertical = Size20dp), + ) + HorizontalDivider(thickness = DividerThickness) + } + } + } else { itemsIndexed(followSetsState, key = { _, item -> item.identifierTag }) { _, list -> PeopleListAndUserItem( modifier = Modifier.fillMaxWidth(), @@ -136,32 +133,44 @@ fun FollowListAndPackAndUserView( ) HorizontalDivider(thickness = DividerThickness) } - stickyHeader { - Row( - modifier = - Modifier - .fillMaxWidth() - .padding(start = 10.dp, end = 10.dp, top = 10.dp), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = SpacedBy5dp, - ) { - Column(modifier = Modifier.weight(1f)) { - Text( - text = stringRes(R.string.discover_follows), - color = MaterialTheme.colorScheme.primary, - style = MaterialTheme.typography.titleSmall, - ) - Text( - text = stringRes(R.string.discover_follows_explainer), - style = MaterialTheme.typography.bodyMedium, - color = MaterialTheme.colorScheme.grayText, - ) - } - NewListButton( - onClick = { nav.nav(Route.FollowPackMetadataEdit()) }, + } + stickyHeader { + Row( + modifier = + Modifier + .fillMaxWidth() + .padding(start = 10.dp, end = 10.dp, top = 10.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = SpacedBy5dp, + ) { + Column(modifier = Modifier.weight(1f)) { + Text( + text = stringRes(R.string.discover_follows), + color = MaterialTheme.colorScheme.primary, + style = MaterialTheme.typography.titleSmall, + ) + Text( + text = stringRes(R.string.discover_follows_explainer), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.grayText, ) } + NewListButton( + onClick = { nav.nav(Route.FollowPackMetadataEdit()) }, + ) } + } + if (followPackFeedState.isEmpty()) { + item { + Column(horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) { + Text( + text = stringRes(R.string.feed_is_empty), + modifier = Modifier.padding(vertical = Size20dp), + ) + HorizontalDivider(thickness = DividerThickness) + } + } + } else { itemsIndexed(followPackFeedState, key = { _, item -> item.identifierTag }) { _, list -> FollowPackAndUserItem( modifier = Modifier.fillMaxWidth(), From 075a92a709fa583feddf1486ca6e40f3c6216a51 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 11:45:26 -0500 Subject: [PATCH 20/60] Version 1.04 --- amethyst/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/amethyst/build.gradle b/amethyst/build.gradle index 4dcd2040b..e418d0065 100644 --- a/amethyst/build.gradle +++ b/amethyst/build.gradle @@ -44,9 +44,9 @@ android { applicationId = "com.vitorpamplona.amethyst" minSdk = libs.versions.android.minSdk.get().toInteger() targetSdk = libs.versions.android.targetSdk.get().toInteger() - versionCode = 428 - versionName = generateVersionName("1.03.0") - buildConfigField "String", "RELEASE_NOTES_ID", "\"08abe267baf5d7ce14db7975866f929e2794cc23484171aef0816c60a2416597\"" + versionCode = 429 + versionName = generateVersionName("1.04.0") + buildConfigField "String", "RELEASE_NOTES_ID", "\"81a7d493065830f6cb8b97fd8441438e0872ceafb06346226ef6e7c0987b3ac7\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { @@ -151,7 +151,7 @@ android { signingConfig = signingConfigs.debug } } - + // TODO: remove this when lightcompressor uses one MP4 parser only packaging { resources { From a86f64fce5ecf15dab1c480d15a067c540590500 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 12:01:17 -0500 Subject: [PATCH 21/60] Fixes release Id for the zap the devs button --- amethyst/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amethyst/build.gradle b/amethyst/build.gradle index e418d0065..d084ec36d 100644 --- a/amethyst/build.gradle +++ b/amethyst/build.gradle @@ -46,7 +46,7 @@ android { targetSdk = libs.versions.android.targetSdk.get().toInteger() versionCode = 429 versionName = generateVersionName("1.04.0") - buildConfigField "String", "RELEASE_NOTES_ID", "\"81a7d493065830f6cb8b97fd8441438e0872ceafb06346226ef6e7c0987b3ac7\"" + buildConfigField "String", "RELEASE_NOTES_ID", "\"3a03c75d85aaf6b181d3b232d064c4d4feea5c73f0bea2bd91ed61b8da7cd6a6\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { From a1879a93dff3008328cbbb9f77a48d394ad8c245 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 12:26:38 -0500 Subject: [PATCH 22/60] sending a new version for quartz --- quartz/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/build.gradle.kts b/quartz/build.gradle.kts index 664ef157f..0a8bc3321 100644 --- a/quartz/build.gradle.kts +++ b/quartz/build.gradle.kts @@ -255,7 +255,7 @@ mavenPublishing { coordinates( groupId = "com.vitorpamplona.quartz", artifactId = "quartz", - version = "1.03.0" + version = "1.04.0" ) // Configure publishing to Maven Central From 7742e2778092fb0829ebcfaacf39743112bbed9f Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 15:20:56 -0500 Subject: [PATCH 23/60] Moves all hashtags to lowercase and unfollows with ignore case just in case some other client added in uppercase --- .../model/nip51Lists/hashtagLists/HashtagListState.kt | 4 ++-- .../java/com/vitorpamplona/amethyst/ui/MainActivity.kt | 2 +- .../amethyst/ui/components/RichTextViewer.kt | 2 +- .../amethyst/ui/note/elements/DisplayHashtags.kt | 2 +- .../amethyst/ui/note/elements/DisplayUncitedHashtags.kt | 2 +- .../ui/note/nip22Comments/DisplayHashtagExternalId.kt | 2 +- .../screen/loggedIn/profile/hashtags/TabFollowedTags.kt | 2 +- .../amethyst/ui/screen/loggedIn/search/SearchScreen.kt | 2 +- .../com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt | 3 +++ .../quartz/nip51Lists/hashtagList/HashtagListEvent.kt | 6 +++--- .../kotlin/com/vitorpamplona/quartz/utils/ArrayUtils.kt | 8 ++++++++ 11 files changed, 23 insertions(+), 12 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/hashtagLists/HashtagListState.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/hashtagLists/HashtagListState.kt index dd05892a4..8a1341376 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/hashtagLists/HashtagListState.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/nip51Lists/hashtagLists/HashtagListState.kt @@ -89,9 +89,9 @@ class HashtagListState( val hashtagList = getHashtagList() return if (hashtagList == null) { - HashtagListEvent.create(hashtag, true, signer) + HashtagListEvent.create(hashtag.lowercase(), true, signer) } else { - HashtagListEvent.add(hashtagList, hashtag, true, signer) + HashtagListEvent.add(hashtagList, hashtag.lowercase(), true, signer) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt index f6b9baf5b..08b152492 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/MainActivity.kt @@ -141,7 +141,7 @@ fun uriToRoute( return Route.Notification } if (isHashtagRoute(uri)) { - return Route.Hashtag(uri.removePrefix("nostr:").removePrefix("hashtag?id=")) + return Route.Hashtag(uri.removePrefix("nostr:").removePrefix("hashtag?id=").lowercase()) } val nip19 = Nip19Parser.uriToRoute(uri)?.entity diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt index fe52b0f61..c0ca8c5a0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/RichTextViewer.kt @@ -692,7 +692,7 @@ fun HashTag( modifier = remember { Modifier.clickable { - nav.nav(Route.Hashtag(segment.hashtag)) + nav.nav(Route.Hashtag(segment.hashtag.lowercase())) } }, inlineContent = diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt index 9700d74d8..b0300c708 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayHashtags.kt @@ -86,6 +86,6 @@ private fun DisplayTagList( overflow = TextOverflow.Ellipsis, maxLines = 1, ) { - nav.nav(Route.Hashtag(firstTag)) + nav.nav(Route.Hashtag(firstTag.lowercase())) } } 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 8cd1da73b..a7601f1ef 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 @@ -96,7 +96,7 @@ fun DisplayUncitedHashtags( unusedHashtags.forEach { hashtag -> ClickableTextColor( text = "#$hashtag ", - onClick = { nav.nav(Route.Hashtag(hashtag)) }, + onClick = { nav.nav(Route.Hashtag(hashtag.lowercase())) }, linkColor = MaterialTheme.colorScheme.lessImportantLink, ) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayHashtagExternalId.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayHashtagExternalId.kt index 824e38004..47b430521 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayHashtagExternalId.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/nip22Comments/DisplayHashtagExternalId.kt @@ -55,7 +55,7 @@ fun DisplayHashtagExternalId( nav: INav, ) { DisplayHashtagExternalId(externalId.topic) { - nav.nav(Route.Hashtag(externalId.topic)) + nav.nav(Route.Hashtag(externalId.topic.lowercase())) } } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/hashtags/TabFollowedTags.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/hashtags/TabFollowedTags.kt index 718d2b814..9730cfbc6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/hashtags/TabFollowedTags.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/hashtags/TabFollowedTags.kt @@ -57,7 +57,7 @@ fun TabFollowedTags( HashtagHeader( tag = hashtag, account = accountViewModel, - onClick = { nav.nav(Route.Hashtag(hashtag)) }, + onClick = { nav.nav(Route.Hashtag(hashtag.lowercase())) }, ) HorizontalDivider( thickness = DividerThickness, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt index df6aa1058..bc4349cae 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt @@ -257,7 +257,7 @@ private fun DisplaySearchResults( hashTags, key = { _, item -> "#$item" }, ) { _, item -> - HashtagLine(item) { nav.nav(Route.Hashtag(item)) } + HashtagLine(item.lowercase()) { nav.nav(Route.Hashtag(item.lowercase())) } HorizontalDivider( modifier = Modifier.padding(top = 10.dp), diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt index f94abb68d..8f3dea77a 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/TagArrayExt.kt @@ -24,6 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Tag import com.vitorpamplona.quartz.nip01Core.core.TagArray import com.vitorpamplona.quartz.utils.startsWith import com.vitorpamplona.quartz.utils.startsWithAny +import com.vitorpamplona.quartz.utils.startsWithIgnoreCase inline fun TagArray.filterToArray(predicate: (Array) -> Boolean): TagArray = filterTo(ArrayList(), predicate).toTypedArray() @@ -31,6 +32,8 @@ inline fun TagArray.remove(predicate: (Array) -> Boolean): TagArray = fi fun TagArray.remove(startsWith: Array): TagArray = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).toTypedArray() +fun TagArray.removeIgnoreCase(startsWith: Array): TagArray = filterNotTo(ArrayList(this.size), { it.startsWithIgnoreCase(startsWith) }).toTypedArray() + fun TagArray.removeParsing( transform: (Tag) -> R, equalsTo: R, diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt index ccc0e45aa..6eb3162a3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip51Lists/hashtagList/HashtagListEvent.kt @@ -36,8 +36,8 @@ import com.vitorpamplona.quartz.nip31Alts.alt import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List -import com.vitorpamplona.quartz.nip51Lists.remove import com.vitorpamplona.quartz.nip51Lists.removeAny +import com.vitorpamplona.quartz.nip51Lists.removeIgnoreCase import com.vitorpamplona.quartz.utils.TimeUtils @Immutable @@ -140,8 +140,8 @@ class HashtagListEvent( ): HashtagListEvent { val privateTags = earlierVersion.privateTags(signer) ?: throw SignerExceptions.UnauthorizedDecryptionException() return resign( - privateTags = privateTags.remove(HashtagTag.assemble(hashtag)), - tags = earlierVersion.tags.remove(HashtagTag.assemble(hashtag)), + privateTags = privateTags.removeIgnoreCase(HashtagTag.assemble(hashtag)), + tags = earlierVersion.tags.removeIgnoreCase(HashtagTag.assemble(hashtag)), signer = signer, createdAt = createdAt, ) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/ArrayUtils.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/ArrayUtils.kt index db36dd7ce..4f2d8e6ca 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/ArrayUtils.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/ArrayUtils.kt @@ -40,6 +40,14 @@ fun Array.startsWith(startsWith: Array): Boolean { return true } +fun Array.startsWithIgnoreCase(startsWith: Array): Boolean { + if (startsWith.size > this.size) return false + for (tagIdx in startsWith.indices) { + if (!startsWith[tagIdx].equals(this[tagIdx], ignoreCase = true)) return false + } + return true +} + fun Array.startsWithAny(startsWithList: List>): Boolean = startsWithList.any { startsWith(it) } public inline fun Array.lastNotNullOfOrNull(transform: (T) -> R?): R? { From 14e30989248f596ba7b2c4ba192d500e9b53184e Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 15:27:57 -0500 Subject: [PATCH 24/60] Fixes deserialization issues with old jsons that didn't have these properties --- .../java/com/vitorpamplona/amethyst/LocalPreferences.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt index 7f825ffb8..38c81a7ee 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/LocalPreferences.kt @@ -77,9 +77,9 @@ private const val DEBUG_PREFERENCES_NAME = "debug_prefs" @Serializable data class AccountInfo( val npub: String, - val hasPrivKey: Boolean, - val loggedInWithExternalSigner: Boolean, - val isTransient: Boolean, + val hasPrivKey: Boolean = false, + val loggedInWithExternalSigner: Boolean = false, + val isTransient: Boolean = false, ) private object PrefKeys { From bbc4f4281a2d3c6983ae9924c7f94cd6e48d5d43 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 20:30:16 +0000 Subject: [PATCH 25/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-hu-rHU/strings.xml | 23 ++++++++ .../src/main/res/values-pl-rPL/strings.xml | 56 ++++++++++--------- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index b951de13d..0c7151217 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -444,11 +444,13 @@ Követési lista Követettek bejegyzései Összes követett felhasználó + Alapértelmezett követési lista Követés proxyn keresztül Közelben lévők bejegyzései Globális Némítottak bejegyzései Követési gyüjtemények + Ezek a követési listák az Ön saját alkalmazás-használatából lettek kialakítva. A felhasználókat privát vagy nyilvánosan követheti Címkézett könyvjelzők Általános könyvjelzők Nyílvános @@ -483,6 +485,7 @@ Új %1$s lista létrehozása felhasználóval %1$s követési gyüjtemény létrehozása, és hozzáadás a következhöz: %2$s. Új %1$s lista + Új követési lista Követési gyüjtemény másolása/klónozása Leírás módosítása Ennek a listának nincs leírása @@ -495,6 +498,7 @@ Gyüjtemény létrehozása Gyüjtemény másolása/klónozása Gyüjtemény átnevezése + Lista szerkesztése Módosítás Ön átnevezi a követési gyüjteményt erről: erre: @@ -633,6 +637,7 @@ Követett címke Átjátszók Követett csomagok + Ezek a listák azon felhasználók listái, akiket másoknak ajánlhat. Csak nyilvános felhasználók szerepelhetnek a listán. Olvasmányok Hírforrás-algoritmus Piac @@ -1119,5 +1124,23 @@ Már rajta van a listán Privát tagok Nyilvános tagok + Privát tagok (%1$s) + Nyilvános tagok (%1$s) Felhasználó hozzáadása a listához + Felhasználó törlése a listáról + Követési csomag + Tagok + Követési lista metaadatai + A követési listák metaadatai a Nostr-on bárki számára láthatók. Csak a privát tagok adatai vannak titkosítva. + Követési csomag metaadatai + A követési csomag metaadatai a Nostr-on bárki számára láthatók, és gyakran megjelennek számos weboldalon, új felhasználók számára készült kezdőcsomagként. + Követési csomag szerkesztése + Csomagnév + Új csomagnév + Csomagleírás + Új csomagleírás + Közvetítési lista + Közvetítési csomag + Lista törlése + Csomag törlése diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 7f69d130e..16d58bc90 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -55,7 +55,7 @@ Używasz klucza publicznego i kluczy publicznych tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc wgrać Używasz klucza publicznego i kluczy publicznych tylko do odczytu. Zaloguj się za pomocą klucza prywatnego, aby móc zapisać się na udział w wydarzeniu Nieautoryzowane odszyfrowywanie - Sygnatariusz nie autoryzował deszyfrowania wymaganego do wykonania tej operacji. Aktywuj deszyfrowanie NIP-44 w aplikacji podpisującej i spróbuj ponownie + Sygnatariusz nie autoryzował deszyfrowania wymaganego do wykonania tej operacji. Aktywuj deszyfrowanie NIP-44 w aplikacji logującej i spróbuj ponownie Nie odnaleziono sygnatariusza Czy aplikacja sygnatariusza została odinstalowana? Sprawdź, czy aplikacja sygnatariusza jest zainstalowana i czy ma to konto. Wyloguj się i zaloguj ponownie, jeśli aplikacja sygnatariusza uległa zmianie. Zapy @@ -80,7 +80,7 @@ " Obserwujące" "%1$s Obserwowanych" "%1$s Obserwujących" - Twój Profil + Mój Profil Filtry bezpieczeństwa Wyloguj się Pokaż Więcej @@ -440,22 +440,24 @@ Nie Lista obserwowanych Obserwowane - Wszyscy obserwujący + Obserwujące + Domyślna lista obserwowanych Obserwuje przez proxy W pobliżu Wszystkie Zablokowane - Zbiory obserwowanych + Listy obserwowanych + Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników prywatnie lub publicznie Oznaczone zakładki Ogólne zakładki Publiczna Prywatna Mieszana - Wygląda na to, że nie masz jeszcze żadnych zbiorów obserwowanych. - \nDotknij poniżej, aby odświeżyć, lub naciśnij przycisk Dodaj, aby utworzyć nowy. + Wygląda na to, że nie masz jeszcze żadnej listy obserwowanych. + \nDotknij poniżej, aby odświeżyć, lub naciśnij przycisk Dodaj, aby utworzyć listę. - Nowy - Dodaj autora do zbioru obserwowanych + Nowa + Dodaj autora do listy obserwowanych Dodaj lub usuń użytkownika z list, lub utwórz nową listę z tym użytkownikiem. Ikona dla listy %1$s %1$s jest uczestnikiem publicznym @@ -473,25 +475,26 @@ %1$s nie jest na liście %1$s nie jest uczestnikiem Twoje listy oraz %1$s - Twój zbiór obserwowanych - Nie znaleziono zbiorów obserwowanych lub nie masz żadnych zbiorów obserwowanych. Dotknij poniżej, aby odświeżyć lub użyj menu, aby go utworzyć. + Twoja lista obserwowanych + Nie znaleziono list obserwowanych lub nie masz żadnych list obserwowanych. Naciśnij poniżej, aby odświeżyć lub użyj menu, aby utworzyć nową. Podczas pobierania wystąpił błąd: %1$s Utwórz nową listę \"Utwórz nową listę %1$s z użytkownikiem Tworzy zbiór obserwowanych %1$s i dodaje do niego %2$s. - Nowa lista %1$s - Kopiuj/Klonuj zbiór obserwowanych + Nowa lista + Kopiuj/Sklonuj listę obserwowanych Modyfikuj opis Ta lista nie ma opisu Aktualny opis: - Możesz wybrać własną nazwę/opis dla sklonowanego zbioru poniżej. - Nazwa zbioru + Ustaw nową nazwę/opis dla sklonowanej listy poniżej. + Nazwa listy (Nazwa Oryginalna) - Opis zbioru (opcjonalnie) - (Opis oryginalnego zbioru) - Utwórz zbiór - Kopiuj/Klonuj zbiór - Zmień nazwę zbioru + Opis listy (opcjonalnie) + Opis nowej listy + Utwórz listę + Kopiuj/Sklonuj listę + Zmień nazwę listy + Edytuj listę Modyfikuj Zmieniasz nazwę z do.. @@ -777,11 +780,11 @@ Nie znaleziono portfeli Lightning Zapłacone Portfel %1$s - Błąd podczas otwierania aplikacji podpisującej - Nie można odnaleźć aplikacji podpisującej. Sprawdź, czy aplikacja nie została odinstalowana + Błąd podczas otwierania aplikacji logującej + Nie można odnaleźć aplikacji logującej. Sprawdź, czy aplikacja nie została odinstalowana Prośba o zalogowanie została odrzucona - Odrzucono aplikację podpisującego - Upewnij się, że aplikacja podpisującego autoryzuje tę transakcję + Prośba o zalogowanie odrzucona + Upewnij się, że aplikacja logującego autoryzuje tę operację Nie znaleziono portfeli do zapłacenia faktury z Lightning (Error: %1$s). Proszę zainstalować Lightning wallet, aby używać zapów Nie znaleziono portfeli do zapłacenia faktury z Lightning. Proszę zainstalować Lightning wallet, aby używać zapów Ukryte słowa @@ -1088,10 +1091,10 @@ Nie udało się otworzyć pliku Brak zainstalowanych aplikacji torrent do otwarcia i pobrania pliku. Zdarzenie nie ma wystarczającej ilości informacji, aby zbudować link magnetyczny - Moje Listy/Zbiory + Moje Listy/Zestawy Moje listy Użytkownicy - Wybierz listę, aby filtrować aktualności + Wybierz listę profili, aby filtrować aktualności Wyloguj się przy blokowaniu urządzenia Wiadomość prywatna Publiczna wiadomość @@ -1116,6 +1119,9 @@ Już jest na liście Prywatni uczestnicy Uczestnicy publiczni + Prywatni uczestnicy (%1$s) Dodaj użytkownika do listy Usuń użytkownika z listy + Uczestnicy + Usuń listę From 673d8d2c309849b2cc80fc1ab3c53e931fd35f91 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 16:11:58 -0500 Subject: [PATCH 26/60] Makes sure the Zap the Devs dialog doesn't appear behind the status bar --- .../amethyst/ui/note/ZapCustomDialog.kt | 160 ++++++++++-------- amethyst/src/main/res/values/strings.xml | 1 + 2 files changed, 92 insertions(+), 69 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt index 5f16c7d80..127abf1df 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt @@ -28,13 +28,15 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -42,6 +44,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -68,12 +71,12 @@ import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge import com.vitorpamplona.amethyst.ui.components.TextSpinner import com.vitorpamplona.amethyst.ui.components.TitleExplainer import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage +import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.note.buttons.CloseButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ButtonBorder import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer -import com.vitorpamplona.amethyst.ui.theme.DoubleVertSpacer import com.vitorpamplona.amethyst.ui.theme.Size10dp import com.vitorpamplona.amethyst.ui.theme.Size55dp import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer @@ -281,6 +284,7 @@ fun ZapButton( } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun PayViaIntentDialog( payingInvoices: ImmutableList, @@ -289,9 +293,8 @@ fun PayViaIntentDialog( onError: (UserBasedErrorMessage) -> Unit, justShowError: (UserBasedErrorMessage) -> Unit, ) { - val context = LocalContext.current - if (payingInvoices.size == 1) { + val context = LocalContext.current val payable = payingInvoices.first() payViaIntent(payable.invoice, context, onClose) { onError(UserBasedErrorMessage(it, payable.info.user)) @@ -307,71 +310,27 @@ fun PayViaIntentDialog( ), ) { SetDialogToEdgeToEdge() - Surface { - Column(modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState())) { - Row( - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - CloseButton(onPress = onClose) - } - Spacer(modifier = DoubleVertSpacer) - - payingInvoices.forEachIndexed { index, payable -> - val paid = remember { mutableStateOf(false) } - - Row( - verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(vertical = Size10dp), - ) { - if (payable.info.user != null) { - BaseUserPicture(payable.info.user, Size55dp, accountViewModel = accountViewModel) - } else { - DisplayBlankAuthor(size = Size55dp, accountViewModel = accountViewModel) - } - - Spacer(modifier = DoubleHorzSpacer) - - Column(modifier = Modifier.weight(1f)) { - if (payable.info.user != null) { - UsernameDisplay(payable.info.user, accountViewModel = accountViewModel) - } else { - Text( - text = stringRes(id = R.string.wallet_number, index + 1), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) - } - Row { - Text( - text = showAmount((payable.amountMilliSats / 1000.0f).toBigDecimal()), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) - Spacer(modifier = StdHorzSpacer) - Text( - text = stringRes(id = R.string.sats), - maxLines = 1, - overflow = TextOverflow.Ellipsis, - fontWeight = FontWeight.Bold, - fontSize = 18.sp, - ) - } - } - - Spacer(modifier = DoubleHorzSpacer) - - PayButton(isActive = !paid.value) { - payViaIntent(payable.invoice, context, { paid.value = true }) { - justShowError(UserBasedErrorMessage(it, null)) - } - } - } + Scaffold( + topBar = { + TopBarWithBackButton(stringRes(id = R.string.manual_zaps), onClose) + }, + ) { pad -> + LazyColumn( + Modifier.padding( + 16.dp, + pad.calculateTopPadding(), + 16.dp, + pad.calculateBottomPadding(), + ), + ) { + itemsIndexed( + payingInvoices, + key = { _: Int, invoice: ZapPaymentHandler.Payable -> + invoice.invoice + }, + ) { index, payable -> + DisplayPayable(index, payable, justShowError, accountViewModel) } } } @@ -379,6 +338,69 @@ fun PayViaIntentDialog( } } +@Composable +fun DisplayPayable( + index: Int, + payable: ZapPaymentHandler.Payable, + justShowError: (UserBasedErrorMessage) -> Unit, + accountViewModel: AccountViewModel, +) { + val paid = rememberSaveable(payable) { mutableStateOf(false) } + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(vertical = Size10dp), + ) { + if (payable.info.user != null) { + BaseUserPicture(payable.info.user, Size55dp, accountViewModel = accountViewModel) + } else { + DisplayBlankAuthor(size = Size55dp, accountViewModel = accountViewModel) + } + + Spacer(modifier = DoubleHorzSpacer) + + Column(modifier = Modifier.weight(1f)) { + if (payable.info.user != null) { + UsernameDisplay(payable.info.user, accountViewModel = accountViewModel) + } else { + Text( + text = stringRes(id = R.string.wallet_number, index + 1), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + ) + } + Row { + Text( + text = showAmount((payable.amountMilliSats / 1000.0f).toBigDecimal()), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + ) + Spacer(modifier = StdHorzSpacer) + Text( + text = stringRes(id = R.string.sats), + maxLines = 1, + overflow = TextOverflow.Ellipsis, + fontWeight = FontWeight.Bold, + fontSize = 18.sp, + ) + } + } + + Spacer(modifier = DoubleHorzSpacer) + val context = LocalContext.current + + PayButton(isActive = !paid.value) { + payViaIntent(payable.invoice, context, { paid.value = true }) { + justShowError(UserBasedErrorMessage(it, null)) + } + } + } +} + fun payViaIntent( invoice: String, context: Context, diff --git a/amethyst/src/main/res/values/strings.xml b/amethyst/src/main/res/values/strings.xml index 86da1355d..86328a8ec 100644 --- a/amethyst/src/main/res/values/strings.xml +++ b/amethyst/src/main/res/values/strings.xml @@ -378,6 +378,7 @@ Block and Report Block + Manual Zap Splits Bookmarks Drafts Private Bookmarks From fef78cd55718a77ae7e20e6cb426da4a1c64c2c4 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 16:41:02 -0500 Subject: [PATCH 27/60] Fixes test case for payload type --- .../java/com/vitorpamplona/amethyst/ImageUploadTesting.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt index 6f940370e..f0159a048 100644 --- a/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt +++ b/amethyst/src/androidTest/java/com/vitorpamplona/amethyst/ImageUploadTesting.kt @@ -110,7 +110,7 @@ class ImageUploadTesting { .upload( inputStream = inputStream, hash = initialHash, - length = paylod.size, + length = paylod.size.toLong(), baseFileName = "filename.png", contentType = "image/png", alt = null, From f7e72c57d3d5754f3ea673dd8182b9f524c2959c Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 16:41:47 -0500 Subject: [PATCH 28/60] Turn the Pay zaps via intent dialog into a full screen with route --- .../ui/components/ReusableZapButton.kt | 55 ++++++------ .../amethyst/ui/navigation/AppNavigation.kt | 3 + .../amethyst/ui/navigation/routes/Routes.kt | 6 ++ .../amethyst/ui/note/PollNote.kt | 56 ++++-------- .../amethyst/ui/note/ReactionsRow.kt | 73 +++++++++------- .../amethyst/ui/note/ZapCustomDialog.kt | 85 +++++++++---------- .../ui/screen/loggedIn/AccountViewModel.kt | 2 + 7 files changed, 140 insertions(+), 140 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt index dc9d10831..5e1dbae50 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/ReusableZapButton.kt @@ -50,12 +50,14 @@ import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.ZapPaymentHandler import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.UserFinderFilterAssemblerSubscription import com.vitorpamplona.amethyst.ui.actions.CrossfadeIfEnabled +import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.ObserveZapIcon -import com.vitorpamplona.amethyst.ui.note.PayViaIntentDialog import com.vitorpamplona.amethyst.ui.note.ZapAmountChoicePopup import com.vitorpamplona.amethyst.ui.note.ZapIcon import com.vitorpamplona.amethyst.ui.note.ZappedIcon +import com.vitorpamplona.amethyst.ui.note.payViaIntent import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp @@ -64,11 +66,12 @@ import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size35dp import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid /** * Configuration for zap button behavior and appearance @@ -91,6 +94,7 @@ data class ZapButtonCallbacks( val onZapComplete: ((Boolean) -> Unit)? = null, ) +@OptIn(ExperimentalUuidApi::class) @Composable fun ReusableZapButton( baseNote: Note, @@ -100,9 +104,6 @@ fun ReusableZapButton( callbacks: ZapButtonCallbacks = ZapButtonCallbacks(), ) { var wantsToZap by remember { mutableStateOf?>(null) } - var wantsToPay by remember(baseNote) { - mutableStateOf>(persistentListOf()) - } // Makes sure the user is loaded to get his ln address ahead of time (for DVM buttons) if (config.showUserFinderSubscription) { @@ -138,7 +139,19 @@ fun ReusableZapButton( accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, message, toUser) } }, - onPayViaIntent = { wantsToPay = it }, + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { + zappingProgress = 0f + accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, UserBasedErrorMessage(it, payable.info.user)) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) + } + }, ) }, modifier = Modifier.fillMaxWidth(), @@ -166,25 +179,17 @@ fun ReusableZapButton( onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } }, - onPayViaIntent = { wantsToPay = it }, - ) - } - - if (wantsToPay.isNotEmpty()) { - PayViaIntentDialog( - payingInvoices = wantsToPay, - accountViewModel = accountViewModel, - onClose = { wantsToPay = persistentListOf() }, - onError = { - wantsToPay = persistentListOf() - scope.launch { - zappingProgress = 0f - accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, it) - } - }, - justShowError = { - scope.launch { - accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, it) + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { + zappingProgress = 0f + accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, UserBasedErrorMessage(it, payable.info.user)) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) } }, ) 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 b3d2671ea..af2e26dad 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 @@ -53,6 +53,7 @@ import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.getRouteWithArguments import com.vitorpamplona.amethyst.ui.navigation.routes.isBaseRoute import com.vitorpamplona.amethyst.ui.navigation.routes.isSameRoute +import com.vitorpamplona.amethyst.ui.note.PayViaIntentScreen import com.vitorpamplona.amethyst.ui.note.nip22Comments.ReplyCommentPostScreen import com.vitorpamplona.amethyst.ui.screen.AccountStateViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountSwitcherAndLeftDrawerLayout @@ -137,6 +138,8 @@ fun AppNavigation( composableFromBottomArgs { PeopleListMetadataScreen(it.dTag, accountViewModel, nav) } composableFromBottomArgs { FollowPackMetadataScreen(it.dTag, accountViewModel, nav) } + composableFromBottomArgs { PayViaIntentScreen(it.paymentId, accountViewModel, nav) } + composableFromBottomArgs { NewUserMetadataScreen(nav, accountViewModel) } composable { SearchScreen(accountViewModel, nav) } 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 778073e83..becfc33bc 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 @@ -252,6 +252,11 @@ sealed class Route { val version: String? = null, val draft: String? = null, ) : Route() + + @Serializable + data class ManualZapSplitPayment( + val paymentId: String, + ) : Route() } inline fun isBaseRoute(navController: NavHostController): Boolean = navController.currentBackStackEntry?.destination?.hasRoute() == true @@ -310,6 +315,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/PollNote.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt index 22183a391..263b563c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/PollNote.kt @@ -52,7 +52,6 @@ import androidx.compose.runtime.MutableState import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf -import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -81,6 +80,7 @@ import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.components.toasts.StringToastMsg import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeToMessage import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel @@ -102,14 +102,14 @@ import com.vitorpamplona.quartz.nip01Core.core.ImmutableListOfLists import com.vitorpamplona.quartz.nip01Core.core.toImmutableListOfLists import com.vitorpamplona.quartz.nip31Alts.AltTag import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent -import com.vitorpamplona.quartz.utils.TimeUtils import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlin.math.roundToInt +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid @Preview @Composable @@ -499,7 +499,7 @@ private fun RenderOptionBeforeVote( } @Composable -@OptIn(ExperimentalFoundationApi::class) +@OptIn(ExperimentalFoundationApi::class, ExperimentalUuidApi::class) fun ZapVote( baseNote: Note, poolOption: PollOption, @@ -513,14 +513,8 @@ fun ZapVote( val isLoggedUser by remember { derivedStateOf { accountViewModel.isLoggedUser(baseNote.author) } } var wantsToZap by remember { mutableStateOf(false) } - var wantsToPay by remember { - mutableStateOf>( - persistentListOf(), - ) - } var zappingProgress by remember { mutableFloatStateOf(0f) } - var zapStartingTime by remember { mutableLongStateOf(0L) } var showErrorMessageDialog by remember { mutableStateOf(null) } @@ -563,7 +557,6 @@ fun ZapVote( accountViewModel.zapAmountChoices().size == 1 && pollViewModel.isValidInputVoteAmount(accountViewModel.zapAmountChoices().first()) ) { - zapStartingTime = TimeUtils.now() accountViewModel.zap( baseNote, accountViewModel.zapAmountChoices().first() * 1000, @@ -584,12 +577,13 @@ fun ZapVote( ), ) { if (wantsToZap) { + val context = LocalContext.current FilteredZapAmountChoicePopup( baseNote, accountViewModel, pollViewModel, poolOption.option, - onZapStarts = { zapStartingTime = TimeUtils.now() }, + onZapStarts = { }, onDismiss = { wantsToZap = false zappingProgress = 0f @@ -600,33 +594,17 @@ fun ZapVote( zappingProgress = 0f }, onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } }, - onPayViaIntent = { wantsToPay = it }, - ) - } - - if (wantsToPay.isNotEmpty()) { - PayViaIntentDialog( - payingInvoices = wantsToPay, - accountViewModel = accountViewModel, - onClose = { wantsToPay = persistentListOf() }, - onError = { - wantsToPay = persistentListOf() - scope.launch { - zappingProgress = 0f - showErrorMessageDialog = - StringToastMsg( - stringRes(context, R.string.error_dialog_zap_error), - it.error, - ) - } - }, - justShowError = { - scope.launch { - showErrorMessageDialog = - StringToastMsg( - stringRes(context, R.string.error_dialog_zap_error), - it.error, - ) + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { error -> + zappingProgress = 0f + showErrorMessageDialog = StringToastMsg(stringRes(context, R.string.error_dialog_zap_error), error) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) } }, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt index 20560510c..bd8d3d7f4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ReactionsRow.kt @@ -114,6 +114,7 @@ import com.vitorpamplona.amethyst.ui.components.AnimatedBorderTextCornerRadius import com.vitorpamplona.amethyst.ui.components.ClickableBox import com.vitorpamplona.amethyst.ui.components.GenericLoadable import com.vitorpamplona.amethyst.ui.components.InLineIconRenderer +import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.navigation.routes.routeReplyTo @@ -169,6 +170,8 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlin.math.roundToInt +import kotlin.uuid.ExperimentalUuidApi +import kotlin.uuid.Uuid @Composable fun ReactionsRow( @@ -970,7 +973,7 @@ private fun likeClick( } @Composable -@OptIn(ExperimentalFoundationApi::class) +@OptIn(ExperimentalFoundationApi::class, ExperimentalUuidApi::class) fun ZapReaction( baseNote: Note, grayTint: Color, @@ -983,12 +986,6 @@ fun ZapReaction( var wantsToZap by remember { mutableStateOf(false) } var wantsToChangeZapAmount by remember { mutableStateOf(false) } var wantsToSetCustomZap by remember { mutableStateOf(false) } - var wantsToPay by - remember(baseNote) { - mutableStateOf>( - persistentListOf(), - ) - } val context = LocalContext.current val scope = rememberCoroutineScope() @@ -1022,7 +1019,19 @@ fun ZapReaction( accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, message, user) } }, - onPayViaIntent = { wantsToPay = it }, + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { error -> + zappingProgress = 0f + accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, UserBasedErrorMessage(error, payable.info.user)) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) + } + }, ) } }, @@ -1053,7 +1062,19 @@ fun ZapReaction( } }, onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } }, - onPayViaIntent = { wantsToPay = it }, + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { error -> + zappingProgress = 0f + accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, UserBasedErrorMessage(error, payable.info.user)) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) + } + }, ) } @@ -1064,26 +1085,6 @@ fun ZapReaction( ) } - if (wantsToPay.isNotEmpty()) { - PayViaIntentDialog( - payingInvoices = wantsToPay, - accountViewModel = accountViewModel, - onClose = { wantsToPay = persistentListOf() }, - onError = { - wantsToPay = persistentListOf() - scope.launch { - zappingProgress = 0f - accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, it) - } - }, - justShowError = { - scope.launch { - accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, it) - } - }, - ) - } - if (wantsToSetCustomZap) { ZapCustomDialog( onZapStarts = { zapStartingTime = TimeUtils.now() }, @@ -1095,7 +1096,19 @@ fun ZapReaction( } }, onProgress = { scope.launch(Dispatchers.Main) { zappingProgress = it } }, - onPayViaIntent = { wantsToPay = it }, + onPayViaIntent = { + if (it.size == 1) { + val payable = it.first() + payViaIntent(payable.invoice, context, { }) { error -> + zappingProgress = 0f + accountViewModel.toastManager.toast(R.string.error_dialog_zap_error, UserBasedErrorMessage(error, payable.info.user)) + } + } else { + val uid = Uuid.random().toString() + accountViewModel.tempManualPaymentCache.put(uid, it) + nav.nav(Route.ManualZapSplitPayment(uid)) + } + }, accountViewModel = accountViewModel, baseNote = baseNote, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt index 127abf1df..019455527 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/ZapCustomDialog.kt @@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn @@ -67,10 +68,10 @@ import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.ZapPaymentHandler -import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge import com.vitorpamplona.amethyst.ui.components.TextSpinner import com.vitorpamplona.amethyst.ui.components.TitleExplainer import com.vitorpamplona.amethyst.ui.components.toasts.multiline.UserBasedErrorMessage +import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton import com.vitorpamplona.amethyst.ui.note.buttons.CloseButton import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel @@ -286,52 +287,42 @@ fun ZapButton( @OptIn(ExperimentalMaterial3Api::class) @Composable -fun PayViaIntentDialog( - payingInvoices: ImmutableList, +fun PayViaIntentScreen( + paymentId: String, accountViewModel: AccountViewModel, - onClose: () -> Unit, - onError: (UserBasedErrorMessage) -> Unit, - justShowError: (UserBasedErrorMessage) -> Unit, + nav: INav, ) { - if (payingInvoices.size == 1) { - val context = LocalContext.current - val payable = payingInvoices.first() - payViaIntent(payable.invoice, context, onClose) { - onError(UserBasedErrorMessage(it, payable.info.user)) - } - } else { - Dialog( - onDismissRequest = onClose, - properties = - DialogProperties( - dismissOnClickOutside = false, - usePlatformDefaultWidth = false, - decorFitsSystemWindows = false, - ), - ) { - SetDialogToEdgeToEdge() + Scaffold( + topBar = { + TopBarWithBackButton(stringRes(id = R.string.manual_zaps), nav::popBack) + }, + ) { pad -> + val list = accountViewModel.tempManualPaymentCache.get(paymentId) - Scaffold( - topBar = { - TopBarWithBackButton(stringRes(id = R.string.manual_zaps), onClose) - }, - ) { pad -> - LazyColumn( - Modifier.padding( - 16.dp, - pad.calculateTopPadding(), - 16.dp, - pad.calculateBottomPadding(), - ), - ) { - itemsIndexed( - payingInvoices, - key = { _: Int, invoice: ZapPaymentHandler.Payable -> - invoice.invoice - }, - ) { index, payable -> - DisplayPayable(index, payable, justShowError, accountViewModel) - } + if (list == null) { + Column( + Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Text(stringRes(R.string.feed_is_empty)) + } + } else { + LazyColumn( + Modifier.padding( + 16.dp, + pad.calculateTopPadding(), + 16.dp, + pad.calculateBottomPadding(), + ), + ) { + itemsIndexed( + accountViewModel.tempManualPaymentCache.get(paymentId) ?: emptyList(), + key = { _: Int, invoice: ZapPaymentHandler.Payable -> + invoice.invoice + }, + ) { index, payable -> + DisplayPayable(index, payable, accountViewModel) } } } @@ -342,7 +333,6 @@ fun PayViaIntentDialog( fun DisplayPayable( index: Int, payable: ZapPaymentHandler.Payable, - justShowError: (UserBasedErrorMessage) -> Unit, accountViewModel: AccountViewModel, ) { val paid = rememberSaveable(payable) { mutableStateOf(false) } @@ -395,7 +385,10 @@ fun DisplayPayable( PayButton(isActive = !paid.value) { payViaIntent(payable.invoice, context, { paid.value = true }) { - justShowError(UserBasedErrorMessage(it, null)) + accountViewModel.toastManager.toast( + R.string.error_dialog_zap_error, + UserBasedErrorMessage(it, payable.info.user), + ) } } } 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 66283da30..3e44b809e 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 @@ -175,6 +175,8 @@ class AccountViewModel( val toastManager = ToastManager() val feedStates = AccountFeedContentStates(account, viewModelScope) + val tempManualPaymentCache = LruCache>(5) + @OptIn(ExperimentalCoroutinesApi::class) val notificationHasNewItems = combineTransform( From f630c340457eacd33dfb2a1e41e288768d2d79c1 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 21:51:29 +0000 Subject: [PATCH 29/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-pl-rPL/strings.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 16d58bc90..052f3924d 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -447,7 +447,7 @@ Wszystkie Zablokowane Listy obserwowanych - Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników prywatnie lub publicznie + Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników dyskretnie lub otwarcie Oznaczone zakładki Ogólne zakładki Publiczna @@ -482,6 +482,7 @@ \"Utwórz nową listę %1$s z użytkownikiem Tworzy zbiór obserwowanych %1$s i dodaje do niego %2$s. Nowa lista + Nowa Kategoria Kopiuj/Sklonuj listę obserwowanych Modyfikuj opis Ta lista nie ma opisu @@ -633,6 +634,7 @@ Obserwowane tagi Transmitery Godne uwagi + Są to listy profili, które polecasz innym użytkownikom. Dozwolone są wyłącznie profile publiczne. Popularne Wybrane przez algorytm Market @@ -1122,6 +1124,18 @@ Prywatni uczestnicy (%1$s) Dodaj użytkownika do listy Usuń użytkownika z listy + Kategoria profilów Uczestnicy + Metadane listy profili + Metadane kategorii profilów + Metadane kategorii profilów są widoczne dla wszystkich użytkowników serwisu Nostr i często publikowane na wielu stronach internetowych jako zestawy startowe dla nowych użytkowników. + Edytuj kategorię profili + Nazwa kategorii + Nowa nazwa kategorii + Opis kategorii + Opis nowej kategorii + Upowszechnij listę + Upowszechnij kategorię Usuń listę + Usuń kategorię From 5264bd2cbcff3f67dbd230c59919db6c9e29f480 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 16:51:45 -0500 Subject: [PATCH 30/60] v1.04.1 --- CHANGELOG.md | 18 ++++++++++++++++++ amethyst/build.gradle | 2 +- quartz/build.gradle.kts | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e6f60a1b..2b54d77de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + +# [Release v1.04.1: Bugfixes](https://github.com/vitorpamplona/amethyst/releases/tag/v1.04.1) - 2025-11-15 + +#Amethyst v1.04.1: Bug fixes + +- Fixes crashing when starting +- Fixes hashtag unfollowing for mixed case tags +- Fixes release Id for the zap the devs button +- Fixes quartz version for a release to Maven +- Fixes disappearing of the Zap the Devs Manual Payment screen +- Fixes back button of the Zap the Devs Manual Payment screen staying behind the status bar + +Translations: +- Polish by @npub16gjyljum0ksrrm28zzvejydgxwfm7xse98zwc4hlgq8epxeuggushqwyrm +- Hungarian by @npub1dnvslq0vvrs8d603suykc4harv94yglcxwna9sl2xu8grt2afm3qgfh0tp + +Download: http://amethyst.social + # [Release v1.04.0: List Management](https://github.com/vitorpamplona/amethyst/releases/tag/v1.04.0) - 2025-11-15 diff --git a/amethyst/build.gradle b/amethyst/build.gradle index d084ec36d..c29b4ade6 100644 --- a/amethyst/build.gradle +++ b/amethyst/build.gradle @@ -45,7 +45,7 @@ android { minSdk = libs.versions.android.minSdk.get().toInteger() targetSdk = libs.versions.android.targetSdk.get().toInteger() versionCode = 429 - versionName = generateVersionName("1.04.0") + versionName = generateVersionName("1.04.1") buildConfigField "String", "RELEASE_NOTES_ID", "\"3a03c75d85aaf6b181d3b232d064c4d4feea5c73f0bea2bd91ed61b8da7cd6a6\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/quartz/build.gradle.kts b/quartz/build.gradle.kts index 0a8bc3321..a3830ac7b 100644 --- a/quartz/build.gradle.kts +++ b/quartz/build.gradle.kts @@ -255,7 +255,7 @@ mavenPublishing { coordinates( groupId = "com.vitorpamplona.quartz", artifactId = "quartz", - version = "1.04.0" + version = "1.04.1" ) // Configure publishing to Maven Central From b6a7d9146faa39bafa7a9889c549a69fcf9eb1c2 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 21:52:58 +0000 Subject: [PATCH 31/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-pl-rPL/strings.xml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 16d58bc90..052f3924d 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -447,7 +447,7 @@ Wszystkie Zablokowane Listy obserwowanych - Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników prywatnie lub publicznie + Są to listy obserwowanych przeznaczone do prywatnego użytku. Możesz obserwować użytkowników dyskretnie lub otwarcie Oznaczone zakładki Ogólne zakładki Publiczna @@ -482,6 +482,7 @@ \"Utwórz nową listę %1$s z użytkownikiem Tworzy zbiór obserwowanych %1$s i dodaje do niego %2$s. Nowa lista + Nowa Kategoria Kopiuj/Sklonuj listę obserwowanych Modyfikuj opis Ta lista nie ma opisu @@ -633,6 +634,7 @@ Obserwowane tagi Transmitery Godne uwagi + Są to listy profili, które polecasz innym użytkownikom. Dozwolone są wyłącznie profile publiczne. Popularne Wybrane przez algorytm Market @@ -1122,6 +1124,18 @@ Prywatni uczestnicy (%1$s) Dodaj użytkownika do listy Usuń użytkownika z listy + Kategoria profilów Uczestnicy + Metadane listy profili + Metadane kategorii profilów + Metadane kategorii profilów są widoczne dla wszystkich użytkowników serwisu Nostr i często publikowane na wielu stronach internetowych jako zestawy startowe dla nowych użytkowników. + Edytuj kategorię profili + Nazwa kategorii + Nowa nazwa kategorii + Opis kategorii + Opis nowej kategorii + Upowszechnij listę + Upowszechnij kategorię Usuń listę + Usuń kategorię From ae6f37a52f2ae48c7c1c24e1b5f5b12c0b1dd614 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 17:28:55 -0500 Subject: [PATCH 32/60] v1.04.2 to appease the PlayStore --- amethyst/build.gradle | 4 ++-- quartz/build.gradle.kts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/amethyst/build.gradle b/amethyst/build.gradle index c29b4ade6..43fb7b33a 100644 --- a/amethyst/build.gradle +++ b/amethyst/build.gradle @@ -44,8 +44,8 @@ android { applicationId = "com.vitorpamplona.amethyst" minSdk = libs.versions.android.minSdk.get().toInteger() targetSdk = libs.versions.android.targetSdk.get().toInteger() - versionCode = 429 - versionName = generateVersionName("1.04.1") + versionCode = 430 + versionName = generateVersionName("1.04.2") buildConfigField "String", "RELEASE_NOTES_ID", "\"3a03c75d85aaf6b181d3b232d064c4d4feea5c73f0bea2bd91ed61b8da7cd6a6\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/quartz/build.gradle.kts b/quartz/build.gradle.kts index a3830ac7b..8fd17de15 100644 --- a/quartz/build.gradle.kts +++ b/quartz/build.gradle.kts @@ -255,7 +255,7 @@ mavenPublishing { coordinates( groupId = "com.vitorpamplona.quartz", artifactId = "quartz", - version = "1.04.1" + version = "1.04.2" ) // Configure publishing to Maven Central From 5f6e65f76880e3a5bac527fad08c56f13f54de3f Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sat, 15 Nov 2025 22:35:09 +0000 Subject: [PATCH 33/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-pl-rPL/strings.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 052f3924d..5b574ba1f 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -344,6 +344,7 @@ Wyślij zgłoszenie Zablokuj i zgłoś Zablokuj + Ręczny podział zapów Zakładki Projekty Prywatne Zakładki @@ -480,7 +481,7 @@ Podczas pobierania wystąpił błąd: %1$s Utwórz nową listę \"Utwórz nową listę %1$s z użytkownikiem - Tworzy zbiór obserwowanych %1$s i dodaje do niego %2$s. + Tworzy zestaw obserwowanych %1$s i dodaje do niego %2$s. Nowa lista Nowa Kategoria Kopiuj/Sklonuj listę obserwowanych @@ -1121,12 +1122,14 @@ Już jest na liście Prywatni uczestnicy Uczestnicy publiczni - Prywatni uczestnicy (%1$s) + Uczestnicy prywatni (%1$s) + Uczestnicy publiczni (%1$s) Dodaj użytkownika do listy Usuń użytkownika z listy Kategoria profilów Uczestnicy Metadane listy profili + Metadane listy obserwowanych są widoczne dla wszystkich użytkowników w sieci Nostr. Tylko Twoi uczestnicy prywatni są zaszyfrowani. Metadane kategorii profilów Metadane kategorii profilów są widoczne dla wszystkich użytkowników serwisu Nostr i często publikowane na wielu stronach internetowych jako zestawy startowe dla nowych użytkowników. Edytuj kategorię profili From 4f5acc5c29ff9d5ac979f72a896889cfa9d068b5 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Sat, 15 Nov 2025 17:57:03 -0500 Subject: [PATCH 34/60] Updates to the latest zapstore config --- zapstore.yaml | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/zapstore.yaml b/zapstore.yaml index fb1e36998..ffc1ede49 100644 --- a/zapstore.yaml +++ b/zapstore.yaml @@ -1,16 +1,13 @@ -amethyst: - android: - name: Amethyst - description: The all-in-one Nostr client - license: MIT - builder: npub142gywvjkq0dv6nupggyn2euhx4nduwc7yz5f24ah9rpmunr2s39se3xrj0 - repository: https://github.com/vitorpamplona/amethyst - artifacts: - - amethyst-googleplay-arm64-v8a-v%v.apk - - amethyst-googleplay-armeabi-v7a-v%v.apk - - amethyst-googleplay-universal-v%v.apk - - amethyst-googleplay-x86-v%v.apk - - amethyst-googleplay-x86_64-v%v.apk +name: Amethyst +description: The all-in-one Nostr client +license: MIT +builder: npub142gywvjkq0dv6nupggyn2euhx4nduwc7yz5f24ah9rpmunr2s39se3xrj0 +repository: https://github.com/vitorpamplona/amethyst +homepage: https://amethyst.social/ +assets: + - amethyst-googleplay.*.apk +remote_metadata: + - github From 3b81490ac146913a5be4f6d93ad71a95402c026f Mon Sep 17 00:00:00 2001 From: davotoula Date: Sun, 16 Nov 2025 17:43:59 +0100 Subject: [PATCH 35/60] user correct overlad that accepts argument --- .../com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt index d62753d7c..c80dfcdf3 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/UpdateZapAmountDialog.kt @@ -353,7 +353,7 @@ fun UpdateZapAmountContent( postViewModel.copyFromClipboard(it) } } catch (e: IllegalArgumentException) { - accountViewModel.toastManager.toast(R.string.invalid_nip47_uri_title, R.string.invalid_nip47_uri_description) + accountViewModel.toastManager.toast(R.string.invalid_nip47_uri_title, R.string.invalid_nip47_uri_description, uri ?: "") } }, ) { From 976ff9970a96b16e03b93debe0132b314911cbdd Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Sun, 16 Nov 2025 16:50:25 +0000 Subject: [PATCH 36/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-cs-rCZ/strings.xml | 1 + .../src/main/res/values-de-rDE/strings.xml | 1 + .../src/main/res/values-hi-rIN/strings.xml | 20 ++++++++++++++++--- .../src/main/res/values-pl-rPL/strings.xml | 6 +++--- .../src/main/res/values-pt-rBR/strings.xml | 1 + .../src/main/res/values-sv-rSE/strings.xml | 1 + 6 files changed, 24 insertions(+), 6 deletions(-) diff --git a/amethyst/src/main/res/values-cs-rCZ/strings.xml b/amethyst/src/main/res/values-cs-rCZ/strings.xml index f6b9d8272..b50dae0dc 100644 --- a/amethyst/src/main/res/values-cs-rCZ/strings.xml +++ b/amethyst/src/main/res/values-cs-rCZ/strings.xml @@ -345,6 +345,7 @@ Odeslat zprávu Blokovat a nahlásit Blokovat + Manuální zap rozdělení Záložky Koncepty Soukromé záložky diff --git a/amethyst/src/main/res/values-de-rDE/strings.xml b/amethyst/src/main/res/values-de-rDE/strings.xml index 9c1f13bd2..e9720b177 100644 --- a/amethyst/src/main/res/values-de-rDE/strings.xml +++ b/amethyst/src/main/res/values-de-rDE/strings.xml @@ -351,6 +351,7 @@ anz der Bedingungen ist erforderlich Meldung veröffentlichen Blockieren und melden Blockieren + Manuelle Zap-Splits Lesezeichen Entwürfe Private Lesezeichen diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index d8d019210..933b1ffa8 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -347,6 +347,7 @@ सूचना प्रकाशित करें बाधित करें तथा सूचना दें बाधित करें + मनुष्यकृत ज्साप विभाजन स्मर्तव्य पाण्डुलिपियाँ निजी स्मर्तव्य @@ -449,7 +450,7 @@ मेरे आसपास वैश्विक मौन सूची - अनुगम्य सूचियाँ + अनुचरण सूचियाँ सूचक युक्त स्मर्त्तव्य सूची सामान्य स्मर्त्तव्य सूची सार्वजनिक @@ -459,9 +460,9 @@ \nनवीकरण के लिए नीचे दबाएँ। अथवा एक नया बनाने के लिए जोड घुण्डियाँ टाँकें। नव्य - लेखक जोडें अनुगम्य सूची में + लेखक जोडें अनुचरण सूची में प्रयोक्ता को सूचियों में जोडें अथवा हटाएँ अथवा इस प्रयोक्ता के साथ नई सूची बनाएँ। - सूची %1$s के लिए चिह्न + अनुचरण सूची के लिए चिह्न %1$s एक सार्वजनिक सदस्य है %1$s एक निजी सदस्य है सार्वजनिक सदस्य के रूप में जोडें @@ -484,6 +485,7 @@ प्रयोक्ता के साथ नई सूची %1$s बनाएँ अनुगम्य सूची %1$s बनाता है तथा उससे %2$s जोडता है। नई %1$s सूची + नव्य अनुचरण पोटली अनुचरण सूची की अनुकृति करें विवरण का संशोधन करें इस सूची का कोई विवरण नहीं @@ -496,6 +498,7 @@ समुच्चय बनाएँ सूची की अनुकृति समुच्चय पुनःनामकरण + सूची सम्पादन संशोधन करें आप पनःनामकरण कर रहे हैं इस से इस तक.. @@ -1126,4 +1129,15 @@ सूची से प्रयोक्ता हटाएँ अनुचरण पोटली सदस्य सूची + अनुचरण सूची उपतथ्य + अनुचरण पोटली उपतथ्य + अनुचरण पोटली सम्पादन + पोटली नाम + नव्य पोटली नाम + पोटली विवरण + नव्य पोटली विवरण + सूची प्रसारण + पोटली प्रसारण + सूची मिटाएँ + पोटली मिटाएँ diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 5b574ba1f..6fe375b37 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -68,9 +68,9 @@ Zacytuj Sklonuj Zaproponuj zmianę - Nowa kwota w Satach + Nowa kwota w Satsach Dodaj - "odpowiadając do" + "odpowiadając do " " i " "na kanale " Baner profilu @@ -475,7 +475,7 @@ Pusty %1$s nie jest na liście %1$s nie jest uczestnikiem - Twoje listy oraz %1$s + %1$s na Twoich listach Twoja lista obserwowanych Nie znaleziono list obserwowanych lub nie masz żadnych list obserwowanych. Naciśnij poniżej, aby odświeżyć lub użyj menu, aby utworzyć nową. Podczas pobierania wystąpił błąd: %1$s diff --git a/amethyst/src/main/res/values-pt-rBR/strings.xml b/amethyst/src/main/res/values-pt-rBR/strings.xml index 253715823..1bcf79d0c 100644 --- a/amethyst/src/main/res/values-pt-rBR/strings.xml +++ b/amethyst/src/main/res/values-pt-rBR/strings.xml @@ -345,6 +345,7 @@ Enviar Denuncia Bloquear e Denunciar Bloquear + Divisão manual de Zap Itens Salvos Rascunhos Itens Salvos Privados diff --git a/amethyst/src/main/res/values-sv-rSE/strings.xml b/amethyst/src/main/res/values-sv-rSE/strings.xml index d7d545a47..cbd573908 100644 --- a/amethyst/src/main/res/values-sv-rSE/strings.xml +++ b/amethyst/src/main/res/values-sv-rSE/strings.xml @@ -345,6 +345,7 @@ Skicka rapport Blockera och rapportera Blockera + Manuell Zap delning Bokmärken Utkast Privata Bokmärken From f5d8b9df8b02f8aa6149f0ffb9691daf4625834f Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Mon, 17 Nov 2025 07:53:24 +0000 Subject: [PATCH 37/60] New Crowdin translations by GitHub Action --- amethyst/src/main/res/values-hi-rIN/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/amethyst/src/main/res/values-hi-rIN/strings.xml b/amethyst/src/main/res/values-hi-rIN/strings.xml index 933b1ffa8..3aa49db20 100644 --- a/amethyst/src/main/res/values-hi-rIN/strings.xml +++ b/amethyst/src/main/res/values-hi-rIN/strings.xml @@ -451,6 +451,7 @@ वैश्विक मौन सूची अनुचरण सूचियाँ + ये अनुचरण सूचियाँ आपके उपयोग के लिए रूपांकित हैं। आप प्रयोक्ताओं का अनुचरण कर सकते हैं निजी अथवा सार्वजनिक रूप से सूचक युक्त स्मर्त्तव्य सूची सामान्य स्मर्त्तव्य सूची सार्वजनिक @@ -637,6 +638,7 @@ अनुचरित विषयसूचक पुनःप्रसारक अनुचरण पोटलियाँ + ये प्रयोक्ता सूचियाँ हैं जो आप अन्य लोगों के लिए अनुशंसित करते हैं। केवल सार्वजनिक प्रयोक्ता अनुमत। पठितव्य सूचनावली विधियाँ पण्यक्षेत्र @@ -1130,7 +1132,9 @@ अनुचरण पोटली सदस्य सूची अनुचरण सूची उपतथ्य + अनुचरण सूची उपतथ्य नोस्टर में सब के द्वारा देखा जा सकता है। केवल आपके निजी सदस्य रहस्यीकृत हैं। अनुचरण पोटली उपतथ्य + अनुचरण पोटली उपतथ्य नोस्टर में सब के द्वारा देखा जा सकता है तथा प्रायः अनेक जालस्थानों पर प्रकाशित होते हैं प्रारम्भ सामग्री के रूप में नये प्रयोक्ताओं के लिए। अनुचरण पोटली सम्पादन पोटली नाम नव्य पोटली नाम From df1bf82e764ad2afbd1d592134f78d192af53cd9 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Mon, 10 Nov 2025 15:03:45 -0300 Subject: [PATCH 38/60] Create NostrSignerRemote --- .../signer/NostrSignerRemote.kt | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt new file mode 100644 index 000000000..613c0a1bc --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient +import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req +import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent +import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent + +class NostrSignerRemote( + signer: NostrSignerInternal, + val remotePubkey: HexKey, + val relays: List, + val client: INostrClient, +) : NostrSigner(signer.pubKey) { + val subscription = + client.req( + relays = relays, + filter = + Filter( + kinds = listOf(NostrConnectEvent.KIND), + tags = mapOf("p" to listOf(remotePubkey)), + ), + ) { event -> + } + + fun openSubscription() { + subscription.updateFilter() + } + + fun closeSubscription() { + subscription.close() + } + + override fun isWriteable(): Boolean = true + + override suspend fun sign( + createdAt: Long, + kind: Int, + tags: Array>, + content: String, + ): T { + TODO("Not yet implemented") + } + + override suspend fun nip04Encrypt( + plaintext: String, + toPublicKey: HexKey, + ): String { + TODO("Not yet implemented") + } + + override suspend fun nip04Decrypt( + ciphertext: String, + fromPublicKey: HexKey, + ): String { + TODO("Not yet implemented") + } + + override suspend fun nip44Encrypt( + plaintext: String, + toPublicKey: HexKey, + ): String { + TODO("Not yet implemented") + } + + override suspend fun nip44Decrypt( + ciphertext: String, + fromPublicKey: HexKey, + ): String { + TODO("Not yet implemented") + } + + override suspend fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent { + TODO("Not yet implemented") + } + + override suspend fun deriveKey(nonce: HexKey): HexKey { + TODO("Not yet implemented") + } + + override fun hasForegroundSupport(): Boolean = true +} From e6f109de740ca0323b85fe4fbc5c21ce3e97dcc5 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Mon, 10 Nov 2025 15:29:43 -0300 Subject: [PATCH 39/60] - Add connect, getPublivKey and ping - send NostrConnectEvent to relays --- .../signer/NostrSignerRemote.kt | 103 +++++++++++++++++- 1 file changed, 100 insertions(+), 3 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 613c0a1bc..193cf8656 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -22,31 +22,44 @@ package com.vitorpamplona.quartz.nip46RemoteSigner.signer import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Encrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent class NostrSignerRemote( - signer: NostrSignerInternal, + val signer: NostrSignerInternal, val remotePubkey: HexKey, - val relays: List, + val relays: Set, val client: INostrClient, + val permissions: String? = null, + val secret: String? = null, ) : NostrSigner(signer.pubKey) { val subscription = client.req( - relays = relays, + relays = relays.toList(), filter = Filter( kinds = listOf(NostrConnectEvent.KIND), tags = mapOf("p" to listOf(remotePubkey)), ), ) { event -> + } fun openSubscription() { @@ -65,6 +78,20 @@ class NostrSignerRemote( tags: Array>, content: String, ): T { + val template = EventTemplate( + createdAt = createdAt, + kind = kind, + tags = tags, + content = content, + ) + val event = NostrConnectEvent.create( + message = BunkerRequestSign( + event = template, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -72,6 +99,15 @@ class NostrSignerRemote( plaintext: String, toPublicKey: HexKey, ): String { + val event = NostrConnectEvent.create( + message = BunkerRequestNip04Encrypt( + message = plaintext, + pubKey = toPublicKey, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -79,6 +115,15 @@ class NostrSignerRemote( ciphertext: String, fromPublicKey: HexKey, ): String { + val event = NostrConnectEvent.create( + message = BunkerRequestNip04Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -86,6 +131,15 @@ class NostrSignerRemote( plaintext: String, toPublicKey: HexKey, ): String { + val event = NostrConnectEvent.create( + message = BunkerRequestNip44Encrypt( + message = plaintext, + pubKey = toPublicKey, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -93,6 +147,49 @@ class NostrSignerRemote( ciphertext: String, fromPublicKey: HexKey, ): String { + val event = NostrConnectEvent.create( + message = BunkerRequestNip44Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) + TODO("Not yet implemented") + } + + suspend fun ping(): String { + val event = NostrConnectEvent.create( + message = BunkerRequestPing(), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) + TODO("Not yet implemented") + } + + suspend fun connect(): String { + val event = NostrConnectEvent.create( + message = BunkerRequestConnect( + remoteKey = remotePubkey, + permissions = permissions, + secret = secret, + ), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) + TODO("Not yet implemented") + } + + suspend fun getPublicKey(): String { + val event = NostrConnectEvent.create( + message = BunkerRequestGetPublicKey(), + remoteKey = remotePubkey, + signer = signer + ) + client.send(event, relayList = relays) TODO("Not yet implemented") } From da85e59424dce37ced5d3badb47949923366d8a8 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Mon, 10 Nov 2025 15:36:57 -0300 Subject: [PATCH 40/60] - Add connect, getPublivKey and ping - send NostrConnectEvent to relays --- .../signer/NostrSignerRemote.kt | 143 ++++++++++-------- 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 193cf8656..518bfebd6 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -22,7 +22,6 @@ package com.vitorpamplona.quartz.nip46RemoteSigner.signer import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -59,7 +58,6 @@ class NostrSignerRemote( tags = mapOf("p" to listOf(remotePubkey)), ), ) { event -> - } fun openSubscription() { @@ -78,19 +76,22 @@ class NostrSignerRemote( tags: Array>, content: String, ): T { - val template = EventTemplate( - createdAt = createdAt, - kind = kind, - tags = tags, - content = content, - ) - val event = NostrConnectEvent.create( - message = BunkerRequestSign( - event = template, - ), - remoteKey = remotePubkey, - signer = signer - ) + val template = + EventTemplate( + createdAt = createdAt, + kind = kind, + tags = tags, + content = content, + ) + val event = + NostrConnectEvent.create( + message = + BunkerRequestSign( + event = template, + ), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -99,14 +100,16 @@ class NostrSignerRemote( plaintext: String, toPublicKey: HexKey, ): String { - val event = NostrConnectEvent.create( - message = BunkerRequestNip04Encrypt( - message = plaintext, - pubKey = toPublicKey, - ), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = + BunkerRequestNip04Encrypt( + message = plaintext, + pubKey = toPublicKey, + ), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -115,14 +118,16 @@ class NostrSignerRemote( ciphertext: String, fromPublicKey: HexKey, ): String { - val event = NostrConnectEvent.create( - message = BunkerRequestNip04Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = + BunkerRequestNip04Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -131,14 +136,16 @@ class NostrSignerRemote( plaintext: String, toPublicKey: HexKey, ): String { - val event = NostrConnectEvent.create( - message = BunkerRequestNip44Encrypt( - message = plaintext, - pubKey = toPublicKey, - ), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = + BunkerRequestNip44Encrypt( + message = plaintext, + pubKey = toPublicKey, + ), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } @@ -147,48 +154,54 @@ class NostrSignerRemote( ciphertext: String, fromPublicKey: HexKey, ): String { - val event = NostrConnectEvent.create( - message = BunkerRequestNip44Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = + BunkerRequestNip44Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } suspend fun ping(): String { - val event = NostrConnectEvent.create( - message = BunkerRequestPing(), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = BunkerRequestPing(), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } suspend fun connect(): String { - val event = NostrConnectEvent.create( - message = BunkerRequestConnect( + val event = + NostrConnectEvent.create( + message = + BunkerRequestConnect( + remoteKey = remotePubkey, + permissions = permissions, + secret = secret, + ), remoteKey = remotePubkey, - permissions = permissions, - secret = secret, - ), - remoteKey = remotePubkey, - signer = signer - ) + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } suspend fun getPublicKey(): String { - val event = NostrConnectEvent.create( - message = BunkerRequestGetPublicKey(), - remoteKey = remotePubkey, - signer = signer - ) + val event = + NostrConnectEvent.create( + message = BunkerRequestGetPublicKey(), + remoteKey = remotePubkey, + signer = signer, + ) client.send(event, relayList = relays) TODO("Not yet implemented") } From aee6ffdbf5bc14c7651d21e72bd814d966a3765a Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Mon, 10 Nov 2025 17:26:39 -0300 Subject: [PATCH 41/60] return BunkerResponse from connect --- .../signer/NostrSignerRemote.kt | 59 ++++++++++++++----- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 518bfebd6..61b3171bb 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.quartz.nip46RemoteSigner.signer import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -37,9 +38,14 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.utils.cache.LargeCache +import com.vitorpamplona.quartz.utils.tryAndWait +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume class NostrSignerRemote( val signer: NostrSignerInternal, @@ -49,15 +55,23 @@ class NostrSignerRemote( val permissions: String? = null, val secret: String? = null, ) : NostrSigner(signer.pubKey) { + private val timeout = 30_000L + private val awaitingRequests = LargeCache>() + val subscription = client.req( relays = relays.toList(), filter = Filter( kinds = listOf(NostrConnectEvent.KIND), - tags = mapOf("p" to listOf(remotePubkey)), + tags = mapOf("p" to listOf(signer.pubKey)), ), ) { event -> + val message = signer.signerSync.nip44Decrypt(event.content, remotePubkey) + val bunkerResponse = OptimizedJsonMapper.fromJsonTo(message) + + awaitingRequests.get(bunkerResponse.id)?.resume(bunkerResponse) + awaitingRequests.remove(bunkerResponse.id) } fun openSubscription() { @@ -83,16 +97,21 @@ class NostrSignerRemote( tags = tags, content = content, ) + + val request = + BunkerRequestSign( + event = template, + ) + val event = NostrConnectEvent.create( - message = - BunkerRequestSign( - event = template, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) + client.send(event, relayList = relays) + TODO("Not yet implemented") } @@ -179,20 +198,32 @@ class NostrSignerRemote( TODO("Not yet implemented") } - suspend fun connect(): String { + suspend fun connect(): BunkerResponse? { + val request = + BunkerRequestConnect( + remoteKey = remotePubkey, + permissions = permissions, + secret = secret, + ) val event = NostrConnectEvent.create( - message = - BunkerRequestConnect( - remoteKey = remotePubkey, - permissions = permissions, - secret = secret, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + + return result } suspend fun getPublicKey(): String { From b2f2a409c30d3e8ec604463ce1d9c31691ca9b9d Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 08:17:36 -0300 Subject: [PATCH 42/60] implement the functions of nip46 --- .../signer/NostrSignerRemote.kt | 154 +++++++++++++----- 1 file changed, 114 insertions(+), 40 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 61b3171bb..4f9cc2832 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -39,6 +39,7 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent @@ -110,95 +111,156 @@ class NostrSignerRemote( signer = signer, ) - client.send(event, relayList = relays) + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } - TODO("Not yet implemented") + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + + return (result as BunkerResponseEvent).event as T } override suspend fun nip04Encrypt( plaintext: String, toPublicKey: HexKey, ): String { + val request = + BunkerRequestNip04Encrypt( + message = plaintext, + pubKey = toPublicKey, + ) val event = NostrConnectEvent.create( - message = - BunkerRequestNip04Encrypt( - message = plaintext, - pubKey = toPublicKey, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + return result?.result ?: "" } override suspend fun nip04Decrypt( ciphertext: String, fromPublicKey: HexKey, ): String { + val request = + BunkerRequestNip04Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ) val event = NostrConnectEvent.create( - message = - BunkerRequestNip04Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + return result?.result ?: "" } override suspend fun nip44Encrypt( plaintext: String, toPublicKey: HexKey, ): String { + val request = + BunkerRequestNip44Encrypt( + message = plaintext, + pubKey = toPublicKey, + ) val event = NostrConnectEvent.create( - message = - BunkerRequestNip44Encrypt( - message = plaintext, - pubKey = toPublicKey, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + return result?.result ?: "" } override suspend fun nip44Decrypt( ciphertext: String, fromPublicKey: HexKey, ): String { + val request = + BunkerRequestNip44Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ) val event = NostrConnectEvent.create( - message = - BunkerRequestNip44Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + return result?.result ?: "" } - suspend fun ping(): String { + suspend fun ping(): String? { + val request = BunkerRequestPing() val event = NostrConnectEvent.create( - message = BunkerRequestPing(), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + + return result?.result } - suspend fun connect(): BunkerResponse? { + suspend fun connect(): HexKey? { val request = BunkerRequestConnect( remoteKey = remotePubkey, @@ -223,18 +285,30 @@ class NostrSignerRemote( client.send(event, relayList = relays) } - return result + return result?.result } - suspend fun getPublicKey(): String { + suspend fun getPublicKey(): HexKey? { + val request = BunkerRequestGetPublicKey() val event = NostrConnectEvent.create( - message = BunkerRequestGetPublicKey(), + message = request, remoteKey = remotePubkey, signer = signer, ) - client.send(event, relayList = relays) - TODO("Not yet implemented") + + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relays) + } + + return result?.result } override suspend fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent { From 8d529e1ea969c29bfe5031b0fd0f204778272d86 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 08:56:36 -0300 Subject: [PATCH 43/60] add a signer result interface for remote signer --- .../nip46RemoteSigner/signer/SignerResult.kt | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt new file mode 100644 index 000000000..f86f0f8d8 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip01Core.core.Event + +sealed interface SignerResult { + sealed interface RequestAddressed : SignerResult { + class Successful( + val result: T, + ) : RequestAddressed + + class Rejected : RequestAddressed + + class TimedOut : RequestAddressed + + class ReceivedButCouldNotPerform( + val message: String? = null, + ) : RequestAddressed + + class ReceivedButCouldNotParseEventFromResult( + val eventJson: String, + ) : RequestAddressed + + class ReceivedButCouldNotVerifyResultingEvent( + val invalidEvent: Event, + ) : RequestAddressed + } +} + +interface IResult From 55b4ddc453494d7c71ede29a248303bf9e72a80a Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 09:29:32 -0300 Subject: [PATCH 44/60] add a fromBunkerUri helper --- .../signer/NostrSignerRemote.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 4f9cc2832..fe0a27c7b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -43,6 +43,7 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent +import com.vitorpamplona.quartz.utils.Hex import com.vitorpamplona.quartz.utils.cache.LargeCache import com.vitorpamplona.quartz.utils.tryAndWait import kotlin.coroutines.Continuation @@ -320,4 +321,39 @@ class NostrSignerRemote( } override fun hasForegroundSupport(): Boolean = true + + companion object { + fun fromBunkerUri( + bunkerUri: String, + signer: NostrSignerInternal, + client: INostrClient, + permissions: String? = null, + ): NostrSignerRemote { + if (!bunkerUri.startsWith("bunker://")) throw Exception("Invalid bunker uri") + val splitData = bunkerUri.split("?") + val remotePubkey = splitData[0].removePrefix("bunker://") + if (!Hex.isHex(remotePubkey)) throw Exception("Invalid pubkey in bunker uri") + val params = splitData[1].split("&") + val relays = mutableSetOf() + var secret: String? = null + for (param in params) { + val splitParam = param.split("=") + if (splitParam.size < 2) continue + if (splitParam.first() == "relay") { + relays.add(NormalizedRelayUrl(splitParam[1])) + } + if (splitParam.first() == "secret") { + secret = splitParam[1] + } + } + return NostrSignerRemote( + signer = signer, + remotePubkey = remotePubkey, + relays = relays, + client = client, + permissions = permissions, + secret = secret, + ) + } + } } From e02dfce152f0e7ab8dcd9741b442e6827a8b647f Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 10:45:03 -0300 Subject: [PATCH 45/60] create a RemoteSignerManager --- .../signer/NostrSignerRemote.kt | 375 ++++++++++-------- .../signer/RemoteSignerManager.kt | 88 ++++ .../nip46RemoteSigner/signer/SignerResult.kt | 20 + 3 files changed, 309 insertions(+), 174 deletions(-) create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/RemoteSignerManager.kt diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index fe0a27c7b..b2aee390c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -22,7 +22,7 @@ package com.vitorpamplona.quartz.nip46RemoteSigner.signer import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper +import com.vitorpamplona.quartz.nip01Core.crypto.verify import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -38,16 +38,15 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePong +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePublicKey import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent import com.vitorpamplona.quartz.utils.Hex -import com.vitorpamplona.quartz.utils.cache.LargeCache -import com.vitorpamplona.quartz.utils.tryAndWait -import kotlin.coroutines.Continuation -import kotlin.coroutines.resume class NostrSignerRemote( val signer: NostrSignerInternal, @@ -57,8 +56,13 @@ class NostrSignerRemote( val permissions: String? = null, val secret: String? = null, ) : NostrSigner(signer.pubKey) { - private val timeout = 30_000L - private val awaitingRequests = LargeCache>() + private val manager = + RemoteSignerManager( + signer = signer, + remoteKey = remotePubkey, + relayList = relays, + client = client, + ) val subscription = client.req( @@ -69,11 +73,7 @@ class NostrSignerRemote( tags = mapOf("p" to listOf(signer.pubKey)), ), ) { event -> - val message = signer.signerSync.nip44Decrypt(event.content, remotePubkey) - val bunkerResponse = OptimizedJsonMapper.fromJsonTo(message) - - awaitingRequests.get(bunkerResponse.id)?.resume(bunkerResponse) - awaitingRequests.remove(bunkerResponse.id) + manager.newResponse(event) } fun openSubscription() { @@ -92,224 +92,251 @@ class NostrSignerRemote( tags: Array>, content: String, ): T { - val template = - EventTemplate( - createdAt = createdAt, - kind = kind, - tags = tags, - content = content, - ) - - val request = - BunkerRequestSign( - event = template, - ) - - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) - val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + val template = + EventTemplate( + createdAt = createdAt, + kind = kind, + tags = tags, + content = content, + ) - awaitingRequests.put(request.id, continuation) + BunkerRequestSign( + event = template, + ) + }, + parser = { response -> + if (response is BunkerResponseEvent) { + if (!response.event.verify()) { + SignerResult.RequestAddressed.ReceivedButCouldNotVerifyResultingEvent(response.event) + } else { + SignerResult.RequestAddressed.Successful(SignResult(response.event)) + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - client.send(event, relayList = relays) + if (result is SignerResult.RequestAddressed.Successful) { + (result.result.event as? T)?.let { + return it } + } - return (result as BunkerResponseEvent).event as T + throw Exception("Could not sign") } override suspend fun nip04Encrypt( plaintext: String, toPublicKey: HexKey, ): String { - val request = - BunkerRequestNip04Encrypt( - message = plaintext, - pubKey = toPublicKey, - ) - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestNip04Encrypt( + message = plaintext, + pubKey = toPublicKey, + ) + }, + parser = { response -> + if (response is BunkerResponseEncrypt) { + if (response.error != null) { + SignerResult.RequestAddressed.Rejected() + } else { + SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - awaitingRequests.put(request.id, continuation) + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.ciphertext + } - client.send(event, relayList = relays) - } - return result?.result ?: "" + throw Exception("Could not encrypt") } override suspend fun nip04Decrypt( ciphertext: String, fromPublicKey: HexKey, ): String { - val request = - BunkerRequestNip04Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ) - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestNip04Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ) + }, + parser = { response -> + if (response is BunkerResponseDecrypt) { + if (response.error != null) { + SignerResult.RequestAddressed.Rejected() + } else { + SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - awaitingRequests.put(request.id, continuation) + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.plaintext + } - client.send(event, relayList = relays) - } - return result?.result ?: "" + throw Exception("Could not decrypt") } override suspend fun nip44Encrypt( plaintext: String, toPublicKey: HexKey, ): String { - val request = - BunkerRequestNip44Encrypt( - message = plaintext, - pubKey = toPublicKey, - ) - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestNip44Encrypt( + message = plaintext, + pubKey = toPublicKey, + ) + }, + parser = { response -> + if (response is BunkerResponseEncrypt) { + if (response.error != null) { + SignerResult.RequestAddressed.Rejected() + } else { + SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - awaitingRequests.put(request.id, continuation) + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.ciphertext + } - client.send(event, relayList = relays) - } - return result?.result ?: "" + throw Exception("Could not encrypt") } override suspend fun nip44Decrypt( ciphertext: String, fromPublicKey: HexKey, ): String { - val request = - BunkerRequestNip44Decrypt( - ciphertext = ciphertext, - pubKey = fromPublicKey, - ) - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestNip44Decrypt( + ciphertext = ciphertext, + pubKey = fromPublicKey, + ) + }, + parser = { response -> + if (response is BunkerResponseDecrypt) { + if (response.error != null) { + SignerResult.RequestAddressed.Rejected() + } else { + SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - awaitingRequests.put(request.id, continuation) + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.plaintext + } - client.send(event, relayList = relays) - } - return result?.result ?: "" + throw Exception("Could not decrypt") } suspend fun ping(): String? { - val request = BunkerRequestPing() - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, + val result = + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestPing() + }, + parser = { response -> + if (response is BunkerResponsePong) { + if (response.result != null) { + SignerResult.RequestAddressed.Successful(PingResult(response.result)) + } else { + SignerResult.RequestAddressed.Rejected() + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, ) - val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.pong + } - awaitingRequests.put(request.id, continuation) - - client.send(event, relayList = relays) - } - - return result?.result + throw Exception("Could not ping") } - suspend fun connect(): HexKey? { - val request = - BunkerRequestConnect( - remoteKey = remotePubkey, - permissions = permissions, - secret = secret, - ) - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, - ) - + suspend fun connect(): HexKey { val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestConnect( + remoteKey = remotePubkey, + permissions = permissions, + secret = secret, + ) + }, + parser = { response -> + if (response is BunkerResponsePublicKey) { + if (response.result != null) { + SignerResult.RequestAddressed.Successful(PublicKeyResult(response.result)) + } else { + SignerResult.RequestAddressed.Rejected() + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, + ) - awaitingRequests.put(request.id, continuation) + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.pubkey + } - client.send(event, relayList = relays) - } - - return result?.result + throw Exception("Could not connect") } - suspend fun getPublicKey(): HexKey? { - val request = BunkerRequestGetPublicKey() - val event = - NostrConnectEvent.create( - message = request, - remoteKey = remotePubkey, - signer = signer, + suspend fun getPublicKey(): HexKey { + val result = + manager.launchWaitAndParse( + bunkerRequestBuilder = { + BunkerRequestGetPublicKey() + }, + parser = { response -> + if (response is BunkerResponsePublicKey) { + if (response.result != null) { + SignerResult.RequestAddressed.Successful(PublicKeyResult(response.result)) + } else { + SignerResult.RequestAddressed.Rejected() + } + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + }, ) - val result = - tryAndWait(timeout) { continuation -> - continuation.invokeOnCancellation { - awaitingRequests.remove(request.id) - } + if (result is SignerResult.RequestAddressed.Successful) { + return result.result.pubkey + } - awaitingRequests.put(request.id, continuation) - - client.send(event, relayList = relays) - } - - return result?.result + throw Exception("Could not get public key") } override suspend fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/RemoteSignerManager.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/RemoteSignerManager.kt new file mode 100644 index 000000000..eb07ca232 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/RemoteSignerManager.kt @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip01Core.core.Event +import com.vitorpamplona.quartz.nip01Core.core.OptimizedJsonMapper +import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient +import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl +import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequest +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent +import com.vitorpamplona.quartz.utils.cache.LargeCache +import com.vitorpamplona.quartz.utils.tryAndWait +import kotlin.coroutines.Continuation +import kotlin.coroutines.resume + +class RemoteSignerManager( + val timeout: Long = 30000, + val client: INostrClient, + val signer: NostrSignerInternal, + val remoteKey: String, + val relayList: Set, +) { + private val awaitingRequests = LargeCache>() + + fun newResponse(responseEvent: Event) { + val bunkerResponse = OptimizedJsonMapper.fromJsonTo(responseEvent.content) + awaitingRequests.get(bunkerResponse.id)?.resume(bunkerResponse) + } + + /** + * Launches the signer, waits and parses the result + * + * @param bunkerRequestBuilder The BunkerRequest to be sent. + * @param parser A function that parses the BunkerResponse into a [SignerResult.RequestAddressed]. + * @return The result after parsing the BunkerResponse using the provided parser. + * + * This function uses the [tryAndWait] utility to implement a timeout on the Bunker Request approval. + * It assigns a unique ID to the request and keeps a continuation to resume once the result is received. + * If the timeout occurs or the continuation is cancelled, the request ID is cleaned up from [awaitingRequests]. + */ + suspend fun launchWaitAndParse( + bunkerRequestBuilder: () -> BunkerRequest, + parser: (response: BunkerResponse) -> SignerResult.RequestAddressed, + ): SignerResult.RequestAddressed { + val request = bunkerRequestBuilder() + val event = + NostrConnectEvent.create( + message = request, + remoteKey = remoteKey, + signer = signer, + ) + val result = + tryAndWait(timeout) { continuation -> + continuation.invokeOnCancellation { + awaitingRequests.remove(request.id) + } + + awaitingRequests.put(request.id, continuation) + + client.send(event, relayList = relayList) + } + + return when (result) { + null -> SignerResult.RequestAddressed.TimedOut() + else -> parser(result) + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt index f86f0f8d8..1bb20fc06 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignerResult.kt @@ -47,3 +47,23 @@ sealed interface SignerResult { } interface IResult + +data class SignResult( + val event: Event, +) : IResult + +data class EncryptionResult( + val ciphertext: String, +) : IResult + +data class DecryptionResult( + val plaintext: String, +) : IResult + +data class PingResult( + val pong: String, +) : IResult + +data class PublicKeyResult( + val pubkey: String, +) : IResult From c2f2dc46d91ab574ea2746ccd52080df57da34fa Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 11:49:00 -0300 Subject: [PATCH 46/60] check for error result --- .../signer/NostrSignerRemote.kt | 115 +++++++++++------- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index b2aee390c..1633590f9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -40,6 +40,7 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePong import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePublicKey @@ -114,6 +115,8 @@ class NostrSignerRemote( } else { SignerResult.RequestAddressed.Successful(SignResult(response.event)) } + } else if (response is BunkerResponseError) { + SignerResult.RequestAddressed.Rejected() } else { SignerResult.RequestAddressed.ReceivedButCouldNotPerform() } @@ -142,14 +145,18 @@ class NostrSignerRemote( ) }, parser = { response -> - if (response is BunkerResponseEncrypt) { - if (response.error != null) { - SignerResult.RequestAddressed.Rejected() - } else { + when (response) { + is BunkerResponseEncrypt -> { SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -174,14 +181,16 @@ class NostrSignerRemote( ) }, parser = { response -> - if (response is BunkerResponseDecrypt) { - if (response.error != null) { - SignerResult.RequestAddressed.Rejected() - } else { + when (response) { + is BunkerResponseDecrypt -> { SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -206,14 +215,18 @@ class NostrSignerRemote( ) }, parser = { response -> - if (response is BunkerResponseEncrypt) { - if (response.error != null) { - SignerResult.RequestAddressed.Rejected() - } else { + when (response) { + is BunkerResponseEncrypt -> { SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -238,14 +251,18 @@ class NostrSignerRemote( ) }, parser = { response -> - if (response is BunkerResponseDecrypt) { - if (response.error != null) { - SignerResult.RequestAddressed.Rejected() - } else { + when (response) { + is BunkerResponseDecrypt -> { SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -257,21 +274,25 @@ class NostrSignerRemote( throw Exception("Could not decrypt") } - suspend fun ping(): String? { + suspend fun ping(): String { val result = manager.launchWaitAndParse( bunkerRequestBuilder = { BunkerRequestPing() }, parser = { response -> - if (response is BunkerResponsePong) { - if (response.result != null) { - SignerResult.RequestAddressed.Successful(PingResult(response.result)) - } else { + when (response) { + is BunkerResponsePong -> { + SignerResult.RequestAddressed.Successful(PingResult(response.id)) + } + + is BunkerResponseError -> { SignerResult.RequestAddressed.Rejected() } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -294,14 +315,18 @@ class NostrSignerRemote( ) }, parser = { response -> - if (response is BunkerResponsePublicKey) { - if (response.result != null) { - SignerResult.RequestAddressed.Successful(PublicKeyResult(response.result)) - } else { + when (response) { + is BunkerResponsePublicKey -> { + SignerResult.RequestAddressed.Successful(PublicKeyResult(response.pubkey)) + } + + is BunkerResponseError -> { SignerResult.RequestAddressed.Rejected() } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) @@ -320,14 +345,18 @@ class NostrSignerRemote( BunkerRequestGetPublicKey() }, parser = { response -> - if (response is BunkerResponsePublicKey) { - if (response.result != null) { - SignerResult.RequestAddressed.Successful(PublicKeyResult(response.result)) - } else { + when (response) { + is BunkerResponsePublicKey -> { + SignerResult.RequestAddressed.Successful(PublicKeyResult(response.pubkey)) + } + + is BunkerResponseError -> { SignerResult.RequestAddressed.Rejected() } - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } } }, ) From 7dce71d8fad5e98586ae610f913abb46c53156a8 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 13:33:48 -0300 Subject: [PATCH 47/60] added response helper --- .../signer/Nip04DecryptResponse.kt | 42 ++++++ .../signer/Nip04EncryptResponse.kt | 44 ++++++ .../signer/Nip44DecryptResponse.kt | 44 ++++++ .../signer/Nip44EncryptResponse.kt | 44 ++++++ .../signer/NostrSignerRemote.kt | 131 ++---------------- .../nip46RemoteSigner/signer/PingResponse.kt | 44 ++++++ .../signer/PubKeyResponse.kt | 44 ++++++ .../nip46RemoteSigner/signer/SignResponse.kt | 43 ++++++ 8 files changed, 313 insertions(+), 123 deletions(-) create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04DecryptResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04EncryptResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44DecryptResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44EncryptResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PingResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PubKeyResponse.kt create mode 100644 quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignResponse.kt diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04DecryptResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04DecryptResponse.kt new file mode 100644 index 000000000..a671fbc58 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04DecryptResponse.kt @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError + +class Nip04DecryptResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponseDecrypt -> { + SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) + } + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04EncryptResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04EncryptResponse.kt new file mode 100644 index 000000000..39e3d9ef9 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip04EncryptResponse.kt @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError + +class Nip04EncryptResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponseEncrypt -> { + SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) + } + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44DecryptResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44DecryptResponse.kt new file mode 100644 index 000000000..7349f8991 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44DecryptResponse.kt @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError + +class Nip44DecryptResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponseDecrypt -> { + SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) + } + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44EncryptResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44EncryptResponse.kt new file mode 100644 index 000000000..255fe5f46 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/Nip44EncryptResponse.kt @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError + +class Nip44EncryptResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponseEncrypt -> { + SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) + } + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 1633590f9..44873b8f9 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -22,7 +22,6 @@ package com.vitorpamplona.quartz.nip46RemoteSigner.signer import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.core.HexKey -import com.vitorpamplona.quartz.nip01Core.crypto.verify import com.vitorpamplona.quartz.nip01Core.relay.client.INostrClient import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.req import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter @@ -38,12 +37,6 @@ import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Decrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip44Encrypt import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestPing import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestSign -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseDecrypt -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEncrypt -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePong -import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePublicKey import com.vitorpamplona.quartz.nip46RemoteSigner.NostrConnectEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapPrivateEvent import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent @@ -108,19 +101,7 @@ class NostrSignerRemote( event = template, ) }, - parser = { response -> - if (response is BunkerResponseEvent) { - if (!response.event.verify()) { - SignerResult.RequestAddressed.ReceivedButCouldNotVerifyResultingEvent(response.event) - } else { - SignerResult.RequestAddressed.Successful(SignResult(response.event)) - } - } else if (response is BunkerResponseError) { - SignerResult.RequestAddressed.Rejected() - } else { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - }, + parser = SignResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -144,21 +125,7 @@ class NostrSignerRemote( pubKey = toPublicKey, ) }, - parser = { response -> - when (response) { - is BunkerResponseEncrypt -> { - SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = Nip04EncryptResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -180,19 +147,7 @@ class NostrSignerRemote( pubKey = fromPublicKey, ) }, - parser = { response -> - when (response) { - is BunkerResponseDecrypt -> { - SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) - } - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = Nip04DecryptResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -214,21 +169,7 @@ class NostrSignerRemote( pubKey = toPublicKey, ) }, - parser = { response -> - when (response) { - is BunkerResponseEncrypt -> { - SignerResult.RequestAddressed.Successful(EncryptionResult(response.ciphertext)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = Nip44EncryptResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -250,21 +191,7 @@ class NostrSignerRemote( pubKey = fromPublicKey, ) }, - parser = { response -> - when (response) { - is BunkerResponseDecrypt -> { - SignerResult.RequestAddressed.Successful(DecryptionResult(response.plaintext)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = Nip44DecryptResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -280,21 +207,7 @@ class NostrSignerRemote( bunkerRequestBuilder = { BunkerRequestPing() }, - parser = { response -> - when (response) { - is BunkerResponsePong -> { - SignerResult.RequestAddressed.Successful(PingResult(response.id)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = PingResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -314,21 +227,7 @@ class NostrSignerRemote( secret = secret, ) }, - parser = { response -> - when (response) { - is BunkerResponsePublicKey -> { - SignerResult.RequestAddressed.Successful(PublicKeyResult(response.pubkey)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = PubKeyResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { @@ -344,21 +243,7 @@ class NostrSignerRemote( bunkerRequestBuilder = { BunkerRequestGetPublicKey() }, - parser = { response -> - when (response) { - is BunkerResponsePublicKey -> { - SignerResult.RequestAddressed.Successful(PublicKeyResult(response.pubkey)) - } - - is BunkerResponseError -> { - SignerResult.RequestAddressed.Rejected() - } - - else -> { - SignerResult.RequestAddressed.ReceivedButCouldNotPerform() - } - } - }, + parser = PubKeyResponse::parse, ) if (result is SignerResult.RequestAddressed.Successful) { diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PingResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PingResponse.kt new file mode 100644 index 000000000..754ce1c16 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PingResponse.kt @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePong + +class PingResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponsePong -> { + SignerResult.RequestAddressed.Successful(PingResult(response.id)) + } + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PubKeyResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PubKeyResponse.kt new file mode 100644 index 000000000..43fed5d03 --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/PubKeyResponse.kt @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponsePublicKey + +class PubKeyResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + when (response) { + is BunkerResponsePublicKey -> { + SignerResult.RequestAddressed.Successful(PublicKeyResult(response.pubkey)) + } + + is BunkerResponseError -> { + SignerResult.RequestAddressed.Rejected() + } + + else -> { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } + } +} diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignResponse.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignResponse.kt new file mode 100644 index 000000000..35f47498b --- /dev/null +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/SignResponse.kt @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.quartz.nip46RemoteSigner.signer + +import com.vitorpamplona.quartz.nip01Core.crypto.verify +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponse +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseError +import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerResponseEvent + +class SignResponse { + companion object { + fun parse(response: BunkerResponse): SignerResult.RequestAddressed = + if (response is BunkerResponseEvent) { + if (!response.event.verify()) { + SignerResult.RequestAddressed.ReceivedButCouldNotVerifyResultingEvent(response.event) + } else { + SignerResult.RequestAddressed.Successful(SignResult(response.event)) + } + } else if (response is BunkerResponseError) { + SignerResult.RequestAddressed.Rejected() + } else { + SignerResult.RequestAddressed.ReceivedButCouldNotPerform() + } + } +} From a6f3e09a6ca8f177c5d3f3bb93ef121e0a96cb37 Mon Sep 17 00:00:00 2001 From: greenart7c3 Date: Wed, 12 Nov 2025 13:47:26 -0300 Subject: [PATCH 48/60] add a convertExeptions function --- .../signer/NostrSignerRemote.kt | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt index 44873b8f9..58811230b 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip46RemoteSigner/signer/NostrSignerRemote.kt @@ -29,6 +29,7 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.signers.EventTemplate import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal +import com.vitorpamplona.quartz.nip01Core.signers.SignerExceptions import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestConnect import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestGetPublicKey import com.vitorpamplona.quartz.nip46RemoteSigner.BunkerRequestNip04Decrypt @@ -110,7 +111,7 @@ class NostrSignerRemote( } } - throw Exception("Could not sign") + throw convertExceptions("Could not sign", result) } override suspend fun nip04Encrypt( @@ -132,7 +133,7 @@ class NostrSignerRemote( return result.result.ciphertext } - throw Exception("Could not encrypt") + throw convertExceptions("Could not encrypt", result) } override suspend fun nip04Decrypt( @@ -154,7 +155,7 @@ class NostrSignerRemote( return result.result.plaintext } - throw Exception("Could not decrypt") + throw convertExceptions("Could not decrypt", result) } override suspend fun nip44Encrypt( @@ -176,7 +177,7 @@ class NostrSignerRemote( return result.result.ciphertext } - throw Exception("Could not encrypt") + throw convertExceptions("Could not encrypt", result) } override suspend fun nip44Decrypt( @@ -198,7 +199,7 @@ class NostrSignerRemote( return result.result.plaintext } - throw Exception("Could not decrypt") + throw convertExceptions("Could not decrypt", result) } suspend fun ping(): String { @@ -214,7 +215,7 @@ class NostrSignerRemote( return result.result.pong } - throw Exception("Could not ping") + throw convertExceptions("Could not ping", result) } suspend fun connect(): HexKey { @@ -234,7 +235,7 @@ class NostrSignerRemote( return result.result.pubkey } - throw Exception("Could not connect") + throw convertExceptions("Could not connect", result) } suspend fun getPublicKey(): HexKey { @@ -250,7 +251,7 @@ class NostrSignerRemote( return result.result.pubkey } - throw Exception("Could not get public key") + throw convertExceptions("Could not get public key", result) } override suspend fun decryptZapEvent(event: LnZapRequestEvent): LnZapPrivateEvent { @@ -263,6 +264,19 @@ class NostrSignerRemote( override fun hasForegroundSupport(): Boolean = true + fun convertExceptions( + title: String, + result: SignerResult.RequestAddressed<*>, + ): Exception = + when (result) { + is SignerResult.RequestAddressed.Successful<*> -> IllegalStateException("$title: This should not happen. There is a bug on Quartz.") + is SignerResult.RequestAddressed.ReceivedButCouldNotParseEventFromResult<*> -> IllegalStateException("$title: Failed to parse event: ${result.eventJson}.") + is SignerResult.RequestAddressed.ReceivedButCouldNotVerifyResultingEvent<*> -> IllegalStateException("$title: Failed to verify event: ${result.invalidEvent.toJson()}.") + is SignerResult.RequestAddressed.ReceivedButCouldNotPerform<*> -> SignerExceptions.CouldNotPerformException("$title: ${result.message}") + is SignerResult.RequestAddressed.Rejected<*> -> SignerExceptions.ManuallyUnauthorizedException("$title: User has rejected the request.") + is SignerResult.RequestAddressed.TimedOut<*> -> SignerExceptions.TimedOutException("$title: User didn't accept or reject in time.") + } + companion object { fun fromBunkerUri( bunkerUri: String, From 69ea1c8e511fbcd32a233065f360bbe786caef99 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Mon, 17 Nov 2025 11:10:43 +0000 Subject: [PATCH 49/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-nl-rNL/strings.xml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/amethyst/src/main/res/values-nl-rNL/strings.xml b/amethyst/src/main/res/values-nl-rNL/strings.xml index 3db9ae5d1..fbebaa099 100644 --- a/amethyst/src/main/res/values-nl-rNL/strings.xml +++ b/amethyst/src/main/res/values-nl-rNL/strings.xml @@ -112,6 +112,7 @@ Verzenden Opslaan Maken + Hernoemen Annuleren Uploaden afbeelding mislukt Relay adres @@ -124,6 +125,8 @@ Publieke chats Globale feed Zoeken + Zoek en voeg gebruiker toe + Gebruiker toevoegen Voeg relay toe Naam Naam @@ -344,6 +347,7 @@ Rapporteer Blokkeer en rapporteer Blokkeren + Handmatige Zap Splits Bladwijzers Concepten Privé bladwijzers @@ -441,10 +445,49 @@ Volgerslijst Iedereen Volg alle gebruikers + Standaard volglijst Volgt via proxy In de buurt Globaal Mute-lijst + Volglijst + Dit zijn volglijsten ontworpen voor eigen gebruik. Je kunt gebruikers privé of publiekelijk volgen + Gelabelde bladwijzers + Algemene bladwijzers + Openbaar + Privé + Gemengd + Het lijkt erop dat je nog geen volgsets hebt. + \nTik hieronder om te vernieuwen, of tik op de toevoegen knoppen om een nieuwe te maken. + + Nieuw + Voeg auteur toe aan volglijst + Gebruiker toevoegen of verwijderen uit lijsten, of maak een nieuwe lijst aan met deze gebruiker. + Icoon voor volgset + %1$s is een openbaar lid + %1$s is een privélid + Voeg toe als openbaar lid + Als privélid toevoegen + Openbare leden + Privé leden + Openbare profielen + Privé profielen + lid + leden + Geen leden + Leeg + %1$s staat niet in deze lijst + %1$s is geen lid + Jouw lijsten en %1$s + Jouw lijsten + Er zijn geen volglijsten gevonden, of je hebt geen volglijsten. Tik hieronder om te vernieuwen of gebruik het menu om er een aan te maken. + Er was een probleem tijdens het ophalen: %1$s + Maak nieuwe lijst + Nieuwe lijst met %1$s lidmaatschap + Creëert een nieuwe volgset en voegt %1$s toe als lid van %2$s. + Nieuwe volglijst + Nieuwe volglijst + Kopieer/kloon volglijst Standaard poort is 9050 ## Verbind via Tor met Orbot \n\n1. Installeer [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) From f73046e652b2148bd2daef27285124947cc761b6 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Mon, 17 Nov 2025 12:46:11 +0000 Subject: [PATCH 50/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-nl-rNL/strings.xml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/amethyst/src/main/res/values-nl-rNL/strings.xml b/amethyst/src/main/res/values-nl-rNL/strings.xml index fbebaa099..0d30b2b23 100644 --- a/amethyst/src/main/res/values-nl-rNL/strings.xml +++ b/amethyst/src/main/res/values-nl-rNL/strings.xml @@ -488,6 +488,21 @@ Nieuwe volglijst Nieuwe volglijst Kopieer/kloon volglijst + Beschrijving wijzigen + Deze lijst heeft geen beschrijving + Huidige beschrijving: + Stel een nieuwe naam/omschrijving in voor de gekloonde lijst hieronder. + Lijstnaam + Nieuwe lijstnaam + Lijstbeschrijving (optioneel) + Beschrijving nieuwe lijst + Lijst maken + Kopieer/kloon lijst + Lijst hernoemen + Bewerk lijst + Aanpassen + Je hernoemt de naam van + om.. Standaard poort is 9050 ## Verbind via Tor met Orbot \n\n1. Installeer [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) @@ -623,6 +638,7 @@ Gevolgde tags Relays Volg pakketten + Dit zijn lijsten van gebruikers die u aanbeveelt aan andere mensen. Alleen openbare gebruikers zijn toegestaan. Gelezen Feed algoritmes Marktplaats @@ -704,6 +720,17 @@ Plakken vanaf klembord Invalide NIP-47 URI De URI %1$s is geen geldige NIP-47 login-URI. + Verbinding maken met nieuwe NWC-wallet + Wallet niet gevonden + Amethyst kon geen wallet-apps vinden die Nostr Wallet Connect (NWC) ondersteunen. +\n\nWat je kan doen: +\n\t1. Verifieer NWC Support: Controleer of uw voorkeurswallet app compatibel is met Nostr Wallet Connect. +\n\t2. Maak een verbinding. Ga naar uw wallet-app en maak een nieuwe NWC verbinding aan. +\n\t3. Link naar Amethyst: Je wallet geeft je meestal drie opties: +\n\t\t3. Automatische link: Een knop om automatisch te openen en te verbinden met Amethyst. Als dat zo is, klik dan op die knop, open Amethist en druk op opslaan op het nieuwe scherm. +\n\t\t3. Handmatige link: Een URI voor verbinding, u kunt het plakpictogram op dit scherm kopiëren en klikken om het direct in te voeren. +\n\t\t3. QR-Code: De wallet maakt een QR-code die je kunt lezen op de QR-code knop op dit scherm. + Voor de interface van de app Donker-, Licht- of Systeemthema Automatisch afbeeldingen en GIF\'s laden @@ -875,6 +902,8 @@ Normaal Hoog Ongecomprimeerd + H.265/HEVC Codec gebruiken + Betere kwaliteit in kleinere bestandsformaten, maar niet alle apparaten ondersteunen H.265 playback. Concept bewerken Inloggen met QR-Code Route @@ -933,6 +962,16 @@ Het maken van een relay lijst speciaal ontworpen voor zoekopdracht en gebruikers-tagging zal deze resultaten verbeteren. Voeg tussen de 1 en 3 relays toe om te gebruiken bij het zoeken naar content of bij het taggen van gebruikers. Zorg ervoor dat uw gekozen relays implementatie van NIP-50 Goede opties zijn:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Outbox relays + Stel uw openbare outbox relays in om te posten + Het maken van een relay-lijst speciaal ontworpen voor het ontvangen van jouw inhoud is cruciaal voor de Nostr ervaring en de enige manier waarop jouw volgers je kunnen vinden. + Voer tussen de 1 en 3 relays in om je berichten te ontvangen. Zorg ervoor dat je geen betaling nodig hebt als je niet betaalt om in te voegen + Goede opties zijn:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social + Inbox relays + Stel uw openbare inbox relays in om meldingen te ontvangen + Het maken van een relay-lijst speciaal ontworpen voor het ontvangen van meldingen is cruciaal voor uw Nostr ervaring. + Voeg tussen de 1 en 3 relays toe die meldingen voor u ontvangen. Zorg ervoor dat ze geen betaling of vertrouwensweb van de afzender nodig hebben, anders ontvangt u alleen meldingen van betalers of langdurig gebruikers + Goede opties zijn:\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social DM uploaden Relay-instellingen Openbare thuis relays @@ -1058,6 +1097,9 @@ Kon bestand niet openen Geen torrent apps geïnstalleerd om het bestand te openen en te downloaden. Evenement heeft niet genoeg informatie om een magnet-link te maken + Mijn lijsten/sets + Mijn lijsten + Gebruikers Selecteer een lijst om de feed te filteren Afmelden bij apparaatvergrendeling Privébericht @@ -1079,4 +1121,27 @@ Wilt u het recente crashrapport verzenden naar Amethyst in een DM? Er zal geen persoonlijke informatie gedeeld worden Verzenden Dit bericht zal verdwijnen in %1$d dagen + Selecteer ondertekenaar + Al in de lijst + Privé leden + Openbare leden + Privéleden (%1$s) + Openbare leden (%1$s) + Gebruiker toevoegen aan de lijst + Gebruiker uit de lijst verwijderen + Volgpakket + Leden + Volglijst metadata + Volglijsten metadata kunnen door iedereen op Nostr. Alleen uw privéleden zijn versleuteld. + Volglijst metadata + Volgpakket metadata kan door iedereen op Nostr worden gezien en is vaak op veel websites gepubliceerd als opstartuitrustingen voor nieuwe gebruikers. + Wijzig volglijst + Pakketnaam + Nieuwe pakketnaam + Pakketbeschrijving + Nieuwe pakketbeschrijving + Uitzendlijst + Uitzendpakket + Verwijder lijst + Verwijder pakket From be2d976124b9e0a92ea89dfe0718149eb47fa9d3 Mon Sep 17 00:00:00 2001 From: kirpy Date: Mon, 17 Nov 2025 12:55:10 -0700 Subject: [PATCH 51/60] Open njump.to, iris.to, zap.stream and shosho.live in Amethyst --- amethyst/src/main/AndroidManifest.xml | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/amethyst/src/main/AndroidManifest.xml b/amethyst/src/main/AndroidManifest.xml index 4c34d20dd..9bbfce57b 100644 --- a/amethyst/src/main/AndroidManifest.xml +++ b/amethyst/src/main/AndroidManifest.xml @@ -133,6 +133,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 941f890e467e036a18ff69ab9f425b2b31a3d44b Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Mon, 17 Nov 2025 21:49:41 +0000 Subject: [PATCH 52/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-fr-rFR/strings.xml | 54 ++++++++++++++++++ .../src/main/res/values-hu-rHU/strings.xml | 55 ++++++++++--------- .../src/main/res/values-pl-rPL/strings.xml | 10 ++-- .../src/main/res/values-sl-rSI/strings.xml | 7 ++- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/amethyst/src/main/res/values-fr-rFR/strings.xml b/amethyst/src/main/res/values-fr-rFR/strings.xml index c24ae691b..eb5c21348 100644 --- a/amethyst/src/main/res/values-fr-rFR/strings.xml +++ b/amethyst/src/main/res/values-fr-rFR/strings.xml @@ -112,6 +112,7 @@ Envoyer Sauvegarder Créer + Renommer Annuler Échec du téléchargement de l\'image Adresse du relais @@ -124,6 +125,8 @@ Flux de chat public Flux mondial Flux de recherche + Rechercher et ajouter un utilisateur + Ajouter un utilisateur Ajouter un relais Nom Nom visible du public @@ -344,6 +347,7 @@ Publier le signalement Bloquer et Signaler Bloquer + Division manuelle de zaps Favoris Brouillons Favoris Privés @@ -445,6 +449,44 @@ Autour de moi Général Liste en Sourdine + Marque-pages étiquetés + Marque-pages généraux + Public + Privé + Mixte + Nouveau + %1$s est un membre public + %1$s est un membre privé + Ajouter en tant que membre public + Ajouter en tant que membre privé + Membres publics + Membres privés + Profils publics + Profils privés + membre + membres + Aucun membre + Vide + %1$s n\'est pas dans cette liste + %1$s n\'est pas un membre + Vos listes et %1$s + Vos listes + Un problème est survenu lors de la récupération : %1$s + Créer une nouvelle liste + Modifier la description + Cette liste n\'a pas de description + Description actuelle : + Nom de la liste + Nom de la nouvelle liste + Description de la liste (facultatif) + Description de la nouvelle liste + Créer une liste + Copier/Dupliquer la liste + Renommer la liste + Modifier la liste + Modifier + Vous renommez depuis + vers.. Le port par défaut est 9050 ## Se connecter à travers Tor avec Orbot \n\n1. Installe [Orbot](https://play.google.com/store/apps/details?id=org.torproject.android) @@ -661,6 +703,7 @@ Coller depuis le presse-papiers URI NIP-47 invalide L\'URI %1$s n\'est pas une URI de connexion NIP-47 valide. + Portefeuille introuvable Pour l\'interface de l\'App Sombre, Clair ou thème Système Charger automatiquement les images et les GIFs @@ -832,6 +875,7 @@ Moyenne Haute Non compressé + Utiliser le codec H.265/HEVC Modifier le brouillon Se connecter avec un QR Code Route @@ -1014,6 +1058,8 @@ Télécharger Échec de l\'ouverture du fichier Aucune application torrent installée pour ouvrir et télécharger le fichier. + Mes listes + Utilisateurs Sélectionnez une liste pour filtrer le fil Se déconnecter au verrouillage de l\'appareil Message privé @@ -1035,4 +1081,12 @@ Voulez-vous envoyer le rapport d\'erreur récent à Amethyst dans un MP ? Aucune information personnelle ne sera partagée Envoyer Ce message disparaîtra dans %1$d jours + Déjà dans la liste + Membres privés + Membres publics + Membres privés (%1$s) + Membres publics (%1$s) + Ajouter l\'utilisateur à la liste + Supprimer l\'utilisateur de la liste + Membres diff --git a/amethyst/src/main/res/values-hu-rHU/strings.xml b/amethyst/src/main/res/values-hu-rHU/strings.xml index 0c7151217..d0278c771 100644 --- a/amethyst/src/main/res/values-hu-rHU/strings.xml +++ b/amethyst/src/main/res/values-hu-rHU/strings.xml @@ -115,7 +115,7 @@ Átnevezés Mégse Nem sikerült feltölteni a képet - Atjátszó címe + Átjátszó címe Bejegyzések Bájt Hibák @@ -347,6 +347,7 @@ Bejelentés közzététele Letiltás és bejelentés Letiltás + Kézi Zap-megosztás Könyvjelző Piszkozatok Privát könyvjelzők @@ -427,7 +428,7 @@ Feltöltés… Feldolgozás… Letöltés… - Hash-selés… + Kivonatolás Kész Hiba Saját átjátszók (NIP-95) @@ -449,7 +450,7 @@ Közelben lévők bejegyzései Globális Némítottak bejegyzései - Követési gyüjtemények + Követési listák Ezek a követési listák az Ön saját alkalmazás-használatából lettek kialakítva. A felhasználókat privát vagy nyilvánosan követheti Címkézett könyvjelzők Általános könyvjelzők @@ -460,14 +461,14 @@ \nKoppintson a frissítéshez vagy érintse meg a hozzáadás gombot a gyüjtemény létrehozásához. Új - Szerző hozzáadása a követési gyűjteményhez + Szerző hozzáadása a követési listához Felhasználó hozzáadása vagy eltávolítása a listákból, vagy új lista létrehozása ezzel a felhasználóval. - Ikon a(z) %1$s nevű listához + Ikon a követési listához %1$s egy nyílvános tag %1$s egy privát tag Hozzáadás mint nyílvános tag Hozzáadás mint privát tag - Publikus Tagok + Nyilvános tagok Privát Tagok Nyílvános profilok Privát profilok @@ -478,26 +479,26 @@ A(z) %1$s nincs a listában %1$s nem tag Saját listák és %1$s - Saját követési gyüjtemények - Nem találhatók követési gyüjtemények, vagy nincs követési gyüjteménye. Érintse meg az alábbi gombot a frissítéshez vagy használja a menüt egy gyüjtemény létrehozásához. + Saját listák + Nem találhatók vagy Önnek még nincs követési listája. Koppintson az alábbi gombra a frissítéshez vagy használja a menüt egy új lista létrehozásához. Probléma történt a következő lekérdezésekor: %1$s Új lista létrehozása - Új %1$s lista létrehozása felhasználóval - %1$s követési gyüjtemény létrehozása, és hozzáadás a következhöz: %2$s. - Új %1$s lista + Új lista %1$s tagsággal + Egy új követési gyüjtemény létrehozása, és %1$s hozzáadása mint %2$s tag. + Új követési lista Új követési lista - Követési gyüjtemény másolása/klónozása + Követési lista másolása/klónozása Leírás módosítása Ennek a listának nincs leírása Jelenlegi leírás: - Az alábbiakban beállíthat egy egyéni nevet/leírást ehhez a klónozott követési gyűjteményhez. - Név megadása - (Gyüjtemény eredeti neve) - Leírás megadása (nem kötelező) - (Gyüjtemény eredeti leírása) - Gyüjtemény létrehozása - Gyüjtemény másolása/klónozása - Gyüjtemény átnevezése + Az alábbiakban beállíthat egy új nevet/leírást ehhez a klónozott követési listához. + Listanév + Új listanév + Listaleírás (nem kötelező) + Új listaleírás + Lista létrehozása + Lista másolása/klónozása + Lista átnevezése Lista szerkesztése Módosítás Ön átnevezi a követési gyüjteményt erről: @@ -692,7 +693,7 @@ Zap-ek továbbítása neki: A funkciót támogató kliensek a Zap-eket az alábbi LN-címre vagy felhasználói profilra továbbítják az Öné helyett A helyszín megjelenítése mint - Hozzáadja a helyének geohash-sét a bejegyzéséhez. A nyilvánosság tudni fogja, hogy a jelenlegi helytől 5 km-en (3 mi) belül tertózkodik + Hozzáadja a helyszínének geokivonatát a bejegyzéséhez. A nyilvánosság tudni fogja, hogy a jelenlegi helytől 5 km-en (3 mi) belül tertózkodik Helyszín-alapú bejegyzés Csak a helyszín követői láthatják. Az általános követők nem fogják látni. Hashtag-exkluzív bejegyzés @@ -719,15 +720,15 @@ Beszúrás vágólapról Érvénytelen NIP-47 URI A(z) %1$s URI nem egy érvényes NIP-47 bejelentkezési URI. - Csatlakozás az új NWC tárcához - Tárca nem található - Az Amethyst nem talált olyan pénztárcaalkalmazást, amely támogatja a Nostr Wallet Connect (NWC) szolgáltatást. + Kapcsolódás az új NWC-pénztárcához + Nem található pénztárca + Az Amethyst nem talált olyan pénztárca-alkalmazást, amely támogatja a Nostr Wallet Connect (NWC) szolgáltatást. \n\nAmit tehet: -\n\t1. NWC támogatás ellenőrzése: Ellenőrizze, hogy a kívánt pénztárcaalkalmazás kompatibilis-e a Nostr Wallet Connect szolgáltatással. +\n\t1. NWC-támogatás ellenőrzése: Ellenőrizze, hogy a kívánt pénztárca-alkalmazás kompatibilis-e a Nostr Wallet Connect szolgáltatással. \n\t2. Kapcsolat létrehozása: Nyissa meg a pénztárcaalkalmazást, és hozzon létre egy új NWC-kapcsolatot. \n\t3. Kapcsolódás az Amethysthez: A pénztárcája általában három lehetőséget kínál: -\n\t\t3.1 Automatikus kapcsolódás: Egy gomb az Amethyst automatikus megnyitásához és csatlakoztatásához. Ha igen, kattintson erre a gombra, nyissa meg az Amethyst alkalmazást, és mentse el az új képernyőn. -\n\t\t3.2 Manuális kapcsolódás: Egy kapcsolat URl, amelyet kimásolhat, és a képernyőn található beillesztés ikonra kattintva közvetlenül beírhatja. +\n\t\t3.1 Automatikus kapcsolódás: Egy gomb az Amethyst automatikus megnyitásához és kapcsolódáshoz. Koppintson erre a gombra, nyissa meg az Amethyst alkalmazást, és mentse el az új képernyőn. +\n\t\t3.2 Kézi kapcsolódás: Egy kapcsolódási cím, amelyet kimásolhat, és a képernyőn található beillesztés gombra koppintva közvetlenül beírhatja. \n\t\t3.3 QR-kód: A pénztárca létrehoz egy QR-kódot, amelyet a képernyőn található QR-kód gombról olvashat be. Az alkalmazás felületéhez diff --git a/amethyst/src/main/res/values-pl-rPL/strings.xml b/amethyst/src/main/res/values-pl-rPL/strings.xml index 6fe375b37..48d6c77b6 100644 --- a/amethyst/src/main/res/values-pl-rPL/strings.xml +++ b/amethyst/src/main/res/values-pl-rPL/strings.xml @@ -465,14 +465,14 @@ %1$s jest uczestnikiem prywatnym Dodaj jako uczestnika publicznego Dodaj jako uczestnika prywatnego - Uczestnicy publiczni - Prywatni uczestnicy + Publiczne + Prywatne Profile publiczne Profile prywatne uczestnik - uczestnicy + członkowie Brak uczestników - Pusty + Pusto %1$s nie jest na liście %1$s nie jest uczestnikiem %1$s na Twoich listach @@ -480,7 +480,7 @@ Nie znaleziono list obserwowanych lub nie masz żadnych list obserwowanych. Naciśnij poniżej, aby odświeżyć lub użyj menu, aby utworzyć nową. Podczas pobierania wystąpił błąd: %1$s Utwórz nową listę - \"Utwórz nową listę %1$s z użytkownikiem + \"Utwórz nową listę %1$s z członkiem Tworzy zestaw obserwowanych %1$s i dodaje do niego %2$s. Nowa lista Nowa Kategoria diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 67d4e2f1f..102f1acec 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -89,7 +89,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Napaka pri razčlembi sporočila o napaki " Sledi" " Sledilcev" - "%1$s Sledi" + "%1$s Sledim" "%1$s Sledilcev" Profil Varnostni filtri @@ -185,7 +185,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaše Galerija "sledilcev" - "Reportaže" + "Prijav" "%1$s Prijave" Več možnosti " Releji" @@ -199,7 +199,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Kopiraj javni ključ (NPub) v odložišče Pošlji direktno sporočilo Uredi uporabnikove metapodatke - Sledim + Že sledim Sledi nazaj Deblokiraj Kopiraj uporabnikov ID @@ -358,6 +358,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Objavi prijavo Blokiraj in prijavi Blokiraj + Ročno razdeli zape Zaznamki Osnutki Privatni zaznamki From 3762fb7b2a4c62afb42aca3dc94e09e66d6811e6 Mon Sep 17 00:00:00 2001 From: StellarStoic Date: Tue, 18 Nov 2025 13:23:36 +0100 Subject: [PATCH 53/60] ui: center QR dialog content and reduce excessive top spacing --- .../amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt index ac561432a..dd6d24b21 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt @@ -150,8 +150,9 @@ fun ShowQRDialog( ) { Column { Column( - modifier = Modifier.fillMaxSize().padding(horizontal = 10.dp), - verticalArrangement = Arrangement.SpaceAround, + modifier = Modifier.padding(horizontal = 10.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { if (presenting) { Column { From 326f059d1e3e83a9f7ef2a8306c913a277a75278 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 18 Nov 2025 16:00:28 -0500 Subject: [PATCH 54/60] Removes logging for connected and available relay dump --- .../java/com/vitorpamplona/amethyst/DebugUtils.kt | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt index 78a12f4bb..178950005 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/DebugUtils.kt @@ -58,17 +58,6 @@ fun debugState(context: Context) { Log.d(STATE_DUMP_TAG, "Memory Class $memClass MB (largeHeap $isLargeHeap)") } - Log.d( - STATE_DUMP_TAG, - "Connected Relays: " + - Amethyst.instance.client - .relayStatusFlow() - .value.connected.size + "/" + - Amethyst.instance.client - .relayStatusFlow() - .value.available.size, - ) - Log.d( STATE_DUMP_TAG, "Indexed Relays: " + From a36d35912a1339abe57114af6a23fbd82cb5b1c1 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 18 Nov 2025 17:12:39 -0500 Subject: [PATCH 55/60] Manages the pool state without having to loop through relays, saving some milliseconds of processing. --- .../vitorpamplona/amethyst/model/Account.kt | 4 +- .../AccountFollowsLoaderSubAssembler.kt | 2 +- .../loaders/UserOutboxFinderSubAssembler.kt | 2 +- .../ui/navigation/drawer/DrawerContent.kt | 103 ++++++++---------- .../connected/ConnectedRelayListViewModel.kt | 4 +- .../vitorpamplona/amethyst/ui/theme/Shape.kt | 2 + .../nip01Core/relay/client/INostrClient.kt | 9 +- .../nip01Core/relay/client/NostrClient.kt | 4 +- .../nip01Core/relay/client/pool/RelayPool.kt | 80 +++++--------- 9 files changed, 90 insertions(+), 120 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt index 0eb7fa0b5..e25bc0e08 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/Account.kt @@ -704,7 +704,7 @@ class Account( fun computeRelayListToBroadcast(event: Event): Set { if (event is MetadataEvent || event is AdvertisedRelayListEvent) { // everywhere - return followPlusAllMineWithIndex.flow.value + client.relayStatusFlow().value.available + return followPlusAllMineWithIndex.flow.value + client.availableRelaysFlow().value } if (event is GiftWrapEvent) { val receiver = event.recipientPubKey() @@ -904,7 +904,7 @@ class Account( } fun sendLiterallyEverywhere(event: Event) { - client.send(event, followPlusAllMineWithIndex.flow.value + client.relayStatusFlow().value.available) + client.send(event, followPlusAllMineWithIndex.flow.value + client.availableRelaysFlow().value) cache.justConsumeMyOwnEvent(event) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt index 87c91c143..9c7db9910 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/account/follows/AccountFollowsLoaderSubAssembler.kt @@ -154,7 +154,7 @@ class AccountFollowsLoaderSubAssembler( println("AccountFollowNeeds ${users.size}") - val connectedRelays = client.relayStatusFlow().value.connected + val connectedRelays = client.connectedRelaysFlow().value val perRelay = pickRelaysToLoadUsers(users, accounts, connectedRelays, failureTracker.cannotConnectRelays, hasTried) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/loaders/UserOutboxFinderSubAssembler.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/loaders/UserOutboxFinderSubAssembler.kt index bb145322d..76108f540 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/loaders/UserOutboxFinderSubAssembler.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/relayClient/reqCommand/user/loaders/UserOutboxFinderSubAssembler.kt @@ -96,7 +96,7 @@ class UserOutboxFinderSubAssembler( if (noOutboxList.isEmpty()) return null val accounts = keys.mapTo(mutableSetOf()) { it.account } - val connectedRelays = client.relayStatusFlow().value.connected + val connectedRelays = client.connectedRelaysFlow().value val perRelayKeysBoth = pickRelaysToLoadUsers( diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index a8604e363..2456f9d05 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -112,11 +112,11 @@ import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer import com.vitorpamplona.amethyst.ui.theme.Font18SP import com.vitorpamplona.amethyst.ui.theme.IconRowModifier import com.vitorpamplona.amethyst.ui.theme.IconRowTextModifier -import com.vitorpamplona.amethyst.ui.theme.Size16dp import com.vitorpamplona.amethyst.ui.theme.Size20Modifier import com.vitorpamplona.amethyst.ui.theme.Size22Modifier import com.vitorpamplona.amethyst.ui.theme.Size26Modifier import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer +import com.vitorpamplona.amethyst.ui.theme.Width16Space import com.vitorpamplona.amethyst.ui.theme.bannerModifier import com.vitorpamplona.amethyst.ui.theme.drawerSpacing import com.vitorpamplona.amethyst.ui.theme.placeholderText @@ -124,7 +124,8 @@ import com.vitorpamplona.amethyst.ui.theme.profileContentHeaderModifier import com.vitorpamplona.quartz.nip01Core.core.Address import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.core.ImmutableListOfLists -import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayPool +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine @Composable fun DrawerContent( @@ -537,40 +538,6 @@ fun ListContent( } } -@Composable -private fun RelayStatus(accountViewModel: AccountViewModel) { - val connectedRelaysText by accountViewModel.account.client - .relayStatusFlow() - .collectAsStateWithLifecycle() - - RenderRelayStatus(connectedRelaysText) -} - -@Composable -private fun RenderRelayStatus(relayPool: RelayPool.RelayPoolStatus) { - val text by - remember(relayPool) { derivedStateOf { "${relayPool.connected.size}/${relayPool.available.size}" } } - - val placeHolder = MaterialTheme.colorScheme.placeholderText - - val color by - remember(relayPool) { - derivedStateOf { - if (relayPool.isConnected) { - placeHolder - } else { - Color.Red - } - } - } - - Text( - text = text, - color = color, - style = MaterialTheme.typography.titleMedium, - ) -} - @Composable fun NavigationRow( title: Int, @@ -691,35 +658,55 @@ fun IconRowRelays( modifier = Modifier .fillMaxWidth() - .clickable { onClick() }, + .padding(vertical = 15.dp, horizontal = 25.dp) + .clickable(onClick = onClick), + verticalAlignment = Alignment.CenterVertically, ) { - Row( - modifier = - Modifier - .fillMaxWidth() - .padding(vertical = 15.dp, horizontal = 25.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Icon( - painter = painterRes(R.drawable.relays, 4), - contentDescription = stringRes(R.string.relay_setup), - modifier = Modifier.size(22.dp), - tint = MaterialTheme.colorScheme.onSurface, - ) + Icon( + painter = painterRes(R.drawable.relays, 4), + contentDescription = stringRes(R.string.relay_setup), + modifier = Size22Modifier, + tint = MaterialTheme.colorScheme.onSurface, + ) - Text( - modifier = Modifier.padding(start = 16.dp), - text = stringRes(id = R.string.relay_setup), - fontSize = 18.sp, - ) + Text( + modifier = IconRowTextModifier, + text = stringRes(id = R.string.relay_setup), + fontSize = Font18SP, + ) - Spacer(modifier = Modifier.width(Size16dp)) + Spacer(modifier = Width16Space) - RelayStatus(accountViewModel = accountViewModel) - } + RelayStatus(accountViewModel) } } +class PoolStatus( + val share: String, + val isConnected: Boolean, +) + +@Composable +private fun RelayStatus(accountViewModel: AccountViewModel) { + val statusCounterFlow: Flow = + remember(accountViewModel) { + combine( + accountViewModel.account.client.connectedRelaysFlow(), + accountViewModel.account.client.availableRelaysFlow(), + ) { connected, available -> + PoolStatus("${connected.size}/${available.size}", connected.isNotEmpty()) + } + } + + val relayPool by statusCounterFlow.collectAsStateWithLifecycle(PoolStatus("", false)) + + Text( + text = relayPool.share, + color = if (relayPool.isConnected) MaterialTheme.colorScheme.placeholderText else Color.Red, + style = MaterialTheme.typography.titleMedium, + ) +} + @Composable fun BottomContent( user: User, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/connected/ConnectedRelayListViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/connected/ConnectedRelayListViewModel.kt index 0479378fb..2c7463e74 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/connected/ConnectedRelayListViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/connected/ConnectedRelayListViewModel.kt @@ -50,8 +50,8 @@ class ConnectedRelayListViewModel : BasicRelaySetupInfoModel() { override fun getRelayList(): List = account.client - .relayStatusFlow() - .value.available + .availableRelaysFlow() + .value .sorted() override suspend fun saveRelayList(urlList: List) { 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 c322daa36..1fcd3daab 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 @@ -255,6 +255,8 @@ val drawerSpacing = Modifier.padding(top = Size10dp, start = Size25dp, end = Siz val IconRowTextModifier = Modifier.padding(start = 16.dp) val IconRowModifier = Modifier.fillMaxWidth().padding(vertical = 15.dp, horizontal = 25.dp) +val Width16Space = Modifier.width(Size16dp) + val emptyLineItemModifier = Modifier.height(Size75dp).fillMaxWidth() val imageHeaderBannerSize = Modifier.fillMaxWidth().height(150.dp) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/INostrClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/INostrClient.kt index 41ac7b89a..2206257c1 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/INostrClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/INostrClient.kt @@ -22,7 +22,6 @@ package com.vitorpamplona.quartz.nip01Core.relay.client import com.vitorpamplona.quartz.nip01Core.core.Event import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener -import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayPool import com.vitorpamplona.quartz.nip01Core.relay.client.reqs.IRequestListener import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient import com.vitorpamplona.quartz.nip01Core.relay.client.single.newSubId @@ -32,7 +31,9 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow interface INostrClient { - fun relayStatusFlow(): StateFlow + fun connectedRelaysFlow(): StateFlow> + + fun availableRelaysFlow(): StateFlow> fun connect() @@ -80,7 +81,9 @@ interface INostrClient { } object EmptyNostrClient : INostrClient { - override fun relayStatusFlow() = MutableStateFlow(RelayPool.RelayPoolStatus()) + override fun connectedRelaysFlow() = MutableStateFlow(emptySet()) + + override fun availableRelaysFlow() = MutableStateFlow(emptySet()) override fun connect() { } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt index c62e09d21..cc3ef2db3 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/NostrClient.kt @@ -320,5 +320,7 @@ class NostrClient( override fun getCountFiltersOrNull(subId: String): Map>? = activeCounts.getSubscriptionFiltersOrNull(subId) - override fun relayStatusFlow() = relayPool.statusFlow + override fun connectedRelaysFlow() = relayPool.connectedRelays + + override fun availableRelaysFlow() = relayPool.availableRelays } diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt index 40f6b9c4d..cf0490924 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nip01Core/relay/client/pool/RelayPool.kt @@ -20,7 +20,6 @@ */ package com.vitorpamplona.quartz.nip01Core.relay.client.pool -import androidx.compose.runtime.Immutable import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.EmptyClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient @@ -31,8 +30,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl import com.vitorpamplona.quartz.nip01Core.relay.sockets.WebsocketBuilder import com.vitorpamplona.quartz.utils.cache.LargeCache import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update /** * RelayPool manages a collection of Nostr relays, abstracting individual connections and providing @@ -61,9 +60,11 @@ class RelayPool( ) : IRelayClientListener { private val relays = LargeCache() - // Backing property to avoid flow emissions from other classes - private val _statusFlow = MutableStateFlow(RelayPoolStatus()) - val statusFlow: StateFlow = _statusFlow.asStateFlow() + private val _connectedRelays = MutableStateFlow>(emptySet()) + val connectedRelays = _connectedRelays.asStateFlow() + + private val _availableRelays = MutableStateFlow>(emptySet()) + val availableRelays = _availableRelays.asStateFlow() fun getRelay(url: NormalizedRelayUrl): IRelayClient? = relays.get(url) @@ -87,21 +88,18 @@ class RelayPool( relay.connectAndSyncFiltersIfDisconnected(ignoreRetryDelays) } } - updateStatus() } fun connect() { relays.forEach { url, relay -> relay.connect() } - updateStatus() } fun connectIfDisconnected() { relays.forEach { url, relay -> relay.connectAndSyncFiltersIfDisconnected() } - updateStatus() } fun connectIfDisconnected(relay: NormalizedRelayUrl) = relays.get(relay)?.connectAndSyncFiltersIfDisconnected() @@ -110,7 +108,6 @@ class RelayPool( relays.forEach { url, relay -> relay.disconnect() } - updateStatus() } fun sendOrConnectAndSync( @@ -144,7 +141,13 @@ class RelayPool( // -------------------- // Pool Maintenance // -------------------- - fun getOrCreateRelay(relay: NormalizedRelayUrl) = relays.getOrCreate(relay, ::createNewRelay) + fun getOrCreateRelay(relay: NormalizedRelayUrl): IRelayClient { + val r = relays.getOrCreate(relay, ::createNewRelay) + if (_availableRelays.value.size != relays.size()) { + _availableRelays.update { relays.keys() } + } + return r + } fun createRelayIfAbsent(relay: NormalizedRelayUrl): Boolean = relays.createIfAbsent(relay, ::createNewRelay) @@ -155,39 +158,40 @@ class RelayPool( val toRemove = relays.keys() - newRelays var atLeastOne = false - newRelays.forEach { - if (createRelayIfAbsent(it)) { + newRelays.forEach { relay -> + if (createRelayIfAbsent(relay)) { atLeastOne = true } } - toRemove.forEach { - if (removeRelayInner(it)) { + toRemove.forEach { relay -> + if (removeRelayInner(relay)) { atLeastOne = true } } if (atLeastOne) { - updateStatus() + _availableRelays.update { relays.keys() } } } fun addRelay(relay: NormalizedRelayUrl): IRelayClient { if (createRelayIfAbsent(relay)) { - updateStatus() + _availableRelays.update { relays.keys() } } return getOrCreateRelay(relay) } fun addAllRelays(relayList: List) { var atLeastOne = false - relayList.forEach { - if (createRelayIfAbsent(it)) { + relayList.forEach { relay -> + if (createRelayIfAbsent(relay)) { atLeastOne = true } } + if (atLeastOne) { - updateStatus() + _availableRelays.update { relays.keys() } } } @@ -202,7 +206,7 @@ class RelayPool( fun removeRelay(relay: NormalizedRelayUrl) { if (removeRelayInner(relay)) { - updateStatus() + _availableRelays.update { relays.keys() } } } @@ -210,7 +214,7 @@ class RelayPool( if (relays.size() > 0) { disconnect() relays.clear() - updateStatus() + _availableRelays.update { emptySet() } } } @@ -224,12 +228,12 @@ class RelayPool( pingMillis: Int, compressed: Boolean, ) { - updateStatus() + _connectedRelays.update { it + relay.url } listener.onConnected(relay, pingMillis, compressed) } override fun onDisconnected(relay: IRelayClient) { - updateStatus() + _connectedRelays.update { it - relay.url } listener.onDisconnected(relay) } @@ -251,33 +255,5 @@ class RelayPool( success: Boolean, ) = listener.onSent(relay, cmdStr, cmd, success) - // --------------- - // STATUS Reports - // --------------- - - fun availableRelays(): Set = relays.keys() - - fun connectedRelays(): Set = - relays.mapNotNullIntoSet { url, relay -> - if (relay.isConnected()) { - url - } else { - null - } - } - - private fun updateStatus() { - val connected = connectedRelays() - val available = availableRelays() - if (_statusFlow.value.connected != connected || _statusFlow.value.available != available) { - _statusFlow.tryEmit(RelayPoolStatus(connected, available)) - } - } - - @Immutable - data class RelayPoolStatus( - val connected: Set = emptySet(), - val available: Set = emptySet(), - val isConnected: Boolean = connected.isNotEmpty(), - ) + fun connectedRelaysCount(): Int = relays.count { url, relay -> relay.isConnected() } } From 302aee325f1f2df2f32666a5740194c565574865 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Tue, 18 Nov 2025 22:19:14 +0000 Subject: [PATCH 56/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-fr-rFR/strings.xml | 23 +++++++++++++++++++ .../src/main/res/values-sl-rSI/strings.xml | 6 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/res/values-fr-rFR/strings.xml b/amethyst/src/main/res/values-fr-rFR/strings.xml index eb5c21348..a863d2a1d 100644 --- a/amethyst/src/main/res/values-fr-rFR/strings.xml +++ b/amethyst/src/main/res/values-fr-rFR/strings.xml @@ -473,9 +473,11 @@ Vos listes Un problème est survenu lors de la récupération : %1$s Créer une nouvelle liste + Nouvelle liste avec %1$s membres Modifier la description Cette liste n\'a pas de description Description actuelle : + Définissez un nouveau nom/description pour la liste dupliquée ci-dessous. Nom de la liste Nom de la nouvelle liste Description de la liste (facultatif) @@ -622,6 +624,7 @@ Tags suivis Relais Packs à suivre + Ce sont des listes d\'utilisateurs que vous recommandez à d\'autres personnes. Seuls les utilisateurs publics sont autorisés. Lectures Algorithmes de flux Place de Marché @@ -703,6 +706,7 @@ Coller depuis le presse-papiers URI NIP-47 invalide L\'URI %1$s n\'est pas une URI de connexion NIP-47 valide. + Se connecter à un nouveau portefeuille NWC Portefeuille introuvable Pour l\'interface de l\'App Sombre, Clair ou thème Système @@ -876,6 +880,7 @@ Haute Non compressé Utiliser le codec H.265/HEVC + Une meilleure qualité avec des tailles de fichier plus petites, mais tous les appareils ne supportent pas la lecture H.265. Modifier le brouillon Se connecter avec un QR Code Route @@ -934,6 +939,15 @@ La création d\'une liste de relais spécialement conçue pour la recherche et l\'étiquetage utilisateur améliorera ces résultats. Insérez de 1 à 3 relais à utiliser lors de la recherche de contenu ou de l\'étiquetage utilisateur. Assurez-vous que les relais que vous avez choisis implémentent le NIP-50 De bonnes options sont:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Relais d\'envoi + Configurez vos relais d\'envoi pour publier + Créer une liste de relais spécialement conçue pour recevoir votre contenu est crucial pour votre expérience Nostr et la seule façon que vos abonnés puissent vous trouver. + Insérez entre 1 et 3 relais qui reçoivent vos messages. Assurez-vous qu\'ils ne nécessitent pas de paiement si vous ne payez pas pour publier + De bonnes options sont :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social + Configurez vos relais de messagerie publique pour recevoir des notifications + Créer une liste de relais spécialement conçue pour recevoir des notifications est crucial pour votre expérience Nostr. + Insérez entre 1 et 3 relais qui reçoivent des notifications pour vous. Assurez-vous qu\'ils n\'exigent pas de paiement ou de web de confiance de la part de l\'expéditeur, sinon vous ne recevrez que des notifications des payeurs ou des utilisateurs à long terme + De bonnes options sont :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social Téléversement de MP Paramètres du relais Relais publics d\'accueil @@ -1058,6 +1072,7 @@ Télécharger Échec de l\'ouverture du fichier Aucune application torrent installée pour ouvrir et télécharger le fichier. + L\'événement ne possède pas assez d\'informations pour construire un lien magnet Mes listes Utilisateurs Sélectionnez une liste pour filtrer le fil @@ -1089,4 +1104,12 @@ Ajouter l\'utilisateur à la liste Supprimer l\'utilisateur de la liste Membres + Nom du pack + Nom du nouveau pack + Description du pack + Description du nouveau pack + Liste de diffusion + Pack de diffusion + Supprimer la liste + Supprimer le pack diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 102f1acec..899b5bdf0 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -185,8 +185,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaše Galerija "sledilcev" - "Prijav" - "%1$s Prijave" + "Prijave" + "%1$s Prijav" Več možnosti " Releji" Spletna stran @@ -453,7 +453,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaši podatki bodo takoj preneseni v običajno omrežje Da Ne - Spisek komu sledimo + Seznam sledenih Vse, čemur sledimo Vsi sledeni sledenih Privzeti seznam sledenih From 07ce3d5e5f05e2a296ce654d24fa068511fcee63 Mon Sep 17 00:00:00 2001 From: Crowdin Bot Date: Tue, 18 Nov 2025 22:20:37 +0000 Subject: [PATCH 57/60] New Crowdin translations by GitHub Action --- .../src/main/res/values-fr-rFR/strings.xml | 23 +++++++++++++++++++ .../src/main/res/values-sl-rSI/strings.xml | 6 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/amethyst/src/main/res/values-fr-rFR/strings.xml b/amethyst/src/main/res/values-fr-rFR/strings.xml index eb5c21348..a863d2a1d 100644 --- a/amethyst/src/main/res/values-fr-rFR/strings.xml +++ b/amethyst/src/main/res/values-fr-rFR/strings.xml @@ -473,9 +473,11 @@ Vos listes Un problème est survenu lors de la récupération : %1$s Créer une nouvelle liste + Nouvelle liste avec %1$s membres Modifier la description Cette liste n\'a pas de description Description actuelle : + Définissez un nouveau nom/description pour la liste dupliquée ci-dessous. Nom de la liste Nom de la nouvelle liste Description de la liste (facultatif) @@ -622,6 +624,7 @@ Tags suivis Relais Packs à suivre + Ce sont des listes d\'utilisateurs que vous recommandez à d\'autres personnes. Seuls les utilisateurs publics sont autorisés. Lectures Algorithmes de flux Place de Marché @@ -703,6 +706,7 @@ Coller depuis le presse-papiers URI NIP-47 invalide L\'URI %1$s n\'est pas une URI de connexion NIP-47 valide. + Se connecter à un nouveau portefeuille NWC Portefeuille introuvable Pour l\'interface de l\'App Sombre, Clair ou thème Système @@ -876,6 +880,7 @@ Haute Non compressé Utiliser le codec H.265/HEVC + Une meilleure qualité avec des tailles de fichier plus petites, mais tous les appareils ne supportent pas la lecture H.265. Modifier le brouillon Se connecter avec un QR Code Route @@ -934,6 +939,15 @@ La création d\'une liste de relais spécialement conçue pour la recherche et l\'étiquetage utilisateur améliorera ces résultats. Insérez de 1 à 3 relais à utiliser lors de la recherche de contenu ou de l\'étiquetage utilisateur. Assurez-vous que les relais que vous avez choisis implémentent le NIP-50 De bonnes options sont:\n - nostr.wine\n - relay.nostr.band\n - relay.noswhere.com + Relais d\'envoi + Configurez vos relais d\'envoi pour publier + Créer une liste de relais spécialement conçue pour recevoir votre contenu est crucial pour votre expérience Nostr et la seule façon que vos abonnés puissent vous trouver. + Insérez entre 1 et 3 relais qui reçoivent vos messages. Assurez-vous qu\'ils ne nécessitent pas de paiement si vous ne payez pas pour publier + De bonnes options sont :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social + Configurez vos relais de messagerie publique pour recevoir des notifications + Créer une liste de relais spécialement conçue pour recevoir des notifications est crucial pour votre expérience Nostr. + Insérez entre 1 et 3 relais qui reçoivent des notifications pour vous. Assurez-vous qu\'ils n\'exigent pas de paiement ou de web de confiance de la part de l\'expéditeur, sinon vous ne recevrez que des notifications des payeurs ou des utilisateurs à long terme + De bonnes options sont :\n - nos.lol\n - nostr.mom\n - nostr.bitcoiner.social Téléversement de MP Paramètres du relais Relais publics d\'accueil @@ -1058,6 +1072,7 @@ Télécharger Échec de l\'ouverture du fichier Aucune application torrent installée pour ouvrir et télécharger le fichier. + L\'événement ne possède pas assez d\'informations pour construire un lien magnet Mes listes Utilisateurs Sélectionnez une liste pour filtrer le fil @@ -1089,4 +1104,12 @@ Ajouter l\'utilisateur à la liste Supprimer l\'utilisateur de la liste Membres + Nom du pack + Nom du nouveau pack + Description du pack + Description du nouveau pack + Liste de diffusion + Pack de diffusion + Supprimer la liste + Supprimer le pack diff --git a/amethyst/src/main/res/values-sl-rSI/strings.xml b/amethyst/src/main/res/values-sl-rSI/strings.xml index 102f1acec..899b5bdf0 100644 --- a/amethyst/src/main/res/values-sl-rSI/strings.xml +++ b/amethyst/src/main/res/values-sl-rSI/strings.xml @@ -185,8 +185,8 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaše Galerija "sledilcev" - "Prijav" - "%1$s Prijave" + "Prijave" + "%1$s Prijav" Več možnosti " Releji" Spletna stran @@ -453,7 +453,7 @@ Za podpisovanje se je potrebno prijaviti s privatnim ključem Vaši podatki bodo takoj preneseni v običajno omrežje Da Ne - Spisek komu sledimo + Seznam sledenih Vse, čemur sledimo Vsi sledeni sledenih Privzeti seznam sledenih From 2f93aa87777f08570a4aefba07e1f5a4a22fb1b9 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 18 Nov 2025 17:56:04 -0500 Subject: [PATCH 58/60] Moves the QR Code screen from Dialog to full Route --- .../amethyst/ui/navigation/AppNavigation.kt | 3 + .../ui/navigation/drawer/DrawerContent.kt | 19 +- .../amethyst/ui/navigation/routes/Routes.kt | 5 + .../profile/header/DrawAdditionalInfo.kt | 18 +- .../screen/loggedIn/qrcode/QrCodeScanner.kt | 2 + .../ui/screen/loggedIn/qrcode/ShowQRDialog.kt | 236 ----------------- .../ui/screen/loggedIn/qrcode/ShowQRScreen.kt | 245 ++++++++++++++++++ 7 files changed, 258 insertions(+), 270 deletions(-) delete mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt create mode 100644 amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt 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 af2e26dad..259dc3446 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 @@ -90,6 +90,7 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.NotificationS import com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications.publicMessages.NewPublicMessageScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.privacy.PrivacyOptionsScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.ProfileScreen +import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.ShowQRScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.redirect.LoadRedirectScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.AllRelayListScreen import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.RelayInformationScreen @@ -138,6 +139,8 @@ fun AppNavigation( composableFromBottomArgs { PeopleListMetadataScreen(it.dTag, accountViewModel, nav) } composableFromBottomArgs { FollowPackMetadataScreen(it.dTag, accountViewModel, nav) } + composableFromBottomArgs { ShowQRScreen(it.pubkey, accountViewModel, nav) } + composableFromBottomArgs { PayViaIntentScreen(it.paymentId, accountViewModel, nav) } composableFromBottomArgs { NewUserMetadataScreen(nav, accountViewModel) } diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt index 2456f9d05..10fd98294 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/navigation/drawer/DrawerContent.kt @@ -105,7 +105,6 @@ import com.vitorpamplona.amethyst.ui.note.LoadStatuses import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.keyBackup.AccountBackupDialog -import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.ShowQRDialog import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.DoubleHorzSpacer @@ -713,9 +712,6 @@ fun BottomContent( accountViewModel: AccountViewModel, nav: INav, ) { - // store the dialog open or close state - var dialogOpen by remember { mutableStateOf(false) } - Column(modifier = Modifier) { HorizontalDivider( modifier = Modifier.padding(top = 15.dp), @@ -759,7 +755,7 @@ fun BottomContent( Box(modifier = Modifier.weight(1F)) IconButton( onClick = { - dialogOpen = true + nav.nav(Route.QRDisplay(user.pubkeyHex)) nav.closeDrawer() }, ) { @@ -772,17 +768,4 @@ fun BottomContent( } } } - - if (dialogOpen) { - ShowQRDialog( - user, - accountViewModel, - onScan = { - dialogOpen = false - nav.closeDrawer() - nav.nav(it) - }, - onClose = { dialogOpen = false }, - ) - } } 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 becfc33bc..147b1711e 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 @@ -89,6 +89,10 @@ sealed class Route { val id: String, ) : Route() + @Serializable data class QRDisplay( + val pubkey: String, + ) : Route() + @Serializable data class ContentDiscovery( val id: String, ) : Route() @@ -287,6 +291,7 @@ fun getRouteWithArguments(navController: NavHostController): Route? { dest.hasRoute() -> entry.toRoute() dest.hasRoute() -> entry.toRoute() + dest.hasRoute() -> entry.toRoute() dest.hasRoute() -> entry.toRoute() dest.hasRoute() -> entry.toRoute() diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt index c38c54728..48b57a643 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/profile/header/DrawAdditionalInfo.kt @@ -53,13 +53,13 @@ import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji import com.vitorpamplona.amethyst.ui.components.DisplayNip05ProfileStatus import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.DrawPlayName import com.vitorpamplona.amethyst.ui.painterRes import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.apps.DisplayAppRecommendations import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.apps.UserAppRecommendationsFeedViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.profile.header.badges.DisplayBadges -import com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode.ShowQRDialog import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.Size15Modifier import com.vitorpamplona.amethyst.ui.theme.Size25Modifier @@ -127,23 +127,9 @@ fun DrawAdditionalInfo( ) } - var dialogOpen by remember { mutableStateOf(false) } - - if (dialogOpen) { - ShowQRDialog( - user = user, - accountViewModel = accountViewModel, - onScan = { - dialogOpen = false - nav.nav(it) - }, - onClose = { dialogOpen = false }, - ) - } - IconButton( modifier = Size25Modifier, - onClick = { dialogOpen = true }, + onClick = { nav.nav(Route.QRDisplay(user.pubkeyHex)) }, ) { Icon( painter = painterRes(R.drawable.ic_qrcode, 1), diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/QrCodeScanner.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/QrCodeScanner.kt index d160cb813..06158a5ac 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/QrCodeScanner.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/QrCodeScanner.kt @@ -43,6 +43,8 @@ fun NIP19QrCodeScanner( try { if (it != null) { onScan(uriToRoute(it, accountViewModel.account)) + } else { + onScan(null) } } catch (e: Throwable) { if (e is CancellationException) throw e diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt deleted file mode 100644 index dd6d24b21..000000000 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRDialog.kt +++ /dev/null @@ -1,236 +0,0 @@ -/** - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.FilledTonalButton -import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import com.vitorpamplona.amethyst.R -import com.vitorpamplona.amethyst.model.User -import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji -import com.vitorpamplona.amethyst.ui.components.DisplayNIP05 -import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage -import com.vitorpamplona.amethyst.ui.components.SetDialogToEdgeToEdge -import com.vitorpamplona.amethyst.ui.components.nip05VerificationAsAState -import com.vitorpamplona.amethyst.ui.navigation.routes.Route -import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon -import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel -import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel -import com.vitorpamplona.amethyst.ui.stringRes -import com.vitorpamplona.amethyst.ui.theme.Font14SP -import com.vitorpamplona.amethyst.ui.theme.Size10dp -import com.vitorpamplona.amethyst.ui.theme.Size35dp -import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer -import com.vitorpamplona.amethyst.ui.theme.largeProfilePictureModifier -import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata - -@Preview -@Composable -fun ShowQRDialogPreview() { - val accountViewModel = mockAccountViewModel() - accountViewModel.userProfile().info = - UserMetadata().apply { - name = "My Name" - picture = "Picture" - nip05 = null - banner = "http://banner.com/test" - website = "http://mywebsite.com/test" - about = "This is the about me" - } - - ShowQRDialog( - user = accountViewModel.userProfile(), - accountViewModel = accountViewModel, - onScan = {}, - onClose = {}, - ) -} - -@Composable -fun BackButton(onPress: () -> Unit) { - IconButton( - onClick = onPress, - ) { - ArrowBackIcon(MaterialTheme.colorScheme.onBackground) - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ShowQRDialog( - user: User, - accountViewModel: AccountViewModel, - onScan: (Route) -> Unit, - onClose: () -> Unit, -) { - var presenting by remember { mutableStateOf(true) } - - Dialog( - onDismissRequest = onClose, - properties = DialogProperties(usePlatformDefaultWidth = false), - ) { - SetDialogToEdgeToEdge() - - Scaffold( - topBar = { - TopAppBar( - title = {}, - navigationIcon = { - Row { - Spacer(modifier = StdHorzSpacer) - BackButton(onPress = onClose) - } - }, - colors = - TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surface, - ), - ) - }, - ) { pad -> - Surface( - Modifier - .fillMaxSize() - .padding( - start = 10.dp, - end = 10.dp, - top = pad.calculateTopPadding(), - bottom = pad.calculateBottomPadding(), - ).consumeWindowInsets(pad) - .imePadding(), - ) { - Column { - Column( - modifier = Modifier.padding(horizontal = 10.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - if (presenting) { - Column { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth(), - ) { - RobohashFallbackAsyncImage( - robot = user.pubkeyHex, - model = user.profilePicture(), - contentDescription = stringRes(R.string.profile_image), - modifier = MaterialTheme.colorScheme.largeProfilePictureModifier, - loadProfilePicture = accountViewModel.settings.showProfilePictures(), - loadRobohash = accountViewModel.settings.isNotPerformanceMode(), - ) - } - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth().padding(top = 10.dp), - ) { - CreateTextWithEmoji( - text = user.info?.bestName() ?: "", - tags = user.info?.tags, - fontWeight = FontWeight.Bold, - fontSize = 20.sp, - ) - } - - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth().padding(top = 4.dp), - ) { - val nip05 = user.nip05() - if (nip05 != null) { - val nip05Verified = - nip05VerificationAsAState(user.info!!, user.pubkeyHex, accountViewModel) - - DisplayNIP05(nip05, nip05Verified, accountViewModel) - } else { - Text( - text = user.pubkeyDisplayHex(), - fontSize = Font14SP, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - ) - } - } - } - - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier.fillMaxWidth().padding(horizontal = Size10dp), - ) { - QrCodeDrawer(user.toNostrUri()) - } - - Row(modifier = Modifier.padding(horizontal = 30.dp)) { - FilledTonalButton( - onClick = { presenting = false }, - shape = RoundedCornerShape(Size35dp), - modifier = Modifier.fillMaxWidth().height(50.dp), - ) { - Text(text = stringRes(R.string.scan_qr)) - } - } - } else { - NIP19QrCodeScanner(accountViewModel) { - if (it == null) { - presenting = true - } else { - onScan(it) - } - } - } - } - } - } - } - } -} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt new file mode 100644 index 000000000..89da19efa --- /dev/null +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/qrcode/ShowQRScreen.kt @@ -0,0 +1,245 @@ +/** + * Copyright (c) 2025 Vitor Pamplona + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the + * Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +package com.vitorpamplona.amethyst.ui.screen.loggedIn.qrcode + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.imePadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilledTonalButton +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.model.User +import com.vitorpamplona.amethyst.ui.components.CreateTextWithEmoji +import com.vitorpamplona.amethyst.ui.components.DisplayNIP05 +import com.vitorpamplona.amethyst.ui.components.RobohashFallbackAsyncImage +import com.vitorpamplona.amethyst.ui.components.nip05VerificationAsAState +import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton +import com.vitorpamplona.amethyst.ui.note.ArrowBackIcon +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.LoadUser +import com.vitorpamplona.amethyst.ui.screen.loggedIn.mockAccountViewModel +import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.Font14SP +import com.vitorpamplona.amethyst.ui.theme.Size10dp +import com.vitorpamplona.amethyst.ui.theme.Size35dp +import com.vitorpamplona.amethyst.ui.theme.largeProfilePictureModifier +import com.vitorpamplona.quartz.nip01Core.core.HexKey +import com.vitorpamplona.quartz.nip01Core.metadata.UserMetadata + +@Preview +@Composable +fun ShowQRScreenPreview() { + val accountViewModel = mockAccountViewModel() + accountViewModel.userProfile().info = + UserMetadata().apply { + name = "My Name" + picture = "Picture" + nip05 = null + banner = "http://banner.com/test" + website = "http://mywebsite.com/test" + about = "This is the about me" + } + + ShowQRScreen( + pubkey = accountViewModel.userProfile().pubkeyHex, + accountViewModel = accountViewModel, + nav = EmptyNav(), + ) +} + +@Composable +fun BackButton(onPress: () -> Unit) { + IconButton( + onClick = onPress, + ) { + ArrowBackIcon(MaterialTheme.colorScheme.onBackground) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ShowQRScreen( + pubkey: HexKey, + accountViewModel: AccountViewModel, + nav: INav, +) { + LoadUser(pubkey, accountViewModel) { user -> + if (user != null) { + ShowQRScreen( + user = user, + accountViewModel = accountViewModel, + nav = nav, + ) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ShowQRScreen( + user: User, + accountViewModel: AccountViewModel, + nav: INav, +) { + Scaffold( + topBar = { + TopBarWithBackButton( + "", + nav::popBack, + ) + }, + ) { pad -> + Column( + Modifier + .fillMaxSize() + .padding( + start = 20.dp, + end = 20.dp, + top = pad.calculateTopPadding(), + bottom = pad.calculateBottomPadding(), + ).consumeWindowInsets(pad) + .imePadding(), + verticalArrangement = Arrangement.SpaceAround, + horizontalAlignment = Alignment.CenterHorizontally, + ) { + ShowQRBody(user, accountViewModel, nav) + } + } +} + +@Composable +fun ShowQRBody( + user: User, + accountViewModel: AccountViewModel, + nav: INav, +) { + var presenting by remember { mutableStateOf(true) } + if (presenting) { + PresentQR(user, accountViewModel) { + presenting = false + } + } else { + NIP19QrCodeScanner(accountViewModel) { + if (it == null) { + presenting = true + } else { + nav.nav(it) + } + } + } +} + +@Composable +fun PresentQR( + user: User, + accountViewModel: AccountViewModel, + switchToScan: () -> Unit, +) { + Column { + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth(), + ) { + RobohashFallbackAsyncImage( + robot = user.pubkeyHex, + model = user.profilePicture(), + contentDescription = stringRes(R.string.profile_image), + modifier = MaterialTheme.colorScheme.largeProfilePictureModifier, + loadProfilePicture = accountViewModel.settings.showProfilePictures(), + loadRobohash = accountViewModel.settings.isNotPerformanceMode(), + ) + } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(top = 10.dp), + ) { + CreateTextWithEmoji( + text = user.info?.bestName() ?: "", + tags = user.info?.tags, + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + ) + } + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(top = 4.dp), + ) { + val nip05 = user.nip05() + if (nip05 != null) { + val nip05Verified = + nip05VerificationAsAState(user.info!!, user.pubkeyHex, accountViewModel) + + DisplayNIP05(nip05, nip05Verified, accountViewModel) + } else { + Text( + text = user.pubkeyDisplayHex(), + fontSize = Font14SP, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + } + } + + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(horizontal = Size10dp), + ) { + QrCodeDrawer(user.toNostrUri()) + } + + Row(modifier = Modifier.padding(horizontal = 30.dp)) { + FilledTonalButton( + onClick = switchToScan, + shape = RoundedCornerShape(Size35dp), + modifier = Modifier.fillMaxWidth().height(50.dp), + ) { + Text(text = stringRes(R.string.scan_qr)) + } + } +} From 89d7e52dc4ea042f8ffdda25393115cf6e68943f Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 18 Nov 2025 18:07:08 -0500 Subject: [PATCH 59/60] Avoids blinking image space in the screen --- .../screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt index 2314bf79f..22779c0d5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/discover/nip51FollowSets/FollowSetCard.kt @@ -174,8 +174,8 @@ fun RenderFollowSetThumb( it, ), contentScale = ContentScale.Crop, - mainImageModifier = Modifier, - loadedImageModifier = FollowSetImageModifier, + mainImageModifier = FollowSetImageModifier, + loadedImageModifier = Modifier, accountViewModel = accountViewModel, onLoadingBackground = { DefaultImageHeaderBackground(baseNote, accountViewModel) }, onError = { DefaultImageHeader(baseNote, accountViewModel) }, From 23d1e94ddfdabc13c6404e29b32417aa7f0d168a Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 18 Nov 2025 19:12:21 -0500 Subject: [PATCH 60/60] Moves the prepare video call to IO --- .../service/playback/composable/GetVideoController.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/GetVideoController.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/GetVideoController.kt index e35a1ecf0..25ad563d0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/GetVideoController.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/playback/composable/GetVideoController.kt @@ -64,7 +64,7 @@ fun GetVideoController( if (controllerId.needsController()) { // If there is a connection, don't wait. if (!onlyOnePreparing.getAndSet(true)) { - scope.launch { + scope.launch(Dispatchers.IO) { Log.d("PlaybackService", "Preparing Video ${controllerId.id} ${mediaItem.src.videoUri}") PlaybackServiceClient.prepareController( mediaControllerState = controllerId, @@ -172,7 +172,7 @@ fun GetVideoController( // if the controller is not null, just continue playing what the controller was playing if (controllerId.needsController()) { if (!onlyOnePreparing.getAndSet(true)) { - scope.launch(Dispatchers.Main) { + scope.launch(Dispatchers.IO) { Log.d("PlaybackService", "Preparing Video from Resume ${controllerId.id} ${mediaItem.src.videoUri} ") PlaybackServiceClient.prepareController( mediaControllerState = controllerId,