done i18n

This commit is contained in:
2026-03-06 18:46:21 +00:00
parent 3c24da4af8
commit edc1a33547
44 changed files with 2289 additions and 2390 deletions

219
CLAUDE.md
View File

@@ -2,197 +2,82 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
## Project overview
Holistream is a Vue 3 streaming application with Server-Side Rendering (SSR) deployed on Cloudflare Workers. It provides video upload, management, and streaming capabilities.
`stream-ui` is a Vue 3 SSR frontend deployed on Cloudflare Workers. It uses Hono as the Worker server layer and a custom Vite SSR setup rather than Nuxt.
## Technology Stack
## Common commands
- **Framework**: Vue 3 with JSX/TSX support
- **Router**: Vue Router 5 with SSR-aware history
- **Server**: Hono framework on Cloudflare Workers
- **Build Tool**: Vite 7 with custom SSR plugin
- **Styling**: UnoCSS (Tailwind-like utility-first CSS)
- **UI Components**: PrimeVue 4 with Aura theme
- **State Management**: Pinia + Pinia Colada for server state
- **HTTP Client**: Auto-generated from OpenAPI spec via swagger-typescript-api
- **Package Manager**: Bun
## Common Commands
Run all commands from `stream-ui/`.
```bash
# Development server with hot reload
bun dev
# Install dependencies
bun install
# Production build (client + worker)
# Start local dev server
bun run dev
# Build client + worker bundles
bun run build
# Preview production build locally
bun preview
bun run preview
# Deploy to Cloudflare Workers
bun run deploy
# Generate TypeScript types from Wrangler config
# Regenerate Cloudflare binding types from Wrangler config
bun run cf-typegen
# View Cloudflare Worker logs
# Tail Cloudflare Worker logs
bun run tail
```
**Note**: The project uses Bun as the package manager. If using npm/yarn, replace `bun` with `npm run` or `yarn`.
Notes:
- This project uses Bun (`bun.lock` is present).
- There is currently no configured `test` script.
- There is currently no configured `lint` script.
## Architecture
### SSR Architecture
### SSR entrypoints
- `src/index.tsx`: Hono Worker entry; registers middleware, proxy routes, merge/display/manifest routes, then SSR routes
- `src/main.ts`: shared app factory for SSR and client hydration
- `src/client.ts`: client-side hydration entry
- `ssrPlugin.ts`: custom Vite SSR plugin that builds the client first, injects the Vite manifest, and swaps environment-specific modules
The app uses a custom SSR setup (`ssrPlugin.ts`) that:
- Builds the client bundle FIRST, then the Worker bundle
- Injects the Vite manifest into the server build for asset rendering
- Uses environment-based module resolution for `httpClientAdapter` and `liteMqtt`
### Routing and app structure
- Routes live in `src/routes/index.ts`.
- Routing is SSR-aware: `createMemoryHistory()` on the server and `createWebHistory()` in the browser.
- The app is split into:
- public pages
- auth pages
- protected dashboard/settings pages
- Current protected areas include `videos`, `notification`, and `settings/*` routes.
Entry points:
- **Server**: `src/index.tsx` - Hono app that renders Vue SSR stream
- **Client**: `src/client.ts` - Hydrates the SSR-rendered app
### State and hydration
- Pinia is used for app state.
- `@pinia/colada` is used for server-state/query hydration.
- SSR serializes Pinia state into `$p` and query cache into `$colada`; `src/client.ts` restores both during hydration.
- `src/stores/auth.ts` owns session state and route guards depend on `auth.user`.
### Module Aliases
### API integration
- `src/api/client.ts` is generated by `swagger-typescript-api`; do not hand-edit generated sections.
- API access should go through the generated client and `@httpClientAdapter`, not raw `fetch`.
- `src/api/httpClientAdapter.server.ts` handles SSR-side API calls by forwarding request headers/cookies and proxying frontend `/r/*` requests to `https://api.pipic.fun`.
- `src/api/httpClientAdapter.client.ts` is the browser-side adapter.
- `@/``src/`
- `@httpClientAdapter``src/api/httpClientAdapter.server.ts` (SSR) or `.client.ts` (browser)
- `@liteMqtt``src/lib/liteMqtt.server.ts` (SSR) or `.ts` (browser)
### Notable flows
- `src/stores/auth.ts` initializes the logged-in user from `/me` and opens an MQTT connection after login.
- `src/composables/useUploadQueue.ts` implements the custom upload queue:
- 90MB chunks
- max 3 parallel uploads
- max 3 retries
- max 5 queued items
- Styling uses UnoCSS (`uno.config.ts`).
### State Management Pattern
## Important notes
Uses **Pinia Colada** for server state with SSR hydration:
- Queries are fetched server-side and serialized to `window.__APP_DATA__`
- Client hydrates the query cache on startup via `hydrateQueryCache()`
- Pinia state is similarly serialized and restored via `PiniaSharedState` plugin
### API Client Architecture
The API client (`src/api/client.ts`) is auto-generated from OpenAPI spec:
- Uses `customFetch` adapter that differs between client/server
- Server adapter (`httpClientAdapter.server.ts`): Forwards cookies via `hono/context-storage`, merges headers, calls `https://api.pipic.fun`
- Client adapter (`httpClientAdapter.client.ts`): Standard fetch with `credentials: "include"`
- API proxy route: `/r/*` paths proxy to `https://api.pipic.fun` via `apiProxyMiddleware`
- Base API URL constant: `baseAPIURL = "https://api.pipic.fun"`
### Routing Structure
Routes are defined in `src/routes/index.ts` with three main layouts:
1. **Public** (`/`): Landing page, terms, privacy
2. **Auth** (`/login`, `/sign-up`, `/forgot`): Authentication pages (redirects if logged in)
3. **Dashboard**: Protected routes requiring auth
- `/overview` - Main dashboard
- `/upload` - Video upload
- `/video` - Video list
- `/video/:id` - Video detail/edit
- `/payments-and-plans` - Billing
- `/notification`, `/profile` - User settings
Route meta supports `@unhead/vue` for SEO: `meta: { head: { title, meta: [...] } }`
### Styling System (UnoCSS)
Configuration in `uno.config.ts`:
- **Presets**: Wind4 (Tailwind), Typography, Attributify, Bootstrap buttons
- **Custom colors**: `primary` (#14a74b), `accent`, `secondary` (#fd7906), `success`, `info`, `warning`, `danger`
- **Shortcuts**: `press-animated` for button press effects
- **Transformers**: `transformerCompileClass` (prefix: `_`), `transformerVariantGroup`
Use `cn()` from `src/lib/utils.ts` for conditional class merging (clsx + tailwind-merge).
### Component Auto-Import
Components in `src/components/` are auto-imported via `unplugin-vue-components`:
- PrimeVue components resolved via `PrimeVueResolver`
- Vue/Pinia/Vue Router APIs auto-imported via `unplugin-auto-import`
### Auth Flow
- `useAuthStore` manages auth state with cookie-based sessions
- `init()` called on every request to fetch current user via `/me` endpoint
- `beforeEach` router guard redirects unauthenticated users from protected routes
- MQTT client connects on user login for real-time notifications
### File Upload Architecture
Upload queue (`src/composables/useUploadQueue.ts`):
- Supports both local files and remote URLs
- Presigned POST URLs fetched from API
- Parallel chunk upload for large files
- Progress tracking with speed calculation
- **Chunk configuration**: 90MB chunks, max 3 parallel uploads, max 3 retries
- **Upload limits**: Max 5 items in queue
- Uses `tmpfiles.org` API for chunk uploads, `/merge` endpoint for finalizing
- Cancel support via XHR abort tracking
### Type Safety
- TypeScript strict mode enabled
- `CloudflareBindings` interface for environment variables (generated via `cf-typegen`)
- API types auto-generated from backend OpenAPI spec
### Environment Variables
Cloudflare Worker bindings (configured in `wrangler.jsonc`):
- No explicit secrets in code - use Wrangler secrets management
- `compatibility_date`: "2025-08-03"
- `compatibility_flags`: ["nodejs_compat"]
## Important File Locations
| Purpose | Path |
|---------|------|
| Server entry | `src/index.tsx` |
| Client entry | `src/client.ts` |
| App factory | `src/main.ts` |
| Router config | `src/routes/index.ts` |
| API client | `src/api/client.ts` |
| Auth store | `src/stores/auth.ts` |
| SSR plugin | `ssrPlugin.ts` |
| UnoCSS config | `uno.config.ts` |
| Wrangler config | `wrangler.jsonc` |
| Vite config | `vite.config.ts` |
## Server Structure
Middleware and routes are organized in `src/server/`:
**Middlewares** (`src/server/middlewares/`):
- `setup.ts` - Global middleware: `contextStorage`, CORS, mobile detection via `is-mobile`
- `apiProxy.ts` - Proxies `/r/*` requests to external API
**Routes** (`src/server/routes/`):
- `ssr.ts` - Handles SSR rendering and state serialization
- `display.ts`, `merge.ts`, `manifest.ts`, `wellKnown.ts` - API endpoints
## Development Notes
- Always use `customFetch` from `@httpClientAdapter` for API calls, never raw fetch
- The `honoContext` is provided to Vue app for accessing request context in components
- MQTT client in `src/lib/liteMqtt.ts` (using `TinyMqttClient`) handles real-time notifications
- Icons are custom Vue components in `src/components/icons/`
- Upload indicator is a global component showing queue status
- Root component uses error boundary wrapper: `withErrorBoundary(RouterView)` in `src/main.ts`
- **Testing & Linting**: There are currently no automated test suites (like Vitest) or linting tools (like ESLint/Prettier) configured.
## Code Organization
### Component Structure
- Keep view components small and focused - extract logical sections into child components
- Page views should compose child components, not contain all logic inline
- Example: `src/routes/settings/Settings.vue` uses child components in `src/routes/settings/components/`
- Components that exceed ~200 lines should be considered for refactoring
- Use `components/` subfolder pattern for page-specific components: `src/routes/{feature}/components/`
### Icons
- **Use custom SVG icon components** from `src/components/icons/` for UI icons (e.g., `Home`, `Video`, `Bell`, `SettingsIcon`)
- Custom icons are Vue components with `filled` prop for active/filled state
- PrimeIcons (`pi pi-*` class) should **only** be used for:
- Button icons in PrimeVue components (e.g., `icon="pi pi-check"`)
- Dialog/action icons where no custom SVG exists
- **Do NOT use** `<i class="pi pi-*">` for navigation icons, action buttons, or UI elements that have custom SVG equivalents
- When adding new icons, create SVG components in `src/components/icons/` following the existing pattern (support `filled` prop)
- Prefer the actual current code over older documentation when they conflict.
- The previous version of this file contained stale route and dependency details; verify against `src/routes/index.ts` and `package.json` before assuming old pages or libraries still exist.
- Any frontend change that affects API contracts should be checked against the backend repo (`../stream.api`) as well.