A lone link's preview is looked up where the server filed it
The server unfurls what detect_urls finds, trailing .,;:!? trimmed, and files the preview under that. The web and Android cards looked a lone link's preview up under body.trim(), punctuation included, so a note reading "https://example.com/a." never showed its card. - grammar.json gains a urls section: what the server finds in a body, and the link a lone-link note is filed under. - The web's rule moves out of NoteCard into notes/links.ts loneUrl(); Android's LinkPreviewRow gets the same loneUrl(); both trim like the server. - The server and web suites run the cases; Android's JVM test pins them by hand, as it does the tint. Fixes #5399. DRY pass #2, batch 3 (#5372). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,13 +35,26 @@ private val COMPACT_IMAGE_WIDTH = 48.dp
|
||||
/**
|
||||
* A URL that is the WHOLE body, whitespace either side allowed.
|
||||
*
|
||||
* Mirrors `LONE_URL_RE` in `NoteCard.vue` deliberately — the two surfaces have to
|
||||
* agree on what counts as "this note is a link", or the same note reads as a card
|
||||
* on one and a paragraph on the other. Someone pasting a link rarely trims it,
|
||||
* Mirrors `LONE_URL_RE` in the web's `notes/links.ts` deliberately — the two surfaces
|
||||
* have to agree on what counts as "this note is a link", or the same note reads as a
|
||||
* card on one and a paragraph on the other. Someone pasting a link rarely trims it,
|
||||
* which is why the surrounding whitespace is tolerated rather than rejected.
|
||||
*/
|
||||
private val LONE_URL = Regex("""^\s*(https?://[^\s<>"'\]\)]+)\s*$""")
|
||||
|
||||
/** The sentence's punctuation, not the link's: the server trims it before unfurling. */
|
||||
private val TRAILING_PUNCTUATION = charArrayOf('.', ',', ';', ':', '!', '?')
|
||||
|
||||
/**
|
||||
* The link a note that is nothing but a link files its preview under, or null.
|
||||
*
|
||||
* Trimmed the way the server's `unfurl_queue.detect_urls` trims it, since that is the
|
||||
* key the preview arrives under (#5399). The web's `loneUrl` is the same rule, and
|
||||
* both run the `urls` cases in `core/testdata/grammar.json` (here, by hand).
|
||||
*/
|
||||
fun loneUrl(body: String): String? =
|
||||
LONE_URL.matchEntire(body)?.groupValues?.get(1)?.trimEnd(*TRAILING_PUNCTUATION)?.ifEmpty { null }
|
||||
|
||||
/**
|
||||
* The preview for a note that is nothing but a URL, or null.
|
||||
*
|
||||
@@ -56,13 +69,12 @@ private val LONE_URL = Regex("""^\s*(https?://[^\s<>"'\]\)]+)\s*$""")
|
||||
* the URL does.
|
||||
*/
|
||||
fun loneUrlPreview(note: Note): LinkPreview? {
|
||||
if (!LONE_URL.matches(note.body)) return null
|
||||
val url = note.body.trim()
|
||||
val url = loneUrl(note.body) ?: return null
|
||||
return note.previews.firstOrNull { it.url == url }
|
||||
}
|
||||
|
||||
/** True when the body is a lone URL, whether or not a preview has arrived for it. */
|
||||
fun isLoneUrl(note: Note): Boolean = LONE_URL.matches(note.body)
|
||||
fun isLoneUrl(note: Note): Boolean = loneUrl(note.body) != null
|
||||
|
||||
/**
|
||||
* A fetched link preview, in one of two sizes.
|
||||
|
||||
Reference in New Issue
Block a user