make do without tauri and test vid

s 0f44589 ws that starts to work
s 6df44a1 first video
s dacb6cd click to time
s 7831ae4 remove tauri
s 2d18c9b concurrently and frontmatter
s dc43284 add new video and test
s 0dd03af fix for youtube format and markdown compat
s c30fa38 remove placeholder mds
s d8f1a54 remove images from git
This commit is contained in:
polv committed 2026-02-01 18:41:23 +07:00
1 parent fc58e68ad7
commit 00033e0341
38 files changed
+4897 -6257

No files matched your search

+92
View File
@@ -0,0 +1,92 @@
// @ts-check
import { WebSocketServer } from 'ws';
import { readFileSync, mkdirSync, writeFileSync } from "fs";
import { join as joinPath } from 'path'
import matter from 'gray-matter';
const PORT = 8080
const wss = new WebSocketServer({ port: PORT });
console.log(`WebSocket server running on ws://localhost:${PORT}`);
wss.on('connection', (ws) => {
console.log('New client connected');
let filename = ''
const ROOT_DIR = 'docs';
ws.on('message', (message, isBinary) => {
if (message instanceof Buffer && isBinary) {
writeFileSync(joinPath(ROOT_DIR, filename), message);
return;
}
const { name, ...payload } = JSON.parse(message.toString('utf-8'));
switch (name) {
case 'download_q': {
const { q, duration } = payload;
console.log(`Start ${q}`)
const q_stem = q.replace(/\.[a-z0-9]+$/, "").replace(/\[.+?\]/g, '').trim();
try {
mkdirSync(joinPath(ROOT_DIR, q_stem));
} catch (e) {}
let isChanged = false;
const ts = [];
let { data, content } = matter(readFileSync(joinPath(ROOT_DIR, `${q_stem}.md`), 'utf-8'));
data.video = '/' + q;
const interval = data.interval;
if (typeof interval === 'number') {
for (let t = 0; t < duration; t += interval) {
const min = Math.floor(t / 60)
const sec = Math.floor(t - min * 60)
content += `\n${min}:${sec.toString().padStart(2, '0')}\n`;
}
}
const re = /^(?<min>\d{1,2}):(?<sec>\d{2})\s*$/;
const lines = content.split('\n')
content = ''
for (const line of lines) {
const m = re.exec(line);
if (m?.groups) {
const { min, sec } = m.groups;
const t = `${min}_${sec}`;
ts.push(t);
content += `\n![${line}](./${q_stem}/${t}.png)\n\n`;
isChanged = true;
} else {
content += `${line}\n`;
}
}
if (isChanged){
writeFileSync(joinPath(ROOT_DIR, `${q_stem}.md`), matter.stringify(content, data));
ws.send(JSON.stringify({ name: "seek_q_ts", q, ts }));
}
} break;
case 'timed_q' : {
const { q, t } = payload;
const q_stem = q.replace(/\.[a-z0-9]+$/, "").replace(/\[.+?\]/g, '').trim();
filename = t ? joinPath(q_stem, `${t}.png`) : '';
} break;
case 'done' : {
const { q } = payload
console.log(`Done ${q}`)
} break;
}
});
ws.on('close', () => {
console.log('Client disconnected');
});
});