mirror of
https://github.com/devon22/obsidian-gridexplorer.git
synced 2026-07-22 05:38:16 +00:00
2.6.4
This commit is contained in:
parent
3e0143289d
commit
ba61dbdc42
16 changed files with 291 additions and 93 deletions
|
|
@ -15,7 +15,7 @@ const context = await esbuild.context({
|
|||
banner: {
|
||||
js: banner,
|
||||
},
|
||||
entryPoints: ["main.ts"],
|
||||
entryPoints: ["src/main.ts"],
|
||||
bundle: true,
|
||||
external: [
|
||||
"obsidian",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "gridexplorer",
|
||||
"name": "GridExplorer",
|
||||
"version": "2.6.3",
|
||||
"version": "2.6.4",
|
||||
"minAppVersion": "1.1.0",
|
||||
"description": "Browse note files in a grid view.",
|
||||
"author": "Devon22",
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "gridexplorer",
|
||||
"version": "2.6.3",
|
||||
"version": "2.6.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "gridexplorer",
|
||||
"version": "2.6.3",
|
||||
"version": "2.6.4",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^16.11.6",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "gridexplorer",
|
||||
"version": "2.6.3",
|
||||
"version": "2.6.4",
|
||||
"description": "Browse note files in a grid view.",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, TFile } from 'obsidian';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import GridExplorerPlugin from './main';
|
||||
import { GridView } from './GridView';
|
||||
import { isDocumentFile, isMediaFile } from './fileUtils';
|
||||
|
||||
|
|
@ -22,6 +22,19 @@ export class FileWatcher {
|
|||
return;
|
||||
}
|
||||
|
||||
//編輯檔案
|
||||
this.plugin.registerEvent(
|
||||
this.app.vault.on('modify', (file) => {
|
||||
if (file instanceof TFile) {
|
||||
if (this.gridView.sourceMode === 'recent-files') {
|
||||
if(isDocumentFile(file) || (isMediaFile(file) && this.gridView.randomNoteIncludeMedia)) {
|
||||
this.scheduleRender(3000);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
//新增檔案
|
||||
this.plugin.registerEvent(
|
||||
this.app.vault.on('create', (file) => {
|
||||
|
|
@ -151,6 +164,10 @@ export class FileWatcher {
|
|||
|
||||
// 以 200ms 去抖動的方式排程 render,避免短時間內大量重繪
|
||||
private scheduleRender = (delay: number = 200): void => {
|
||||
// 若分頁被釘選,暫停重新渲染
|
||||
if (this.gridView.isPinned()) {
|
||||
return;
|
||||
}
|
||||
if (this.renderTimer !== null) {
|
||||
clearTimeout(this.renderTimer);
|
||||
}
|
||||
|
|
|
|||
185
src/GridView.ts
185
src/GridView.ts
|
|
@ -1,6 +1,6 @@
|
|||
import { WorkspaceLeaf, ItemView, TFolder, TFile, Menu, Notice, Platform, setIcon, getFrontMatterInfo, FrontMatterCache, normalizePath, setTooltip } from 'obsidian';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { handleKeyDown as handleKeyDownHelper } from './handleKeyDown';
|
||||
import GridExplorerPlugin from './main';
|
||||
import { handleKeyDown } from './handleKeyDown';
|
||||
import { isDocumentFile, isMediaFile, isImageFile, isVideoFile, isAudioFile, sortFiles, ignoredFiles, getFiles, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS, isFolderIgnored } from './fileUtils';
|
||||
import { FileWatcher } from './fileWatcher';
|
||||
import { findFirstImageInNote } from './mediaUtils';
|
||||
|
|
@ -48,6 +48,7 @@ export class GridView extends ItemView {
|
|||
showIgnoredFolders: boolean = false; // 顯示忽略資料夾
|
||||
pinnedList: string[] = []; // 置頂清單
|
||||
taskFilter: string = 'uncompleted'; // 任務分類
|
||||
hideHeaderElements: boolean = false; // 是否隱藏標題列元素(模式名稱和按鈕)
|
||||
customOptionIndex: number = -1; // 自訂模式選項索引
|
||||
// 使用者在設定或 UI 中選擇的基礎卡片樣式(不受資料夾臨時覆蓋影響)
|
||||
baseCardLayout: 'horizontal' | 'vertical' = 'horizontal';
|
||||
|
|
@ -74,7 +75,7 @@ export class GridView extends ItemView {
|
|||
this.registerDomEvent(document, 'keydown', (event: KeyboardEvent) => {
|
||||
// 只有當 GridView 是活動視圖時才處理鍵盤事件
|
||||
if (this.app.workspace.getActiveViewOfType(GridView) === this) {
|
||||
this.handleKeyDown(event);
|
||||
return handleKeyDown(this, event);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -141,6 +142,11 @@ export class GridView extends ItemView {
|
|||
}
|
||||
}
|
||||
|
||||
// 判斷當前Leaf是否被釘選
|
||||
isPinned(): boolean {
|
||||
return (this.leaf as any)?.pinned ?? false;
|
||||
}
|
||||
|
||||
// 將來源加入歷史記錄(LRU 去重)
|
||||
// 1. 若已有相同紀錄先移除,確保唯一
|
||||
// 2. 插入到陣列開頭,代表最新使用
|
||||
|
|
@ -166,6 +172,11 @@ export class GridView extends ItemView {
|
|||
this.pushHistory(this.sourceMode, this.sourcePath);
|
||||
}
|
||||
|
||||
// 全域搜尋時切換路徑則清空搜尋
|
||||
if (this.searchQuery !== '' && this.searchAllFiles) {
|
||||
this.searchQuery = '';
|
||||
}
|
||||
|
||||
this.folderSortType = '';
|
||||
this.pinnedList = [];
|
||||
if (mode === 'folder') {
|
||||
|
|
@ -240,7 +251,7 @@ export class GridView extends ItemView {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 添加新增筆記按鈕
|
||||
const newNoteButton = headerButtonsDiv.createEl('button', { attr: { 'aria-label': t('new_note') } });
|
||||
setIcon(newNoteButton, 'square-pen');
|
||||
|
|
@ -1183,6 +1194,14 @@ export class GridView extends ItemView {
|
|||
container.empty();
|
||||
container.addClass('ge-grid-container');
|
||||
|
||||
// 隱藏頂部元素
|
||||
const displayValue = this.hideHeaderElements ? 'none' : 'flex';
|
||||
const headerButtons = this.containerEl.querySelector('.ge-header-buttons') as HTMLElement;
|
||||
const modenameContainer = this.containerEl.querySelector('.ge-modename-content') as HTMLElement;
|
||||
|
||||
if (headerButtons) headerButtons.style.display = displayValue;
|
||||
if (modenameContainer) modenameContainer.style.display = displayValue;
|
||||
|
||||
// 根據設定決定是否啟用卡片模式
|
||||
if (this.cardLayout === 'vertical') {
|
||||
container.addClass('ge-vertical-card');
|
||||
|
|
@ -1190,6 +1209,15 @@ export class GridView extends ItemView {
|
|||
container.removeClass('ge-vertical-card');
|
||||
}
|
||||
|
||||
// 添加點擊空白處取消選中的事件處理器
|
||||
container.addEventListener('click', (event) => {
|
||||
// 只有當點擊的是容器本身,而不是其子元素時才清除選中
|
||||
if (event.target === container) {
|
||||
this.clearSelection();
|
||||
this.hasKeyboardFocus = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 設定網格項目寬度和高度等設定
|
||||
const settings = this.plugin.settings;
|
||||
const gridItemWidth = this.cardLayout === 'vertical' ? settings.verticalGridItemWidth : settings.gridItemWidth;
|
||||
|
|
@ -1218,14 +1246,31 @@ export class GridView extends ItemView {
|
|||
}
|
||||
}
|
||||
|
||||
// 添加點擊空白處取消選中的事件處理器
|
||||
container.addEventListener('click', (event) => {
|
||||
// 只有當點擊的是容器本身,而不是其子元素時才清除選中
|
||||
if (event.target === container) {
|
||||
this.clearSelection();
|
||||
this.hasKeyboardFocus = false;
|
||||
}
|
||||
// 定義所有可能的模式(不包括 custom-)
|
||||
const modeClasses = [
|
||||
'bookmarks',
|
||||
'search',
|
||||
'backlinks',
|
||||
'outgoinglinks',
|
||||
'all-files',
|
||||
'recent-files',
|
||||
'random-note',
|
||||
'tasks',
|
||||
'folder'
|
||||
];
|
||||
|
||||
// 先移除所有模式相關的 class
|
||||
this.containerEl.removeClass('ge-mode-custom'); // 特別處理 custom 類別
|
||||
modeClasses.forEach(mode => {
|
||||
this.containerEl.removeClass(`ge-mode-${mode}`);
|
||||
});
|
||||
|
||||
// 添加當前模式的 class
|
||||
if (this.sourceMode.startsWith('custom-')) {
|
||||
this.containerEl.addClass('ge-mode-custom');
|
||||
} else if (modeClasses.includes(this.sourceMode)) {
|
||||
this.containerEl.addClass(`ge-mode-${this.sourceMode}`);
|
||||
}
|
||||
|
||||
// 重置網格項目數組
|
||||
this.gridItems = [];
|
||||
|
|
@ -1410,9 +1455,15 @@ export class GridView extends ItemView {
|
|||
}
|
||||
|
||||
// 點擊時進入子資料夾
|
||||
folderEl.addEventListener('click', () => {
|
||||
this.setSource('folder', folder.path, true);
|
||||
this.clearSelection();
|
||||
folderEl.addEventListener('click', (event) => {
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.openFolderInNewView(folder.path);
|
||||
} else {
|
||||
this.setSource('folder', folder.path, true);
|
||||
this.clearSelection();
|
||||
}
|
||||
});
|
||||
|
||||
// 添加右鍵選單
|
||||
|
|
@ -1423,35 +1474,10 @@ export class GridView extends ItemView {
|
|||
//在新網格視圖開啟
|
||||
menu.addItem((item) => {
|
||||
item
|
||||
.setTitle( t('open_in_new_grid_view'))
|
||||
.setTitle(t('open_in_new_grid_view'))
|
||||
.setIcon('grid')
|
||||
.onClick(() => {
|
||||
const { workspace } = this.app;
|
||||
let leaf = null;
|
||||
workspace.getLeavesOfType('grid-view');
|
||||
switch (this.plugin.settings.defaultOpenLocation) {
|
||||
case 'left':
|
||||
leaf = workspace.getLeftLeaf(false);
|
||||
break;
|
||||
case 'right':
|
||||
leaf = workspace.getRightLeaf(false);
|
||||
break;
|
||||
case 'tab':
|
||||
default:
|
||||
leaf = workspace.getLeaf('tab');
|
||||
break;
|
||||
}
|
||||
if (!leaf) {
|
||||
// 如果無法獲取指定位置的 leaf,則回退到新分頁
|
||||
leaf = workspace.getLeaf('tab');
|
||||
}
|
||||
leaf.setViewState({ type: 'grid-view', active: true });
|
||||
// 設定資料來源
|
||||
if (leaf.view instanceof GridView) {
|
||||
leaf.view.setSource('folder', folder.path);
|
||||
}
|
||||
// 確保視圖是活躍的
|
||||
workspace.revealLeaf(leaf);
|
||||
this.openFolderInNewView(folder.path);
|
||||
});
|
||||
});
|
||||
menu.addSeparator();
|
||||
|
|
@ -2021,20 +2047,18 @@ export class GridView extends ItemView {
|
|||
//將預覽文字設定到標題的 title 屬性中
|
||||
const titleEl = fileEl.querySelector('.ge-title');
|
||||
if (titleEl) {
|
||||
setTooltip(contentArea as HTMLElement, `${titleEl.textContent}`, { placement: this.cardLayout === 'vertical' ? 'bottom' : 'right' })
|
||||
setTooltip(contentArea as HTMLElement, `${titleEl.textContent}`)
|
||||
}
|
||||
|
||||
if (frontMatterInfo.exists) {
|
||||
const colorValue = metadata?.color;
|
||||
if (colorValue) {
|
||||
// 設置背景色、框線色和文字顏色
|
||||
fileEl.setAttribute('style', `
|
||||
background-color: rgba(var(--color-${colorValue}-rgb), 0.2);
|
||||
border-color: rgba(var(--color-${colorValue}-rgb), 0.5);
|
||||
`);
|
||||
// 使用 CSS 類別來設置顏色
|
||||
fileEl.addClass(`ge-note-color-${colorValue}`);
|
||||
|
||||
// 設置預覽內容文字顏色
|
||||
if (pEl) {
|
||||
pEl.style.color = `rgba(var(--color-${colorValue}-rgb), 0.7)`;
|
||||
pEl.addClass(`ge-note-color-${colorValue}-text`);
|
||||
}
|
||||
}
|
||||
const titleField = this.plugin.settings.noteTitleField || 'title';
|
||||
|
|
@ -2068,7 +2092,7 @@ export class GridView extends ItemView {
|
|||
contentArea.createEl('p', { text: file.extension.toUpperCase() });
|
||||
}
|
||||
|
||||
setTooltip(fileEl as HTMLElement, `${file.name}`, { placement: this.cardLayout === 'vertical' ? 'bottom' : 'right' })
|
||||
setTooltip(fileEl as HTMLElement, `${file.name}`)
|
||||
}
|
||||
|
||||
// 顯示標籤(僅限 Markdown 檔案)
|
||||
|
|
@ -2457,7 +2481,6 @@ export class GridView extends ItemView {
|
|||
const displayText = shouldShowExtension ? `${file.basename}.${file.extension}` : file.basename;
|
||||
const titleEl = titleContainer.createEl('span', { cls: 'ge-title', text: displayText });
|
||||
if (this.plugin.settings.multiLineTitle) titleEl.addClass('ge-multiline-title');
|
||||
//titleEl.setAttribute('title', displayText);
|
||||
|
||||
// 創建圖片區域,但先不載入圖片
|
||||
if (!this.minMode) {
|
||||
|
|
@ -2691,9 +2714,63 @@ export class GridView extends ItemView {
|
|||
});
|
||||
}
|
||||
|
||||
// 處理鍵盤導航
|
||||
handleKeyDown(event: KeyboardEvent) {
|
||||
return handleKeyDownHelper(this, event);
|
||||
onPaneMenu(menu: Menu, source: string) {
|
||||
menu.addItem(item => {
|
||||
item
|
||||
.setTitle(t('hide_header_elements'))
|
||||
.setIcon("archive-restore")
|
||||
.setChecked(this.hideHeaderElements)
|
||||
.onClick(() => {
|
||||
this.hideHeaderElements = !this.hideHeaderElements;
|
||||
this.render(true);
|
||||
});
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item
|
||||
.setTitle(t('reselect'))
|
||||
.setIcon("grid")
|
||||
.onClick(() => {
|
||||
showFolderSelectionModal(this.app, this.plugin, this);
|
||||
});
|
||||
});
|
||||
menu.addItem((item) => {
|
||||
item
|
||||
.setTitle(t('refresh'))
|
||||
.setIcon("refresh-cw")
|
||||
.onClick(() => {
|
||||
this.render(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 在新視窗中開啟資料夾
|
||||
private openFolderInNewView(folderPath: string) {
|
||||
const { workspace } = this.app;
|
||||
let leaf = null;
|
||||
workspace.getLeavesOfType('grid-view');
|
||||
switch (this.plugin.settings.defaultOpenLocation) {
|
||||
case 'left':
|
||||
leaf = workspace.getLeftLeaf(false);
|
||||
break;
|
||||
case 'right':
|
||||
leaf = workspace.getRightLeaf(false);
|
||||
break;
|
||||
case 'tab':
|
||||
default:
|
||||
leaf = workspace.getLeaf('tab');
|
||||
break;
|
||||
}
|
||||
if (!leaf) {
|
||||
// 如果無法獲取指定位置的 leaf,則回退到新分頁
|
||||
leaf = workspace.getLeaf('tab');
|
||||
}
|
||||
leaf.setViewState({ type: 'grid-view', active: true });
|
||||
// 設定資料來源
|
||||
if (leaf.view instanceof GridView) {
|
||||
leaf.view.setSource('folder', folderPath);
|
||||
}
|
||||
// 確保視圖是活躍的
|
||||
workspace.revealLeaf(leaf);
|
||||
}
|
||||
|
||||
// 清除選中狀態
|
||||
|
|
@ -2824,6 +2901,7 @@ export class GridView extends ItemView {
|
|||
showIgnoredFolders: this.showIgnoredFolders,
|
||||
baseCardLayout: this.baseCardLayout,
|
||||
cardLayout: this.cardLayout,
|
||||
hideHeaderElements: this.hideHeaderElements,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -2843,6 +2921,7 @@ export class GridView extends ItemView {
|
|||
this.showIgnoredFolders = state.state.showIgnoredFolders ?? false;
|
||||
this.baseCardLayout = state.state.baseCardLayout ?? 'horizontal';
|
||||
this.cardLayout = state.state.cardLayout ?? this.baseCardLayout; // 同步 baseCardLayout 的卡片樣式,以便 render() 使用正確的 cardLayout
|
||||
this.hideHeaderElements = state.state.hideHeaderElements ?? false;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import { Plugin, TFolder, TFile, App, Menu, WorkspaceLeaf } from 'obsidian';
|
||||
import { GridView } from './src/GridView';
|
||||
import { updateCustomDocumentExtensions } from './src/fileUtils';
|
||||
import { showFolderSelectionModal } from './src/modal/folderSelectionModal';
|
||||
import { showNoteSettingsModal } from './src/modal/noteSettingsModal';
|
||||
import { GallerySettings, DEFAULT_SETTINGS, GridExplorerSettingTab } from './src/settings';
|
||||
import { t } from './src/translations';
|
||||
import { GridView } from './GridView';
|
||||
import { updateCustomDocumentExtensions } from './fileUtils';
|
||||
import { showFolderSelectionModal } from './modal/folderSelectionModal';
|
||||
import { showNoteSettingsModal } from './modal/noteSettingsModal';
|
||||
import { GallerySettings, DEFAULT_SETTINGS, GridExplorerSettingTab } from './settings';
|
||||
import { t } from './translations';
|
||||
|
||||
export default class GridExplorerPlugin extends Plugin {
|
||||
settings: GallerySettings;
|
||||
|
|
@ -128,9 +128,6 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
|
||||
// 註冊狀態列項目
|
||||
this.statusBarItem = this.addStatusBarItem();
|
||||
// this.statusBarItem.onClickEvent(() => {
|
||||
// this.activateView();
|
||||
// });
|
||||
|
||||
// 註冊資料夾的右鍵選單
|
||||
this.registerEvent(
|
||||
|
|
@ -392,9 +389,61 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
}),
|
||||
);
|
||||
|
||||
// console.log('GridExplorer: Starting cache warming process.');
|
||||
// this.startWarmingCache();
|
||||
});
|
||||
}
|
||||
|
||||
// startWarmingCache() {
|
||||
// // 1. 取得所有 Markdown 檔案的列表
|
||||
// const filesToWarm = this.app.vault.getMarkdownFiles();
|
||||
// if (!filesToWarm || filesToWarm.length === 0) {
|
||||
// console.log('GridExplorer: No markdown files to warm.');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 建立一個檔案佇列 (Queue)
|
||||
// let fileQueue = [...filesToWarm];
|
||||
// console.log(`GridExplorer: Warming up cache for ${fileQueue.length} files.`);
|
||||
|
||||
// // 2. 定義處理單個檔案的函式
|
||||
// // 我們會使用 app.vault.cachedRead 來讀取檔案內容,
|
||||
// // 這個動作會觸發 Obsidian 的快取機制。
|
||||
// const processFile = (file: TFile) => {
|
||||
// try {
|
||||
// // 核心操作:讀取檔案。我們不需要對回傳的 content 做任何事。
|
||||
// this.app.vault.cachedRead(file);
|
||||
// // console.log(`Warmed: ${file.path}`); // 可選:用於除錯
|
||||
// } catch (e) {
|
||||
// console.error(`GridExplorer: Failed to warm cache for ${file.path}:`, e);
|
||||
// }
|
||||
// };
|
||||
|
||||
// // 3. 使用 requestIdleCallback 來排程任務
|
||||
// const scheduleNextBatch = (deadline: IdleDeadline) => {
|
||||
// // deadline.timeRemaining() 會告訴我們還有多少閒置時間 (毫秒)
|
||||
// // 只要還有閒置時間,並且佇列中還有檔案,我們就繼續處理。
|
||||
// while (deadline.timeRemaining() > 0 && fileQueue.length > 0) {
|
||||
// // 從佇列的前端取出一個檔案來處理
|
||||
// const file = fileQueue.shift();
|
||||
// if (file) {
|
||||
// processFile(file);
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 如果佇列中還有檔案沒處理完,就排程下一次的 requestIdleCallback
|
||||
// if (fileQueue.length > 0) {
|
||||
// requestIdleCallback(scheduleNextBatch);
|
||||
// } else {
|
||||
// console.log('GridExplorer: Cache warming complete.');
|
||||
// }
|
||||
// };
|
||||
|
||||
// // 4. 啟動第一個閒置回呼
|
||||
// requestIdleCallback(scheduleNextBatch);
|
||||
// }
|
||||
|
||||
// 設定 Canvas 拖曳處理
|
||||
private setupCanvasDropHandlers() {
|
||||
const setup = () => {
|
||||
this.app.workspace.getLeavesOfType('canvas').forEach(leaf => {
|
||||
|
|
@ -434,7 +483,7 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
filePath = paths[0];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Grid Explorer: Failed to parse drop data from Grid Explorer.", e);
|
||||
console.error("GridExplorer: Failed to parse drop data from GridExplorer.", e);
|
||||
}
|
||||
|
||||
// 如果無法取得檔案路徑,則中止操作
|
||||
|
|
@ -444,7 +493,7 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
|
||||
const tfile = this.app.vault.getAbstractFileByPath(filePath);
|
||||
if (!(tfile instanceof TFile)) {
|
||||
console.warn('Grid Explorer: Dropped item is not a TFile or could not be found.', filePath);
|
||||
console.warn('GridExplorer: Dropped item is not a TFile or could not be found.', filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -475,6 +524,7 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
setup(); // 首次執行設定
|
||||
}
|
||||
|
||||
// 打開最近文件
|
||||
async openNoteInRecentFiles(file: TFile) {
|
||||
const view = await this.activateView('recent-files') as GridView;
|
||||
// 如果是文件,等待視圖渲染完成後捲動到該文件位置
|
||||
|
|
@ -502,6 +552,7 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
// 打開筆記到資料夾模式
|
||||
async openNoteInFolder(file: TFile | TFolder = this.app.vault.getRoot()) {
|
||||
// 如果是文件,使用其父資料夾路徑
|
||||
const folderPath = file ? (file instanceof TFile ? file.parent?.path : file.path) : "/";
|
||||
|
|
@ -532,6 +583,7 @@ export default class GridExplorerPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
// 激活視圖
|
||||
async activateView(mode = 'folder', path = '') {
|
||||
const { workspace } = this.app;
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, Modal, Setting, Notice } from 'obsidian';
|
||||
import GridExplorerPlugin from '../../main';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { CustomMode } from '../settings';
|
||||
import { t } from '../translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, Modal, Setting, TFolder, TFile } from 'obsidian';
|
||||
import GridExplorerPlugin from '../../main';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { GridView } from '../GridView';
|
||||
import { t } from '../translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, Modal, Setting, TFolder, normalizePath } from 'obsidian';
|
||||
import GridExplorerPlugin from '../../main';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { GridView } from '../GridView';
|
||||
import { t } from '../translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, Modal, Platform } from 'obsidian';
|
||||
import GridExplorerPlugin from '../../main';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { GridView } from '../GridView';
|
||||
import { t } from '../translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, Modal, Setting, TFile } from 'obsidian';
|
||||
import GridExplorerPlugin from '../../main';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import { GridView } from '../GridView';
|
||||
import { t } from '../translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { App, PluginSettingTab, Setting, AbstractInputSuggest, Notice, ButtonComponent } from 'obsidian';
|
||||
import GridExplorerPlugin from '../main';
|
||||
import GridExplorerPlugin from './main';
|
||||
import { CustomModeModal } from './modal/customModeModal';
|
||||
import { t } from './translations';
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': '預設',
|
||||
'hidden': '隱藏',
|
||||
|
||||
// 隱藏頂部元素
|
||||
'hide_header_elements': '隱藏頂部元素',
|
||||
|
||||
// 顯示"返回上層資料夾"選項設定
|
||||
'show_parent_folder_item': '顯示「返回上層資料夾」',
|
||||
'show_parent_folder_item_desc': '在網格的第一項顯示「返回上層資料夾」選項',
|
||||
|
|
@ -437,6 +440,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': 'Default',
|
||||
'hidden': 'Hidden',
|
||||
|
||||
// Hide header elements setting
|
||||
'hide_header_elements': 'Hide header elements',
|
||||
|
||||
// Show "Parent Folder" option setting
|
||||
'show_parent_folder_item': 'Show "Parent Folder" item',
|
||||
'show_parent_folder_item_desc': 'Show a "Parent Folder" item as the first item in the grid',
|
||||
|
|
@ -698,6 +704,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': '默认',
|
||||
'hidden': '隐藏',
|
||||
|
||||
// 隐藏頂部元素
|
||||
'hide_header_elements': '隱藏頂部元素',
|
||||
|
||||
// 显示"返回上级文件夹"选项设置
|
||||
'show_parent_folder_item': '显示「返回上级文件夹」',
|
||||
'show_parent_folder_item_desc': '在网格的第一项显示「返回上级文件夹」选项',
|
||||
|
|
@ -959,6 +968,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': 'デフォルト',
|
||||
'hidden': '隠す',
|
||||
|
||||
// 隠す頂部元素
|
||||
'hide_header_elements': '頂部元素を隠す',
|
||||
|
||||
// "親フォルダ"オプション設定を表示
|
||||
'show_parent_folder_item': '「親フォルダ」項目を表示',
|
||||
'show_parent_folder_item_desc': 'グリッドの最初の項目として「親フォルダ」項目を表示します',
|
||||
|
|
@ -1221,6 +1233,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': 'По умолчанию',
|
||||
'hidden': 'Скрытые',
|
||||
|
||||
// Hide header elements setting
|
||||
'hide_header_elements': 'Скрыть элементы заголовка',
|
||||
|
||||
// Show "Parent Folder" option setting
|
||||
'show_parent_folder_item': 'Показывать элемент "Родительская папка"',
|
||||
'show_parent_folder_item_desc': 'Показывать элемент "Родительская папка" первым в сетке',
|
||||
|
|
@ -1482,6 +1497,9 @@ export const TRANSLATIONS: Translations = {
|
|||
'default': 'По умолчанию',
|
||||
'hidden': 'Сховати',
|
||||
|
||||
// Hide header elements setting
|
||||
'hide_header_elements': 'Скрыть элементы заголовка',
|
||||
|
||||
// Show "Parent Folder" option setting
|
||||
'show_parent_folder_item': 'Показувати елемент "Батьківська папка"',
|
||||
'show_parent_folder_item_desc': 'Показувати елемент "Батьківська папка" першим у сітці',
|
||||
|
|
|
|||
64
styles.css
64
styles.css
|
|
@ -266,7 +266,7 @@
|
|||
|
||||
.ge-vertical-card .ge-media-card .ge-image-area img,
|
||||
.ge-vertical-card .ge-media-card .ge-image-area video {
|
||||
border-radius: 6px;
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
.ge-vertical-card .ge-media-card .ge-content-area,
|
||||
|
|
@ -372,40 +372,74 @@
|
|||
align-items: center;
|
||||
}
|
||||
|
||||
/* 資料夾顏色 Folder Color */
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-red {
|
||||
/* 資料夾和筆記顏色 Folder & Note Colors */
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-red,
|
||||
.ge-grid-item.ge-note-color-red {
|
||||
background-color: rgba(var(--color-red-rgb), 0.2);
|
||||
border-color: rgba(var(--color-red-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-orange {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-orange,
|
||||
.ge-grid-item.ge-note-color-orange {
|
||||
background-color: rgba(var(--color-orange-rgb), 0.2);
|
||||
border-color: rgba(var(--color-orange-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-yellow {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-yellow,
|
||||
.ge-grid-item.ge-note-color-yellow {
|
||||
background-color: rgba(var(--color-yellow-rgb), 0.2);
|
||||
border-color: rgba(var(--color-yellow-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-green {
|
||||
background-color: rgba(var(--color-green-rgb), 0.2);
|
||||
border-color: rgba(var(--color-green-rgb), 0.5);
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-green,
|
||||
.ge-grid-item.ge-note-color-green {
|
||||
background-color: rgba(var(--color-green-rgb), 0.2);
|
||||
border-color: rgba(var(--color-green-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-cyan {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-cyan,
|
||||
.ge-grid-item.ge-note-color-cyan {
|
||||
background-color: rgba(var(--color-cyan-rgb), 0.2);
|
||||
border-color: rgba(var(--color-cyan-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-blue {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-blue,
|
||||
.ge-grid-item.ge-note-color-blue {
|
||||
background-color: rgba(var(--color-blue-rgb), 0.2);
|
||||
border-color: rgba(var(--color-blue-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-purple {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-purple,
|
||||
.ge-grid-item.ge-note-color-purple {
|
||||
background-color: rgba(var(--color-purple-rgb), 0.2);
|
||||
border-color: rgba(var(--color-purple-rgb), 0.5);
|
||||
}
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-pink {
|
||||
.ge-grid-item.ge-folder-item.ge-folder-color-pink,
|
||||
.ge-grid-item.ge-note-color-pink {
|
||||
background-color: rgba(var(--color-pink-rgb), 0.2);
|
||||
border-color: rgba(var(--color-pink-rgb), 0.5);
|
||||
}
|
||||
|
||||
/* 筆記文字顏色 Note Text Color */
|
||||
.ge-note-color-red-text {
|
||||
color: rgba(var(--color-red-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-orange-text {
|
||||
color: rgba(var(--color-orange-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-yellow-text {
|
||||
color: rgba(var(--color-yellow-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-green-text {
|
||||
color: rgba(var(--color-green-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-cyan-text {
|
||||
color: rgba(var(--color-cyan-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-blue-text {
|
||||
color: rgba(var(--color-blue-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-purple-text {
|
||||
color: rgba(var(--color-purple-rgb), 0.7) !important;
|
||||
}
|
||||
.ge-note-color-pink-text {
|
||||
color: rgba(var(--color-pink-rgb), 0.7) !important;
|
||||
}
|
||||
|
||||
/* 資料夾上的資料夾筆記按鈕 Folder Note Button */
|
||||
.ge-foldernote-button {
|
||||
color: var(--text-muted);
|
||||
|
|
@ -508,7 +542,7 @@
|
|||
.ge-header-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
padding: 12px 16px;
|
||||
padding: 10px 16px;
|
||||
background: var(--background-primary);
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
flex-shrink: 0;
|
||||
|
|
@ -569,7 +603,6 @@
|
|||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
max-width: 200px;
|
||||
color: var(--text-normal);
|
||||
font-size: var(--font-ui-small);
|
||||
display: inline-flex;
|
||||
|
|
@ -649,12 +682,11 @@ a.ge-mode-title:hover {
|
|||
/* 當前資料夾樣式 */
|
||||
.ge-current-folder {
|
||||
font-size: var(--font-ui-small);
|
||||
font-weight: bold;
|
||||
padding: 4px 8px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
background-color: var(--background-modifier-hover);
|
||||
border: 1px solid var(--background-modifier-hover);
|
||||
color: var(--text-normal);
|
||||
border-radius: 4px;
|
||||
display: inline-flex;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
{
|
||||
"2.6.3": "1.1.0"
|
||||
"2.6.4": "1.1.0"
|
||||
}
|
||||
Loading…
Reference in a new issue