diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt index 787484503..750d10ae9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/model/LocalCache.kt @@ -2298,12 +2298,17 @@ object LocalCache : ILocalCache, ICacheProvider { } } + val findsFollowing = finds.associateWith { forAccount?.isFollowing(it) == true } + val anyNameStartsWith = finds.associateWith { it.metadataOrNull()?.anyNameStartsWith(dualCase) == true } + val anyAddressStartsWith = finds.associateWith { it.metadataOrNull()?.anyAddressStartsWith(dualCase) == true } + val displayNames = finds.associateWith { it.toBestDisplayName().lowercase() } + return finds.sortedWith( compareBy( - { forAccount?.isFollowing(it) == false }, - { it.metadataOrNull()?.anyNameStartsWith(dualCase) == false }, - { it.metadataOrNull()?.anyAddressStartsWith(dualCase) == false }, - { it.toBestDisplayName().lowercase() }, + { findsFollowing[it] == false }, + { anyNameStartsWith[it] == false }, + { anyAddressStartsWith[it] == false }, + { displayNames[it] }, { it.pubkeyHex }, ), ) diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUri.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUri.kt index 202dc19b9..b2c06663c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUri.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUri.kt @@ -55,7 +55,7 @@ data class BlossomUri( buildList { servers.forEach { add("xs=${percentEncodeQueryValue(it)}") } authors.forEach { add("as=$it") } - size?.let { add("sz=$it") } + this@BlossomUri.size?.let { add("sz=$it") } } if (params.isNotEmpty()) { append('?') diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt index e29bf7773..f572721a5 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UrlDetector.kt @@ -334,6 +334,17 @@ class UrlDetector( } else if (originalLength > 0 || numSlashes > 0 || !CharUtils.isAlpha(curr)) { // if it's not a character a-z or A-Z then assume we aren't matching scheme, but instead // matching username and password. + // Add the slashes to the end of the scheme so it matches what's in the scheme list + val schemeStartIndex = findValidSchemeNoSlashesStartIndex(buffer.toString()) + if (schemeStartIndex >= 0) { + if (schemeStartIndex > 0) { + buffer.deleteRange(0, schemeStartIndex) + } + currentUrlMarker.setIndex(UrlPart.SCHEME, 0) + reader.goBack() + return true + } + reader.goBack() return readUserPass(0) } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUriTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUriTest.kt index 68be8cdb6..72265e6f5 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUriTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nipB7Blossom/BlossomUriTest.kt @@ -131,4 +131,24 @@ class BlossomUriTest { assertNotNull(result) assertEquals(listOf(authorPubkey, author2), result.authors) } + + @Test + fun handlesMultipleAuthorsMultipleServers() { + val author1 = "781208004e09102d7da3b7345e64fd193cd1bc3fce8fdae6008d77f9cabcd036" + val author2 = "b53185b9f27962ebdf76b8a9b0a84cd8b27f9f3d4abd59f715788a3bf9e7f75e" + val server1 = "cdn.example.com" + val server2 = "media.nostr.build" + val fileHex = "a7b3c2d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1" + val fileExt = "png" + val size = 2547831L + val uri = "blossom:$fileHex.$fileExt?xs=$server1&xs=$server2&as=$author1&as=$author2&sz=$size" + val result = BlossomUri.parse(uri) + + assertNotNull(result) + assertEquals(fileHex, result.sha256) + assertEquals(fileExt, result.extension) + assertEquals(listOf(author1, author2), result.authors) + assertEquals(listOf(server1, server2), result.servers) + assertEquals(size, result.size) + } } diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt index 2ad6bd802..9e73fd43f 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/urldetector/detection/UriDetectionTest.kt @@ -734,6 +734,25 @@ class UriDetectionTest { runTest("blossom:b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=cdn.satellite.earth", "blossom:b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf?xs=cdn.satellite.earth") } + @Test + fun testBlossomShema2() { + runTest("blossom:9584b6d64e43747364b10276f4b821e5df09f46477b3b8c60cced3e8c647fbef.jpg?xs=blossom.primal.net", "blossom:9584b6d64e43747364b10276f4b821e5df09f46477b3b8c60cced3e8c647fbef.jpg?xs=blossom.primal.net") + } + + @Test + fun testFullText() { + val text = + """ + Did you know you can embed #Nostr live streams into #Nostr long-form posts? Sounds like an obvious thing, but it's only supported by nostr:npub1048qg5p6kfnpth2l98kq3dffg097tutm4npsz2exygx25ge2k9xqf5x3nf at the moment. + + See how it can be done here: https://lnshort.it/live-stream-embeds/ + + https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg + """.trimIndent() + + runTest(text, "nostr:npub1048qg5p6kfnpth2l98kq3dffg097tutm4npsz2exygx25ge2k9xqf5x3nf", "https://lnshort.it/live-stream-embeds/", "https://nostr.build/i/fd53fcf5ad950fbe45127e4bcee1b59e8301d41de6beee211f45e344db214e8a.jpg") + } + @Test fun testBasicIPv6() { runTest("I saw this on http://[2001:db8:1f70:0:999:de8:7648:6e8] I think it is really cool", "http://[2001:db8:1f70:0:999:de8:7648:6e8]")