Simplify download folder browser by removing manual path rows and preserving scroll position

- Remove 'Use model root' and 'Use typed folder' manual rows from the folder browser
- Remove category badge and folder browser header elements
- Add nested scroll element detection for scroll delta handling
- Preserve scroll position when re-rendering the folder browser on toggle
This commit is contained in:
Dariusz L
2026-06-23 04:28:41 +02:00
parent f2cd4cde30
commit c08eabc465
2 changed files with 29 additions and 78 deletions
+1 -46
View File
@@ -5690,23 +5690,6 @@
overflow: hidden;
padding: 0;
}
.mr-folder-browser-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
padding: 10px 12px;
border-bottom: 1px solid rgba(255,255,255,0.075);
background: rgba(255,255,255,0.025);
}
.mr-folder-browser-title {
color: var(--mr-text);
font-size: 12px;
font-weight: 750;
line-height: 1.25;
}
.mr-folder-browser-subtitle,
.mr-folder-browser-category,
.mr-folder-browser-preview-label,
.mr-folder-browser-root-path,
.mr-folder-browser-count,
@@ -5715,16 +5698,6 @@
font-size: 10px;
line-height: 1.3;
}
.mr-folder-browser-category {
max-width: 160px;
padding: 3px 7px;
border: 1px solid rgba(255,255,255,0.09);
border-radius: 999px;
background: rgba(255,255,255,0.035);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mr-folder-browser-preview {
display: grid;
gap: 3px;
@@ -5750,8 +5723,7 @@
.mr-folder-browser-root + .mr-folder-browser-root {
margin-top: 6px;
}
.mr-folder-browser-root-head,
.mr-folder-browser-manual {
.mr-folder-browser-root-head {
width: 100%;
border: 0;
color: var(--mr-text);
@@ -5767,7 +5739,6 @@
padding: 6px 8px;
}
.mr-folder-browser-root-head:hover,
.mr-folder-browser-manual:hover,
.mr-folder-browser-row:hover {
background: rgba(114,211,138,0.095);
}
@@ -5874,22 +5845,6 @@
border-radius: 999px;
background: rgba(255,255,255,0.045);
}
.mr-folder-browser-manual {
display: grid;
gap: 2px;
padding: 8px 12px;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.mr-folder-browser-manual-title {
color: var(--mr-text);
font-size: 11px;
font-weight: 700;
}
.mr-folder-browser-manual-path {
color: var(--mr-text-muted);
font-size: 10px;
word-break: break-all;
}
.mr-folder-browser-empty {
padding: 24px 12px;
color: var(--mr-text-muted);
+28 -32
View File
@@ -1492,20 +1492,25 @@ export const downloadTargetMethods = {
return;
}
event.preventDefault();
event.stopPropagation();
const nestedScrollEl = event.target?.closest?.('.mr-folder-browser-scroll');
const targetScrollEl = nestedScrollEl && scrollEl.contains(nestedScrollEl)
? nestedScrollEl
: scrollEl;
const maxScrollTop = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
const maxScrollTop = Math.max(0, targetScrollEl.scrollHeight - targetScrollEl.clientHeight);
if (maxScrollTop <= 0) {
return;
}
event.preventDefault();
event.stopPropagation();
const nextScrollTop = Math.min(
maxScrollTop,
Math.max(0, scrollEl.scrollTop + deltaY)
Math.max(0, targetScrollEl.scrollTop + deltaY)
);
scrollEl.scrollTop = nextScrollTop;
targetScrollEl.scrollTop = nextScrollTop;
}, { passive: false });
},
@@ -1760,7 +1765,11 @@ export const downloadTargetMethods = {
.join('');
};
const renderDownloadFolderBrowser = (targetEl, folders, filterText, onSelect) => {
const renderDownloadFolderBrowser = (targetEl, folders, filterText, onSelect, options = {}) => {
const previousScrollEl = options.preserveScroll
? targetEl.querySelector('.mr-folder-browser-scroll')
: null;
const previousScrollTop = previousScrollEl ? previousScrollEl.scrollTop : 0;
const rawFilter = String(filterText || '').trim();
const filter = rawFilter.toLowerCase();
const normalizedFilter = filter.replace(/[\/]+/g, '\\');
@@ -1807,22 +1816,6 @@ export const downloadTargetMethods = {
|| selectedValue
|| this.getDownloadTargetBaseDirectory(category)
|| '';
const hasExactTypedMatch = rawFilter
? folderEntries.some(entry => entry.value.toLowerCase() === normalizeSubfolderPath(rawFilter).toLowerCase())
: true;
const typedPath = normalizeSubfolderPath(rawFilter);
const clearRow = selectedValue
? `<button class="mr-folder-browser-manual" type="button" data-browser-action="select" data-value="" data-base-directory="">
<span class="mr-folder-browser-manual-title">Use model root</span>
<span class="mr-folder-browser-manual-path">${this.escapeHtml(this.getDownloadTargetBaseDirectory(category) || 'Category root')}</span>
</button>`
: '';
const manualRow = typedPath && !hasExactTypedMatch
? `<button class="mr-folder-browser-manual" type="button" data-browser-action="select" data-value="${encodeURIComponent(typedPath)}" data-base-directory="">
<span class="mr-folder-browser-manual-title">Use typed folder</span>
<span class="mr-folder-browser-manual-path">${this.escapeHtml(typedPath)}</span>
</button>`
: '';
const rootHtml = rootGroups.map(group => {
const tree = buildFolderTree(group.entries);
const stateKey = `root:${group.key}`;
@@ -1854,24 +1847,25 @@ export const downloadTargetMethods = {
targetEl.classList.add('mr-download-folder-browser');
targetEl.innerHTML = `
<div class="mr-folder-browser-head">
<div>
<div class="mr-folder-browser-title">Browse folders</div>
<div class="mr-folder-browser-subtitle">${filteredEntries.length} of ${folderEntries.length} folders</div>
</div>
<div class="mr-folder-browser-category">${this.escapeHtml(this.getCategoryDisplayName(category))}</div>
</div>
<div class="mr-folder-browser-preview">
<span class="mr-folder-browser-preview-label">Target folder path</span>
<span class="mr-folder-browser-preview-path">${this.escapeHtml(previewPath)}</span>
</div>
${clearRow}
${manualRow}
<div class="mr-folder-browser-scroll">
${rootHtml || `<div class="mr-folder-browser-empty">No folders match this filter.</div>`}
</div>
`;
showFloatingSubfolderList();
if (options.preserveScroll) {
const restoreScrollPosition = () => {
const scrollEl = targetEl.querySelector('.mr-folder-browser-scroll');
if (!scrollEl) return;
const maxScrollTop = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
scrollEl.scrollTop = Math.min(previousScrollTop, maxScrollTop);
};
restoreScrollPosition();
requestAnimationFrame(restoreScrollPosition);
}
targetEl.querySelectorAll('[data-browser-action="toggle"]').forEach(button => {
button.addEventListener('mousedown', (event) => {
@@ -1884,7 +1878,9 @@ export const downloadTargetMethods = {
} else {
expandedSet.add(stateKey);
}
renderDownloadFolderBrowser(targetEl, folders, filterText, onSelect);
renderDownloadFolderBrowser(targetEl, folders, filterText, onSelect, {
preserveScroll: true
});
});
});