Val Town Code SearchReturn to Val Town

API Access

You can access search results via JSON API by adding format=json to your query:

https://codesearch.val.run/?q=image&page=227&format=json

For typeahead suggestions, use the /typeahead endpoint:

https://codesearch.val.run/typeahead?q=image

Returns an array of strings in format "username" or "username/projectName"

Found 2775 results for "image"(1137ms)

OpenTownie_1742929531340Chat.tsx11 matches

@dcm31•Updated 1 month ago
6import { playBellSound } from "../utils/soundEffects.ts";
7import { BranchControl } from "./BranchControl.tsx";
8import { ImageUpload, PROMPT_IMAGE_LIMIT } from "./ImageUpload.tsx";
9import { MessagePart } from "./MessagePart.tsx";
10
123 const [branchId, setBranchId] = useLocalStorage<string | undefined>("branchId", undefined);
124 const [soundEnabled, setSoundEnabled] = useLocalStorage<boolean>("soundEnabled", true);
125 const [images, setImages] = useState<(string | null)[]>([]);
126
127 // Only track message end times - we'll use message.createdAt for start times
163 branchId,
164 anthropicApiKey,
165 images: images
166 .filter((img): img is string => {
167 // Make sure it's a string and a valid data URL
168 const isValid = typeof img === "string" && img.startsWith("data:");
169 if (!isValid && img !== null) {
170 console.warn("Invalid image format:", img?.substring(0, 50) + "...");
171 }
172 return isValid;
202 const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
203 e.preventDefault();
204 const validImages = images.filter((img): img is string => typeof img === "string");
205 console.log("Submitting with images:", validImages);
206 if (input.trim() || validImages.length > 0) {
207 originalHandleSubmit(e);
208 setImages([]);
209 }
210 };
344 disabled={running}
345 >
346 {(images.length > 0 || !running) && <ImageUpload images={images} setImages={setImages} />}
347
348 <div className="flex gap-2">
359 if (e.key === "Enter" && !e.shiftKey && !isMobile) {
360 e.preventDefault();
361 if (input.trim() || images.filter(Boolean).length > 0) {
362 handleSubmit(e as any);
363 }
381 }
382 }}
383 title="Attach images"
384 >
385 📎

OpenTownie_1742929531340ImageUpload.tsx49 matches

@dcm31•Updated 1 month ago
2import React, { useRef, useState } from "https://esm.sh/react@18.2.0?dev";
3
4// Maximum number of images that can be uploaded
5export const PROMPT_IMAGE_LIMIT = 5;
6
7interface ImageUploadProps {
8 images: (string | null)[];
9 setImages: (images: (string | null)[]) => void;
10}
11
12export function ImageUpload({ images, setImages }: ImageUploadProps) {
13 const fileInputRef = useRef<HTMLInputElement>(null);
14 const [isDragging, setIsDragging] = useState(false);
23 // Process the selected files
24 const processFiles = async (files: File[]) => {
25 // Filter for image files only
26 const imageFiles = files.filter(file => file.type.startsWith('image/'));
27
28 // Limit the number of images
29 const filesToProcess = imageFiles.slice(0, PROMPT_IMAGE_LIMIT - images.filter(Boolean).length);
30
31 if (filesToProcess.length === 0) return;
32
33 // Add null placeholders for loading state
34 const newImages = [...images, ...Array(filesToProcess.length).fill(null)];
35 setImages(newImages);
36
37 // Process each file
38 const processedImages = await Promise.all(
39 filesToProcess.map(async (file) => {
40 return await readFileAsDataURL(file);
42 );
43
44 // Replace null placeholders with actual images
45 const updatedImages = [...images];
46 processedImages.forEach((dataUrl, index) => {
47 updatedImages[images.length + index] = dataUrl;
48 });
49
50 setImages(updatedImages.slice(0, PROMPT_IMAGE_LIMIT));
51 };
52
57 reader.onload = () => {
58 const result = reader.result as string;
59 console.log("Image loaded, size:", result.length, "bytes");
60 resolve(result);
61 };
93 };
94
95 // Handle removing an image
96 const removeImage = (index: number) => {
97 const newImages = [...images];
98 newImages.splice(index, 1);
99 setImages(newImages);
100 };
101
102 // Check if we've reached the image limit
103 const isAtLimit = images.filter(Boolean).length >= PROMPT_IMAGE_LIMIT;
104
105 return (
106 <div className="w-full">
107 {/* Image previews */}
108 {images.length > 0 && (
109 <div className="flex flex-wrap gap-2 mb-2">
110 {images.map((image, index) => (
111 <div key={index} className="relative">
112 {image ? (
113 <div className="relative group">
114 <img
115 src={image}
116 alt={`Uploaded ${index + 1}`}
117 className="h-16 w-16 object-cover rounded border border-gray-300"
119 <button
120 className="absolute top-0 right-0 bg-red-500 text-white rounded-full w-5 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
121 onClick={() => removeImage(index)}
122 title="Remove image"
123 >
124 ×
151 ref={fileInputRef}
152 onChange={handleFileChange}
153 accept="image/*"
154 multiple
155 className="hidden"
157 <div className="text-sm text-gray-500">
158 {isDragging ? (
159 "Drop images here"
160 ) : (
161 <>
162 <span className="text-blue-500">Upload images</span> or drag and drop
163 <div className="text-xs mt-1">
164 {images.filter(Boolean).length}/{PROMPT_IMAGE_LIMIT} images
165 </div>
166 </>
173}
174
175// Component to display images in messages
176export function ImagePreview({ images }: { images: string[] }) {
177 const [expandedImage, setExpandedImage] = useState<string | null>(null);
178
179 if (!images || images.length === 0) return null;
180
181 return (
182 <div className="mt-2">
183 <div className="flex flex-wrap gap-2">
184 {images.map((image, index) => (
185 <div key={index} className="relative">
186 <img
187 src={image}
188 alt={`Image ${index + 1}`}
189 className="max-h-32 max-w-32 object-contain rounded cursor-pointer"
190 onClick={() => setExpandedImage(image)}
191 />
192 </div>
194 </div>
195
196 {/* Modal for expanded image */}
197 {expandedImage && (
198 <div
199 className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50"
200 onClick={() => setExpandedImage(null)}
201 >
202 <div className="max-w-[90%] max-h-[90%]">
203 <img
204 src={expandedImage}
205 alt="Expanded view"
206 className="max-w-full max-h-full object-contain"

OpenTownie_1742929531340index.ts11 matches

@dcm31•Updated 1 month ago
39 }
40
41 const { messages, project, branchId, anthropicApiKey, images } = await c.req.json();
42
43 console.log("Original messages:", JSON.stringify(messages, null, 2));
44 console.log("Images received:", JSON.stringify(images, null, 2));
45
46 // Create a new array of messages to avoid mutating the original
47 let processedMessages = [...messages];
48
49 // If there are images, we need to add them to the last user message
50 if (images && Array.isArray(images) && images.length > 0) {
51 // Find the last user message
52 const lastUserMessageIndex = processedMessages.findIndex(
71 });
72
73 // Add each image to the content array using the correct ImagePart format
74 for (const image of images) {
75 if (image && image.url) {
76 // Extract mime type from data URL if available
77 let mimeType = undefined;
78 if (image.url.startsWith('data:')) {
79 const matches = image.url.match(/^data:([^;]+);/);
80 if (matches && matches.length > 1) {
81 mimeType = matches[1];
84
85 newUserMessage.content.push({
86 type: 'image',
87 image: image.url,
88 mimeType
89 });

OpenTownie_1742929531340MessagePart.tsx11 matches

@dcm31•Updated 1 month ago
2import { type Message } from "https://esm.sh/@ai-sdk/react?dev&deps=react@18.2.0&react-dom@18.2.0";
3import ReactMarkdown from "https://esm.sh/react-markdown?dev&deps=react@18.2.0&react-dom@18.2.0";
4import { ImagePreview } from "./ImageUpload.tsx";
5
6export function MessagePart({ part }: { part: NonNullable<Message["parts"]>[number] }) {
61 );
62 }
63 if (part.type === "image") {
64 // Handle both formats: {image: {url: string}} and {image: string}
65 const imageUrl = typeof part.image === 'string'
66 ? part.image
67 : part.image.url || (part.image as any).source?.url;
68
69 return (
70 <div className="mt-2">
71 <img
72 src={imageUrl}
73 alt="Uploaded image"
74 className="max-h-64 max-w-full object-contain rounded"
75 />
77 );
78 }
79 // Handle multiple images in a single part
80 if (part.type === "images") {
81 return <ImagePreview images={part.images.map(img => img.url)} />;
82 }
83}

OpenTownie_1742929531340system_prompt.txt10 matches

@dcm31•Updated 1 month ago
12- If a section of code that you're working on is getting too complex, consider refactoring it into subcomponents
13
14## Image Handling
15
16- When users upload images, carefully analyze them to understand their content
17- Reference specific details from the images in your responses
18- If multiple images are uploaded, consider their relationship to each other
19- For code-related images (screenshots, diagrams), extract relevant information and incorporate it into your solutions
20- For UI mockups or design images, use them as reference for layout and design, use the colors from the image
21- When images contain text or code, transcribe relevant portions as needed
22- If image content is unclear, ask clarifying questions about what the user wants you to focus on
23
24## Technical Requirements
95## Val Town Platform Specifics
96- **Redirects:** Use `return new Response(null, { status: 302, headers: { Location: "/place/to/redirect" }})` instead of `Response.redirect` which is broken
97- **Images:** Avoid external images or base64 images. Use emojis, unicode symbols, or icon fonts/libraries instead
98- For AI-generated images, use: `https://maxm-imggenurl.web.val.run/the-description-of-your-image`
99- **Storage:** DO NOT use the Deno KV module for storage
100- **Browser APIs:** DO NOT use the `alert()`, `prompt()`, or `confirm()` methods

OpenTownie_1742929529007Chat.tsx11 matches

@dcm31•Updated 1 month ago
6import { playBellSound } from "../utils/soundEffects.ts";
7import { BranchControl } from "./BranchControl.tsx";
8import { ImageUpload, PROMPT_IMAGE_LIMIT } from "./ImageUpload.tsx";
9import { MessagePart } from "./MessagePart.tsx";
10
123 const [branchId, setBranchId] = useLocalStorage<string | undefined>("branchId", undefined);
124 const [soundEnabled, setSoundEnabled] = useLocalStorage<boolean>("soundEnabled", true);
125 const [images, setImages] = useState<(string | null)[]>([]);
126
127 // Only track message end times - we'll use message.createdAt for start times
163 branchId,
164 anthropicApiKey,
165 images: images
166 .filter((img): img is string => {
167 // Make sure it's a string and a valid data URL
168 const isValid = typeof img === "string" && img.startsWith("data:");
169 if (!isValid && img !== null) {
170 console.warn("Invalid image format:", img?.substring(0, 50) + "...");
171 }
172 return isValid;
202 const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
203 e.preventDefault();
204 const validImages = images.filter((img): img is string => typeof img === "string");
205 console.log("Submitting with images:", validImages);
206 if (input.trim() || validImages.length > 0) {
207 originalHandleSubmit(e);
208 setImages([]);
209 }
210 };
344 disabled={running}
345 >
346 {(images.length > 0 || !running) && <ImageUpload images={images} setImages={setImages} />}
347
348 <div className="flex gap-2">
359 if (e.key === "Enter" && !e.shiftKey && !isMobile) {
360 e.preventDefault();
361 if (input.trim() || images.filter(Boolean).length > 0) {
362 handleSubmit(e as any);
363 }
381 }
382 }}
383 title="Attach images"
384 >
385 📎

OpenTownie_1742929529007ImageUpload.tsx49 matches

@dcm31•Updated 1 month ago
2import React, { useRef, useState } from "https://esm.sh/react@18.2.0?dev";
3
4// Maximum number of images that can be uploaded
5export const PROMPT_IMAGE_LIMIT = 5;
6
7interface ImageUploadProps {
8 images: (string | null)[];
9 setImages: (images: (string | null)[]) => void;
10}
11
12export function ImageUpload({ images, setImages }: ImageUploadProps) {
13 const fileInputRef = useRef<HTMLInputElement>(null);
14 const [isDragging, setIsDragging] = useState(false);
23 // Process the selected files
24 const processFiles = async (files: File[]) => {
25 // Filter for image files only
26 const imageFiles = files.filter(file => file.type.startsWith('image/'));
27
28 // Limit the number of images
29 const filesToProcess = imageFiles.slice(0, PROMPT_IMAGE_LIMIT - images.filter(Boolean).length);
30
31 if (filesToProcess.length === 0) return;
32
33 // Add null placeholders for loading state
34 const newImages = [...images, ...Array(filesToProcess.length).fill(null)];
35 setImages(newImages);
36
37 // Process each file
38 const processedImages = await Promise.all(
39 filesToProcess.map(async (file) => {
40 return await readFileAsDataURL(file);
42 );
43
44 // Replace null placeholders with actual images
45 const updatedImages = [...images];
46 processedImages.forEach((dataUrl, index) => {
47 updatedImages[images.length + index] = dataUrl;
48 });
49
50 setImages(updatedImages.slice(0, PROMPT_IMAGE_LIMIT));
51 };
52
57 reader.onload = () => {
58 const result = reader.result as string;
59 console.log("Image loaded, size:", result.length, "bytes");
60 resolve(result);
61 };
93 };
94
95 // Handle removing an image
96 const removeImage = (index: number) => {
97 const newImages = [...images];
98 newImages.splice(index, 1);
99 setImages(newImages);
100 };
101
102 // Check if we've reached the image limit
103 const isAtLimit = images.filter(Boolean).length >= PROMPT_IMAGE_LIMIT;
104
105 return (
106 <div className="w-full">
107 {/* Image previews */}
108 {images.length > 0 && (
109 <div className="flex flex-wrap gap-2 mb-2">
110 {images.map((image, index) => (
111 <div key={index} className="relative">
112 {image ? (
113 <div className="relative group">
114 <img
115 src={image}
116 alt={`Uploaded ${index + 1}`}
117 className="h-16 w-16 object-cover rounded border border-gray-300"
119 <button
120 className="absolute top-0 right-0 bg-red-500 text-white rounded-full w-5 h-5 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity"
121 onClick={() => removeImage(index)}
122 title="Remove image"
123 >
124 ×
151 ref={fileInputRef}
152 onChange={handleFileChange}
153 accept="image/*"
154 multiple
155 className="hidden"
157 <div className="text-sm text-gray-500">
158 {isDragging ? (
159 "Drop images here"
160 ) : (
161 <>
162 <span className="text-blue-500">Upload images</span> or drag and drop
163 <div className="text-xs mt-1">
164 {images.filter(Boolean).length}/{PROMPT_IMAGE_LIMIT} images
165 </div>
166 </>
173}
174
175// Component to display images in messages
176export function ImagePreview({ images }: { images: string[] }) {
177 const [expandedImage, setExpandedImage] = useState<string | null>(null);
178
179 if (!images || images.length === 0) return null;
180
181 return (
182 <div className="mt-2">
183 <div className="flex flex-wrap gap-2">
184 {images.map((image, index) => (
185 <div key={index} className="relative">
186 <img
187 src={image}
188 alt={`Image ${index + 1}`}
189 className="max-h-32 max-w-32 object-contain rounded cursor-pointer"
190 onClick={() => setExpandedImage(image)}
191 />
192 </div>
194 </div>
195
196 {/* Modal for expanded image */}
197 {expandedImage && (
198 <div
199 className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50"
200 onClick={() => setExpandedImage(null)}
201 >
202 <div className="max-w-[90%] max-h-[90%]">
203 <img
204 src={expandedImage}
205 alt="Expanded view"
206 className="max-w-full max-h-full object-contain"

OpenTownie_1742929529007index.ts11 matches

@dcm31•Updated 1 month ago
39 }
40
41 const { messages, project, branchId, anthropicApiKey, images } = await c.req.json();
42
43 console.log("Original messages:", JSON.stringify(messages, null, 2));
44 console.log("Images received:", JSON.stringify(images, null, 2));
45
46 // Create a new array of messages to avoid mutating the original
47 let processedMessages = [...messages];
48
49 // If there are images, we need to add them to the last user message
50 if (images && Array.isArray(images) && images.length > 0) {
51 // Find the last user message
52 const lastUserMessageIndex = processedMessages.findIndex(
71 });
72
73 // Add each image to the content array using the correct ImagePart format
74 for (const image of images) {
75 if (image && image.url) {
76 // Extract mime type from data URL if available
77 let mimeType = undefined;
78 if (image.url.startsWith('data:')) {
79 const matches = image.url.match(/^data:([^;]+);/);
80 if (matches && matches.length > 1) {
81 mimeType = matches[1];
84
85 newUserMessage.content.push({
86 type: 'image',
87 image: image.url,
88 mimeType
89 });

OpenTownie_1742929529007MessagePart.tsx11 matches

@dcm31•Updated 1 month ago
2import { type Message } from "https://esm.sh/@ai-sdk/react?dev&deps=react@18.2.0&react-dom@18.2.0";
3import ReactMarkdown from "https://esm.sh/react-markdown?dev&deps=react@18.2.0&react-dom@18.2.0";
4import { ImagePreview } from "./ImageUpload.tsx";
5
6export function MessagePart({ part }: { part: NonNullable<Message["parts"]>[number] }) {
61 );
62 }
63 if (part.type === "image") {
64 // Handle both formats: {image: {url: string}} and {image: string}
65 const imageUrl = typeof part.image === 'string'
66 ? part.image
67 : part.image.url || (part.image as any).source?.url;
68
69 return (
70 <div className="mt-2">
71 <img
72 src={imageUrl}
73 alt="Uploaded image"
74 className="max-h-64 max-w-full object-contain rounded"
75 />
77 );
78 }
79 // Handle multiple images in a single part
80 if (part.type === "images") {
81 return <ImagePreview images={part.images.map(img => img.url)} />;
82 }
83}

OpenTownie_1742929529007system_prompt.txt10 matches

@dcm31•Updated 1 month ago
12- If a section of code that you're working on is getting too complex, consider refactoring it into subcomponents
13
14## Image Handling
15
16- When users upload images, carefully analyze them to understand their content
17- Reference specific details from the images in your responses
18- If multiple images are uploaded, consider their relationship to each other
19- For code-related images (screenshots, diagrams), extract relevant information and incorporate it into your solutions
20- For UI mockups or design images, use them as reference for layout and design, use the colors from the image
21- When images contain text or code, transcribe relevant portions as needed
22- If image content is unclear, ask clarifying questions about what the user wants you to focus on
23
24## Technical Requirements
95## Val Town Platform Specifics
96- **Redirects:** Use `return new Response(null, { status: 302, headers: { Location: "/place/to/redirect" }})` instead of `Response.redirect` which is broken
97- **Images:** Avoid external images or base64 images. Use emojis, unicode symbols, or icon fonts/libraries instead
98- For AI-generated images, use: `https://maxm-imggenurl.web.val.run/the-description-of-your-image`
99- **Storage:** DO NOT use the Deno KV module for storage
100- **Browser APIs:** DO NOT use the `alert()`, `prompt()`, or `confirm()` methods

brainrot_image_gen1 file match

@dcm31•Updated 2 days ago
Generate images for Italian Brainrot characters using FAL AI

modifyImage2 file matches

@stevekrouse•Updated 2 days ago