This commit is contained in:
Devon22 2026-01-13 15:46:35 +08:00
parent c62da3e004
commit 5c8d190ef4
6 changed files with 114 additions and 63 deletions

View file

@ -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",

6
package-lock.json generated
View file

@ -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 @@
}
}
}
}
}

View file

@ -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"
}
}
}

View file

@ -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;
}

View file

@ -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; /* 提升最小點擊高度,可視需要調整到 4044px */
padding: 8px 10px;
/* ↑ from 4px 6px */
gap: 10px;
/* ↑ from 6px */
min-height: 36px;
/* 提升最小點擊高度,可視需要調整到 4044px */
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;
}

View file

@ -1,3 +1,3 @@
{
"3.0.2": "1.1.0"
"3.0.3": "1.1.0"
}