Adds the core project structure, including configuration files, a basic HTML page, and the main application component. It also lays the groundwork for the canvas, color palette, and configuration modal functionalities. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0385ea33-cde8-4bbd-8fce-8d192d30eb41 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/870d08ce-da3b-4822-9874-c2fe2b7628b1/0385ea33-cde8-4bbd-8fce-8d192d30eb41/Vuy7IOw
90 lines
3.0 KiB
TypeScript
90 lines
3.0 KiB
TypeScript
import { sql } from "drizzle-orm";
|
|
import { pgTable, text, varchar, integer, timestamp, boolean, json } from "drizzle-orm/pg-core";
|
|
import { createInsertSchema } from "drizzle-zod";
|
|
import { z } from "zod";
|
|
|
|
export const pixels = pgTable("pixels", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
x: integer("x").notNull(),
|
|
y: integer("y").notNull(),
|
|
color: varchar("color", { length: 7 }).notNull(), // hex color
|
|
userId: varchar("user_id").notNull(),
|
|
username: varchar("username").notNull(),
|
|
createdAt: timestamp("created_at").defaultNow().notNull(),
|
|
});
|
|
|
|
export const canvasConfig = pgTable("canvas_config", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
canvasWidth: integer("canvas_width").notNull().default(100),
|
|
canvasHeight: integer("canvas_height").notNull().default(100),
|
|
defaultCooldown: integer("default_cooldown").notNull().default(5), // seconds
|
|
enableAutomaticEvents: boolean("enable_automatic_events").notNull().default(false),
|
|
eventDuration: integer("event_duration").notNull().default(30), // minutes
|
|
eventInterval: integer("event_interval").notNull().default(6), // hours
|
|
showGridByDefault: boolean("show_grid_by_default").notNull().default(true),
|
|
updatedAt: timestamp("updated_at").defaultNow().notNull(),
|
|
});
|
|
|
|
export const userCooldowns = pgTable("user_cooldowns", {
|
|
id: varchar("id").primaryKey().default(sql`gen_random_uuid()`),
|
|
userId: varchar("user_id").notNull(),
|
|
lastPlacement: timestamp("last_placement").defaultNow().notNull(),
|
|
cooldownEnds: timestamp("cooldown_ends").notNull(),
|
|
});
|
|
|
|
export const insertPixelSchema = createInsertSchema(pixels).omit({
|
|
id: true,
|
|
createdAt: true,
|
|
});
|
|
|
|
export const insertCanvasConfigSchema = createInsertSchema(canvasConfig).omit({
|
|
id: true,
|
|
updatedAt: true,
|
|
});
|
|
|
|
export const insertUserCooldownSchema = createInsertSchema(userCooldowns).omit({
|
|
id: true,
|
|
lastPlacement: true,
|
|
});
|
|
|
|
export type Pixel = typeof pixels.$inferSelect;
|
|
export type InsertPixel = z.infer<typeof insertPixelSchema>;
|
|
export type CanvasConfig = typeof canvasConfig.$inferSelect;
|
|
export type InsertCanvasConfig = z.infer<typeof insertCanvasConfigSchema>;
|
|
export type UserCooldown = typeof userCooldowns.$inferSelect;
|
|
export type InsertUserCooldown = z.infer<typeof insertUserCooldownSchema>;
|
|
|
|
// WebSocket message types
|
|
export const wsMessageSchema = z.union([
|
|
z.object({
|
|
type: z.literal("pixel_placed"),
|
|
data: z.object({
|
|
x: z.number(),
|
|
y: z.number(),
|
|
color: z.string(),
|
|
userId: z.string(),
|
|
username: z.string(),
|
|
timestamp: z.string(),
|
|
}),
|
|
}),
|
|
z.object({
|
|
type: z.literal("user_count"),
|
|
data: z.object({
|
|
count: z.number(),
|
|
}),
|
|
}),
|
|
z.object({
|
|
type: z.literal("config_updated"),
|
|
data: insertCanvasConfigSchema,
|
|
}),
|
|
z.object({
|
|
type: z.literal("cooldown_update"),
|
|
data: z.object({
|
|
userId: z.string(),
|
|
remainingSeconds: z.number(),
|
|
}),
|
|
}),
|
|
]);
|
|
|
|
export type WSMessage = z.infer<typeof wsMessageSchema>;
|