Add CLAUDE.md, use snackbar for WebGPU errors
Add a new CLAUDE.md project guidelines file. Update BabylonCanvas to replace alert() with an Angular Material MatSnackBar and use ngx-translate for a localized WebGPU-not-supported message (injects MatSnackBar and TranslateService and updates imports). Add the corresponding WEBGPU.NOT_SUPPORTED entries to en.json and de.json for localization.
This commit is contained in:
91
CLAUDE.md
Normal file
91
CLAUDE.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
# Claude Code Guidelines
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
This is the frontend of the Playground project, built with Angular 21 and Angular Material. It includes features like a light/dark theme toggle and multi-language support via ngx-translate. The application is a static Single Page Application (SPA) served by NGINX.
|
||||||
|
|
||||||
|
**Key Technologies:**
|
||||||
|
* **Frontend Framework:** Angular 21
|
||||||
|
* **UI Components & Theming:** Angular Material
|
||||||
|
* **Internationalization:** ngx-translate
|
||||||
|
* **Server:** NGINX (for serving the SPA)
|
||||||
|
* **Containerization:** Docker
|
||||||
|
* **CI/CD:** GitHub Actions
|
||||||
|
|
||||||
|
## Building and Running
|
||||||
|
|
||||||
|
### Local Development
|
||||||
|
|
||||||
|
1. **Install dependencies:**
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
2. **Start development server:**
|
||||||
|
```bash
|
||||||
|
ng serve --open
|
||||||
|
```
|
||||||
|
The app will run at `http://localhost:4200`.
|
||||||
|
|
||||||
|
### Building for Production
|
||||||
|
|
||||||
|
To build the project for production, which creates the optimized static files:
|
||||||
|
```bash
|
||||||
|
ng build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Language
|
||||||
|
- All code must be written in **English** — including variable names, function names, comments, and commit messages.
|
||||||
|
|
||||||
|
## Clean Code
|
||||||
|
- Write simple, clear, and readable code.
|
||||||
|
- Avoid deeply nested or chained calls. Break complex expressions into named intermediate variables or separate steps.
|
||||||
|
- Code should be understandable by junior developers without additional explanation.
|
||||||
|
|
||||||
|
## Braces
|
||||||
|
- Always use curly braces `{}` for branches and loops — even for single-line bodies.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// ✅ correct
|
||||||
|
if (isValid) {
|
||||||
|
doSomething();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ❌ avoid
|
||||||
|
if (isValid) doSomething();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
- Extract reusable or logically distinct logic into separate, well-named functions.
|
||||||
|
- A function should do one thing and do it well.
|
||||||
|
- Prefer short functions that are easy to test and understand.
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
- Only add comments when they explain the **why** or the **idea** behind the code — not the **what**.
|
||||||
|
- Do not comment on things that are already obvious from the code itself.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// ✅ useful comment — explains intent
|
||||||
|
// Retry once to handle transient network errors
|
||||||
|
const result = await fetchWithRetry(url);
|
||||||
|
|
||||||
|
// ❌ useless comment — just restates the code
|
||||||
|
// Call fetchWithRetry with url
|
||||||
|
const result = await fetchWithRetry(url);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Conventions
|
||||||
|
|
||||||
|
* **Language:** TypeScript
|
||||||
|
* **Framework:** Angular
|
||||||
|
* **Styling:** SCSS (based on `styles.scss` and component-specific `.scss` files).
|
||||||
|
* **Linting:** ESLint is configured (see `eslint.config.js` and `package.json` scripts).
|
||||||
|
* **Internationalization:** Uses `ngx-translate` with `en.json` and `de.json` asset files.
|
||||||
|
|
||||||
|
## Project Structure (Key Areas)
|
||||||
|
|
||||||
|
* `src/app/`: Contains the main application logic, components, services, and routing.
|
||||||
|
* `src/app/pages/`: Specific pages of the application (e.g., about, algorithms, imprint, projects).
|
||||||
|
* `src/assets/`: Static assets including images, internationalization files (`i18n`), and logos.
|
||||||
|
* `Dockerfile`: Defines the Docker image for the application.
|
||||||
|
* `nginx.conf`: NGINX configuration for serving the SPA.
|
||||||
|
* `.gitea/workflows/`: Contains CI/CD workflows (e.g., `build-Frontend-a.yml`).
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import {AfterViewInit, Component, ElementRef, EventEmitter, inject, Input, NgZone, OnDestroy, Output, ViewChild} from '@angular/core';
|
import {AfterViewInit, Component, ElementRef, EventEmitter, inject, Input, NgZone, OnDestroy, Output, ViewChild} from '@angular/core';
|
||||||
|
import {MatSnackBar} from '@angular/material/snack-bar';
|
||||||
|
import {TranslateService} from '@ngx-translate/core';
|
||||||
import {ArcRotateCamera, Camera, MeshBuilder, Scene, ShaderLanguage, ShaderMaterial, Vector2, Vector3, WebGPUEngine} from '@babylonjs/core';
|
import {ArcRotateCamera, Camera, MeshBuilder, Scene, ShaderLanguage, ShaderMaterial, Vector2, Vector3, WebGPUEngine} from '@babylonjs/core';
|
||||||
|
|
||||||
export interface RenderConfig {
|
export interface RenderConfig {
|
||||||
@@ -26,6 +28,8 @@ export interface SceneEventData {
|
|||||||
})
|
})
|
||||||
export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
||||||
readonly ngZone = inject(NgZone);
|
readonly ngZone = inject(NgZone);
|
||||||
|
private readonly snackBar = inject(MatSnackBar);
|
||||||
|
private readonly translate = inject(TranslateService);
|
||||||
|
|
||||||
@ViewChild('renderCanvas', { static: true }) canvasRef!: ElementRef<HTMLCanvasElement>;
|
@ViewChild('renderCanvas', { static: true }) canvasRef!: ElementRef<HTMLCanvasElement>;
|
||||||
|
|
||||||
@@ -72,9 +76,11 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy {
|
|||||||
engine: this.engine
|
engine: this.engine
|
||||||
});
|
});
|
||||||
this.addRenderLoop(canvas);
|
this.addRenderLoop(canvas);
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
alert("WebGPU could not be started. Please check your browser if it supports WebGPU.");
|
const message = this.translate.instant('WEBGPU.NOT_SUPPORTED');
|
||||||
|
this.snackBar.open(message, 'OK', { duration: 8000, horizontalPosition: "center", verticalPosition: "top" });
|
||||||
this.engine = null!;
|
this.engine = null!;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -500,6 +500,9 @@
|
|||||||
"DISCLAIMER_4": "Der XPBD-Kompromiss: XPBD umgeht dieses komplexe Matrix-Problem völlig, indem es als lokaler Löser arbeitet. Es kombiniert die unbedingte Stabilität eines impliziten Lösers mit der enormen Geschwindigkeit, Parallelisierbarkeit und dynamischen Anpassungsfähigkeit eines expliziten Systems."
|
"DISCLAIMER_4": "Der XPBD-Kompromiss: XPBD umgeht dieses komplexe Matrix-Problem völlig, indem es als lokaler Löser arbeitet. Es kombiniert die unbedingte Stabilität eines impliziten Lösers mit der enormen Geschwindigkeit, Parallelisierbarkeit und dynamischen Anpassungsfähigkeit eines expliziten Systems."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WEBGPU": {
|
||||||
|
"NOT_SUPPORTED": "WebGPU konnte nicht gestartet werden. Bitte prüfe, ob dein Browser WebGPU unterstützt."
|
||||||
|
},
|
||||||
"ALGORITHM": {
|
"ALGORITHM": {
|
||||||
"TITLE": "Algorithmen",
|
"TITLE": "Algorithmen",
|
||||||
"PATHFINDING": {
|
"PATHFINDING": {
|
||||||
|
|||||||
@@ -499,6 +499,9 @@
|
|||||||
"DISCLAIMER_4": "The XPBD Compromise: XPBD completely bypasses this complex matrix problem by acting as a local solver. It combines the absolute stability of an implicit solver with the enormous speed, parallelizability, and dynamic adaptability of an explicit system."
|
"DISCLAIMER_4": "The XPBD Compromise: XPBD completely bypasses this complex matrix problem by acting as a local solver. It combines the absolute stability of an implicit solver with the enormous speed, parallelizability, and dynamic adaptability of an explicit system."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"WEBGPU": {
|
||||||
|
"NOT_SUPPORTED": "WebGPU could not be started. Please check if your browser supports WebGPU."
|
||||||
|
},
|
||||||
"ALGORITHM": {
|
"ALGORITHM": {
|
||||||
"TITLE": "Algorithms",
|
"TITLE": "Algorithms",
|
||||||
"PATHFINDING": {
|
"PATHFINDING": {
|
||||||
|
|||||||
Reference in New Issue
Block a user