mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-14 21:26:15 -08:00
fix(sources): offer Refresh only when it can run; drag handle never opens
- PlaylistRefreshActionService runs one refresh at a time, but canRefresh checked only the source, so the switcher, the command palette and the dashboard offered a Refresh that refresh() then ignored. canRefresh now applies the same global guard. - In Custom order a click on a row's drag handle bubbled to the row and opened the source; the handle now stops it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ea3dacb052
commit
f48911a889
4 files changed
+31
-2
No files matched your search
@@ -369,6 +369,15 @@ describe('PlaylistRefreshActionService', () => {
|
||||
service.refresh(playlist);
|
||||
expect(service.isSourceBusy('busy')).toBe(true);
|
||||
expect(service.isSourceBusy('other')).toBe(false);
|
||||
// One refresh at a time: no other source is offered meanwhile.
|
||||
const other = createPlaylistMeta({
|
||||
_id: 'other',
|
||||
serverUrl: undefined,
|
||||
username: undefined,
|
||||
password: undefined,
|
||||
url: 'https://source.test/other',
|
||||
});
|
||||
expect(service.canRefresh(other)).toBe(false);
|
||||
// The Sources page and the removal guard see it too.
|
||||
expect(activity.isBusy('busy')).toBe(true);
|
||||
resolve({ _id: 'busy', playlist: { items: [] } } as Playlist);
|
||||
@@ -376,6 +385,7 @@ describe('PlaylistRefreshActionService', () => {
|
||||
await Promise.resolve();
|
||||
expect(service.isSourceBusy('busy')).toBe(false);
|
||||
expect(activity.isBusy('busy')).toBe(false);
|
||||
expect(service.canRefresh(other)).toBe(true);
|
||||
});
|
||||
|
||||
it('passes trusted TLS hosts to URL-backed M3U refreshes', async () => {
|
||||
|
||||
@@ -64,7 +64,13 @@ export class PlaylistRefreshActionService {
|
||||
readonly refreshPreparation = this.refreshPreparationState.asReadonly();
|
||||
|
||||
canRefresh(playlist: PlaylistMeta | null): boolean {
|
||||
if (!playlist || this.activity.isBusy(playlist._id)) {
|
||||
// The same guards as refresh(): one refresh runs at a time, so an
|
||||
// offer made meanwhile would be a silent no-op.
|
||||
if (
|
||||
!playlist ||
|
||||
this.isRefreshing() ||
|
||||
this.activity.isBusy(playlist._id)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,12 @@
|
||||
(keydown)="onRowKeydown($event)"
|
||||
>
|
||||
@if (draggable()) {
|
||||
<mat-icon cdkDragHandle class="source-row__handle" aria-hidden="true"
|
||||
<!-- Grabbing the handle is not opening the source. -->
|
||||
<mat-icon
|
||||
cdkDragHandle
|
||||
class="source-row__handle"
|
||||
aria-hidden="true"
|
||||
(click)="$event.stopPropagation()"
|
||||
>drag_indicator</mat-icon
|
||||
>
|
||||
}
|
||||
|
||||
@@ -169,6 +169,14 @@ describe('SourceRowComponent', () => {
|
||||
expect(opened).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('does not open the source from a click on the drag handle', () => {
|
||||
const element = render(M3U, { draggable: true });
|
||||
const opened = jest.fn();
|
||||
fixture.componentInstance.activated.subscribe(opened);
|
||||
element.querySelector<HTMLElement>('.source-row__handle')?.click();
|
||||
expect(opened).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('refreshes the focused row with R', () => {
|
||||
const element = render(M3U, { canRefresh: true });
|
||||
const refresh = jest.fn();
|
||||
|
||||
Reference in new issue
Block a user