This commit is contained in:
Devon22 2025-07-11 17:39:33 +08:00
parent cfb912e76e
commit 8677eee105
9 changed files with 256 additions and 91 deletions

View file

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

View file

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

View file

@ -1,4 +1,4 @@
import { WorkspaceLeaf, ItemView, TFolder, TFile, Menu, Notice, Platform, setIcon, getFrontMatterInfo, FrontMatterCache, normalizePath } from 'obsidian';
import { WorkspaceLeaf, ItemView, TFolder, TFile, Menu, Notice, Platform, setIcon, getFrontMatterInfo, FrontMatterCache, normalizePath, setTooltip } from 'obsidian';
import GridExplorerPlugin from '../main';
import { handleKeyDown as handleKeyDownHelper } from './handleKeyDown';
import { isDocumentFile, isMediaFile, isImageFile, isVideoFile, isAudioFile, sortFiles, ignoredFiles, getFiles, IMAGE_EXTENSIONS, VIDEO_EXTENSIONS } from './fileUtils';
@ -197,6 +197,11 @@ export class GridView extends ItemView {
if(this.sourceMode === '') this.sourceMode = 'folder';
if(this.sourcePath === '') this.sourcePath = '/';
// 非資料夾模式時,強制路徑為根目錄
if(this.sourceMode !== 'folder') {
this.sourcePath = '/';
}
this.render(resetScroll);
// 通知 Obsidian 保存視圖狀態
this.app.workspace.requestSaveLayout();
@ -696,12 +701,12 @@ export class GridView extends ItemView {
parentFolderName = t('root');
}
const folderNameContainer = this.containerEl.createDiv('ge-foldername-content');
const modenameContainer = this.containerEl.createDiv('ge-modename-content');
// 為區域添加點擊事件,點擊後網格容器捲動到最頂部
folderNameContainer.addEventListener('click', (event: MouseEvent) => {
modenameContainer.addEventListener('click', (event: MouseEvent) => {
// 只有當點擊的是頂部按鈕區域本身(而不是其中的按鈕)時才觸發捲動
if (event.target === folderNameContainer) {
if (event.target === modenameContainer) {
event.preventDefault();
// 取得網格容器
const gridContainer = this.containerEl.querySelector('.ge-grid-container');
@ -716,7 +721,7 @@ export class GridView extends ItemView {
// 建立可點擊的上層資料夾名稱
const customFolderIcon = this.plugin.settings.customFolderIcon;
const parentFolderLink = folderNameContainer.createEl('a', {
const parentFolderLink = modenameContainer.createEl('a', {
text: `${customFolderIcon} ${parentFolderName}`.trim(),
cls: 'ge-parent-folder-link'
});
@ -801,10 +806,10 @@ export class GridView extends ItemView {
});
// 分隔符號
folderNameContainer.createEl('span', { text: ' > ' });
modenameContainer.createEl('span', { text: ' > ' });
// 目前資料夾名稱
folderNameContainer.createEl('span', { text: currentFolderName });
modenameContainer.createEl('span', { text: currentFolderName });
if (Platform.isDesktop) {
// 為上層按鈕添加拖曳目標功能
@ -864,12 +869,12 @@ export class GridView extends ItemView {
}
} else if (!(this.searchQuery !== '' && this.searchAllFiles)) {
// 顯示目前模式名稱
const folderNameContainer = this.containerEl.createDiv('ge-foldername-content');
const modenameContainer = this.containerEl.createDiv('ge-modename-content');
// 為區域添加點擊事件,點擊後網格容器捲動到最頂部
folderNameContainer.addEventListener('click', (event: MouseEvent) => {
modenameContainer.addEventListener('click', (event: MouseEvent) => {
// 只有當點擊的是頂部按鈕區域本身(而不是其中的按鈕)時才觸發捲動
if (event.target === folderNameContainer) {
if (event.target === modenameContainer) {
event.preventDefault();
// 取得網格容器
const gridContainer = this.containerEl.querySelector('.ge-grid-container');
@ -953,17 +958,45 @@ export class GridView extends ItemView {
}
}
// 顯示模式名稱
folderNameContainer.createEl('span', {
text: `${modeIcon} ${modeName}`.trim(),
cls: 'ge-mode-title'
});
// 顯示模式名稱 (若為自訂模式則提供點擊選單以快速切換)
let modeTitleEl: HTMLElement;
if (this.sourceMode.startsWith('custom-')) {
// 使用可點擊的 <a> 元素
modeTitleEl = modenameContainer.createEl('a', {
text: `${modeIcon} ${modeName}`.trim(),
cls: 'ge-parent-folder-link'
});
// 點擊時顯示所有自訂模式選單
modeTitleEl.addEventListener('click', (evt) => {
const menu = new Menu();
this.plugin.settings.customModes
.filter(m => m.enabled ?? true) // 僅顯示啟用的自訂模式
.forEach((m) => {
menu.addItem(item => {
item.setTitle(`${m.icon || '🧩'} ${m.displayName}`)
.setChecked(m.internalName === this.sourceMode)
.onClick(() => {
// 切換至選取的自訂模式並重新渲染
this.setSource(m.internalName, '', true);
});
});
});
menu.showAtMouseEvent(evt);
});
} else {
// 其他模式維持原本的 span
modeTitleEl = modenameContainer.createEl('span', {
text: `${modeIcon} ${modeName}`.trim(),
cls: 'ge-mode-title'
});
}
switch (this.sourceMode) {
case 'tasks':
folderNameContainer.createEl('span', { text: ' > ' });
modenameContainer.createEl('span', { text: ' > ' });
const taskFilterSpan = folderNameContainer.createEl('a', { text: t(`${this.taskFilter}`), cls: 'ge-task-filter' });
const taskFilterSpan = modenameContainer.createEl('a', { text: t(`${this.taskFilter}`), cls: 'ge-task-filter' });
taskFilterSpan.addEventListener('click', (evt) => {
const menu = new Menu();
menu.addItem((item) => {
@ -999,10 +1032,16 @@ export class GridView extends ItemView {
break;
default:
if (this.sourceMode.startsWith('custom-')) {
// 把 modenameContainer 加上所有自訂模式選項的選單
// 取得當前自訂模式
const mode = this.plugin.settings.customModes.find(m => m.internalName === this.sourceMode);
if (mode && mode.options && mode.options.length > 0) {
folderNameContainer.createEl('span', { text: ' > ' });
modenameContainer.createEl('span', { text: ' > ' });
if (this.customOptionIndex >= mode.options.length || this.customOptionIndex < -1) {
this.customOptionIndex = -1;
}
let subName: string | undefined;
if (this.customOptionIndex === -1) {
@ -1012,7 +1051,7 @@ export class GridView extends ItemView {
subName = opt.name?.trim() || `${t('option')} ${this.customOptionIndex + 1}`;
}
const subSpan = folderNameContainer.createEl('a', { text: subName ?? '-', cls: 'ge-sub-option' });
const subSpan = modenameContainer.createEl('a', { text: subName ?? '-', cls: 'ge-sub-option' });
subSpan.addEventListener('click', (evt) => {
const menu = new Menu();
// 預設選項
@ -1045,8 +1084,8 @@ export class GridView extends ItemView {
}
} else if (this.searchQuery !== '' && this.searchAllFiles) {
// 顯示全域搜尋名稱
const folderNameContainer = this.containerEl.createDiv('ge-foldername-content');
folderNameContainer.createEl('span', {
const modenameContainer = this.containerEl.createDiv('ge-modename-content');
modenameContainer.createEl('span', {
text: `🔍 ${t('global_search')}`,
cls: 'ge-mode-title'
});
@ -1226,7 +1265,7 @@ export class GridView extends ItemView {
const titleContainer = contentArea.createDiv('ge-title-container');
const customFolderIcon = this.plugin.settings.customFolderIcon;
titleContainer.createEl('span', { cls: 'ge-title', text: `${customFolderIcon} ${folder.name}`.trim() });
titleContainer.setAttribute('title', folder.name);
setTooltip(folderEl, folder.name,{ placement: this.cardLayout === 'vertical' ? 'bottom' : 'right' });
// 檢查同名筆記是否存在
const notePath = `${folder.path}/${folder.name}.md`;
@ -1681,11 +1720,59 @@ export class GridView extends ItemView {
let pEl: HTMLElement | null = null;
if (!this.minMode) {
const summaryField = this.plugin.settings.noteSummaryField || 'summary';
const summaryValue = metadata?.[summaryField];
let summaryField = this.plugin.settings.noteSummaryField || 'summary';
let summaryValue = metadata?.[summaryField];
if (this.sourceMode.startsWith('custom-')) {
// 自訂模式下,使用自訂的 fields 來顯示摘要
const mode = this.plugin.settings.customModes.find(m => m.internalName === this.sourceMode);
if (mode) {
let fields = mode?.fields || '';
// 當有選到子選項 (index >= 0) 而且 options 陣列確實存在
if (this.customOptionIndex >= 0 &&
mode.options &&
this.customOptionIndex < mode.options.length) {
const option = mode.options[this.customOptionIndex];
fields = option.fields || '';
}
// 如果 fields 不為空,則使用它來顯示摘要
if (fields) {
// 將 fields 以逗號分隔成陣列,並過濾掉空值
const fieldList = fields.split(',').map(f => f.trim()).filter(Boolean);
const fieldValues: string[] = [];
// 收集所有欄位值
fieldList.forEach(field => {
if (metadata?.[field] !== undefined && metadata?.[field] !== '' && metadata?.[field] !== null) {
// 如果是數字,則加入千位分隔符號
if (typeof metadata[field] === 'number') {
metadata[field] = metadata[field].toLocaleString();
}
// 如果是陣列,則轉換為字串
if (Array.isArray(metadata[field])) {
metadata[field] = metadata[field].join(', ');
}
fieldValues.push(`${field}: ${metadata[field]}`);
}
});
// 如果有找到任何欄位值,則組合起來
if (fieldValues.length > 0) {
summaryValue = fieldValues.join('\n'); // 使用 | 分隔不同欄位
}
}
}
}
if (summaryValue) {
pEl = contentArea.createEl('p', { text: summaryValue.trim() });
if (!this.sourceMode.startsWith('custom-')) {
// Frontmatter 有設定摘要值
pEl = contentArea.createEl('p', { text: summaryValue.trim() });
} else {
// custom mode 有設定顯示欄位值
pEl = contentArea.createEl('p', { text: summaryValue.trim() , cls: 'ge-content-area-p-field' });
}
} else {
// Frontmatter 沒有設定摘要值,則使用內文
let contentWithoutFrontmatter = '';
if (summaryLength < 500) {
contentWithoutFrontmatter = content.substring(frontMatterInfo.contentStart).slice(0, 500);
@ -1737,7 +1824,8 @@ export class GridView extends ItemView {
//將預覽文字設定到標題的 title 屬性中
const titleEl = fileEl.querySelector('.ge-title');
if (titleEl && pEl) {
titleEl.setAttribute('title', `${titleEl.textContent}\n${pEl.textContent}` || '');
// titleEl.setAttribute('title', `${titleEl.textContent}\n${pEl.textContent}` || '');
setTooltip(contentArea as HTMLElement, `${titleEl.textContent}`, { placement: this.cardLayout === 'vertical' ? 'bottom' : 'right' })
}
if (frontMatterInfo.exists) {
@ -1783,6 +1871,8 @@ export class GridView extends ItemView {
if (!this.minMode) {
contentArea.createEl('p', { text: file.extension.toUpperCase() });
}
setTooltip(fileEl as HTMLElement, `${file.name}`, { placement: this.cardLayout === 'vertical' ? 'bottom' : 'right' })
}
// 顯示標籤(僅限 Markdown 檔案)
@ -2208,6 +2298,11 @@ export class GridView extends ItemView {
fileEl.addClass('ge-foldernote');
}
//如果檔案是否處於置頂範圍,添加 ge-pinned 類別
if (this.pinnedList.includes(file.name)) {
fileEl.addClass('ge-pinned');
}
// 創建左側內容區,包含圖示和標題
const contentArea = fileEl.createDiv('ge-content-area');
@ -2216,7 +2311,9 @@ export class GridView extends ItemView {
const extension = file.extension.toLowerCase();
// 檢查是否為媒體檔案,如果是則添加 ge-media-card 類別
if (this.cardLayout === 'vertical' && (isImageFile(file) || isVideoFile(file))) {
if (this.cardLayout === 'vertical' &&
(isImageFile(file) || isVideoFile(file)) &&
!this.minMode) {
fileEl.addClass('ge-media-card');
}
@ -2252,7 +2349,7 @@ export class GridView extends ItemView {
const displayText = shouldShowExtension ? `${file.basename}.${file.extension}` : file.basename;
const titleEl = titleContainer.createEl('span', { cls: 'ge-title', text: displayText });
if (this.plugin.settings.multiLineTitle) titleEl.addClass('ge-multiline-title');
titleEl.setAttribute('title', displayText);
//titleEl.setAttribute('title', displayText);
// 創建圖片區域,但先不載入圖片
if (!this.minMode) {
@ -2347,6 +2444,7 @@ export class GridView extends ItemView {
// 獲取選中的檔案
const selectedFiles = this.getSelectedFiles();
let drag_filename = '';
// 添加拖曳資料
if (selectedFiles.length > 1) {
@ -2360,6 +2458,8 @@ export class GridView extends ItemView {
// 添加檔案路徑列表
event.dataTransfer?.setData('application/obsidian-grid-explorer-files',
JSON.stringify(selectedFiles.map(f => f.path)));
drag_filename = `${selectedFiles.length} ${t('files')}`;
} else {
// 如果只有單個檔案被選中,使用檔案路徑
const isMedia = isMediaFile(file);
@ -2373,8 +2473,25 @@ export class GridView extends ItemView {
// 添加檔案路徑列表
event.dataTransfer?.setData('application/obsidian-grid-explorer-files',
JSON.stringify([file.path]));
drag_filename = file.basename;
}
const dragImage = document.createElement('div');
dragImage.className = 'ge-custom-drag-preview';
dragImage.textContent = drag_filename;
// 將元素暫時加入 DOM
document.body.appendChild(dragImage);
// 設定拖曳圖示
event.dataTransfer!.setDragImage(dragImage, 20, 20);
// 延遲移除元素(讓拖曳圖示正常顯示)
setTimeout(() => {
document.body.removeChild(dragImage);
}, 0);
// 設定拖曳效果
event.dataTransfer!.effectAllowed = 'all';
// 添加拖曳中的視覺效果

View file

@ -30,25 +30,25 @@ export class CustomModeModal extends Modal {
// 向下相容:使用第一個選項作為主要 dataviewCode
let dataviewCode = this.mode ? this.mode.dataviewCode : '';
let enabled = this.mode ? (this.mode.enabled ?? true) : true;
let fields = this.mode ? this.mode.fields : '';
new Setting(contentEl)
.setName(t('custom_mode_display_name'))
.setDesc(t('custom_mode_display_name_desc'))
.addText(text => {
text.setValue(displayName)
.onChange(value => {
displayName = value;
});
});
new Setting(contentEl)
.setName(t('custom_mode_icon'))
.setDesc(t('custom_mode_icon_desc'))
.setName(t('custom_mode_display_name'))
.setDesc(t('custom_mode_display_name_desc'))
.addText(text => {
text.setValue(icon)
.onChange(value => {
icon = value || '🧩';
});
// 設置固定寬度,適合單個圖示
text.inputEl.style.width = '3em';
text.inputEl.style.minWidth = '3em';
})
.addText(text => {
text.setValue(displayName)
.onChange(value => {
displayName = value;
});
});
const dvSetting = new Setting(contentEl)
@ -61,9 +61,11 @@ export class CustomModeModal extends Modal {
dvSetting.settingEl.style.gap = '0.5rem';
dvSetting.addText(text => {
text.setValue(name).onChange(v => name = v);
text.setValue(name)
.setPlaceholder(t('default'))
.onChange(v => name = v);
});
dvSetting.addTextArea(text => {
text.setValue(dataviewCode)
.onChange(value => {
@ -75,6 +77,14 @@ export class CustomModeModal extends Modal {
text.inputEl.style.width = '100%';
});
dvSetting.addText(text => {
text.setValue(fields || '')
.setPlaceholder(t('custom_mode_fields_placeholder'))
.onChange(value => {
fields = value;
});
});
// 讓 Text 與 TextArea 在 control 區域各佔一行
dvSetting.controlEl.style.display = 'flex';
dvSetting.controlEl.style.flexDirection = 'column';
@ -115,6 +125,13 @@ export class CustomModeModal extends Modal {
});
text.inputEl.setAttr('rows', 6);
text.inputEl.style.width = '100%';
})
.addText(text => {
text.setPlaceholder(t('custom_mode_fields_placeholder'))
.setValue(opt.fields || '')
.onChange(val => {
opt.fields = val;
});
});
// 移除按鈕(至少保留一個)
@ -160,7 +177,8 @@ export class CustomModeModal extends Modal {
name,
dataviewCode,
options: options,
enabled
enabled,
fields
});
this.close();
});

View file

@ -6,6 +6,7 @@ import { t } from './translations';
export interface CustomModeOption {
name: string;
dataviewCode: string;
fields?: string;
}
export interface CustomMode {
@ -16,6 +17,7 @@ export interface CustomMode {
dataviewCode: string;
options?: CustomModeOption[];
enabled?: boolean; // 是否顯示此自訂模式,預設為 true
fields?: string;
}
export interface GallerySettings {

View file

@ -148,13 +148,12 @@ export const TRANSLATIONS: Translations = {
'import_error': '匯入失敗:無效的檔案格式',
'edit_custom_mode': '編輯自訂模式',
'custom_mode': '自訂模式',
'custom_mode_icon': '圖示',
'custom_mode_icon_desc': '在模式選單中顯示的圖示',
'custom_mode_display_name': '顯示名稱',
'custom_mode_display_name_desc': '在模式選單中顯示的名稱',
'custom_mode_dataview_code': 'Dataviewjs 代碼',
'custom_mode_dataview_code_desc': '輸入 Dataviewjs 代碼以取得檔案列表',
'custom_mode_sub_options': '自訂模式子選項',
'custom_mode_fields_placeholder': '輸入 frontmatter 欄位名稱,用逗號分隔 (如: date,category,status) (可選)',
'show_bookmarks_mode': '顯示書籤模式',
'show_search_mode': '顯示搜尋結果模式',
'show_backlinks_mode': '顯示反向連結模式',
@ -409,13 +408,12 @@ export const TRANSLATIONS: Translations = {
'import_error': 'Import failed: Invalid file format',
'edit_custom_mode': 'Edit Custom Mode',
'custom_mode': 'Custom Mode',
'custom_mode_icon': 'Icon',
'custom_mode_icon_desc': 'The icon displayed in the mode menu',
'custom_mode_display_name': 'Display Name',
'custom_mode_display_name_desc': 'The name displayed in the mode menu',
'custom_mode_dataview_code': 'Dataview Query',
'custom_mode_dataview_code_desc': 'Enter a Dataview query to get the list of files',
'custom_mode_sub_options': 'Custom Mode Sub Options',
'custom_mode_fields_placeholder': 'Enter frontmatter field names, separated by commas (e.g. date,category,status) (optional)',
'show_bookmarks_mode': 'Show bookmarks mode',
'show_search_mode': 'Show search results mode',
'show_backlinks_mode': 'Show backlinks mode',
@ -670,13 +668,12 @@ export const TRANSLATIONS: Translations = {
'import_error': '导入失败:无效的文件格式',
'edit_custom_mode': '编辑自定义模式',
'custom_mode': '自定义模式',
'custom_mode_icon': '图标',
'custom_mode_icon_desc': '在模式菜单中显示的图标',
'custom_mode_display_name': '显示名称',
'custom_mode_display_name_desc': '在模式菜单中显示的名称',
'custom_mode_dataview_code': 'Dataviewjs 代码',
'custom_mode_dataview_code_desc': '输入 Dataviewjs 代码以获取文件列表',
'custom_mode_sub_options': '自定义模式子选项',
'custom_mode_fields_placeholder': '输入 frontmatter 栏位名称,用逗号分隔 (如: date,category,status) (可选)',
'show_bookmarks_mode': '显示书签模式',
'show_search_mode': '显示搜索结果模式',
'show_backlinks_mode': '显示反向链接模式',
@ -931,13 +928,12 @@ export const TRANSLATIONS: Translations = {
'import_error': 'インポート失敗:無効なファイル形式',
'edit_custom_mode': 'カスタムモードを編集',
'custom_mode': 'カスタムモード',
'custom_mode_icon': 'アイコン',
'custom_mode_icon_desc': 'モードメニューで表示するアイコン',
'custom_mode_display_name': '表示名',
'custom_mode_display_name_desc': 'モードメニューで表示する名前',
'custom_mode_dataview_code': 'Dataviewjs コード',
'custom_mode_dataview_code_desc': 'ファイルリストを取得する Dataviewjs コードを入力',
'custom_mode_sub_options': 'カスタムモード子選択肢',
'custom_mode_fields_placeholder': 'frontmatterのフィールド名をカンマ区切りで入力 (例: date,category,status) (任意)',
'show_bookmarks_mode': 'ブックマークモードを表示',
'show_search_mode': '検索結果モードを表示',
'show_backlinks_mode': 'バックリンクモードを表示',
@ -1193,13 +1189,12 @@ export const TRANSLATIONS: Translations = {
'import_error': 'Ошибка импорта: недопустимый формат файла',
'edit_custom_mode': 'Редактировать режим отображения',
'custom_mode': 'Режим отображения',
'custom_mode_icon': 'Иконка',
'custom_mode_icon_desc': 'Иконка, отображаемая в меню режимов',
'custom_mode_display_name': 'Отображаемое имя',
'custom_mode_display_name_desc': 'Отображаемое имя в меню режимов',
'custom_mode_dataview_code': 'Код Dataview',
'custom_mode_dataview_code_desc': 'Введите код Dataview для получения списка файлов',
'custom_mode_sub_options': 'Подопции пользовательского режима',
'custom_mode_fields_placeholder': 'Введите названия полей frontmatter через запятую (напр.: date,category,status) (необязательно)',
'show_bookmarks_mode': 'Показывать режим закладок',
'show_search_mode': 'Показывать режим результатов поиска',
'show_backlinks_mode': 'Показывать режим обратных ссылок',
@ -1454,13 +1449,12 @@ export const TRANSLATIONS: Translations = {
'import_error': 'Помилка імпорту: недопустимий формат файлу',
'edit_custom_mode': 'Редагувати режим відображення',
'custom_mode': 'Режим відображення',
'custom_mode_icon': 'Іконка',
'custom_mode_icon_desc': 'Іконка, відображається в меню режимів',
'custom_mode_display_name': 'Відображається ім`я',
'custom_mode_display_name_desc': 'Відображається ім`я в меню режимів',
'custom_mode_dataview_code': 'Код Dataview',
'custom_mode_dataview_code_desc': 'Введіть код Dataview для отримання списку файлів',
'custom_mode_sub_options': 'Підпараметри користувацького режиму',
'custom_mode_fields_placeholder': 'Введіть назви полів frontmatter через кому (напр.: date,category,status) (необязательно)',
'show_bookmarks_mode': 'Показувати режим закладок',
'show_search_mode': 'Показувати режим результатів пошуку',
'show_backlinks_mode': 'Показувати режим зворотних посилань',

View file

@ -4,8 +4,6 @@
height: 100%;
}
/* --------------------------------------------------------------------------- */
/* 網格容器 Grid Container */
@ -46,6 +44,10 @@
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.ge-grid-item:hover p {
color: var(--text-muted);
}
/* 摘要區域 Content Area */
.ge-content-area {
flex: 1;
@ -134,20 +136,27 @@
line-height: 1.4;
overflow: hidden;
display: -webkit-box;
height: 100%;
-webkit-line-clamp: 3;
line-clamp: 3;
-webkit-box-orient: vertical;
height: 100%;
}
.ge-grid-item:hover p {
color: var(--text-muted);
}
.ge-content-area p:empty {
margin: 0;
}
.ge-content-area-p-field,
.ge-content-area .ge-content-area-p-field {
display: block;
-webkit-line-clamp: unset !important;
line-clamp: unset !important;
-webkit-box-orient: unset !important;
white-space: pre-wrap;
overflow: visible;
height: auto;
}
/* 圖片區域 Image Area */
.ge-image-area {
width: var(--image-area-width);
@ -182,7 +191,8 @@
flex-direction: column;
align-items: stretch;
height: var(--grid-item-height); /* 與一般網格一致,保持同排等高 */
gap: 12px;
gap: 0px;
padding: 0px !important;
}
/* 摘要文字 Content Area */
@ -190,18 +200,14 @@
order: 1;
flex: 1 1 auto; /* 使摘要區撐開,標籤可貼底 */
flex-grow: 1; /* Add this line */
padding: 10px !important;
}
/* 圖片置中,滿版顯示 Image Area */
.ge-vertical-card .ge-image-area {
order: 3;
width: 100%;
height: var(--image-area-height);
}
.ge-vertical-card .ge-image-area img,
.ge-vertical-card .ge-image-area video {
border-radius: 6px;
height: var(--image-area-height);
}
/* 標籤列置底 Tags Container */
@ -219,6 +225,11 @@
order: 3;
}
.ge-vertical-card.ge-image-top .ge-image-area img,
.ge-vertical-card.ge-image-top .ge-image-area video {
border-radius: calc(var(--button-radius) - var(--border-width)) calc(var(--button-radius) - var(--border-width)) 0px 0px !important;
}
/* 預設 bottom 可維持原有順序,以下為明確設置 */
.ge-vertical-card.ge-image-bottom .ge-image-area {
order: 3;
@ -228,6 +239,11 @@
order: 1;
}
.ge-vertical-card.ge-image-bottom .ge-image-area img,
.ge-vertical-card.ge-image-bottom .ge-image-area video {
border-radius: 0px 0px calc(var(--button-radius) - var(--border-width)) calc(var(--button-radius) - var(--border-width)) !important;
}
/* 鼠標懸停效果:整張卡片微抬升 */
.ge-vertical-card .ge-grid-item:hover {
transform: translateY(-2px);
@ -292,6 +308,7 @@
justify-content: center;
background-color: var(--background-secondary);
border-radius: 4px;
border: 1px solid var(--background-modifier-border);
}
.ge-video-thumbnail svg {
@ -535,8 +552,8 @@
/* --------------------------------------------------------------------------- */
/* 資料夾名稱區域樣式 Folder Name Content */
.ge-foldername-content {
/* Mode名稱區域樣式 Mode Name Content */
.ge-modename-content {
justify-content: center;
padding: 10px 8px 9px 8px;
background-color: var(--background-secondary);
@ -544,24 +561,23 @@
font-size: var(--font-ui-medium);
}
.ge-foldername-content span {
.ge-modename-content span {
display: inline-flex;
align-items: center;
}
.ge-foldername-content span.ge-mode-title {
.ge-modename-content span.ge-mode-title {
padding-left: 5px;
padding-right: 3px;
}
/* 為資料夾名稱、分隔符等元素添加間距 */
.ge-foldername-content > *:nth-child(1) {
.ge-modename-content > *:nth-child(1) {
margin-left: 11px;
margin-right: 3px;
}
.ge-foldername-content > *:nth-child(2) {
.ge-modename-content > *:nth-child(2) {
margin-right: 6px;
}
@ -1193,18 +1209,18 @@
width: 60px;
}
/* 忽略資料夾設定 */
/* 忽略資料夾設定 Ignored Folders Setting */
.ge-ignored-folders-container {
margin-bottom: 16px;
}
/* 忽略資料夾列表 */
/* 忽略資料夾列表 Ignored Folders List */
.ge-ignored-folders-list {
list-style: none;
padding: 0;
}
/* 忽略資料夾項目 */
/* 忽略資料夾項目 Ignored Folder Item */
.ge-ignored-folder-item {
display: flex;
align-items: center;
@ -1216,7 +1232,7 @@
background-color: var(--background-primary);
}
/* 忽略資料夾路徑 */
/* 忽略資料夾路徑 Ignored Folder Path */
.ge-ignored-folder-path {
flex-grow: 1;
margin-right: 8px;
@ -1225,7 +1241,7 @@
white-space: nowrap;
}
/* 忽略資料夾刪除按鈕 */
/* 忽略資料夾刪除按鈕 Ignored Folder Remove */
.ge-ignored-folder-remove {
background-color: var(--interactive-normal);
color: var(--text-normal);
@ -1240,13 +1256,34 @@
background-color: var(--interactive-hover);
}
/* 忽略資料夾模式的容器 */
/* 忽略資料夾模式的容器 Ignored Folder Patterns Container */
.ignored-folder-patterns-container {
margin-bottom: 16px;
}
/* 忽略資料夾模式列表 */
/* 忽略資料夾模式列表 Ignored Folder Patterns List */
.ge-ignored-folder-patterns-list {
list-style: none;
padding: 0;
}
/* 拖曳預覽 Drag Preview */
.ge-custom-drag-preview {
position: absolute;
top: -1000px; /* 隱藏在視窗外 */
left: -1000px;
font-size: var(--font-ui-small);
white-space: nowrap;
color: rgba(var(--mono-rgb-0), 0.9);
background: rgba(var(--mono-rgb-100), 0.9);
border: 1px solid var(--border-color);
border-radius: 4px;
padding: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
pointer-events: none;
z-index: 1000;
max-width: 150px;
overflow: hidden;
text-overflow: ellipsis;
}

View file

@ -1,6 +1,3 @@
{
"2.5.6": "1.1.0",
"2.5.7": "1.1.0",
"2.6.0": "1.1.0",
"2.6.1": "1.1.0"
"2.6.2": "1.1.0"
}