Moves all hashtags to lowercase and unfollows with ignore case just in case some other client added in uppercase
This commit is contained in:
+2
-2
@@ -89,9 +89,9 @@ class HashtagListState(
|
|||||||
val hashtagList = getHashtagList()
|
val hashtagList = getHashtagList()
|
||||||
|
|
||||||
return if (hashtagList == null) {
|
return if (hashtagList == null) {
|
||||||
HashtagListEvent.create(hashtag, true, signer)
|
HashtagListEvent.create(hashtag.lowercase(), true, signer)
|
||||||
} else {
|
} else {
|
||||||
HashtagListEvent.add(hashtagList, hashtag, true, signer)
|
HashtagListEvent.add(hashtagList, hashtag.lowercase(), true, signer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ fun uriToRoute(
|
|||||||
return Route.Notification
|
return Route.Notification
|
||||||
}
|
}
|
||||||
if (isHashtagRoute(uri)) {
|
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
|
val nip19 = Nip19Parser.uriToRoute(uri)?.entity
|
||||||
|
|||||||
@@ -692,7 +692,7 @@ fun HashTag(
|
|||||||
modifier =
|
modifier =
|
||||||
remember {
|
remember {
|
||||||
Modifier.clickable {
|
Modifier.clickable {
|
||||||
nav.nav(Route.Hashtag(segment.hashtag))
|
nav.nav(Route.Hashtag(segment.hashtag.lowercase()))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
inlineContent =
|
inlineContent =
|
||||||
|
|||||||
+1
-1
@@ -86,6 +86,6 @@ private fun DisplayTagList(
|
|||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
) {
|
) {
|
||||||
nav.nav(Route.Hashtag(firstTag))
|
nav.nav(Route.Hashtag(firstTag.lowercase()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -96,7 +96,7 @@ fun DisplayUncitedHashtags(
|
|||||||
unusedHashtags.forEach { hashtag ->
|
unusedHashtags.forEach { hashtag ->
|
||||||
ClickableTextColor(
|
ClickableTextColor(
|
||||||
text = "#$hashtag ",
|
text = "#$hashtag ",
|
||||||
onClick = { nav.nav(Route.Hashtag(hashtag)) },
|
onClick = { nav.nav(Route.Hashtag(hashtag.lowercase())) },
|
||||||
linkColor = MaterialTheme.colorScheme.lessImportantLink,
|
linkColor = MaterialTheme.colorScheme.lessImportantLink,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ fun DisplayHashtagExternalId(
|
|||||||
nav: INav,
|
nav: INav,
|
||||||
) {
|
) {
|
||||||
DisplayHashtagExternalId(externalId.topic) {
|
DisplayHashtagExternalId(externalId.topic) {
|
||||||
nav.nav(Route.Hashtag(externalId.topic))
|
nav.nav(Route.Hashtag(externalId.topic.lowercase()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ fun TabFollowedTags(
|
|||||||
HashtagHeader(
|
HashtagHeader(
|
||||||
tag = hashtag,
|
tag = hashtag,
|
||||||
account = accountViewModel,
|
account = accountViewModel,
|
||||||
onClick = { nav.nav(Route.Hashtag(hashtag)) },
|
onClick = { nav.nav(Route.Hashtag(hashtag.lowercase())) },
|
||||||
)
|
)
|
||||||
HorizontalDivider(
|
HorizontalDivider(
|
||||||
thickness = DividerThickness,
|
thickness = DividerThickness,
|
||||||
|
|||||||
+1
-1
@@ -257,7 +257,7 @@ private fun DisplaySearchResults(
|
|||||||
hashTags,
|
hashTags,
|
||||||
key = { _, item -> "#$item" },
|
key = { _, item -> "#$item" },
|
||||||
) { _, item ->
|
) { _, item ->
|
||||||
HashtagLine(item) { nav.nav(Route.Hashtag(item)) }
|
HashtagLine(item.lowercase()) { nav.nav(Route.Hashtag(item.lowercase())) }
|
||||||
|
|
||||||
HorizontalDivider(
|
HorizontalDivider(
|
||||||
modifier = Modifier.padding(top = 10.dp),
|
modifier = Modifier.padding(top = 10.dp),
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import com.vitorpamplona.quartz.nip01Core.core.Tag
|
|||||||
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
import com.vitorpamplona.quartz.nip01Core.core.TagArray
|
||||||
import com.vitorpamplona.quartz.utils.startsWith
|
import com.vitorpamplona.quartz.utils.startsWith
|
||||||
import com.vitorpamplona.quartz.utils.startsWithAny
|
import com.vitorpamplona.quartz.utils.startsWithAny
|
||||||
|
import com.vitorpamplona.quartz.utils.startsWithIgnoreCase
|
||||||
|
|
||||||
inline fun TagArray.filterToArray(predicate: (Array<String>) -> Boolean): TagArray = filterTo(ArrayList(), predicate).toTypedArray()
|
inline fun TagArray.filterToArray(predicate: (Array<String>) -> Boolean): TagArray = filterTo(ArrayList(), predicate).toTypedArray()
|
||||||
|
|
||||||
@@ -31,6 +32,8 @@ inline fun TagArray.remove(predicate: (Array<String>) -> Boolean): TagArray = fi
|
|||||||
|
|
||||||
fun TagArray.remove(startsWith: Array<String>): TagArray = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).toTypedArray()
|
fun TagArray.remove(startsWith: Array<String>): TagArray = filterNotTo(ArrayList(this.size), { it.startsWith(startsWith) }).toTypedArray()
|
||||||
|
|
||||||
|
fun TagArray.removeIgnoreCase(startsWith: Array<String>): TagArray = filterNotTo(ArrayList(this.size), { it.startsWithIgnoreCase(startsWith) }).toTypedArray()
|
||||||
|
|
||||||
fun <R> TagArray.removeParsing(
|
fun <R> TagArray.removeParsing(
|
||||||
transform: (Tag) -> R,
|
transform: (Tag) -> R,
|
||||||
equalsTo: R,
|
equalsTo: R,
|
||||||
|
|||||||
+3
-3
@@ -36,8 +36,8 @@ import com.vitorpamplona.quartz.nip31Alts.alt
|
|||||||
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent
|
import com.vitorpamplona.quartz.nip51Lists.PrivateTagArrayEvent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent
|
import com.vitorpamplona.quartz.nip51Lists.encryption.PrivateTagsInContent
|
||||||
import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List
|
import com.vitorpamplona.quartz.nip51Lists.encryption.signNip51List
|
||||||
import com.vitorpamplona.quartz.nip51Lists.remove
|
|
||||||
import com.vitorpamplona.quartz.nip51Lists.removeAny
|
import com.vitorpamplona.quartz.nip51Lists.removeAny
|
||||||
|
import com.vitorpamplona.quartz.nip51Lists.removeIgnoreCase
|
||||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -140,8 +140,8 @@ class HashtagListEvent(
|
|||||||
): HashtagListEvent {
|
): HashtagListEvent {
|
||||||
val privateTags = earlierVersion.privateTags(signer) ?: throw SignerExceptions.UnauthorizedDecryptionException()
|
val privateTags = earlierVersion.privateTags(signer) ?: throw SignerExceptions.UnauthorizedDecryptionException()
|
||||||
return resign(
|
return resign(
|
||||||
privateTags = privateTags.remove(HashtagTag.assemble(hashtag)),
|
privateTags = privateTags.removeIgnoreCase(HashtagTag.assemble(hashtag)),
|
||||||
tags = earlierVersion.tags.remove(HashtagTag.assemble(hashtag)),
|
tags = earlierVersion.tags.removeIgnoreCase(HashtagTag.assemble(hashtag)),
|
||||||
signer = signer,
|
signer = signer,
|
||||||
createdAt = createdAt,
|
createdAt = createdAt,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -40,6 +40,14 @@ fun Array<String>.startsWith(startsWith: Array<String>): Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Array<String>.startsWithIgnoreCase(startsWith: Array<String>): 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<String>.startsWithAny(startsWithList: List<Array<String>>): Boolean = startsWithList.any { startsWith(it) }
|
fun Array<String>.startsWithAny(startsWithList: List<Array<String>>): Boolean = startsWithList.any { startsWith(it) }
|
||||||
|
|
||||||
public inline fun <T, R> Array<out T>.lastNotNullOfOrNull(transform: (T) -> R?): R? {
|
public inline fun <T, R> Array<out T>.lastNotNullOfOrNull(transform: (T) -> R?): R? {
|
||||||
|
|||||||
Reference in New Issue
Block a user