-
+
@@ -65,28 +65,61 @@
*/
/**
- * @param {DB} node
- * @param {string} query
- * @param {boolean} parentMatched
- * @returns {DB|null}
- */
+ * @param {DB} node
+ * @param {string} query
+ * @param {boolean} parentMatched
+ * @returns {DB|null}
+ */
function filterDb(node, query, parentMatched = false) {
/** @type {DB} */
let result = {};
let filesCount = 0;
+ const q = query.replace(/^\/|\/$/g, '').toLowerCase();
+ const parts = q.split('/');
+ const targetSegment = parts[0];
+
for (const [key, value] of Object.entries(node)) {
+ const lowerKey = key.toLowerCase();
if (typeof value === 'object') {
- const isMatch = parentMatched || key.toLowerCase().includes(query);
- const subTree = filterDb(value, query, isMatch);
- if (subTree !== null) {
- result[key] = subTree;
- filesCount++;
+ if (parentMatched) {
+ const subTree = filterDb(value, q, true);
+ if (subTree !== null) {
+ result[key] = subTree;
+ filesCount++;
+ }
+ } else {
+ let nextQuery = q;
+ let isMatch = false;
+
+ if (lowerKey.startsWith(targetSegment)) {
+ if (parts.length === 1) {
+ isMatch = true;
+ } else {
+ nextQuery = parts.slice(1).join('/');
+ }
+ }
+
+ let subTree = filterDb(value, nextQuery, isMatch);
+
+ if (subTree === null && nextQuery !== q) {
+ subTree = filterDb(value, q, false);
+ }
+
+ if (subTree !== null) {
+ result[key] = subTree;
+ filesCount++;
+ }
}
} else {
- if (parentMatched || key.toLowerCase().includes(query)) {
+ if (parentMatched) {
result[key] = value;
filesCount++;
+ } else {
+ if (parts.length === 1 && lowerKey.startsWith(targetSegment)) {
+ result[key] = value;
+ filesCount++;
+ }
}
}
}
@@ -172,12 +205,13 @@
if (isPeeking) {
const peekName = basePathArray.join('/');
- fileHeader.innerHTML = `Files
(Peeking: ${peekName})`;
+ fileHeader.innerHTML = `Files
(Peeking: ${peekName})`;
} else if (lockedFileViewPath) {
const lockName = lockedFileViewPath.join('/');
- fileHeader.innerHTML = `Files
(Selected: ${lockName})`;
+ fileHeader.innerHTML = `Files
(Selected: ${lockName})`;
} else {
- fileHeader.innerHTML = `Files`;
+ const pathName = basePathArray.join('/') || '/';
+ fileHeader.innerHTML = `Files
(${pathName})`;
}
if (!node) {
@@ -304,7 +338,7 @@
if (!node) return;
}
- dirHeader.innerText = pathStack.join('/');
+ dirHeader.innerText = pathStack.join('/') || '/';
let lastScroll = dirPanel.scrollTop;
dirPanel.innerHTML = '';
diff --git a/src/web/style.css b/src/web/style.css
index 5fad81c5..a846eda3 100644
--- a/src/web/style.css
+++ b/src/web/style.css
@@ -110,6 +110,7 @@ code {
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.9em;
+ font-weight: normal;
}
.card {
@@ -321,6 +322,12 @@ th {
margin-right: 0.2em;
}
+.nowrap {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
@media (prefers-color-scheme: dark) {
body {
background-color: #000;