mirror of
https://github.com/hoornet/vega.git
synced 2026-05-06 12:19:11 -07:00
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:
57
src/lib/markdown.ts
Normal file
57
src/lib/markdown.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import { marked } from "marked";
|
||||
import { markedHighlight } from "marked-highlight";
|
||||
import DOMPurify from "dompurify";
|
||||
import hljs from "highlight.js/lib/core";
|
||||
import "highlight.js/styles/atom-one-dark.min.css";
|
||||
|
||||
// Register commonly used languages (keeps bundle small)
|
||||
import javascript from "highlight.js/lib/languages/javascript";
|
||||
import typescript from "highlight.js/lib/languages/typescript";
|
||||
import python from "highlight.js/lib/languages/python";
|
||||
import rust from "highlight.js/lib/languages/rust";
|
||||
import json from "highlight.js/lib/languages/json";
|
||||
import bash from "highlight.js/lib/languages/bash";
|
||||
import css from "highlight.js/lib/languages/css";
|
||||
import xml from "highlight.js/lib/languages/xml";
|
||||
import markdown from "highlight.js/lib/languages/markdown";
|
||||
import go from "highlight.js/lib/languages/go";
|
||||
import sql from "highlight.js/lib/languages/sql";
|
||||
import yaml from "highlight.js/lib/languages/yaml";
|
||||
|
||||
hljs.registerLanguage("javascript", javascript);
|
||||
hljs.registerLanguage("js", javascript);
|
||||
hljs.registerLanguage("typescript", typescript);
|
||||
hljs.registerLanguage("ts", typescript);
|
||||
hljs.registerLanguage("python", python);
|
||||
hljs.registerLanguage("rust", rust);
|
||||
hljs.registerLanguage("json", json);
|
||||
hljs.registerLanguage("bash", bash);
|
||||
hljs.registerLanguage("sh", bash);
|
||||
hljs.registerLanguage("shell", bash);
|
||||
hljs.registerLanguage("css", css);
|
||||
hljs.registerLanguage("html", xml);
|
||||
hljs.registerLanguage("xml", xml);
|
||||
hljs.registerLanguage("markdown", markdown);
|
||||
hljs.registerLanguage("md", markdown);
|
||||
hljs.registerLanguage("go", go);
|
||||
hljs.registerLanguage("sql", sql);
|
||||
hljs.registerLanguage("yaml", yaml);
|
||||
hljs.registerLanguage("yml", yaml);
|
||||
|
||||
// Configure marked with highlight.js via marked-highlight extension
|
||||
marked.use(
|
||||
markedHighlight({
|
||||
highlight(code: string, lang: string) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
return hljs.highlight(code, { language: lang }).value;
|
||||
}
|
||||
return hljs.highlightAuto(code).value;
|
||||
},
|
||||
}),
|
||||
{ breaks: true },
|
||||
);
|
||||
|
||||
export function renderMarkdown(md: string): string {
|
||||
const html = marked(md) as string;
|
||||
return DOMPurify.sanitize(html, { ADD_ATTR: ["id", "class"] });
|
||||
}
|
||||
67
src/lib/notifications.ts
Normal file
67
src/lib/notifications.ts
Normal 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`,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user