From a937331a931d1805d45fd3d966cdc547bd59304d Mon Sep 17 00:00:00 2001 From: Marek Date: Sat, 18 Apr 2026 17:54:40 +0200 Subject: [PATCH] update --- main.js | 100 ++++++++++++++++++++++++++++++++++++++++------------- styles.css | 86 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 153 insertions(+), 33 deletions(-) diff --git a/main.js b/main.js index b1402bc..e131cd1 100644 --- a/main.js +++ b/main.js @@ -2049,6 +2049,38 @@ var GridView = class extends import_obsidian7.ItemView { cls: "ge-title", text: `\u{1F4C1} ..`, }); + const parentFolderObj = this.app.vault.getAbstractFileByPath(parentPath); + if (parentFolderObj instanceof import_obsidian7.TFolder) { + const parentFiles = parentFolderObj.children + .filter((c) => c instanceof import_obsidian7.TFile) + .filter((f) => isDocumentFile(f) || isMediaFile(f)); + const filteredParentFiles = this.sortFiles(this.ignoredFiles(parentFiles)); + if (filteredParentFiles.length > 0) { + const filesList = parentFolderEl.createDiv("ge-folder-files"); + for (const f of filteredParentFiles) { + const fileRow = filesList.createDiv("ge-folder-file-item"); + fileRow.dataset.filePath = f.path; + const icon = fileRow.createDiv("ge-icon-container"); + const ext = f.extension.toLowerCase(); + let iconName = "file"; + if (isImageFile(f)) iconName = "image"; + else if (isVideoFile(f)) iconName = "play-circle"; + else if (isAudioFile(f)) iconName = "music"; + else if (ext === "pdf") iconName = "ge-pdf-file"; + else if (ext === "canvas") iconName = "layout-dashboard"; + else if (ext === "md" || ext === "txt") iconName = "file-text"; + (0, import_obsidian8.setIcon)(icon, iconName); + fileRow.createEl("span", { + cls: "ge-folder-file-title", + text: f.basename, + }); + fileRow.addEventListener("click", (e) => { + e.stopPropagation(); + this.app.workspace.getLeaf(false).openFile(f); + }); + } + } + } parentFolderEl.addEventListener("click", () => { this.setSource("folder", parentPath); this.clearSelection(); @@ -2218,6 +2250,35 @@ var GridView = class extends import_obsidian7.ItemView { this.setSource("folder", folder.path); this.clearSelection(); }); + const folderFiles = folder.children + .filter((c) => c instanceof import_obsidian7.TFile) + .filter((f) => isDocumentFile(f) || isMediaFile(f)); + const filteredFolderFiles = this.sortFiles(this.ignoredFiles(folderFiles)); + if (filteredFolderFiles.length > 0) { + const filesList = folderEl.createDiv("ge-folder-files"); + for (const f of filteredFolderFiles) { + const fileRow = filesList.createDiv("ge-folder-file-item"); + fileRow.dataset.filePath = f.path; + const icon = fileRow.createDiv("ge-icon-container"); + const ext = f.extension.toLowerCase(); + let iconName = "file"; + if (isImageFile(f)) iconName = "image"; + else if (isVideoFile(f)) iconName = "play-circle"; + else if (isAudioFile(f)) iconName = "music"; + else if (ext === "pdf") iconName = "ge-pdf-file"; + else if (ext === "canvas") iconName = "layout-dashboard"; + else if (ext === "md" || ext === "txt") iconName = "file-text"; + (0, import_obsidian8.setIcon)(icon, iconName); + fileRow.createEl("span", { + cls: "ge-folder-file-title", + text: f.basename, + }); + fileRow.addEventListener("click", (e) => { + e.stopPropagation(); + this.app.workspace.getLeaf(false).openFile(f); + }); + } + } folderEl.addEventListener("contextmenu", (event) => { event.preventDefault(); const menu = new import_obsidian7.Menu(); @@ -2455,52 +2516,43 @@ var GridView = class extends import_obsidian7.ItemView { threshold: 0.1, } ); + let filesCardEl = null; + let filesListEl = null; + if (files.length > 0) { + filesCardEl = container.createDiv("ge-grid-item ge-files-card"); + filesListEl = filesCardEl.createDiv("ge-folder-files"); + } for (const file of files) { - const fileEl = container.createDiv("ge-grid-item"); + const fileEl = filesListEl.createDiv("ge-folder-file-item"); this.gridItems.push(fileEl); fileEl.dataset.filePath = file.path; - const contentArea = fileEl.createDiv("ge-content-area"); - const titleContainer = contentArea.createDiv("ge-title-container"); const extension = file.extension.toLowerCase(); + const iconContainer = fileEl.createDiv("ge-icon-container"); if (isImageFile(file)) { - const iconContainer = titleContainer.createDiv( - "ge-icon-container ge-img" - ); + iconContainer.addClass("ge-img"); (0, import_obsidian8.setIcon)(iconContainer, "image"); } else if (isVideoFile(file)) { - const iconContainer = titleContainer.createDiv( - "ge-icon-container ge-video" - ); + iconContainer.addClass("ge-video"); (0, import_obsidian8.setIcon)(iconContainer, "play-circle"); } else if (isAudioFile(file)) { - const iconContainer = titleContainer.createDiv( - "ge-icon-container ge-audio" - ); + iconContainer.addClass("ge-audio"); (0, import_obsidian8.setIcon)(iconContainer, "music"); } else if (extension === "pdf") { - const iconContainer = titleContainer.createDiv( - "ge-icon-container ge-pdf" - ); + iconContainer.addClass("ge-pdf"); (0, import_obsidian8.setIcon)(iconContainer, "ge-pdf-file"); } else if (extension === "canvas") { - const iconContainer = titleContainer.createDiv( - "ge-icon-container ge-canvas" - ); + iconContainer.addClass("ge-canvas"); (0, import_obsidian8.setIcon)(iconContainer, "layout-dashboard"); } else if (extension === "md" || extension === "txt") { - const iconContainer = titleContainer.createDiv("ge-icon-container"); (0, import_obsidian8.setIcon)(iconContainer, "file-text"); } else { - const iconContainer = titleContainer.createDiv("ge-icon-container"); (0, import_obsidian8.setIcon)(iconContainer, "file"); } - const titleEl = titleContainer.createEl("span", { - cls: "ge-title", + const titleEl = fileEl.createEl("span", { + cls: "ge-folder-file-title", text: file.basename, }); titleEl.setAttribute("title", file.basename); - fileEl.createDiv("ge-image-area"); - observer.observe(fileEl); fileEl.addEventListener("click", (event) => { const index = this.gridItems.indexOf(fileEl); if (index >= 0) { diff --git a/styles.css b/styles.css index 478ec95..8d9af97 100644 --- a/styles.css +++ b/styles.css @@ -18,14 +18,18 @@ /* Grid 樣式 */ .ge-grid-container { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(var(--grid-item-width, 300px), 1fr)); - gap: 12px; + display: block; + column-count: 1; + column-width: 320px; + column-gap: 12px; padding: 12px !important; - align-items: start; - align-content: start; background: var(--background-secondary) !important; - flex: 1; + flex: 1 1 0; + width: 100%; + min-width: 0; + max-width: 100%; + box-sizing: border-box; + overflow-x: hidden; overflow-y: auto; } @@ -43,7 +47,24 @@ transition: transform 0.2s, box-shadow 0.2s; display: flex; gap: 14px; - height: var(--grid-item-height); + width: auto; + max-width: 100%; + min-width: 0; + box-sizing: border-box; + break-inside: avoid; + margin-bottom: 12px; + overflow: hidden; +} + +.ge-grid-item.ge-files-card { + cursor: default; + min-height: 0; +} + +.ge-grid-item.ge-files-card:hover { + transform: none; + background-color: var(--background-primary); + box-shadow: none; } .ge-grid-item:hover { @@ -174,7 +195,9 @@ padding: 7px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); transition: all 0.2s ease; - height: 100%; + height: auto; + flex-direction: column; + gap: 6px; } .ge-grid-item.ge-folder-item:hover { @@ -189,6 +212,10 @@ .ge-grid-item.ge-folder-item .ge-title { color: var(--text-normal); + overflow: visible; + text-overflow: clip; + white-space: normal; + word-break: break-word; } /* 上層資料夾的特殊樣式 */ @@ -203,7 +230,48 @@ /* 調整資料夾項目的高度 */ .ge-grid-item.ge-folder-item .ge-content-area { min-height: 0px; - justify-content: center; + justify-content: flex-start; +} + +.ge-folder-files { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 4px; + width: 100%; + min-width: 0; +} + +.ge-folder-file-item { + display: inline-flex; + align-items: center; + gap: 6px; + padding: 4px 8px; + border-radius: 4px; + cursor: pointer; + background-color: var(--background-primary); + border: 1px solid var(--background-modifier-border); + font-size: 0.85em; + max-width: 100%; + min-width: 0; + box-sizing: border-box; +} + +.ge-folder-file-item:hover { + background-color: var(--background-modifier-hover); +} + +.ge-folder-file-item .ge-icon-container { + flex-shrink: 0; + width: 14px; + height: 14px; +} + +.ge-folder-file-title { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + min-width: 0; } .ge-grid-item.ge-folder-item .ge-title-container {