diff --git a/manifest.json b/manifest.json index 2549eaa..2da73b3 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "gridexplorer", "name": "GridExplorer", - "version": "2.9.8", + "version": "2.9.9", "minAppVersion": "1.1.0", "description": "Browse note files in a grid view.", "author": "Devon22", diff --git a/package-lock.json b/package-lock.json index d44b8ee..1180aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gridexplorer", - "version": "2.9.8", + "version": "2.9.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gridexplorer", - "version": "2.9.8", + "version": "2.9.9", "license": "MIT", "devDependencies": { "@types/node": "^16.11.6", diff --git a/package.json b/package.json index ea30d96..9881122 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridexplorer", - "version": "2.9.8", + "version": "2.9.9", "description": "Browse note files in a grid view.", "main": "main.js", "scripts": { diff --git a/src/GridView.ts b/src/GridView.ts index d3d910d..b00c8e6 100644 --- a/src/GridView.ts +++ b/src/GridView.ts @@ -5,13 +5,14 @@ import { renderModePath } from './renderModePath'; import { renderFolder } from './renderFolder'; import { renderFiles } from './renderFiles'; import { handleKeyDown } from './handleKeyDown'; -import { isDocumentFile, isMediaFile, isImageFile, isVideoFile, isAudioFile, getFiles, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS } from './fileUtils'; +import { isMediaFile, isImageFile, isVideoFile, isAudioFile, getFiles, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS } from './fileUtils'; import { FileWatcher } from './fileWatcher'; import { findFirstImageInNote } from './mediaUtils'; import { showFolderSelectionModal } from './modal/folderSelectionModal'; import { MediaModal } from './modal/mediaModal'; import { showNoteSettingsModal } from './modal/noteSettingsModal'; import { FloatingAudioPlayer } from './floatingAudioPlayer'; +import { ExplorerView, EXPLORER_VIEW_TYPE } from './ExplorerView'; import { t } from './translations'; // 定義分隔器狀態 @@ -763,9 +764,10 @@ export class GridView extends ItemView { fileEl.style.height = '100%'; } - // 如果 frontmatter 中存在 redirect 欄位,將圖示設為 shuffle - const redirectValue = metadata?.redirect; - if (redirectValue) { + // 如果 frontmatter 同時存在 type 與非空的 redirect(視為捷徑檔),將圖示設為 shuffle + const redirectType = metadata?.type; + const redirectPath = metadata?.redirect; + if (redirectType && typeof redirectPath === 'string' && redirectPath.trim() !== '') { const iconContainer = fileEl.querySelector('.ge-icon-container'); if (iconContainer) { setIcon(iconContainer as HTMLElement, 'shuffle'); @@ -1179,6 +1181,28 @@ export class GridView extends ItemView { // 開始觀察這個元素 observer.observe(fileEl); + // 加入滑鼠移入顯示的右上角圓形按鈕(僅針對可在網格中顯示筆記的檔案) + // 位置與顯示由 CSS 控制(.ge-hover-open-note) + // 當設定為「直接在網格中顯示筆記」時,不顯示此按鈕 + // if (file.extension === 'md' && !this.plugin.settings.showNoteInGrid) { + // // 確保容器可做為定位參考 + // fileEl.style.position = fileEl.style.position || 'relative'; + // const quickBtn = fileEl.createDiv({ cls: 'ge-hover-open-note' }); + // setIcon(quickBtn, 'maximize-2'); + // quickBtn.addEventListener('click', (e) => { + // e.stopPropagation(); + // e.preventDefault(); + // // 如果是捷徑檔案,遵循捷徑開啟邏輯;否則在網格中顯示筆記 + // if (!this.openShortcutFile(file)) { + // this.showNoteInGrid(file); + // } + // }); + // // 阻止滑鼠事件影響拖曳或選取 + // quickBtn.addEventListener('mousedown', (e) => { + // e.stopPropagation(); + // }); + // } + // 點擊時開啟檔案 fileEl.addEventListener('click', (event) => { // 獲取項目索引 @@ -1439,10 +1463,9 @@ export class GridView extends ItemView { .setSection?.("open") .onClick(() => { if (selectedFiles.length > 1) { - // 如果多個檔案被選中,開啟所有文件檔案 - const documentFiles = selectedFiles.filter(f => isDocumentFile(f)); - for (const docFile of documentFiles) { - this.app.workspace.getLeaf(true).openFile(docFile); + // 如果多個檔案被選中,開啟所有檔案 + for (const f of selectedFiles) { + this.app.workspace.getLeaf(true).openFile(f); } } else { this.app.workspace.getLeaf(true).openFile(file); @@ -1450,6 +1473,18 @@ export class GridView extends ItemView { }); }); + // 加入暫存區選項 (僅在行動裝置上顯示) + if (Platform.isMobile) { + menu.addItem((item) => { + item + .setTitle(t('add_to_stash')) + .setIcon('archive') + .onClick(() => { + this.addFilesToStash(selectedFiles); + }); + }); + } + // 刪除選項 menu.addItem((item) => { (item as any).setWarning(true); @@ -1474,6 +1509,37 @@ export class GridView extends ItemView { }); } + // 將檔案添加到 ExplorerView 的暫存區 + private addFilesToStash(files: TFile[]) { + // 獲取當前活動的 ExplorerView + const explorerLeaves = this.app.workspace.getLeavesOfType(EXPLORER_VIEW_TYPE); + + if (explorerLeaves.length === 0) { + new Notice('找不到 Explorer 視圖'); + return; + } + + // 使用第一個找到的 ExplorerView + const explorerView = explorerLeaves[0].view as ExplorerView; + + if (!explorerView) { + new Notice('無法訪問 Explorer 視圖'); + return; + } + + // 將檔案路徑轉換為字串陣列 + const filePaths = files.map(file => file.path); + + // 調用 ExplorerView 的 addToStash 方法 + (explorerView as any).addToStash(filePaths); + + // 強制立即重新渲染 ExplorerView 以確保畫面更新 + (explorerView as any).refresh(); + + // 顯示成功通知 + new Notice(t('added_to_stash')); + } + onPaneMenu(menu: Menu, source: string) { menu.addItem(item => { item @@ -1713,9 +1779,6 @@ export class GridView extends ItemView { const gridContainer = this.containerEl.querySelector('.ge-grid-container'); if (!gridContainer) return; - // 隱藏網格內容 - gridContainer.addClass('ge-hidden'); - // 創建筆記顯示容器 this.noteViewContainer = this.containerEl.createDiv('ge-note-view-container'); @@ -1828,10 +1891,7 @@ export class GridView extends ItemView { hideNoteInGrid() { if (!this.isShowingNote) return; - const gridContainer = this.containerEl.querySelector('.ge-grid-container'); - if (gridContainer) { - gridContainer.removeClass('ge-hidden'); - } + //const gridContainer = this.containerEl.querySelector('.ge-grid-container'); if (this.noteViewContainer) { // 移除鍵盤事件監聽器 diff --git a/src/renderModePath.ts b/src/renderModePath.ts index cb0256e..190bc59 100644 --- a/src/renderModePath.ts +++ b/src/renderModePath.ts @@ -128,12 +128,19 @@ export function renderModePath(gridView: GridView) { let pathEl; if (isLast) { - if (path.path === '/' && gridView.plugin.settings.folderDisplayStyle === 'show') { - // 當顯示資料夾開啟且是根目錄時,使用 span 元素 - pathEl = modenameContainer.createEl('span', { - text: `${customFolderIcon} ${path.name}`.trim(), - cls: 'ge-mode-title' - }); + if (path.path === '/') { + // 當根目錄時,根據設定使用 span 元素 + if (gridView.plugin.settings.folderDisplayStyle !== 'menu') { + pathEl = modenameContainer.createEl('span', { + text: `${customFolderIcon} ${path.name}`.trim(), + cls: 'ge-mode-title' + }); + } else { + pathEl = modenameContainer.createEl('a', { + text: `${customFolderIcon} ${path.name}`.trim(), + cls: 'ge-current-folder' + }); + } } else { // 其他情況使用 a 元素 pathEl = modenameContainer.createEl('a', { @@ -516,7 +523,16 @@ export function renderModePath(gridView: GridView) { } } - if (gridView.sourcePath !== '/') { + // 根目錄顯示規則: + // show -> 不顯示選單(可直接點選) + // menu -> 顯示選單 + // hide -> 不顯示選單 + if (gridView.sourcePath === '/') { + if (gridView.plugin.settings.folderDisplayStyle === 'menu') { + menu.showAtMouseEvent(event); + } + } else { + // 非根目錄維持原本行為:顯示選單 menu.showAtMouseEvent(event); } }); diff --git a/src/translations.ts b/src/translations.ts index de33fa5..3924d36 100644 --- a/src/translations.ts +++ b/src/translations.ts @@ -301,7 +301,6 @@ export const TRANSLATIONS: Translations = { 'display_minimized_desc': '將此筆記以最小化方式顯示', // Quick Access Settings and Commands - 'quick_access_settings_title': '快速存取設定', 'quick_access_folder_name': '快速存取資料夾', 'quick_access_folder_desc': '設定「開啟快速存取資料夾」命令所使用的資料夾', @@ -314,11 +313,14 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': '使用快速存取模式', 'open_quick_access_folder': '開啟快速存取資料夾', 'open_quick_access_mode': '開啟快速存取模式', + // Explorer Stash 'stash': '暫存區', 'drop_files_here': '拖曳檔案到此暫存', 'clear': '清空', 'save_stash_as_markdown': '將暫存區存為 Markdown', + 'add_to_stash': '加入暫存區', + 'added_to_stash': '已添加到暫存區', }, 'en': { // Notifications @@ -601,7 +603,6 @@ export const TRANSLATIONS: Translations = { 'display_minimized_desc': 'Show this note in minimized mode', // Quick Access Settings and Commands - 'quick_access_settings_title': 'Quick Access Settings', 'quick_access_folder_name': 'Quick access folder', 'quick_access_folder_desc': 'Set the folder used by the "Open quick access folder" command', @@ -614,11 +615,14 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': 'Use quick access mode', 'open_quick_access_folder': 'Open quick access folder', 'open_quick_access_mode': 'Open quick access mode', + // Explorer Stash 'stash': 'Stash', 'drop_files_here': 'Drop files here to stash', 'clear': 'Clear', 'save_stash_as_markdown': 'Save stash as Markdown', + 'add_to_stash': 'Add to stash', + 'added_to_stash': 'Added to stash', }, 'zh': { // 通知信息 @@ -899,7 +903,6 @@ export const TRANSLATIONS: Translations = { 'display_minimized_desc': '将此笔记以最小化方式显示', // Quick Access Settings and Commands - 'quick_access_settings_title': '快速访问设置', 'quick_access_folder_name': '快速访问文件夹', 'quick_access_folder_desc': '设置“打开快速访问文件夹”命令使用的文件夹', @@ -912,11 +915,14 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': '使用快速访问模式', 'open_quick_access_folder': '打开快速访问文件夹', 'open_quick_access_mode': '打开快速访问模式', + // Explorer Stash 'stash': '暂存区', 'drop_files_here': '拖曳文件到此暂存', 'clear': '清空', 'save_stash_as_markdown': '将暂存区保存为 Markdown', + 'add_to_stash': '加入暂存区', + 'added_to_stash': '已添加到暂存区', }, 'ja': { // 通知メッジ @@ -1196,9 +1202,7 @@ export const TRANSLATIONS: Translations = { 'display_minimized': '最小化表示', 'display_minimized_desc': 'このノートを最小化モードで表示', - //TODO: please check the translation! // Quick Access Settings and Commands - 'quick_access_settings_title': 'クイックアクセス設定', 'quick_access_folder_name': 'クイックアクセスフォルダー', 'quick_access_folder_desc': '「クイックアクセス フォルダーを開く」コマンドで使用するフォルダーを設定します', @@ -1211,11 +1215,14 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': 'クイックアクセスモードを使用する', 'open_quick_access_folder': 'クイックアクセス フォルダーを開く', 'open_quick_access_mode': 'クイックアクセスモードを開く', + // Explorer Stash 'stash': '一時保存', 'drop_files_here': 'ここにドラッグして一時保存', 'clear': 'クリア', 'save_stash_as_markdown': '一時保存をMarkdownとして保存', + 'add_to_stash': '一時保存に追加', + 'added_to_stash': '一時保存に追加されました', }, 'ru': { // Notifications @@ -1438,7 +1445,7 @@ export const TRANSLATIONS: Translations = { 'filter_folders': 'Фильтровать папки...', 'search_for': 'Поиск', - // + // Shortcut Selection Dialog 'create_shortcut': 'Создать ярлик', 'select_folder': 'Выбрать папку', 'select_file': 'Выбрать файл', @@ -1509,11 +1516,14 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': 'Использовать режим быстрого доступа', 'open_quick_access_folder': 'Открыть папку быстрого доступа', 'open_quick_access_mode': 'Открыть быстрый доступ по режиму', + // Explorer Stash - 'stash': 'Буфер', + 'stash': 'Хранилище', 'drop_files_here': 'Перетащите файлы сюда, чтобы сохранить', 'clear': 'Очистить', - 'save_stash_as_markdown': 'Сохранить буфер как Markdown', + 'save_stash_as_markdown': 'Сохранить хранилище как Markdown', + 'add_to_stash': 'Добавить в хранилище', + 'added_to_stash': 'Добавлено в хранилище', }, 'uk': { // Notifications @@ -1794,7 +1804,6 @@ export const TRANSLATIONS: Translations = { 'display_minimized_desc': 'Показувати цю нотатку у мінімізованому режимі', // Quick Access Settings and Commands - 'quick_access_settings_title': 'Налаштування Швидкого доступу', 'quick_access_folder_name': 'Папка швидкого доступу', 'quick_access_folder_desc': 'Встановіть папку, що використовується командою «Відкрити папку швидкого доступу»', @@ -1807,10 +1816,13 @@ export const TRANSLATIONS: Translations = { 'use_quick_access_mode': 'Використовувати режим швидкого доступу', 'open_quick_access_folder': 'Відкрити папку швидкого доступу', 'open_quick_access_mode': 'Відкрити швидкий доступ за режимом', + // Explorer Stash 'stash': 'Тимчасове сховище', 'drop_files_here': 'Перетягніть файли сюди для збереження', 'clear': 'Очистити', 'save_stash_as_markdown': 'Зберегти сховище як Markdown', + 'add_to_stash': 'Додати до сховища', + 'added_to_stash': 'Додано до сховища', } } diff --git a/styles.css b/styles.css index 637db53..26ffc49 100644 --- a/styles.css +++ b/styles.css @@ -48,6 +48,43 @@ color: var(--text-muted); } +/* 右上角懸浮開啟筆記按鈕 Hover Open-in-Grid Button */ +/* .ge-grid-item { position: relative; } +.ge-hover-open-note { + position: absolute; + top: 6px; + right: 6px; + width: 24px; + height: 24px; + border-radius: 50%; + background: rgba(0, 0, 0, 0.55); + border: 0; + display: flex; + align-items: center; + justify-content: center; + color: #fff; + box-shadow: 0 1px 2px rgba(0,0,0,0.1); + opacity: 0; + transition: opacity 0.15s ease, background-color 0.15s ease, color 0.15s ease; + pointer-events: none; + z-index: 2; +} + +.ge-grid-item:hover .ge-hover-open-note { + opacity: 1; + pointer-events: auto; +} + +.ge-hover-open-note:hover { + background: rgba(0, 0, 0, 0.75); + color: #fff; +} + +.ge-hover-open-note svg { + width: 14px; + height: 14px; +} */ + /* 摘要區域 Content Area */ .ge-content-area { flex: 1; @@ -1871,9 +1908,10 @@ a.ge-current-folder:hover { border-color: var(--horizontal-line); } -/* 隱藏網格內容 */ +/* 隱藏網格內容(跳過隱藏時的樣式/排版/繪製成本) */ .ge-grid-container.ge-hidden { - display: none; + content-visibility: hidden; + pointer-events: none; } /* 行動裝置隱藏滾動條 Mobile hidden Scrollbar */ diff --git a/versions.json b/versions.json index cbaf610..bde000f 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "2.9.8": "1.1.0" + "2.9.9": "1.1.0" } \ No newline at end of file