mirror of
https://github.com/devon22/obsidian-gridexplorer.git
synced 2026-07-22 12:00:25 +00:00
3.0.3
This commit is contained in:
parent
c62da3e004
commit
5c8d190ef4
6 changed files with 114 additions and 63 deletions
|
|
@ -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
6
package-lock.json
generated
|
|
@ -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 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
120
styles.css
120
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;
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"3.0.2": "1.1.0"
|
||||
"3.0.3": "1.1.0"
|
||||
}
|
||||
Loading…
Reference in a new issue