From 5c8d190ef4925d36adc12097ebbfa2cb71f7a681 Mon Sep 17 00:00:00 2001 From: Devon22 Date: Tue, 13 Jan 2026 15:46:35 +0800 Subject: [PATCH] 3.0.3 --- manifest.json | 2 +- package-lock.json | 6 +-- package.json | 4 +- src/GridView.ts | 43 +++++++++-------- styles.css | 120 ++++++++++++++++++++++++++++++++-------------- versions.json | 2 +- 6 files changed, 114 insertions(+), 63 deletions(-) diff --git a/manifest.json b/manifest.json index 268be12..5d271c9 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "gridexplorer", "name": "GridExplorer", - "version": "3.0.2", + "version": "3.0.3", "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 78b6091..ef82ee5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gridexplorer", - "version": "3.0.2", + "version": "3.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gridexplorer", - "version": "3.0.2", + "version": "3.0.3", "license": "MIT", "devDependencies": { "@types/node": "^16.11.6", @@ -2394,4 +2394,4 @@ } } } -} +} \ No newline at end of file diff --git a/package.json b/package.json index 16042df..1eb7794 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridexplorer", - "version": "3.0.2", + "version": "3.0.3", "description": "Browse note files in a grid view.", "main": "main.js", "scripts": { @@ -21,4 +21,4 @@ "tslib": "2.4.0", "typescript": "4.7.4" } -} +} \ No newline at end of file diff --git a/src/GridView.ts b/src/GridView.ts index b5bc63d..1dd1d45 100644 --- a/src/GridView.ts +++ b/src/GridView.ts @@ -234,7 +234,7 @@ export class GridView extends ItemView { searchFilesNameOnly, searchMediaFiles, }); - + this.recentSources.unshift(key); // 一旦有新的歷史被推入,清空 futureSources this.futureSources = []; @@ -347,7 +347,7 @@ export class GridView extends ItemView { mode: this.sourceMode, path: this.sourcePath, }); - } catch {} + } catch { } await this.render(); } @@ -363,9 +363,9 @@ export class GridView extends ItemView { } }); this.eventCleanupFunctions = []; - + // 清理檔案監聽器(FileWatcher 的事件監聽器會在插件卸載時自動清理) - + super.onunload(); } @@ -388,7 +388,7 @@ export class GridView extends ItemView { } }); this.eventCleanupFunctions = []; - + // 清空整個容器 this.containerEl.empty(); @@ -401,6 +401,7 @@ export class GridView extends ItemView { // 創建內容區域 const contentEl = this.containerEl.createDiv('view-content'); + // 取得置頂清單 if (this.sourceMode === 'folder' && this.sourcePath !== '/') { this.pinnedList = []; @@ -704,7 +705,7 @@ export class GridView extends ItemView { } if (metadata?.[fieldKey] !== undefined && metadata?.[fieldKey] !== '' && metadata?.[fieldKey] !== null) { - + let value = metadata[fieldKey]; // 如果是數字,則加入千位分隔符號 @@ -715,7 +716,7 @@ export class GridView extends ItemView { if (Array.isArray(metadata[fieldKey])) { value = metadata[fieldKey].join(', '); } - + let outputValue: string | number | null = value; if (calcExpr) { try { @@ -813,7 +814,7 @@ export class GridView extends ItemView { fileEl.addClass('ge-note-color-custom'); fileEl.style.setProperty('--ge-note-color-bg', hexToRgba(colorValue, 0.2)); fileEl.style.setProperty('--ge-note-color-border', hexToRgba(colorValue, 0.5)); - + // 設置預覽內容文字顏色 if (pEl) { pEl.addClass('ge-note-color-custom-text'); @@ -1313,7 +1314,7 @@ export class GridView extends ItemView { // 只有在滑鼠確實懸停在此項目上且按下 Ctrl 時才觸發 // 且滑鼠沒有按下(避免干擾 Ctrl+click) // 並且當前 GridView 必須是活動視圖 - if (isHovering && e.ctrlKey && !isMouseDown && + if (isHovering && e.ctrlKey && !isMouseDown && this.app.workspace.getActiveViewOfType(GridView) === this) { // 短暫延遲以確保不是 Ctrl+click 操作 setTimeout(() => { @@ -1348,7 +1349,7 @@ export class GridView extends ItemView { document.addEventListener('keydown', keydownListener, { capture: true }); } }; - + const onMouseLeave = () => { isHovering = false; isMouseDown = false; @@ -1358,12 +1359,12 @@ export class GridView extends ItemView { } triggeredInHover = false; }; - + fileEl.addEventListener('mouseenter', onMouseEnter); fileEl.addEventListener('mouseleave', onMouseLeave); fileEl.addEventListener('mousedown', onMouseDown); fileEl.addEventListener('mouseup', onMouseUp); - + // 添加清理函數到數組中 this.eventCleanupFunctions.push(() => { if (keydownListener) { @@ -1532,13 +1533,13 @@ export class GridView extends ItemView { // 使用 Obsidian 內建的拖曳格式(obsidian:// URI) // const vaultName = this.app.vault.getName(); - + if (selectedFiles.length > 1) { // 多檔案:建立多個 obsidian://open URI // const obsidianUris = selectedFiles.map(f => // `obsidian://open?vault=${encodeURIComponent(vaultName)}&file=${encodeURIComponent(f.path)}` // ); - + // // 設定 text/uri-list // event.dataTransfer?.setData('text/uri-list', obsidianUris.join('\n')); // console.log(obsidianUris.join('\n')); @@ -1556,7 +1557,7 @@ export class GridView extends ItemView { } else { // 單檔案:建立單一 obsidian://open URI // const obsidianUri = `obsidian://open?vault=${encodeURIComponent(vaultName)}&file=${encodeURIComponent(file.path)}`; - + // 設定為 text/uri-list // event.dataTransfer?.setData('text/uri-list', obsidianUri); @@ -1691,7 +1692,7 @@ export class GridView extends ItemView { private addFilesToStash(files: TFile[]) { // 獲取當前活動的 ExplorerView const explorerLeaves = this.app.workspace.getLeavesOfType(EXPLORER_VIEW_TYPE); - + if (explorerLeaves.length === 0) { new Notice('找不到 Explorer 視圖'); return; @@ -1699,7 +1700,7 @@ export class GridView extends ItemView { // 使用第一個找到的 ExplorerView const explorerView = explorerLeaves[0].view as ExplorerView; - + if (!explorerView) { new Notice('無法訪問 Explorer 視圖'); return; @@ -1707,13 +1708,13 @@ export class GridView extends ItemView { // 將檔案路徑轉換為字串陣列 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')); } @@ -1984,7 +1985,7 @@ export class GridView extends ItemView { new Notice(`${t('target_not_found')}: ${redirectPath}`); } } - + return false; } diff --git a/styles.css b/styles.css index e5967b1..e3508ad 100644 --- a/styles.css +++ b/styles.css @@ -31,7 +31,7 @@ .ge-grid-item { background-color: var(--background-primary); border: 1px solid var(--background-modifier-border); - border-radius: var(--button-radius); + border-radius: var(--radius-m); padding: 10px; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; @@ -229,7 +229,8 @@ /* 垂直排列 */ flex-direction: column; align-items: stretch; - height: var(--grid-item-height); /* 與一般網格一致,保持同排等高 */ + height: var(--grid-item-height); + /* 與一般網格一致,保持同排等高 */ gap: 0px; padding: 0px !important; } @@ -237,8 +238,10 @@ /* 摘要文字 Content Area */ .ge-vertical-card .ge-content-area { order: 1; - flex: 1 1 auto; /* 使摘要區撐開,標籤可貼底 */ - flex-grow: 1; /* Add this line */ + flex: 1 1 auto; + /* 使摘要區撐開,標籤可貼底 */ + flex-grow: 1; + /* Add this line */ padding: 10px !important; } @@ -246,7 +249,7 @@ .ge-vertical-card .ge-image-area { order: 3; width: 100%; - height: var(--image-area-height); + height: var(--image-area-height); } /* 標籤列置底 Tags Container */ @@ -266,8 +269,8 @@ .ge-vertical-card.ge-image-top .ge-image-area img, .ge-vertical-card.ge-image-top .ge-image-area video { - border-radius: calc(var(--button-radius) - var(--border-width)) calc(var(--button-radius) - var(--border-width)) 0px 0px !important; -} + border-radius: calc(var(--radius-m) - var(--border-width)) calc(var(--radius-m) - var(--border-width)) 0px 0px !important; +} /* 預設 bottom 可維持原有順序,以下為明確設置 */ .ge-vertical-card.ge-image-bottom .ge-image-area { @@ -280,8 +283,8 @@ .ge-vertical-card.ge-image-bottom .ge-image-area img, .ge-vertical-card.ge-image-bottom .ge-image-area video { - border-radius: 0px 0px calc(var(--button-radius) - var(--border-width)) calc(var(--button-radius) - var(--border-width)) !important; -} + border-radius: 0px 0px calc(var(--radius-m) - var(--border-width)) calc(var(--radius-m) - var(--border-width)) !important; +} /* 鼠標懸停效果:整張卡片微抬升 */ .ge-vertical-card .ge-grid-item:hover { @@ -290,7 +293,8 @@ /* 僅圖片/影片的直向卡片 Media Card */ .ge-vertical-card .ge-media-card { - padding: 0; /* 移除內距,讓媒體填滿 */ + padding: 0; + /* 移除內距,讓媒體填滿 */ border: none; gap: 0; height: var(--grid-item-height); @@ -305,12 +309,13 @@ .ge-vertical-card .ge-media-card .ge-image-area img, .ge-vertical-card .ge-media-card .ge-image-area video { - border-radius: 4px !important; + border-radius: var(--radius-m) !important; } .ge-vertical-card .ge-media-card .ge-content-area, .ge-vertical-card .ge-media-card .ge-tags-container { - display: none !important; /* 隱藏標題、摘要、標籤 */ + display: none !important; + /* 隱藏標題、摘要、標籤 */ } /* 標籤容器 Tags Container */ @@ -406,7 +411,8 @@ } .ge-grid-item.ge-folder-item .ge-content-area { - min-height: 0px; /* 設定最小高度 */ + min-height: 0px; + /* 設定最小高度 */ justify-content: center; } @@ -686,11 +692,13 @@ @container (max-width: 350px) { .ge-header-buttons { gap: 7px; - padding: 9px 7px; /* 保持上下 padding 9px,減少左右 padding 到 6px */ + padding: 9px 7px; + /* 保持上下 padding 9px,減少左右 padding 到 6px */ } .ge-header-buttons button { - padding: 6px 9px; /* 保持上下 padding 6px,減少左右 padding 到 8px */ + padding: 6px 9px; + /* 保持上下 padding 6px,減少左右 padding 到 8px */ gap: 3px; font-size: 13px; } @@ -1260,8 +1268,10 @@ a.ge-current-folder:hover { .ge-search-text { font-size: 14px; color: var(--text-normal); - flex-grow: 1; /* 讓文字填滿剩餘空間 */ - min-width: 0; /* 防止内容溢出 */ + flex-grow: 1; + /* 讓文字填滿剩餘空間 */ + min-width: 0; + /* 防止内容溢出 */ overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -1627,7 +1637,8 @@ a.ge-current-folder:hover { /* 拖曳預覽 Drag Preview */ .ge-custom-drag-preview { position: absolute; - top: -1000px; /* 隱藏在視窗外 */ + top: -1000px; + /* 隱藏在視窗外 */ left: -1000px; font-size: var(--font-ui-small); white-space: nowrap; @@ -2383,7 +2394,8 @@ a.ge-current-folder:hover { } .ge-explorer-folder-children { - margin-left: 0; /* 由 header paddingLeft 控制縮排 */ + margin-left: 0; + /* 由 header paddingLeft 控制縮排 */ } .ge-explorer-folder-children.is-collapsed { @@ -2393,32 +2405,40 @@ a.ge-current-folder:hover { /* ExplorerView - Mobile spacing & touch targets */ .is-mobile .ge-explorer-folder-header, .is-mobile .ge-explorer-mode-item { - padding: 8px 10px; /* ↑ from 4px 6px */ - gap: 10px; /* ↑ from 6px */ - min-height: 36px; /* 提升最小點擊高度,可視需要調整到 40–44px */ + padding: 8px 10px; + /* ↑ from 4px 6px */ + gap: 10px; + /* ↑ from 6px */ + min-height: 36px; + /* 提升最小點擊高度,可視需要調整到 40–44px */ border-radius: var(--radius-s); } /* 頂層根節點 header 的外距在手機放大一點,避免項目太擠 */ -.is-mobile .ge-explorer-view-container > .ge-explorer-folder-node > .ge-explorer-folder-header { - margin: 8px 10px; /* ↑ from 6px 8px */ +.is-mobile .ge-explorer-view-container>.ge-explorer-folder-node>.ge-explorer-folder-header { + margin: 8px 10px; + /* ↑ from 6px 8px */ } /* 讓切換箭頭與圖示在手機更好點 */ .is-mobile .ge-explorer-folder-toggle, .is-mobile .ge-explorer-folder-icon { - width: 20px; /* ↑ from 16px */ - height: 20px; /* ↑ from 16px */ + width: 20px; + /* ↑ from 16px */ + height: 20px; + /* ↑ from 16px */ } /* 模式子項的縮排在手機視覺可略加(可選) */ .is-mobile .ge-explorer-mode-item { - padding-left: 32px; /* ↑ from 28px */ + padding-left: 32px; + /* ↑ from 28px */ } /* 列與列之間多一點空隙(可選,避免過度擁擠) */ .is-mobile .ge-explorer-folder-header { - margin-bottom: 5px; /* ↑ from 3px */ + margin-bottom: 5px; + /* ↑ from 3px */ } /* 降低手機點擊的藍色高亮痕跡(可選) */ @@ -2430,8 +2450,9 @@ a.ge-current-folder:hover { /* --------------------------------------------------------------------------- */ /* 統一三個根節點(自訂模式/模式/Folder)的上下間距與外觀 */ /* 頂層根節點 header:統一外距與圓角(自訂模式/模式/Folder) */ -.ge-explorer-view-container > .ge-explorer-folder-node > .ge-explorer-folder-header { - margin: 6px 8px; /* 一致的左右/上下間距 */ +.ge-explorer-view-container>.ge-explorer-folder-node>.ge-explorer-folder-header { + margin: 6px 8px; + /* 一致的左右/上下間距 */ border-radius: var(--radius-s); } @@ -2516,7 +2537,8 @@ a.ge-current-folder:hover { flex: 1 1 auto; min-width: 0; height: 28px; - padding: 4px 28px 4px 8px; /* 右側預留清除鍵空間 */ + padding: 4px 28px 4px 8px; + /* 右側預留清除鍵空間 */ background: transparent; border: none; outline: none; @@ -2563,7 +2585,8 @@ a.ge-current-folder:hover { /* --------------------------------------------------------------------------- */ /* ExplorerView Stash Group */ .ge-explorer-stash-dropzone { - padding-left: 28px; /* 與 .ge-explorer-mode-item 一致的縮排 */ + padding-left: 28px; + /* 與 .ge-explorer-mode-item 一致的縮排 */ border: 1px dashed var(--background-modifier-border); border-radius: var(--radius-s); margin: 4px 0px 4px -1px; @@ -2596,15 +2619,18 @@ a.ge-current-folder:hover { } .ge-explorer-stash-item { - padding-left: 28px; /* 與 .ge-explorer-mode-item 一致的縮排 */ - position: relative; /* 供插入指示線定位 */ + padding-left: 28px; + /* 與 .ge-explorer-mode-item 一致的縮排 */ + position: relative; + /* 供插入指示線定位 */ } /* 暫存區拖曳排序:插入指示線(上方) */ .ge-explorer-stash-item.ge-stash-insert-before::before { content: ""; position: absolute; - left: 20px; /* 與內容縮排對齊,略小於 28px 以避開圖示 */ + left: 20px; + /* 與內容縮排對齊,略小於 28px 以避開圖示 */ right: 8px; top: -1px; height: 0; @@ -2653,4 +2679,28 @@ a.ge-current-folder:hover { .ge-input-error { border-color: var(--color-red) !important; background-color: rgba(var(--color-red-rgb), 0.1) !important; +} + +/* --------------------------------------------------------------------------- */ +/* 手機版頂部邊距適配 (針對 Obsidian 更新後的介面調整) */ + +.is-phone .ge-grid-view-container, +.is-phone .ge-note-view-container { + /* 讓整個插件容器避開頂部安全區域 (狀態列/瀏海) */ + /* Obsidian 更新後將此變數用於處理頂部間距 */ + padding-top: var(--safe-area-inset-top); + padding-left: var(--safe-area-inset-left); + padding-right: var(--safe-area-inset-right); +} + +/* 移除 Obsidian 預設為 .view-content 添加的 margin-top, + 因為 GridExplorer 的 header buttons 位在 view-content 之外, + 這會導致 buttons 與 grid 之間出現多餘的空隙。 */ +.is-phone .ge-grid-view-container .view-content { + margin-top: 0 !important; + padding-bottom: calc(var(--view-bottom-spacing) + var(--size-4-3)) !important; +} + +.is-phone .ge-note-view-container { + padding-bottom: var(--view-bottom-spacing) !important; } \ No newline at end of file diff --git a/versions.json b/versions.json index 2ef4290..7f13794 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "3.0.2": "1.1.0" + "3.0.3": "1.1.0" } \ No newline at end of file