a tool for shared writing and social publishing

add generic pub icon if user did not specify one, adjust styling to be reflected in rendered version

+31 -7
+28 -4
app/api/pub_icon/route.ts
··· 10 10 export const runtime = "nodejs"; 11 11 12 12 export async function GET(req: NextRequest) { 13 + const searchParams = req.nextUrl.searchParams; 14 + const bgColor = searchParams.get("bg") || "#0000E1"; 15 + const fgColor = searchParams.get("fg") || "#FFFFFF"; 16 + 13 17 try { 14 - const searchParams = req.nextUrl.searchParams; 15 18 const at_uri = searchParams.get("at_uri"); 16 19 17 20 if (!at_uri) { ··· 43 46 } 44 47 45 48 publicationUri = docInPub.publication; 46 - publicationRecord = docInPub.publications.record as PubLeafletPublication.Record; 49 + publicationRecord = docInPub.publications 50 + .record as PubLeafletPublication.Record; 47 51 } else if (uri.collection === "pub.leaflet.publication") { 48 52 // Query the publications table directly 49 53 const { data: publication } = await supabaseServerClient ··· 65 69 66 70 // Check if the publication has an icon 67 71 if (!publicationRecord?.icon) { 68 - return new NextResponse(null, { status: 404 }); 72 + // Generate a placeholder with the first letter of the publication name 73 + const firstLetter = (publicationRecord?.name || "?") 74 + .slice(0, 1) 75 + .toUpperCase(); 76 + 77 + // Create a simple SVG placeholder with theme colors 78 + const svg = `<svg width="96" height="96" xmlns="http://www.w3.org/2000/svg"> 79 + <rect width="96" height="96" rx="48" ry="48" fill="${bgColor}"/> 80 + <text x="50%" y="50%" font-size="64" font-weight="bold" font-family="Arial, Helvetica, sans-serif" fill="${fgColor}" text-anchor="middle" dominant-baseline="central">${firstLetter}</text> 81 + </svg>`; 82 + 83 + return new NextResponse(svg, { 84 + headers: { 85 + "Content-Type": "image/svg+xml", 86 + "Cache-Control": 87 + "public, max-age=3600, s-maxage=3600, stale-while-revalidate=2592000", 88 + "CDN-Cache-Control": "s-maxage=3600, stale-while-revalidate=2592000", 89 + }, 90 + }); 69 91 } 70 92 71 93 // Parse the publication URI to get the DID 72 94 const pubUri = new AtUri(publicationUri); 73 95 74 96 // Get the CID from the icon blob 75 - const cid = (publicationRecord.icon.ref as unknown as { $link: string })["$link"]; 97 + const cid = (publicationRecord.icon.ref as unknown as { $link: string })[ 98 + "$link" 99 + ]; 76 100 77 101 // Fetch the blob from the PDS 78 102 const identity = await idResolver.did.resolve(pubUri.host);
+3 -3
components/AtMentionLink.tsx
··· 24 24 isPublication || isDocument ? ( 25 25 <img 26 26 src={`/api/pub_icon?at_uri=${encodeURIComponent(atURI)}`} 27 - className="inline-block w-4 h-4 rounded-full ml-1 align-text-bottom" 27 + className="inline-block w-5 h-5 rounded-full mr-1 align-text-top" 28 28 alt="" 29 - width="16" 30 - height="16" 29 + width="20" 30 + height="20" 31 31 loading="lazy" 32 32 /> 33 33 ) : null;