mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(settings): close the M3U group editor on any relock
The group management dialog lists every group name, locked ones included, even when it opened without lock toggles (unreadable lock store). It now closes on any relock, and the groups view re-checks the lock state before opening it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b078526bef
commit
0f5276c581
5 files changed
+38
-6
No files matched your search
@@ -386,7 +386,9 @@ so a cancelled or refused PIN leaves it showing the real state.
|
||||
read (`ensureLocksReadable`): a draft taken from the empty fail-closed
|
||||
snapshot would erase the real locks on Save if storage recovered in
|
||||
between. The M3U and Xtream dialogs then open without lock toggles; the
|
||||
Stalker dialog does not open. Bulk actions stay in the dialog, and while the session is locked
|
||||
Stalker dialog does not open. Every one of them closes on a relock, the
|
||||
M3U one also when it opened without toggles, since it still lists every
|
||||
group name. Bulk actions stay in the dialog, and while the session is locked
|
||||
a locked category is not in the rail, so unlocking always goes through
|
||||
the "N locked · Enter PIN to show" row or the dialog. The M3U dialog
|
||||
hands its lock list back to `ChannelListContainerComponent`, which
|
||||
|
||||
+11
-3
@@ -55,13 +55,21 @@ describe('GroupManagementDialogComponent', () => {
|
||||
expect(dialogRef.close).toHaveBeenCalledWith(undefined);
|
||||
});
|
||||
|
||||
it('keeps the plain hide/show editor open when the lock feature is off', async () => {
|
||||
it('keeps the plain hide/show editor open while nothing relocks', async () => {
|
||||
const fixture = await create({ groups, hiddenGroupTitles: ['News'] });
|
||||
|
||||
parentalLock.active.set(true);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dialogRef.close).not.toHaveBeenCalled();
|
||||
expect(fixture.componentInstance.showLocks).toBe(false);
|
||||
});
|
||||
|
||||
it('closes the editor without lock toggles too on a relock: it lists every group', async () => {
|
||||
// Opened without toggles because the lock store was unreadable.
|
||||
const fixture = await create({ groups, hiddenGroupTitles: ['News'] });
|
||||
|
||||
parentalLock.active.set(true);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(dialogRef.close).toHaveBeenCalledWith(undefined);
|
||||
});
|
||||
});
|
||||
+3
-2
@@ -105,9 +105,10 @@ export class GroupManagementDialogComponent {
|
||||
|
||||
constructor() {
|
||||
// A relock while the editor is open: the locked group names it
|
||||
// lists and the lock list it can rewrite are behind the PIN.
|
||||
// lists (with or without lock toggles — every group is listed) and
|
||||
// the lock list it can rewrite are behind the PIN.
|
||||
effect(() => {
|
||||
if (this.showLocks && this.parentalLock.active()) {
|
||||
if (this.parentalLock.active()) {
|
||||
this.dialogRef.close(undefined);
|
||||
}
|
||||
});
|
||||
|
||||
+16
@@ -51,6 +51,7 @@ describe('GroupsViewComponent', () => {
|
||||
requestUnlock: jest.Mock;
|
||||
ensureLocksReadable: jest.Mock;
|
||||
lockedGroupTitles: jest.Mock;
|
||||
active: jest.Mock;
|
||||
};
|
||||
|
||||
const sportsCenter = createChannel(
|
||||
@@ -112,6 +113,7 @@ describe('GroupsViewComponent', () => {
|
||||
requestUnlock: jest.fn().mockResolvedValue(true),
|
||||
ensureLocksReadable: jest.fn().mockResolvedValue(true),
|
||||
lockedGroupTitles: jest.fn(() => ['News']),
|
||||
active: jest.fn(() => false),
|
||||
};
|
||||
|
||||
dialog = {
|
||||
@@ -558,6 +560,20 @@ describe('GroupsViewComponent', () => {
|
||||
expect(data.lockedGroupTitles).toBeUndefined();
|
||||
});
|
||||
|
||||
it('opens no manage-groups dialog when the session relocked while the store was read', async () => {
|
||||
fixture.componentRef.setInput('playlistId', 'playlist-a');
|
||||
fixture.componentRef.setInput('lockedGroupTitles', []);
|
||||
fixture.detectChanges();
|
||||
parentalLock.ensureLocksReadable.mockImplementation(async () => {
|
||||
parentalLock.active.mockReturnValue(true);
|
||||
return true;
|
||||
});
|
||||
|
||||
await component.openGroupManagement();
|
||||
|
||||
expect(dialog.open).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('drops the manage-groups result once another playlist is open', async () => {
|
||||
const hiddenGroupTitlesChanged = jest.fn();
|
||||
const lockedGroupTitlesChanged = jest.fn();
|
||||
|
||||
@@ -567,6 +567,11 @@ export class GroupsViewComponent {
|
||||
this.playlistId() === playlistId
|
||||
? this.parentalLock.lockedGroupTitles(playlistId)
|
||||
: null;
|
||||
// Relocked while the store was being read: the dialog lists every
|
||||
// group, locked ones included.
|
||||
if (this.parentalLock.active() || this.playlistId() !== playlistId) {
|
||||
return;
|
||||
}
|
||||
const dialogRef = this.dialog.open(GroupManagementDialogComponent, {
|
||||
data: {
|
||||
groups,
|
||||
|
||||
Reference in new issue
Block a user