440 {profile && (
441 <div className="flex items-center space-x-4">
442 <img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
443 <span>{profile.username}</span>
444 <a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
583 alt="Blob content"
584 className="max-w-full h-auto"
585 onError={() => console.error("Error loading image")}
586 />
587 </div>
635 <li>Create public shareable links for blobs</li>
636 <li>View and manage public folder</li>
637 <li>Preview images directly in the interface</li>
638 </ul>
639 </div>
693 const { ValTown } = await import("npm:@valtown/sdk");
694 const vt = new ValTown();
695 const { email: authorEmail, profileImageUrl, username } = await vt.me.profile.retrieve();
696 // const authorEmail = me.email;
697
761
762 c.set("email", email);
763 c.set("profile", { profileImageUrl, username });
764 await next();
765};
440 {profile && (
441 <div className="flex items-center space-x-4">
442 <img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
443 <span>{profile.username}</span>
444 <a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
583 alt="Blob content"
584 className="max-w-full h-auto"
585 onError={() => console.error("Error loading image")}
586 />
587 </div>
635 <li>Create public shareable links for blobs</li>
636 <li>View and manage public folder</li>
637 <li>Preview images directly in the interface</li>
638 </ul>
639 </div>
693 const { ValTown } = await import("npm:@valtown/sdk");
694 const vt = new ValTown();
695 const { email: authorEmail, profileImageUrl, username } = await vt.me.profile.retrieve();
696 // const authorEmail = me.email;
697
761
762 c.set("email", email);
763 c.set("profile", { profileImageUrl, username });
764 await next();
765};
17 const calculateAspectRatio = (file: File) => {
18 return new Promise<{ width: number; height: number }>((resolve) => {
19 const img = new Image();
20 img.onload = () => {
21 URL.revokeObjectURL(img.src);
206 headers: {
207 Authorization: `Bearer ${token}`,
208 "Content-Type": "image/gif",
209 "Content-Length": String(size),
210 },
440 {profile && (
441 <div className="flex items-center space-x-4">
442 <img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
443 <span>{profile.username}</span>
444 <a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
583 alt="Blob content"
584 className="max-w-full h-auto"
585 onError={() => console.error("Error loading image")}
586 />
587 </div>
635 <li>Create public shareable links for blobs</li>
636 <li>View and manage public folder</li>
637 <li>Preview images directly in the interface</li>
638 </ul>
639 </div>
693 const { ValTown } = await import("npm:@valtown/sdk");
694 const vt = new ValTown();
695 const { email: authorEmail, profileImageUrl, username } = await vt.me.profile.retrieve();
696 // const authorEmail = me.email;
697
761
762 c.set("email", email);
763 c.set("profile", { profileImageUrl, username });
764 await next();
765};
440 {profile && (
441 <div className="flex items-center space-x-4">
442 <img src={profile.profileImageUrl} alt="Profile" className="w-8 h-8 rounded-full" />
443 <span>{profile.username}</span>
444 <a href="/auth/logout" className="text-blue-400 hover:text-blue-300">Logout</a>
583 alt="Blob content"
584 className="max-w-full h-auto"
585 onError={() => console.error("Error loading image")}
586 />
587 </div>
635 <li>Create public shareable links for blobs</li>
636 <li>View and manage public folder</li>
637 <li>Preview images directly in the interface</li>
638 </ul>
639 </div>
693 const { ValTown } = await import("npm:@valtown/sdk");
694 const vt = new ValTown();
695 const { email: authorEmail, profileImageUrl, username } = await vt.me.profile.retrieve();
696 // const authorEmail = me.email;
697
761
762 c.set("email", email);
763 c.set("profile", { profileImageUrl, username });
764 await next();
765};
6const KEY = "glifInventory";
7const INVENTORY_TABLE = `${KEY}_inventory_${SCHEMA_VERSION}`;
8const DEFAULT_IMAGE_URL = "https://res.cloudinary.com/dzkwltgyd/image/upload/v1733165766/image-input-block-production/apjbm5nfc6yoevwnisxh.jpg";
9
10// Inventory Database Initialization
16 item_name TEXT NOT NULL,
17 item_type TEXT NOT NULL,
18 image_url TEXT NOT NULL,
19 description TEXT,
20 quantity INTEGER NOT NULL DEFAULT 1,
51 .min(1, "Item name is required")
52 .max(100, "Item name must be 100 characters or less"),
53 image: z.string()
54 .url("Valid image URL is required")
55 .max(500, "Image URL must be 500 characters or less")
56 .optional(),
57 type: z.string()
111 id: row.id,
112 name: row.item_name,
113 image: row.image_url,
114 type: row.item_type,
115 description: row.description,
129 await sqlite.execute(
130 `INSERT INTO ${INVENTORY_TABLE} (
131 id, address, item_name, item_type, image_url,
132 description, quantity, weight, rarity, durability
133 ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
140 item.name,
141 item.type,
142 item.image || DEFAULT_IMAGE_URL,
143 item.description || null,
144 item.quantity || 1,
393 "item": {
394 "name": "Magic Sword",
395 "image": "https://example.com/sword.png",
396 "type": "tool",
397 "description": "A powerful magical sword",
400 }
401}'</code></pre>
402 <p>Note: The "image" field is optional. If not provided, a default image will be used.</p>
403
404 <h3 class="route">POST /remove</h3>