3This Todo App is server rendered *and* client-hydrated React. This architecture is a lightweight alternative to NextJS, RemixJS, or other React metaframeworks with no compile or build step. The data is saved server-side in [Val Town SQLite](https://docs.val.town/std/sqlite/).
4
5
6
7## SSR React Mini Framework
33 title: string;
34 description: string;
35 image: string | null;
36 pubDate: string;
37 type: string;
51
52
53
54
55
1import { email } from "https://esm.town/v/std/email";
2import { nasaImageDetails } from "https://esm.town/v/wallek/nasaImageDetails";
3
4export const todaysNasaMail = async () => {
5 const { html, nasaAPOD } = await nasaImageDetails();
6 console.log({ html, nasaAPOD });
7 const mailMeTodaysNasaImage = await email({
8 html: "<a href=\"https://wallek-nasaImage.web.val.run\">Weblink</a><br/><br/><br/>" + html,
9 subject: `Daily NASA – ${nasaAPOD.title}`,
10 });
29 const imgTag = document?.querySelector("img");
30 const imgSrc = imgTag?.getAttribute("src");
31 const image = imgSrc || mediaThumbnail || mediaContent || null;
32 const link = getLink(item);
33 const { _text, _cdata } = item.title ?? {};
36 const description = paragraph || item.description?._text
37 || item.description?._cdata || "";
38 return { title, description, image, pubDate, link };
39 }) ?? [];
40
49 title: string;
50 description: string;
51 image: string | null;
52 pubDate: string;
53 link: string;
2
3export let gifEndpoint = (req, res) => {
4 res.set("Content-Type", "image/gif");
5 res.send(
6 Buffer.from("R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=", "base64"),
1import { Buffer } from "node:buffer";
2
3export async function imageUrlToBase64(res: Response) {
4 // From https://stackoverflow.com/a/60321567
5 const buffer = Buffer.from(await res.arrayBuffer());
18 width:100% !important
19 }
20 .image-container {
21 height:68px !important;
22 width:110px !important;
27 }
28 }
29 .image-container {
30 background-color:#E0E0E0;
31 border-radius:4px;
33 width:128px;
34 }
35 .image-container img {
36 border-radius: inherit;
37 display: block;
4 if (req.path.startsWith("/qr")) {
5 const { qrcode } = await import("https://deno.land/x/qrcode/mod.ts");
6 const base64Image = await qrcode(req.query.data);
7 res.set("content-type", "image/gif");
8 res.send(
9 Buffer.from(base64Image.replace("data:image/gif;base64,", ""), "base64"),
10 );
11 }
13 return new Response(canvas.toBuffer(), {
14 headers: {
15 "Content-Type": "image/png",
16 },
17 });