From 6eb602d332d2afb55c44af88a8d8107805c239fb Mon Sep 17 00:00:00 2001 From: 4gray Date: Sat, 25 Apr 2026 22:14:20 +0200 Subject: [PATCH] feat(playlist-switcher): add refresh button for active playlist with spinning icon Entire-Checkpoint: c6e522b4276c --- .../playlist-switcher.component.html | 20 ++++++ .../playlist-switcher.component.scss | 61 ++++++++++++++++++- .../playlist-switcher.component.ts | 11 ++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.html b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.html index 9a2ac4f32..3e70348aa 100644 --- a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.html +++ b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.html @@ -16,6 +16,26 @@
{{ displayTitle() }}
{{ subtitle() }}
+ @if (canRefreshActivePlaylist()) { + + } expand_more diff --git a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.scss b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.scss index 09211ff0f..c09cf72e5 100644 --- a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.scss +++ b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.scss @@ -93,13 +93,71 @@ } } +.trigger-refresh-button { + margin-left: auto; + width: 32px; + height: 32px; + min-width: 32px; + min-height: 32px; + padding: 0; + line-height: 32px; + flex-shrink: 0; + display: inline-flex; + align-items: center; + justify-content: center; + color: var(--mat-sys-on-surface-variant); + transition: + color 0.15s ease, + background 0.15s ease; + + &:hover:not(:disabled) { + color: var(--mat-sys-on-surface); + background: var(--mat-sys-surface-container); + } + + ::ng-deep .mat-mdc-button-touch-target { + width: 32px; + height: 32px; + } + + ::ng-deep .mat-mdc-button-persistent-ripple, + ::ng-deep .mat-mdc-focus-indicator { + border-radius: 50%; + } +} + +.trigger-refresh-icon { + font-size: 18px; + width: 18px; + height: 18px; + line-height: 18px; + margin: 0; + padding: 0; + display: inline-flex; + align-items: center; + justify-content: center; + + &.is-spinning { + animation: switcher-refresh-spin 1s linear infinite; + } +} + +@keyframes switcher-refresh-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + .dropdown-icon { font-size: 20px; width: 20px; height: 20px; color: var(--mat-sys-on-surface-variant); transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); - margin-left: auto; + margin-left: 4px; &.rotated { transform: rotate(180deg); @@ -169,6 +227,7 @@ line-height: 30px; color: var(--mat-sys-on-surface-variant); opacity: 0.8; + padding: 0; &:hover, &.is-active { diff --git a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.ts b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.ts index 8730b4a91..ab6a189c1 100644 --- a/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.ts +++ b/libs/playlist/shared/ui/src/lib/playlist-switcher/playlist-switcher.component.ts @@ -20,6 +20,7 @@ import { MatIcon } from '@angular/material/icon'; import { MatInputModule } from '@angular/material/input'; import { MatMenu, MatMenuModule, MatMenuTrigger } from '@angular/material/menu'; import { MatSnackBar } from '@angular/material/snack-bar'; +import { MatTooltip } from '@angular/material/tooltip'; import { Store } from '@ngrx/store'; import { normalizeDateLocale } from '@iptvnator/pipes'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; @@ -61,6 +62,7 @@ const DEFAULT_PLAYLIST_TYPE_FILTERS: Record = { MatInputModule, MatMenuModule, MatRippleModule, + MatTooltip, TranslatePipe, ], }) @@ -87,10 +89,19 @@ export class PlaylistSwitcherComponent { readonly showPlaylistInfo = input(false); readonly showAccountInfo = input(false); readonly showAddPlaylist = input(false); + readonly canRefreshActivePlaylist = input(false); + readonly isRefreshingActivePlaylist = input(false); readonly playlistSelected = output(); readonly playlistInfoRequested = output(); readonly accountInfoRequested = output(); readonly addPlaylistRequested = output(); + readonly refreshPlaylistRequested = output(); + + onRefreshClick(event: Event): void { + event.stopPropagation(); + event.preventDefault(); + this.refreshPlaylistRequested.emit(); + } readonly menuTrigger = viewChild.required('menuTrigger'); readonly playlistMenu = viewChild.required('playlistMenu');