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

67
src/lib/notifications.ts Normal file
View File

@@ -0,0 +1,67 @@
import {
isPermissionGranted,
requestPermission,
sendNotification,
} from "@tauri-apps/plugin-notification";
const SETTINGS_KEY = "wrystr_notification_settings";
interface NotificationSettings {
mentions: boolean;
dms: boolean;
zaps: boolean;
}
const defaults: NotificationSettings = { mentions: true, dms: true, zaps: true };
export function getNotificationSettings(): NotificationSettings {
try {
const stored = localStorage.getItem(SETTINGS_KEY);
return stored ? { ...defaults, ...JSON.parse(stored) } : defaults;
} catch {
return defaults;
}
}
export function saveNotificationSettings(settings: NotificationSettings): void {
localStorage.setItem(SETTINGS_KEY, JSON.stringify(settings));
}
export async function ensurePermission(): Promise<boolean> {
let granted = await isPermissionGranted();
if (!granted) {
const result = await requestPermission();
granted = result === "granted";
}
return granted;
}
export async function notifyMention(authorName: string, preview: string): Promise<void> {
const settings = getNotificationSettings();
if (!settings.mentions) return;
if (!(await ensurePermission())) return;
sendNotification({
title: `${authorName} mentioned you`,
body: preview.slice(0, 120),
});
}
export async function notifyDM(authorName: string, preview: string): Promise<void> {
const settings = getNotificationSettings();
if (!settings.dms) return;
if (!(await ensurePermission())) return;
sendNotification({
title: `DM from ${authorName}`,
body: preview.slice(0, 120),
});
}
export async function notifyZap(senderName: string, amount: number): Promise<void> {
const settings = getNotificationSettings();
if (!settings.zaps) return;
if (!(await ensurePermission())) return;
sendNotification({
title: `${senderName} zapped you`,
body: `${amount.toLocaleString()} sats`,
});
}