mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-14 05:06:16 -08:00
fix(ui): keep the auto-refresh badge on playlist rows with one provider icon
Showing one provider icon per row moved the auto-refresh badge into the M3U branches only, so a restored Stalker playlist with a URL and auto-refresh lost it although the URL is still re-fetched. The row now renders one icon container: the provider icon from the shared precedence, then the badge for any row with a URL or a local M3U, exactly the rows that showed it before. The Xtream portal-status dot, used without source health, keeps that corner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
fb293ea23d
commit
0268aa8667
3 files changed
+81
-64
No files matched your search
+49
-52
@@ -19,16 +19,18 @@
|
||||
}
|
||||
<!-- One provider icon per row, by the shared precedence: a restored
|
||||
Stalker or Xtream playlist can also carry a URL. -->
|
||||
@switch (sourceIconKey) {
|
||||
@case ('stalker') {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="'HOME.PLAYLISTS.STALKER_PORTAL' | translate"
|
||||
>{{ sourceIcons.stalker }}</mat-icon
|
||||
>
|
||||
}
|
||||
@case ('xtream') {
|
||||
<div class="icon-container">
|
||||
<div class="icon-container">
|
||||
@switch (sourceIconKey) {
|
||||
@case ('stalker') {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
'HOME.PLAYLISTS.STALKER_PORTAL' | translate
|
||||
"
|
||||
>{{ sourceIcons.stalker }}</mat-icon
|
||||
>
|
||||
}
|
||||
@case ('xtream') {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
@@ -36,50 +38,45 @@
|
||||
"
|
||||
>{{ sourceIcons.xtream }}</mat-icon
|
||||
>
|
||||
@if (!runtime.supportsSourceHealth) {
|
||||
<span
|
||||
class="status-dot"
|
||||
[class]="getStatusClass()"
|
||||
[matTooltip]="'Portal status: ' + portalStatus"
|
||||
[attr.aria-label]="'Portal status: ' + portalStatus"
|
||||
></span>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@case ('m3u-url') {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
('HOME.PLAYLISTS.ADDED_VIA_URL' | translate) +
|
||||
' ' +
|
||||
item.url
|
||||
"
|
||||
>{{ sourceIcons['m3u-url'] }}</mat-icon
|
||||
>
|
||||
}
|
||||
@default {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
'HOME.PLAYLISTS.ADDED_VIA_FILE' | translate
|
||||
"
|
||||
>{{ sourceIcons['m3u-local'] }}</mat-icon
|
||||
>
|
||||
}
|
||||
}
|
||||
@default {
|
||||
<div class="icon-container">
|
||||
@if (sourceIconKey === 'm3u-url') {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
('HOME.PLAYLISTS.ADDED_VIA_URL' | translate) +
|
||||
' ' +
|
||||
item.url
|
||||
"
|
||||
>{{ sourceIcons['m3u-url'] }}</mat-icon
|
||||
>
|
||||
} @else {
|
||||
<mat-icon
|
||||
class="upload-type-icon"
|
||||
[matTooltip]="
|
||||
'HOME.PLAYLISTS.ADDED_VIA_FILE' | translate
|
||||
"
|
||||
>{{ sourceIcons['m3u-local'] }}</mat-icon
|
||||
>
|
||||
}
|
||||
@if (item.autoRefresh) {
|
||||
<mat-icon
|
||||
class="auto-refresh-indicator"
|
||||
[matTooltip]="
|
||||
'HOME.PLAYLISTS.AUTO_REFRESH_ENABLED'
|
||||
| translate
|
||||
"
|
||||
>autorenew</mat-icon
|
||||
>
|
||||
}
|
||||
</div>
|
||||
@if (showsPortalStatusDot) {
|
||||
<span
|
||||
class="status-dot"
|
||||
[class]="getStatusClass()"
|
||||
[matTooltip]="'Portal status: ' + portalStatus"
|
||||
[attr.aria-label]="'Portal status: ' + portalStatus"
|
||||
></span>
|
||||
} @else if (showsAutoRefresh) {
|
||||
<mat-icon
|
||||
class="auto-refresh-indicator"
|
||||
[matTooltip]="
|
||||
'HOME.PLAYLISTS.AUTO_REFRESH_ENABLED' | translate
|
||||
"
|
||||
>autorenew</mat-icon
|
||||
>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="playlist-content">
|
||||
<div class="playlist-title">
|
||||
|
||||
+13
-12
@@ -226,16 +226,15 @@ describe('PlaylistItemComponent', () => {
|
||||
[
|
||||
{ macAddress: '00:1A:79:00:00:01', url: 'http://portal.test' },
|
||||
'cast',
|
||||
true,
|
||||
],
|
||||
[
|
||||
{ serverUrl: 'http://xtream.test', url: 'http://xtream.test' },
|
||||
'cloud',
|
||||
],
|
||||
[{ url: 'http://list.test/playlist.m3u' }, 'link'],
|
||||
[{}, 'description'],
|
||||
[{ macAddress: '00:1A:79:00:00:01' }, 'cast', false],
|
||||
[{ serverUrl: 'http://xtream.test' }, 'cloud', false],
|
||||
[{ url: 'http://list.test/playlist.m3u' }, 'link', true],
|
||||
[{}, 'description', true],
|
||||
])(
|
||||
'shows one provider icon for %o, with the shared precedence',
|
||||
(source, icon) => {
|
||||
'shows one provider icon for %o (%s) and keeps the auto-refresh badge: %s',
|
||||
(source, icon, autoRefreshBadge) => {
|
||||
fixture.destroy();
|
||||
fixture = TestBed.createComponent(PlaylistItemComponent);
|
||||
fixture.componentInstance.item = {
|
||||
@@ -243,18 +242,20 @@ describe('PlaylistItemComponent', () => {
|
||||
_id: 'source',
|
||||
count: 10,
|
||||
importDate: Date.now().toString(),
|
||||
autoRefresh: false,
|
||||
autoRefresh: true,
|
||||
...source,
|
||||
};
|
||||
fixture.detectChanges();
|
||||
|
||||
const row = fixture.nativeElement as HTMLElement;
|
||||
const icons = Array.from(
|
||||
(fixture.nativeElement as HTMLElement).querySelectorAll(
|
||||
'.upload-type-icon'
|
||||
),
|
||||
row.querySelectorAll('.upload-type-icon'),
|
||||
(element) => element.textContent?.trim()
|
||||
);
|
||||
expect(icons).toEqual([icon]);
|
||||
expect(row.querySelector('.auto-refresh-indicator') !== null).toBe(
|
||||
autoRefreshBadge
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
+19
@@ -78,6 +78,25 @@ export class PlaylistItemComponent implements OnInit {
|
||||
get sourceIconKey(): PlaylistSourceIconKey {
|
||||
return resolvePlaylistSourceIconKey(this.item);
|
||||
}
|
||||
|
||||
/** Without source health, Xtream rows badge the portal status instead. */
|
||||
get showsPortalStatusDot(): boolean {
|
||||
return (
|
||||
this.sourceIconKey === 'xtream' &&
|
||||
!this.runtime.supportsSourceHealth
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Auto-refresh re-fetches a URL or a local file, so any row with a URL
|
||||
* keeps the badge, whichever provider icon it shows.
|
||||
*/
|
||||
get showsAutoRefresh(): boolean {
|
||||
return (
|
||||
!!this.item.autoRefresh &&
|
||||
(!!this.item.url || this.sourceIconKey === 'm3u-local')
|
||||
);
|
||||
}
|
||||
private readonly translate = inject(TranslateService);
|
||||
private readonly languageTick = toSignal(
|
||||
this.translate.onLangChange.pipe(startWith(null)),
|
||||
|
||||
Reference in new issue
Block a user