160 transition-property: background-color;
161 transition-duration: 400ms;
162 transition-timing-function: linear;
163}
164
769 transition-property: color, background-color, border-color, opacity;
770 transition-duration: 200ms;
771 transition-timing-function: ease-in-out;
772}
773
1/**
2 * Sound effects utility functions for the application
3 */
4
7 * @returns A Promise that resolves when the sound has started playing
8 */
9export function playBellSound(): Promise<void> {
10 return new Promise((resolve) => {
11 try {
69 * @returns A Promise that resolves when the sound has started playing
70 */
71export function playSimpleNotification(): Promise<void> {
72 return new Promise((resolve) => {
73 try {
20}
21
22async function createTables() {
23 await sqlite.execute(`
24 CREATE TABLE IF NOT EXISTS ${USAGE_TABLE} (
42}
43
44async function deleteTables() {
45 await sqlite.execute(`DROP TABLE IF EXISTS ${USAGE_TABLE}`);
46}
7import { useAuth } from "../hooks/useAuth.tsx";
8
9export function RequireAuthRoute () {
10 const location = useLocation();
11 const { isAuthenticated } = useAuth();
7// but in the meantime, we can cache user info in memory
8const userIdCache: { [key: string]: any } = {};
9export async function getUser(bearerToken: string) {
10 if (userIdCache[bearerToken]) return userIdCache[bearerToken];
11
16}
17
18async function last24Hours(userId: string) {
19 const usage = await sqlite.execute(
20 `SELECT
37const DAILY_PRO_LIMIT = 5; // $5 per day
38
39export async function overLimit(bearerToken: string) {
40 const user = await getUser(bearerToken);
41 const last24HourUsage = await last24Hours(user.id);
44}
45
46export async function trackUsage({
47 bearerToken,
48 val_id,
4import { Loading } from "./Loading.tsx";
5
6export function ProjectsRoute () {
7 const projects = useProjects();
8
42}
43
44function ProjectCard ({
45 user,
46 project,
81}
82
83function Privacy ({ privacy }: {
84 privacy: "public"|"unlisted"|"private";
85}) {
10}
11
12export function Preview({ projectFiles, messages, running }: PreviewProps) {
13 const [selectedEndpointIndex, setSelectedEndpointIndex] = useState<number>(0);
14 const [customPath, setCustomPath] = useState<string>("/");
9}
10
11export function PreviewFrame (props: PreviewProps) {
12 const previewKey = useRef<string>("new-chat");
13 const [count, setCount] = useState<number>(0);
77const TSRE = /\/$/;
78
79function URLInput ({ url, pathname, setPathname }) {
80 const prefix = url.replace(TSRE, "");
81 return (
94}
95
96function PreviewSelect ({ index, setIndex, files }) {
97 return (
98 <div>
120}
121
122function usePreviewURL ({ files }) {
123 const [index, setIndex] = useState<number>(0);
124 const htmlVals = files?.filter(file => file.links?.endpoint !== undefined);
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2
3export function NotFoundRoute () {
4 return (
5 <div className="container">Page not found</div>
4import { useCreateProject } from "../hooks/useCreateProject.tsx";
5
6export function NewProjectRoute () {
7 const [name, setName] = useState("");
8 const [privacy, setPrivacy] = useState("public");
65]
66
67function PrivacyRadios ({
68 value,
69 onChange,
A helper function to build a file's email
Simple functional CSS library for Val Town
import { OpenAI } from "https://esm.town/v/std/openai";
export default async function(req: Request): Promise<Response> {
if (req.method === "OPTIONS") {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": "*",
LangChain (https://langchain.com) Ambassador, KubeSphere (https://kubesphere.io) Ambassador, CNCF OpenFunction (https://openfunction.dev) TOC Member.