From 1d7c50f0c0a33889b28750008fed512d0e2ea515 Mon Sep 17 00:00:00 2001 From: Marek Lenczewski Date: Sat, 18 Apr 2026 07:42:54 +0200 Subject: [PATCH] Update --- main.js | 505 +++++++++++++++++++++++++++++++++++++++-------------- styles.css | 7 - 2 files changed, 373 insertions(+), 139 deletions(-) diff --git a/main.js b/main.js index 98d0871..b1402bc 100644 --- a/main.js +++ b/main.js @@ -54,8 +54,6 @@ var TRANSLATIONS = { // 按鈕和標籤 sorting: "\u6392\u5E8F\u65B9\u5F0F", refresh: "\u91CD\u65B0\u6574\u7406", - reselect_folder: "\u91CD\u65B0\u9078\u64C7\u4F4D\u7F6E", - go_up: "\u8FD4\u56DE\u4E0A\u5C64\u8CC7\u6599\u593E", no_backlinks: "\u6C92\u6709\u53CD\u5411\u9023\u7D50", search: "\u641C\u5C0B", search_placeholder: "\u641C\u5C0B\u95DC\u9375\u5B57", @@ -65,6 +63,13 @@ var TRANSLATIONS = { untitled: "\u672A\u547D\u540D", files: "\u500B\u6A94\u6848", add: "\u65B0\u589E", + new_folder: "\u65B0\u589E\u8CC7\u6599\u593E", + new_feature: "\u65B0\u589E\u529F\u80FD", + add_feature_files: "\u65B0\u589E\u529F\u80FD\u6A94\u6848", + rename_folder: "\u91CD\u65B0\u547D\u540D\u8CC7\u6599\u593E", + folder_name_placeholder: "\u8CC7\u6599\u593E\u540D\u7A31", + create: "\u5EFA\u7ACB", + rename: "\u91CD\u65B0\u547D\u540D", // 視圖標題 grid_view_title: "\u7DB2\u683C\u8996\u5716", bookmarks_mode: "\u66F8\u7C64", @@ -180,9 +185,10 @@ var TRANSLATIONS = { delete_note: "\u522A\u9664\u6A94\u6848", open_folder_note: "\u958B\u555F\u8CC7\u6599\u593E\u7B46\u8A18", create_folder_note: "\u5EFA\u7ACB\u8CC7\u6599\u593E\u7B46\u8A18", - ignore_folder: "\u5FFD\u7565\u6B64\u8CC7\u6599\u593E", + delete_folder: "\u522A\u9664\u8CC7\u6599\u593E", + delete_folder_confirm: "\u78BA\u5B9A\u8981\u522A\u9664\u8CC7\u6599\u593E\u300C{name}\u300D\u53CA\u5176\u6240\u6709\u5167\u5BB9\u55CE\uFF1F", + delete: "\u522A\u9664", searching: "\u641C\u5C0B\u4E2D...", - no_files: "\u6C92\u6709\u627E\u5230\u4EFB\u4F55\u6A94\u6848", filter_folders: "\u7BE9\u9078\u8CC7\u6599\u593E...", }, en: { @@ -191,8 +197,6 @@ var TRANSLATIONS = { // Buttons and Labels sorting: "Sort by", refresh: "Refresh", - reselect_folder: "Reselect folder", - go_up: "Go Up", no_backlinks: "No backlinks", search: "Search", search_placeholder: "Search keyword", @@ -202,6 +206,13 @@ var TRANSLATIONS = { untitled: "Untitled", files: "files", add: "Add", + new_folder: "New folder", + new_feature: "New feature", + add_feature_files: "Add feature files", + rename_folder: "Rename folder", + folder_name_placeholder: "Folder name", + create: "Create", + rename: "Rename", // View Titles grid_view_title: "Grid view", bookmarks_mode: "Bookmarks", @@ -299,9 +310,10 @@ var TRANSLATIONS = { delete_note: "Delete file", open_folder_note: "Open folder note", create_folder_note: "Create folder note", - ignore_folder: "Ignore this folder", + delete_folder: "Delete folder", + delete_folder_confirm: "Delete folder \"{name}\" and all its contents?", + delete: "Delete", searching: "Searching...", - no_files: "No files found", filter_folders: "Filter folders...", }, zh: { @@ -311,8 +323,6 @@ var TRANSLATIONS = { // 按钮和标签 sorting: "\u6392\u5E8F\u65B9\u5F0F", refresh: "\u5237\u65B0", - reselect_folder: "\u91CD\u65B0\u9009\u62E9\u4F4D\u7F6E", - go_up: "\u8FD4\u56DE\u4E0A\u7EA7\u6587\u4EF6\u5939", no_backlinks: "\u6CA1\u6709\u53CD\u5411\u94FE\u63A5", search: "\u641C\u7D22", search_placeholder: "\u641C\u7D22\u5173\u952E\u5B57", @@ -322,6 +332,13 @@ var TRANSLATIONS = { untitled: "\u672A\u547D\u540D", files: "\u4E2A\u6587\u4EF6", add: "\u6DFB\u52A0", + new_folder: "\u65B0\u5EFA\u6587\u4EF6\u5939", + new_feature: "\u65B0\u5EFA\u529F\u80FD", + add_feature_files: "\u65B0\u5EFA\u529F\u80FD\u6587\u4EF6", + rename_folder: "\u91CD\u547D\u540D\u6587\u4EF6\u5939", + folder_name_placeholder: "\u6587\u4EF6\u5939\u540D\u79F0", + create: "\u521B\u5EFA", + rename: "\u91CD\u547D\u540D", // 视图标题 grid_view_title: "\u7F51\u683C\u89C6\u56FE", bookmarks_mode: "\u4E66\u7B7E", @@ -437,9 +454,10 @@ var TRANSLATIONS = { delete_note: "\u5220\u9664\u6587\u4EF6", open_folder_note: "\u6253\u5F00\u6587\u4EF6\u5939\u7B14\u8BB0", create_folder_note: "\u521B\u5EFA\u6587\u4EF6\u5939\u7B14\u8BB0", - ignore_folder: "\u5FFD\u7565\u6B64\u6587\u4EF6\u5939", + delete_folder: "\u5220\u9664\u6587\u4EF6\u5939", + delete_folder_confirm: "\u786E\u5B9A\u5220\u9664\u6587\u4EF6\u5939\u201C{name}\u201D\u53CA\u5176\u6240\u6709\u5185\u5BB9\u5417\uFF1F", + delete: "\u5220\u9664", searching: "\u641C\u7D22\u4E2D...", - no_files: "\u6CA1\u6709\u627E\u5230\u4EFB\u4F55\u6587\u4EF6", filter_folders: "\u7B5B\u9009\u6587\u4EF6\u5939...", }, ja: { @@ -449,8 +467,6 @@ var TRANSLATIONS = { // ボタンとラベル sorting: "\u4E26\u3073\u66FF\u3048", refresh: "\u66F4\u65B0", - reselect_folder: "\u30D5\u30A9\u30EB\u30C0\u3092\u518D\u9078\u629E", - go_up: "\u4E0A\u306E\u968E\u5C64\u3078", no_backlinks: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u306A\u3057", search: "\u691C\u7D22", search_placeholder: "\u30AD\u30FC\u30EF\u30FC\u30C9\u691C\u7D22", @@ -461,6 +477,13 @@ var TRANSLATIONS = { untitled: "\u7121\u984C", files: "\u30D5\u30A1\u30A4\u30EB", add: "\u8FFD\u52A0", + new_folder: "\u65B0\u898F\u30D5\u30A9\u30EB\u30C0", + new_feature: "\u65B0\u898F\u6A5F\u80FD", + add_feature_files: "\u6A5F\u80FD\u30D5\u30A1\u30A4\u30EB\u3092\u8FFD\u52A0", + rename_folder: "\u30D5\u30A9\u30EB\u30C0\u540D\u3092\u5909\u66F4", + folder_name_placeholder: "\u30D5\u30A9\u30EB\u30C0\u540D", + create: "\u4F5C\u6210", + rename: "\u540D\u524D\u3092\u5909\u66F4", // ビュータイトル grid_view_title: "\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC", bookmarks_mode: "\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF", @@ -598,10 +621,10 @@ var TRANSLATIONS = { "\u30D5\u30A9\u30EB\u30C0\u30CE\u30FC\u30C8\u3092\u958B\u304F", create_folder_note: "\u30D5\u30A9\u30EB\u30C0\u30CE\u30FC\u30C8\u3092\u4F5C\u6210", - ignore_folder: "\u3053\u306E\u30D5\u30A9\u30EB\u30C0\u3092\u7121\u8996", + delete_folder: "\u30D5\u30A9\u30EB\u30C0\u3092\u524A\u9664", + delete_folder_confirm: "\u30D5\u30A9\u30EB\u30C0\u300C{name}\u300D\u3068\u305D\u306E\u3059\u3079\u3066\u306E\u5185\u5BB9\u3092\u524A\u9664\u3057\u307E\u3059\u304B\uFF1F", + delete: "\u524A\u9664", searching: "\u691C\u7D22\u4E2D...", - no_files: - "\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093", filter_folders: "\u30D5\u30A9\u30EB\u30C0\u3092\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0...", }, @@ -1316,6 +1339,89 @@ function showSearchModal(app, gridView, defaultQuery = "") { new SearchModal(app, gridView, defaultQuery).open(); } +var FolderNameModal = class extends import_obsidian4.Modal { + constructor(app, titleKey, submitKey, defaultValue, onSubmit) { + super(app); + this.titleKey = titleKey; + this.submitKey = submitKey; + this.defaultValue = defaultValue || ""; + this.onSubmit = onSubmit; + } + onOpen() { + const { contentEl } = this; + contentEl.empty(); + new import_obsidian4.Setting(contentEl) + .setName(t(this.titleKey)) + .setHeading(); + const inputContainer = contentEl.createDiv("ge-search-container"); + const input = inputContainer.createEl("input", { + type: "text", + value: this.defaultValue, + placeholder: t("folder_name_placeholder"), + }); + const buttonContainer = contentEl.createDiv("ge-button-container"); + const submitButton = buttonContainer.createEl("button", { + text: t(this.submitKey), + }); + const cancelButton = buttonContainer.createEl("button", { + text: t("cancel"), + }); + const submit = () => { + const name = input.value.trim(); + if (!name) return; + this.close(); + this.onSubmit(name); + }; + submitButton.addEventListener("click", submit); + input.addEventListener("keydown", (e) => { + if (e.key === "Enter") { + e.preventDefault(); + e.stopPropagation(); + submit(); + } + }); + cancelButton.addEventListener("click", () => this.close()); + input.focus(); + input.setSelectionRange(input.value.length, input.value.length); + } + onClose() { + this.contentEl.empty(); + } +}; + +var ConfirmModal = class extends import_obsidian4.Modal { + constructor(app, title, message, confirmLabel, onConfirm) { + super(app); + this.title = title; + this.message = message; + this.confirmLabel = confirmLabel; + this.onConfirm = onConfirm; + } + onOpen() { + const { contentEl } = this; + contentEl.empty(); + new import_obsidian4.Setting(contentEl).setName(this.title).setHeading(); + contentEl.createEl("p", { text: this.message }); + const buttonContainer = contentEl.createDiv("ge-button-container"); + const confirmButton = buttonContainer.createEl("button", { + text: this.confirmLabel, + cls: "mod-warning", + }); + const cancelButton = buttonContainer.createEl("button", { + text: t("cancel"), + }); + confirmButton.addEventListener("click", () => { + this.close(); + this.onConfirm(); + }); + cancelButton.addEventListener("click", () => this.close()); + cancelButton.focus(); + } + onClose() { + this.contentEl.empty(); + } +}; + // src/FileWatcher.ts var import_obsidian6 = require("obsidian"); var FileWatcher = class { @@ -1434,6 +1540,7 @@ var GridView = class extends import_obsidian7.ItemView { this.fileWatcher.registerFileWatcher(); } this.registerDomEvent(document, "keydown", (event) => { + if (document.body.querySelector(".modal-container")) return; if (this.app.workspace.getActiveViewOfType(GridView) === this) { this.handleKeyDown(event); } @@ -1684,70 +1791,100 @@ var GridView = class extends import_obsidian7.ItemView { }); (0, import_obsidian8.setIcon)(newNoteButton, "square-pen"); } - if ( - this.sourceMode === "folder" && - this.sourcePath !== "/" && - this.searchQuery === "" - ) { - const upButton = headerButtonsDiv.createEl("button", { - attr: { "aria-label": t("go_up") }, + if (this.sourceMode === "folder" && this.searchQuery === "") { + const newFolderButton = headerButtonsDiv.createEl("button", { + attr: { "aria-label": t("new_folder") }, }); - upButton.addEventListener("click", () => { - const parentPath = - this.sourcePath.split("/").slice(0, -1).join("/") || "/"; - this.setSource("folder", parentPath); - this.clearSelection(); - }); - (0, import_obsidian8.setIcon)(upButton, "arrow-up"); - if (import_obsidian7.Platform.isDesktop) { - upButton.addEventListener("dragover", (event) => { - event.preventDefault(); - event.dataTransfer.dropEffect = "move"; - upButton.addClass("ge-dragover"); - }); - upButton.addEventListener("dragleave", () => { - upButton.removeClass("ge-dragover"); - }); - upButton.addEventListener("drop", async (event) => { - var _a; - event.preventDefault(); - upButton.removeClass("ge-dragover"); - const filePath = - (_a = event.dataTransfer) == null - ? void 0 - : _a.getData("text/plain"); - if (!filePath) return; - const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1"); - const parentPath = - this.sourcePath.split("/").slice(0, -1).join("/") || "/"; - if (!parentPath) return; - const file = this.app.vault.getAbstractFileByPath(cleanedFilePath); - const folder = this.app.vault.getAbstractFileByPath(parentPath); - if ( - file instanceof import_obsidian7.TFile && - folder instanceof import_obsidian7.TFolder - ) { + newFolderButton.addEventListener("click", () => { + new FolderNameModal( + this.app, + "new_folder", + "create", + "", + async (name) => { + const basePath = this.sourcePath === "/" ? "" : this.sourcePath; + let folderPath = basePath ? `${basePath}/${name}` : name; + let counter = 1; + while (this.app.vault.getAbstractFileByPath(folderPath)) { + folderPath = basePath + ? `${basePath}/${name} ${counter}` + : `${name} ${counter}`; + counter++; + } try { - const newPath = `${parentPath}/${file.name}`; - await this.app.fileManager.renameFile(file, newPath); + await this.app.vault.createFolder(folderPath); this.render(); } catch (error) { console.error( - "An error occurred while moving the file to parent folder:", + "An error occurred while creating a new folder:", error ); } } - }); - } + ).open(); + }); + (0, import_obsidian8.setIcon)(newFolderButton, "folder"); + } + if (this.sourceMode === "folder" && this.searchQuery === "") { + const newFeatureButton = headerButtonsDiv.createEl("button", { + attr: { "aria-label": t("new_feature") }, + }); + newFeatureButton.addEventListener("click", () => { + new FolderNameModal( + this.app, + "new_feature", + "create", + "", + async (name) => { + const basePath = this.sourcePath === "/" ? "" : this.sourcePath; + let folderPath = basePath ? `${basePath}/${name}` : name; + let counter = 1; + while (this.app.vault.getAbstractFileByPath(folderPath)) { + folderPath = basePath + ? `${basePath}/${name} ${counter}` + : `${name} ${counter}`; + counter++; + } + try { + await this.app.vault.createFolder(folderPath); + await this.app.vault.create(`${folderPath}/features.md`, ""); + await this.app.vault.create(`${folderPath}/specs.md`, ""); + this.render(); + } catch (error) { + console.error( + "An error occurred while creating a feature folder:", + error + ); + } + } + ).open(); + }); + (0, import_obsidian8.setIcon)(newFeatureButton, "folder-kanban"); + } + if (this.sourceMode === "folder" && this.searchQuery === "") { + const addFeatureFilesButton = headerButtonsDiv.createEl("button", { + attr: { "aria-label": t("add_feature_files") }, + }); + addFeatureFilesButton.addEventListener("click", async () => { + const basePath = this.sourcePath === "/" ? "" : this.sourcePath; + const filenames = ["features.md", "specs.md"]; + try { + for (const filename of filenames) { + const filePath = basePath ? `${basePath}/${filename}` : filename; + if (!this.app.vault.getAbstractFileByPath(filePath)) { + await this.app.vault.create(filePath, ""); + } + } + this.render(); + } catch (error) { + console.error( + "An error occurred while creating feature files:", + error + ); + } + }); + (0, import_obsidian8.setIcon)(addFeatureFilesButton, "files"); } - const reselectButton = headerButtonsDiv.createEl("button", { - attr: { "aria-label": t("reselect_folder") }, - }); - reselectButton.addEventListener("click", () => { - showFolderSelectionModal(this.app, this.plugin, this); - }); - (0, import_obsidian8.setIcon)(reselectButton, "folder"); const refreshButton = headerButtonsDiv.createEl("button", { attr: { "aria-label": t("refresh") }, }); @@ -1798,43 +1935,6 @@ var GridView = class extends import_obsidian7.ItemView { }); (0, import_obsidian8.setIcon)(sortButton, "arrow-up-narrow-wide"); } - if (this.sourceMode !== "random-note") { - const searchButtonContainer = headerButtonsDiv.createDiv( - "ge-search-button-container" - ); - const searchButton = searchButtonContainer.createEl("button", { - cls: "search-button", - attr: { "aria-label": t("search") }, - }); - (0, import_obsidian8.setIcon)(searchButton, "search"); - searchButton.addEventListener("click", () => { - this.showSearchModal(); - }); - if (this.searchQuery) { - searchButton.style.display = "none"; - const searchTextContainer = searchButtonContainer.createDiv( - "ge-search-text-container" - ); - const searchText = searchTextContainer.createEl("span", { - cls: "ge-search-text", - text: this.searchQuery, - }); - searchText.style.cursor = "pointer"; - searchText.addEventListener("click", () => { - this.showSearchModal(this.searchQuery); - }); - const clearButton = searchTextContainer.createDiv("ge-clear-button"); - (0, import_obsidian8.setIcon)(clearButton, "x"); - clearButton.addEventListener("click", (e) => { - e.stopPropagation(); - this.searchQuery = ""; - this.searchAllFiles = true; - this.clearSelection(); - this.render(); - this.app.workspace.requestSaveLayout(); - }); - } - } if ( this.sourceMode === "random-note" && this.plugin.settings.showMediaFiles @@ -1963,13 +2063,52 @@ var GridView = class extends import_obsidian7.ItemView { parentFolderEl.removeClass("ge-dragover"); }); parentFolderEl.addEventListener("drop", async (event) => { - var _a2; + var _a2, _b2; event.preventDefault(); parentFolderEl.removeClass("ge-dragover"); - const filePath = + const draggedFolderPath = (_a2 = event.dataTransfer) == null ? void 0 - : _a2.getData("text/plain"); + : _a2.getData("application/x-obsidian-grid-folder"); + if (draggedFolderPath) { + const sourceFolder = + this.app.vault.getAbstractFileByPath(draggedFolderPath); + const targetFolder = + this.app.vault.getAbstractFileByPath(parentPath); + if ( + !(sourceFolder instanceof import_obsidian7.TFolder) || + !(targetFolder instanceof import_obsidian7.TFolder) + ) + return; + if ( + parentPath === draggedFolderPath || + parentPath.startsWith(draggedFolderPath + "/") + ) + return; + const currentParent = sourceFolder.parent + ? sourceFolder.parent.path + : "/"; + if (currentParent === parentPath) return; + const newPath = + parentPath === "/" || parentPath === "" + ? sourceFolder.name + : `${parentPath}/${sourceFolder.name}`; + if (this.app.vault.getAbstractFileByPath(newPath)) return; + try { + await this.app.fileManager.renameFile(sourceFolder, newPath); + this.render(); + } catch (error) { + console.error( + "An error occurred while moving the folder to parent folder:", + error + ); + } + return; + } + const filePath = + (_b2 = event.dataTransfer) == null + ? void 0 + : _b2.getData("text/plain"); if (!filePath) return; const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1"); const file = this.app.vault.getAbstractFileByPath(cleanedFilePath); @@ -2040,6 +2179,23 @@ var GridView = class extends import_obsidian7.ItemView { const folderEl = container.createDiv("ge-grid-item ge-folder-item"); this.gridItems.push(folderEl); folderEl.dataset.folderPath = folder.path; + if (import_obsidian7.Platform.isDesktop) { + folderEl.setAttribute("draggable", "true"); + folderEl.addEventListener("dragstart", (event) => { + var _a2; + (_a2 = event.dataTransfer) == null + ? void 0 + : _a2.setData( + "application/x-obsidian-grid-folder", + folder.path + ); + event.dataTransfer.effectAllowed = "move"; + folderEl.addClass("ge-dragging"); + }); + folderEl.addEventListener("dragend", () => { + folderEl.removeClass("ge-dragging"); + }); + } const contentArea = folderEl.createDiv("ge-content-area"); const titleContainer = contentArea.createDiv("ge-title-container"); titleContainer.createEl("span", { @@ -2094,12 +2250,62 @@ var GridView = class extends import_obsidian7.ItemView { } menu.addItem((item) => { item - .setTitle(t("ignore_folder")) - .setIcon("x") + .setTitle(t("rename_folder")) + .setIcon("pencil") .onClick(() => { - this.plugin.settings.ignoredFolders.push(folder.path); - this.plugin.saveSettings(); - this.render(); + new FolderNameModal( + this.app, + "rename_folder", + "rename", + folder.name, + async (newName) => { + if (newName === folder.name) return; + const parentPath = folder.parent + ? folder.parent.path + : "/"; + const newPath = + parentPath === "/" || parentPath === "" + ? newName + : `${parentPath}/${newName}`; + try { + await this.app.fileManager.renameFile(folder, newPath); + this.render(); + } catch (error) { + console.error( + "An error occurred while renaming folder:", + error + ); + } + } + ).open(); + }); + }); + menu.addItem((item) => { + item + .setTitle(t("delete_folder")) + .setIcon("trash-2") + .onClick(() => { + const msg = t("delete_folder_confirm").replace( + "{name}", + folder.name + ); + new ConfirmModal( + this.app, + t("delete_folder"), + msg, + t("delete"), + async () => { + try { + await this.app.fileManager.trashFile(folder); + this.render(); + } catch (error) { + console.error( + "An error occurred while deleting folder:", + error + ); + } + } + ).open(); }); }); menu.showAtMouseEvent(event); @@ -2151,13 +2357,8 @@ var GridView = class extends import_obsidian7.ItemView { if (this.sourceMode === "random-note") { files = files.slice(0, 10); } - if (files.length === 0) { - const noFilesDiv = container.createDiv("ge-no-files"); - noFilesDiv.setText(t("no_files")); - if (this.plugin.statusBarItem) { - this.plugin.statusBarItem.setText(""); - } - return; + if (files.length === 0 && this.plugin.statusBarItem) { + this.plugin.statusBarItem.setText(""); } const observer = new IntersectionObserver( (entries, observer2) => { @@ -2209,7 +2410,7 @@ var GridView = class extends import_obsidian7.ItemView { (contentWithoutMediaLinks.length > summaryLength ? "" : ""); contentArea.createEl("p", { text: preview.trim() }); imageUrl = await findFirstImageInNote(this.app, content); - } else { + } else if (file.extension.toLowerCase() !== "pdf") { contentArea.createEl("p", { text: file.extension.toUpperCase(), }); @@ -2280,7 +2481,7 @@ var GridView = class extends import_obsidian7.ItemView { const iconContainer = titleContainer.createDiv( "ge-icon-container ge-pdf" ); - (0, import_obsidian8.setIcon)(iconContainer, "paperclip"); + (0, import_obsidian8.setIcon)(iconContainer, "ge-pdf-file"); } else if (extension === "canvas") { const iconContainer = titleContainer.createDiv( "ge-icon-container ge-canvas" @@ -2384,17 +2585,53 @@ var GridView = class extends import_obsidian7.ItemView { folderItem.removeClass("ge-dragover"); }); folderItem.addEventListener("drop", async (event) => { - var _a2; + var _a2, _b2; event.preventDefault(); folderItem.removeClass("ge-dragover"); - const filePath = - (_a2 = event.dataTransfer) == null - ? void 0 - : _a2.getData("text/plain"); - if (!filePath) return; - const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1"); const folderPath = folderItem.dataset.folderPath; if (!folderPath) return; + const draggedFolderPath = + (_a2 = event.dataTransfer) == null + ? void 0 + : _a2.getData("application/x-obsidian-grid-folder"); + if (draggedFolderPath) { + const sourceFolder = + this.app.vault.getAbstractFileByPath(draggedFolderPath); + const targetFolder = + this.app.vault.getAbstractFileByPath(folderPath); + if ( + !(sourceFolder instanceof import_obsidian7.TFolder) || + !(targetFolder instanceof import_obsidian7.TFolder) + ) + return; + if ( + folderPath === draggedFolderPath || + folderPath.startsWith(draggedFolderPath + "/") + ) + return; + const currentParent = sourceFolder.parent + ? sourceFolder.parent.path + : "/"; + if (currentParent === folderPath) return; + const newPath = `${folderPath}/${sourceFolder.name}`; + if (this.app.vault.getAbstractFileByPath(newPath)) return; + try { + await this.app.fileManager.renameFile(sourceFolder, newPath); + this.render(); + } catch (error) { + console.error( + "An error occurred while moving the folder:", + error + ); + } + return; + } + const filePath = + (_b2 = event.dataTransfer) == null + ? void 0 + : _b2.getData("text/plain"); + if (!filePath) return; + const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1"); const file = this.app.vault.getAbstractFileByPath(cleanedFilePath); const folder = this.app.vault.getAbstractFileByPath(folderPath); if ( @@ -3184,6 +3421,10 @@ var GridExplorerSettingTab = class extends import_obsidian9.PluginSettingTab { var GridExplorerPlugin = class extends import_obsidian10.Plugin { async onload() { await this.loadSettings(); + (0, import_obsidian10.addIcon)( + "ge-pdf-file", + `PDF` + ); this.registerView("grid-view", (leaf) => new GridView(leaf, this)); this.addSettingTab(new GridExplorerSettingTab(this.app, this)); this.addCommand({ diff --git a/styles.css b/styles.css index 72ac057..478ec95 100644 --- a/styles.css +++ b/styles.css @@ -445,13 +445,6 @@ color: var(--text-muted); } -.ge-no-files { - text-align: center; - padding: 2em; - color: var(--text-muted); - font-size: 1.2em; -} - /* 資料夾搜尋輸入框樣式 */ .ge-folder-search-container { margin-bottom: 16px;