3_It's a tool that sends a daily email that shows everyone who you follow on Bluesky who has updated their profile in the last day. You can Remix it on Val Town (this website), tweak a few environnment variables, and it'll be yours!_ Here's what an email looks like with a person's description update:
45
67## Setup
1import { Hono } from 'https://esm.sh/hono@3.11.7';
2import { serveFile, readFile } from 'https://esm.town/v/std/utils/index.ts';
3import { sampleImages } from '../shared/types';
45const app = new Hono();
10});
1112// API endpoint to get images
13app.get('/api/images', (c) => {
14return c.json(sampleImages);
15});
16
2import React from 'https://esm.sh/react@18.2.0';
3import { createRoot } from 'https://esm.sh/react-dom@18.2.0/client';
4import { ImageViewer } from './components/ImageViewer';
5import { sampleImages } from '../shared/types';
6import { parseProject } from 'https://esm.town/v/std/utils/index.ts';
719<div className="min-h-screen bg-gray-100 py-8">
20<header className="max-w-4xl mx-auto px-4 mb-8">
21<h1 className="text-3xl font-bold text-center text-gray-800">Image Viewer</h1>
22<p className="text-center text-gray-600 mt-2">
23Browse through a collection of AI-generated images
24</p>
25</header>
2627<main>
28<ImageViewer images={sampleImages} />
29</main>
3031<footer className="mt-12 pb-8 text-center text-gray-500 text-sm">
32<p>Use arrow keys or buttons to navigate between images</p>
33<p>Click on an image to view it in full screen</p>
34{projectInfo && (
35<p className="mt-4">
ZapImageViewer.tsx20 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0 */
2import React, { useState, useEffect, useCallback } from 'https://esm.sh/react@18.2.0';
3import { Image } from '../../shared/types';
4import { Navigation } from './Navigation';
56interface ImageViewerProps {
7images: Image[];
8initialIndex?: number;
9}
1011export const ImageViewer: React.FC<ImageViewerProps> = ({
12images,
13initialIndex = 0
14}) => {
17const [isLoading, setIsLoading] = useState(true);
18
19const currentImage = images[currentIndex];
2021const handlePrevious = useCallback(() => {
2728const handleNext = useCallback(() => {
29if (currentIndex < images.length - 1) {
30setCurrentIndex(currentIndex + 1);
31setIsLoading(true);
32}
33}, [currentIndex, images.length]);
3435const toggleFullscreen = useCallback(() => {
54}, [handleKeyDown]);
5556const handleImageLoad = () => {
57setIsLoading(false);
58};
5960if (!currentImage) {
61return <div className="text-center p-8">No images available</div>;
62}
6364return (
65<div className="max-w-4xl mx-auto p-4">
66<h1 className="text-2xl font-bold text-center mb-2">{currentImage.title}</h1>
67<p className="text-gray-600 text-center mb-6">{currentImage.description}</p>
68
69<div className="relative overflow-hidden rounded-lg shadow-lg bg-white">
75
76<div
77className={`image-container cursor-pointer ${isLoading ? 'opacity-0' : 'fade-in'}`}
78onClick={toggleFullscreen}
79>
80<img
81src={currentImage.url}
82alt={currentImage.title}
83className="w-full h-auto"
84onLoad={handleImageLoad}
85/>
86</div>
89<Navigation
90currentIndex={currentIndex}
91totalImages={images.length}
92onPrevious={handlePrevious}
93onNext={handleNext}
97<div className="fullscreen" onClick={toggleFullscreen}>
98<img
99src={currentImage.url}
100alt={currentImage.title}
101className="max-w-full max-h-full"
102/>
ZapNavigation.tsx7 matches
4interface NavigationProps {
5currentIndex: number;
6totalImages: number;
7onPrevious: () => void;
8onNext: () => void;
11export const Navigation: React.FC<NavigationProps> = ({
12currentIndex,
13totalImages,
14onPrevious,
15onNext
25: 'text-blue-600 hover:bg-blue-100'
26}`}
27aria-label="Previous image"
28>
29<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
33
34<div className="text-gray-700 font-medium">
35{currentIndex + 1} / {totalImages}
36</div>
37
38<button
39onClick={onNext}
40disabled={currentIndex === totalImages - 1}
41className={`p-2 rounded-full ${
42currentIndex === totalImages - 1
43? 'text-gray-400 cursor-not-allowed'
44: 'text-blue-600 hover:bg-blue-100'
45}`}
46aria-label="Next image"
47>
48<svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
Zapindex.html2 matches
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>Image Viewer</title>
7<script src="https://cdn.twind.style" crossorigin></script>
8<script src="https://esm.town/v/std/catch"></script>
20100% { opacity: 1; }
21}
22.image-container img {
23transition: transform 0.3s ease;
24}
1// Shared types for the image viewer app
23export interface Image {
4id: number;
5title: string;
910export interface ViewerState {
11images: Image[];
12currentIndex: number;
13isFullscreen: boolean;
14}
1516// Helper function to generate AI image URLs
17export function generateImageUrl(prompt: string): string {
18// Using Val Town's AI image generation service
19return `https://maxm-imggenurl.web.val.run/${encodeURIComponent(prompt)}`;
20}
2122// Sample image data
23export const sampleImages: Image[] = [
24{
25id: 1,
26title: "Mountain Landscape",
27description: "A beautiful mountain landscape with snow-capped peaks and a clear blue sky",
28url: generateImageUrl("mountain landscape with snow-capped peaks and clear blue sky, photorealistic")
29},
30{
32title: "Ocean Sunset",
33description: "Stunning sunset over the ocean with orange and purple hues",
34url: generateImageUrl("stunning sunset over the ocean with orange and purple hues, photorealistic")
35},
36{
38title: "Forest Path",
39description: "A serene path through a dense forest with sunlight filtering through the trees",
40url: generateImageUrl("serene path through a dense forest with sunlight filtering through the trees, photorealistic")
41},
42{
44title: "City Skyline",
45description: "Modern city skyline at night with glowing lights",
46url: generateImageUrl("modern city skyline at night with glowing lights, photorealistic")
47},
48{
50title: "Desert Dunes",
51description: "Golden sand dunes in a vast desert landscape",
52url: generateImageUrl("golden sand dunes in a vast desert landscape at sunset, photorealistic")
53}
54];
1# Image Viewer App
23A simple image viewing application built on Val Town.
45## Features
67- Browse through a collection of AI-generated images
8- Responsive design that works on mobile and desktop
9- Clean, minimal UI with keyboard navigation support
16โโโ frontend/
17โ โโโ components/
18โ โ โโโ ImageViewer.tsx # Main viewer component
19โ โ โโโ Navigation.tsx # Navigation controls
20โ โโโ index.html # Main HTML template
27281. Visit the app URL
292. Use the arrow buttons or keyboard arrow keys to navigate between images
303. Click on an image to view it in full size
3132## Technologies Used
26"title": "Markdown Editor",
27"code":
28"<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Markdown Editor</title>\n <link href=\"https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css\" rel=\"stylesheet\">\n</head>\n<body class=\"bg-white\">\n <div class=\"max-w-full mx-auto p-4 pt-6 md:p-6 lg:p-8\">\n <h1 class=\"text-3xl text-center mb-4\">Markdown Editor</h1>\n <div class=\"flex flex-row\">\n <div class=\"editor p-4 rounded-lg border border-gray-200 w-full md:w-1/2\">\n <textarea id=\"editor\" class=\"w-full h-screen p-2 border border-gray-200 rounded-lg\" placeholder=\"Type your Markdown here...\"></textarea>\n </div>\n <div class=\"preview p-4 rounded-lg border border-gray-200 w-full md:w-1/2 ml-2 md:ml-4 lg:ml-8\">\n <div id=\"preview\"></div>\n </div>\n </div>\n <p class=\"text-center mt-4\">Built on <a href=\"https://cerebrascoder.com\">Cerebras Coder</a></p>\n </div>\n\n <script>\n const editor = document.getElementById('editor');\n const preview = document.getElementById('preview');\n\n // Initialize textarea with default markdown\n const defaultMarkdown = `\n# Introduction to Markdown\nMarkdown is a lightweight markup language that is easy to read and write. It is often used for formatting text in plain text editors, chat applications, and even web pages.\n\n## Headers\nHeaders are denoted by the # symbol followed by a space. The number of # symbols determines the level of the header:\n# Heading 1\n## Heading 2\n### Heading 3\n\n## Emphasis\nYou can use emphasis to make your text **bold** or *italic*:\n*Italics*\n**Bold**\n\n## Lists\nYou can use lists to organize your text:\n* Item 1\n* Item 2\n* Item 3\nOr\n1. Item 1\n2. Item 2\n3. Item 3\n\n## Links\nYou can use links to reference external resources:\n[Google](https://www.google.com)\n\n## Images\nYou can use images to add visual content:\n\n`;\n editor.value = defaultMarkdown;\n\n // Update preview on input\n editor.addEventListener('input', () => {\n const markdown = editor.value;\n const html = markdownToHtml(markdown);\n preview.innerHTML = html;\n });\n\n // Initialize preview with default markdown\n const defaultHtml = markdownToHtml(defaultMarkdown);\n preview.innerHTML = defaultHtml;\n\n // Function to convert Markdown to HTML\n function markdownToHtml(markdown) {\n // Bold\n markdown = markdown.replace(/\\*\\*(.*?)\\*\\*/g, '<b>$1</b>');\n\n // Italic\n markdown = markdown.replace(/\\*(.*?)\\*/g, '<i>$1</i>');\n\n // Links\n markdown = markdown.replace(/\\[(.*?)\\]\\((.*?)\\)/g, '<a href=\"$2\">$1</a>');\n\n // Images\n markdown = markdown.replace(/!\\[(.*?)\\]\\((.*?)\\)/g, '<img src=\"$2\" alt=\"$1\">');\n\n // Headings\n markdown = markdown.replace(/(^#{1,6} )(.*)/gm, (match, level, text) => {\n return `<h${level.length}>${text}</h${level.length}>`;\n });\n\n // Lists\n markdown = markdown.replace(/^(\\*|\\d+\\.) (.*)/gm, (match, marker, text) => {\n if (marker.startsWith('*')) {\n return `<li>${text}</li>`;\n } else {\n return `<li>${text}</li>`;\n }\n });\n\n // Line breaks\n markdown = markdown.replace(/\\n/g, '<br>');\n\n // Fix for nested lists\n markdown = markdown.replace(/<li><li>/g, '<li>');\n markdown = markdown.replace(/<\\/li><\\/li>/g, '</li>');\n\n // Wrap lists in ul\n markdown = markdown.replace(/(<li>.*<\\/li>)/g, '<ul>$1</ul>');\n\n return markdown;\n }\n </script>\n</body>\n</html>",
29"performance": {
30"tokensPerSecond": 4092.96,
cerebras_coderindex.html1 match
21<meta property="og:description" content="Turn your ideas into fully functional apps in less than a second โ powered by Llama3.3-70b on Cerebras's super-fast wafer chips. Code is 100% open-source, hosted on Val Town."">
22<meta property="og:type" content="website">
23<meta property="og:image" content="https://stevekrouse-blob_admin.web.val.run/api/public/CerebrasCoderOG.jpg">
24
25