Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Readme

open "https://ejfox-codeshowcase.web.val.run/?code=$(pbpaste | jq -sRr @uri)" to get a screenshottable code snippet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
* This val creates a simple code snippet display service.
* It accepts code via GET request, displays it in a
* beautifully-formatted syntax-highlighted snippet,
* uses an LLM to generate a title for the snippet,
* and allows shuffling through random, animated gradients.
*/
import { OpenAI } from "https://esm.town/v/std/openai";
export default async function server(request: Request): Promise<Response> {
const url = new URL(request.url);
const code = url.searchParams.get("code") || "console.log(\"Hello, World!\");";
const language = url.searchParams.get("language") || "javascript";
// Generate title using OpenAI
const openai = new OpenAI();
const completion = await openai.chat.completions.create({
messages: [
{
role: "system",
content: "You are a helpful assistant that generates short, concise titles for code snippets.",
},
{
role: "user",
content: `Generate a short title (5 words or less) for this ${language} code snippet:\n\n${code}`,
},
],
model: "gpt-4o-mini",
max_tokens: 20,
});
const title = completion.choices[0]?.message?.content || "Code Snippet";
const commandText = `open "${url.origin}${url.pathname}?code=$(pbpaste | jq -sRr @uri)"`;
return new Response(
`
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://d3js.org/d3-color.v2.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v2.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v2.min.js"></script>
<style>
#code-block {
font-size: 18px;
white-space: pre-wrap;
word-wrap: break-word;
}
body {
transition: background 2s ease;
}
</style>
</head>
<body class="min-h-screen flex flex-col justify-center items-center p-8">
<button id="shuffle" class="absolute top-4 right-4 opacity-50 hover:opacity-100 transition-opacity duration-300">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 12c0-1.232-.046-2.453-.138-3.662a4.006 4.006 0 00-3.7-3.7 48.678 48.678 0 00-7.324 0 4.006 4.006 0 00-3.7 3.7c-.017.22-.032.441-.046.662M19.5 12l3-3m-3 3l-3-3m-12 3c0 1.232.046 2.453
</svg>
</button>
<h1 class="text-md opacity-50 blend-mode-difference mb-6 w-full text-left px-6">${title}</h1>
<div id="code-container" class="w-full max-w-3xl bg-gray-800 bg-opacity-95 rounded-lg shadow-lg overflow-auto">
<pre><code id="code-block" class="language-${language}">${code}</code></pre>
</div>
<div class="fixed bottom-0 left-0 right-0 bg-gray-800 bg-opacity-75 text-white p-2 text-xs font-mono">
${commandText}
</div>
<script>
hljs.highlightAll();
function shuffleGradient() {
const t1 = Math.random();
const t2 = (t1 + 0.3) % 1; // Ensure colors are distinct
const color1 = d3.interpolateTurbo(t1);
const color2 = d3.interpolateTurbo(t2);
const angle = Math.floor(Math.random() * 360);
const size = 50 + Math.random() * 50; // Random size between 50% and 100%
document.body.style.background = \`
linear-gradient(\${angle}deg, \${color1} 0%, \${color2} \${size}%)
\`;
// Animate the gradient
let start = null;
const duration = 10000; // 10 seconds
function animate(timestamp) {
if (!start) start = timestamp;
const progress = (timestamp - start) / duration;
if (progress < 1) {
const currentAngle = angle + (360 * progress);
document.body.style.background = \`
linear-gradient(\${currentAngle}deg, \${color1} 0%, \${color2} \${size}%)
ejfox-codeshowcase.web.val.run
August 25, 2024