mirror of
https://github.com/devon22/obsidian-gridexplorer.git
synced 2026-07-22 12:00:25 +00:00
210 lines
7.4 KiB
TypeScript
210 lines
7.4 KiB
TypeScript
import { App, Modal, Setting, TFolder, TFile } from 'obsidian';
|
|
import { t } from './translations';
|
|
import GridExplorerPlugin from '../main';
|
|
import { GridView } from './GridView';
|
|
|
|
export interface FolderNoteSettings {
|
|
sort: string;
|
|
color: string;
|
|
icon: string;
|
|
}
|
|
|
|
export function showFolderNoteSettingsModal(app: App, plugin: GridExplorerPlugin, folder: TFolder, gridView: GridView) {
|
|
new FolderNoteSettingsModal(app, plugin, folder, gridView).open();
|
|
}
|
|
|
|
export class FolderNoteSettingsModal extends Modal {
|
|
plugin: GridExplorerPlugin;
|
|
folder: TFolder;
|
|
gridView: GridView;
|
|
settings: FolderNoteSettings = {
|
|
sort: '',
|
|
color: '',
|
|
icon: '📁'
|
|
};
|
|
existingFile: TFile | null = null;
|
|
|
|
constructor(app: App, plugin: GridExplorerPlugin, folder: TFolder, gridView: GridView) {
|
|
super(app);
|
|
this.plugin = plugin;
|
|
this.folder = folder;
|
|
this.gridView = gridView;
|
|
|
|
// 檢查同名筆記是否存在
|
|
const notePath = `${folder.path}/${folder.name}.md`;
|
|
const noteFile = this.app.vault.getAbstractFileByPath(notePath);
|
|
if (noteFile instanceof TFile) {
|
|
this.existingFile = noteFile;
|
|
}
|
|
}
|
|
|
|
async onOpen() {
|
|
const { contentEl } = this;
|
|
contentEl.empty();
|
|
|
|
// 如果筆記已存在,讀取其設定
|
|
if (this.existingFile) {
|
|
await this.loadExistingSettings();
|
|
}
|
|
|
|
// 標題
|
|
new Setting(contentEl).setName(t('folder_note_settings')).setHeading();
|
|
|
|
// 排序選項
|
|
new Setting(contentEl)
|
|
.setName(t('folder_sort_type'))
|
|
.setDesc(t('folder_sort_type_desc'))
|
|
.addDropdown(dropdown => {
|
|
dropdown
|
|
.addOption('', t('default_sort'))
|
|
.addOption('name-asc', t('sort_name_asc'))
|
|
.addOption('name-desc', t('sort_name_desc'))
|
|
.addOption('mtime-desc', t('sort_mtime_desc'))
|
|
.addOption('mtime-asc', t('sort_mtime_asc'))
|
|
.addOption('ctime-desc', t('sort_ctime_desc'))
|
|
.addOption('ctime-asc', t('sort_ctime_asc'))
|
|
.addOption('random', t('sort_random'))
|
|
.setValue(this.settings.sort)
|
|
.onChange(value => {
|
|
this.settings.sort = value;
|
|
});
|
|
});
|
|
|
|
// 顏色選項
|
|
new Setting(contentEl)
|
|
.setName(t('folder_color'))
|
|
.setDesc(t('folder_color_desc'))
|
|
.addDropdown(dropdown => {
|
|
dropdown
|
|
.addOption('', t('no_color'))
|
|
.addOption('red', t('color_red'))
|
|
.addOption('orange', t('color_orange'))
|
|
.addOption('yellow', t('color_yellow'))
|
|
.addOption('green', t('color_green'))
|
|
.addOption('cyan', t('color_cyan'))
|
|
.addOption('blue', t('color_blue'))
|
|
.addOption('purple', t('color_purple'))
|
|
.addOption('pink', t('color_pink'))
|
|
.setValue(this.settings.color)
|
|
.onChange(value => {
|
|
this.settings.color = value;
|
|
});
|
|
});
|
|
|
|
// 圖示選項
|
|
const customFolderIcon = this.plugin.settings.customFolderIcon;
|
|
new Setting(contentEl)
|
|
.setName(t('folder_icon'))
|
|
.setDesc(t('folder_icon_desc'))
|
|
.addText(text => {
|
|
text
|
|
.setPlaceholder(customFolderIcon)
|
|
.setValue(this.settings.icon || customFolderIcon)
|
|
.onChange(value => {
|
|
this.settings.icon = value || customFolderIcon;
|
|
});
|
|
});
|
|
|
|
// 按鈕區域
|
|
const buttonSetting = new Setting(contentEl);
|
|
|
|
// 顯示確認按鈕在右側
|
|
buttonSetting.addButton(button => {
|
|
button
|
|
.setButtonText(t('confirm'))
|
|
.setCta() // 設置為主要按鈕樣式
|
|
.onClick(() => {
|
|
this.saveFolderNote();
|
|
this.close();
|
|
});
|
|
});
|
|
}
|
|
|
|
// 讀取現有筆記的設定
|
|
async loadExistingSettings() {
|
|
if (!this.existingFile) return;
|
|
|
|
try {
|
|
// 使用 metadataCache 讀取筆記的 frontmatter
|
|
const fileCache = this.app.metadataCache.getFileCache(this.existingFile);
|
|
if (fileCache && fileCache.frontmatter) {
|
|
// 讀取排序設定
|
|
if ('sort' in fileCache.frontmatter) {
|
|
this.settings.sort = fileCache.frontmatter.sort || '';
|
|
}
|
|
|
|
// 讀取顏色設定
|
|
if ('color' in fileCache.frontmatter) {
|
|
this.settings.color = fileCache.frontmatter.color || '';
|
|
}
|
|
|
|
// 讀取圖示設定
|
|
if ('icon' in fileCache.frontmatter) {
|
|
this.settings.icon = fileCache.frontmatter.icon || '📁';
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('無法讀取資料夾筆記設定', error);
|
|
}
|
|
}
|
|
|
|
// 儲存或更新資料夾筆記
|
|
async saveFolderNote() {
|
|
// 建立資料夾筆記路徑
|
|
const notePath = `${this.folder.path}/${this.folder.name}.md`;
|
|
|
|
try {
|
|
let file: TFile;
|
|
|
|
// 如果筆記已存在,更新它
|
|
if (this.existingFile) {
|
|
file = this.existingFile;
|
|
}
|
|
// 否則建立新筆記
|
|
else {
|
|
// 建立筆記內容
|
|
file = await this.app.vault.create(notePath, '');
|
|
await this.app.workspace.getLeaf().openFile(file);
|
|
}
|
|
|
|
// 使用 fileManager.processFrontMatter 更新 frontmatter
|
|
await this.app.fileManager.processFrontMatter(file, (frontmatter) => {
|
|
if (this.settings.sort) {
|
|
frontmatter['sort'] = this.settings.sort;
|
|
} else {
|
|
delete frontmatter['sort'];
|
|
}
|
|
if (this.settings.color) {
|
|
frontmatter['color'] = this.settings.color;
|
|
} else {
|
|
delete frontmatter['color'];
|
|
}
|
|
if (this.settings.icon && this.settings.icon !== '📁') {
|
|
frontmatter['icon'] = this.settings.icon;
|
|
} else {
|
|
delete frontmatter['icon'];
|
|
}
|
|
});
|
|
|
|
// 強制更新 metadata cache
|
|
this.app.metadataCache.getFileCache(file);
|
|
|
|
// 等待一小段時間以確保 metadata cache 已更新
|
|
setTimeout(() => {
|
|
// 重新渲染所有 grid-view 視圖
|
|
this.app.workspace.getLeavesOfType('grid-view').forEach(leaf => {
|
|
if (leaf.view instanceof GridView) {
|
|
leaf.view.render();
|
|
}
|
|
});
|
|
}, 200);
|
|
} catch (error) {
|
|
console.error('無法儲存資料夾筆記', error);
|
|
}
|
|
}
|
|
|
|
onClose() {
|
|
const { contentEl } = this;
|
|
contentEl.empty();
|
|
}
|
|
}
|