Add syntax highlighting in code blocks and OS push notifications

Syntax highlighting: shared markdown renderer with highlight.js
(atom-one-dark theme), 12 language grammars registered (JS, TS,
Python, Rust, Go, Bash, JSON, YAML, SQL, CSS, HTML, Markdown).
Applied to both article reader and editor preview.

OS notifications: Tauri notification plugin for mentions, DMs, and
zaps. Per-type toggles in Settings with custom toggle switches.
Fires on new unread mentions/DMs; requests OS permission on first
enable. Notification utility at src/lib/notifications.ts.
This commit is contained in:
Jure
2026-03-20 11:11:53 +01:00
parent 93ca13cc51
commit 989ed01dfc
11 changed files with 237 additions and 16 deletions

View File

@@ -1,6 +1,7 @@
import { create } from "zustand";
import { NDKEvent } from "@nostr-dev-kit/ndk";
import { fetchMentions } from "../lib/nostr";
import { notifyMention, notifyDM } from "../lib/notifications";
const NOTIF_SEEN_KEY = "wrystr_notif_last_seen";
const DM_SEEN_KEY = "wrystr_dm_last_seen";
@@ -52,7 +53,16 @@ export const useNotificationsStore = create<NotificationsState>((set, get) => ({
try {
const lastSeenAt = isNewAccount ? loadLastSeen() : get().lastSeenAt;
const events = await fetchMentions(pubkey, lastSeenAt);
const unreadCount = events.filter((e) => (e.created_at ?? 0) > lastSeenAt).length;
const newEvents = events.filter((e) => (e.created_at ?? 0) > lastSeenAt);
const unreadCount = newEvents.length;
// Fire OS notification for new mentions (only truly new ones since last fetch)
const prevCount = get().unreadCount;
if (unreadCount > prevCount && newEvents.length > 0) {
const latest = newEvents[0];
const authorName = latest.pubkey.slice(0, 8) + "…";
const preview = latest.content?.slice(0, 120) || "mentioned you";
notifyMention(authorName, preview).catch(() => {});
}
set({ notifications: events, unreadCount, lastSeenAt });
} catch {
// Non-critical
@@ -76,10 +86,17 @@ export const useNotificationsStore = create<NotificationsState>((set, get) => ({
},
computeDMUnread: (conversations: Array<{ partnerPubkey: string; lastAt: number }>) => {
const { dmLastSeen } = get();
const dmUnreadCount = conversations.filter(
const { dmLastSeen, dmUnreadCount: prevCount } = get();
const unreadConvos = conversations.filter(
(c) => c.lastAt > (dmLastSeen[c.partnerPubkey] ?? 0)
).length;
);
const dmUnreadCount = unreadConvos.length;
// Fire OS notification if new unread DMs appeared
if (dmUnreadCount > prevCount && unreadConvos.length > 0) {
const latest = unreadConvos[0];
const name = latest.partnerPubkey.slice(0, 8) + "…";
notifyDM(name, "New message").catch(() => {});
}
set({ dmUnreadCount });
},
}));