This commit is contained in:
Devon22 2025-04-10 00:24:22 +08:00
parent a414b60cb0
commit bfb847d266
10 changed files with 123 additions and 57 deletions

View file

@ -1,7 +1,7 @@
{
"id": "gridexplorer",
"name": "GridExplorer",
"version": "1.9.9",
"version": "1.9.10",
"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": "1.9.9",
"version": "1.9.10",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gridexplorer",
"version": "1.9.9",
"version": "1.9.10",
"license": "MIT",
"devDependencies": {
"@types/node": "^16.11.6",

View file

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

View file

@ -8,9 +8,9 @@ import { showNoteColorSettingsModal } from './NoteColorSettingsModal';
import { showFolderRenameModal } from './FolderRenameModal';
import { showSearchModal } from './SearchModal';
import { FileWatcher } from './FileWatcher';
import { isDocumentFile, isMediaFile, isImageFile, isVideoFile, isAudioFile } from './fileUtils';
import { t } from './translations';
import GridExplorerPlugin from '../main';
import { isDocumentFile, isMediaFile, isImageFile, isVideoFile, isAudioFile } from './fileUtils';
// 定義網格視圖
export class GridView extends ItemView {
@ -21,6 +21,7 @@ export class GridView extends ItemView {
folderSortType: string; // 資料夾排序模式
searchQuery: string; // 搜尋關鍵字
searchAllFiles: boolean; // 是否搜尋所有筆記
searchMediaFiles: boolean; // 是否搜尋媒體檔案
randomNoteIncludeMedia: boolean; // 隨機筆記是否包含圖片和影片
selectedItemIndex: number = -1; // 當前選中的項目索引
selectedItems: Set<number> = new Set(); // 存儲多選的項目索引
@ -40,6 +41,7 @@ export class GridView extends ItemView {
this.folderSortType = ''; // 資料夾排序模式
this.searchQuery = ''; // 搜尋關鍵字
this.searchAllFiles = true; // 是否搜尋所有筆記
this.searchMediaFiles = false; // 是否搜尋媒體檔案
this.randomNoteIncludeMedia = false; // 隨機筆記是否包含圖片和影片
// 根據設定決定是否註冊檔案變更監聽器
@ -819,7 +821,6 @@ export class GridView extends ItemView {
clearButton.addEventListener('click', (e) => {
e.stopPropagation(); // 防止觸發搜尋文字的點擊事件
this.searchQuery = '';
this.searchAllFiles = true;
this.clearSelection();
this.render();
// 通知 Obsidian 保存視圖狀態
@ -925,7 +926,11 @@ export class GridView extends ItemView {
// 如果是反向連結模式,但沒有活動中的檔案
if (this.sourceMode === 'backlinks' && !this.app.workspace.getActiveFile()) {
new Notice(t('no_backlinks'));
const noFilesDiv = container.createDiv('ge-no-files');
noFilesDiv.setText(t('no_backlinks'));
if (this.plugin.statusBarItem) {
this.plugin.statusBarItem.setText('');
}
return;
}
@ -1174,7 +1179,7 @@ export class GridView extends ItemView {
}
// 媒體檔案根據 searchMediaFiles 設定決定是否包含
if (isMediaFile(file)) {
return this.plugin.settings.searchMediaFiles;
return this.searchMediaFiles;
}
return false;
});
@ -1196,6 +1201,7 @@ export class GridView extends ItemView {
}
})
);
// 根據設定的排序方式排序檔案
files = this.sortFiles(files);
@ -1211,12 +1217,12 @@ export class GridView extends ItemView {
//最近檔案模式只取前30筆
if (this.sourceMode === 'recent-files') {
files = files.slice(0, 30);
files = files.slice(0, this.plugin.settings.recentFilesCount);
}
// 隨機筆記模式只取前10筆
if (this.sourceMode === 'random-note') {
files = files.slice(0, 10);
files = files.slice(0, this.plugin.settings.randomNoteCount);
}
// 如果沒有檔案,顯示提示訊息
@ -2068,6 +2074,7 @@ export class GridView extends ItemView {
folderSortType: this.folderSortType,
searchQuery: this.searchQuery,
searchAllFiles: this.searchAllFiles,
searchMediaFiles: this.searchMediaFiles,
randomNoteIncludeMedia: this.randomNoteIncludeMedia
}
};
@ -2082,6 +2089,7 @@ export class GridView extends ItemView {
this.folderSortType = state.state.folderSortType || '';
this.searchQuery = state.state.searchQuery || '';
this.searchAllFiles = state.state.searchAllFiles ?? true;
this.searchMediaFiles = state.state.searchMediaFiles ?? false;
this.randomNoteIncludeMedia = state.state.randomNoteIncludeMedia ?? false;
this.render();
}

View file

@ -49,8 +49,10 @@ export class SearchModal extends Modal {
searchInput.focus();
});
const searchOptionsContainer = contentEl.createDiv('ge-search-options-container');
// 創建搜尋範圍設定
const searchScopeContainer = contentEl.createDiv('ge-search-scope-container');
const searchScopeContainer = searchOptionsContainer.createDiv('ge-search-scope-container');
const searchScopeCheckbox = searchScopeContainer.createEl('input', {
type: 'checkbox',
cls: 'ge-search-scope-checkbox'
@ -61,6 +63,18 @@ export class SearchModal extends Modal {
cls: 'ge-search-scope-label'
});
// 創建搜尋媒體檔案設定
const searchMediaFilesContainer = searchOptionsContainer.createDiv('ge-search-media-files-container');
const searchMediaFilesCheckbox = searchMediaFilesContainer.createEl('input', {
type: 'checkbox',
cls: 'ge-search-media-files-checkbox'
});
searchMediaFilesCheckbox.checked = this.gridView.searchMediaFiles;
const searchMediaFilesLabel = searchMediaFilesContainer.createEl('span', {
text: t('search_media_files'),
cls: 'ge-search-media-files-label'
});
// 點擊容器時切換勾選框狀態
searchScopeContainer.addEventListener('click', (e) => {
if (e.target !== searchScopeCheckbox) {
@ -68,12 +82,22 @@ export class SearchModal extends Modal {
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
}
});
searchMediaFilesContainer.addEventListener('click', (e) => {
if (e.target !== searchMediaFilesCheckbox) {
searchMediaFilesCheckbox.checked = !searchMediaFilesCheckbox.checked;
this.gridView.searchMediaFiles = !searchMediaFilesCheckbox.checked;
}
});
// 勾選框變更時更新搜尋範圍
searchScopeCheckbox.addEventListener('change', () => {
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
});
searchMediaFilesCheckbox.addEventListener('change', () => {
this.gridView.searchMediaFiles = !searchMediaFilesCheckbox.checked;
});
// 創建按鈕容器
const buttonContainer = contentEl.createDiv('ge-button-container');
@ -91,6 +115,7 @@ export class SearchModal extends Modal {
const performSearch = () => {
this.gridView.searchQuery = searchInput.value;
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
this.gridView.searchMediaFiles = searchMediaFilesCheckbox.checked;
this.gridView.clearSelection();
this.gridView.render(true);
// 通知 Obsidian 保存視圖狀態

View file

@ -37,7 +37,7 @@ export function isVideoFile(file: TFile): boolean {
// 檢查檔案是否為音樂檔案
export function isAudioFile(file: TFile): boolean {
const audioExtensions = ['flac', 'm4a', 'mp3', 'ogg', 'wav', 'webm', '3gp'];
const audioExtensions = ['flac', 'm4a', 'mp3', 'ogg', 'wav', '3gp'];
return audioExtensions.includes(file.extension.toLowerCase());
}

View file

@ -14,7 +14,6 @@ export interface GallerySettings {
summaryLength: number; // 筆記摘要的字數
enableFileWatcher: boolean; // 是否啟用檔案監控
showMediaFiles: boolean; // 是否顯示圖片和影片
searchMediaFiles: boolean; // 搜尋時是否包含圖片和影片
showVideoThumbnails: boolean; // 是否顯示影片縮圖
defaultOpenLocation: string; // 預設開啟位置
showParentFolderItem: boolean; // 是否显示"返回上级文件夹"选项
@ -29,6 +28,8 @@ export interface GallerySettings {
recentSources: string[]; // 最近的瀏覽記錄
modifiedDateField: string; // 修改時間的欄位名稱
createdDateField: string; // 建立時間的欄位名稱
recentFilesCount: number; // 最近筆記模式顯示的筆數
randomNoteCount: number; // 隨機筆記模式顯示的筆數
}
// 預設設定
@ -44,7 +45,6 @@ export const DEFAULT_SETTINGS: GallerySettings = {
summaryLength: 100, // 筆記摘要的字數,預設 100
enableFileWatcher: true, // 預設啟用檔案監控
showMediaFiles: true, // 預設顯示圖片和影片
searchMediaFiles: false, // 預設搜尋時也包含圖片和影片
showVideoThumbnails: false, // 預設不顯示影片縮圖
defaultOpenLocation: 'tab', // 預設開啟位置:新分頁
showParentFolderItem: false, // 預設不顯示"返回上级文件夹"選項
@ -55,6 +55,8 @@ export const DEFAULT_SETTINGS: GallerySettings = {
showAllFilesMode: false, // 預設不顯示所有檔案模式
showRandomNoteMode: false, // 預設不顯示隨機筆記模式
showRecentFilesMode: true, // 預設不顯示最近筆記模式
recentFilesCount: 30, // 預設最近筆記模式顯示的筆數
randomNoteCount: 10, // 預設隨機筆記模式顯示的筆數
customDocumentExtensions: '', // 自訂文件副檔名(用逗號分隔)
recentSources: [], // 預設最近的瀏覽記錄
modifiedDateField: '',
@ -126,18 +128,6 @@ export class GridExplorerSettingTab extends PluginSettingTab {
});
});
// 設定是否顯示最近檔案模式
new Setting(containerEl)
.setName(t('show_recent_files_mode'))
.addToggle(toggle => {
toggle
.setValue(this.plugin.settings.showRecentFilesMode)
.onChange(async (value) => {
this.plugin.settings.showRecentFilesMode = value;
await this.plugin.saveSettings();
});
});
// 設定是否顯示所有檔案模式
new Setting(containerEl)
.setName(t('show_all_files_mode'))
@ -150,6 +140,30 @@ export class GridExplorerSettingTab extends PluginSettingTab {
});
});
// 設定是否顯示最近檔案模式
new Setting(containerEl)
.setName(t('show_recent_files_mode'))
.addToggle(toggle => {
toggle
.setValue(this.plugin.settings.showRecentFilesMode)
.onChange(async (value) => {
this.plugin.settings.showRecentFilesMode = value;
await this.plugin.saveSettings();
});
});
// 最近檔案模式的顯示資料筆數
new Setting(containerEl)
.setName(t('recent_files_count'))
.addText(text => {
text
.setValue(this.plugin.settings.recentFilesCount.toString())
.onChange(async (value) => {
this.plugin.settings.recentFilesCount = parseInt(value);
await this.plugin.saveSettings();
});
});
// 設定是否顯示隨機筆記模式
new Setting(containerEl)
.setName(t('show_random_note_mode'))
@ -162,6 +176,18 @@ export class GridExplorerSettingTab extends PluginSettingTab {
});
});
// 隨機筆記模式的顯示資料筆數
new Setting(containerEl)
.setName(t('random_note_count'))
.addText(text => {
text
.setValue(this.plugin.settings.randomNoteCount.toString())
.onChange(async (value) => {
this.plugin.settings.randomNoteCount = parseInt(value);
await this.plugin.saveSettings();
});
});
// 媒體檔案設定區域
containerEl.createEl('h3', { text: t('media_files_settings') });
@ -174,27 +200,6 @@ export class GridExplorerSettingTab extends PluginSettingTab {
.setValue(this.plugin.settings.showMediaFiles)
.onChange(async (value) => {
this.plugin.settings.showMediaFiles = value;
// 如果關閉了顯示媒體檔案,也自動關閉搜尋媒體檔案
if (!value) {
this.plugin.settings.searchMediaFiles = false;
// 重新載入設定頁面以更新 UI
this.display();
}
await this.plugin.saveSettings();
});
});
// 搜尋圖片和影片設定
new Setting(containerEl)
.setName(t('search_media_files'))
.setDesc(t('search_media_files_desc'))
.addToggle(toggle => {
toggle
.setValue(this.plugin.settings.searchMediaFiles)
.onChange(async (value) => {
this.plugin.settings.searchMediaFiles = value;
await this.plugin.saveSettings();
});
});

View file

@ -32,6 +32,7 @@ export const TRANSLATIONS: Translations = {
'search': '搜尋',
'search_placeholder': '搜尋關鍵字',
'search_current_location_only': '僅搜尋目前位置',
'search_media_files': '搜尋媒體檔案',
'cancel': '取消',
'new_note': '新增筆記',
'new_folder': '新增資料夾',
@ -64,8 +65,6 @@ export const TRANSLATIONS: Translations = {
'media_files_settings': '媒體檔案設定',
'show_media_files': '顯示圖片和影片',
'show_media_files_desc': '在網格視圖中顯示圖片和影片檔案',
'search_media_files': '搜尋圖片和影片',
'search_media_files_desc': '在搜尋結果中包含圖片和影片檔案(僅在啟用顯示圖片和影片時有效)',
'show_video_thumbnails': '顯示影片縮圖',
'show_video_thumbnails_desc': '在網格視圖中顯示影片的縮圖,關閉時將顯示播放圖示',
'ignored_folders': '忽略的資料夾',
@ -108,7 +107,9 @@ export const TRANSLATIONS: Translations = {
'show_backlinks_mode': '顯示反向連結模式',
'show_all_files_mode': '顯示所有檔案模式',
'show_recent_files_mode': '顯示最近檔案模式',
'recent_files_count': '最近檔案模式顯示筆數',
'show_random_note_mode': '顯示隨機筆記模式',
'random_note_count': '隨機筆記模式顯示筆數',
'random_note_notes_only': '僅筆記',
'random_note_include_media_files': '包含圖片影片',
@ -186,6 +187,7 @@ export const TRANSLATIONS: Translations = {
'search': 'Search',
'search_placeholder': 'Search keyword',
'search_current_location_only': 'Search current location only',
'search_media_files': 'Search media files',
'cancel': 'Cancel',
'new_note': 'New note',
'new_folder': 'New folder',
@ -218,8 +220,6 @@ export const TRANSLATIONS: Translations = {
'media_files_settings': 'Media files settings',
'show_media_files': 'Show images and videos',
'show_media_files_desc': 'Display image and video files in the grid view',
'search_media_files': 'Search images and videos',
'search_media_files_desc': 'Include image and video files in search results (only effective when show images and videos is enabled)',
'show_video_thumbnails': 'Show video thumbnails',
'show_video_thumbnails_desc': 'Display thumbnails for videos in the grid view, shows a play icon when disabled',
'ignored_folders': 'Ignored folders',
@ -262,7 +262,9 @@ export const TRANSLATIONS: Translations = {
'show_backlinks_mode': 'Show backlinks mode',
'show_all_files_mode': 'Show all files mode',
'show_recent_files_mode': 'Show recent files mode',
'recent_files_count': 'Recent files count',
'show_random_note_mode': 'Show random note mode',
'random_note_count': 'Random note count',
'random_note_notes_only': 'Notes Only',
'random_note_include_media_files': 'Include Media Files',
@ -340,6 +342,7 @@ export const TRANSLATIONS: Translations = {
'search': '搜索',
'search_placeholder': '搜索关键字',
'search_current_location_only': '仅搜索当前位置',
'search_media_files': '搜索媒体文件',
'cancel': '取消',
'new_note': '新建笔记',
'new_folder': '新建文件夹',
@ -372,8 +375,6 @@ export const TRANSLATIONS: Translations = {
'media_files_settings': '媒体文件设置',
'show_media_files': '显示图片和视频',
'show_media_files_desc': '在网格视图中显示图片和视频文件',
'search_media_files': '搜索图片和视频',
'search_media_files_desc': '在搜索结果中包含图片和视频文件(仅在启用显示图片和视频时有效)',
'show_video_thumbnails': '显示视频缩略图',
'show_video_thumbnails_desc': '在网格视图中显示视频的缩略图,关闭时将显示播放图标',
'ignored_folders': '忽略的文件夹',
@ -416,7 +417,9 @@ export const TRANSLATIONS: Translations = {
'show_backlinks_mode': '显示反向链接模式',
'show_all_files_mode': '显示所有文件模式',
'show_recent_files_mode': '显示最近文件模式',
'recent_files_count': '最近文件模式显示笔数',
'show_random_note_mode': '显示随机笔记模式',
'random_note_count': '随机笔记模式显示笔数',
'random_note_notes_only': '仅笔记',
'random_note_include_media_files': '包含图片视频',
@ -494,6 +497,7 @@ export const TRANSLATIONS: Translations = {
'search': '検索',
'search_placeholder': 'キーワード検索',
'search_current_location_only': '現在の場所のみ検索',
'search_media_files': 'メディアファイルを検索',
'cancel': 'キャンセル',
'new_note': '新規ノート',
'new_folder': '新規フォルダ',
@ -526,8 +530,6 @@ export const TRANSLATIONS: Translations = {
'media_files_settings': 'メディアファイル設定',
'show_media_files': '画像と動画を表示',
'show_media_files_desc': 'グリッドビューで画像と動画ファイルを表示する',
'search_media_files': '画像と動画を検索',
'search_media_files_desc': '検索結果に画像と動画ファイルを含める(画像と動画の表示が有効な場合のみ)',
'show_video_thumbnails': '動画のサムネイルを表示',
'show_video_thumbnails_desc': 'グリッドビューで動画のサムネイルを表示する、無効の場合は再生アイコンを表示',
'ignored_folders': '無視するフォルダ',
@ -570,7 +572,9 @@ export const TRANSLATIONS: Translations = {
'show_backlinks_mode': 'バックリンクモードを表示',
'show_all_files_mode': '全ファイルモードを表示',
'show_recent_files_mode': '最近ファイルモードを表示',
'recent_files_count': '最近ファイルモード表示筆数',
'show_random_note_mode': 'ランダムノートモードを表示',
'random_note_count': 'ランダムノートモード表示筆数',
'random_note_notes_only': 'ノートのみ',
'random_note_include_media_files': 'メディアを含む',

View file

@ -302,11 +302,17 @@
color: var(--text-muted);
}
/* 搜尋選項容器 */
.ge-search-options-container {
display: flex;
gap: 16px;
margin: 4px;
}
/* 搜尋範圍設定樣式 */
.ge-search-scope-container {
display: flex;
align-items: center;
margin: 4px 0;
cursor: pointer;
padding: 4px;
}
@ -321,6 +327,24 @@
color: var(--text-normal);
}
/* 搜尋媒體檔案設定樣式 */
.ge-search-media-files-container {
display: flex;
align-items: center;
cursor: pointer;
padding: 4px;
}
.ge-search-media-files-checkbox {
cursor: pointer;
}
.ge-search-media-files-label {
cursor: pointer;
user-select: none;
color: var(--text-normal);
}
.ge-button-container {
display: flex;
gap: 8px;

View file

@ -1,3 +1,3 @@
{
"1.9.9": "1.1.0"
"1.9.10": "1.1.0"
}