Zusammenfassung der Änderungen:
1. FluxorComponent als Basisklasse - Dialog reagiert nun auf PersonState-Änderungen
2. Redundante DB-Anfragen vermeiden - LoadPersonsAction wird nur dispatched wenn Persons.Count == 0 && !IsLoading
3. Pre-Selection bei asynchronem Laden - In OnAfterRender wird die Member-Vorauswahl aktualisiert sobald Persons verfügbar sind
Ursache des Problems:
- Der Dialog dispatched LoadPersonsAction bei jedem Öffnen
- DayDetails.razor dispatched gleichzeitig mehrere Actions (LoadAvailablePersonsAction, etc.)
- Viele parallele DB-Requests erschöpfen den Connection Pool
Neue Datei erstellt:
- src/Koogle.Web/Components/Game/PlayerSelectorDialog.razor - Dialog zur manuellen Spielerauswahl
Geändert:
- src/Koogle.Web/Components/Pages/Days/DayDetails.razor:863-891 - ShowPlayerSelector implementiert
Funktionsweise:
1. Bei ParticipantsMode.FreeToChoose zeigt GameInputPanel.razor:23-32 den Button "Spieler wechseln"
2. Der neue Dialog listet alle Spieler aus Participants.PlayerIds
3. Bei DeathBox werden ausgeschiedene Spieler standardmäßig ausgeblendet (Toggle verfügbar)
4. Bei Spielerauswahl wird SetCurrentPlayerAction dispatcht
Features:
- Aktueller Spieler ist markiert (grün)
- Ausgeschiedene Spieler sind durchgestrichen mit "Ausgeschieden"-Badge
- Optional können ausgeschiedene Spieler eingeblendet werden (falls nötig)
- Funktioniert mit allen Game-Typen (DeathBox, Shit, Training)
Summary of Changes:
Phase 1-3 (Domain/Infrastructure/Application):
- ThrowEventType enum with Strike, Circle, Bell, Gutter flags
- ClubGif, ClubGifRating, GifSubmissionToken entities
- EF configurations with proper indexes
- ClubGifRepository with weighted random selection
- MediaStorageService for file storage (wwwroot/club-media/{LoginName}/gifs/)
- ClubGifService with rating system and auto-disable at -5 threshold
Phase 4-5 (Admin UI & Playback):
- Admin page at /club/{ClubId}/admin/gifs with Upload, Import, Edit, Token management
- QR code generation for submission tokens
- GifPlayer component with overlay, rating buttons, and dismiss
- Fluxor state management (GifState, actions, reducers, effects)
Phase 6 (Anonymous Submission):
- Public page at /gif/submit/{Token} with EmptyLayout
- Token validation and file upload
Phase 7 (Game Integration + Migration):
- Database migration AddClubGifFeature applied
- GameEffects.TriggerGifForEventsAsync triggers GIFs on special throws
- SignalR broadcast via BroadcastGifTriggeredAsync to all clients
- DayDetails.razor includes GifPlayer and handles SignalR GIF events
Key Features:
- GIFs play on Strike (alle 9), Circle (Kranz), Bell (Glocke), Gutter (Rinne)
- Weighted random selection based on ratings
- Real-time sync across all connected clients via SignalR
- Thumbs up/down rating with auto-disable at -5
- Max file size: 20MB, Video duration: 15s
- Supports GIF, MP4, WebM formats
- GameBoardPanel: Dynamic board component rendering
- CompletedGamesList: Shows game history for day
- DayDetails: 3 tabs (Details/Eingabe/Tafel) + Start/End Game buttons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extend DayState with SelectedDayExpenses, AvailableExpenses
- Add Fluxor actions for load/create/update/delete expenses
- Add reducers + effects for PersonExpense operations
- Create AddPersonExpenseDialog with inverse expense support
- Update DayDetails with expense table, summary, status toggle
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>