docs: keyvisual/background/nametag features
This commit is contained in:
parent
c544f1db60
commit
ec275ec026
96
AGENTS.md
96
AGENTS.md
|
|
@ -140,6 +140,92 @@ ### Maintenance note
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## KeyVisual & Background
|
||||||
|
|
||||||
|
Each service export can carry a key-visual image (shown as a standalone fallback slide) and a background image (rendered as a media layer behind every song/sermon slide).
|
||||||
|
|
||||||
|
Resolution is lazy and happens at export time:
|
||||||
|
|
||||||
|
1. Per-service column (`key_visual_filename` / `background_filename` on the `services` table)
|
||||||
|
2. Global default from Settings (`current_key_visual` / `current_background`)
|
||||||
|
3. None (slide omitted / no background layer)
|
||||||
|
|
||||||
|
When a service is finalized, the resolved filenames are snapshotted into the per-service columns so the export is stable even if the global default changes later.
|
||||||
|
|
||||||
|
### Key files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `app/Services/ServiceImageResolver.php` | Lazy resolution: per-service column → global Setting → null |
|
||||||
|
| `app/Http/Controllers/ServiceImageController.php` | `POST /services/{service}/key-visual` + `POST /services/{service}/background`; scope dialog ("Nur für diesen Service" / "Als Standard setzen") |
|
||||||
|
| `app/Services/FileConversionService.php` | Added `convertImageCover()` for COVER-mode 1920×1080 conversion |
|
||||||
|
| `app/Services/PlaylistExportService.php` | Injects keyvisual fallback slides and sermon sequence (keyvisual → nametag → slides) |
|
||||||
|
| `app/Services/ProExportService.php` | Adds background media layer on song/sermon slides |
|
||||||
|
| `resources/js/Components/ServiceImagePanel.vue` | Upload panel with scope dialog; used on the service Edit page |
|
||||||
|
| `resources/js/Pages/Services/Edit.vue` | Image panels rendered at the top of the edit form |
|
||||||
|
| `resources/js/Pages/Settings.vue` | Global default key-visual and background fields |
|
||||||
|
|
||||||
|
### Settings keys
|
||||||
|
|
||||||
|
| Key | Purpose |
|
||||||
|
|-----|---------|
|
||||||
|
| `current_key_visual` | Global default key-visual filename |
|
||||||
|
| `current_background` | Global default background filename |
|
||||||
|
|
||||||
|
### Routes
|
||||||
|
|
||||||
|
| Method | Route | Name |
|
||||||
|
|--------|-------|------|
|
||||||
|
| POST | `/services/{service}/key-visual` | `services.key-visual.store` |
|
||||||
|
| POST | `/services/{service}/background` | `services.background.store` |
|
||||||
|
|
||||||
|
### Parser package changes (commit `582ef85`)
|
||||||
|
|
||||||
|
- New `slideData['background']` contract: background-layer media action on any slide
|
||||||
|
- New `slideData['imageOnly']` flag: image-only slide (no text layer)
|
||||||
|
- New Slide read accessors: `hasBackgroundMedia()`, `getBackgroundMediaUrl()`, `getBackgroundMediaFormat()`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## NameTag (Namenseinblender)
|
||||||
|
|
||||||
|
A name-tag slide is injected into the sermon sequence (between the key-visual and the sermon slides) to display the moderator and/or preacher name on screen.
|
||||||
|
|
||||||
|
The slide is only generated when the Namenseinblender macro is fully configured in Settings. It renders plain white text and optionally triggers a ProPresenter macro.
|
||||||
|
|
||||||
|
### Name resolution order
|
||||||
|
|
||||||
|
1. `moderator_name` / `preacher_name_override` columns on the `services` table (manual override set via Edit form)
|
||||||
|
2. Responsible person from the CTS `responsible` JSON field matching the configured role
|
||||||
|
3. None (slide omitted)
|
||||||
|
|
||||||
|
### Key files
|
||||||
|
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `app/Services/NameTagResolver.php` | Resolves moderator/preacher name: responsible JSON → CTS role → manual override |
|
||||||
|
| `app/Services/NameTagSlideBuilder.php` | Builds `slideData` for the nametag slide (plain white text + optional macro) |
|
||||||
|
| `app/Http/Controllers/ServiceController.php` | `PATCH /services/{service}/name-overrides` — saves manual name overrides |
|
||||||
|
| `resources/js/Pages/Services/Edit.vue` | Name override input fields in the edit form |
|
||||||
|
| `resources/js/Pages/Settings.vue` | Namenseinblender submenu with macro name/UUID/collection fields |
|
||||||
|
|
||||||
|
### Settings keys
|
||||||
|
|
||||||
|
| Key | Purpose |
|
||||||
|
|-----|---------|
|
||||||
|
| `namenseinblender_macro_name` | ProPresenter macro name |
|
||||||
|
| `namenseinblender_macro_uuid` | ProPresenter macro UUID |
|
||||||
|
| `namenseinblender_macro_collection_name` | Macro collection name |
|
||||||
|
| `namenseinblender_macro_collection_uuid` | Macro collection UUID |
|
||||||
|
|
||||||
|
### Routes
|
||||||
|
|
||||||
|
| Method | Route | Name |
|
||||||
|
|--------|-------|------|
|
||||||
|
| PATCH | `/services/{service}/name-overrides` | `services.name-overrides.update` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Repository Structure
|
## Repository Structure
|
||||||
|
|
||||||
Two git repositories, both local (no remote):
|
Two git repositories, both local (no remote):
|
||||||
|
|
@ -147,9 +233,9 @@ ## Repository Structure
|
||||||
| Repo | Path | Branch | Purpose |
|
| Repo | Path | Branch | Purpose |
|
||||||
|------|------|--------|---------|
|
|------|------|--------|---------|
|
||||||
| **pp-planer** | `/Users/thorsten/AI/pp-planer` | `cts-presenter-app` | Laravel app (main codebase) |
|
| **pp-planer** | `/Users/thorsten/AI/pp-planer` | `cts-presenter-app` | Laravel app (main codebase) |
|
||||||
| **propresenter-work** | `/Users/thorsten/AI/propresenter-work/php` | `propresenter-parser` | ProPresenter .pro/.proplaylist parser (composer path dependency) |
|
| **propresenter** | `/Users/thorsten/AI/propresenter` | `propresenter-parser` | ProPresenter .pro/.proplaylist parser (composer path dependency) |
|
||||||
|
|
||||||
The parser is linked via `composer.json` path repository: `"url": "../propresenter-work/php"`.
|
The parser is linked via `composer.json` path repository: `"url": "../propresenter"`.
|
||||||
|
|
||||||
## Build, Test, Lint Commands
|
## Build, Test, Lint Commands
|
||||||
|
|
||||||
|
|
@ -200,10 +286,10 @@ # Migrations
|
||||||
ddev exec php artisan migrate
|
ddev exec php artisan migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
### propresenter-work (Parser Module)
|
### propresenter (Parser Module)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /Users/thorsten/AI/propresenter-work/php
|
cd /Users/thorsten/AI/propresenter
|
||||||
|
|
||||||
# Run all tests (230 tests)
|
# Run all tests (230 tests)
|
||||||
./vendor/bin/phpunit
|
./vendor/bin/phpunit
|
||||||
|
|
@ -228,7 +314,7 @@ ## Architecture
|
||||||
tests/Feature/ # Pest v4 / PHPUnit feature tests
|
tests/Feature/ # Pest v4 / PHPUnit feature tests
|
||||||
tests/e2e/ # Playwright browser tests (TypeScript)
|
tests/e2e/ # Playwright browser tests (TypeScript)
|
||||||
|
|
||||||
propresenter-work/php/
|
propresenter/
|
||||||
src/ # ProFileReader, ProFileGenerator, ProPlaylistGenerator, Song, Group, Slide, Arrangement
|
src/ # ProFileReader, ProFileGenerator, ProPlaylistGenerator, Song, Group, Slide, Arrangement
|
||||||
tests/ # PHPUnit 11 tests with #[Test] attributes
|
tests/ # PHPUnit 11 tests with #[Test] attributes
|
||||||
ref/ # .pro fixture files for testing
|
ref/ # .pro fixture files for testing
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue