fix: improve note interactions and markdown LaTeX support
## Bug Fixes ### Note Card Actions - Fix broken size change functionality (missing state declaration) - Implement React 19 useOptimistic for instant UI feedback - Add startTransition for non-blocking updates - Ensure smooth animations without page refresh - All note actions now work: pin, archive, color, size, checklist ### Markdown LaTeX Rendering - Add remark-math and rehype-katex plugins - Support inline equations with dollar sign syntax - Support block equations with double dollar sign syntax - Import KaTeX CSS for proper styling - Equations now render correctly instead of showing raw LaTeX ## Technical Details - Replace undefined currentNote references with optimistic state - Add optimistic updates before server actions for instant feedback - Use router.refresh() in transitions for smart cache invalidation - Install remark-math, rehype-katex, and katex packages ## Testing - Build passes successfully with no TypeScript errors - Dev server hot-reloads changes correctly
This commit is contained in:
@@ -20,12 +20,18 @@ export async function fetchLinkMetadata(url: string): Promise<LinkMetadata | nul
|
||||
|
||||
const response = await fetch(targetUrl, {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (compatible; Memento/1.0; +http://localhost:3000)',
|
||||
// Use a real browser User-Agent to avoid 403 Forbidden from strict sites
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
|
||||
'Accept-Language': 'en-US,en;q=0.5'
|
||||
},
|
||||
next: { revalidate: 3600 } // Cache for 1 hour
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
if (!response.ok) {
|
||||
console.warn(`[Scrape] Failed to fetch ${targetUrl}: ${response.status} ${response.statusText}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const html = await response.text();
|
||||
const $ = cheerio.load(html);
|
||||
@@ -34,21 +40,21 @@ export async function fetchLinkMetadata(url: string): Promise<LinkMetadata | nul
|
||||
$(`meta[property="${prop}"]`).attr('content') ||
|
||||
$(`meta[name="${prop}"]`).attr('content');
|
||||
|
||||
const title = getMeta('og:title') || $('title').text() || '';
|
||||
const description = getMeta('og:description') || getMeta('description') || '';
|
||||
const imageUrl = getMeta('og:image');
|
||||
const siteName = getMeta('og:site_name');
|
||||
// Robust extraction with fallbacks
|
||||
const title = getMeta('og:title') || $('title').text() || getMeta('twitter:title') || url;
|
||||
const description = getMeta('og:description') || getMeta('description') || getMeta('twitter:description') || '';
|
||||
const imageUrl = getMeta('og:image') || getMeta('twitter:image') || $('link[rel="image_src"]').attr('href');
|
||||
const siteName = getMeta('og:site_name') || '';
|
||||
|
||||
return {
|
||||
url: targetUrl,
|
||||
title: title.substring(0, 100), // Truncate if too long
|
||||
title: title.substring(0, 100),
|
||||
description: description.substring(0, 200),
|
||||
imageUrl,
|
||||
siteName
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fetching link metadata:', error);
|
||||
console.error(`[Scrape] Error fetching ${url}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user