feat: remember and normalize downloaded subfolder paths for reuse in download targets
This commit is contained in:
@@ -492,6 +492,18 @@ export const resolveDownloadMethods = {
|
||||
if (progress.filename) info.filename = progress.filename;
|
||||
},
|
||||
|
||||
rememberDownloadSubfolderAfterCompletion(info = {}, progress = {}) {
|
||||
const category = info?.category || progress?.category || '';
|
||||
const subfolder = info?.subfolder || progress?.subfolder || '';
|
||||
if (!category || !subfolder) return;
|
||||
|
||||
this.rememberDownloadedSubfolder?.(
|
||||
category,
|
||||
subfolder,
|
||||
info?.baseDirectory || progress?.base_directory || progress?.baseDirectory || ''
|
||||
);
|
||||
},
|
||||
|
||||
renderDownloadStatusMessage(message, type, progress = {}, info = {}) {
|
||||
const contextMenuModel = this.getDownloadFolderContext(progress, info);
|
||||
return this.renderStatusMessage(message, type, {
|
||||
@@ -742,6 +754,7 @@ export const resolveDownloadMethods = {
|
||||
const snapshot = this.rememberDownloadSnapshotForMissing(info.missing, {
|
||||
downloadId,
|
||||
category: info.category || '',
|
||||
subfolder: info.subfolder || '',
|
||||
filename: progress.filename || info.filename || '',
|
||||
downloadPath: progress.path || info.downloadPath || '',
|
||||
downloadDirectory: progress.directory || info.downloadDirectory || '',
|
||||
@@ -1261,6 +1274,7 @@ export const resolveDownloadMethods = {
|
||||
this.rememberDownloadSnapshotForMissing(missing, {
|
||||
downloadId: null,
|
||||
category,
|
||||
subfolder,
|
||||
filename,
|
||||
downloadPath: '',
|
||||
downloadDirectory: '',
|
||||
@@ -1340,6 +1354,7 @@ export const resolveDownloadMethods = {
|
||||
progressDiv,
|
||||
downloadBtn,
|
||||
category,
|
||||
subfolder,
|
||||
filename,
|
||||
downloadPath: data.path || '',
|
||||
downloadDirectory: data.directory || '',
|
||||
@@ -1450,6 +1465,7 @@ export const resolveDownloadMethods = {
|
||||
isActive: false
|
||||
});
|
||||
this.renderDownloadSnapshot(downloadId, completedSnapshot, { progressDiv, downloadBtn });
|
||||
this.rememberDownloadSubfolderAfterCompletion(info, progress);
|
||||
this.rememberCompletedDownloadHistory?.(downloadId, info, progress);
|
||||
delete this.activeDownloads[downloadId];
|
||||
this.updateDownloadAllButtonState();
|
||||
@@ -2515,6 +2531,7 @@ export const resolveDownloadMethods = {
|
||||
this.rememberDownloadSnapshotForMissing(missing, {
|
||||
downloadId: null,
|
||||
category: targetSelection.category,
|
||||
subfolder: targetSelection.subfolder,
|
||||
filename,
|
||||
downloadPath: '',
|
||||
downloadDirectory: '',
|
||||
@@ -2589,6 +2606,7 @@ export const resolveDownloadMethods = {
|
||||
progressDiv,
|
||||
downloadBtn: btn,
|
||||
category: targetSelection.category,
|
||||
subfolder: targetSelection.subfolder,
|
||||
filename,
|
||||
downloadPath: data.path || '',
|
||||
downloadDirectory: data.directory || '',
|
||||
|
||||
@@ -503,6 +503,73 @@ export const downloadTargetMethods = {
|
||||
return this.downloadSubfolders.get(this.normalizeDownloadCategory(category)) || [];
|
||||
},
|
||||
|
||||
normalizeDownloadSubfolderPath(value = '') {
|
||||
return String(value || '')
|
||||
.replace(/\//g, '\\')
|
||||
.split('\\')
|
||||
.map(part => part.trim())
|
||||
.filter(part => part && part !== '.' && part !== '..')
|
||||
.join('\\');
|
||||
},
|
||||
|
||||
getDownloadSubfolderPrefixes(value = '') {
|
||||
const parts = this.normalizeDownloadSubfolderPath(value).split('\\').filter(Boolean);
|
||||
const prefixes = [];
|
||||
let current = '';
|
||||
parts.forEach(part => {
|
||||
current = current ? `${current}\\${part}` : part;
|
||||
prefixes.push(current);
|
||||
});
|
||||
return prefixes;
|
||||
},
|
||||
|
||||
rememberDownloadedSubfolder(category = '', subfolder = '', baseDirectory = '') {
|
||||
const key = this.normalizeDownloadCategory(category);
|
||||
if (!key || key === 'unknown') return;
|
||||
|
||||
const prefixes = this.getDownloadSubfolderPrefixes(subfolder);
|
||||
if (!prefixes.length) return;
|
||||
|
||||
const cached = this.downloadSubfolders.get(key);
|
||||
if (!Array.isArray(cached)) {
|
||||
this.downloadSubfolders.delete(key);
|
||||
return;
|
||||
}
|
||||
|
||||
const targetBaseDirectory = String(baseDirectory || this.getDownloadTargetBaseDirectory(key) || '');
|
||||
const normalizeBase = (value = '') => String(value || '')
|
||||
.replace(/[\\/]+/g, '/')
|
||||
.replace(/\/+$/g, '')
|
||||
.toLowerCase();
|
||||
const normalizeValue = (value = '') => this.normalizeDownloadSubfolderPath(value).toLowerCase();
|
||||
const makeIdentity = (value = '', base = '') => `${normalizeValue(value)}::${normalizeBase(base)}`;
|
||||
const known = new Set(cached.map(option => makeIdentity(
|
||||
this.getSubfolderOptionValue(option),
|
||||
this.getSubfolderOptionBaseDirectory(option)
|
||||
)));
|
||||
const next = [...cached];
|
||||
|
||||
prefixes.forEach(prefix => {
|
||||
const identity = makeIdentity(prefix, targetBaseDirectory);
|
||||
if (known.has(identity)) return;
|
||||
known.add(identity);
|
||||
next.push({
|
||||
value: prefix,
|
||||
label: prefix,
|
||||
base_directory: targetBaseDirectory
|
||||
});
|
||||
});
|
||||
|
||||
next.sort((a, b) => {
|
||||
const valueCompare = this.getSubfolderOptionValue(a)
|
||||
.localeCompare(this.getSubfolderOptionValue(b), undefined, { sensitivity: 'base' });
|
||||
if (valueCompare !== 0) return valueCompare;
|
||||
return this.getSubfolderOptionBaseDirectory(a)
|
||||
.localeCompare(this.getSubfolderOptionBaseDirectory(b), undefined, { sensitivity: 'base' });
|
||||
});
|
||||
this.downloadSubfolders.set(key, next);
|
||||
},
|
||||
|
||||
getSubfolderOptionValue(option) {
|
||||
return String(
|
||||
option && typeof option === 'object'
|
||||
|
||||
Reference in New Issue
Block a user