From 94a07564244235aa67d79ae41f1cfc459a71f108 Mon Sep 17 00:00:00 2001 From: 4gray Date: Fri, 1 May 2026 23:43:36 +0200 Subject: [PATCH] fix(ui): unify the three side-by-side empty states in m3u groups view Three placeholders were rendering at once when a search filter cleared both the groups rail and the channel list, and they each used a different visual treatment: 1. Groups rail (.groups-nav-empty) was bare 0.82rem muted text with no icon and no hint, and routed through CHANNELS.NO_SEARCH_RESULTS ("No channels found") which is wrong copy for the *groups* column. 2. Channel list (.groups-content-empty-state) was the canonical L4 icon + title + hint pattern (correct). 3. Player area () was a 72px icon at 0.2 opacity, which read as ghosted on dark theme. Bring the groups rail into the L4 family scaled down for the narrow column: 28px search_off / folder_off icon at 0.5 opacity, 0.85rem title, 0.78rem hint at 0.65 opacity, centered. Add a CHANNELS.NO_GROUPS_FOUND i18n key so the copy reflects the column ("No groups found"). Bump portal-empty-state's icon opacity from 0.2 -> 0.35 and title opacity from 0.5 -> 0.6 so the player-area placeholder feels present rather than abandoned. Co-Authored-By: Claude Opus 4.7 (1M context) Entire-Checkpoint: 6719280e397b --- apps/web/src/assets/i18n/en.json | 1 + .../portal-empty-state.component.scss | 4 +-- .../groups-view/groups-view.component.html | 26 ++++++++++++---- .../groups-view/groups-view.component.scss | 31 +++++++++++++++++-- 4 files changed, 51 insertions(+), 11 deletions(-) diff --git a/apps/web/src/assets/i18n/en.json b/apps/web/src/assets/i18n/en.json index 5c0e1006b..e3514f0c1 100644 --- a/apps/web/src/assets/i18n/en.json +++ b/apps/web/src/assets/i18n/en.json @@ -377,6 +377,7 @@ "LOADING_MORE": "Loading more...", "NO_SEARCH_RESULTS": "No channels found", "NO_CHANNELS_FOUND": "No channels found", + "NO_GROUPS_FOUND": "No groups found", "TRY_DIFFERENT_SEARCH": "Try a different search term", "DETAILS_DIALOG": { "TITLE": "Channel details", diff --git a/libs/portal/shared/ui/src/lib/components/portal-empty-state/portal-empty-state.component.scss b/libs/portal/shared/ui/src/lib/components/portal-empty-state/portal-empty-state.component.scss index 2a57f575b..787f2f427 100644 --- a/libs/portal/shared/ui/src/lib/components/portal-empty-state/portal-empty-state.component.scss +++ b/libs/portal/shared/ui/src/lib/components/portal-empty-state/portal-empty-state.component.scss @@ -21,7 +21,7 @@ width: 72px; height: 72px; margin-bottom: 24px; - opacity: 0.2; + opacity: 0.35; animation: portal-empty-state-float 2.8s ease-in-out infinite; } @@ -30,7 +30,7 @@ font-weight: 520; letter-spacing: -0.01em; margin: 0; - opacity: 0.5; + opacity: 0.6; } @keyframes portal-empty-state-fade-in { diff --git a/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.html b/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.html index f3a820742..ca3ceff9d 100644 --- a/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.html +++ b/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.html @@ -137,12 +137,26 @@ } } @else {
- {{ - (hasSearchQuery() - ? 'CHANNELS.NO_SEARCH_RESULTS' - : 'CHANNELS.NO_VISIBLE_GROUPS' - ) | translate - }} + + {{ + hasSearchQuery() ? 'search_off' : 'folder_off' + }} + +
+ {{ + (hasSearchQuery() + ? 'CHANNELS.NO_GROUPS_FOUND' + : 'CHANNELS.NO_VISIBLE_GROUPS' + ) | translate + }} +
+ @if (hasSearchQuery()) { +
+ {{ + 'CHANNELS.TRY_DIFFERENT_SEARCH' | translate + }} +
+ }
} diff --git a/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.scss b/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.scss index 4c4623c15..0847d0673 100644 --- a/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.scss +++ b/libs/ui/components/src/lib/channel-list-container/groups-view/groups-view.component.scss @@ -183,10 +183,35 @@ } .groups-nav-empty { - padding: 16px 12px; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + padding: 24px 12px; color: var(--app-muted-color, var(--mat-sys-on-surface-variant)); - font-size: 0.82rem; - line-height: 1.4; + + &__icon { + width: 28px; + height: 28px; + font-size: 28px; + opacity: 0.5; + margin-bottom: 10px; + } + + &__title { + font-size: 0.85rem; + font-weight: 520; + letter-spacing: -0.01em; + margin-bottom: 4px; + text-wrap: balance; + } + + &__hint { + font-size: 0.78rem; + line-height: 1.4; + opacity: 0.65; + text-wrap: pretty; + } } .group-nav-item {