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? {