6<p align=center>
7<a href="https://maxm-valtownchatgpt.web.val.run/">
8<img width=600 src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/c180aba1-997a-4e40-615a-1ed8456b5a00/public">
9</a>
10</p>
sqliteExplorerAppREADME.md1 match
3View and interact with your Val Town SQLite data. It's based off Steve's excellent [SQLite Admin](https://www.val.town/v/stevekrouse/sqlite_admin?v=46) val, adding the ability to run SQLite queries directly in the interface. This new version has a revised UI and that's heavily inspired by [LibSQL Studio](https://github.com/invisal/libsql-studio) by [invisal](https://github.com/invisal). This is now more an SPA, with tables, queries and results showing up on the same page.
45
67## Install
1011<div align="center">
12<img src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/67a1d35e-c37c-41a4-0e5a-03a9ba585d00/public" width="500px"/>
13</div>
1011<div align="center">
12<img src="https://imagedelivery.net/iHX6Ovru0O7AjmyT5yZRoA/67a1d35e-c37c-41a4-0e5a-03a9ba585d00/public" width="500px"/>
13</div>
blob_adminREADME.md1 match
3This is a lightweight Blob Admin interface to view and debug your Blob data.
45
67Use this button to install the val:
16"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" ",
17),
18{ headers: { "Content-Type": "image/svg+xml" } },
19);
20}
resumeHandlermain.tsx1 match
17<meta name="viewport" content="width=device-width, initial-scale=1.0">
18<title>hello, resume</title>
19<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text y='50%' font-size='24' text-anchor='middle' x='50%' dy='.3em'>📄</text></svg>">
20<style>
21${helloResume}
uploadImageREADME.md2 matches
1# uploadImage
2uploads an image to val.town just like when you paste an image into a readme
uploadImagemain.tsx6 matches
1/**
2* upload an image to val.town
3* @param {Blob} image - image must have image/jpeg, image/png, image/webp, image/gif or image/svg+xml content-type
4* @returns {string} - uploaded image url
5*/
6export async function uploadImage(image: Blob): Promise<string> {
7const fd = new FormData();
8fd.append(
9"file",
10image,
11);
12const data = await (await fetch(await getUploadURL(), {
24}
25async function getUploadURL(): Promise<string> {
26const data = await (await fetch("https://www.val.town/api/trpc/generateImageUploadUrl", {
27"headers": {
28"content-type": "application/json",
asciiNycCamerasmain.tsx11 matches
34import valTownBadge from "https://esm.town/v/jxnblk/valTownBadge?v=16";
5import { imageToAscii } from "https://esm.town/v/maxm/imageToAscii";
6import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
7import { Hono } from "npm:hono@3";
35document.getElementById("message").style.display = "none";
36document.getElementById("close-btn").style.display = "flex";
37await fetchImage(id);
38};
39152<p>
153Click on a circle to select a traffic camera. <br />{" "}
154The traffic images will be converted to ASCII and streamed to your browser.
155<br /> <a className="underline" href={info.htmlUrl}>Source code & info</a>.
156</p>
196);
197app.get("/camera-ascii/:id", async (c) => {
198const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
199const { stringColor } = await imageToAscii(url, 150);
200return new Response(stringColor, { headers: { "Content-Type": "text/plain" } });
201});
203"/camera/:id",
204async (c) => {
205const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
206const { string, stringColor } = await imageToAscii(url, 150);
207return new Response(
208`<style>
228<p class="loading"></p>
229<p>
230<a target="_blank" href="${url}">view source image</a>
231</p>
232<script>
258app.get("/camera-text-stream/:id", async (c) => {
259let timerId: number | undefined;
260const url = "https://webcams.nyctmc.org/api/cameras/" + c.req.param("id") + "/image";
261const body = new ReadableStream({
262async start(controller) {
264controller.enqueue(new TextEncoder().encode("data: " + JSON.stringify(msg) + "\r\n\r\n"));
265};
266const { stringColor } = await imageToAscii(url, 150);
267write(stringColor);
268timerId = setInterval(async () => {
269const { stringColor } = await imageToAscii(url, 150);
270write(stringColor);
271}, 2000);