mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2026-09-03 20:53:09 -05:00
Allow contributors to use the tool they want, reducing coupling with copilot See PeerTube dev position on AI: https://joinpeertube.org/faq#what-is-the-ai-policy-for-peertube-development
241 lines
9.6 KiB
Markdown
241 lines
9.6 KiB
Markdown
# Client — Angular Frontend SPA
|
|
|
|
PeerTube's web client is an Angular single-page application served
|
|
under `/client/`. It communicates with the backend exclusively through
|
|
the REST API (`/api/v1/`). A separate Vite-built embed player lives
|
|
in `src/standalone/` for third-party iframe embedding.
|
|
|
|
## Directory Structure
|
|
|
|
- **src/app/** — Main Angular application
|
|
- `+about/`, `+admin/`, `+home/`, `+login/`, `+signup/`, etc. —
|
|
Lazy-loaded route modules (prefixed with `+`)
|
|
- `core/` — Singleton services: auth, routing, plugins, theme,
|
|
server config, notifications, screen-size helpers
|
|
- `shared/` — Reusable components & directives organized by domain
|
|
(`shared-video/`, `shared-forms/`, `shared-moderation/`, etc.)
|
|
- `header/`, `menu/`, `modal/` — App shell layout components
|
|
- `helpers/` — Client-side utility functions
|
|
- `hotkeys/` — Keyboard shortcut definitions
|
|
- `app.routes.ts` — Top-level route definitions (lazy-loaded)
|
|
- `app.component.ts` — Root component
|
|
- **src/root-helpers/** — Framework-agnostic helpers (logger, storage,
|
|
theme manager, translations, plugin manager) shared between the
|
|
main app and standalone builds
|
|
- **src/standalone/** — Independently built artifacts:
|
|
- `player/` — PeerTube video player (Vite build, HLS.js + P2P)
|
|
- `embed-player-api/` — Public npm package for programmatic
|
|
embed control (`@peertube/embed-api`)
|
|
- `videos/` — Embed page (`embed.html`) and test harness
|
|
- **src/sass/** — Global SCSS: Bootstrap overrides, PrimeNG theme,
|
|
utility classes, z-index scale, fonts
|
|
- **src/locale/** — Angular XLIFF translation files
|
|
- **src/assets/** — Static images and assets
|
|
- **src/environments/** — Angular environment configs
|
|
- **e2e/** — End-to-end tests (WebdriverIO + Mocha)
|
|
- **proxy.config.json** — Dev-server proxy to backend (:9000)
|
|
|
|
## Build & Development Commands
|
|
|
|
All commands run from the **repository root** unless noted.
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Full stack: server (:9000) + Angular dev server (:3000)
|
|
npm run dev
|
|
|
|
# Client only (requires a running backend on :9000)
|
|
npm run dev:client
|
|
|
|
# Embed player only
|
|
npm run dev:embed
|
|
```
|
|
|
|
The Angular dev server proxies `/api`, `/plugins`, `/themes`,
|
|
`/static`, `/lazy-static`, `/socket.io`, and `/client/assets` to the
|
|
backend at `http://127.0.0.1:9000` (see `proxy.config.json`).
|
|
|
|
### Build
|
|
|
|
```bash
|
|
# Full client build (production)
|
|
npm run build:client
|
|
|
|
# Embed player build
|
|
npm run build:embed
|
|
```
|
|
|
|
Output goes to `client/dist/` with per-locale sub-directories
|
|
(e.g. `client/dist/en-US/`, `client/dist/fr-FR/`).
|
|
|
|
### Lint
|
|
|
|
```bash
|
|
# From repository root
|
|
cd client
|
|
|
|
# TypeScript + Angular templates (ESLint)
|
|
npm run lint-ts
|
|
|
|
# SCSS (Stylelint)
|
|
npm run lint-scss
|
|
|
|
# Both
|
|
npm run lint
|
|
```
|
|
|
|
### E2E tests
|
|
|
|
```bash
|
|
# Local browser (from repo root)
|
|
npm run e2e:local
|
|
|
|
# BrowserStack
|
|
npm run e2e:browserstack
|
|
```
|
|
|
|
E2E uses **WebdriverIO** with a **Mocha** framework. Config files are
|
|
in `e2e/` (`wdio.local.conf.ts`, `wdio.browserstack.conf.ts`).
|
|
|
|
## Code Style & Conventions
|
|
|
|
### TypeScript / ESLint
|
|
|
|
The client has its own `eslint.config.mjs` extending
|
|
`eslint-config-love` and `angular-eslint`. Key rules match the
|
|
server:
|
|
|
|
| Rule | Value |
|
|
|---------------------|-----------------------------------|
|
|
| Semicolons | **never** (`@stylistic/semi`) |
|
|
| Max line length | 140 characters |
|
|
| Array brackets | Spaces inside `[ 'a', 'b' ]` |
|
|
| Trailing newline | Required (`eol-last`) |
|
|
| Indentation | 2 spaces |
|
|
|
|
### Angular-specific rules
|
|
|
|
| Rule | Value |
|
|
|------------------------------------------|--------------------------|
|
|
| Component selector prefix | `my-` (kebab-case) |
|
|
| Directive selector prefix | `my` (camelCase) |
|
|
| View encapsulation | Required (enforced) |
|
|
|
|
### SCSS / Stylelint
|
|
|
|
Configured in `.stylelintrc.json`, extends
|
|
`stylelint-config-sass-guidelines` with `stylelint-order`. Key rules:
|
|
|
|
- Declaration order: custom properties → declarations → `@include`
|
|
- Max nesting depth: 8
|
|
- Max compound selectors: 9
|
|
- `::ng-deep` pseudo-element allowed
|
|
|
|
### Naming patterns
|
|
|
|
- Lazy-loaded route folders: `+feature-name/` (e.g. `+admin/`,
|
|
`+video-watch/`)
|
|
- Shared modules: `shared-domain/` (e.g. `shared-video/`,
|
|
`shared-forms/`)
|
|
- Services: PascalCase with `Service` suffix
|
|
(`AuthService`, `ServerService`)
|
|
- Components: PascalCase with `Component` suffix, selector prefixed
|
|
`my-` (`my-video-miniature`)
|
|
- Path aliases: `@app/*` → `src/app/*`,
|
|
`@root-helpers/*` → `src/root-helpers/*`
|
|
|
|
### Internationalization
|
|
|
|
- Source locale: `en` (base href `/client/en-US/`)
|
|
- Translation files: XLIFF format in `src/locale/`
|
|
- Merge tool: `@peertube/xliffmerge` (config: `.xliffmerge.json`)
|
|
- Use Angular `$localize` / `i18n` attributes; do NOT use raw strings
|
|
for user-visible text
|
|
|
|
## Architecture Notes
|
|
|
|
```
|
|
┌────────────────────────────────────────────────────────┐
|
|
│ Angular SPA (client/) │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
|
│ │ Routes │ │ Core │ │ Shared │ │
|
|
│ │ (+about, │ │ (auth, REST, │ │ (forms, video │ │
|
|
│ │ +admin, │──│ plugins, │──│ miniature, │ │
|
|
│ │ +videos) │ │ server, │ │ moderation...) │ │
|
|
│ │ │ │ theme) │ │ │ │
|
|
│ └──────────┘ └──────┬───────┘ └──────────────────┘ │
|
|
│ │ │
|
|
│ ┌─────────────────────▼────────────────────────────┐ │
|
|
│ │ root-helpers (no Angular dep) │ │
|
|
│ │ logger, storage, plugins-manager, theme, i18n │ │
|
|
│ └──────────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────────┐ │
|
|
│ │ standalone/ (Vite builds) │ │
|
|
│ │ player/ │ embed-player-api/ │ videos/embed │ │
|
|
│ └─────────────────────────────────────────────────┘ │
|
|
└────────────────────────┬────────────────────────────────┘
|
|
│ HTTP (REST API)
|
|
▼
|
|
┌──────────────────────┐
|
|
│ Express Backend │
|
|
│ (:9000 /api/v1/*) │
|
|
└──────────────────────┘
|
|
```
|
|
|
|
- **Lazy loading**: Each `+feature/` folder exports route configs
|
|
loaded via `loadChildren` in `app.routes.ts`
|
|
- **Core services**: Singletons bootstrapped in `main.ts` via
|
|
`getCoreProviders()` — auth, REST client, server config polling,
|
|
plugin hooks, theme manager
|
|
- **Plugin hooks**: Client-side plugins register via
|
|
`HooksService` / `PluginService` in `core/plugins/`
|
|
- **State management**: No dedicated store library; services hold
|
|
state, components subscribe via RxJS observables
|
|
- **UI framework**: Bootstrap 5 + PrimeNG + ng-bootstrap;
|
|
global SCSS in `src/sass/`
|
|
- **Video player**: Custom build in `standalone/player/` using
|
|
Video.js + HLS.js + P2P Media Loader; embedded via
|
|
`standalone/videos/embed.html`
|
|
|
|
## Agent Guardrails
|
|
|
|
### Files agents must NOT modify
|
|
|
|
- `src/locale/*.xlf` — Generated translation files; updated via
|
|
`npm run i18n:update` only
|
|
- `dist/` — Build output; never edit manually
|
|
- `node_modules/` — Managed by pnpm
|
|
- `.angular/` — Angular build cache
|
|
|
|
### Required checks before pushing
|
|
|
|
1. `cd client && npm run lint` must pass (TS + SCSS)
|
|
2. Production build must succeed: `npm run build:client`
|
|
(from repo root)
|
|
3. If new user-visible strings added: extract with
|
|
`npm run i18n:create-custom-files` and verify XLIFF
|
|
|
|
### Boundaries
|
|
|
|
- Do not import from `server/` — the client communicates with the
|
|
backend exclusively via the REST API
|
|
- Do not import Angular-specific code in `root-helpers/` or
|
|
`standalone/` — these must remain framework-agnostic
|
|
- Shared API types come from `@peertube/peertube-models` and
|
|
`@peertube/peertube-core-utils` (workspace packages)
|
|
- Do not add new npm dependencies without explicit approval
|
|
|
|
## Further Reading
|
|
|
|
- [../support/doc/plugins/guide.md](../support/doc/plugins/guide.md)
|
|
— Plugin & theme development (client hooks)
|
|
- [src/standalone/embed-player-api/README.md](src/standalone/embed-player-api/README.md)
|
|
— Embed player API documentation
|
|
- [../support/doc/api/embeds.md](../support/doc/api/embeds.md)
|
|
— Embed integration guide
|
|
- [../AGENTS.md](../AGENTS.md)
|
|
— Root project AGENTS.md (server, build, CI, testing)
|