Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 121 lines 4.9 kB view raw
1(function initACMediaRecords(global) { 2 if (global.ACMediaRecords) return; 3 4 function normalizeLink(link) { 5 if (!link || typeof link !== "string") return ""; 6 const trimmed = link.trim(); 7 if (!trimmed) return ""; 8 if (/^https?:\/\//i.test(trimmed)) return trimmed; 9 if (/^at:\/\//i.test(trimmed)) return `https://pdsls.dev/${trimmed}`; 10 if (/^[\w.-]+\.[a-z]{2,}([/?#].*)?$/i.test(trimmed)) return `https://${trimmed}`; 11 return ""; 12 } 13 14 function recordFallbackLink(item) { 15 if (!item?.uri || typeof item.uri !== "string") return ""; 16 const atUri = item.uri.startsWith("at://") 17 ? item.uri 18 : `at://${item.uri.split("//")[1] || item.uri}`; 19 return `https://pdsls.dev/${atUri}`; 20 } 21 22 function escapeHtml(value) { 23 return String(value ?? "") 24 .replace(/&/g, "&amp;") 25 .replace(/</g, "&lt;") 26 .replace(/>/g, "&gt;") 27 .replace(/"/g, "&quot;") 28 .replace(/'/g, "&#39;"); 29 } 30 31 function buildFeedModalPayload(item, col, repoLabel, ago, title, primaryLink) { 32 const recordLink = recordFallbackLink(item); 33 const safePrimaryLink = normalizeLink(primaryLink); 34 const safeCode = item?.code ? encodeURIComponent(String(item.code)) : ""; 35 let iframeUrl = ""; 36 let previewHtml = ""; 37 let extraHtml = ""; 38 39 switch (col.label) { 40 case "painting": 41 if (safeCode) { 42 previewHtml = `<img src="https://aesthetic.computer/media/paintings/${safeCode}" alt="" style="width:100%;max-height:360px;object-fit:contain;border:1px solid rgba(205,92,155,0.2);border-radius:6px;background:#fff;">`; 43 } 44 break; 45 case "kidlisp": 46 if (safeCode) { 47 previewHtml = `<img src="https://oven.aesthetic.computer/grab/webp/640/360/$${safeCode}?duration=2500&fps=8&quality=80&density=1&nowait=true" alt="" style="width:100%;max-height:360px;object-fit:cover;border:1px solid rgba(205,92,155,0.2);border-radius:6px;">`; 48 } 49 if (item?.source) { 50 extraHtml = `<pre style="margin:0;padding:0.75em;background:rgba(205,92,155,0.08);border:1px solid rgba(205,92,155,0.2);border-radius:6px;white-space:pre-wrap;word-break:break-word;max-height:180px;overflow:auto;">${escapeHtml(String(item.source).slice(0, 1200))}</pre>`; 51 } 52 break; 53 case "mood": 54 if (item?.mood) { 55 extraHtml = `<blockquote style="margin:0;padding:0.75em;border-left:3px solid rgba(205,92,155,0.6);background:rgba(205,92,155,0.08);border-radius:4px;">${escapeHtml(item.mood)}</blockquote>`; 56 } 57 break; 58 case "news": { 59 const newsUrl = safePrimaryLink || "https://news.aesthetic.computer"; 60 iframeUrl = newsUrl; 61 if (item?.body) { 62 extraHtml = `<div style="padding:0.75em;background:rgba(205,92,155,0.08);border:1px solid rgba(205,92,155,0.2);border-radius:6px;max-height:220px;overflow:auto;">${escapeHtml(String(item.body).slice(0, 1800))}</div>`; 63 } 64 break; 65 } 66 case "paper": 67 iframeUrl = safePrimaryLink; 68 break; 69 default: 70 iframeUrl = ""; 71 } 72 73 const metadata = [ 74 ["Type", col.label], 75 ["When", ago || "recent"], 76 ["From", repoLabel || "unknown"], 77 ["Rkey", item?.uri ? String(item.uri).split("/").pop() : ""], 78 ] 79 .filter((entry) => entry[1]) 80 .map((entry) => `<div><strong>${escapeHtml(entry[0])}:</strong> ${escapeHtml(entry[1])}</div>`) 81 .join(""); 82 83 const rawRecord = escapeHtml(JSON.stringify(item, null, 2)); 84 const bodyHtml = ` 85 ${previewHtml} 86 ${extraHtml} 87 <div style="display:grid;gap:0.35em;font-size:0.82em;line-height:1.45;padding:0.65em 0.75em;border:1px solid rgba(205,92,155,0.2);border-radius:6px;background:rgba(205,92,155,0.06);">${metadata}</div> 88 <details> 89 <summary style="cursor:pointer;opacity:0.8;">Raw record</summary> 90 <pre style="margin-top:0.5em;padding:0.65em;background:rgba(0,0,0,0.05);border-radius:6px;overflow:auto;font-size:0.75em;max-height:220px;">${rawRecord}</pre> 91 </details> 92 `; 93 94 const actions = []; 95 if (safePrimaryLink) actions.push({ label: "Open Link", url: safePrimaryLink }); 96 if (col.label === "news") actions.push({ label: "Open News Site", url: "https://news.aesthetic.computer" }); 97 if (recordLink) actions.push({ label: "View Record", url: recordLink }); 98 99 const seen = new Set(); 100 const dedupedActions = actions.filter((action) => { 101 if (seen.has(action.url)) return false; 102 seen.add(action.url); 103 return true; 104 }); 105 106 return { 107 title: `${col.icon} ${title || col.label}`, 108 subtitle: `${col.label} · ${ago || "recent"} · ${repoLabel || "unknown"}`, 109 bodyHtml, 110 iframeUrl, 111 actions: dedupedActions, 112 }; 113 } 114 115 global.ACMediaRecords = { 116 buildFeedModalPayload, 117 escapeHtml, 118 normalizeLink, 119 recordFallbackLink, 120 }; 121})(window);