diff --git a/bun.lockb b/bun.lockb index b4d6c32..66ef4ee 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/components.json b/components.json new file mode 100644 index 0000000..20958c8 --- /dev/null +++ b/components.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://shadcn-svelte.com/schema.json", + "style": "new-york", + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app.css", + "baseColor": "stone" + }, + "aliases": { + "components": "$lib/components", + "utils": "$lib/utils" + }, + "typescript": true +} diff --git a/package.json b/package.json index fd4f8d2..314149e 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "chatapp", + "name": "svchat", "private": true, "version": "0.0.1", "type": "module", @@ -7,38 +7,43 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "start": "PORT=3005 tsm ./prodServer.ts", + "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "format": "prettier --write .", "lint": "prettier --check . && eslint ." }, "devDependencies": { - "@eslint/compat": "^1.2.3", - "@sveltejs/adapter-node": "^5.2.11", - "@sveltejs/kit": "^2.0.0", - "@sveltejs/vite-plugin-svelte": "^4.0.0", + "@eslint/compat": "^1.2.5", + "@eslint/js": "^9.18.0", + "@sveltejs/adapter-auto": "^4.0.0", + "@sveltejs/kit": "^2.16.0", + "@sveltejs/vite-plugin-svelte": "^5.0.0", "autoprefixer": "^10.4.20", - "eslint": "^9.7.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.36.0", - "globals": "^15.0.0", - "prettier": "^3.3.2", - "prettier-plugin-svelte": "^3.2.6", - "prettier-plugin-tailwindcss": "^0.6.5", + "bits-ui": "^0.22.0", + "clsx": "^2.1.1", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-svelte": "^2.46.1", + "globals": "^15.14.0", + "prettier": "^3.4.2", + "prettier-plugin-svelte": "^3.3.3", + "prettier-plugin-tailwindcss": "^0.6.10", "svelte": "^5.0.0", "svelte-check": "^4.0.0", - "tailwindcss": "^3.4.9", + "tailwind-merge": "^3.0.1", + "tailwind-variants": "^0.3.1", + "tailwindcss": "^3.4.17", "typescript": "^5.0.0", - "typescript-eslint": "^8.0.0", - "vite": "^5.4.11" + "typescript-eslint": "^8.20.0", + "vite": "^6.0.0" }, "dependencies": { + "lucide-svelte": "^0.474.0", + "socket.io": "^4.8.1", "@types/express": "^5.0.0", "cassandra-driver": "^4.7.2", - "daisyui": "^4.12.23", "express": "^4.21.2", - "socket.io": "^4.8.1", "socket.io-client": "^4.8.1", "tsm": "^2.3.0", "uuid": "^11.0.4" diff --git a/src/app.css b/src/app.css index 3f9d957..6746b56 100644 --- a/src/app.css +++ b/src/app.css @@ -1,10 +1,58 @@ -@import 'tailwindcss/base'; -@import 'tailwindcss/components'; -@import 'tailwindcss/utilities'; +@tailwind base; +@tailwind components; +@tailwind utilities; -.abs-centered { - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 142.1 76.2% 36.3%; + --primary-foreground: 355.7 100% 97.3%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 72.22% 50.59%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 142.1 76.2% 36.3%; + --radius: 0.3rem; + } + .dark { + --background: 20 14.3% 4.1%; + --foreground: 0 0% 95%; + --card: 24 9.8% 10%; + --card-foreground: 0 0% 95%; + --popover: 0 0% 9%; + --popover-foreground: 0 0% 95%; + --primary: 142.1 70.6% 45.3%; + --primary-foreground: 144.9 80.4% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 15%; + --muted-foreground: 240 5% 64.9%; + --accent: 12 6.5% 15.1%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 142.4 71.8% 29.2%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } } diff --git a/src/app.html b/src/app.html index 7c9830c..84ffad1 100644 --- a/src/app.html +++ b/src/app.html @@ -1,31 +1,12 @@ - - + + %sveltekit.head% - - -
%sveltekit.body%
+ +
%sveltekit.body%
diff --git a/src/lib/components/channel.svelte b/src/lib/components/channel.svelte new file mode 100644 index 0000000..dd9f7f0 --- /dev/null +++ b/src/lib/components/channel.svelte @@ -0,0 +1,20 @@ + + + + {#if unread} + + {:else} + + {/if} + {channelName} + diff --git a/src/lib/components/mainLayout.svelte b/src/lib/components/mainLayout.svelte new file mode 100644 index 0000000..b302c9e --- /dev/null +++ b/src/lib/components/mainLayout.svelte @@ -0,0 +1,40 @@ + + +
+ +
+
+
+

bello

+
+
+
+
+
diff --git a/src/lib/components/ui/badge/badge.svelte b/src/lib/components/ui/badge/badge.svelte new file mode 100644 index 0000000..c2eae1c --- /dev/null +++ b/src/lib/components/ui/badge/badge.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/badge/index.ts b/src/lib/components/ui/badge/index.ts new file mode 100644 index 0000000..502ad3e --- /dev/null +++ b/src/lib/components/ui/badge/index.ts @@ -0,0 +1,19 @@ +import { type VariantProps, tv } from 'tailwind-variants'; + +export { default as Badge } from './badge.svelte'; +export const badgeVariants = tv({ + base: 'focus:ring-ring inline-flex select-none items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2', + variants: { + variant: { + default: 'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent shadow', + secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent', + destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent shadow', + outline: 'text-foreground', + }, + }, + defaultVariants: { + variant: 'default', + }, +}); + +export type Variant = VariantProps['variant']; diff --git a/src/lib/components/ui/button/button.svelte b/src/lib/components/ui/button/button.svelte new file mode 100644 index 0000000..2e4b156 --- /dev/null +++ b/src/lib/components/ui/button/button.svelte @@ -0,0 +1,18 @@ + + + + + diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..affba83 --- /dev/null +++ b/src/lib/components/ui/button/index.ts @@ -0,0 +1,48 @@ +import type { Button as ButtonPrimitive } from 'bits-ui'; +import { type VariantProps, tv } from 'tailwind-variants'; +import Root from './button.svelte'; + +const buttonVariants = tv({ + base: 'focus-visible:ring-ring inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 disabled:pointer-events-none disabled:opacity-50', + variants: { + variant: { + default: 'bg-primary text-primary-foreground hover:bg-primary/90 shadow', + destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm', + outline: 'border-input bg-background hover:bg-accent hover:text-accent-foreground border shadow-sm', + secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-sm', + ghost: 'hover:bg-accent hover:text-accent-foreground', + link: 'text-primary underline-offset-4 hover:underline', + }, + size: { + default: 'h-9 px-4 py-2', + sm: 'h-8 rounded-md px-3 text-xs', + lg: 'h-10 rounded-md px-8', + icon: 'h-9 w-9', + }, + }, + defaultVariants: { + variant: 'default', + size: 'default', + }, +}); + +type Variant = VariantProps['variant']; +type Size = VariantProps['size']; + +type Props = ButtonPrimitive.Props & { + variant?: Variant; + size?: Size; +}; + +type Events = ButtonPrimitive.Events; + +export { + Root, + type Props, + type Events, + // + Root as Button, + type Props as ButtonProps, + type Events as ButtonEvents, + buttonVariants, +}; diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..e2dce55 --- /dev/null +++ b/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..72ff678 --- /dev/null +++ b/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,13 @@ + + +

+ +

diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..3d6a4b6 --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..c9822c5 --- /dev/null +++ b/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..bed9ca4 --- /dev/null +++ b/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,17 @@ + + + + + diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..2b8296a --- /dev/null +++ b/src/lib/components/ui/card/card.svelte @@ -0,0 +1,21 @@ + + + +
+ +
diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..1432839 --- /dev/null +++ b/src/lib/components/ui/card/index.ts @@ -0,0 +1,24 @@ +import Root from './card.svelte'; +import Content from './card-content.svelte'; +import Description from './card-description.svelte'; +import Footer from './card-footer.svelte'; +import Header from './card-header.svelte'; +import Title from './card-title.svelte'; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, +}; + +export type HeadingLevel = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'; diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..b976af4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..a9f8d73 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,22 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..ef74d45 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,30 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..37647b6 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,16 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..06a8337 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,11 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..acfdb3a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,34 @@ + + + + + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..0d46384 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..454af6c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..1955384 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,25 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..7e4bc9d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,31 @@ + + + + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..22001e4 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,48 @@ +import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui'; +import Item from './dropdown-menu-item.svelte'; +import Label from './dropdown-menu-label.svelte'; +import Content from './dropdown-menu-content.svelte'; +import Shortcut from './dropdown-menu-shortcut.svelte'; +import RadioItem from './dropdown-menu-radio-item.svelte'; +import Separator from './dropdown-menu-separator.svelte'; +import RadioGroup from './dropdown-menu-radio-group.svelte'; +import SubContent from './dropdown-menu-sub-content.svelte'; +import SubTrigger from './dropdown-menu-sub-trigger.svelte'; +import CheckboxItem from './dropdown-menu-checkbox-item.svelte'; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; + +export { + Sub, + Root, + Item, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as DropdownMenu, + Sub as DropdownMenuSub, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + Group as DropdownMenuGroup, + Content as DropdownMenuContent, + Trigger as DropdownMenuTrigger, + Shortcut as DropdownMenuShortcut, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + RadioGroup as DropdownMenuRadioGroup, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + CheckboxItem as DropdownMenuCheckboxItem, +}; diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..1d669f9 --- /dev/null +++ b/src/lib/components/ui/input/index.ts @@ -0,0 +1,29 @@ +import Root from './input.svelte'; + +export type FormInputEvent = T & { + currentTarget: EventTarget & HTMLInputElement; +}; +export type InputEvents = { + blur: FormInputEvent; + change: FormInputEvent; + click: FormInputEvent; + focus: FormInputEvent; + focusin: FormInputEvent; + focusout: FormInputEvent; + keydown: FormInputEvent; + keypress: FormInputEvent; + keyup: FormInputEvent; + mouseover: FormInputEvent; + mouseenter: FormInputEvent; + mouseleave: FormInputEvent; + mousemove: FormInputEvent; + paste: FormInputEvent; + input: FormInputEvent; + wheel: FormInputEvent; +}; + +export { + Root, + // + Root as Input, +}; diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..ef65e2a --- /dev/null +++ b/src/lib/components/ui/input/input.svelte @@ -0,0 +1,41 @@ + + + diff --git a/src/lib/components/ui/sheet/index.ts b/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..ffd7444 --- /dev/null +++ b/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,106 @@ +import { Dialog as SheetPrimitive } from 'bits-ui'; +import { type VariantProps, tv } from 'tailwind-variants'; + +import Portal from './sheet-portal.svelte'; +import Overlay from './sheet-overlay.svelte'; +import Content from './sheet-content.svelte'; +import Header from './sheet-header.svelte'; +import Footer from './sheet-footer.svelte'; +import Title from './sheet-title.svelte'; +import Description from './sheet-description.svelte'; + +const Root = SheetPrimitive.Root; +const Close = SheetPrimitive.Close; +const Trigger = SheetPrimitive.Trigger; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; + +export const sheetVariants = tv({ + base: 'bg-background fixed z-50 gap-4 p-6 shadow-lg', + variants: { + side: { + top: 'inset-x-0 top-0 border-b ', + bottom: 'inset-x-0 bottom-0 border-t', + left: 'inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm', + right: 'inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm', + }, + }, + defaultVariants: { + side: 'right', + }, +}); + +export const sheetTransitions = { + top: { + in: { + y: '-100%', + duration: 500, + opacity: 1, + }, + out: { + y: '-100%', + duration: 300, + opacity: 1, + }, + }, + bottom: { + in: { + y: '100%', + duration: 500, + opacity: 1, + }, + out: { + y: '100%', + duration: 300, + opacity: 1, + }, + }, + left: { + in: { + x: '-100%', + duration: 500, + opacity: 1, + }, + out: { + x: '-100%', + duration: 300, + opacity: 1, + }, + }, + right: { + in: { + x: '100%', + duration: 500, + opacity: 1, + }, + out: { + x: '100%', + duration: 300, + opacity: 1, + }, + }, +}; + +export type Side = VariantProps['side']; diff --git a/src/lib/components/ui/sheet/sheet-content.svelte b/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..1937f26 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,37 @@ + + + + + + + + + Close + + + diff --git a/src/lib/components/ui/sheet/sheet-description.svelte b/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..ba17548 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/sheet/sheet-footer.svelte b/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..c625327 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/sheet/sheet-header.svelte b/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..ac2ca13 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,13 @@ + + +
+ +
diff --git a/src/lib/components/ui/sheet/sheet-overlay.svelte b/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..52b450a --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-portal.svelte b/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 0000000..e6cc867 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/components/ui/sheet/sheet-title.svelte b/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..b8d0128 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,13 @@ + + + + + diff --git a/src/lib/server/db/index.ts b/src/lib/server/db/index.ts index 2b7640c..5edf507 100644 --- a/src/lib/server/db/index.ts +++ b/src/lib/server/db/index.ts @@ -1,17 +1,5 @@ import cassandra from 'cassandra-driver'; -function reverseArray(array: cassandra.types.Row[]) { - let left = null; - let right = null; - const length = array.length; - for (left = 0, right = length - 1; left < right; left += 1, right -= 1) { - const temporary = array[left]; - array[left] = array[right]; - array[right] = temporary; - } - return array; -} - async function createChannel(client: cassandra.Client, channelName: string) { try { await client.execute(` @@ -40,7 +28,7 @@ async function storeMessage(client: cassandra.Client, channelName: string, conte } } -async function getMessages(client: cassandra.Client, channelName: string, limit: number) { +async function getMessages(client: cassandra.Client, channelName: string, limit: number): Promise { try { const res = await client.execute( `SELECT * FROM channels.channel_${channelName} WHERE channel_name = '${channelName}' ORDER BY timestamp DESC LIMIT ${limit}`, @@ -49,6 +37,7 @@ async function getMessages(client: cassandra.Client, channelName: string, limit: } catch (e) { // @ts-expect-error I don't like this thing yelling at me console.log(`Error fetching messages: ${e.message}`); + return; } } diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..362d630 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,53 @@ +import { type ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import { cubicOut } from 'svelte/easing'; +import type { TransitionConfig } from 'svelte/transition'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +type FlyAndScaleParams = { + y?: number; + x?: number; + start?: number; + duration?: number; +}; + +export const flyAndScale = (node: Element, params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }): TransitionConfig => { + const style = getComputedStyle(node); + const transform = style.transform === 'none' ? '' : style.transform; + + const scaleConversion = (valueA: number, scaleA: [number, number], scaleB: [number, number]) => { + const [minA, maxA] = scaleA; + const [minB, maxB] = scaleB; + + const percentage = (valueA - minA) / (maxA - minA); + const valueB = percentage * (maxB - minB) + minB; + + return valueB; + }; + + const styleToString = (style: Record): string => { + return Object.keys(style).reduce((str, key) => { + if (style[key] === undefined) return str; + return str + `${key}:${style[key]};`; + }, ''); + }; + + return { + duration: params.duration ?? 200, + delay: 0, + css: (t) => { + const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0]); + const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0]); + const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1]); + + return styleToString({ + transform: `${transform} translate3d(${x}px, ${y}px, 0) scale(${scale})`, + opacity: t, + }); + }, + easing: cubicOut, + }; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 34832d6..dd9063f 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,6 +1,11 @@ -{@render children()} + + {@render children()} + diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 96a1efd..e69de29 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,62 +0,0 @@ - - -{#snippet message(messages: TypeMessage[])} - {#each messages as message} - - {/each} -{/snippet} - -
-
-

SVChat

-
-
-
- {@render message(log)} - {@render message(data.messages)} -
-
- - -
-
diff --git a/svelte.config.js b/svelte.config.js index a9692c1..4f546cd 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-node'; +import adapter from '@sveltejs/adapter-auto'; import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; /** @type {import('@sveltejs/kit').Config} */ @@ -12,6 +12,9 @@ const config = { // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://svelte.dev/docs/kit/adapters for more information about adapters. adapter: adapter(), + alias: { + '@/*': './path/to/lib/*', + }, }, }; diff --git a/tailwind.config.ts b/tailwind.config.ts index 108883c..7c1b0d9 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,46 +1,64 @@ +import { fontFamily } from 'tailwindcss/defaultTheme'; import type { Config } from 'tailwindcss'; -import daisyui from 'daisyui'; -export default { +const config: Config = { + darkMode: ['class'], content: ['./src/**/*.{html,js,svelte,ts}'], - plugins: [daisyui], + safelist: ['dark'], theme: { - fontSize: { - sm: '0.750rem', - base: '1rem', - xl: '1.333rem', - '2xl': '1.777rem', - '3xl': '2.369rem', - '4xl': '3.158rem', - '5xl': '4.210rem', + container: { + center: true, + padding: '2rem', + screens: { + '2xl': '1400px', + }, }, - fontFamily: { - heading: 'IBM Plex Sans', - body: 'IBM Plex Sans', - }, - fontWeight: { - normal: '400', - bold: '700', - }, - }, - daisyui: { - themes: [ - { - light: { - "primary": "#5fb979", - "secondary": "#9fdfb3", - "accent": "#66db89", - "neutral": "#1b3222", - "base-100": "#f2f8f4", + extend: { + colors: { + border: 'hsl(var(--border) / )', + input: 'hsl(var(--input) / )', + ring: 'hsl(var(--ring) / )', + background: 'hsl(var(--background) / )', + foreground: 'hsl(var(--foreground) / )', + primary: { + DEFAULT: 'hsl(var(--primary) / )', + foreground: 'hsl(var(--primary-foreground) / )', }, - dark: { - "primary": "#46a05f", - "secondary": "#206034", - "accent": "#249947", - "neutral": "#1b3222", - "base-100": "#2D2D2D", + secondary: { + DEFAULT: 'hsl(var(--secondary) / )', + foreground: 'hsl(var(--secondary-foreground) / )', + }, + destructive: { + DEFAULT: 'hsl(var(--destructive) / )', + foreground: 'hsl(var(--destructive-foreground) / )', + }, + muted: { + DEFAULT: 'hsl(var(--muted) / )', + foreground: 'hsl(var(--muted-foreground) / )', + }, + accent: { + DEFAULT: 'hsl(var(--accent) / )', + foreground: 'hsl(var(--accent-foreground) / )', + }, + popover: { + DEFAULT: 'hsl(var(--popover) / )', + foreground: 'hsl(var(--popover-foreground) / )', + }, + card: { + DEFAULT: 'hsl(var(--card) / )', + foreground: 'hsl(var(--card-foreground) / )', }, }, - ], + borderRadius: { + lg: 'var(--radius)', + md: 'calc(var(--radius) - 2px)', + sm: 'calc(var(--radius) - 4px)', + }, + fontFamily: { + sans: [...fontFamily.sans], + }, + }, }, -} satisfies Config; +}; + +export default config;