This commit is contained in:
Devon22 2025-07-28 00:58:55 +08:00
parent ff12994654
commit 72d23b806f
12 changed files with 113 additions and 49 deletions

View file

@ -1,7 +1,7 @@
{
"id": "gridexplorer",
"name": "GridExplorer",
"version": "2.7.6",
"version": "2.7.7",
"minAppVersion": "1.1.0",
"description": "Browse note files in a grid view.",
"author": "Devon22",

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "gridexplorer",
"version": "2.7.6",
"version": "2.7.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gridexplorer",
"version": "2.7.6",
"version": "2.7.7",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",

View file

@ -1,6 +1,6 @@
{
"name": "gridexplorer",
"version": "2.7.6",
"version": "2.7.7",
"description": "Browse note files in a grid view.",
"main": "main.js",
"scripts": {

View file

@ -174,8 +174,8 @@ export class FileWatcher {
// 以 200ms 去抖動的方式排程 render避免短時間內大量重繪
private scheduleRender = (delay: number = 200): void => {
// 若分頁被釘選,暫停重新渲染
if (this.gridView.isPinned()) {
// 若分頁被釘選或正在顯示筆記,暫停重新渲染
if (this.gridView.isPinned() || this.gridView.isShowingNote) {
return;
}
if(this.gridView.sourceMode === 'recent-files' && this.gridView.containerEl.offsetParent === null) {

View file

@ -58,7 +58,7 @@ export class GridView extends ItemView {
baseCardLayout: 'horizontal' | 'vertical' = 'horizontal'; // 使用者在設定或 UI 中選擇的基礎卡片樣式(不受資料夾臨時覆蓋影響)
cardLayout: 'horizontal' | 'vertical' = 'horizontal'; // 目前實際使用的卡片樣式(可能被資料夾 metadata 臨時覆蓋)
private renderToken: number = 0; // 用於取消尚未完成之批次排程的遞增令牌
private isShowingNote: boolean = false; // 是否正在顯示筆記
isShowingNote: boolean = false; // 是否正在顯示筆記
private noteViewContainer: HTMLElement | null = null; // 筆記檢視容器
constructor(leaf: WorkspaceLeaf, plugin: GridExplorerPlugin) {
@ -189,12 +189,31 @@ export class GridView extends ItemView {
this.searchQuery = '';
}
// 切換自訂模式時重設選項索引
if(mode.startsWith('custom-')) {
this.customOptionIndex = -1;
this.folderSortType = 'none';
}
// 更新來源模式和路徑
if(mode !== '') this.sourceMode = mode;
if(path !== '') this.sourcePath = path;
if(this.sourceMode === '') this.sourceMode = 'folder';
if(this.sourcePath === '') this.sourcePath = '/';
// 非資料夾模式時,強制路徑為根目錄
if(this.sourceMode !== 'folder') {
this.sourcePath = '/';
}
// 讀取Folder設定
this.folderSortType = '';
this.pinnedList = [];
if (mode === 'folder') {
if (this.sourceMode === 'folder') {
console.log(this.sourcePath);
// 檢查是否有與資料夾同名的 md 檔案
const folderName = path.split('/').pop() || '';
const mdFilePath = `${path}/${folderName}.md`;
const folderName = this.sourcePath.split('/').pop() || '';
const mdFilePath = `${this.sourcePath}/${folderName}.md`;
const mdFile = this.app.vault.getAbstractFileByPath(mdFilePath);
let tempLayout: 'horizontal' | 'vertical' = this.baseCardLayout;
if (mdFile instanceof TFile) {
@ -210,21 +229,6 @@ export class GridView extends ItemView {
this.cardLayout = this.baseCardLayout;
}
if(mode.startsWith('custom-')) {
this.customOptionIndex = -1; // 切換自訂模式時重設選項索引
this.folderSortType = 'none';
}
if(mode !== '') this.sourceMode = mode;
if(path !== '') this.sourcePath = path;
if(this.sourceMode === '') this.sourceMode = 'folder';
if(this.sourcePath === '') this.sourcePath = '/';
// 非資料夾模式時,強制路徑為根目錄
if(this.sourceMode !== 'folder') {
this.sourcePath = '/';
}
// 通知 Obsidian 保存視圖狀態
this.app.workspace.requestSaveLayout();
@ -2702,6 +2706,8 @@ export class GridView extends ItemView {
} else {
this.openMediaFile(file, files);
}
} else if (file.extension === 'pdf' || file.extension === 'canvas' || file.extension === 'base') {
this.app.workspace.getLeaf(true).openFile(file);
} else {
// 非媒體檔案:在 grid container 中顯示筆記
this.showNoteInGrid(file);
@ -3107,6 +3113,52 @@ export class GridView extends ItemView {
// 在 grid container 中顯示筆記
async showNoteInGrid(file: TFile) {
// 檢查是否為捷徑檔案
const fileCache = this.app.metadataCache.getFileCache(file);
const redirectType = fileCache?.frontmatter?.type;
const redirectPath = fileCache?.frontmatter?.redirect;
if (redirectType && typeof redirectPath === 'string' && redirectPath.trim() !== '') {
let target;
if (redirectType === 'file') {
if (redirectPath.startsWith('[[') && redirectPath.endsWith(']]')) {
const noteName = redirectPath.slice(2, -2);
target = this.app.metadataCache.getFirstLinkpathDest(noteName, file.path);
} else {
target = this.app.vault.getAbstractFileByPath(normalizePath(redirectPath));
}
if (target instanceof TFile) {
// 遞迴處理目標檔案
this.showNoteInGrid(target);
return;
} else {
new Notice(`${t('target_not_found')}: ${redirectPath}`);
return;
}
}
else if (redirectType === 'folder') {
// 判斷redirectPath是否為資料夾
if (this.app.vault.getAbstractFileByPath(normalizePath(redirectPath)) instanceof TFolder) {
this.setSource('folder', redirectPath, true);
this.clearSelection();
return;
} else {
new Notice(`${t('target_not_found')}: ${redirectPath}`);
return;
}
} else if (redirectType === 'mode') {
// 判斷redirectPath是否為模式
this.setSource(redirectPath, '', true);
this.clearSelection();
return;
} else {
new Notice(`${t('target_not_found')}: ${redirectPath}`);
return;
}
}
// 關閉之前的筆記顯示
if (this.isShowingNote) {
this.hideNoteInGrid();
@ -3148,8 +3200,18 @@ export class GridView extends ItemView {
// 捲動內容容器
const scrollContainer = this.noteViewContainer.createDiv('ge-note-scroll-container');
// 假設在視圖側邊欄則把字型調小
const isInSidebar = this.leaf.getRoot() === this.app.workspace.leftSplit ||
this.leaf.getRoot() === this.app.workspace.rightSplit;
if (isInSidebar) {
scrollContainer.style.fontSize = '1em';
}
// 創建筆記內容容器
const noteContent = scrollContainer.createDiv('ge-note-content-container');
if (isInSidebar) {
noteContent.style.padding = '15px';
}
// 創建筆記內容區域
const noteContentArea = noteContent.createDiv('ge-note-content');

View file

@ -1,6 +1,7 @@
import { TFile, TFolder, getFrontMatterInfo, App, Notice } from 'obsidian';
import { type GallerySettings } from './settings';
import { GridView } from './GridView';
import { type GallerySettings } from './settings';
import { t } from './translations';
// 擴展 App 類型以包含 plugins 屬性
declare module 'obsidian' {
@ -507,7 +508,7 @@ export async function getFiles(gridView: GridView, includeMediaFiles: boolean):
// 自訂模式
const dvApi = app.plugins.plugins.dataview?.api;
if (!dvApi) {
new Notice('Dataview plugin is not enabled.');
new Notice(t('Dataview plugin is not enabled.'));
return [];
}

View file

@ -1,8 +1,8 @@
import type { GridView } from "./GridView";
export function handleKeyDown(gridView: GridView, event: KeyboardEvent) {
// 如果沒有項目,直接返回
if (gridView.gridItems.length === 0) return;
// 如果沒有項目或正在檢視筆記,直接返回
if (gridView.gridItems.length === 0 || gridView.isShowingNote) return;
// 如果有Modal視窗直接返回
if (document.querySelector('.modal-container')) return;

View file

@ -193,8 +193,8 @@ export default class GridExplorerPlugin extends Plugin {
});
// 搜尋選取的筆記名稱
const link = this.app.fileManager.generateMarkdownLink(file, "");
const truncatedText = file.basename.length > 20 ? file.basename.substring(0, 20) + '...' : file.basename;
const menuItemTitle = t('search_selection_in_grid_view').replace('...', `[[${truncatedText}]]`); // 假設翻譯中有...代表要替換的部分,或者直接格式化
const truncatedText = file.basename.length > 8 ? file.basename.substring(0, 8) + '...' : file.basename;
const menuItemTitle = t('search_selection_in_grid_view').replace('...', ` [[${truncatedText}]]`); // 假設翻譯中有...代表要替換的部分,或者直接格式化
menu.addItem(item => {
item
.setTitle(menuItemTitle)
@ -229,8 +229,8 @@ export default class GridExplorerPlugin extends Plugin {
this.app.workspace.on('editor-menu', (menu: Menu, editor) => {
if (editor.somethingSelected()) {
const selectedText = editor.getSelection();
// 截斷過長的文字,最多顯示 20 個字元
const truncatedText = selectedText.length > 20 ? selectedText.substring(0, 20) + '...' : selectedText;
// 截斷過長的文字,最多顯示 15 個字元
const truncatedText = selectedText.length > 15 ? selectedText.substring(0, 15) + '...' : selectedText;
const menuItemTitle = t('search_selection_in_grid_view').replace('...', `${truncatedText}`); // 假設翻譯中有...代表要替換的部分,或者直接格式化
menu.addItem(item => {
@ -257,8 +257,8 @@ export default class GridExplorerPlugin extends Plugin {
// 註冊tag-wrangler右鍵選單
this.registerEvent(
(this.app.workspace as any).on('tag-wrangler:contextmenu', (menu: Menu, tagName: string) => {
// 截斷過長的文字,最多顯示 20 個字元
const truncatedText = tagName.length > 20 ? tagName.substring(0, 20) + '...' : tagName;
// 截斷過長的文字,最多顯示 15 個字元
const truncatedText = tagName.length > 15 ? tagName.substring(0, 15) + '...' : tagName;
const menuItemTitle = t('search_selection_in_grid_view').replace('...', `「#${truncatedText}`); // 假設翻譯中有...代表要替換的部分,或者直接格式化
menu.addItem(item => {

View file

@ -67,7 +67,7 @@ export class ShortcutSelectionModal extends Modal {
modeOptions.push({
type: 'mode',
value: mode.internalName,
display: `🧩 ${mode.displayName}`
display: `${mode.icon} ${mode.displayName}`
});
});

View file

@ -206,11 +206,11 @@ export const TRANSLATIONS: Translations = {
'select_folders': '選擇資料夾',
'select_folders_to_ignore': '選擇要忽略的資料夾',
'open_grid_view': '開啟網格視圖',
'open_in_grid_view': '在網格視圖開啟',
'open_note_in_grid_view': '在網格視圖開啟當前筆記',
'open_backlinks_in_grid_view': '在網格視圖開啟反向連結',
'open_outgoinglinks_in_grid_view': '在網格視圖開啟外部連結',
'open_recent_files_in_grid_view': '在最近檔案開啟當前筆記',
'open_in_grid_view': '在網格視圖開啟',
'open_note_in_grid_view': '在網格視圖開啟當前筆記',
'open_backlinks_in_grid_view': '在網格視圖開啟反向連結',
'open_outgoinglinks_in_grid_view': '在網格視圖開啟外部連結',
'open_recent_files_in_grid_view': '在最近檔案開啟當前筆記',
'open_settings': '開啟設定',
'open_new_grid_view': '開啟新網格視圖',
'open_in_new_grid_view': '在新網格視圖中開啟',
@ -263,7 +263,7 @@ export const TRANSLATIONS: Translations = {
'set_note_attribute': '設定筆記屬性',
'rename_folder': '重新命名資料夾',
'enter_new_folder_name': '輸入新資料夾名稱',
'search_selection_in_grid_view': '在網格視圖搜尋...',
'search_selection_in_grid_view': '在網格視圖搜尋...',
'show_date_dividers': '顯示日期分隔器',
'show_date_dividers_desc': '在日期相關排序時,在不同天的第一筆之前顯示日期分隔器',
'date_divider_format': '日期分隔器格式',
@ -753,10 +753,10 @@ export const TRANSLATIONS: Translations = {
'select_folders_to_ignore': '选择要忽略的文件夹',
'open_grid_view': '打开网格视图',
'open_in_grid_view': '在网格视图中打开',
'open_note_in_grid_view': '在网格视图打开当前笔记',
'open_backlinks_in_grid_view': '在网格视图打开反向链接',
'open_outgoinglinks_in_grid_view': '在网格视图打开外部链接',
'open_recent_files_in_grid_view': '在最近文件打开当前笔记',
'open_note_in_grid_view': '在网格视图打开当前笔记',
'open_backlinks_in_grid_view': '在网格视图打开反向链接',
'open_outgoinglinks_in_grid_view': '在网格视图打开外部链接',
'open_recent_files_in_grid_view': '在最近文件打开当前笔记',
'open_settings': '打开设置',
'open_new_grid_view': '打开新网格视图',
'open_in_new_grid_view': '在新网格视图中打开',
@ -809,7 +809,7 @@ export const TRANSLATIONS: Translations = {
'set_note_attribute': '设置笔记属性',
'rename_folder': '重新命名文件夹',
'enter_new_folder_name': '输入新文件夹名称',
'search_selection_in_grid_view': '在网格视图搜寻...',
'search_selection_in_grid_view': '在网格视图搜寻...',
'show_date_dividers': '显示日期分隔器',
'show_date_dividers_desc': '在日期相关排序时,在不同天的第一条之前显示日期分隔器',
'date_divider_format': '日期分隔器格式',

View file

@ -1653,7 +1653,8 @@ a.ge-current-folder:hover {
.ge-note-scroll-container {
flex: 1 1 auto;
overflow: auto;
background-color: var(--background-secondary);
background-color: var(--background-primary);
font-size: var(--font-text-size);
}
.ge-note-close-button,

View file

@ -1,3 +1,3 @@
{
"2.7.6": "1.1.0"
"2.7.7": "1.1.0"
}