diff --git a/libs/workspace/dashboard/data-access/src/lib/dashboard-data.service.ts b/libs/workspace/dashboard/data-access/src/lib/dashboard-data.service.ts index 33db2fbf8..7754ff143 100644 --- a/libs/workspace/dashboard/data-access/src/lib/dashboard-data.service.ts +++ b/libs/workspace/dashboard/data-access/src/lib/dashboard-data.service.ts @@ -1,4 +1,4 @@ -import { Injectable, computed, inject, signal } from '@angular/core'; +import { Injectable, NgZone, computed, inject, signal } from '@angular/core'; import { Store } from '@ngrx/store'; import { PlaylistActions, @@ -58,6 +58,7 @@ interface DashboardNavigationTarget { export class DashboardDataService { private readonly store = inject(Store); private readonly dbService = inject(DatabaseService); + private readonly ngZone = inject(NgZone); private readonly xtreamGlobalRecentItems = signal([]); private readonly xtreamGlobalFavorites = signal( @@ -133,9 +134,13 @@ export class DashboardDataService { const normalized = recentItems.map((item) => this.mapGlobalRecent(item) ); - this.xtreamGlobalRecentItems.set(normalized); - } catch { - this.xtreamGlobalRecentItems.set([]); + this.ngZone.run(() => this.xtreamGlobalRecentItems.set(normalized)); + } catch (err) { + console.warn( + '[DashboardData] Failed to reload global recent items', + err + ); + this.ngZone.run(() => this.xtreamGlobalRecentItems.set([])); } } @@ -150,9 +155,13 @@ export class DashboardDataService { const normalized = favorites.map((item) => this.mapGlobalFavorite(item) ); - this.xtreamGlobalFavorites.set(normalized); - } catch { - this.xtreamGlobalFavorites.set([]); + this.ngZone.run(() => this.xtreamGlobalFavorites.set(normalized)); + } catch (err) { + console.warn( + '[DashboardData] Failed to reload global favorites', + err + ); + this.ngZone.run(() => this.xtreamGlobalFavorites.set([])); } } diff --git a/libs/workspace/dashboard/data-access/src/lib/dashboard-widget.model.ts b/libs/workspace/dashboard/data-access/src/lib/dashboard-widget.model.ts index 4f1dba321..6f2a0cc12 100644 --- a/libs/workspace/dashboard/data-access/src/lib/dashboard-widget.model.ts +++ b/libs/workspace/dashboard/data-access/src/lib/dashboard-widget.model.ts @@ -1,7 +1,7 @@ export type DashboardWidgetType = - | 'recent-sources' | 'source-stats' | 'continue-watching' + | 'on-air' | 'recently-watched' | 'global-favorites'; @@ -33,7 +33,7 @@ export interface DashboardLayoutState { widgets: DashboardWidgetConfig[]; } -export const DASHBOARD_LAYOUT_VERSION = 6; +export const DASHBOARD_LAYOUT_VERSION = 12; export const DASHBOARD_WIDGET_SIZE_OPTIONS: DashboardWidgetSize[] = [ 'one-third', 'half', @@ -58,22 +58,13 @@ export function createDefaultWidgetScope(): DashboardWidgetScopeSettings { } export const DEFAULT_DASHBOARD_WIDGETS: DashboardWidgetConfig[] = [ - { - id: 'recent-sources', - type: 'recent-sources', - title: 'Recent Sources', - description: 'Latest added or refreshed playlists across providers.', - size: 'half', - enabled: true, - order: 0, - }, { id: 'source-stats', type: 'source-stats', title: 'Source Statistics', description: 'Current source mix and total connected libraries.', size: 'one-third', - enabled: true, + enabled: false, order: 1, }, { @@ -81,10 +72,19 @@ export const DEFAULT_DASHBOARD_WIDGETS: DashboardWidgetConfig[] = [ type: 'continue-watching', title: 'Continue Watching', description: 'Jump back into the last active source.', - size: 'half', + size: 'full', enabled: true, order: 2, }, + { + id: 'on-air', + type: 'on-air', + title: 'On Air Now', + description: 'Live programs currently airing across your EPG channels.', + size: 'full', + enabled: true, + order: 3, + }, { id: 'recently-watched', type: 'recently-watched', @@ -92,7 +92,7 @@ export const DEFAULT_DASHBOARD_WIDGETS: DashboardWidgetConfig[] = [ description: 'Global watch history across channels, VOD and series.', size: 'two-thirds', enabled: true, - order: 3, + order: 4, settings: { scope: createDefaultWidgetScope(), }, @@ -104,7 +104,7 @@ export const DEFAULT_DASHBOARD_WIDGETS: DashboardWidgetConfig[] = [ description: 'Pinned items across all connected providers.', size: 'one-third', enabled: true, - order: 4, + order: 5, settings: { scope: createDefaultWidgetScope(), }, diff --git a/libs/workspace/dashboard/feature/src/lib/workspace-dashboard.component.html b/libs/workspace/dashboard/feature/src/lib/workspace-dashboard.component.html index 809fcaed3..91c1cda63 100644 --- a/libs/workspace/dashboard/feature/src/lib/workspace-dashboard.component.html +++ b/libs/workspace/dashboard/feature/src/lib/workspace-dashboard.component.html @@ -1,43 +1,45 @@
-
-
-

Workspace Dashboard

-

Control Center

-

- Keep your daily sources in one place. In customize mode, edit - directly on the canvas, then use the sidebar for visibility and - scope. -

-
-
-
-

- @if (editMode()) { - Drag cards by the handle. Resize inline. Use the sidebar for - visibility and scope. - } @else { - Start customize mode to rearrange and resize widgets in place. - } -

-
- @if (editMode()) { + @if (editMode()) { +

+ {{ 'WORKSPACE.DASHBOARD.TOOLBAR_HINT_EDITING' | translate }} +

+
- } - +
+ } @else { +

+ {{ 'WORKSPACE.DASHBOARD.TOPBAR_LABEL' | translate }} +

+ -
+ }
drag_indicator -

- {{ widget.title }} -

- - @for ( - size of sizeOptions; - track size.value - ) { - - {{ size.label }} - - } - +
+ + {{ + getSizeLabel(widget.size) + }} + +
@@ -125,10 +141,17 @@ @if (editMode()) {