Add NIP-05 badges, hashtag pages, keyword muting, suggestion dismissal, notification poller

- Article cover: aspect-video replaces max-h-72 for consistent 16:9
- NIP-05 verification badge on note cards with 1-hour TTL cache
- Dedicated hashtag feed pages (clicking #tag opens live feed, not search)
- Keyword muting: word-boundary matching, applied across all feed views
- Follow suggestion dismissal: persistent "don't suggest again" per person
- Background notification poller (60s): mentions, zaps, new followers
- All notification types independently toggleable in settings
- Centralized notification firing (removed inline store notifications)
This commit is contained in:
Jure
2026-03-20 12:09:11 +01:00
parent 989ed01dfc
commit 57630227e1
20 changed files with 499 additions and 35 deletions

View File

@@ -194,7 +194,7 @@ interface NoteContentProps {
}
export function NoteContent({ content, inline, mediaOnly }: NoteContentProps) {
const { openSearch } = useUIStore();
const { openHashtag } = useUIStore();
const segments = parseContent(content);
const images: string[] = segments.filter((s) => s.type === "image").map((s) => s.value);
const videos: string[] = segments.filter((s) => s.type === "video").map((s) => s.value);
@@ -246,7 +246,7 @@ export function NoteContent({ content, inline, mediaOnly }: NoteContentProps) {
<span
key={i}
className="text-accent/80 cursor-pointer hover:text-accent"
onClick={(e) => { e.stopPropagation(); openSearch(`#${seg.value}`); }}
onClick={(e) => { e.stopPropagation(); openHashtag(seg.value); }}
>
{seg.display}
</span>
@@ -441,7 +441,7 @@ export function NoteContent({ content, inline, mediaOnly }: NoteContentProps) {
<span
key={i}
className="text-accent/80 cursor-pointer hover:text-accent"
onClick={(e) => { e.stopPropagation(); openSearch(`#${seg.value}`); }}
onClick={(e) => { e.stopPropagation(); openHashtag(seg.value); }}
>
{seg.display}
</span>