From 7ee95bf606e369298d5304fadbbe1f5e5084acfc Mon Sep 17 00:00:00 2001 From: 4gray Date: Sun, 11 Jan 2026 17:13:56 +0100 Subject: [PATCH] docs: document xtream store, category management --- CLAUDE.md | 74 ++++++++++++++++++++++++ docs/architecture/category-management.md | 29 ++++++++-- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b885f245b..76d313a0e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -111,6 +111,80 @@ This is an Nx monorepo with the following structure: - Entity adapter pattern for managing playlists collection - Router store integration for route-based state +**XtreamStore Architecture** (Signal Store with Feature Composition): + +The Xtream Codes module uses NgRx Signal Store with a layered architecture: + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ PRESENTATION LAYER │ +│ Components use XtreamStore (facade) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ FACADE LAYER │ +│ XtreamStore │ +│ (Composes feature stores, unified API) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ┌────────────┬────────────┼────────────┬────────────┐ + ▼ ▼ ▼ ▼ ▼ +┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ +│ withPortal│ │withContent │ │withSelection│ │ withSearch │ │ withPlayer │ +└────────────┘ └────────────┘ └────────────┘ └────────────┘ └────────────┘ + │ │ │ + └───────────────────────────┼──────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ DATA SOURCE LAYER │ +│ IXtreamDataSource │ +│ ┌───────────────────┬───────────────────┐ │ +│ ▼ ▼ │ +│ ElectronDataSource PwaDataSource │ +│ (DB-first + API) (API-only) │ +└─────────────────────────────────────────────────────────────────┘ +``` + +File structure: +``` +apps/web/src/app/xtream-tauri/ +├── stores/ +│ ├── features/ +│ │ ├── with-portal.feature.ts # Playlist & portal status +│ │ ├── with-content.feature.ts # Categories & streams +│ │ ├── with-selection.feature.ts # UI selection & pagination +│ │ ├── with-search.feature.ts # Search functionality +│ │ ├── with-epg.feature.ts # EPG data +│ │ ├── with-player.feature.ts # Stream URLs & player +│ │ └── index.ts +│ ├── xtream.store.ts # Facade composing all features +│ └── index.ts +├── services/ +│ ├── xtream-api.service.ts # Xtream Codes API calls +│ ├── xtream-url.service.ts # Stream URL construction +│ └── index.ts +├── data-sources/ +│ ├── xtream-data-source.interface.ts # Abstract interface + types +│ ├── electron-xtream-data-source.ts # DB-first implementation +│ ├── pwa-xtream-data-source.ts # API-only implementation +│ └── index.ts # Factory provider +└── with-favorites.feature.ts # Favorites (existing) +└── with-recent-items.ts # Recently viewed (existing) +``` + +Key patterns: +- **Feature stores**: Each `with*.feature.ts` uses `signalStoreFeature()` for focused functionality +- **Facade pattern**: `XtreamStore` composes all features, maintaining backward compatibility +- **Data source abstraction**: `IXtreamDataSource` interface with environment-specific implementations +- **Factory injection**: `provideXtreamDataSource()` selects Electron or PWA implementation at runtime + +Data strategies by environment: +| Environment | Strategy | +|-------------|----------| +| **Electron** | DB-first: Check DB → fetch API if missing → cache to DB | +| **PWA** | API-only: Always fetch from API, store in memory | + **Routing**: Lazy-loaded routes in `apps/web/src/app/app.routes.ts` - Home/playlists overview: `/` diff --git a/docs/architecture/category-management.md b/docs/architecture/category-management.md index af20001e5..06ed9b54e 100644 --- a/docs/architecture/category-management.md +++ b/docs/architecture/category-management.md @@ -84,10 +84,21 @@ Added `reloadCategories()` method to refresh categories from database after visi ## Behavior Notes - **New categories**: When a playlist is refreshed, new categories from the remote API are added with `hidden = false` (visible by default) -- **Persistence**: Visibility settings survive playlist refresh +- **Persistence**: Visibility settings survive playlist refresh (see below) - **Per-playlist, per-type**: Categories are managed per playlist and per content type (live/movies/series) - **No content deletion**: Hiding a category only affects sidebar visibility; the category and its content remain in the database +### Visibility Preservation During Refresh + +When a user refreshes an Xtream playlist, hidden category preferences are preserved through the following mechanism: + +1. **Before deletion**: The `DB_DELETE_XTREAM_CONTENT` handler extracts and returns the `hidden` status of all categories (keyed by `xtreamId` and `type`) +2. **Temporary storage**: The hidden categories are stored in `localStorage` under key `xtream-restore-{playlistId}` along with favorites and recently viewed data +3. **During re-import**: When categories are saved via `DB_SAVE_CATEGORIES`, the data source checks `localStorage` for saved hidden category xtreamIds +4. **Restoration**: Categories matching the saved xtreamIds are inserted with `hidden = true`, preserving the user's visibility preferences + +This ensures that users don't lose their category visibility customizations when refreshing playlists to get updated content. + ## Files Changed ``` @@ -96,17 +107,23 @@ libs/shared/database/src/lib/ └── connection.ts # Added migration for existing databases apps/electron-backend/src/app/ -├── events/database/category.events.ts # New IPC handlers -└── api/main.preload.ts # Exposed new IPC methods +├── events/database/category.events.ts # IPC handlers (including hidden category restoration) +├── events/database/xtream.events.ts # Returns hidden categories during content deletion +└── api/main.preload.ts # Exposed new IPC methods (with hidden category params) libs/services/src/lib/ -└── database-electron.service.ts # New service methods +└── database-electron.service.ts # Service methods (with hidden category support) + +libs/ui/components/src/lib/recent-playlists/ +└── recent-playlists.component.ts # Stores hidden categories to localStorage on refresh apps/web/src/app/xtream-tauri/ -├── category-management-dialog/ # New dialog component +├── category-management-dialog/ # Dialog component │ ├── category-management-dialog.component.ts │ ├── category-management-dialog.component.html │ └── category-management-dialog.component.scss +├── data-sources/ +│ └── electron-xtream-data-source.ts # Reads/passes hidden categories on save ├── xtream-main-container.component.ts # Added button & dialog ├── xtream-main-container.component.html ├── live-stream-layout/ @@ -118,7 +135,7 @@ apps/web/src/app/xtream-tauri/ apps/web/src/assets/i18n/ └── en.json # Added translation keys -global.d.ts # TypeScript types for new IPC methods +global.d.ts # TypeScript types for IPC methods ``` ## Translation Keys