Files
obsidian-grid/main.js
Marek Lenczewski c7e13c0168 init
2026-04-15 21:14:00 +02:00

3330 lines
126 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if ((from && typeof from === "object") || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, {
get: () => from[key],
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
});
}
return to;
};
var __toCommonJS = (mod) =>
__copyProps(__defProp({}, "__esModule", { value: true }), mod);
// main.ts
var main_exports = {};
__export(main_exports, {
default: () => GridExplorerPlugin,
});
module.exports = __toCommonJS(main_exports);
var import_obsidian10 = require("obsidian");
// src/GridView.ts
var import_obsidian7 = require("obsidian");
var import_obsidian8 = require("obsidian");
// src/FolderSelectionModal.ts
var import_obsidian = require("obsidian");
// src/translations.ts
function t(key) {
const lang = window.localStorage.getItem("language");
const translations = TRANSLATIONS[lang] || TRANSLATIONS["en"];
return translations[key] || key;
}
var TRANSLATIONS = {
"zh-TW": {
// 通知訊息
bookmarks_plugin_disabled:
"\u8ACB\u5148\u555F\u7528\u66F8\u7C64\u5916\u639B",
// 按鈕和標籤
sorting: "\u6392\u5E8F\u65B9\u5F0F",
refresh: "\u91CD\u65B0\u6574\u7406",
reselect_folder: "\u91CD\u65B0\u9078\u64C7\u4F4D\u7F6E",
go_up: "\u8FD4\u56DE\u4E0A\u5C64\u8CC7\u6599\u593E",
no_backlinks: "\u6C92\u6709\u53CD\u5411\u9023\u7D50",
search: "\u641C\u5C0B",
search_placeholder: "\u641C\u5C0B\u95DC\u9375\u5B57",
search_current_location_only: "\u50C5\u641C\u5C0B\u76EE\u524D\u4F4D\u7F6E",
cancel: "\u53D6\u6D88",
new_note: "\u65B0\u589E\u7B46\u8A18",
untitled: "\u672A\u547D\u540D",
files: "\u500B\u6A94\u6848",
add: "\u65B0\u589E",
// 視圖標題
grid_view_title: "\u7DB2\u683C\u8996\u5716",
bookmarks_mode: "\u66F8\u7C64",
folder_mode: "\u8CC7\u6599\u593E",
search_results: "\u641C\u5C0B\u7D50\u679C",
backlinks_mode: "\u53CD\u5411\u9023\u7D50",
all_files_mode: "\u6240\u6709\u6A94\u6848",
random_note_mode: "\u96A8\u6A5F\u7B46\u8A18",
// 排序選項
sort_name_asc: "\u540D\u7A31 (A \u2192 Z)",
sort_name_desc: "\u540D\u7A31 (Z \u2192 A)",
sort_mtime_desc: "\u4FEE\u6539\u6642\u9593 (\u65B0 \u2192 \u820A)",
sort_mtime_asc: "\u4FEE\u6539\u6642\u9593 (\u820A \u2192 \u65B0)",
sort_ctime_desc: "\u5EFA\u7ACB\u6642\u9593 (\u65B0 \u2192 \u820A)",
sort_ctime_asc: "\u5EFA\u7ACB\u6642\u9593 (\u820A \u2192 \u65B0)",
sort_random: "\u96A8\u6A5F\u6392\u5E8F",
// 設定
grid_view_settings: "\u7DB2\u683C\u8996\u5716\u8A2D\u5B9A",
media_files_settings: "\u5A92\u9AD4\u6A94\u6848\u8A2D\u5B9A",
show_media_files: "\u986F\u793A\u5716\u7247\u548C\u5F71\u7247",
show_media_files_desc:
"\u5728\u7DB2\u683C\u8996\u5716\u4E2D\u986F\u793A\u5716\u7247\u548C\u5F71\u7247\u6A94\u6848",
search_media_files: "\u641C\u5C0B\u5716\u7247\u548C\u5F71\u7247",
search_media_files_desc:
"\u5728\u641C\u5C0B\u7D50\u679C\u4E2D\u5305\u542B\u5716\u7247\u548C\u5F71\u7247\u6A94\u6848\uFF08\u50C5\u5728\u555F\u7528\u986F\u793A\u5716\u7247\u548C\u5F71\u7247\u6642\u6709\u6548\uFF09",
show_video_thumbnails: "\u986F\u793A\u5F71\u7247\u7E2E\u5716",
show_video_thumbnails_desc:
"\u5728\u7DB2\u683C\u8996\u5716\u4E2D\u986F\u793A\u5F71\u7247\u7684\u7E2E\u5716\uFF0C\u95DC\u9589\u6642\u5C07\u986F\u793A\u64AD\u653E\u5716\u793A",
ignored_folders: "\u5FFD\u7565\u7684\u8CC7\u6599\u593E",
ignored_folders_desc:
"\u5728\u9019\u88E1\u8A2D\u5B9A\u8981\u5FFD\u7565\u7684\u8CC7\u6599\u593E",
add_ignored_folder: "\u65B0\u589E\u5FFD\u7565\u8CC7\u6599\u593E",
no_ignored_folders:
"\u6C92\u6709\u5FFD\u7565\u7684\u8CC7\u6599\u593E\u3002",
ignored_folder_patterns:
"\u4EE5\u5B57\u4E32\u5FFD\u7565\u8CC7\u6599\u593E\u548C\u6A94\u6848",
ignored_folder_patterns_desc:
"\u4F7F\u7528\u5B57\u4E32\u6A21\u5F0F\u5FFD\u7565\u8CC7\u6599\u593E\u548C\u6A94\u6848\uFF08\u652F\u63F4\u6B63\u5247\u8868\u9054\u5F0F\uFF09",
add_ignored_folder_pattern:
"\u65B0\u589E\u5FFD\u7565\u8CC7\u6599\u593E\u6A21\u5F0F",
ignored_folder_pattern_placeholder:
"\u8F38\u5165\u8CC7\u6599\u593E\u540D\u7A31\u6216\u6B63\u5247\u8868\u9054\u5F0F",
no_ignored_folder_patterns:
"\u6C92\u6709\u5FFD\u7565\u7684\u8CC7\u6599\u593E\u6A21\u5F0F\u3002",
remove: "\u79FB\u9664",
default_sort_type: "\u9810\u8A2D\u6392\u5E8F\u6A21\u5F0F",
default_sort_type_desc:
"\u8A2D\u5B9A\u958B\u555F\u7DB2\u683C\u8996\u5716\u6642\u7684\u9810\u8A2D\u6392\u5E8F\u6A21\u5F0F",
grid_item_width: "\u7DB2\u683C\u9805\u76EE\u5BEC\u5EA6",
grid_item_width_desc:
"\u8A2D\u5B9A\u7DB2\u683C\u9805\u76EE\u7684\u5BEC\u5EA6",
grid_item_height: "\u7DB2\u683C\u9805\u76EE\u9AD8\u5EA6",
grid_item_height_desc:
"\u8A2D\u5B9A\u7DB2\u683C\u9805\u76EE\u7684\u9AD8\u5EA6 (\u8A2D\u70BA0\u6642\u70BA\u81EA\u52D5\u8ABF\u6574)",
image_area_width: "\u5716\u7247\u5340\u57DF\u5BEC\u5EA6",
image_area_width_desc:
"\u8A2D\u5B9A\u5716\u7247\u9810\u89BD\u5340\u57DF\u7684\u5BEC\u5EA6",
image_area_height: "\u5716\u7247\u5340\u57DF\u9AD8\u5EA6",
image_area_height_desc:
"\u8A2D\u5B9A\u5716\u7247\u9810\u89BD\u5340\u57DF\u7684\u9AD8\u5EA6",
title_font_size: "\u6A19\u984C\u5B57\u9AD4\u5927\u5C0F",
title_font_size_desc:
"\u8A2D\u5B9A\u6A19\u984C\u5B57\u9AD4\u7684\u5927\u5C0F",
summary_length: "\u6458\u8981\u9577\u5EA6",
summary_length_desc: "\u8A2D\u5B9A\u6458\u8981\u7684\u9577\u5EA6",
enable_file_watcher: "\u555F\u7528\u6A94\u6848\u76E3\u63A7",
enable_file_watcher_desc:
"\u555F\u7528\u5F8C\u6703\u81EA\u52D5\u5075\u6E2C\u6A94\u6848\u8B8A\u66F4\u4E26\u66F4\u65B0\u8996\u5716\uFF0C\u95DC\u9589\u5F8C\u9700\u624B\u52D5\u9EDE\u64CA\u91CD\u65B0\u6574\u7406\u6309\u9215",
reset_to_default: "\u91CD\u7F6E\u70BA\u9810\u8A2D\u503C",
reset_to_default_desc:
"\u5C07\u6240\u6709\u8A2D\u5B9A\u91CD\u7F6E\u70BA\u9810\u8A2D\u503C",
settings_reset_notice:
"\u8A2D\u5B9A\u503C\u5DF2\u91CD\u7F6E\u70BA\u9810\u8A2D\u503C",
ignored_folders_settings: "\u5FFD\u7565\u8CC7\u6599\u593E\u8A2D\u5B9A",
display_mode_settings: "\u986F\u793A\u6A21\u5F0F\u8A2D\u5B9A",
show_bookmarks_mode: "\u986F\u793A\u66F8\u7C64\u6A21\u5F0F",
show_search_mode: "\u986F\u793A\u641C\u5C0B\u7D50\u679C\u6A21\u5F0F",
show_backlinks_mode: "\u986F\u793A\u53CD\u5411\u9023\u7D50\u6A21\u5F0F",
show_all_files_mode: "\u986F\u793A\u6240\u6709\u6A94\u6848\u6A21\u5F0F",
show_random_note_mode: "\u986F\u793A\u96A8\u6A5F\u7B46\u8A18\u6A21\u5F0F",
random_note_notes_only: "\u50C5\u7B46\u8A18",
random_note_include_media_files: "\u5305\u542B\u5716\u7247\u5F71\u7247",
// 顯示"返回上層資料夾"選項設定
show_parent_folder_item:
"\u986F\u793A\u300C\u8FD4\u56DE\u4E0A\u5C64\u8CC7\u6599\u593E\u300D",
show_parent_folder_item_desc:
"\u5728\u7DB2\u683C\u7684\u7B2C\u4E00\u9805\u986F\u793A\u300C\u8FD4\u56DE\u4E0A\u5C64\u8CC7\u6599\u593E\u300D\u9078\u9805",
parent_folder: "\u4E0A\u5C64\u8CC7\u6599\u593E",
// 預設開啟位置設定
default_open_location: "\u9810\u8A2D\u958B\u555F\u4F4D\u7F6E",
default_open_location_desc:
"\u8A2D\u5B9A\u7DB2\u683C\u8996\u5716\u9810\u8A2D\u958B\u555F\u7684\u4F4D\u7F6E",
open_in_left_sidebar: "\u958B\u5728\u5DE6\u5074\u908A\u6B04",
open_in_right_sidebar: "\u958B\u5728\u53F3\u5074\u908A\u6B04",
open_in_new_tab: "\u5728\u65B0\u5206\u9801\u958B\u555F",
reuse_existing_leaf:
"\u91CD\u8907\u4F7F\u7528\u5DF2\u958B\u555F\u7684\u8996\u5716",
reuse_existing_leaf_desc:
"\u958B\u555F\u7DB2\u683C\u8996\u5716\u6642\uFF0C\u512A\u5148\u4F7F\u7528\u5DF2\u958B\u555F\u7684\u8996\u5716\u800C\u975E\u5EFA\u7ACB\u65B0\u8996\u5716",
custom_document_extensions:
"\u81EA\u8A02\u6587\u4EF6\u6A94\u6848\u526F\u6A94\u540D",
custom_document_extensions_desc:
"\u984D\u5916\u7684\u6587\u4EF6\u526F\u6A94\u540D\uFF08\u7528\u9017\u865F\u5206\u9694\uFF0C\u4E0D\u542B\u9EDE\u865F\uFF09",
custom_document_extensions_placeholder: "\u4F8B\u5982\uFF1Atxt,doc,docx",
// 選擇資料夾對話框
select_folders: "\u9078\u64C7\u8CC7\u6599\u593E",
open_grid_view: "\u958B\u555F\u7DB2\u683C\u8996\u5716",
open_note_in_grid_view:
"\u5728\u7DB2\u683C\u8996\u5716\u4E2D\u958B\u555F\u7576\u524D\u7B46\u8A18",
open_backlinks_in_grid_view:
"\u5728\u7DB2\u683C\u8996\u5716\u4E2D\u958B\u555F\u53CD\u5411\u9023\u7D50",
open_settings: "\u958B\u555F\u8A2D\u5B9A",
delete_note: "\u522A\u9664\u6A94\u6848",
open_folder_note: "\u958B\u555F\u8CC7\u6599\u593E\u7B46\u8A18",
create_folder_note: "\u5EFA\u7ACB\u8CC7\u6599\u593E\u7B46\u8A18",
ignore_folder: "\u5FFD\u7565\u6B64\u8CC7\u6599\u593E",
searching: "\u641C\u5C0B\u4E2D...",
no_files: "\u6C92\u6709\u627E\u5230\u4EFB\u4F55\u6A94\u6848",
filter_folders: "\u7BE9\u9078\u8CC7\u6599\u593E...",
},
en: {
// Notifications
bookmarks_plugin_disabled: "Please enable the Bookmarks plugin first",
// Buttons and Labels
sorting: "Sort by",
refresh: "Refresh",
reselect_folder: "Reselect folder",
go_up: "Go Up",
no_backlinks: "No backlinks",
search: "Search",
search_placeholder: "Search keyword",
search_current_location_only: "Search current location only",
cancel: "Cancel",
new_note: "New note",
untitled: "Untitled",
files: "files",
add: "Add",
// View Titles
grid_view_title: "Grid view",
bookmarks_mode: "Bookmarks",
folder_mode: "Folder",
search_results: "Search results",
backlinks_mode: "Backlinks",
all_files_mode: "All files",
random_note_mode: "Random note",
// Sort Options
sort_name_asc: "Name (A \u2192 Z)",
sort_name_desc: "Name (Z \u2192 A)",
sort_mtime_desc: "Modified (New \u2192 Old)",
sort_mtime_asc: "Modified (Old \u2192 New)",
sort_ctime_desc: "Created (New \u2192 Old)",
sort_ctime_asc: "Created (Old \u2192 New)",
sort_random: "Random",
// Settings
grid_view_settings: "Grid view settings",
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",
ignored_folders_desc: "Set folders to ignore here",
add_ignored_folder: "Add ignored folder",
no_ignored_folders: "No ignored folders.",
ignored_folder_patterns: "Ignore folders and files by pattern",
ignored_folder_patterns_desc:
"Use string patterns to ignore folders and files (supports regular expressions)",
add_ignored_folder_pattern: "Add folder pattern",
ignored_folder_pattern_placeholder: "Enter folder name or regex pattern",
no_ignored_folder_patterns: "No ignored folder patterns.",
remove: "Remove",
default_sort_type: "Default sort type",
default_sort_type_desc:
"Set the default sorting method when opening Grid View",
grid_item_width: "Grid item width",
grid_item_width_desc: "Set the width of grid items",
grid_item_height: "Grid item height",
grid_item_height_desc:
"Set the height of grid items (set to 0 to automatically adjust)",
image_area_width: "Image area width",
image_area_width_desc: "Set the width of the image preview area",
image_area_height: "Image area height",
image_area_height_desc: "Set the height of the image preview area",
title_font_size: "Title font size",
title_font_size_desc: "Set the size of the title font",
summary_length: "Summary length",
summary_length_desc: "Set the length of the summary",
enable_file_watcher: "Enable file watcher",
enable_file_watcher_desc:
"When enabled, the view will automatically update when files change. If disabled, you need to click the refresh button manually",
reset_to_default: "Reset to default",
reset_to_default_desc: "Reset all settings to default values",
settings_reset_notice: "Settings have been reset to default values",
ignored_folders_settings: "Ignore folders settings",
display_mode_settings: "Display mode settings",
show_bookmarks_mode: "Show bookmarks mode",
show_search_mode: "Show search results mode",
show_backlinks_mode: "Show backlinks mode",
show_all_files_mode: "Show all files mode",
show_random_note_mode: "Show random note mode",
random_note_notes_only: "Notes Only",
random_note_include_media_files: "Include Media Files",
// 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',
parent_folder: "Parent Folder",
// Default open location setting
default_open_location: "Default open location",
default_open_location_desc:
"Set the default location to open the grid view",
open_in_left_sidebar: "Open in left sidebar",
open_in_right_sidebar: "Open in right sidebar",
open_in_new_tab: "Open in new tab",
reuse_existing_leaf: "Reuse existing view",
reuse_existing_leaf_desc:
"When opening Grid View, prioritize using an existing view instead of creating a new one",
custom_document_extensions: "Custom Document Extensions",
custom_document_extensions_desc:
"Additional document extensions (comma-separated, without dots)",
custom_document_extensions_placeholder: "e.g., txt,doc,docx",
// Select Folder Dialog
select_folders: "Select folder",
open_grid_view: "Open grid view",
open_note_in_grid_view: "Open note in grid view",
open_backlinks_in_grid_view: "Open backlinks in grid view",
open_settings: "Open settings",
delete_note: "Delete file",
open_folder_note: "Open folder note",
create_folder_note: "Create folder note",
ignore_folder: "Ignore this folder",
searching: "Searching...",
no_files: "No files found",
filter_folders: "Filter folders...",
},
zh: {
// 通知信息
bookmarks_plugin_disabled:
"\u8BF7\u5148\u542F\u7528\u4E66\u7B7E\u63D2\u4EF6",
// 按钮和标签
sorting: "\u6392\u5E8F\u65B9\u5F0F",
refresh: "\u5237\u65B0",
reselect_folder: "\u91CD\u65B0\u9009\u62E9\u4F4D\u7F6E",
go_up: "\u8FD4\u56DE\u4E0A\u7EA7\u6587\u4EF6\u5939",
no_backlinks: "\u6CA1\u6709\u53CD\u5411\u94FE\u63A5",
search: "\u641C\u7D22",
search_placeholder: "\u641C\u7D22\u5173\u952E\u5B57",
search_current_location_only: "\u4EC5\u641C\u7D22\u5F53\u524D\u4F4D\u7F6E",
cancel: "\u53D6\u6D88",
new_note: "\u65B0\u5EFA\u7B14\u8BB0",
untitled: "\u672A\u547D\u540D",
files: "\u4E2A\u6587\u4EF6",
add: "\u6DFB\u52A0",
// 视图标题
grid_view_title: "\u7F51\u683C\u89C6\u56FE",
bookmarks_mode: "\u4E66\u7B7E",
folder_mode: "\u6587\u4EF6\u5939",
search_results: "\u641C\u7D22\u7ED3\u679C",
backlinks_mode: "\u53CD\u5411\u94FE\u63A5",
all_files_mode: "\u6240\u6709\u6587\u4EF6",
random_note_mode: "\u968F\u673A\u7B14\u8BB0",
// 排序选项
sort_name_asc: "\u540D\u79F0 (A \u2192 Z)",
sort_name_desc: "\u540D\u79F0 (Z \u2192 A)",
sort_mtime_desc: "\u4FEE\u6539\u65F6\u95F4 (\u65B0 \u2192 \u65E7)",
sort_mtime_asc: "\u4FEE\u6539\u65F6\u95F4 (\u65E7 \u2192 \u65B0)",
sort_ctime_desc: "\u521B\u5EFA\u65F6\u95F4 (\u65B0 \u2192 \u65E7)",
sort_ctime_asc: "\u521B\u5EFA\u65F6\u95F4 (\u65E7 \u2192 \u65B0)",
sort_random: "\u968F\u673A\u6392\u5E8F",
// 设置
grid_view_settings: "\u7F51\u683C\u89C6\u56FE\u8BBE\u7F6E",
media_files_settings: "\u5A92\u4F53\u6587\u4EF6\u8BBE\u7F6E",
show_media_files: "\u663E\u793A\u56FE\u7247\u548C\u89C6\u9891",
show_media_files_desc:
"\u5728\u7F51\u683C\u89C6\u56FE\u4E2D\u663E\u793A\u56FE\u7247\u548C\u89C6\u9891\u6587\u4EF6",
search_media_files: "\u641C\u7D22\u56FE\u7247\u548C\u89C6\u9891",
search_media_files_desc:
"\u5728\u641C\u7D22\u7ED3\u679C\u4E2D\u5305\u542B\u56FE\u7247\u548C\u89C6\u9891\u6587\u4EF6\uFF08\u4EC5\u5728\u542F\u7528\u663E\u793A\u56FE\u7247\u548C\u89C6\u9891\u65F6\u6709\u6548\uFF09",
show_video_thumbnails: "\u663E\u793A\u89C6\u9891\u7F29\u7565\u56FE",
show_video_thumbnails_desc:
"\u5728\u7F51\u683C\u89C6\u56FE\u4E2D\u663E\u793A\u89C6\u9891\u7684\u7F29\u7565\u56FE\uFF0C\u5173\u95ED\u65F6\u5C06\u663E\u793A\u64AD\u653E\u56FE\u6807",
ignored_folders: "\u5FFD\u7565\u7684\u6587\u4EF6\u5939",
ignored_folders_desc:
"\u5728\u8FD9\u91CC\u8BBE\u7F6E\u8981\u5FFD\u7565\u7684\u6587\u4EF6\u5939",
add_ignored_folder: "\u6DFB\u52A0\u5FFD\u7565\u6587\u4EF6\u5939",
no_ignored_folders:
"\u6CA1\u6709\u5FFD\u7565\u7684\u6587\u4EF6\u5939\u3002",
ignored_folder_patterns:
"\u4EE5\u5B57\u7B26\u4E32\u5FFD\u7565\u6587\u4EF6\u5939\u548C\u6587\u4EF6",
ignored_folder_patterns_desc:
"\u4F7F\u7528\u5B57\u7B26\u4E32\u6A21\u5F0F\u5FFD\u7565\u6587\u4EF6\u5939\u548C\u6587\u4EF6\uFF08\u652F\u6301\u6B63\u5219\u8868\u8FBE\u5F0F\uFF09",
add_ignored_folder_pattern:
"\u6DFB\u52A0\u5FFD\u7565\u6587\u4EF6\u5939\u6A21\u5F0F",
ignored_folder_pattern_placeholder:
"\u8F93\u5165\u6587\u4EF6\u5939\u540D\u79F0\u6216\u6B63\u5219\u8868\u8FBE\u5F0F",
no_ignored_folder_patterns:
"\u6CA1\u6709\u5FFD\u7565\u7684\u6587\u4EF6\u5939\u6A21\u5F0F\u3002",
remove: "\u79FB\u9664",
default_sort_type: "\u9ED8\u8BA4\u6392\u5E8F\u6A21\u5F0F",
default_sort_type_desc:
"\u8BBE\u7F6E\u6253\u5F00\u7F51\u683C\u89C6\u56FE\u65F6\u7684\u9ED8\u8BA4\u6392\u5E8F\u6A21\u5F0F",
grid_item_width: "\u7F51\u683C\u9879\u76EE\u5BBD\u5EA6",
grid_item_width_desc:
"\u8BBE\u7F6E\u7F51\u683C\u9879\u76EE\u7684\u5BBD\u5EA6",
grid_item_height: "\u7F51\u683C\u9879\u76EE\u9AD8\u5EA6",
grid_item_height_desc:
"\u8BBE\u7F6E\u7F51\u683C\u9879\u76EE\u7684\u9AD8\u5EA6 (\u8BBE\u4E3A0\u65F6\u4E3A\u81EA\u52A8\u8C03\u6574)",
image_area_width: "\u56FE\u7247\u533A\u57DF\u5BBD\u5EA6",
image_area_width_desc:
"\u8BBE\u7F6E\u56FE\u7247\u9884\u89C8\u533A\u57DF\u7684\u5BBD\u5EA6",
image_area_height: "\u56FE\u7247\u533A\u57DF\u9AD8\u5EA6",
image_area_height_desc:
"\u8BBE\u7F6E\u56FE\u7247\u9884\u89C8\u533A\u57DF\u7684\u9AD8\u5EA6",
title_font_size: "\u6807\u9898\u5B57\u4F53\u5927\u5C0F",
title_font_size_desc:
"\u8BBE\u7F6E\u6807\u9898\u5B57\u4F53\u7684\u5927\u5C0F",
summary_length: "\u6458\u8981\u957F\u5EA6",
summary_length_desc: "\u8BBE\u7F6E\u6458\u8981\u7684\u957F\u5EA6",
enable_file_watcher: "\u542F\u7528\u6587\u4EF6\u76D1\u63A7",
enable_file_watcher_desc:
"\u542F\u7528\u540E\u4F1A\u81EA\u52A8\u68C0\u6D4B\u6587\u4EF6\u53D8\u66F4\u5E76\u66F4\u65B0\u89C6\u56FE\uFF0C\u5173\u95ED\u540E\u9700\u624B\u52A8\u70B9\u51FB\u5237\u65B0\u6309\u94AE",
reset_to_default: "\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C",
reset_to_default_desc:
"\u5C06\u6240\u6709\u8BBE\u7F6E\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C",
settings_reset_notice:
"\u8BBE\u7F6E\u503C\u5DF2\u91CD\u7F6E\u4E3A\u9ED8\u8BA4\u503C",
ignored_folders_settings: "\u5FFD\u7565\u6587\u4EF6\u5939\u8BBE\u7F6E",
display_mode_settings: "\u663E\u793A\u6A21\u5F0F\u8BBE\u7F6E",
show_bookmarks_mode: "\u663E\u793A\u4E66\u7B7E\u6A21\u5F0F",
show_search_mode: "\u663E\u793A\u641C\u7D22\u7ED3\u679C\u6A21\u5F0F",
show_backlinks_mode: "\u663E\u793A\u53CD\u5411\u94FE\u63A5\u6A21\u5F0F",
show_all_files_mode: "\u663E\u793A\u6240\u6709\u6587\u4EF6\u6A21\u5F0F",
show_random_note_mode: "\u663E\u793A\u968F\u673A\u7B14\u8BB0\u6A21\u5F0F",
random_note_notes_only: "\u4EC5\u7B14\u8BB0",
random_note_include_media_files: "\u5305\u542B\u56FE\u7247\u89C6\u9891",
// 显示"返回上级文件夹"选项设置
show_parent_folder_item:
"\u663E\u793A\u300C\u8FD4\u56DE\u4E0A\u7EA7\u6587\u4EF6\u5939\u300D",
show_parent_folder_item_desc:
"\u5728\u7F51\u683C\u7684\u7B2C\u4E00\u9879\u663E\u793A\u300C\u8FD4\u56DE\u4E0A\u7EA7\u6587\u4EF6\u5939\u300D\u9009\u9879",
parent_folder: "\u4E0A\u7EA7\u6587\u4EF6\u5939",
// 默认打开位置设置
default_open_location: "\u9ED8\u8BA4\u6253\u5F00\u4F4D\u7F6E",
default_open_location_desc:
"\u8BBE\u7F6E\u7F51\u683C\u89C6\u56FE\u9ED8\u8BA4\u6253\u5F00\u7684\u4F4D\u7F6E",
open_in_left_sidebar: "\u5728\u5DE6\u4FA7\u8FB9\u680F\u6253\u5F00",
open_in_right_sidebar: "\u5728\u53F3\u4FA7\u8FB9\u680F\u6253\u5F00",
open_in_new_tab: "\u5728\u65B0\u6807\u7B7E\u9875\u6253\u5F00",
reuse_existing_leaf:
"\u91CD\u590D\u4F7F\u7528\u5DF2\u6253\u5F00\u7684\u89C6\u56FE",
reuse_existing_leaf_desc:
"\u6253\u5F00\u7F51\u683C\u89C6\u56FE\u65F6\uFF0C\u4F18\u5148\u4F7F\u7528\u5DF2\u6253\u5F00\u7684\u89C6\u56FE\u800C\u975E\u521B\u5EFA\u65B0\u89C6\u56FE",
custom_document_extensions:
"\u81EA\u5B9A\u4E49\u6587\u4EF6\u6269\u5C55\u540D",
custom_document_extensions_desc:
"\u989D\u5916\u7684\u6587\u4EF6\u6269\u5C55\u540D\uFF08\u7528\u9017\u53F7\u5206\u9694\uFF0C\u4E0D\u542B\u70B9\u53F7\uFF09",
custom_document_extensions_placeholder: "\u4F8B\u5982\uFF1Atxt,doc,docx",
// 选择文件夹对话框
select_folders: "\u9009\u62E9\u6587\u4EF6\u5939",
open_grid_view: "\u6253\u5F00\u7F51\u683C\u89C6\u56FE",
open_note_in_grid_view:
"\u5728\u7F51\u683C\u89C6\u56FE\u4E2D\u6253\u5F00\u5F53\u524D\u7B14\u8BB0",
open_backlinks_in_grid_view:
"\u5728\u7F51\u683C\u89C6\u56FE\u4E2D\u6253\u5F00\u53CD\u5411\u94FE\u63A5",
open_settings: "\u6253\u5F00\u8BBE\u7F6E",
delete_note: "\u5220\u9664\u6587\u4EF6",
open_folder_note: "\u6253\u5F00\u6587\u4EF6\u5939\u7B14\u8BB0",
create_folder_note: "\u521B\u5EFA\u6587\u4EF6\u5939\u7B14\u8BB0",
ignore_folder: "\u5FFD\u7565\u6B64\u6587\u4EF6\u5939",
searching: "\u641C\u7D22\u4E2D...",
no_files: "\u6CA1\u6709\u627E\u5230\u4EFB\u4F55\u6587\u4EF6",
filter_folders: "\u7B5B\u9009\u6587\u4EF6\u5939...",
},
ja: {
// 通知メッジ
bookmarks_plugin_disabled:
"\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF\u30D7\u30E9\u30B0\u30A4\u30F3\u3092\u6709\u52B9\u306B\u3057\u3066\u304F\u3060\u3055\u3044",
// ボタンとラベル
sorting: "\u4E26\u3073\u66FF\u3048",
refresh: "\u66F4\u65B0",
reselect_folder: "\u30D5\u30A9\u30EB\u30C0\u3092\u518D\u9078\u629E",
go_up: "\u4E0A\u306E\u968E\u5C64\u3078",
no_backlinks: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u306A\u3057",
search: "\u691C\u7D22",
search_placeholder: "\u30AD\u30FC\u30EF\u30FC\u30C9\u691C\u7D22",
search_current_location_only:
"\u73FE\u5728\u306E\u5834\u6240\u306E\u307F\u691C\u7D22",
cancel: "\u30AD\u30E3\u30F3\u30BB\u30EB",
new_note: "\u65B0\u898F\u30CE\u30FC\u30C8",
untitled: "\u7121\u984C",
files: "\u30D5\u30A1\u30A4\u30EB",
add: "\u8FFD\u52A0",
// ビュータイトル
grid_view_title: "\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC",
bookmarks_mode: "\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF",
folder_mode: "\u30D5\u30A9\u30EB\u30C0",
search_results: "\u691C\u7D22\u7D50\u679C",
backlinks_mode: "\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF",
all_files_mode: "\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB",
random_note_mode: "\u30E9\u30F3\u30C0\u30E0\u30CE\u30FC\u30C8",
// 並べ替えオプション
sort_name_asc: "\u540D\u524D (A \u2192 Z)",
sort_name_desc: "\u540D\u524D (Z \u2192 A)",
sort_mtime_desc: "\u66F4\u65B0\u65E5\u6642 (\u65B0 \u2192 \u53E4)",
sort_mtime_asc: "\u66F4\u65B0\u65E5\u6642 (\u53E4 \u2192 \u65B0)",
sort_ctime_desc: "\u4F5C\u6210\u65E5\u6642 (\u65B0 \u2192 \u53E4)",
sort_ctime_asc: "\u4F5C\u6210\u65E5\u6642 (\u53E4 \u2192 \u65B0)",
sort_random: "\u30E9\u30F3\u30C0\u30E0",
// 設定
grid_view_settings:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u8A2D\u5B9A",
media_files_settings:
"\u30E1\u30C7\u30A3\u30A2\u30D5\u30A1\u30A4\u30EB\u8A2D\u5B9A",
show_media_files: "\u753B\u50CF\u3068\u52D5\u753B\u3092\u8868\u793A",
show_media_files_desc:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3067\u753B\u50CF\u3068\u52D5\u753B\u30D5\u30A1\u30A4\u30EB\u3092\u8868\u793A\u3059\u308B",
search_media_files: "\u753B\u50CF\u3068\u52D5\u753B\u3092\u691C\u7D22",
search_media_files_desc:
"\u691C\u7D22\u7D50\u679C\u306B\u753B\u50CF\u3068\u52D5\u753B\u30D5\u30A1\u30A4\u30EB\u3092\u542B\u3081\u308B\uFF08\u753B\u50CF\u3068\u52D5\u753B\u306E\u8868\u793A\u304C\u6709\u52B9\u306A\u5834\u5408\u306E\u307F\uFF09",
show_video_thumbnails:
"\u52D5\u753B\u306E\u30B5\u30E0\u30CD\u30A4\u30EB\u3092\u8868\u793A",
show_video_thumbnails_desc:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3067\u52D5\u753B\u306E\u30B5\u30E0\u30CD\u30A4\u30EB\u3092\u8868\u793A\u3059\u308B\u3001\u7121\u52B9\u306E\u5834\u5408\u306F\u518D\u751F\u30A2\u30A4\u30B3\u30F3\u3092\u8868\u793A",
ignored_folders: "\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0",
ignored_folders_desc:
"\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u3092\u8A2D\u5B9A\u3059\u308B",
add_ignored_folder:
"\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u3092\u8FFD\u52A0",
no_ignored_folders:
"\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
ignored_folder_patterns:
"\u30D1\u30BF\u30FC\u30F3\u3067\u30D5\u30A9\u30EB\u30C0\u3068\u30D5\u30A1\u30A4\u30EB\u3092\u7121\u8996",
ignored_folder_patterns_desc:
"\u6587\u5B57\u5217\u30D1\u30BF\u30FC\u30F3\u3092\u4F7F\u7528\u3057\u3066\u30D5\u30A9\u30EB\u30C0\u3068\u30D5\u30A1\u30A4\u30EB\u3092\u7121\u8996\u3059\u308B\uFF08\u6B63\u898F\u8868\u73FE\u3092\u30B5\u30DD\u30FC\u30C8\uFF09",
add_ignored_folder_pattern:
"\u30D5\u30A9\u30EB\u30C0\u30D1\u30BF\u30FC\u30F3\u3092\u8FFD\u52A0",
ignored_folder_pattern_placeholder:
"\u30D5\u30A9\u30EB\u30C0\u540D\u307E\u305F\u306F\u6B63\u898F\u8868\u73FE\u30D1\u30BF\u30FC\u30F3\u3092\u5165\u529B",
no_ignored_folder_patterns:
"\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u30D1\u30BF\u30FC\u30F3\u306F\u3042\u308A\u307E\u305B\u3093\u3002",
remove: "\u524A\u9664",
default_sort_type:
"\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u4E26\u3073\u66FF\u3048",
default_sort_type_desc:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3092\u958B\u3044\u305F\u3068\u304D\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u4E26\u3073\u66FF\u3048\u65B9\u6CD5\u3092\u8A2D\u5B9A",
grid_item_width:
"\u30B0\u30EA\u30C3\u30C9\u30A2\u30A4\u30C6\u30E0\u306E\u5E45",
grid_item_width_desc:
"\u30B0\u30EA\u30C3\u30C9\u30A2\u30A4\u30C6\u30E0\u306E\u5E45\u3092\u8A2D\u5B9A",
grid_item_height:
"\u30B0\u30EA\u30C3\u30C9\u30A2\u30A4\u30C6\u30E0\u306E\u9AD8\u3055",
grid_item_height_desc:
"\u30B0\u30EA\u30C3\u30C9\u30A2\u30A4\u30C6\u30E0\u306E\u9AD8\u3055\u3092\u8A2D\u5B9A\uFF080\u306B\u8A2D\u5B9A\u3059\u308B\u3068\u81EA\u52D5\u8ABF\u6574\uFF09",
image_area_width: "\u753B\u50CF\u30A8\u30EA\u30A2\u306E\u5E45",
image_area_width_desc:
"\u753B\u50CF\u30D7\u30EC\u30D3\u30E5\u30FC\u30A8\u30EA\u30A2\u306E\u5E45\u3092\u8A2D\u5B9A",
image_area_height: "\u753B\u50CF\u30A8\u30EA\u30A2\u306E\u9AD8\u3055",
image_area_height_desc:
"\u753B\u50CF\u30D7\u30EC\u30D3\u30E5\u30FC\u30A8\u30EA\u30A2\u306E\u9AD8\u3055\u3092\u8A2D\u5B9A",
title_font_size:
"\u30BF\u30A4\u30C8\u30EB\u306E\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA",
title_font_size_desc:
"\u30BF\u30A4\u30C8\u30EB\u306E\u30D5\u30A9\u30F3\u30C8\u30B5\u30A4\u30BA\u3092\u8A2D\u5B9A",
summary_length: "\u8981\u7D04\u306E\u9577\u3055",
summary_length_desc: "\u8981\u7D04\u306E\u9577\u3055\u3092\u8A2D\u5B9A",
enable_file_watcher:
"\u30D5\u30A1\u30A4\u30EB\u76E3\u8996\u3092\u6709\u52B9\u306B\u3059\u308B",
enable_file_watcher_desc:
"\u6709\u52B9\u306B\u3059\u308B\u3068\u3001\u30D5\u30A1\u30A4\u30EB\u306E\u5909\u66F4\u3092\u81EA\u52D5\u7684\u306B\u691C\u51FA\u3057\u3066\u30D3\u30E5\u30FC\u3092\u66F4\u65B0\u3057\u307E\u3059\u3002\u7121\u52B9\u306E\u5834\u5408\u306F\u3001\u66F4\u65B0\u30DC\u30BF\u30F3\u3092\u624B\u52D5\u3067\u30AF\u30EA\u30C3\u30AF\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059",
reset_to_default: "\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u623B\u3059",
reset_to_default_desc:
"\u3059\u3079\u3066\u306E\u8A2D\u5B9A\u3092\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306B\u623B",
settings_reset_notice:
"\u8A2D\u5B9A\u5024\u304C\u30C7\u30D5\u30A9\u30EB\u30C8\u5024\u306B\u30EA\u30BB\u30C3\u30C8\u3055\u308C\u307E\u3057\u305F",
ignored_folders_settings:
"\u7121\u8996\u3059\u308B\u30D5\u30A9\u30EB\u30C0\u8A2D\u5B9A",
display_mode_settings: "\u8868\u793A\u30E2\u30FC\u30C9\u8A2D\u5B9A",
show_bookmarks_mode:
"\u30D6\u30C3\u30AF\u30DE\u30FC\u30AF\u30E2\u30FC\u30C9\u3092\u8868\u793A",
show_search_mode:
"\u691C\u7D22\u7D50\u679C\u30E2\u30FC\u30C9\u3092\u8868\u793A",
show_backlinks_mode:
"\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u30E2\u30FC\u30C9\u3092\u8868\u793A",
show_all_files_mode:
"\u5168\u30D5\u30A1\u30A4\u30EB\u30E2\u30FC\u30C9\u3092\u8868\u793A",
show_random_note_mode:
"\u30E9\u30F3\u30C0\u30E0\u30CE\u30FC\u30C8\u30E2\u30FC\u30C9\u3092\u8868\u793A",
random_note_notes_only: "\u30CE\u30FC\u30C8\u306E\u307F",
random_note_include_media_files:
"\u30E1\u30C7\u30A3\u30A2\u3092\u542B\u3080",
// 「親フォルダ」オプション設定を表示
show_parent_folder_item:
"\u300C\u89AA\u30D5\u30A9\u30EB\u30C0\u300D\u9805\u76EE\u3092\u8868\u793A",
show_parent_folder_item_desc:
"\u30B0\u30EA\u30C3\u30C9\u306E\u6700\u521D\u306E\u9805\u76EE\u3068\u3057\u3066\u300C\u89AA\u30D5\u30A9\u30EB\u30C0\u300D\u9805\u76EE\u3092\u8868\u793A\u3057\u307E\u3059",
parent_folder: "\u89AA\u30D5\u30A9\u30EB\u30C0",
// 預設開啟位置設定
default_open_location:
"\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u958B\u304F\u5834\u6240",
default_open_location_desc:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3092\u958B\u304F\u30C7\u30D5\u30A9\u30EB\u30C8\u306E\u5834\u6240\u3092\u8A2D\u5B9A",
open_in_left_sidebar:
"\u5DE6\u30B5\u30A4\u30C9\u30D0\u30FC\u3067\u958B\u304F",
open_in_right_sidebar:
"\u53F3\u30B5\u30A4\u30C9\u30D0\u30FC\u3067\u958B\u304F",
open_in_new_tab: "\u65B0\u3057\u3044\u30BF\u30D6\u3067\u958B\u304F",
reuse_existing_leaf:
"\u65E2\u5B58\u306E\u30D3\u30E5\u30FC\u3092\u518D\u5229\u7528",
reuse_existing_leaf_desc:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3092\u958B\u304F\u3068\u304D\u3001\u65B0\u3057\u3044\u30D3\u30E5\u30FC\u3092\u4F5C\u6210\u305B\u305A\u306B\u65E2\u5B58\u306E\u30D3\u30E5\u30FC\u3092\u512A\u5148\u4F7F\u7528",
custom_document_extensions:
"\u30AB\u30B9\u30BF\u30E0\u6587\u66F8\u62E1\u5F35\u5B50",
custom_document_extensions_desc:
"\u8FFD\u52A0\u306E\u6587\u66F8\u62E1\u5F35\u5B50\uFF08\u30AB\u30F3\u30DE\u533A\u5207\u308A\u3001\u30C9\u30C3\u30C8\u7121\u3057\uFF09",
custom_document_extensions_placeholder: "\u4F8B\uFF1Atxt,doc,docx",
// フォルダ選択ダイアログ
select_folders: "\u30D5\u30A9\u30EB\u30C0\u3092\u9078\u629E",
open_grid_view:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3092\u958B\u304F",
open_note_in_grid_view:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3067\u73FE\u5728\u306E\u30CE\u30FC\u30C8\u3092\u958B\u304F",
open_backlinks_in_grid_view:
"\u30B0\u30EA\u30C3\u30C9\u30D3\u30E5\u30FC\u3067\u30D0\u30C3\u30AF\u30EA\u30F3\u30AF\u3092\u958B\u304F",
open_settings: "\u8A2D\u5B9A\u3092\u958B\u304F",
delete_note: "\u30D5\u30A1\u30A4\u30EB\u3092\u524A\u9664",
open_folder_note:
"\u30D5\u30A9\u30EB\u30C0\u30CE\u30FC\u30C8\u3092\u958B\u304F",
create_folder_note:
"\u30D5\u30A9\u30EB\u30C0\u30CE\u30FC\u30C8\u3092\u4F5C\u6210",
ignore_folder: "\u3053\u306E\u30D5\u30A9\u30EB\u30C0\u3092\u7121\u8996",
searching: "\u691C\u7D22\u4E2D...",
no_files:
"\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093",
filter_folders:
"\u30D5\u30A9\u30EB\u30C0\u3092\u30D5\u30A3\u30EB\u30BF\u30EA\u30F3\u30B0...",
},
};
// src/FolderSelectionModal.ts
function showFolderSelectionModal(app, plugin, activeView) {
new FolderSelectionModal(app, plugin, activeView).open();
}
var FolderSelectionModal = class extends import_obsidian.Modal {
constructor(app, plugin, activeView) {
super(app);
this.folderOptions = [];
this.selectedIndex = -1;
this.plugin = plugin;
this.activeView = activeView;
}
onOpen() {
const { contentEl } = this;
contentEl.empty();
new import_obsidian.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"),
...(import_obsidian.Platform.isMobile && { tabindex: "1" }),
},
});
this.folderOptionsContainer = contentEl.createEl("div", {
cls: "ge-folder-options-container",
attr: import_obsidian.Platform.isMobile ? { tabindex: "0" } : {},
});
this.searchInput.addEventListener("input", () => {
const searchTerm = this.searchInput.value.toLowerCase();
this.filterFolderOptions(searchTerm);
});
this.searchInput.addEventListener("keydown", this.handleKeyDown.bind(this));
if (this.plugin.settings.showBookmarksMode) {
const bookmarksPlugin = this.app.internalPlugins.plugins.bookmarks;
if (bookmarksPlugin == null ? void 0 : bookmarksPlugin.enabled) {
const bookmarkOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option ge-special-option",
text: `\u{1F4D1} ${t("bookmarks_mode")}`,
});
bookmarkOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("bookmarks");
} else {
this.plugin.activateView("bookmarks");
}
this.close();
});
this.folderOptions.push(bookmarkOption);
}
}
if (this.plugin.settings.showSearchMode) {
const searchLeaf = this.app.workspace.getLeavesOfType("search")[0];
if (searchLeaf) {
const searchView = searchLeaf.view;
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: `\u{1F50D} ${t("search_results")}: ${searchInputEl.value}`,
});
searchOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("search");
} else {
this.plugin.activateView("search");
}
this.close();
});
this.folderOptions.push(searchOption);
}
}
}
}
if (this.plugin.settings.showBacklinksMode) {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile) {
const activeFileName = activeFile ? `: ${activeFile.basename}` : "";
const backlinksOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option ge-special-option",
text: `\u{1F517} ${t("backlinks_mode")}${activeFileName}`,
});
backlinksOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("backlinks");
} else {
this.plugin.activateView("backlinks");
}
this.close();
});
this.folderOptions.push(backlinksOption);
}
}
if (this.plugin.settings.showAllFilesMode) {
const allFilesOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option ge-special-option",
text: `\u{1F4D4} ${t("all_files_mode")}`,
});
allFilesOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("all-files");
} else {
this.plugin.activateView("all-files");
}
this.close();
});
this.folderOptions.push(allFilesOption);
}
if (this.plugin.settings.showRandomNoteMode) {
const randomNoteOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option ge-special-option",
text: `\u{1F3B2} ${t("random_note_mode")}`,
});
randomNoteOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("random-note");
} else {
this.plugin.activateView("random-note");
}
this.close();
});
this.folderOptions.push(randomNoteOption);
}
const rootFolderOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option",
text: `\u{1F4C1} /`,
});
rootFolderOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("folder", "/");
} else {
this.plugin.activateView("folder", "/");
}
this.close();
});
this.folderOptions.push(rootFolderOption);
const folders = this.app.vault
.getAllFolders()
.filter((folder) => {
return !this.plugin.settings.ignoredFolders.some(
(ignoredPath) =>
folder.path === ignoredPath ||
folder.path.startsWith(ignoredPath + "/")
);
})
.sort((a, b) => a.path.localeCompare(b.path));
folders.forEach((folder) => {
const folderOption = this.folderOptionsContainer.createEl("div", {
cls: "ge-grid-view-folder-option",
text: `\u{1F4C1} ${folder.path || "/"}`,
});
folderOption.addEventListener("click", () => {
if (this.activeView) {
this.activeView.setSource("folder", folder.path);
} else {
this.plugin.activateView("folder", folder.path);
}
this.close();
});
this.folderOptions.push(folderOption);
});
this.folderOptions.forEach((option, index) => {
option.addEventListener("mouseenter", () => {
this.updateSelection(index);
});
});
}
// 處理鍵盤事件
handleKeyDown(event) {
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, visibleOptions) {
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) {
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() {
return this.folderOptions.filter(
(option) => option.style.display !== "none"
);
}
// 篩選資料夾選項
filterFolderOptions(searchTerm) {
let hasVisibleOptions = false;
this.folderOptions.forEach((option) => {
var _a;
const text =
((_a = option.textContent) == null ? void 0 : _a.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() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/mediaUtils.ts
var import_obsidian2 = require("obsidian");
async function findFirstImageInNote(app, content) {
try {
const internalMatch = content.match(
/(?:!?\[\[(.*?\.(?:jpg|jpeg|png|gif|webp))(?:\|.*?)?\]\]|!\[(.*?)\]\(\s*(\S+?(?:\.(?:jpg|jpeg|png|gif|webp)|format=(?:jpg|jpeg|png|gif|webp))[^\s)]*)\s*(?:\s+["'][^"']*["'])?\s*\))/i
);
if (internalMatch) {
return processMediaLink(app, internalMatch[0]);
} else {
return null;
}
} catch (error) {
console.error("Error finding image in note:", error);
return null;
}
}
function processMediaLink(app, linkText) {
const internalMatch = linkText.match(/!?\[\[(.*?)\]\]/);
if (internalMatch) {
const file = app.metadataCache.getFirstLinkpathDest(internalMatch[1], "");
if (file) {
return app.vault.getResourcePath(file);
}
}
const markdownMatch = linkText.match(/!?\[(.*?)\]\((.*?)\)/);
if (markdownMatch) {
const url = markdownMatch[2].split(' "')[0];
if (url.startsWith("http")) {
return url;
} else {
const file = app.metadataCache.getFirstLinkpathDest(url, "");
if (!file) {
const fileByPath = app.vault.getAbstractFileByPath(url);
if (fileByPath instanceof import_obsidian2.TFile) {
return app.vault.getResourcePath(fileByPath);
}
} else {
return app.vault.getResourcePath(file);
}
}
}
return null;
}
// src/MediaModal.ts
var import_obsidian3 = require("obsidian");
// src/fileUtils.ts
var customDocumentExtensions = [];
function updateCustomDocumentExtensions(settings) {
if (settings.customDocumentExtensions) {
customDocumentExtensions = settings.customDocumentExtensions
.split(",")
.map((ext) => ext.trim().toLowerCase())
.filter((ext) => ext.length > 0);
} else {
customDocumentExtensions = [];
}
}
function isDocumentFile(file) {
const defaultDocumentExtensions = ["md", "pdf", "canvas"];
const extension = file.extension.toLowerCase();
return (
defaultDocumentExtensions.includes(extension) ||
customDocumentExtensions.includes(extension)
);
}
function isImageFile(file) {
const imageExtensions = [
"jpg",
"jpeg",
"png",
"gif",
"webp",
"avif",
"bmp",
"svg",
];
return imageExtensions.includes(file.extension.toLowerCase());
}
function isVideoFile(file) {
const videoExtensions = ["mp4", "webm", "mov", "avi", "mkv", "ogv"];
return videoExtensions.includes(file.extension.toLowerCase());
}
function isAudioFile(file) {
const audioExtensions = ["flac", "m4a", "mp3", "ogg", "wav", "webm", "3gp"];
return audioExtensions.includes(file.extension.toLowerCase());
}
function isMediaFile(file) {
return isImageFile(file) || isVideoFile(file) || isAudioFile(file);
}
// src/MediaModal.ts
var MediaModal = class extends import_obsidian3.Modal {
// 儲存 GridView 實例的引用
constructor(app, file, mediaFiles, gridView) {
super(app);
this.currentMediaElement = null;
this.isZoomed = false;
this.handleWheel = null;
this.file = file;
this.mediaFiles = mediaFiles;
this.currentIndex = this.mediaFiles.findIndex((f) => f.path === file.path);
this.gridView = gridView;
this.modalEl.addClass("ge-media-modal");
}
onOpen() {
const { contentEl } = this;
if (this.gridView) {
this.gridView.disableKeyboardNavigation();
}
contentEl.empty();
contentEl.style.width = "100%";
contentEl.style.height = "100%";
contentEl.addClass("ge-media-modal-content");
const mediaView = contentEl.createDiv("ge-media-view");
const closeButton = contentEl.createDiv("ge-media-close-button");
(0, import_obsidian3.setIcon)(closeButton, "x");
closeButton.addEventListener("click", (e) => {
e.stopPropagation();
this.close();
});
const prevArea = contentEl.createDiv("ge-media-prev-area");
const nextArea = contentEl.createDiv("ge-media-next-area");
const mediaContainer = mediaView.createDiv("ge-media-container");
mediaContainer.addEventListener("click", (e) => {
if (e.target === mediaContainer) {
this.close();
}
});
prevArea.addEventListener("click", (e) => {
e.stopPropagation();
this.showPrevMedia();
});
nextArea.addEventListener("click", (e) => {
e.stopPropagation();
this.showNextMedia();
});
contentEl.addEventListener("wheel", (e) => {
if (!this.isZoomed) {
e.preventDefault();
if (e.deltaY > 0) {
this.showNextMedia();
} else {
this.showPrevMedia();
}
}
});
this.scope.register(null, "ArrowLeft", () => {
this.showPrevMedia();
return false;
});
this.scope.register(null, "ArrowRight", () => {
this.showNextMedia();
return false;
});
this.showMediaAtIndex(this.currentIndex);
}
onClose() {
const { contentEl } = this;
contentEl.empty();
if (this.handleWheel) {
const mediaView = contentEl.querySelector(".ge-media-view");
if (mediaView) {
mediaView.removeEventListener("wheel", this.handleWheel);
}
this.handleWheel = null;
}
if (this.gridView) {
this.gridView.enableKeyboardNavigation();
const currentFile = this.mediaFiles[this.currentIndex];
const gridItemIndex = this.gridView.gridItems.findIndex(
(item) => item.dataset.filePath === currentFile.path
);
if (gridItemIndex >= 0) {
this.gridView.hasKeyboardFocus = true;
this.gridView.selectItem(gridItemIndex);
}
}
}
// 顯示指定索引的媒體檔案
showMediaAtIndex(index) {
if (index < 0 || index >= this.mediaFiles.length) return;
const { contentEl } = this;
const mediaContainer = contentEl.querySelector(".ge-media-container");
if (!mediaContainer) return;
this.currentIndex = index;
if (this.handleWheel) {
const mediaView = contentEl.querySelector(".ge-media-view");
if (mediaView) {
mediaView.removeEventListener("wheel", this.handleWheel);
}
this.handleWheel = null;
}
this.isZoomed = false;
const mediaFile = this.mediaFiles[index];
if (isImageFile(mediaFile)) {
const img = document.createElement("img");
img.className = "ge-fullscreen-image";
img.style.display = "none";
img.src = this.app.vault.getResourcePath(mediaFile);
img.onload = () => {
if (this.currentMediaElement) {
this.currentMediaElement.remove();
}
this.currentMediaElement = img;
this.resetImageStyles(img);
img.style.display = "";
};
mediaContainer.appendChild(img);
img.addEventListener("click", (event) => {
event.stopPropagation();
this.toggleImageZoom(img);
});
} else if (isVideoFile(mediaFile) || isAudioFile(mediaFile)) {
if (this.currentMediaElement) {
this.currentMediaElement.remove();
}
const video = document.createElement("video");
video.className = "ge-fullscreen-video";
video.controls = true;
video.autoplay = true;
video.src = this.app.vault.getResourcePath(mediaFile);
mediaContainer.appendChild(video);
this.currentMediaElement = video;
}
const oldFileNameElement = mediaContainer.querySelector(
".ge-fullscreen-file-name"
);
if (oldFileNameElement) {
oldFileNameElement.remove();
}
if (isAudioFile(mediaFile)) {
const fileName = mediaFile.name;
const fileNameElement = document.createElement("div");
fileNameElement.className = "ge-fullscreen-file-name";
fileNameElement.textContent = fileName;
mediaContainer.appendChild(fileNameElement);
}
}
// 顯示下一個媒體檔案
showNextMedia() {
const nextIndex = (this.currentIndex + 1) % this.mediaFiles.length;
this.showMediaAtIndex(nextIndex);
}
// 顯示上一個媒體檔案
showPrevMedia() {
const prevIndex =
(this.currentIndex - 1 + this.mediaFiles.length) % this.mediaFiles.length;
this.showMediaAtIndex(prevIndex);
}
// 重設圖片樣式
resetImageStyles(img) {
const mediaView = this.contentEl.querySelector(".ge-media-view");
if (!mediaView) return;
img.style.width = "auto";
img.style.height = "auto";
img.style.maxWidth = "100vw";
img.style.maxHeight = "100vh";
img.style.position = "absolute";
img.style.left = "50%";
img.style.top = "50%";
img.style.transform = "translate(-50%, -50%)";
img.style.cursor = "zoom-in";
mediaView.style.overflowX = "hidden";
mediaView.style.overflowY = "hidden";
img.onload = () => {
if (mediaView.clientWidth > mediaView.clientHeight) {
if (img.naturalHeight < mediaView.clientHeight) {
img.style.height = "100%";
}
} else {
if (img.naturalWidth < mediaView.clientWidth) {
img.style.width = "100%";
}
}
};
if (img.complete) {
if (mediaView.clientWidth > mediaView.clientHeight) {
if (img.naturalHeight < mediaView.clientHeight) {
img.style.height = "100%";
}
} else {
if (img.naturalWidth < mediaView.clientWidth) {
img.style.width = "100%";
}
}
}
}
// 切換圖片縮放
toggleImageZoom(img) {
const mediaView = this.contentEl.querySelector(".ge-media-view");
if (!mediaView) return;
if (!this.isZoomed) {
if (mediaView.clientWidth > mediaView.clientHeight) {
if (img.naturalHeight < mediaView.clientHeight) {
img.style.maxWidth = "none";
}
} else {
if (img.naturalWidth < mediaView.clientWidth) {
img.style.maxHeight = "none";
}
}
if (img.offsetWidth < mediaView.clientWidth) {
img.style.width = "100vw";
img.style.height = "auto";
mediaView.style.overflowX = "hidden";
mediaView.style.overflowY = "scroll";
} else {
img.style.width = "auto";
img.style.height = "100vh";
mediaView.style.overflowX = "scroll";
mediaView.style.overflowY = "hidden";
this.handleWheel = (event) => {
event.preventDefault();
mediaView.scrollLeft += event.deltaY;
};
mediaView.addEventListener("wheel", this.handleWheel);
}
img.style.maxWidth = "none";
img.style.maxHeight = "none";
img.style.position = "relative";
img.style.left = "0";
img.style.top = "0";
img.style.margin = "auto";
img.style.transform = "none";
img.style.cursor = "zoom-out";
this.isZoomed = true;
} else {
if (this.handleWheel) {
mediaView.removeEventListener("wheel", this.handleWheel);
this.handleWheel = null;
}
this.resetImageStyles(img);
this.isZoomed = false;
}
}
};
// src/SearchModal.ts
var import_obsidian4 = require("obsidian");
var import_obsidian5 = require("obsidian");
var SearchModal = class extends import_obsidian4.Modal {
constructor(app, gridView, defaultQuery) {
super(app);
this.gridView = gridView;
this.defaultQuery = defaultQuery;
}
onOpen() {
const { contentEl } = this;
contentEl.empty();
new import_obsidian4.Setting(contentEl).setName(t("search")).setHeading();
if (this.gridView) {
this.gridView.disableKeyboardNavigation();
}
const searchContainer = contentEl.createDiv("ge-search-container");
const searchInput = searchContainer.createEl("input", {
type: "text",
value: this.defaultQuery,
placeholder: t("search_placeholder"),
});
const clearButton = searchContainer.createDiv("ge-search-clear-button");
clearButton.style.display = this.defaultQuery ? "flex" : "none";
(0, import_obsidian5.setIcon)(clearButton, "x");
searchInput.addEventListener("input", () => {
clearButton.style.display = searchInput.value ? "flex" : "none";
});
clearButton.addEventListener("click", () => {
searchInput.value = "";
clearButton.style.display = "none";
searchInput.focus();
});
const searchScopeContainer = contentEl.createDiv(
"ge-search-scope-container"
);
const searchScopeCheckbox = searchScopeContainer.createEl("input", {
type: "checkbox",
cls: "ge-search-scope-checkbox",
});
searchScopeCheckbox.checked = !this.gridView.searchAllFiles;
const searchScopeLabel = searchScopeContainer.createEl("span", {
text: t("search_current_location_only"),
cls: "ge-search-scope-label",
});
searchScopeContainer.addEventListener("click", (e) => {
if (e.target !== searchScopeCheckbox) {
searchScopeCheckbox.checked = !searchScopeCheckbox.checked;
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
}
});
searchScopeCheckbox.addEventListener("change", () => {
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
});
const buttonContainer = contentEl.createDiv("ge-button-container");
const searchButton = buttonContainer.createEl("button", {
text: t("search"),
});
const cancelButton = buttonContainer.createEl("button", {
text: t("cancel"),
});
const performSearch = () => {
this.gridView.searchQuery = searchInput.value;
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
this.gridView.clearSelection();
this.gridView.render();
this.gridView.app.workspace.requestSaveLayout();
this.close();
};
searchButton.addEventListener("click", performSearch);
searchInput.addEventListener("keypress", (e) => {
if (e.key === "Enter") {
performSearch();
}
});
cancelButton.addEventListener("click", () => {
this.close();
});
searchInput.focus();
searchInput.setSelectionRange(
searchInput.value.length,
searchInput.value.length
);
}
onClose() {
const { contentEl } = this;
contentEl.empty();
if (this.gridView) {
this.gridView.enableKeyboardNavigation();
}
}
};
function showSearchModal(app, gridView, defaultQuery = "") {
new SearchModal(app, gridView, defaultQuery).open();
}
// src/FileWatcher.ts
var import_obsidian6 = require("obsidian");
var FileWatcher = class {
constructor(plugin, gridView) {
this.plugin = plugin;
this.gridView = gridView;
this.app = plugin.app;
}
registerFileWatcher() {
if (!this.plugin.settings.enableFileWatcher) {
return;
}
this.plugin.registerEvent(
this.app.vault.on("create", (file) => {
if (file instanceof import_obsidian6.TFile) {
if (this.gridView.sourceMode === "random-note") {
return;
}
if (
this.gridView.sourceMode === "folder" &&
this.gridView.sourcePath &&
this.gridView.searchQuery === ""
) {
const fileDirPath =
file.path.split("/").slice(0, -1).join("/") || "/";
if (fileDirPath === this.gridView.sourcePath) {
this.gridView.render();
}
} else {
this.gridView.render();
}
}
})
);
this.plugin.registerEvent(
this.app.vault.on("delete", (file) => {
if (file instanceof import_obsidian6.TFile) {
if (this.gridView.sourceMode === "random-note") {
return;
}
if (
this.gridView.sourceMode === "folder" &&
this.gridView.sourcePath &&
this.gridView.searchQuery === ""
) {
const fileDirPath =
file.path.split("/").slice(0, -1).join("/") || "/";
if (fileDirPath === this.gridView.sourcePath) {
this.gridView.render();
}
} else {
this.gridView.render();
}
}
})
);
this.plugin.registerEvent(
this.app.vault.on("rename", (file, oldPath) => {
if (file instanceof import_obsidian6.TFile) {
if (this.gridView.sourceMode === "random-note") {
return;
}
if (
this.gridView.sourceMode === "folder" &&
this.gridView.sourcePath &&
this.gridView.searchQuery === ""
) {
const fileDirPath =
file.path.split("/").slice(0, -1).join("/") || "/";
const oldDirPath = oldPath.split("/").slice(0, -1).join("/") || "/";
if (
fileDirPath === this.gridView.sourcePath ||
oldDirPath === this.gridView.sourcePath
) {
this.gridView.render();
}
} else {
this.gridView.render();
}
}
})
);
this.plugin.registerEvent(
this.app.internalPlugins.plugins.bookmarks.instance.on("changed", () => {
if (this.gridView.sourceMode === "bookmarks") {
this.gridView.render();
}
})
);
}
};
// src/GridView.ts
var GridView = class extends import_obsidian7.ItemView {
// 隨機筆記是否包含圖片和影片
constructor(leaf, plugin) {
super(leaf);
this.selectedItemIndex = -1;
// 當前選中的項目索引
this.gridItems = [];
// 存儲所有網格項目的引用
this.hasKeyboardFocus = false;
// 是否有鍵盤焦點
this.keyboardNavigationEnabled = true;
this.randomNoteIncludeMedia = false;
this.plugin = plugin;
this.containerEl.addClass("ge-grid-view-container");
this.sourceMode = "";
this.sourcePath = "";
this.sortType = this.plugin.settings.defaultSortType;
this.searchQuery = "";
this.searchAllFiles = true;
this.randomNoteIncludeMedia = this.plugin.settings.showMediaFiles;
if (this.plugin.settings.enableFileWatcher) {
this.fileWatcher = new FileWatcher(plugin, this);
this.fileWatcher.registerFileWatcher();
}
this.registerDomEvent(document, "keydown", (event) => {
if (this.app.workspace.getActiveViewOfType(GridView) === this) {
this.handleKeyDown(event);
}
});
}
getViewType() {
return "grid-view";
}
getIcon() {
return "grid";
}
getDisplayText() {
if (this.sourceMode === "") {
return t("grid_view_title");
} else if (this.sourceMode === "bookmarks") {
return t("bookmarks_mode");
} else if (this.sourceMode === "folder") {
return this.sourcePath;
} else if (this.sourceMode === "search") {
return t("search_results");
} else if (this.sourceMode === "backlinks") {
return t("backlinks_mode");
} else if (this.sourceMode === "all-files") {
return t("all_files_mode");
} else if (this.sourceMode === "random-note") {
return t("random_note_mode");
} else {
return "";
}
}
setSource(mode, path = "") {
this.sourceMode = mode;
this.sourcePath = path;
this.render();
this.app.workspace.requestSaveLayout();
}
async getFiles() {
if (this.sourceMode === "folder" && this.sourcePath) {
const folder = this.app.vault.getAbstractFileByPath(this.sourcePath);
if (folder instanceof import_obsidian7.TFolder) {
const files = folder.children.filter((file) => {
if (!(file instanceof import_obsidian7.TFile)) return false;
if (isDocumentFile(file)) return true;
if (this.plugin.settings.showMediaFiles && isMediaFile(file)) {
return true;
}
return false;
});
return this.sortFiles(files);
}
return [];
} else if (this.sourceMode === "search") {
const globalSearchPlugin =
this.app.internalPlugins.getPluginById("global-search");
if (globalSearchPlugin == null ? void 0 : globalSearchPlugin.instance) {
const searchLeaf = this.app.workspace.getLeavesOfType("search")[0];
if (searchLeaf && searchLeaf.view && searchLeaf.view.dom) {
const resultDomLookup = searchLeaf.view.dom.resultDomLookup;
if (resultDomLookup) {
const files = Array.from(resultDomLookup.keys()).filter(
(file) => file instanceof import_obsidian7.TFile
);
return this.sortFiles(files);
}
}
}
return [];
} else if (this.sourceMode === "backlinks") {
const activeFile = this.app.workspace.getActiveFile();
if (!activeFile) {
return [];
}
const backlinks = /* @__PURE__ */ new Set();
const resolvedLinks = this.app.metadataCache.resolvedLinks;
for (const [sourcePath, links] of Object.entries(resolvedLinks)) {
if (Object.keys(links).includes(activeFile.path)) {
const sourceFile = this.app.vault.getAbstractFileByPath(sourcePath);
if (sourceFile) {
backlinks.add(sourceFile);
}
}
}
return this.sortFiles(this.ignoredFiles(Array.from(backlinks)));
} else if (this.sourceMode === "bookmarks") {
const bookmarksPlugin = this.app.internalPlugins.plugins.bookmarks;
if (!(bookmarksPlugin == null ? void 0 : bookmarksPlugin.enabled)) {
return [];
}
const bookmarks = bookmarksPlugin.instance.items;
const bookmarkedFiles = /* @__PURE__ */ new Set();
const processBookmarkItem = (item) => {
if (item.type === "file") {
const file = this.app.vault.getAbstractFileByPath(item.path);
if (file instanceof import_obsidian7.TFile) {
if (
isDocumentFile(file) ||
(this.plugin.settings.showMediaFiles && isMediaFile(file))
) {
bookmarkedFiles.add(file);
}
}
} else if (item.type === "group" && item.items) {
item.items.forEach(processBookmarkItem);
}
};
bookmarks.forEach(processBookmarkItem);
return Array.from(bookmarkedFiles);
} else if (this.sourceMode === "all-files") {
const allFiles = this.app.vault.getFiles();
const filteredFiles = allFiles.filter((file) => {
if (isDocumentFile(file)) return true;
if (this.plugin.settings.showMediaFiles && isMediaFile(file)) {
return true;
}
return false;
});
return this.sortFiles(filteredFiles);
} else if (this.sourceMode === "random-note") {
const allFiles = this.app.vault.getFiles();
const filteredFiles = allFiles.filter((file) => {
if (isDocumentFile(file)) return true;
if (this.randomNoteIncludeMedia && isMediaFile(file)) {
return true;
}
return false;
});
return filteredFiles.sort(() => Math.random() - 0.5);
} else {
return [];
}
}
//排序檔案
sortFiles(files) {
if (this.sortType === "name-asc") {
return files.sort((a, b) => a.basename.localeCompare(b.basename));
} else if (this.sortType === "name-desc") {
return files.sort((a, b) => b.basename.localeCompare(a.basename));
} else if (this.sortType === "mtime-desc") {
return files.sort((a, b) => b.stat.mtime - a.stat.mtime);
} else if (this.sortType === "mtime-asc") {
return files.sort((a, b) => a.stat.mtime - b.stat.mtime);
} else if (this.sortType === "ctime-desc") {
return files.sort((a, b) => b.stat.ctime - a.stat.ctime);
} else if (this.sortType === "ctime-asc") {
return files.sort((a, b) => a.stat.ctime - b.stat.ctime);
} else if (this.sortType === "random") {
return files.sort(() => Math.random() - 0.5);
} else {
return files;
}
}
//忽略檔案
ignoredFiles(files) {
return files.filter((file) => {
const isInIgnoredFolder = this.plugin.settings.ignoredFolders.some(
(folder) => file.path.startsWith(`${folder}/`)
);
if (isInIgnoredFolder) {
return false;
}
if (
this.plugin.settings.ignoredFolderPatterns &&
this.plugin.settings.ignoredFolderPatterns.length > 0
) {
const matchesIgnoredPattern =
this.plugin.settings.ignoredFolderPatterns.some((pattern) => {
try {
if (/[\^\$\*\+\?\(\)\[\]\{\}\|\\]/.test(pattern)) {
const regex = new RegExp(pattern);
return regex.test(file.path);
} else {
return file.path.toLowerCase().includes(pattern.toLowerCase());
}
} catch (error) {
return file.path.toLowerCase().includes(pattern.toLowerCase());
}
});
return !matchesIgnoredPattern;
}
return true;
});
}
async render() {
const scrollContainer = this.containerEl.children[1];
const scrollTop = scrollContainer ? scrollContainer.scrollTop : 0;
let selectedFilePath = null;
if (
this.selectedItemIndex >= 0 &&
this.selectedItemIndex < this.gridItems.length
) {
const selectedItem = this.gridItems[this.selectedItemIndex];
selectedFilePath = selectedItem.dataset.filePath || null;
}
this.containerEl.empty();
const headerButtonsDiv = this.containerEl.createDiv("ge-header-buttons");
headerButtonsDiv.addEventListener("click", (event) => {
if (event.target === headerButtonsDiv) {
event.preventDefault();
const gridContainer =
this.containerEl.querySelector(".ge-grid-container");
if (gridContainer) {
gridContainer.scrollTo({
top: 0,
behavior: "smooth",
});
}
}
});
headerButtonsDiv.addEventListener("contextmenu", (event) => {
event.preventDefault();
const menu = new import_obsidian7.Menu();
menu.addItem((item) => {
item
.setTitle(t("open_settings"))
.setIcon("settings")
.onClick(() => {
this.app.setting.open();
this.app.setting.openTabById(this.plugin.manifest.id);
});
});
menu.showAtMouseEvent(event);
});
if (this.sourceMode === "folder" && this.searchQuery === "") {
const newNoteButton = headerButtonsDiv.createEl("button", {
attr: { "aria-label": t("new_note") },
});
newNoteButton.addEventListener("click", async () => {
let newFileName = `${t("untitled")}.md`;
let newFilePath =
this.sourcePath === "/"
? newFileName
: `${this.sourcePath}/${newFileName}`;
let counter = 1;
while (this.app.vault.getAbstractFileByPath(newFilePath)) {
newFileName = `${t("untitled")} ${counter}.md`;
newFilePath =
this.sourcePath === "/"
? newFileName
: `${this.sourcePath}/${newFileName}`;
counter++;
}
try {
const newFile = await this.app.vault.create(newFilePath, "");
await this.app.workspace.getLeaf().openFile(newFile);
} catch (error) {
console.error("An error occurred while creating a new note:", error);
}
});
(0, import_obsidian8.setIcon)(newNoteButton, "square-pen");
}
if (
this.sourceMode === "folder" &&
this.sourcePath !== "/" &&
this.searchQuery === ""
) {
const upButton = headerButtonsDiv.createEl("button", {
attr: { "aria-label": t("go_up") },
});
upButton.addEventListener("click", () => {
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
this.setSource("folder", parentPath);
this.clearSelection();
});
(0, import_obsidian8.setIcon)(upButton, "arrow-up");
if (import_obsidian7.Platform.isDesktop) {
upButton.addEventListener("dragover", (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
upButton.addClass("ge-dragover");
});
upButton.addEventListener("dragleave", () => {
upButton.removeClass("ge-dragover");
});
upButton.addEventListener("drop", async (event) => {
var _a;
event.preventDefault();
upButton.removeClass("ge-dragover");
const filePath =
(_a = event.dataTransfer) == null
? void 0
: _a.getData("text/plain");
if (!filePath) return;
const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1");
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
if (!parentPath) return;
const file = this.app.vault.getAbstractFileByPath(cleanedFilePath);
const folder = this.app.vault.getAbstractFileByPath(parentPath);
if (
file instanceof import_obsidian7.TFile &&
folder instanceof import_obsidian7.TFolder
) {
try {
const newPath = `${parentPath}/${file.name}`;
await this.app.fileManager.renameFile(file, newPath);
this.render();
} catch (error) {
console.error(
"An error occurred while moving the file to parent folder:",
error
);
}
}
});
}
}
const reselectButton = headerButtonsDiv.createEl("button", {
attr: { "aria-label": t("reselect_folder") },
});
reselectButton.addEventListener("click", () => {
showFolderSelectionModal(this.app, this.plugin, this);
});
(0, import_obsidian8.setIcon)(reselectButton, "folder");
const refreshButton = headerButtonsDiv.createEl("button", {
attr: { "aria-label": t("refresh") },
});
refreshButton.addEventListener("click", () => {
if (this.sortType === "random") {
this.clearSelection();
}
this.render();
});
(0, import_obsidian8.setIcon)(refreshButton, "refresh-ccw");
if (this.sourceMode !== "bookmarks" && this.sourceMode !== "random-note") {
const sortButton = headerButtonsDiv.createEl("button", {
attr: { "aria-label": t("sorting") },
});
sortButton.addEventListener("click", (evt) => {
const menu = new import_obsidian7.Menu();
const sortOptions = [
{ value: "name-asc", label: t("sort_name_asc"), icon: "a-arrow-up" },
{
value: "name-desc",
label: t("sort_name_desc"),
icon: "a-arrow-down",
},
{ value: "mtime-desc", label: t("sort_mtime_desc"), icon: "clock" },
{ value: "mtime-asc", label: t("sort_mtime_asc"), icon: "clock" },
{
value: "ctime-desc",
label: t("sort_ctime_desc"),
icon: "calendar",
},
{ value: "ctime-asc", label: t("sort_ctime_asc"), icon: "calendar" },
{ value: "random", label: t("sort_random"), icon: "dice" },
];
sortOptions.forEach((option) => {
menu.addItem((item) => {
item
.setTitle(option.label)
.setIcon(option.icon)
.setChecked(this.sortType === option.value)
.onClick(() => {
this.sortType = option.value;
this.render();
this.app.workspace.requestSaveLayout();
});
});
});
menu.showAtMouseEvent(evt);
});
(0, import_obsidian8.setIcon)(sortButton, "arrow-up-narrow-wide");
}
if (this.sourceMode !== "random-note") {
const searchButtonContainer = headerButtonsDiv.createDiv(
"ge-search-button-container"
);
const searchButton = searchButtonContainer.createEl("button", {
cls: "search-button",
attr: { "aria-label": t("search") },
});
(0, import_obsidian8.setIcon)(searchButton, "search");
searchButton.addEventListener("click", () => {
this.showSearchModal();
});
if (this.searchQuery) {
searchButton.style.display = "none";
const searchTextContainer = searchButtonContainer.createDiv(
"ge-search-text-container"
);
const searchText = searchTextContainer.createEl("span", {
cls: "ge-search-text",
text: this.searchQuery,
});
searchText.style.cursor = "pointer";
searchText.addEventListener("click", () => {
this.showSearchModal(this.searchQuery);
});
const clearButton = searchTextContainer.createDiv("ge-clear-button");
(0, import_obsidian8.setIcon)(clearButton, "x");
clearButton.addEventListener("click", (e) => {
e.stopPropagation();
this.searchQuery = "";
this.searchAllFiles = true;
this.clearSelection();
this.render();
this.app.workspace.requestSaveLayout();
});
}
}
if (
this.sourceMode === "random-note" &&
this.plugin.settings.showMediaFiles
) {
const randomNoteSettingsButton = headerButtonsDiv.createEl("button", {
text: this.randomNoteIncludeMedia
? t("random_note_include_media_files")
: t("random_note_notes_only"),
});
const menu = new import_obsidian7.Menu();
menu.addItem((item) => {
item
.setTitle(t("random_note_notes_only"))
.setIcon(this.randomNoteIncludeMedia ? "" : "checkmark")
.onClick(async () => {
this.randomNoteIncludeMedia = false;
randomNoteSettingsButton.textContent = t("random_note_notes_only");
this.render();
});
});
menu.addItem((item) => {
item
.setTitle(t("random_note_include_media_files"))
.setIcon(this.randomNoteIncludeMedia ? "checkmark" : "")
.onClick(async () => {
this.randomNoteIncludeMedia = true;
randomNoteSettingsButton.textContent = t(
"random_note_include_media_files"
);
this.render();
});
});
randomNoteSettingsButton.addEventListener("click", (event) => {
menu.showAtMouseEvent(event);
});
}
const contentEl = this.containerEl.createDiv("view-content");
await this.grid_render();
this.leaf.updateHeader();
if (scrollContainer) {
contentEl.scrollTop = scrollTop;
}
if (selectedFilePath && this.hasKeyboardFocus) {
const newIndex = this.gridItems.findIndex(
(item) => item.dataset.filePath === selectedFilePath
);
if (newIndex >= 0) {
this.selectItem(newIndex);
}
}
}
async grid_render() {
var _a;
const container = this.containerEl.children[1];
container.empty();
container.addClass("ge-grid-container");
container.style.setProperty(
"--grid-item-width",
this.plugin.settings.gridItemWidth + "px"
);
if (this.plugin.settings.gridItemHeight === 0) {
container.style.setProperty("--grid-item-height", "100%");
} else {
container.style.setProperty(
"--grid-item-height",
this.plugin.settings.gridItemHeight + "px"
);
}
container.style.setProperty(
"--image-area-width",
this.plugin.settings.imageAreaWidth + "px"
);
container.style.setProperty(
"--image-area-height",
this.plugin.settings.imageAreaHeight + "px"
);
container.style.setProperty(
"--title-font-size",
this.plugin.settings.titleFontSize + "em"
);
this.gridItems = [];
if (
this.sourceMode === "bookmarks" &&
!((_a = this.app.internalPlugins.plugins.bookmarks) == null
? void 0
: _a.enabled)
) {
new import_obsidian7.Notice(t("bookmarks_plugin_disabled"));
return;
}
if (
this.sourceMode === "backlinks" &&
!this.app.workspace.getActiveFile()
) {
new import_obsidian7.Notice(t("no_backlinks"));
return;
}
if (
this.sourceMode === "folder" &&
this.searchQuery === "" &&
this.plugin.settings.showParentFolderItem &&
this.sourcePath !== "/"
) {
const parentFolderEl = container.createDiv("ge-grid-item ge-folder-item");
this.gridItems.push(parentFolderEl);
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
parentFolderEl.dataset.folderPath = parentPath;
const contentArea = parentFolderEl.createDiv("ge-content-area");
const titleContainer = contentArea.createDiv("ge-title-container");
titleContainer.createEl("span", {
cls: "ge-title",
text: `\u{1F4C1} ..`,
});
parentFolderEl.addEventListener("click", () => {
this.setSource("folder", parentPath);
this.clearSelection();
});
if (import_obsidian7.Platform.isDesktop) {
parentFolderEl.addEventListener("dragover", (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
parentFolderEl.addClass("ge-dragover");
});
parentFolderEl.addEventListener("dragleave", () => {
parentFolderEl.removeClass("ge-dragover");
});
parentFolderEl.addEventListener("drop", async (event) => {
var _a2;
event.preventDefault();
parentFolderEl.removeClass("ge-dragover");
const filePath =
(_a2 = event.dataTransfer) == null
? void 0
: _a2.getData("text/plain");
if (!filePath) return;
const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1");
const file = this.app.vault.getAbstractFileByPath(cleanedFilePath);
const folder = this.app.vault.getAbstractFileByPath(parentPath);
if (
file instanceof import_obsidian7.TFile &&
folder instanceof import_obsidian7.TFolder
) {
try {
const newPath = `${parentPath}/${file.name}`;
await this.app.fileManager.renameFile(file, newPath);
this.render();
} catch (error) {
console.error(
"An error occurred while moving the file to parent folder:",
error
);
}
}
});
}
}
if (this.sourceMode === "folder" && this.searchQuery === "") {
const currentFolder = this.app.vault.getAbstractFileByPath(
this.sourcePath || "/"
);
if (currentFolder instanceof import_obsidian7.TFolder) {
const subfolders = currentFolder.children
.filter((child) => {
if (!(child instanceof import_obsidian7.TFolder)) return false;
const isInIgnoredFolders = this.plugin.settings.ignoredFolders.some(
(ignoredPath) =>
child.path === ignoredPath ||
child.path.startsWith(ignoredPath + "/")
);
if (isInIgnoredFolders) {
return false;
}
if (
this.plugin.settings.ignoredFolderPatterns &&
this.plugin.settings.ignoredFolderPatterns.length > 0
) {
const matchesIgnoredPattern =
this.plugin.settings.ignoredFolderPatterns.some((pattern) => {
try {
if (/[\^\$\*\+\?\(\)\[\]\{\}\|\\]/.test(pattern)) {
const regex = new RegExp(pattern);
return regex.test(child.path);
} else {
return child.name
.toLowerCase()
.includes(pattern.toLowerCase());
}
} catch (error) {
return child.name
.toLowerCase()
.includes(pattern.toLowerCase());
}
});
if (matchesIgnoredPattern) {
return false;
}
}
return true;
})
.sort((a, b) => a.name.localeCompare(b.name));
for (const folder of subfolders) {
const folderEl = container.createDiv("ge-grid-item ge-folder-item");
this.gridItems.push(folderEl);
folderEl.dataset.folderPath = folder.path;
const contentArea = folderEl.createDiv("ge-content-area");
const titleContainer = contentArea.createDiv("ge-title-container");
titleContainer.createEl("span", {
cls: "ge-title",
text: `\u{1F4C1} ${folder.name}`,
});
const notePath = `${folder.path}/${folder.name}.md`;
const noteFile = this.app.vault.getAbstractFileByPath(notePath);
if (noteFile instanceof import_obsidian7.TFile) {
const noteIcon = titleContainer.createEl("span", {
cls: "ge-note-button",
});
(0, import_obsidian8.setIcon)(noteIcon, "panel-left-open");
noteIcon.addEventListener("click", (e) => {
e.stopPropagation();
this.app.workspace.getLeaf().openFile(noteFile);
});
}
folderEl.addEventListener("click", () => {
this.setSource("folder", folder.path);
this.clearSelection();
});
folderEl.addEventListener("contextmenu", (event) => {
event.preventDefault();
const menu = new import_obsidian7.Menu();
const notePath2 = `${folder.path}/${folder.name}.md`;
let noteFile2 = this.app.vault.getAbstractFileByPath(notePath2);
if (noteFile2 instanceof import_obsidian7.TFile) {
menu.addItem((item) => {
item
.setTitle(t("open_folder_note"))
.setIcon("panel-left-open")
.onClick(() => {
this.app.workspace.getLeaf(false).openFile(noteFile2);
});
});
} else {
menu.addItem((item) => {
item
.setTitle(t("create_folder_note"))
.setIcon("file-cog")
.onClick(() => {
this.app.vault.create(notePath2, "");
setTimeout(() => {
this.render();
noteFile2 =
this.app.vault.getAbstractFileByPath(notePath2);
this.app.workspace.getLeaf(false).openFile(noteFile2);
}, 100);
});
});
}
menu.addItem((item) => {
item
.setTitle(t("ignore_folder"))
.setIcon("x")
.onClick(() => {
this.plugin.settings.ignoredFolders.push(folder.path);
this.plugin.saveSettings();
this.render();
});
});
menu.showAtMouseEvent(event);
});
}
}
}
let files = [];
if (this.searchQuery && this.sourceMode !== "random-note") {
const loadingDiv = container.createDiv("ge-loading-indicator");
loadingDiv.setText(t("searching"));
let allFiles = [];
if (this.searchAllFiles) {
allFiles = this.app.vault.getFiles();
} else {
allFiles = await this.getFiles();
}
const filteredFiles = allFiles.filter((file) => {
if (isDocumentFile(file)) {
return true;
}
if (isMediaFile(file)) {
return this.plugin.settings.searchMediaFiles;
}
return false;
});
const lowerCaseSearchQuery = this.searchQuery.toLowerCase();
await Promise.all(
filteredFiles.map(async (file) => {
const fileName = file.name.toLowerCase();
if (fileName.includes(lowerCaseSearchQuery)) {
files.push(file);
} else if (file.extension === "md") {
const content = (
await this.app.vault.cachedRead(file)
).toLowerCase();
if (content.includes(lowerCaseSearchQuery)) {
files.push(file);
}
}
})
);
files = this.sortFiles(files);
loadingDiv.remove();
} else {
files = await this.getFiles();
}
files = this.ignoredFiles(files);
if (this.sourceMode === "random-note") {
files = files.slice(0, 10);
}
if (files.length === 0) {
const noFilesDiv = container.createDiv("ge-no-files");
noFilesDiv.setText(t("no_files"));
if (this.plugin.statusBarItem) {
this.plugin.statusBarItem.setText("");
}
return;
}
const observer = new IntersectionObserver(
(entries, observer2) => {
entries.forEach(async (entry) => {
if (entry.isIntersecting) {
const fileEl = entry.target;
const filePath = fileEl.dataset.filePath;
if (!filePath) return;
const file = this.app.vault.getAbstractFileByPath(filePath);
if (!(file instanceof import_obsidian7.TFile)) return;
let imageUrl = "";
const contentArea = fileEl.querySelector(".ge-content-area");
if (!contentArea.hasAttribute("data-loaded")) {
if (file.extension === "md") {
let summaryLength = this.plugin.settings.summaryLength;
const content = await this.app.vault.cachedRead(file);
const frontMatterInfo = (0,
import_obsidian8.getFrontMatterInfo)(content);
let contentWithoutFrontmatter = "";
if (summaryLength < 500) {
contentWithoutFrontmatter = content
.substring(frontMatterInfo.contentStart)
.slice(0, 500);
} else {
contentWithoutFrontmatter = content
.substring(frontMatterInfo.contentStart)
.slice(0, summaryLength + summaryLength);
}
let contentWithoutMediaLinks =
contentWithoutFrontmatter.replace(
/```[\s\S]*?```\n|<!--[\s\S]*?-->|!?(?:\[[^\]]*\]\([^)]+\)|\[\[[^\]]+\]\])/g,
""
);
contentWithoutMediaLinks = contentWithoutMediaLinks
.replace(/```[\s\S]*$/, "")
.trim();
if (
contentWithoutMediaLinks.startsWith("# ") ||
contentWithoutMediaLinks.startsWith("## ") ||
contentWithoutMediaLinks.startsWith("### ")
) {
contentWithoutMediaLinks = contentWithoutMediaLinks
.split("\n")
.slice(1)
.join("\n");
}
const preview =
contentWithoutMediaLinks.slice(0, summaryLength) +
(contentWithoutMediaLinks.length > summaryLength ? "" : "");
contentArea.createEl("p", { text: preview.trim() });
imageUrl = await findFirstImageInNote(this.app, content);
} else {
contentArea.createEl("p", {
text: file.extension.toUpperCase(),
});
}
contentArea.setAttribute("data-loaded", "true");
}
const imageArea = fileEl.querySelector(".ge-image-area");
if (imageArea && !imageArea.hasAttribute("data-loaded")) {
if (isImageFile(file)) {
const img = imageArea.createEl("img");
img.src = this.app.vault.getResourcePath(file);
imageArea.setAttribute("data-loaded", "true");
} else if (isVideoFile(file)) {
if (this.plugin.settings.showVideoThumbnails) {
const video = imageArea.createEl("video");
video.src = this.app.vault.getResourcePath(file);
} else {
const videoThumb = imageArea.createDiv("ge-video-thumbnail");
(0, import_obsidian8.setIcon)(videoThumb, "play-circle");
}
imageArea.setAttribute("data-loaded", "true");
} else if (file.extension === "md") {
if (imageUrl) {
const img = imageArea.createEl("img");
img.src = imageUrl;
imageArea.setAttribute("data-loaded", "true");
} else {
imageArea.remove();
}
} else {
imageArea.remove();
}
}
observer2.unobserve(fileEl);
}
});
},
{
root: container,
rootMargin: "50px",
// 預先載入視窗外 50px 的內容
threshold: 0.1,
}
);
for (const file of files) {
const fileEl = container.createDiv("ge-grid-item");
this.gridItems.push(fileEl);
fileEl.dataset.filePath = file.path;
const contentArea = fileEl.createDiv("ge-content-area");
const titleContainer = contentArea.createDiv("ge-title-container");
const extension = file.extension.toLowerCase();
if (isImageFile(file)) {
const iconContainer = titleContainer.createDiv(
"ge-icon-container ge-img"
);
(0, import_obsidian8.setIcon)(iconContainer, "image");
} else if (isVideoFile(file)) {
const iconContainer = titleContainer.createDiv(
"ge-icon-container ge-video"
);
(0, import_obsidian8.setIcon)(iconContainer, "play-circle");
} else if (isAudioFile(file)) {
const iconContainer = titleContainer.createDiv(
"ge-icon-container ge-audio"
);
(0, import_obsidian8.setIcon)(iconContainer, "music");
} else if (extension === "pdf") {
const iconContainer = titleContainer.createDiv(
"ge-icon-container ge-pdf"
);
(0, import_obsidian8.setIcon)(iconContainer, "paperclip");
} else if (extension === "canvas") {
const iconContainer = titleContainer.createDiv(
"ge-icon-container ge-canvas"
);
(0, import_obsidian8.setIcon)(iconContainer, "layout-dashboard");
} else if (extension === "md" || extension === "txt") {
const iconContainer = titleContainer.createDiv("ge-icon-container");
(0, import_obsidian8.setIcon)(iconContainer, "file-text");
} else {
const iconContainer = titleContainer.createDiv("ge-icon-container");
(0, import_obsidian8.setIcon)(iconContainer, "file");
}
const titleEl = titleContainer.createEl("span", {
cls: "ge-title",
text: file.basename,
});
titleEl.setAttribute("title", file.basename);
fileEl.createDiv("ge-image-area");
observer.observe(fileEl);
fileEl.addEventListener("click", (event) => {
const index = this.gridItems.indexOf(fileEl);
if (index >= 0) {
this.selectItem(index);
this.hasKeyboardFocus = true;
}
if (isMediaFile(file)) {
if (isAudioFile(file)) {
this.openAudioFile(file);
} else {
this.openMediaFile(file, files);
}
} else {
if (event.ctrlKey) {
this.app.workspace.getLeaf(true).openFile(file);
} else {
this.app.workspace.getLeaf().openFile(file);
}
}
});
fileEl.addEventListener("mousedown", (event) => {
if (event.button === 1) {
event.preventDefault();
}
});
fileEl.addEventListener("mouseup", (event) => {
if (event.button === 1) {
event.preventDefault();
if (!isMediaFile(file)) {
this.app.workspace.getLeaf(true).openFile(file);
}
}
});
if (import_obsidian7.Platform.isDesktop) {
fileEl.setAttribute("draggable", "true");
fileEl.addEventListener("dragstart", (event) => {
var _a2;
const isMedia = isMediaFile(file);
const mdLink = isMedia ? `![[${file.path}]]` : `[[${file.path}]]`;
(_a2 = event.dataTransfer) == null
? void 0
: _a2.setData("text/plain", mdLink);
event.dataTransfer.effectAllowed = "all";
fileEl.addClass("ge-dragging");
});
fileEl.addEventListener("dragend", () => {
fileEl.removeClass("ge-dragging");
});
}
fileEl.addEventListener("contextmenu", (event) => {
event.preventDefault();
const menu = new import_obsidian7.Menu();
this.app.workspace.trigger("file-menu", menu, file);
menu.addItem((item) => {
item
.setTitle(t("open_in_new_tab"))
.setIcon("external-link")
.onClick(() => {
this.app.workspace.getLeaf(true).openFile(file);
});
});
menu.addItem((item) => {
item
.setTitle(t("delete_note"))
.setIcon("trash")
.onClick(async () => {
await this.app.fileManager.trashFile(file);
});
});
menu.showAtMouseEvent(event);
});
}
if (import_obsidian7.Platform.isDesktop) {
const folderItems = this.containerEl.querySelectorAll(".ge-folder-item");
folderItems.forEach((folderItem) => {
folderItem.addEventListener("dragover", (event) => {
event.preventDefault();
event.dataTransfer.dropEffect = "move";
folderItem.addClass("ge-dragover");
});
folderItem.addEventListener("dragleave", () => {
folderItem.removeClass("ge-dragover");
});
folderItem.addEventListener("drop", async (event) => {
var _a2;
event.preventDefault();
folderItem.removeClass("ge-dragover");
const filePath =
(_a2 = event.dataTransfer) == null
? void 0
: _a2.getData("text/plain");
if (!filePath) return;
const cleanedFilePath = filePath.replace(/!?\[\[(.*?)\]\]/, "$1");
const folderPath = folderItem.dataset.folderPath;
if (!folderPath) return;
const file = this.app.vault.getAbstractFileByPath(cleanedFilePath);
const folder = this.app.vault.getAbstractFileByPath(folderPath);
if (
file instanceof import_obsidian7.TFile &&
folder instanceof import_obsidian7.TFolder
) {
try {
const newPath = `${folderPath}/${file.name}`;
await this.app.fileManager.renameFile(file, newPath);
this.render();
} catch (error) {
console.error("An error occurred while moving the file:", error);
}
}
});
});
}
if (
this.selectedItemIndex >= 0 &&
this.selectedItemIndex < this.gridItems.length &&
this.hasKeyboardFocus
) {
this.selectItem(this.selectedItemIndex);
} else if (this.gridItems.length > 0) {
this.selectItem(-1);
}
if (this.plugin.statusBarItem) {
this.plugin.statusBarItem.setText(`${files.length} ${t("files")}`);
}
}
// 處理鍵盤導航
handleKeyDown(event) {
if (!this.keyboardNavigationEnabled || this.gridItems.length === 0) return;
const container = this.containerEl.children[1];
const containerWidth = container.clientWidth;
const itemWidth = this.plugin.settings.gridItemWidth + 20;
const itemsPerRow = Math.max(1, Math.floor(containerWidth / itemWidth));
let newIndex = this.selectedItemIndex;
if (
this.selectedItemIndex === -1 &&
[
"ArrowRight",
"ArrowLeft",
"ArrowDown",
"ArrowUp",
"Home",
"End",
].includes(event.key)
) {
this.hasKeyboardFocus = true;
this.selectItem(0);
event.preventDefault();
return;
}
switch (event.key) {
case "ArrowRight":
if (event.altKey) {
if (
this.selectedItemIndex >= 0 &&
this.selectedItemIndex < this.gridItems.length
) {
this.gridItems[this.selectedItemIndex].click();
}
}
newIndex = Math.min(
this.gridItems.length - 1,
this.selectedItemIndex + 1
);
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "ArrowLeft":
if (event.altKey) {
if (
this.sourceMode === "folder" &&
this.sourcePath &&
this.sourcePath !== "/"
) {
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
this.setSource("folder", parentPath);
this.clearSelection();
event.preventDefault();
}
break;
}
newIndex = Math.max(0, this.selectedItemIndex - 1);
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "ArrowDown":
newIndex = Math.min(
this.gridItems.length - 1,
this.selectedItemIndex + itemsPerRow
);
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "ArrowUp":
if (event.altKey) {
if (
this.sourceMode === "folder" &&
this.sourcePath &&
this.sourcePath !== "/"
) {
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
this.setSource("folder", parentPath);
this.clearSelection();
event.preventDefault();
}
break;
}
newIndex = Math.max(0, this.selectedItemIndex - itemsPerRow);
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "Home":
newIndex = 0;
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "End":
newIndex = this.gridItems.length - 1;
this.hasKeyboardFocus = true;
event.preventDefault();
break;
case "Enter":
if (
this.selectedItemIndex >= 0 &&
this.selectedItemIndex < this.gridItems.length
) {
this.gridItems[this.selectedItemIndex].click();
}
this.clearSelection();
event.preventDefault();
break;
case "Backspace":
if (
this.sourceMode === "folder" &&
this.sourcePath &&
this.sourcePath !== "/"
) {
const parentPath =
this.sourcePath.split("/").slice(0, -1).join("/") || "/";
this.setSource("folder", parentPath);
this.clearSelection();
event.preventDefault();
}
break;
case "Escape":
if (this.selectedItemIndex >= 0) {
this.hasKeyboardFocus = false;
this.clearSelection();
event.preventDefault();
}
break;
}
if (newIndex !== this.selectedItemIndex) {
this.selectItem(newIndex);
}
}
// 清除選中狀態
clearSelection() {
this.gridItems.forEach((item) => {
item.removeClass("ge-selected-item");
});
this.selectedItemIndex = -1;
}
// 選中指定索引的項目
selectItem(index) {
this.gridItems.forEach((item) => {
item.removeClass("ge-selected-item");
});
if (index >= 0 && index < this.gridItems.length) {
this.selectedItemIndex = index;
const selectedItem = this.gridItems[index];
selectedItem.addClass("ge-selected-item");
selectedItem.scrollIntoView({
behavior: "smooth",
block: "nearest",
});
}
}
// 開啟媒體檔案
openMediaFile(file, mediaFiles) {
const getMediaFilesPromise = mediaFiles
? Promise.resolve(mediaFiles.filter((f) => isMediaFile(f)))
: this.getFiles().then((allFiles) =>
allFiles.filter((f) => isMediaFile(f))
);
getMediaFilesPromise.then((filteredMediaFiles) => {
const currentIndex = filteredMediaFiles.findIndex(
(f) => f.path === file.path
);
if (currentIndex === -1) return;
const mediaModal = new MediaModal(
this.app,
file,
filteredMediaFiles,
this
);
mediaModal.open();
});
}
// 開啟音樂檔案
openAudioFile(file) {
const existingPlayers = document.querySelectorAll(
".ge-floating-audio-player"
);
existingPlayers.forEach((player) => player.remove());
const audioPlayerContainer = document.createElement("div");
audioPlayerContainer.className = "ge-floating-audio-player";
const audio = document.createElement("audio");
audio.controls = true;
audio.src = this.app.vault.getResourcePath(file);
const titleElement = document.createElement("div");
titleElement.className = "ge-audio-title";
titleElement.textContent = file.basename;
const closeButton = document.createElement("div");
closeButton.className = "ge-audio-close-button";
(0, import_obsidian8.setIcon)(closeButton, "x");
closeButton.addEventListener("click", () => {
audioPlayerContainer.remove();
});
const handleElement = document.createElement("div");
handleElement.className = "ge-audio-handle";
audioPlayerContainer.appendChild(handleElement);
audioPlayerContainer.appendChild(titleElement);
audioPlayerContainer.appendChild(audio);
audioPlayerContainer.appendChild(closeButton);
let isDragging = false;
let offsetX = 0;
let offsetY = 0;
let isTouchEvent = false;
handleElement.addEventListener("mousedown", (e) => {
if (isTouchEvent) return;
isDragging = true;
offsetX = e.clientX - audioPlayerContainer.getBoundingClientRect().left;
offsetY = e.clientY - audioPlayerContainer.getBoundingClientRect().top;
audioPlayerContainer.classList.add("ge-audio-dragging");
});
handleElement.addEventListener(
"touchstart",
(e) => {
isTouchEvent = true;
isDragging = true;
const touch = e.touches[0];
offsetX =
touch.clientX - audioPlayerContainer.getBoundingClientRect().left;
offsetY =
touch.clientY - audioPlayerContainer.getBoundingClientRect().top;
audioPlayerContainer.classList.add("ge-audio-dragging");
},
{ passive: true }
);
document.addEventListener("mousemove", (e) => {
if (!isDragging || isTouchEvent) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
audioPlayerContainer.style.left = `${x}px`;
audioPlayerContainer.style.top = `${y}px`;
});
document.addEventListener(
"touchmove",
(e) => {
if (!isDragging) return;
const touch = e.touches[0];
const x = touch.clientX - offsetX;
const y = touch.clientY - offsetY;
audioPlayerContainer.style.left = `${x}px`;
audioPlayerContainer.style.top = `${y}px`;
e.preventDefault();
},
{ passive: false }
);
document.addEventListener("mouseup", () => {
if (isTouchEvent) return;
isDragging = false;
audioPlayerContainer.classList.remove("ge-audio-dragging");
});
document.addEventListener("touchend", () => {
isDragging = false;
isTouchEvent = false;
audioPlayerContainer.classList.remove("ge-audio-dragging");
});
document.body.appendChild(audioPlayerContainer);
const rect = audioPlayerContainer.getBoundingClientRect();
audioPlayerContainer.style.left = `${
window.innerWidth - rect.width - 20
}px`;
audioPlayerContainer.style.top = `${
window.innerHeight - rect.height - 20
}px`;
audio.play();
}
// 顯示搜尋 modal
showSearchModal(defaultQuery = "") {
showSearchModal(this.app, this, defaultQuery);
}
// 保存視圖狀態
getState() {
return {
type: "grid-view",
state: {
sourceMode: this.sourceMode,
sourcePath: this.sourcePath,
sortType: this.sortType,
searchQuery: this.searchQuery,
searchAllFiles: this.searchAllFiles,
randomNoteIncludeMedia: this.randomNoteIncludeMedia,
},
};
}
// 讀取視圖狀態
async setState(state) {
var _a, _b;
if (state.state) {
this.sourceMode = state.state.sourceMode || "";
this.sourcePath = state.state.sourcePath || null;
this.sortType = state.state.sortType || "mtime-desc";
this.searchQuery = state.state.searchQuery || "";
this.searchAllFiles =
(_a = state.state.searchAllFiles) != null ? _a : true;
this.randomNoteIncludeMedia =
(_b = state.state.randomNoteIncludeMedia) != null
? _b
: this.plugin.settings.showMediaFiles;
this.render();
}
}
// 禁用鍵盤導航
disableKeyboardNavigation() {
this.keyboardNavigationEnabled = false;
}
// 啟用鍵盤導航
enableKeyboardNavigation() {
this.keyboardNavigationEnabled = true;
}
};
// src/settings.ts
var import_obsidian9 = require("obsidian");
var DEFAULT_SETTINGS = {
ignoredFolders: [],
ignoredFolderPatterns: [],
// 預設以字串忽略的資料夾模式
defaultSortType: "mtime-desc",
// 預設排序模式:修改時間倒序
gridItemWidth: 300,
// 網格項目寬度,預設 300
gridItemHeight: 0,
// 網格項目高度,預設 0
imageAreaWidth: 100,
// 圖片區域寬度,預設 100
imageAreaHeight: 100,
// 圖片區域高度,預設 100
titleFontSize: 1,
// 筆記標題的字型大小,預設 1.0
summaryLength: 100,
// 筆記摘要的字數,預設 100
enableFileWatcher: true,
// 預設啟用檔案監控
showMediaFiles: true,
// 預設顯示圖片和影片
searchMediaFiles: false,
// 預設搜尋時也包含圖片和影片
showVideoThumbnails: false,
// 預設不顯示影片縮圖
defaultOpenLocation: "tab",
// 預設開啟位置:新分頁
showParentFolderItem: false,
// 預設不顯示"返回上级文件夹"選項
reuseExistingLeaf: false,
// 預設不重用現有的網格視圖
showBookmarksMode: true,
// 預設顯示書籤模式
showSearchMode: true,
// 預設顯示搜尋結果模式
showBacklinksMode: true,
// 預設顯示反向連結模式
showAllFilesMode: false,
// 預設不顯示所有檔案模式
showRandomNoteMode: false,
// 預設不顯示隨機筆記模式
customDocumentExtensions: "",
// 自訂文件副檔名(用逗號分隔)
};
var GridExplorerSettingTab = class extends import_obsidian9.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
const { containerEl } = this;
containerEl.empty();
new import_obsidian9.Setting(containerEl)
.setName(t("reset_to_default"))
.setDesc(t("reset_to_default_desc"))
.addButton((button) =>
button.setButtonText(t("reset")).onClick(async () => {
this.plugin.settings = { ...DEFAULT_SETTINGS };
await this.plugin.saveSettings();
this.display();
new import_obsidian9.Notice(t("settings_reset_notice"));
})
);
containerEl.createEl("h3", { text: t("display_mode_settings") });
new import_obsidian9.Setting(containerEl)
.setName(t("show_bookmarks_mode"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showBookmarksMode)
.onChange(async (value) => {
this.plugin.settings.showBookmarksMode = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_search_mode"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showSearchMode)
.onChange(async (value) => {
this.plugin.settings.showSearchMode = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_backlinks_mode"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showBacklinksMode)
.onChange(async (value) => {
this.plugin.settings.showBacklinksMode = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_all_files_mode"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showAllFilesMode)
.onChange(async (value) => {
this.plugin.settings.showAllFilesMode = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_random_note_mode"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showRandomNoteMode)
.onChange(async (value) => {
this.plugin.settings.showRandomNoteMode = value;
await this.plugin.saveSettings();
});
});
containerEl.createEl("h3", { text: t("media_files_settings") });
new import_obsidian9.Setting(containerEl)
.setName(t("show_media_files"))
.setDesc(t("show_media_files_desc"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showMediaFiles)
.onChange(async (value) => {
this.plugin.settings.showMediaFiles = value;
if (!value) {
this.plugin.settings.searchMediaFiles = false;
this.display();
}
await this.plugin.saveSettings();
});
});
new import_obsidian9.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();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_video_thumbnails"))
.setDesc(t("show_video_thumbnails_desc"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showVideoThumbnails)
.onChange(async (value) => {
this.plugin.settings.showVideoThumbnails = value;
await this.plugin.saveSettings();
});
});
containerEl.createEl("h3", { text: t("grid_view_settings") });
new import_obsidian9.Setting(containerEl)
.setName(t("reuse_existing_leaf"))
.setDesc(t("reuse_existing_leaf_desc"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.reuseExistingLeaf)
.onChange(async (value) => {
this.plugin.settings.reuseExistingLeaf = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("default_open_location"))
.setDesc(t("default_open_location_desc"))
.addDropdown((dropdown) => {
dropdown
.addOption("tab", t("open_in_new_tab"))
.addOption("left", t("open_in_left_sidebar"))
.addOption("right", t("open_in_right_sidebar"))
.setValue(this.plugin.settings.defaultOpenLocation)
.onChange(async (value) => {
this.plugin.settings.defaultOpenLocation = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("default_sort_type"))
.setDesc(t("default_sort_type_desc"))
.addDropdown((dropdown) => {
dropdown
.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.plugin.settings.defaultSortType)
.onChange(async (value) => {
this.plugin.settings.defaultSortType = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("enable_file_watcher"))
.setDesc(t("enable_file_watcher_desc"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.enableFileWatcher)
.onChange(async (value) => {
this.plugin.settings.enableFileWatcher = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("custom_document_extensions"))
.setDesc(t("custom_document_extensions_desc"))
.addText((text) => {
text
.setPlaceholder(t("custom_document_extensions_placeholder"))
.setValue(this.plugin.settings.customDocumentExtensions)
.onChange(async (value) => {
this.plugin.settings.customDocumentExtensions = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("show_parent_folder_item"))
.setDesc(t("show_parent_folder_item_desc"))
.addToggle((toggle) => {
toggle
.setValue(this.plugin.settings.showParentFolderItem)
.onChange(async (value) => {
this.plugin.settings.showParentFolderItem = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("grid_item_width"))
.setDesc(t("grid_item_width_desc"))
.addSlider((slider) => {
slider
.setLimits(0, 600, 10)
.setValue(this.plugin.settings.gridItemWidth)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.gridItemWidth = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("grid_item_height"))
.setDesc(t("grid_item_height_desc"))
.addSlider((slider) => {
slider
.setLimits(0, 600, 10)
.setValue(this.plugin.settings.gridItemHeight)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.gridItemHeight = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("image_area_width"))
.setDesc(t("image_area_width_desc"))
.addSlider((slider) => {
slider
.setLimits(0, 300, 10)
.setValue(this.plugin.settings.imageAreaWidth)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.imageAreaWidth = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("image_area_height"))
.setDesc(t("image_area_height_desc"))
.addSlider((slider) => {
slider
.setLimits(0, 300, 10)
.setValue(this.plugin.settings.imageAreaHeight)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.imageAreaHeight = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("title_font_size"))
.setDesc(t("title_font_size_desc"))
.addSlider((slider) => {
slider
.setLimits(0.1, 1.5, 0.05)
.setValue(this.plugin.settings.titleFontSize)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.titleFontSize = value;
await this.plugin.saveSettings();
});
});
new import_obsidian9.Setting(containerEl)
.setName(t("summary_length"))
.setDesc(t("summary_length_desc"))
.addSlider((slider) => {
slider
.setLimits(0, 600, 25)
.setValue(this.plugin.settings.summaryLength)
.setDynamicTooltip()
.onChange(async (value) => {
this.plugin.settings.summaryLength = value;
await this.plugin.saveSettings();
});
});
containerEl.createEl("h3", { text: t("ignored_folders_settings") });
const ignoredFoldersContainer = containerEl.createDiv(
"ignored-folders-container"
);
new import_obsidian9.Setting(containerEl)
.setName(t("ignored_folders"))
.setDesc(t("ignored_folders_desc"))
.setHeading();
new import_obsidian9.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) => {
const isIgnored = this.plugin.settings.ignoredFolders.some(
(ignoredPath) =>
folder.path === ignoredPath ||
folder.path.startsWith(ignoredPath + "/")
);
if (!isIgnored) {
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);
const ignoredFolderPatternsContainer = containerEl.createDiv(
"ignored-folder-patterns-container"
);
new import_obsidian9.Setting(containerEl)
.setName(t("ignored_folder_patterns"))
.setDesc(t("ignored_folder_patterns_desc"))
.setHeading();
const patternSetting = new import_obsidian9.Setting(
ignoredFolderPatternsContainer
)
.setName(t("add_ignored_folder_pattern"))
.addText((text) => {
text
.setPlaceholder(t("ignored_folder_pattern_placeholder"))
.onChange(() => {});
return text;
});
patternSetting.addButton((button) => {
button
.setButtonText(t("add"))
.setCta()
.onClick(async () => {
const inputEl = patternSetting.controlEl.querySelector("input");
const pattern = inputEl.value.trim();
if (
pattern &&
!this.plugin.settings.ignoredFolderPatterns.includes(pattern)
) {
this.plugin.settings.ignoredFolderPatterns.push(pattern);
await this.plugin.saveSettings();
this.renderIgnoredFolderPatternsList(ignoredFolderPatternsList);
inputEl.value = "";
}
});
});
const ignoredFolderPatternsList = ignoredFolderPatternsContainer.createDiv(
"ge-ignored-folder-patterns-list"
);
this.renderIgnoredFolderPatternsList(ignoredFolderPatternsList);
containerEl.appendChild(ignoredFolderPatternsContainer);
}
// 渲染已忽略的資料夾列表
renderIgnoredFoldersList(containerEl) {
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();
});
});
}
// 渲染已忽略的資料夾模式列表
renderIgnoredFolderPatternsList(containerEl) {
containerEl.empty();
if (this.plugin.settings.ignoredFolderPatterns.length === 0) {
containerEl.createEl("p", { text: t("no_ignored_folder_patterns") });
return;
}
const list = containerEl.createEl("ul", { cls: "ge-ignored-folders-list" });
this.plugin.settings.ignoredFolderPatterns.forEach((pattern) => {
const item = list.createEl("li", { cls: "ge-ignored-folder-item" });
item.createSpan({ text: pattern, 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.ignoredFolderPatterns =
this.plugin.settings.ignoredFolderPatterns.filter(
(p) => p !== pattern
);
await this.plugin.saveSettings();
this.renderIgnoredFolderPatternsList(containerEl);
});
});
}
};
// main.ts
var GridExplorerPlugin = class extends import_obsidian10.Plugin {
async onload() {
await this.loadSettings();
this.registerView("grid-view", (leaf) => new GridView(leaf, this));
this.addSettingTab(new GridExplorerSettingTab(this.app, this));
this.addCommand({
id: "open-grid-view",
name: t("open_grid_view"),
callback: () => {
showFolderSelectionModal(this.app, this);
},
});
this.addCommand({
id: "view-current-note-in-grid-view",
name: t("open_note_in_grid_view"),
callback: () => {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile) {
this.openInGridView(activeFile);
} else {
this.openInGridView(this.app.vault.getRoot());
}
},
});
this.addCommand({
id: "view-backlinks-in-grid-view",
name: t("open_backlinks_in_grid_view"),
callback: () => {
const activeFile = this.app.workspace.getActiveFile();
if (activeFile) {
this.activateView("backlinks");
} else {
this.openInGridView(this.app.vault.getRoot());
}
},
});
this.addRibbonIcon("grid", t("open_grid_view"), () => {
showFolderSelectionModal(this.app, this);
});
this.statusBarItem = this.addStatusBarItem();
this.statusBarItem.onClickEvent(() => {
this.activateView();
});
this.registerEvent(
this.app.workspace.on("file-menu", (menu, file) => {
if (
file instanceof import_obsidian10.TFolder ||
file instanceof import_obsidian10.TFile
) {
menu.addItem((item) => {
item
.setTitle(t("open_note_in_grid_view"))
.setIcon("grid")
.onClick(() => {
this.openInGridView(file);
});
});
if (this.settings.showBacklinksMode) {
menu.addItem((item) => {
item
.setTitle(t("open_backlinks_in_grid_view"))
.setIcon("grid")
.onClick(() => {
this.activateView("backlinks");
});
});
}
}
})
);
}
async openInGridView(file = this.app.vault.getRoot()) {
var _a;
const folderPath = file
? file instanceof import_obsidian10.TFile
? (_a = file.parent) == null
? void 0
: _a.path
: file.path
: "/";
const view = await this.activateView("folder", folderPath);
if (file instanceof import_obsidian10.TFile) {
setTimeout(() => {
const gridContainer =
view.containerEl.querySelector(".ge-grid-container");
if (!gridContainer) return;
const gridItem = Array.from(
gridContainer.querySelectorAll(".ge-grid-item")
).find((item) => item.dataset.filePath === file.path);
if (gridItem) {
gridItem.scrollIntoView({ behavior: "smooth", block: "center" });
const itemIndex = view.gridItems.indexOf(gridItem);
if (itemIndex >= 0) {
view.selectItem(itemIndex);
}
}
}, 100);
}
}
async activateView(mode = "bookmarks", path = "") {
const { workspace } = this.app;
let leaf = null;
const leaves = workspace.getLeavesOfType("grid-view");
if (this.settings.reuseExistingLeaf && leaves.length > 0) {
leaf = leaves[0];
} else {
switch (this.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 = workspace.getLeaf("tab");
}
await leaf.setViewState({ type: "grid-view", active: true });
if (leaf.view instanceof GridView) {
leaf.view.setSource(mode, path);
}
workspace.revealLeaf(leaf);
return leaf.view;
}
async loadSettings() {
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
updateCustomDocumentExtensions(this.settings);
}
async saveSettings() {
await this.saveData(this.settings);
updateCustomDocumentExtensions(this.settings);
const leaves = this.app.workspace.getLeavesOfType("grid-view");
leaves.forEach((leaf) => {
if (leaf.view instanceof GridView) {
leaf.view.render();
}
});
}
};
/* nosourcemap */