English Readme

This commit is contained in:
2026-10-03 21:58:09 +02:00
parent 5a6fc7f976
commit 2ccea34bb9
2 changed files with 77 additions and 63 deletions
+77 -59
View File
@@ -1,101 +1,119 @@
# BRETT # BRETT
Ein Imageboard-artiges Upload- und Diskussions-Tool, gebaut mit **Nuxt 4** und **shadcn-vue**. Nutzer können Dateien oder URLs hochladen, in Threads kommentieren, mit Discord-artigen Reactions antworten und aus über einem Dutzend Themes wählen. An imageboard-style upload and discussion platform built with **Nuxt 4** and **shadcn-vue**. Users can upload files or URLs, comment in threads (including file attachments and voice messages), respond with Discord-style reactions, subscribe to threads, and pick from over 20 themes.
## Features ## Features
- **Uploads:** Drag & Drop (Seiten-Dropzone + Upload-Popover), Datei- oder URL-Upload, Thumbnails für Bilder, eingebetteter Plyr-Videoplayer, YouTube-Embeds und Link-Preview-Cards - **Uploads:** Drag & drop (page dropzone + upload popover), file or URL upload, max. 200 MB. Types: **images** (generated thumbnails), **videos** (embedded Plyr player), **audio** (MP3/FLAC with embedded cover art and music metadata via `music-metadata`, dedicated player dialog), **YouTube** and **Twitch embeds**, plus **link preview cards**
- **Threads & Kommentare:** Jeder Upload ist ein Thread mit Kommentarfunktion, Discord-Style-Reactions (Toggle, Zähler, Tooltips) und Live-Updates per WebSocket - **Threads & comments:** Every upload is a thread with comments. Comments support **file attachments** and **voice messages** recorded in the browser (converted to MP3 via `ffmpeg-static`). Discord-style **reactions** on both comments *and* uploads (toggle, counters, tooltips, optimistic updates, burst animation), **@mentions** with autocomplete suggestions and profile hover cards — all with **live WebSocket updates**
- **Auth & Rollen:** Session-Cookie-Login (30 Tage), der erste registrierte Nutzer wird automatisch Admin; Admin-Panel mit Rollenverwaltung und **pro Rolle konfigurierbaren Berechtigungen** (`admin.access`, `roles.manage`, `users.manage`, `comment.delete`, `upload.delete`) — die `admin`-Rolle darf immer alles - **Thread subscriptions & notifications:** Creating, commenting, favoriting, or reacting to a thread automatically subscribes you (`thread_subscriptions` table). Can be toggled per thread via a bell button (a disabled subscription stays disabled even on later participation and also suppresses mentions in that thread). Notifications are **grouped per thread** (no spam from multiple comments), there are **no self-notifications**, and the bell shows live events plus toasts
- **Favoriten & Notifications:** Uploads favorisieren, Benachrichtigungs-Glocke mit Live-Events - **Announcement (MOTD):** Admin-editable slim bar below the header (`MotdBanner.vue`), publicly readable and updated live via WebSocket
- **Themes:** 15+ Themes (Standard, Discord, Cyberpunk, Spring, Terminal, Infoseer, Homebrew, Florense, Kawi Green, Clo.nz, Clawmorphism, Realmorphism, Amber, Neo, Neo Pink, Neo Mint), umgeschaltet über `data-theme` auf `<html>`, persistiert per Cookie - **Tags & filters:** Uploads can be tagged; filter popover by **type, uploader, time range, and tag** (URL query–driven)
- **Layouts:** Umschaltbares Bento-/Uniform-Grid für die Upload-Übersicht - **Command palette:** `Ctrl/Cmd + K` opens a global search across uploads/users/actions
- **Favorites:** Favorite uploads, visible on the profile page
- **Auth & roles:** Session-cookie login (30 days); the first registered user automatically becomes admin. **Admin panel** with user list, role management, and **per-role configurable permissions** (`admin.access`, `roles.manage`, `users.manage`, `site.manage`, `comment.delete`, `upload.delete`, `tag.delete`) — the `admin` role is an implicit wildcard and can do everything; `moderator` is a system role with moderation rights
- **Profiles & personalization:** Profile pages with own uploads, comments, and stats; user overview page. In settings: **avatar** (max. 5 MB), **name color**, **card effects** (WebGL shaders via `ogl` — Aurora, Particles, Plasma, Silk, Dither, Scanner and more as hover-card backgrounds), **border effects**, and vignette
- **Themes:** 21 themes (Standard, Discord, Cyberpunk, Spring, Terminal, Infoseer, Homebrew, Florense, Kawi Green, Clo.nz, Clawmorphism, Realmorphism, Amber, Sunny Sprout, Spotify, Nordic Theme, SS, Amethyst Haze, Deep Wine, myClaude, Neo), switched via `data-theme` on `<html>`, persisted via cookie — SSR-safe without flash. The imported TweakCN themes are included as dark variants only
- **Layouts:** Switchable Bento/uniform grid for the upload overview
## Tech-Stack ## Tech stack
| Bereich | Technologie | | Area | Technology |
|---|---| |---|---|
| Framework | Nuxt 4 / Nitro, Vue 3 (`<script setup>` + TS) | | Framework | Nuxt 4 / Nitro, Vue 3 (`<script setup>` + TS) |
| UI | shadcn-vue (`shadcn-nuxt`), Reka UI, Tailwind CSS v4, Lucide-Icons, vue-sonner | | UI | shadcn-vue (`shadcn-nuxt`), Reka UI, Tailwind CSS v4, Phosphor/Simple Icons via `@nuxt/icon` (local SVG bundle mode), vue-sonner |
| Datenbank | MariaDB 11 + Drizzle ORM | | Database | MariaDB 11 + Drizzle ORM (`mysql2`) |
| Realtime | Nitro WebSocket (`crossws`) | | Realtime | Nitro WebSocket (`crossws`) |
| Medien | `@nuxt/image`, Plyr | | Media | `@nuxt/image`, Plyr, `music-metadata`, `ffmpeg-static`, `ogl` (shader effects) |
| State | Nuxt `useState`-Composables, VueUse | | Data/Utils | `@tanstack/vue-table`, Zod, Unovis charts, dnd-kit-vue |
| State | Nuxt `useState` composables, VueUse |
## Projektstruktur ## Project structure
``` ```
app/ app/
assets/css/tailwind.css # Tailwind v4 Entry + alle Theme-Token ([data-theme="…"]) assets/css/tailwind.css # Tailwind v4 entry + all theme tokens ([data-theme="…"])
components/ # App-Komponenten (Header, Dropzone, Tiles, Comments, …) components/ # App components (header, dropzone, tiles, comments,
ui/ # shadcn-vue Basis-Komponenten # MotdBanner, CommandPalette, ThreadSubscriptionButton, …)
composables/ # useAuth, useTheme, useLiveComments, useCommentReactions, … effects/ # WebGL card effects + vignette/border
ui/ # shadcn-vue base components
composables/ # useAuth, useTheme, useCommandPalette, useCommentReactions,
# useNotifications, useCardShader, …
layouts/ middleware/ plugins/ pages/ layouts/ middleware/ plugins/ pages/
index.vue # Upload-Grid / Startseite index.vue # Upload grid with filters / homepage
thread/[id].vue # Thread-Detailseite mit Kommentaren thread/[id].vue # Thread detail page with comments, attachments, voice recording
admin.vue user/[id].vue settings.vue login.vue register.vue admin.vue # Admin panel (users, roles, permissions, MOTD)
settings.vue # Profile settings (avatar, color, card effects)
users.vue user/[id].vue login.vue register.vue
server/ server/
api/ # Nitro-Endpoints (auth, uploads, comments, notifications, admin, …) api/ # Nitro endpoints (auth, uploads, comments, notifications,
db/schema.ts # Drizzle-Schema (users, sessions, uploads, comments, # users, tags, link-preview, motd, admin/…)
# comment_reactions, favorites, link_previews, db/schema.ts # Drizzle schema (users, sessions, uploads, comments,
# notifications, roles, user_roles) # comment_attachments, comment_reactions,
db/migrations/ # Generierte SQL-Migrationen # upload_reactions, favorites, thread_subscriptions,
plugins/migrate.ts # Führt Migrationen beim Server-Start aus (Dev) # link_previews, notifications, roles, user_roles,
routes/_ws.ts # WebSocket-Route für Live-Events # permissions, role_permissions, tags, upload_tags,
utils/ # auth, db, roles, uploads, notifications, linkPreview # settings)
scripts/migrate.ts # Manueller Migrations-Runner (npm run db:migrate) db/migrations/ # Generated SQL migrations
shared/utils/ # Gemeinsame Utilities (Client & Server) plugins/migrate.ts # Runs migrations on server start (dev)
public/uploads/ # Upload-Ziel (gitignored) routes/_ws.ts # WebSocket route for live events (broadcastToAll)
docker-compose.yml # MariaDB-Container utils/ # auth (requirePermission), db, roles, uploads,
# notifications, threadSubscriptions, linkPreview
scripts/migrate.ts # Manual migration runner (npm run db:migrate)
shared/utils/ # Shared utilities — incl. permissions.ts (catalog + seeding)
public/uploads/ # Upload target, incl. uploads/avatars/ (gitignored)
docker-compose.yml # MariaDB container
``` ```
## Setup ## Setup
**Voraussetzungen:** Node.js ≥ 20, Docker (für die mitgelieferte MariaDB) oder eine eigene MySQL/MariaDB-Instanz. **Requirements:** Node.js ≥ 20, Docker (for the bundled MariaDB) or your own MySQL/MariaDB instance.
```bash ```bash
# 1. Datenbank starten # 1. Start the database
docker compose up -d docker compose up -d
# 2. Umgebung konfigurieren # 2. Configure environment
cp .env.example .env # enthält DATABASE_URL, passt zum Docker-Setup cp .env.example .env # contains DATABASE_URL, matches the Docker setup
# 3. Abhängigkeiten installieren # 3. Install dependencies
npm install npm install
# 4. ffmpeg-Binary nachinstallieren (wird für Sprachnachrichten → MP3 gebraucht; # 4. Fetch the ffmpeg binary (needed for voice messages → MP3;
# der Download läuft über das postinstall-Skript von ffmpeg-static, das je # the download runs in ffmpeg-static's postinstall script, which may be
# nach npm-Konfiguration ggf. geblockt ist) # blocked depending on your npm configuration)
node node_modules/ffmpeg-static/install.js node node_modules/ffmpeg-static/install.js
# 5. Dev-Server starten (Migrationen laufen automatisch) # 5. Start the dev server (migrations + permission seeding run automatically)
npm run dev npm run dev
``` ```
Die App läuft auf <http://localhost:3000>. Der **erste registrierte Account erhält automatisch die Admin-Rolle** und kann danach im Admin-Panel weitere Rollen (`moderator`, …) anlegen und vergeben. The app runs on <http://localhost:3000>. The **first registered account automatically gets the admin role** and can then create additional roles, assign permissions, and set the announcement in the admin panel.
### Ohne Docker ### Without Docker
Eigene MariaDB/MySQL-Instanz bereitstellen und `DATABASE_URL` in `.env` anpassen: Provide your own MariaDB/MySQL instance and adjust `DATABASE_URL` in `.env`:
``` ```
DATABASE_URL=mysql://user:pass@host:3306/datenbank DATABASE_URL=mysql://user:pass@host:3306/database
``` ```
## NPM-Scripts ## NPM scripts
| Befehl | Zweck | | Command | Purpose |
|---|---| |---|---|
| `npm run dev` | Dev-Server mit HMR, Auto-Migrationen | | `npm run dev` | Dev server with HMR, auto-migrations |
| `npm run build` | Production-Build | | `npm run build` | Production build |
| `npm run preview` | Build lokal ausführen | | `npm run preview` | Run the built app locally |
| `npm run db:generate` | Neue Drizzle-Migration aus Schema-Änderung erzeugen | | `npm run db:generate` | Generate a new Drizzle migration from a schema change |
| `npm run db:migrate` | Migrationen manuell anwenden | | `npm run db:migrate` | Apply migrations manually |
| `npm run db:studio` | Drizzle Studio (DB-GUI) | | `npm run db:studio` | Drizzle Studio (DB GUI) |
## Entwicklung ## Development
- **Schema ändern:** `server/db/schema.ts` anpassen → `npm run db:generate` → Migration committen. Im Dev-Betrieb wendet `server/plugins/migrate.ts` sie beim Start automatisch an. - **Change the schema:** Edit `server/db/schema.ts` → `npm run db:generate` → commit the migration. In dev mode, `server/plugins/migrate.ts` applies it automatically on start.
- **Neues Theme hinzufügen:** `[data-theme="…"]`-Block mit den CSS-Variablen in `app/assets/css/tailwind.css` anlegen, den Namen in der `ThemeName`-Union in `app/composables/useTheme.ts` ergänzen und einen Eintrag in `app/components/ThemeSelector.vue` hinzufügen. Themes können auch die `shadow-*`-Tokens überschreiben (Glow-, Offset- oder Flach-Schatten) sowie `font-sans`/`font-heading`/`font-mono`; `--font-logo` bleibt bewusst theme-unabhängig. - **Add a new permission:** Add an entry to `PERMISSIONS` in `shared/utils/permissions.ts` → seeded on next start via `seedPermissions()`; check server-side with `requirePermission(event, key)`, client-side with `can(key)` from `useAuth`.
- **Konventionen:** Semantische Tokens statt hartcodierter Farben (`primary`, `accent`, `muted` …), `rounded-md`/`rounded-sm` skalieren über `--radius` mit dem Theme. Details stehen in `AGENTS.md`. - **Live events:** The server broadcasts via `broadcastToAll` in `server/routes/_ws.ts`; the client handles events in `app/plugins/notifications.client.ts`.
- **Health-Check:** `GET /api/health` meldet den DB-Verbindungsstatus. - **Add a new theme:** Create a `[data-theme="…"]` block with the CSS variables in `app/assets/css/tailwind.css`, add the name to `THEME_NAMES` in `app/composables/useTheme.ts`, and add an entry in `app/components/ThemeSelector.vue`. Themes can also override the `shadow-*` tokens (glow, offset, or flat shadows) and `font-sans`/`font-heading`/`font-mono`; `--font-logo` intentionally stays theme-independent.
- **Conventions:** Semantic tokens instead of hardcoded colors (`primary`, `accent`, `muted`, …); `rounded-md`/`rounded-sm` scale via `--radius` with the theme (`neo` is square: `--radius: 0`). More details in `AGENTS.md`.
- **Health check:** `GET /api/health` reports the DB connection status.
-4
View File
@@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<rect width="64" height="64" rx="32" fill="#0f172a"/>
<text x="32" y="41" font-family="ui-sans-serif, system-ui, sans-serif" font-size="22" font-weight="600" text-anchor="middle" fill="#f8fafc">CN</text>
</svg>

Before

Width:  |  Height:  |  Size: 276 B