This commit is contained in:
Devon22 2025-07-31 23:27:04 +08:00
parent 330c73ba48
commit 63ca91d3bd
13 changed files with 632 additions and 54 deletions

View file

@ -0,0 +1,51 @@
---
date: 2025-06-26
---
1. My Favorites
```
return dv.pages("#Favorites").sort(page => page.modified_date ? dv.date(page.modified_date) : page.file.mtime, 'desc');
```
2. On This Day in History
```
const today = new Date();
return dv.pages().where(p => {
const pageDate = p.modified_date ? new Date(p.modified_date): new Date(p.file.mtime);
return pageDate.getYear() !== today.getYear() &&
pageDate.getMonth() === today.getMonth() &&
pageDate.getDate() === today.getDate();
});
```
3. Backlinks
```
const currentPage = dv.current();
if (!currentPage) return [];
return dv.pages().where(p => p.file.outlinks.includes(currentPage.file.link) && p.file.path.split('/').length > 1).sort(page => page.modified_date ? dv.date(page.modified_date) : page.file.mtime, 'desc');
```
4. Random Images
```
const files = app.vault.getFiles();
const imageFiles = files.filter(file =>
file.path.startsWith("resources/") &&
/\.(png|jpg|jpeg|gif|bmp|svg|webp)$/i.test(file.name)
);
return imageFiles
.sort(() => 0.5 - Math.random())
.slice(0, 10)
.map(f => ({ file: f }));
```
5. Random Videos
```
const files = app.vault.getFiles();
const videoFiles = files.filter(file =>
file.path.startsWith("resources/") &&
/\.(mp4|webm|mov|avi|mkv|ogv)$/i.test(file.name)
);
return videoFiles
.sort(() => 0.5 - Math.random())
.slice(0, 10)
.map(f => ({ file: f }));
```

134
docs/custom-mode-fields.md Normal file
View file

@ -0,0 +1,134 @@
# Grid Explorer Custom Mode Fields Guide
## Overview
Grid Explorer supports setting field aliases and performing real-time computations in custom modes. This allows for more flexible display and calculation of note metadata.
## Basic Syntax
### Field Aliases
Use the `|` symbol to set a display name for a field:
```
original_field|Display Name
```
**Examples:**
- `birthday|Birthday` - Displays the `birthday` field as "Birthday"
- `status|Status` - Displays the `status` field as "Status"
### Computation Expressions
Use `{{ ... }}` to wrap JavaScript expressions for computation:
```
field_name {{ expression }}
```
**Available Variables:**
| Variable | Description | Example |
|----------|-------------|---------|
| `value` | Current field's raw value | `value` or `this` |
| `metadata` | The complete frontmatter metadata object | `metadata.tags` |
| `app` | Obsidian app instance | `app.vault.getMarkdownFiles()` |
| `dv` | Dataview API instance (requires Dataview plugin) | `dv.pages('#tag')` |
## Advanced Usage
### Combining Aliases and Computations
```
field_name|Display Name {{ expression }}
```
**Basic Example:**
```
age|Age {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
**With Dataview Example:**
```
tags|Related Notes {{ dv.pages(value).length }}
```
### Multi-field Combinations
```
full_name|Full Name {{ (metadata.first_name || '') + ' ' + (metadata.last_name || '') }}
```
## Practical Examples
### 1. Basic Computations
#### Calculate Age
```
birthday|Age {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
#### Format Date
```
date|Date {{ new Date(value).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) }}
```
### 2. Advanced Dataview Usage
#### Count Related Notes
```
tags|Related Notes {{ dv.pages(value).length }}
```
#### Show Incomplete Tasks
```
file.folder|To-dos {{ dv.pages(`"${value}"`).file.tasks.where(t => !t.completed).length }}
```
#### Calculate Tag Frequency
```
tags|Tag Stats {{ value.map(tag => `${tag}(${dv.pages(tag).length})`).join(', ') }}
```
#### Show Last Modified Time
```
file.mtime|Last Modified {{ dv.date(value).toFormat('yyyy-MM-dd HH:mm') }}
```
### 3. Conditional Display
```
status|Status {{ value === 'active' ? 'Active' : 'Inactive' }}
```
### 4. Progress Calculation
```
progress|Progress {{ Math.round((metadata.completed / metadata.total) * 100) + '%' }}
```
## Notes
1. JavaScript code in computation expressions is executed dynamically when displayed
2. If a computation fails, it falls back to the original value
3. For security, avoid using potentially harmful code in expressions
4. Keep expressions simple; use Dataview plugin for complex calculations
## Troubleshooting
If computations don't work as expected:
1. Check expression syntax
2. Use `console.log(value, metadata)` for debugging
3. Verify field names and case sensitivity
4. Check for extra spaces or special characters
## Advanced Tips
- Use ternary operators for conditional rendering
- Combine multiple fields in computations
- Use JavaScript built-in functions (like `toLocaleString()`, `toFixed()`) for formatting
- Access Obsidian API using the `app` variable
---
This feature allows for flexible display and computation of note data without writing complex plugin code.

View file

@ -0,0 +1,134 @@
# Grid Explorer カスタムモード フィールドガイド
## 概要
Grid Explorer は、カスタムモードでフィールドのエイリアスを設定し、リアルタイムで計算を実行する機能をサポートしています。これにより、メタデータを柔軟に表示・計算できます。
## 基本構文
### フィールドエイリアス
`|` 記号を使用して、フィールドに表示名を設定します:
```
元のフィールド名|表示名
```
**例:**
- `birthday|誕生日` - `birthday` フィールドを「誕生日」として表示
- `status|状態` - `status` フィールドを「状態」として表示
### 計算式
`{{ ... }}` で JavaScript の式を囲んで計算を実行します:
```
フィールド名 {{ 式 }}
```
**使用可能な変数:**
| 変数 | 説明 | 例 |
|------|------|-----|
| `value` | 現在のフィールドの値 | `value` または `this` |
| `metadata` | フロントマターのメタデータオブジェクト | `metadata.tags` |
| `app` | Obsidian アプリケーションインスタンス | `app.vault.getMarkdownFiles()` |
| `dv` | Dataview API インスタンスDataview プラグインが必要) | `dv.pages('#tag')` |
## 高度な使い方
### エイリアスと計算の組み合わせ
```
フィールド名|表示名 {{ 式 }}
```
**基本例:**
```
birthday|年齢 {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
**Dataview 使用例:**
```
tags|関連ノート {{ dv.pages(value).length }}
```
### 複数フィールドの組み合わせ
```
full_name|フルネーム {{ (metadata.first_name || '') + ' ' + (metadata.last_name || '') }}
```
## 実践的な例
### 1. 基本的な計算
#### 年齢の計算
```
birthday|年齢 {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
#### 日付のフォーマット
```
date|日付 {{ new Date(value).toLocaleDateString('ja-JP', { year: 'numeric', month: 'long', day: 'numeric' }) }}
```
### 2. Dataview の高度な機能
#### 関連ノートのカウント
```
tags|関連ノート {{ dv.pages(value).length }}
```
#### 未完了タスクの表示
```
file.folder|ToDo {{ dv.pages(`"${value}"`).file.tasks.where(t => !t.completed).length }}
```
#### タグの使用頻度
```
tags|タグ統計 {{ value.map(tag => `${tag}(${dv.pages(tag).length})`).join(', ') }}
```
#### 最終更新日時の表示
```
file.mtime|最終更新 {{ dv.date(value).toFormat('yyyy-MM-dd HH:mm') }}
```
### 3. 条件付き表示
```
status|状態 {{ value === 'active' ? '有効' : '無効' }}
```
### 4. 進捗率の計算
```
progress|進捗 {{ Math.round((metadata.completed / metadata.total) * 100) + '%' }}
```
## 注意事項
1. 計算式内の JavaScript コードは表示時に動的に実行されます
2. 計算に失敗した場合は元の値が表示されます
3. セキュリティのため、危険なコードは使用しないでください
4. 複雑な計算には Dataview プラグインの使用を推奨します
## トラブルシューティング
計算が期待通りに動作しない場合:
1. 式の構文を確認してください
2. `console.log(value, metadata)` でデバッグできます
3. フィールド名と大文字小文字を確認してください
4. 余分なスペースや特殊文字を確認してください
## 高度なヒント
- 条件付き表示には三項演算子を使用します
- 複数のフィールドを組み合わせて計算します
- 表示のフォーマットには `toLocaleString()``toFixed()` などの JavaScript 組み込み関数を使用します
- `app` 変数で Obsidian API にアクセスできます
---
この機能を使用すると、複雑なプラグインコードを書かずに、ノートデータを柔軟に表示・計算できます。

View file

@ -0,0 +1,140 @@
# Grid Explorer 自訂模式欄位說明
## 功能概述
Grid Explorer 現在支援在自訂模式中為欄位設定別名,並在顯示時進行即時計算。這讓您能夠以更靈活的方式顯示和計算筆記中的元數據。
## 基本語法
### 欄位別名
使用 `|` 符號為欄位設定顯示名稱:
```
原始欄位名稱|顯示名稱
```
**範例:**
- `birthday|生日` - 將 `birthday` 欄位顯示為「生日」
- `status|狀態` - 將 `status` 欄位顯示為「狀態」
### 計算表達式
使用 `{{ ... }}` 包裝 JavaScript 表達式來進行計算:
```
欄位名稱 {{ 表達式 }}
```
**可用變數:**
在計算表達式中,您可以使用以下變數:
| 變數 | 說明 | 範例 |
|------|------|------|
| `value` | 當前欄位的原始值 | `value``this` |
| `metadata` | 整個 frontmatter 元數據對象 | `metadata.tags` |
| `app` | Obsidian 應用程式實例 | `app.vault.getMarkdownFiles()` |
| `dv` | Dataview API 實例(需安裝 Dataview 插件) | `dv.pages('#tag')` |
## 進階用法
### 結合別名與計算
您可以同時使用別名和計算表達式:
```
欄位名稱|顯示名稱 {{ 表達式 }}
```
**基本範例:**
```
birthday|年齡 {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
**結合 Dataview 範例:**
```
tags|相關筆記 {{ dv.pages(value).length }}
```
### 多欄位組合
您可以在計算表達式中引用其他欄位:
```
full_name|全名 {{ (metadata.first_name || '') + ' ' + (metadata.last_name || '') }}
```
## 實際應用範例
### 1. 基本計算
#### 計算年齡
```
birthday|年齡 {{ Math.floor((Date.now() - new Date(value).getTime()) / (1000 * 60 * 60 * 24 * 365.25)) }}
```
#### 格式化日期
```
date|日期 {{ new Date(value).toLocaleDateString('zh-TW', { year: 'numeric', month: 'long', day: 'numeric' }) }}
```
### 2. 使用 Dataview 的進階功能
#### 計算相關筆記數量
```
tags|相關筆記 {{ dv.pages(value).length }}
```
#### 顯示未完成任務數
```
file.folder|待辦事項 {{ dv.pages(`"${value}"`).file.tasks.where(t => !t.completed).length }}
```
#### 計算標籤使用頻率
```
tags|標籤統計 {{ value.map(tag => `${tag}(${dv.pages(tag).length})`).join(', ') }}
```
#### 顯示最近修改時間
```
file.mtime|最後修改 {{ dv.date(value).toFormat('yyyy-MM-dd HH:mm') }}
```
### 3. 條件顯示
```
status|狀態 {{ value === 'active' ? '啟用' : '停用' }}
```
### 4. 計算進度
```
progress|進度 {{ Math.round((metadata.completed / metadata.total) * 100) + '%' }}
```
## 注意事項
1. 計算表達式中的 JavaScript 代碼會在顯示時動態執行
2. 如果計算表達式出錯,會自動回退顯示原始值
3. 為確保安全性,不建議在表達式中使用可能有害的代碼
4. 表達式應保持簡潔,複雜的計算建議使用 Dataview 插件
## 疑難排解
如果計算結果不符合預期:
1. 檢查表達式語法是否正確
2. 使用 `console.log(value, metadata)` 調試表達式
3. 確認欄位名稱和大小寫是否正確
4. 檢查是否有額外的空格或特殊字符
## 進階提示
- 使用三元運算符進行條件渲染
- 結合多個欄位進行計算
- 使用 JavaScript 的內建函數(如 `toLocaleString()`、`toFixed()` 等)格式化輸出
- 在表達式中使用 `app` 變數訪問 Obsidian API
---
這個功能讓您能夠更靈活地呈現和計算筆記中的數據,無需編寫複雜的插件代碼即可實現強大的顯示效果。

View file

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

4
package-lock.json generated
View file

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

View file

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

View file

@ -39,6 +39,7 @@ export class GridView extends ItemView {
folderSortType: string = ''; // 資料夾排序模式
searchQuery: string = ''; // 搜尋關鍵字
searchAllFiles: boolean = true; // 是否搜尋所有筆記
searchFilesNameOnly: boolean = false; // 是否只搜尋筆記名稱
searchMediaFiles: boolean = false; // 是否搜尋媒體檔案
randomNoteIncludeMedia: boolean = false; // 隨機筆記是否包含圖片和影片
selectedItemIndex: number = -1; // 當前選中的項目索引
@ -84,6 +85,15 @@ export class GridView extends ItemView {
return handleKeyDown(this, event);
}
});
// 監聽 dataview:index-ready
this.registerEvent(
(this.app.metadataCache as any).on('dataview:index-ready', () => {
if (this.sourceMode.startsWith('custom-')) {
this.render();
}
})
);
}
getViewType() {
@ -1938,15 +1948,31 @@ export class GridView extends ItemView {
// 檢查一般搜尋詞
if (normalTerms.length > 0) {
// 檢查檔案名稱是否包含所有一般搜尋字串
const matchesFileName = normalTerms.every(term => fileName.includes(term));
if (!matchesFileName && file.extension === 'md') {
// 如果檔名不匹配且是 Markdown 檔案,檢查內容
const content = (await this.app.vault.cachedRead(file)).toLowerCase();
matchesNormalTerms = normalTerms.every(term => content.includes(term));
if (this.searchFilesNameOnly) {
// 僅檢查檔名
matchesNormalTerms = normalTerms.every(term => fileName.includes(term));
} else {
matchesNormalTerms = matchesFileName;
// 檢查每個一般搜尋字串是否存在於檔名或(若為 Markdown檔案內容中
matchesNormalTerms = true;
let contentLower: string | null = null;
for (const term of normalTerms) {
if (fileName.includes(term)) {
continue; // 此關鍵字已在檔名中找到
}
if (file.extension === 'md') {
// 延遲讀取內容,避免不必要的 IO
if (contentLower === null) {
contentLower = (await this.app.vault.cachedRead(file)).toLowerCase();
}
if (contentLower.includes(term)) {
continue; // 此關鍵字在內容中找到
}
}
// 若此關鍵字既不在檔名也不在內容中,則不符合
matchesNormalTerms = false;
break;
}
}
}
@ -2003,34 +2029,40 @@ export class GridView extends ItemView {
);
// 排序檔案
if (this.sourceMode === 'bookmarks') {
// 保持原始順序
files.sort((a, b) => {
const indexA = fileIndexMap.get(a) ?? Number.MAX_SAFE_INTEGER;
const indexB = fileIndexMap.get(b) ?? Number.MAX_SAFE_INTEGER;
return indexA - indexB;
});
} else if (this.sourceMode === 'recent-files') {
// 臨時的排序類型
const sortType = this.sortType;
this.sortType = 'mtime-desc';
if (this.searchAllFiles) {
// 搜尋所有檔案時
files = sortFiles(files, this);
this.sortType = sortType;
} else if (this.sourceMode === 'random-note') {
// 臨時的排序類型
const sortType = this.sortType;
this.sortType = 'random';
files = sortFiles(files, this);
this.sortType = sortType;
} else if (this.sourceMode.startsWith('custom-')) {
// 保持原始順序
files.sort((a, b) => {
const indexA = fileIndexMap.get(a) ?? Number.MAX_SAFE_INTEGER;
const indexB = fileIndexMap.get(b) ?? Number.MAX_SAFE_INTEGER;
return indexA - indexB;
});
} else {
files = sortFiles(files, this);
// 非搜尋所有檔案時
if (this.sourceMode === 'bookmarks') {
// 保持原始順序
files.sort((a, b) => {
const indexA = fileIndexMap.get(a) ?? Number.MAX_SAFE_INTEGER;
const indexB = fileIndexMap.get(b) ?? Number.MAX_SAFE_INTEGER;
return indexA - indexB;
});
} else if (this.sourceMode === 'recent-files') {
// 臨時的排序類型
const sortType = this.sortType;
this.sortType = 'mtime-desc';
files = sortFiles(files, this);
this.sortType = sortType;
} else if (this.sourceMode === 'random-note') {
// 臨時的排序類型
const sortType = this.sortType;
this.sortType = 'random';
files = sortFiles(files, this);
this.sortType = sortType;
} else if (this.sourceMode.startsWith('custom-')) {
// 保持原始順序
files.sort((a, b) => {
const indexA = fileIndexMap.get(a) ?? Number.MAX_SAFE_INTEGER;
const indexB = fileIndexMap.get(b) ?? Number.MAX_SAFE_INTEGER;
return indexA - indexB;
});
} else {
files = sortFiles(files, this);
}
}
// 忽略檔案
@ -2147,20 +2179,31 @@ export class GridView extends ItemView {
// 收集所有欄位值,並處理別名("原始欄位|別名"
fieldList.forEach(fieldEntry => {
// 解析欄位與顯示名稱
// 只從右邊數來的第一個 '|' 進行分割
// 例如 "State|A|狀態" 會變成 ["State|A", "狀態"]
const lastPipeIndex = fieldEntry.lastIndexOf('|');
let fieldKey, displayName;
// 解析欄位 (fieldKey)、別名 (labelName)、運算式 (calcExpr)
// 格式示例:
// birthday|年齡 {{ Math.floor(...) }}
// birthday {{ Math.floor(...) }}
// birthday|年齡
// birthday
if (lastPipeIndex !== -1) {
// 如果找到 '|',則分割成欄位名稱和顯示名稱
fieldKey = fieldEntry.substring(0, lastPipeIndex).trim();
displayName = fieldEntry.substring(lastPipeIndex + 1).trim() || fieldKey;
let raw = fieldEntry.trim();
let calcExpr: string | null = null;
// 先取出運算區塊 {{ ... }}
const calcMatch = raw.match(/\{\{(.*?)\}\}/);
if (calcMatch) {
calcExpr = calcMatch[1];
raw = raw.substring(0, calcMatch.index).trim(); // 去掉運算部分
}
// 再處理 alias
const aliasIdx = raw.lastIndexOf('|');
let fieldKey: string;
let labelName: string;
if (aliasIdx !== -1) {
fieldKey = raw.substring(0, aliasIdx).trim();
labelName = raw.substring(aliasIdx + 1).trim() || fieldKey;
} else {
// 如果沒有 '|',則使用原始欄位名稱
fieldKey = fieldEntry.trim();
displayName = fieldKey;
fieldKey = raw;
labelName = fieldKey;
}
if (metadata?.[fieldKey] !== undefined && metadata?.[fieldKey] !== '' && metadata?.[fieldKey] !== null) {
@ -2172,7 +2215,20 @@ export class GridView extends ItemView {
if (Array.isArray(metadata[fieldKey])) {
metadata[fieldKey] = metadata[fieldKey].join(', ');
}
fieldValues.push(`${displayName}: ${metadata[fieldKey]}`);
let outputValue: string | number | null = metadata[fieldKey];
if (calcExpr) {
try {
const fn = new Function('value', 'metadata', 'app', 'dv', `return (${calcExpr});`);
// 獲取 Dataview API
const dvApi = this.app.plugins.plugins.dataview?.api;
outputValue = fn(metadata[fieldKey], metadata, this.app, dvApi);
} catch (error) {
console.error('GridExplorer: evaluate displayName error', error);
}
}
fieldValues.push(`${labelName}: ${outputValue}`);
}
});

View file

@ -154,7 +154,9 @@ export class CustomModeModal extends Modal {
renderOptions();
new Setting(contentEl)
const saveSetting = new Setting(contentEl);
saveSetting.settingEl.classList.add('ge-save-footer');
saveSetting
.addButton(button => {
button.setButtonText(t('save'))
.setCta()

View file

@ -164,6 +164,18 @@ export class SearchModal extends Modal {
searchScopeCheckbox.checked = false;
}
// 創建只搜尋檔案名稱設定
const searchNameContainer = searchOptionsContainer.createDiv('ge-search-name-container');
const searchNameCheckbox = searchNameContainer.createEl('input', {
type: 'checkbox',
cls: 'ge-search-name-checkbox'
});
searchNameCheckbox.checked = this.gridView.searchFilesNameOnly;
searchNameContainer.createEl('span', {
text: t('search_files_name_only'),
cls: 'ge-search-name-label'
});
// 創建搜尋媒體檔案設定
const searchMediaFilesContainer = searchOptionsContainer.createDiv('ge-search-media-files-container');
const searchMediaFilesCheckbox = searchMediaFilesContainer.createEl('input', {
@ -189,6 +201,12 @@ export class SearchModal extends Modal {
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
}
});
searchNameContainer.addEventListener('click', (e) => {
if (e.target !== searchNameCheckbox) {
searchNameCheckbox.checked = !searchNameCheckbox.checked;
this.gridView.searchFilesNameOnly = !searchNameCheckbox.checked;
}
});
searchMediaFilesContainer.addEventListener('click', (e) => {
if (e.target !== searchMediaFilesCheckbox) {
searchMediaFilesCheckbox.checked = !searchMediaFilesCheckbox.checked;
@ -302,6 +320,7 @@ export class SearchModal extends Modal {
const performSearch = () => {
this.gridView.searchQuery = searchInput.value;
this.gridView.searchAllFiles = !searchScopeCheckbox.checked;
this.gridView.searchFilesNameOnly = searchNameCheckbox.checked;
this.gridView.searchMediaFiles = searchMediaFilesCheckbox.checked;
this.gridView.clearSelection();
this.gridView.app.workspace.requestSaveLayout();

View file

@ -33,6 +33,7 @@ export const TRANSLATIONS: Translations = {
'search': '搜尋',
'search_placeholder': '搜尋關鍵字',
'search_current_location_only': '僅搜尋目前位置',
'search_files_name_only': '僅搜尋檔名',
'search_media_files': '搜尋媒體檔案',
'cancel': '取消',
'new_note': '新增筆記',
@ -307,6 +308,7 @@ export const TRANSLATIONS: Translations = {
'search': 'Search',
'search_placeholder': 'Search keyword',
'search_current_location_only': 'Search current location only',
'search_files_name_only': 'Search files name only',
'search_media_files': 'Search media files',
'cancel': 'Cancel',
'new_note': 'New note',
@ -581,6 +583,7 @@ export const TRANSLATIONS: Translations = {
'search': '搜索',
'search_placeholder': '搜索关键字',
'search_current_location_only': '仅搜索当前位置',
'search_files_name_only': '仅搜索文件名',
'search_media_files': '搜索媒体文件',
'cancel': '取消',
'new_note': '新建笔记',
@ -853,6 +856,7 @@ export const TRANSLATIONS: Translations = {
'search': '検索',
'search_placeholder': 'キーワード検索',
'search_current_location_only': '現在の場所のみ検索',
'search_files_name_only': 'ファイル名のみ検索',
'search_media_files': 'メディアファイルを検索',
'cancel': 'キャンセル',
'new_note': '新規ノート',
@ -1126,6 +1130,7 @@ export const TRANSLATIONS: Translations = {
'search': 'Поиск',
'search_placeholder': 'Ключевое слово для поиска',
'search_current_location_only': 'Искать только в текущем расположении',
'search_files_name_only': 'Искать только в названии файлов',
'search_media_files': 'Искать медиафайлы',
'cancel': 'Отмена',
'new_note': 'Новая заметка',
@ -1398,6 +1403,7 @@ export const TRANSLATIONS: Translations = {
'search': 'Пошук',
'search_placeholder': 'Ключове слово для пошуку',
'search_current_location_only': 'Шукати лише в поточному розташуванні',
'search_files_name_only': 'Шукати лише в назві файлів',
'search_media_files': 'Шукати медіафайли',
'cancel': 'Скасувати',
'new_note': 'Нова нотатка',

View file

@ -926,6 +926,24 @@ a.ge-current-folder:hover {
font-size: var(--font-ui-small);
}
/* 只搜尋檔案名稱設定樣式 Search Name Container */
.ge-search-name-container {
display: flex;
align-items: center;
cursor: pointer;
}
.ge-search-name-checkbox {
cursor: pointer;
}
.ge-search-name-label {
cursor: pointer;
user-select: none;
color: var(--text-normal);
font-size: var(--font-ui-small);
}
/* 搜尋媒體檔案設定樣式 Search Media Files Container */
.ge-search-media-files-container {
display: flex;
@ -1451,6 +1469,23 @@ a.ge-current-folder:hover {
gap: 0.5rem;
}
/* Save Footer */
.ge-save-footer {
position: sticky;
bottom: 0;
background-color: transparent;
padding: 8px 0;
z-index: 10;
}
.setting-item .ge-save-footer {
border-top: none;
}
.ge-save-footer .setting-item-control button {
box-shadow: 0 5px 8px rgba(0, 0, 0, 0.4);
}
/* --------------------------------------------------------------------------- */
/* Popup Modal Styles */
@ -1871,4 +1906,5 @@ a.ge-current-folder:hover {
.shortcut-option-icon svg {
width: 16px;
height: 16px;
}
}

View file

@ -1,3 +1,3 @@
{
"2.7.10": "1.1.0"
"2.7.11": "1.1.0"
}