Highlight the searched terms in the thread page
This commit is contained in:
parent
d61ec05963
commit
c9227ee8fb
7 changed files with 92 additions and 4 deletions
|
|
@ -65,6 +65,15 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
/* Search terms painted on thread pages via the CSS Custom Highlight API,
|
||||
matching the <mark> tint used in the search results. */
|
||||
::highlight(search-terms) {
|
||||
background-color: color-mix(in srgb, var(--color-secondary) 40%, transparent);
|
||||
}
|
||||
.dark ::highlight(search-terms) {
|
||||
background-color: color-mix(in srgb, var(--color-secondary) 30%, transparent);
|
||||
}
|
||||
|
||||
/* Tighter heading rhythm for all rendered (prose) content. Overrides the
|
||||
typography plugin's em-based heading margins; the first block stays flush. */
|
||||
.prose :is(h1, h2, h3, h4, h5, h6) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
openJoinModal,
|
||||
} from "$lib/join.svelte";
|
||||
import { setActiveGroup } from "$lib/active.svelte";
|
||||
import { applyHighlights, clearHighlights } from "$lib/pageHighlight";
|
||||
import { RELAY_URL, MODE } from "$lib/config";
|
||||
import ThreadScrubber from "$lib/components/ThreadScrubber.svelte";
|
||||
import MessageEditor from "$lib/components/MessageEditor.svelte";
|
||||
|
|
@ -210,6 +211,28 @@
|
|||
if (page.params.id) loadThread(page.params.id);
|
||||
});
|
||||
|
||||
// Arriving from search (?q=…): paint the terms over the title and post
|
||||
// bodies, and scroll to the first match once per navigation. Re-runs as
|
||||
// replies stream in so late matches get painted too.
|
||||
let threadEl = $state<HTMLElement | null>(null);
|
||||
let scrolledFor = "";
|
||||
$effect(() => {
|
||||
const q = page.url.searchParams.get("q")?.trim() ?? "";
|
||||
allPosts; // Repaint when posts load or change
|
||||
if (!threadEl || !q) {
|
||||
clearHighlights();
|
||||
return;
|
||||
}
|
||||
const roots = threadEl.querySelectorAll("h1, [data-quote-post-index]");
|
||||
const first = applyHighlights(roots, q.split(/\s+/));
|
||||
const key = `${page.params.id}|${q}`;
|
||||
if (first && scrolledFor !== key) {
|
||||
scrolledFor = key;
|
||||
first.startContainer.parentElement?.scrollIntoView({ block: "center" });
|
||||
}
|
||||
return clearHighlights;
|
||||
});
|
||||
|
||||
// A thread belongs to its own group; make that the active group so chat and
|
||||
// replies target the right room.
|
||||
$effect(() => {
|
||||
|
|
@ -421,7 +444,7 @@
|
|||
{/snippet}
|
||||
|
||||
{#if detail}
|
||||
<div class="flex items-start gap-6">
|
||||
<div class="flex items-start gap-6" bind:this={threadEl}>
|
||||
<div class="min-w-0 flex-1 {!scrubberVisible ? 'md:pr-18' : ''}">
|
||||
<div
|
||||
class="relative z-10 bg-white pb-1 md:sticky md:-top-2 md:-mx-10 md:-mt-6 md:px-10 md:pt-6 md:pb-3 dark:bg-neutral-900"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue