comparison hg-web/src/repo-browser.tsx @ 190:a2725419f988 hg-web

Updated so that bun builds will with already existing js files.
author MrJuneJune <me@mrjunejune.com>
date Sat, 24 Jan 2026 21:06:42 -0800
parents 32ce881452fa
children a06710325c30
comparison
equal deleted inserted replaced
188:32ce881452fa 190:a2725419f988
1 import React, { useState, useEffect } from 'react'; 1 import React, { useState, useEffect, useRef } from 'react';
2 import renderMarkdown from './markdown_to_html_bin.js'; 2 import createMarkdownModule from 'markdown_converter/markdown_to_html_wasm/markdown_to_html_bin.js';
3
4 console.log(renderMarkdown);
5 3
6 // --- ICONS (Using CDN Links) --- 4 // --- ICONS (Using CDN Links) ---
7 const ICONS = { 5 const ICONS = {
8 folder: "https://cdn-icons-png.flaticon.com/512/11471/11471391.png", 6 folder: "https://cdn-icons-png.flaticon.com/512/11471/11471391.png",
9 file: "https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/icons/document.svg", 7 file: "https://raw.githubusercontent.com/PKief/vscode-material-icon-theme/main/icons/document.svg",
271 } 269 }
272 270
273 /** 271 /**
274 * Component: ReadmeViewer 272 * Component: ReadmeViewer
275 */ 273 */
276 function ReadmeViewer({ content }) { 274 function ReadmeViewer({ content }: { content: string | null }) {
275 const contentRef = useRef<HTMLDivElement>(null);
276 const moduleRef = useRef<any>(null);
277 const [wasmReady, setWasmReady] = useState(false);
278
279 useEffect(() => {
280 createMarkdownModule().then((Module) => {
281 moduleRef.current = Module;
282 setWasmReady(true);
283 });
284 }, []);
285
286 useEffect(() => {
287 if (!content || !wasmReady || !contentRef.current || !moduleRef.current) return;
288
289 const Module = moduleRef.current;
290 const markdownToHtmlPtr = Module.cwrap('markdown_to_html', 'number', ['string']);
291 const markdownFree = Module.cwrap('markdown_free', null, ['number']);
292
293 const ptr = markdownToHtmlPtr(content);
294 const html = Module.UTF8ToString(ptr);
295 markdownFree(ptr);
296 contentRef.current.innerHTML = html;
297 }, [content, wasmReady]);
298
277 if (!content) return null; 299 if (!content) return null;
278 300
279 return ( 301 return (
280 <div id="readmeSection"> 302 <div id="readmeSection">
281 <div className="readme-header"> 303 <div className="readme-header">
282 <img src="https://img.icons8.com/material-outlined/24/000000/menu--v1.png" width="16" alt="" style={{opacity:0.5}} /> 304 <img src="https://img.icons8.com/material-outlined/24/000000/menu--v1.png" width="16" alt="" style={{opacity:0.5}} />
283 README.md 305 README.md
284 </div> 306 </div>
285 <div id="readmeContent"></div> 307 <div id="readmeContent" ref={contentRef}>
308 {!wasmReady && 'Loading...'}
309 </div>
286 </div> 310 </div>
287 ); 311 );
288 } 312 }
289 313
290 /** 314 /**
326 const url = path 350 const url = path
327 ? `${API_BASE}/list?path=${encodeURIComponent(path)}` 351 ? `${API_BASE}/list?path=${encodeURIComponent(path)}`
328 : `${API_BASE}/list`; 352 : `${API_BASE}/list`;
329 353
330 const response = await fetch(url); 354 const response = await fetch(url);
331 const data = await response.json(); 355 let data;
332 356 if (response.ok)
333 if (data.error) throw new Error(data.error); 357 data = await response.json();
358
359 if (data.error)
360 throw new Error(data.error);
334 361
335 setContent({ 362 setContent({
336 files: data.files || [], 363 files: data.files || [],
337 directories: data.directories || [] 364 directories: data.directories || []
338 }); 365 });
343 setLoading(false); 370 setLoading(false);
344 } 371 }
345 }; 372 };
346 373
347 const fetchReadme = async (path) => { 374 const fetchReadme = async (path) => {
348 setReadme(null); 375 const readmePath = path ? `${path}/README.md` : 'README.md';
349 try { 376 const response = await fetch(`${API_BASE}/file?path=${encodeURIComponent(readmePath)}`);
350 const readmePath = path ? `${path}/README.md` : 'README.md'; 377 console.log(response);
351 const response = await fetch(`${API_BASE}/readme?path=${encodeURIComponent(readmePath)}`); 378 if (response.ok)
352 379 {
353 if (response.ok) { 380 const text = await response.text();
354 const text = await response.text(); 381 setReadme(text);
355 setReadme(text); 382 }
356 }
357 } catch (err) { /* Silently fail */ }
358 }; 383 };
359 384
360 return ( 385 return (
361 <> 386 <>
362 <GlobalStyles /> 387 <GlobalStyles />