Add files via upload

This commit is contained in:
Devon22 2025-03-01 03:01:23 +08:00 committed by GitHub
parent 2f1f16b4e3
commit f8ed01b549
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 257 additions and 32 deletions

View file

@ -11,6 +11,11 @@ export function showFolderSelectionModal(app: App, plugin: GridExplorerPlugin, a
export class FolderSelectionModal extends Modal {
plugin: GridExplorerPlugin;
activeView: GridView | undefined;
folderOptionsContainer: HTMLElement;
folderOptions: HTMLElement[] = [];
selectedIndex: number = -1; // 當前選中的選項索引
searchInput: HTMLInputElement;
constructor(app: App, plugin: GridExplorerPlugin, activeView?: GridView) {
super(app);
this.plugin = plugin;
@ -22,11 +27,33 @@ export class FolderSelectionModal extends Modal {
contentEl.empty();
new Setting(contentEl).setName(t('select_folders')).setHeading();
// 添加搜尋輸入框
const searchContainer = contentEl.createEl('div', { cls: 'ge-folder-search-container' });
this.searchInput = searchContainer.createEl('input', {
cls: 'ge-folder-search-input',
attr: {
type: 'text',
placeholder: t('filter_folders')
}
});
// 創建一個容器來存放所有資料夾選項
this.folderOptionsContainer = contentEl.createEl('div', { cls: 'ge-folder-options-container' });
// 搜尋輸入事件處理
this.searchInput.addEventListener('input', () => {
const searchTerm = this.searchInput.value.toLowerCase();
this.filterFolderOptions(searchTerm);
});
// 鍵盤事件處理
this.searchInput.addEventListener('keydown', this.handleKeyDown.bind(this));
// 建立書籤選項
const bookmarksPlugin = (this.app as any).internalPlugins.plugins.bookmarks;
if (bookmarksPlugin?.enabled) {
const bookmarkOption = contentEl.createEl('div', {
cls: 'ge-grid-view-folder-option',
const bookmarkOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option ge-special-option',
text: `📑 ${t('bookmarks_mode')}`
});
@ -38,18 +65,19 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(bookmarkOption);
}
// 建立搜尋結果選項
const searchLeaf = (this.app as any).workspace.getLeavesOfType('search')[0];
if (searchLeaf) {
const searchView = searchLeaf.view;
const searchInput = searchView.searchComponent ? searchView.searchComponent.inputEl : null;
if(searchInput) {
if (searchInput.value.trim().length > 0) {
const searchOption = contentEl.createEl('div', {
cls: 'ge-grid-view-folder-option',
text: `🔍 ${t('search_results')}: ${searchInput.value}`
const searchInputEl = searchView.searchComponent ? searchView.searchComponent.inputEl : null;
if(searchInputEl) {
if (searchInputEl.value.trim().length > 0) {
const searchOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option ge-special-option',
text: `🔍 ${t('search_results')}: ${searchInputEl.value}`
});
searchOption.addEventListener('click', () => {
@ -60,6 +88,7 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(searchOption);
}
}
}
@ -68,8 +97,8 @@ export class FolderSelectionModal extends Modal {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile) {
const activeFileName = activeFile ? `: ${activeFile.basename}` : '';
const backlinksOption = contentEl.createEl('div', {
cls: 'ge-grid-view-folder-option',
const backlinksOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option ge-special-option',
text: `🔗 ${t('backlinks_mode')}${activeFileName}`
});
@ -81,11 +110,12 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(backlinksOption);
}
// 建立所有筆記選項
const allNotesOption = contentEl.createEl('div', {
cls: 'ge-grid-view-folder-option',
const allNotesOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option ge-special-option',
text: `📔 ${t('all_notes_mode')}`
});
@ -97,9 +127,10 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(allNotesOption);
// 建立根目錄選項
const rootFolderOption = contentEl.createEl('div', {
const rootFolderOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option',
text: `📁 /`
});
@ -112,6 +143,7 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(rootFolderOption);
// 取得所有資料夾(排除被忽略的資料夾)
const folders = this.app.vault.getAllFolders()
@ -125,7 +157,7 @@ export class FolderSelectionModal extends Modal {
// 建立資料夾選項
folders.forEach(folder => {
const folderOption = contentEl.createEl('div', {
const folderOption = this.folderOptionsContainer.createEl('div', {
cls: 'ge-grid-view-folder-option',
text: `📁 ${folder.path || '/'}`
});
@ -138,7 +170,127 @@ export class FolderSelectionModal extends Modal {
}
this.close();
});
this.folderOptions.push(folderOption);
});
// 為每個選項添加滑鼠事件
this.folderOptions.forEach((option, index) => {
option.addEventListener('mouseenter', () => {
this.updateSelection(index);
});
});
// 設置初始焦點到搜尋輸入框
this.searchInput.focus();
}
// 處理鍵盤事件
handleKeyDown(event: KeyboardEvent) {
const visibleOptions = this.getVisibleOptions();
if (visibleOptions.length === 0) return;
switch (event.key) {
case 'ArrowDown':
event.preventDefault();
this.moveSelection(1, visibleOptions);
break;
case 'ArrowUp':
event.preventDefault();
this.moveSelection(-1, visibleOptions);
break;
case 'Enter':
event.preventDefault();
if (this.selectedIndex >= 0) {
const selectedOption = this.folderOptions[this.selectedIndex];
if (selectedOption && selectedOption.style.display !== 'none') {
selectedOption.click();
}
}
break;
case 'Escape':
this.close();
break;
}
}
// 移動選擇
moveSelection(direction: number, visibleOptions: HTMLElement[]) {
// 如果沒有選中項或當前選中項不可見,則從頭開始
let currentVisibleIndex = -1;
if (this.selectedIndex >= 0) {
const selectedOption = this.folderOptions[this.selectedIndex];
currentVisibleIndex = visibleOptions.indexOf(selectedOption);
}
// 計算新的可見索引
let newVisibleIndex = currentVisibleIndex + direction;
// 循環選擇
if (newVisibleIndex < 0) {
newVisibleIndex = visibleOptions.length - 1;
} else if (newVisibleIndex >= visibleOptions.length) {
newVisibleIndex = 0;
}
// 轉換為實際的選項索引
if (newVisibleIndex >= 0 && newVisibleIndex < visibleOptions.length) {
const newSelectedOption = visibleOptions[newVisibleIndex];
const newIndex = this.folderOptions.indexOf(newSelectedOption);
this.updateSelection(newIndex);
// 確保選中項在視圖中可見
newSelectedOption.scrollIntoView({ block: 'nearest' });
}
}
// 更新選擇
updateSelection(index: number) {
// 清除之前的選擇
if (this.selectedIndex >= 0 && this.selectedIndex < this.folderOptions.length) {
this.folderOptions[this.selectedIndex].removeClass('ge-selected-option');
}
this.selectedIndex = index;
// 設置新的選擇
if (this.selectedIndex >= 0 && this.selectedIndex < this.folderOptions.length) {
this.folderOptions[this.selectedIndex].addClass('ge-selected-option');
}
}
// 獲取當前可見的選項
getVisibleOptions(): HTMLElement[] {
return this.folderOptions.filter(option =>
option.style.display !== 'none'
);
}
// 篩選資料夾選項
filterFolderOptions(searchTerm: string) {
let hasVisibleOptions = false;
this.folderOptions.forEach(option => {
const text = option.textContent?.toLowerCase() || '';
if (searchTerm === '' || text.includes(searchTerm)) {
option.style.display = 'block';
hasVisibleOptions = true;
} else {
option.style.display = 'none';
}
});
// 重置選擇,並選中第一個可見選項(如果有)
this.updateSelection(-1);
if (hasVisibleOptions) {
const visibleOptions = this.getVisibleOptions();
if (visibleOptions.length > 0) {
const firstVisibleIndex = this.folderOptions.indexOf(visibleOptions[0]);
this.updateSelection(firstVisibleIndex);
}
}
}
onClose() {

View file

@ -32,22 +32,6 @@ export class GridExplorerSettingTab extends PluginSettingTab {
const { containerEl } = this;
containerEl.empty();
// 忽略的資料夾設定
new Setting(containerEl)
.setName(t('ignored_folders'))
.setDesc(t('ignored_folders_desc'))
.addTextArea(text => text
.setPlaceholder(t('ignored_folders_placeholder'))
.setValue(this.plugin.settings.ignoredFolders.join('\n'))
.onChange(async (value) => {
// 將文字區域的內容轉換為陣列,並過濾掉空行
this.plugin.settings.ignoredFolders = value
.split('\n')
.map(folder => folder.trim())
.filter(folder => folder.length > 0);
await this.plugin.saveSettings();
}).inputEl.rows = 8);
// 預設排序模式設定
new Setting(containerEl)
.setName(t('default_sort_type'))
@ -112,5 +96,89 @@ export class GridExplorerSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
});
});
// 忽略的資料夾設定
const ignoredFoldersContainer = containerEl.createDiv('ignored-folders-container');
new Setting(containerEl)
.setName(t('ignored_folders'))
.setDesc(t('ignored_folders_desc'))
.setHeading();
// 新增資料夾選擇器
new Setting(ignoredFoldersContainer)
.setName(t('add_ignored_folder'))
.addDropdown(dropdown => {
// 獲取所有資料夾
const folders = this.app.vault.getAllFolders()
.filter(folder => folder.path !== '/') // 排除根目錄
.sort((a, b) => a.path.localeCompare(b.path));
// 新增空選項作為預設值
dropdown.addOption('', t('select_folders'));
// 新增所有資料夾作為選項
folders.forEach(folder => {
// 只顯示尚未被忽略的資料夾
if (!this.plugin.settings.ignoredFolders.includes(folder.path)) {
dropdown.addOption(folder.path, folder.path);
}
});
dropdown.onChange(async (value) => {
if (value) {
// 新增到忽略列表
this.plugin.settings.ignoredFolders.push(value);
await this.plugin.saveSettings();
// 重新渲染列表
this.renderIgnoredFoldersList(ignoredFoldersList);
// 重設下拉選單
dropdown.setValue('');
this.display();
}
});
});
// 顯示目前已忽略的資料夾列表
const ignoredFoldersList = ignoredFoldersContainer.createDiv('ge-ignored-folders-list');
this.renderIgnoredFoldersList(ignoredFoldersList);
containerEl.appendChild(ignoredFoldersContainer);
}
// 渲染已忽略的資料夾列表
renderIgnoredFoldersList(containerEl: HTMLElement) {
containerEl.empty();
if (this.plugin.settings.ignoredFolders.length === 0) {
containerEl.createEl('p', { text: t('no_ignored_folders') });
return;
}
const list = containerEl.createEl('ul', { cls: 'ge-ignored-folders-list' });
this.plugin.settings.ignoredFolders.forEach(folder => {
const item = list.createEl('li', { cls: 'ge-ignored-folder-item' });
item.createSpan({ text: folder, cls: 'ge-ignored-folder-path' });
const removeButton = item.createEl('button', {
cls: 'ge-ignored-folder-remove',
text: t('remove')
});
removeButton.addEventListener('click', async () => {
// 從忽略列表中移除
this.plugin.settings.ignoredFolders = this.plugin.settings.ignoredFolders
.filter(f => f !== folder);
await this.plugin.saveSettings();
// 重新渲染列表
this.renderIgnoredFoldersList(containerEl);
this.display();
});
});
}
}

View file

@ -11,7 +11,8 @@ type LanguageKey = keyof Translations;
// 全域翻譯函式
export function t(key: string): string {
const lang: LanguageKey = getLanguage() as LanguageKey;
const lang = window.localStorage.getItem('language') as LanguageKey;
//const lang: LanguageKey = getLanguage() as LanguageKey;
const translations = TRANSLATIONS[lang] || TRANSLATIONS['en'];
return translations[key] || key;
}
@ -76,6 +77,7 @@ export const TRANSLATIONS: Translations = {
'open_in_new_tab': '在新分頁開啟',
'searching': '搜尋中...',
'no_files': '沒有找到任何筆記',
'filter_folders': '篩選資料夾...',
},
'en': {
// Notifications
@ -135,6 +137,7 @@ export const TRANSLATIONS: Translations = {
'open_in_new_tab': 'Open in new tab',
'searching': 'Searching...',
'no_files': 'No notes found',
'filter_folders': 'Filter folders...',
},
'zh': {
// 通知信息
@ -191,9 +194,10 @@ export const TRANSLATIONS: Translations = {
'open_grid_view': '开启网格视图',
'open_in_grid_view': '在网格视图中开启',
'delete_note': '删除笔记',
'open_in_new_tab': '在新分頁開啟',
'open_in_new_tab': '在新标签页打开',
'searching': '搜索中...',
'no_files': '没有找到任何笔记',
'filter_folders': '筛选文件夹...',
},
'ja': {
// 通知メッジ
@ -253,5 +257,6 @@ export const TRANSLATIONS: Translations = {
'open_in_new_tab': '新しいタブで開く',
'searching': '検索中...',
'no_files': 'ノートが見つかりません',
'filter_folders': 'フォルダをフィルタリング...',
},
};