refactor(frontend): extract queue storage methods
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
import { queueStorageMethods } from '../web/resolver/actions/queue_storage_methods.js';
|
||||
|
||||
function createStorage() {
|
||||
const values = new Map();
|
||||
return {
|
||||
getItem(key) {
|
||||
return values.has(key) ? values.get(key) : null;
|
||||
},
|
||||
setItem(key, value) {
|
||||
values.set(key, String(value));
|
||||
},
|
||||
removeItem(key) {
|
||||
values.delete(key);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function installStorage(storage) {
|
||||
const previousDescriptor = Object.getOwnPropertyDescriptor(globalThis, 'localStorage');
|
||||
Object.defineProperty(globalThis, 'localStorage', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
value: storage,
|
||||
writable: true,
|
||||
});
|
||||
return () => {
|
||||
if (previousDescriptor) {
|
||||
Object.defineProperty(globalThis, 'localStorage', previousDescriptor);
|
||||
} else {
|
||||
delete globalThis.localStorage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
test('queue storage persists collapsed state and splitter width immediately', () => {
|
||||
const storage = createStorage();
|
||||
const restoreStorage = installStorage(storage);
|
||||
|
||||
try {
|
||||
const context = { ...queueStorageMethods };
|
||||
context.persistQueueCollapsedState(true, 0);
|
||||
context.persistQueueSplitWidth(421, 0);
|
||||
|
||||
assert.equal(storage.getItem('model_resolver_queue_collapsed'), '1');
|
||||
assert.equal(storage.getItem('model_resolver_split_w'), '421');
|
||||
} finally {
|
||||
restoreStorage();
|
||||
}
|
||||
});
|
||||
|
||||
test('download history replaces duplicate identities and keeps newest entries first', () => {
|
||||
const storage = createStorage();
|
||||
const restoreStorage = installStorage(storage);
|
||||
|
||||
try {
|
||||
const context = {
|
||||
...queueStorageMethods,
|
||||
downloadHistoryLimit: 10,
|
||||
downloadHistoryStorageKey: 'test-download-history',
|
||||
updateQueuePanel() {},
|
||||
};
|
||||
|
||||
const first = context.addDownloadHistoryEntry({
|
||||
filename: 'model.safetensors',
|
||||
path: 'models/model.safetensors',
|
||||
category: 'checkpoints',
|
||||
sourceUrl: 'https://example.test/model',
|
||||
completedAt: '2026-01-01T00:00:00.000Z',
|
||||
});
|
||||
const second = context.addDownloadHistoryEntry({
|
||||
filename: 'model.safetensors',
|
||||
path: 'models/model.safetensors',
|
||||
category: 'checkpoints',
|
||||
sourceUrl: 'https://example.test/model',
|
||||
completedAt: '2026-01-02T00:00:00.000Z',
|
||||
});
|
||||
|
||||
assert.notEqual(first.id, second.id);
|
||||
assert.deepEqual(context.getDownloadHistory().map(entry => entry.completedAt), [
|
||||
'2026-01-02T00:00:00.000Z',
|
||||
]);
|
||||
|
||||
const persisted = JSON.parse(storage.getItem('test-download-history'));
|
||||
assert.equal(persisted.length, 1);
|
||||
assert.equal(persisted[0].id, second.id);
|
||||
} finally {
|
||||
restoreStorage();
|
||||
}
|
||||
});
|
||||
@@ -205,46 +205,6 @@ export const queueMethods = {
|
||||
this.contentElement.style.removeProperty('flex-shrink');
|
||||
},
|
||||
|
||||
persistQueueCollapsedState(collapsed, delayMs = 250) {
|
||||
if (this._queueCollapsedPersistTimer) {
|
||||
clearTimeout(this._queueCollapsedPersistTimer);
|
||||
this._queueCollapsedPersistTimer = null;
|
||||
}
|
||||
const writeState = () => {
|
||||
this._queueCollapsedPersistTimer = null;
|
||||
try {
|
||||
localStorage.setItem('model_resolver_queue_collapsed', collapsed ? '1' : '0');
|
||||
} catch (_e) { }
|
||||
};
|
||||
const delay = Math.max(0, Number(delayMs) || 0);
|
||||
if (delay > 0) {
|
||||
this._queueCollapsedPersistTimer = setTimeout(writeState, delay);
|
||||
} else {
|
||||
writeState();
|
||||
}
|
||||
},
|
||||
|
||||
persistQueueSplitWidth(width, delayMs = 250) {
|
||||
const nextWidth = Math.round(Number(width));
|
||||
if (!Number.isFinite(nextWidth) || nextWidth <= 0) return;
|
||||
if (this._queueSplitPersistTimer) {
|
||||
clearTimeout(this._queueSplitPersistTimer);
|
||||
this._queueSplitPersistTimer = null;
|
||||
}
|
||||
const writeWidth = () => {
|
||||
this._queueSplitPersistTimer = null;
|
||||
try {
|
||||
localStorage.setItem('model_resolver_split_w', String(nextWidth));
|
||||
} catch (_e) { }
|
||||
};
|
||||
const delay = Math.max(0, Number(delayMs) || 0);
|
||||
if (delay > 0) {
|
||||
this._queueSplitPersistTimer = setTimeout(writeWidth, delay);
|
||||
} else {
|
||||
writeWidth();
|
||||
}
|
||||
},
|
||||
|
||||
updateQueuePanelTabs(queueCount, downloadCount, activeTab) {
|
||||
const queuedTab = this.queueQueuedTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="queued"]');
|
||||
const downloadsTab = this.queueDownloadsTabButton || this.queueTabs?.querySelector?.('.mr-queue-tab[data-tab="downloads"]');
|
||||
@@ -1006,160 +966,6 @@ export const queueMethods = {
|
||||
return this.getActiveQueuePanelDownloads().map(({ downloadId }) => downloadId);
|
||||
},
|
||||
|
||||
loadDownloadHistory() {
|
||||
if (this._downloadHistoryLoaded) return this.downloadHistory || [];
|
||||
this._downloadHistoryLoaded = true;
|
||||
try {
|
||||
const raw = localStorage.getItem(this.downloadHistoryStorageKey || 'model_resolver_download_history');
|
||||
const parsed = raw ? JSON.parse(raw) : [];
|
||||
this.downloadHistory = Array.isArray(parsed)
|
||||
? parsed.filter(item => item && typeof item === 'object')
|
||||
: [];
|
||||
} catch (error) {
|
||||
console.warn('Model Resolver: failed to load download history', error);
|
||||
this.downloadHistory = [];
|
||||
}
|
||||
return this.downloadHistory;
|
||||
},
|
||||
|
||||
getDownloadHistory() {
|
||||
if (!this._downloadHistoryLoaded) {
|
||||
this.loadDownloadHistory();
|
||||
}
|
||||
return Array.isArray(this.downloadHistory) ? this.downloadHistory : [];
|
||||
},
|
||||
|
||||
saveDownloadHistory() {
|
||||
const history = this.getDownloadHistory().slice(0, this.downloadHistoryLimit || 200);
|
||||
this.downloadHistory = history;
|
||||
try {
|
||||
localStorage.setItem(
|
||||
this.downloadHistoryStorageKey || 'model_resolver_download_history',
|
||||
JSON.stringify(history)
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn('Model Resolver: failed to save download history', error);
|
||||
}
|
||||
},
|
||||
|
||||
getDownloadHistoryIdentity(entry = {}) {
|
||||
return [
|
||||
entry.path || '',
|
||||
entry.filename || '',
|
||||
entry.category || '',
|
||||
entry.sourceUrl || ''
|
||||
].map(value => String(value || '').trim().toLowerCase()).join('::');
|
||||
},
|
||||
|
||||
addDownloadHistoryEntry(entry = {}) {
|
||||
if (!entry || !entry.filename) return null;
|
||||
|
||||
const history = this.getDownloadHistory();
|
||||
const identity = this.getDownloadHistoryIdentity(entry);
|
||||
const filtered = identity
|
||||
? history.filter(item => this.getDownloadHistoryIdentity(item) !== identity)
|
||||
: history;
|
||||
const nextEntry = {
|
||||
...entry,
|
||||
id: entry.id || `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
||||
completedAt: entry.completedAt || new Date().toISOString()
|
||||
};
|
||||
this.downloadHistory = [nextEntry, ...filtered].slice(0, this.downloadHistoryLimit || 200);
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel?.();
|
||||
return nextEntry;
|
||||
},
|
||||
|
||||
rememberCompletedDownloadHistory(downloadId, info = {}, progress = {}) {
|
||||
const missing = info?.missing || {};
|
||||
const filename = progress.filename
|
||||
|| info.filename
|
||||
|| missing.download_source?.filename
|
||||
|| missing.original_path?.split(/[/\\]/).pop()
|
||||
|| '';
|
||||
if (!filename) return null;
|
||||
|
||||
const directory = progress.directory || info.downloadDirectory || '';
|
||||
const path = progress.path || info.downloadPath || '';
|
||||
const category = info.category || missing.category || progress.category || '';
|
||||
const workflowLabel = this.getDownloadWorkflowLabel?.(info) || info.workflowLabel || '';
|
||||
const nodeLabel = missing.subgraph_name || missing.node_type || (missing.subgraph_id ? 'Subgraph' : 'Node');
|
||||
const status = progress.already_exists ? 'already_exists' : 'completed';
|
||||
return this.addDownloadHistoryEntry({
|
||||
downloadId,
|
||||
filename,
|
||||
category,
|
||||
categoryLabel: this.getCategoryDisplayName?.(category) || category,
|
||||
nodeLabel,
|
||||
nodeId: missing.node_id ?? '',
|
||||
widgetIndex: missing.widget_index ?? '',
|
||||
workflowLabel,
|
||||
workflowId: info.workflowId || info.workflow_id || this.getWorkflowContextId?.(info) || '',
|
||||
workflowKey: info.workflowKey || '',
|
||||
workflowRouteKey: info.workflowRouteKey || '',
|
||||
workflowSignature: info.workflowSignature || '',
|
||||
workflowTabId: info.workflowTabId || '',
|
||||
workflowTabName: info.workflowTabName || '',
|
||||
workflowTabAriaControls: info.workflowTabAriaControls || '',
|
||||
workflowTabText: info.workflowTabText || '',
|
||||
path,
|
||||
directory,
|
||||
sourceUrl: info.sourceUrl || missing.download_source?.url || '',
|
||||
totalSize: progress.total_size || progress.size || 0,
|
||||
status,
|
||||
statusLabel: status === 'already_exists' ? 'Already downloaded' : 'Downloaded',
|
||||
message: progress.message || '',
|
||||
completedAt: new Date().toISOString()
|
||||
});
|
||||
},
|
||||
|
||||
formatDownloadHistoryTime(value = '') {
|
||||
if (!value) return '';
|
||||
try {
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return '';
|
||||
return date.toLocaleString(undefined, {
|
||||
month: 'short',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
} catch (_error) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
getDownloadHistoryFolderContext(entry = {}) {
|
||||
const filePath = entry.path || '';
|
||||
const directory = entry.directory || '';
|
||||
const targetPath = filePath || directory;
|
||||
const context = {
|
||||
context_scope: 'download_history',
|
||||
open_folder_label: targetPath ? 'Open Download Folder' : '',
|
||||
name: entry.filename || 'Download',
|
||||
path: targetPath,
|
||||
resolved_path: targetPath,
|
||||
open_path: filePath || directory,
|
||||
folder_path: directory || targetPath,
|
||||
download_directory: directory,
|
||||
download_path: filePath,
|
||||
category: entry.category || '',
|
||||
workflow_id: entry.workflowId || entry.workflow_id || (this.isLikelyWorkflowId?.(entry.workflowLabel) ? entry.workflowLabel : ''),
|
||||
workflow_label: entry.workflowLabel || '',
|
||||
workflow_key: entry.workflowKey || '',
|
||||
workflow_route_key: entry.workflowRouteKey || '',
|
||||
workflow_signature: entry.workflowSignature || '',
|
||||
workflow_tab_id: entry.workflowTabId || '',
|
||||
workflow_tab_name: entry.workflowTabName || '',
|
||||
workflow_tab_aria_controls: entry.workflowTabAriaControls || '',
|
||||
workflow_tab_text: entry.workflowTabText || '',
|
||||
node_id: entry.nodeId ?? '',
|
||||
widget_index: entry.widgetIndex ?? ''
|
||||
};
|
||||
|
||||
return (targetPath || this.canSwitchToDownloadWorkflow?.(context)) ? context : null;
|
||||
},
|
||||
|
||||
renderDownloadsPanel(downloads = [], history = this.getDownloadHistory()) {
|
||||
const activeSubTab = this.queueDownloadsActiveTab === 'history' ? 'history' : 'active';
|
||||
const activeSelected = activeSubTab === 'active';
|
||||
@@ -1465,32 +1271,6 @@ export const queueMethods = {
|
||||
return html;
|
||||
},
|
||||
|
||||
clearDownloadHistory() {
|
||||
this.downloadHistory = [];
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel();
|
||||
},
|
||||
|
||||
removeDownloadHistoryEntry(historyId = '', fallbackIndex = -1) {
|
||||
const history = this.getDownloadHistory();
|
||||
if (!history.length) return;
|
||||
|
||||
const normalizedId = String(historyId || '');
|
||||
let nextHistory = history;
|
||||
if (normalizedId) {
|
||||
nextHistory = history.filter(entry => String(entry?.id || '') !== normalizedId);
|
||||
}
|
||||
|
||||
if (nextHistory.length === history.length && Number.isInteger(fallbackIndex) && fallbackIndex >= 0 && fallbackIndex < history.length) {
|
||||
nextHistory = history.filter((_, index) => index !== fallbackIndex);
|
||||
}
|
||||
|
||||
if (nextHistory.length === history.length) return;
|
||||
this.downloadHistory = nextHistory;
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel();
|
||||
},
|
||||
|
||||
// Remove queued by index
|
||||
removeQueuedByIndex(i) {
|
||||
const list = Array.isArray(this.pendingResolutions) ? this.pendingResolutions : [];
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
export const queueStorageMethods = {
|
||||
persistQueueCollapsedState(collapsed, delayMs = 250) {
|
||||
if (this._queueCollapsedPersistTimer) {
|
||||
clearTimeout(this._queueCollapsedPersistTimer);
|
||||
this._queueCollapsedPersistTimer = null;
|
||||
}
|
||||
const writeState = () => {
|
||||
this._queueCollapsedPersistTimer = null;
|
||||
try {
|
||||
localStorage.setItem('model_resolver_queue_collapsed', collapsed ? '1' : '0');
|
||||
} catch (_e) { }
|
||||
};
|
||||
const delay = Math.max(0, Number(delayMs) || 0);
|
||||
if (delay > 0) {
|
||||
this._queueCollapsedPersistTimer = setTimeout(writeState, delay);
|
||||
} else {
|
||||
writeState();
|
||||
}
|
||||
},
|
||||
|
||||
persistQueueSplitWidth(width, delayMs = 250) {
|
||||
const nextWidth = Math.round(Number(width));
|
||||
if (!Number.isFinite(nextWidth) || nextWidth <= 0) return;
|
||||
if (this._queueSplitPersistTimer) {
|
||||
clearTimeout(this._queueSplitPersistTimer);
|
||||
this._queueSplitPersistTimer = null;
|
||||
}
|
||||
const writeWidth = () => {
|
||||
this._queueSplitPersistTimer = null;
|
||||
try {
|
||||
localStorage.setItem('model_resolver_split_w', String(nextWidth));
|
||||
} catch (_e) { }
|
||||
};
|
||||
const delay = Math.max(0, Number(delayMs) || 0);
|
||||
if (delay > 0) {
|
||||
this._queueSplitPersistTimer = setTimeout(writeWidth, delay);
|
||||
} else {
|
||||
writeWidth();
|
||||
}
|
||||
},
|
||||
|
||||
loadDownloadHistory() {
|
||||
if (this._downloadHistoryLoaded) return this.downloadHistory || [];
|
||||
this._downloadHistoryLoaded = true;
|
||||
try {
|
||||
const raw = localStorage.getItem(this.downloadHistoryStorageKey || 'model_resolver_download_history');
|
||||
const parsed = raw ? JSON.parse(raw) : [];
|
||||
this.downloadHistory = Array.isArray(parsed)
|
||||
? parsed.filter(item => item && typeof item === 'object')
|
||||
: [];
|
||||
} catch (error) {
|
||||
console.warn('Model Resolver: failed to load download history', error);
|
||||
this.downloadHistory = [];
|
||||
}
|
||||
return this.downloadHistory;
|
||||
},
|
||||
|
||||
getDownloadHistory() {
|
||||
if (!this._downloadHistoryLoaded) {
|
||||
this.loadDownloadHistory();
|
||||
}
|
||||
return Array.isArray(this.downloadHistory) ? this.downloadHistory : [];
|
||||
},
|
||||
|
||||
saveDownloadHistory() {
|
||||
const history = this.getDownloadHistory().slice(0, this.downloadHistoryLimit || 200);
|
||||
this.downloadHistory = history;
|
||||
try {
|
||||
localStorage.setItem(
|
||||
this.downloadHistoryStorageKey || 'model_resolver_download_history',
|
||||
JSON.stringify(history)
|
||||
);
|
||||
} catch (error) {
|
||||
console.warn('Model Resolver: failed to save download history', error);
|
||||
}
|
||||
},
|
||||
|
||||
getDownloadHistoryIdentity(entry = {}) {
|
||||
return [
|
||||
entry.path || '',
|
||||
entry.filename || '',
|
||||
entry.category || '',
|
||||
entry.sourceUrl || ''
|
||||
].map(value => String(value || '').trim().toLowerCase()).join('::');
|
||||
},
|
||||
|
||||
addDownloadHistoryEntry(entry = {}) {
|
||||
if (!entry || !entry.filename) return null;
|
||||
|
||||
const history = this.getDownloadHistory();
|
||||
const identity = this.getDownloadHistoryIdentity(entry);
|
||||
const filtered = identity
|
||||
? history.filter(item => this.getDownloadHistoryIdentity(item) !== identity)
|
||||
: history;
|
||||
const nextEntry = {
|
||||
...entry,
|
||||
id: entry.id || `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
||||
completedAt: entry.completedAt || new Date().toISOString()
|
||||
};
|
||||
this.downloadHistory = [nextEntry, ...filtered].slice(0, this.downloadHistoryLimit || 200);
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel?.();
|
||||
return nextEntry;
|
||||
},
|
||||
|
||||
rememberCompletedDownloadHistory(downloadId, info = {}, progress = {}) {
|
||||
const missing = info?.missing || {};
|
||||
const filename = progress.filename
|
||||
|| info.filename
|
||||
|| missing.download_source?.filename
|
||||
|| missing.original_path?.split(/[/\\]/).pop()
|
||||
|| '';
|
||||
if (!filename) return null;
|
||||
|
||||
const directory = progress.directory || info.downloadDirectory || '';
|
||||
const path = progress.path || info.downloadPath || '';
|
||||
const category = info.category || missing.category || progress.category || '';
|
||||
const workflowLabel = this.getDownloadWorkflowLabel?.(info) || info.workflowLabel || '';
|
||||
const nodeLabel = missing.subgraph_name || missing.node_type || (missing.subgraph_id ? 'Subgraph' : 'Node');
|
||||
const status = progress.already_exists ? 'already_exists' : 'completed';
|
||||
return this.addDownloadHistoryEntry({
|
||||
downloadId,
|
||||
filename,
|
||||
category,
|
||||
categoryLabel: this.getCategoryDisplayName?.(category) || category,
|
||||
nodeLabel,
|
||||
nodeId: missing.node_id ?? '',
|
||||
widgetIndex: missing.widget_index ?? '',
|
||||
workflowLabel,
|
||||
workflowId: info.workflowId || info.workflow_id || this.getWorkflowContextId?.(info) || '',
|
||||
workflowKey: info.workflowKey || '',
|
||||
workflowRouteKey: info.workflowRouteKey || '',
|
||||
workflowSignature: info.workflowSignature || '',
|
||||
workflowTabId: info.workflowTabId || '',
|
||||
workflowTabName: info.workflowTabName || '',
|
||||
workflowTabAriaControls: info.workflowTabAriaControls || '',
|
||||
workflowTabText: info.workflowTabText || '',
|
||||
path,
|
||||
directory,
|
||||
sourceUrl: info.sourceUrl || missing.download_source?.url || '',
|
||||
totalSize: progress.total_size || progress.size || 0,
|
||||
status,
|
||||
statusLabel: status === 'already_exists' ? 'Already downloaded' : 'Downloaded',
|
||||
message: progress.message || '',
|
||||
completedAt: new Date().toISOString()
|
||||
});
|
||||
},
|
||||
|
||||
formatDownloadHistoryTime(value = '') {
|
||||
if (!value) return '';
|
||||
try {
|
||||
const date = new Date(value);
|
||||
if (Number.isNaN(date.getTime())) return '';
|
||||
return date.toLocaleString(undefined, {
|
||||
month: 'short',
|
||||
day: '2-digit',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit'
|
||||
});
|
||||
} catch (_error) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
getDownloadHistoryFolderContext(entry = {}) {
|
||||
const filePath = entry.path || '';
|
||||
const directory = entry.directory || '';
|
||||
const targetPath = filePath || directory;
|
||||
const context = {
|
||||
context_scope: 'download_history',
|
||||
open_folder_label: targetPath ? 'Open Download Folder' : '',
|
||||
name: entry.filename || 'Download',
|
||||
path: targetPath,
|
||||
resolved_path: targetPath,
|
||||
open_path: filePath || directory,
|
||||
folder_path: directory || targetPath,
|
||||
download_directory: directory,
|
||||
download_path: filePath,
|
||||
category: entry.category || '',
|
||||
workflow_id: entry.workflowId || entry.workflow_id || (this.isLikelyWorkflowId?.(entry.workflowLabel) ? entry.workflowLabel : ''),
|
||||
workflow_label: entry.workflowLabel || '',
|
||||
workflow_key: entry.workflowKey || '',
|
||||
workflow_route_key: entry.workflowRouteKey || '',
|
||||
workflow_signature: entry.workflowSignature || '',
|
||||
workflow_tab_id: entry.workflowTabId || '',
|
||||
workflow_tab_name: entry.workflowTabName || '',
|
||||
workflow_tab_aria_controls: entry.workflowTabAriaControls || '',
|
||||
workflow_tab_text: entry.workflowTabText || '',
|
||||
node_id: entry.nodeId ?? '',
|
||||
widget_index: entry.widgetIndex ?? ''
|
||||
};
|
||||
|
||||
return (targetPath || this.canSwitchToDownloadWorkflow?.(context)) ? context : null;
|
||||
},
|
||||
|
||||
clearDownloadHistory() {
|
||||
this.downloadHistory = [];
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel();
|
||||
},
|
||||
|
||||
removeDownloadHistoryEntry(historyId = '', fallbackIndex = -1) {
|
||||
const history = this.getDownloadHistory();
|
||||
if (!history.length) return;
|
||||
|
||||
const normalizedId = String(historyId || '');
|
||||
let nextHistory = history;
|
||||
if (normalizedId) {
|
||||
nextHistory = history.filter(entry => String(entry?.id || '') !== normalizedId);
|
||||
}
|
||||
|
||||
if (nextHistory.length === history.length && Number.isInteger(fallbackIndex) && fallbackIndex >= 0 && fallbackIndex < history.length) {
|
||||
nextHistory = history.filter((_, index) => index !== fallbackIndex);
|
||||
}
|
||||
|
||||
if (nextHistory.length === history.length) return;
|
||||
this.downloadHistory = nextHistory;
|
||||
this.saveDownloadHistory();
|
||||
this.updateQueuePanel();
|
||||
},
|
||||
};
|
||||
@@ -13,6 +13,7 @@ import { tabsLoadedMethods } from "./views/tabs_loaded_methods.js";
|
||||
import { downloadTargetMethods } from "./search/download_target_methods.js";
|
||||
import { searchPanelMethods } from "./search/search_panel.js";
|
||||
import { queueMethods } from "./actions/queue_methods.js";
|
||||
import { queueStorageMethods } from "./actions/queue_storage_methods.js";
|
||||
import { resolveDownloadMethods } from "./actions/resolve_download_methods.js";
|
||||
import { selectionMethods } from "./actions/selection_methods.js";
|
||||
import { renderFormatMethods } from "./utils/render_format_methods.js";
|
||||
@@ -341,6 +342,7 @@ applyDialogMethods(
|
||||
optionsMethods,
|
||||
tabsLoadedMethods,
|
||||
queueMethods,
|
||||
queueStorageMethods,
|
||||
lifecycleGraphMethods,
|
||||
missingBrowserMethods,
|
||||
resolveDownloadMethods,
|
||||
|
||||
Reference in New Issue
Block a user