This commit is contained in:
Devon22 2026-07-02 17:46:16 +08:00
parent 1a68669cbf
commit f371ff328b
8 changed files with 213 additions and 55 deletions

View file

@ -1,9 +1,9 @@
{
"id": "mediaviewer",
"name": "Media Viewer",
"version": "2.1.9",
"version": "2.1.10",
"minAppVersion": "1.8.7",
"description": "View and manage media files within your notes.",
"description": "Transform your notes with beautiful interactive media galleries. Seamlessly view, zoom, and manage images, videos, and audio files directly in Obsidian.",
"author": "Devon22",
"authorUrl": "https://github.com/Devon22",
"isDesktopOnly": false

4
package-lock.json generated
View file

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

View file

@ -1,6 +1,6 @@
{
"name": "mediaviewer",
"version": "2.1.9",
"version": "2.1.10",
"description": "View and manage media files within your notes.",
"main": "main.js",
"scripts": {

View file

@ -148,7 +148,7 @@ export class FullScreenModal extends Modal {
if (url) {
let type = 'image';
const isYoutubeUrl = getYoutubeId(url) !== null;
const isYoutubeUrl = getYoutubeId(url) !== null && !Platform.isIosApp;
if (isYoutubeUrl) {
type = 'youtube';
} else {
@ -240,6 +240,10 @@ export class FullScreenModal extends Modal {
'--mv-gallery-thumbnail-width': `${width}px`
});
if (this.plugin.settings.galleryWaterfall) {
galleryContent.addClass('waterfall');
}
galleryContent.toggleClass('is-hidden', this.openType !== 'command');
galleryContent.addEventListener('click', (e) => {
@ -373,7 +377,7 @@ export class FullScreenModal extends Modal {
cls: 'mv-full-iframe',
attr: {
frameborder: '0',
allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share',
allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture',
allowfullscreen: 'true'
}
});
@ -1294,7 +1298,7 @@ export class FullScreenModal extends Modal {
cls: 'mv-full-iframe',
attr: {
frameborder: '0',
allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share',
allow: 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture',
allowfullscreen: 'true'
}
});

View file

@ -83,6 +83,7 @@ interface ContainerInfo {
addButtonEnabled: boolean;
gridSize: string;
paginationEnabled: number;
waterfall?: boolean;
}
interface MediaUrlsData {
@ -152,6 +153,7 @@ export class GalleryBlock {
let gridSize = this.plugin.settings.galleryGridSize || 'medium';
let paginationEnabled = this.plugin.settings.itemsPerPage || 0; // 設定變數以決定是否開啟分頁功能
let filterKeyword: string | null = null; // 新增搜尋關鍵字
let waterfall = this.plugin.settings.galleryWaterfall || false;
// 產生基於內容的唯一識別碼
const galleryId = 'gallery-' + this.hashString(content.trim());
@ -267,6 +269,8 @@ export class GalleryBlock {
continue;
}
// 檢查是否為容器標題設定
const containerTitleMatch = trimmedLine.match(/^title:\s*(.+)$/);
if (containerTitleMatch) {
@ -476,7 +480,7 @@ export class GalleryBlock {
const ytMatch = cleanUrl.match(youtubeRegex);
const ytId = ytMatch ? ytMatch[1] : null;
if (ytId) {
if (ytId && !Platform.isIosApp) {
if (!currentThumbnail) {
currentThumbnail = `https://img.youtube.com/vi/${ytId}/hqdefault.jpg`;
}
@ -678,7 +682,8 @@ export class GalleryBlock {
title: containerTitle,
addButtonEnabled: addButtonEnabled,
gridSize: gridSize,
paginationEnabled: paginationEnabled
paginationEnabled: paginationEnabled,
waterfall: waterfall
},
galleryId: galleryId,
sourcePath: sourcePath,
@ -687,9 +692,10 @@ export class GalleryBlock {
}
hashString(str: string) {
const normalized = str.replace(/\r\n/g, '\n');
let hash = 0;
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i);
for (let i = 0; i < normalized.length; i++) {
const char = normalized.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
@ -784,6 +790,9 @@ export class GalleryBlock {
// 根據 size 參數添加對應的 class 並設定寬度
galleryDiv.addClass(`size-${containerInfo.gridSize}`);
if (containerInfo.waterfall) {
galleryDiv.addClass('waterfall');
}
const propertyName = `galleryGridSize${containerInfo.gridSize.charAt(0).toUpperCase() + containerInfo.gridSize.slice(1)}` as keyof MediaViewSettings;
const width = this.plugin.settings[propertyName];
galleryDiv.setCssProps({
@ -849,13 +858,14 @@ export class GalleryBlock {
// 當 itemsPerPage 為 0 或項目數量不足時,顯示所有項目
if (itemsPerPage <= 0 || items.length <= itemsPerPage) {
// 顯示所有項目
const itemElements: HTMLElement[] = [];
items.forEach((item: GalleryItem, index: number) => {
if (item.type === 'note') {
const noteContainer = this.createNoteContainer(item, index, items, galleryId, sourcePath, mediaUrlsData.isFiltered);
galleryDiv.appendChild(noteContainer);
itemElements.push(noteContainer);
} else {
const mediaContainer = this.createMediaContainer(item, index, items, galleryId, sourcePath, mediaUrlsData.isFiltered);
galleryDiv.appendChild(mediaContainer);
itemElements.push(mediaContainer);
}
});
@ -885,8 +895,9 @@ export class GalleryBlock {
modal.open();
};
galleryDiv.appendChild(addContainer);
itemElements.push(addContainer);
}
this.renderGalleryItems(galleryDiv, itemElements);
} else {
// 使用分頁顯示
const totalPages = Math.ceil(items.length / itemsPerPage);
@ -1279,6 +1290,54 @@ export class GalleryBlock {
return container;
}
renderGalleryItems(galleryDiv: HTMLElement, itemElements: HTMLElement[]) {
if (galleryDiv.classList.contains('waterfall')) {
// 清理舊的 observer
const observedDiv = galleryDiv as HTMLElement & { _resizeObserver?: ResizeObserver };
if (observedDiv._resizeObserver) {
observedDiv._resizeObserver.disconnect();
}
const styleVal = galleryDiv.style.getPropertyValue('--mv-gallery-thumbnail-width');
let colWidth = parseInt(styleVal) || 150;
if (!colWidth) {
let size = 'medium';
if (galleryDiv.classList.contains('size-small')) size = 'small';
else if (galleryDiv.classList.contains('size-large')) size = 'large';
const propertyName = `galleryGridSize${size.charAt(0).toUpperCase() + size.slice(1)}` as keyof MediaViewSettings;
colWidth = (this.plugin.settings[propertyName] as number) || 150;
}
let currentCols = 0;
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const width = entry.contentRect.width;
if (width <= 0) continue;
const cols = Math.max(1, Math.floor(width / (colWidth + 2))); // 2px gap
if (cols !== currentCols) {
currentCols = cols;
galleryDiv.replaceChildren();
const colDivs: HTMLDivElement[] = [];
for (let c = 0; c < cols; c++) {
const colDiv = activeDocument.createElement('div');
colDiv.className = 'mvgb-waterfall-column';
galleryDiv.appendChild(colDiv);
colDivs.push(colDiv);
}
itemElements.forEach((el, idx) => {
colDivs[idx % cols].appendChild(el);
});
}
}
});
resizeObserver.observe(galleryDiv);
observedDiv._resizeObserver = resizeObserver;
} else {
galleryDiv.replaceChildren();
itemElements.forEach(el => galleryDiv.appendChild(el));
}
}
updateGalleryPage(galleryDiv: HTMLElement, items: GalleryItem[], page: number, itemsPerPage: number, sourcePath?: string, isFiltered?: boolean) {
const start = (page - 1) * itemsPerPage;
const end = start + itemsPerPage;
@ -1294,14 +1353,15 @@ export class GalleryBlock {
const galleryId = galleryDiv.getAttribute('data-gallery-id') || '';
// 新增新的項目
const itemElements: HTMLElement[] = [];
currentPageItems.forEach((item: GalleryItem, index: number) => {
const absoluteIndex = start + index;
if (item.type === 'note') {
const noteContainer = this.createNoteContainer(item, absoluteIndex, items, galleryId, sourcePath, isFiltered);
galleryDiv.appendChild(noteContainer);
itemElements.push(noteContainer);
} else {
const mediaContainer = this.createMediaContainer(item, absoluteIndex, items, galleryId, sourcePath, isFiltered);
galleryDiv.appendChild(mediaContainer);
itemElements.push(mediaContainer);
}
});
@ -1312,10 +1372,12 @@ export class GalleryBlock {
const placeholder = activeDocument.createElement('div');
placeholder.className = 'mv-media-thumbnail-container placeholder';
placeholder.addClass('is-placeholder-hidden'); // 隱藏但保持佔位
galleryDiv.appendChild(placeholder);
itemElements.push(placeholder);
}
}
this.renderGalleryItems(galleryDiv, itemElements);
// 更新分頁控制項
if (galleryDiv.parentElement) {
const paginationDiv = galleryDiv.parentElement.querySelector('.mvgb-pagination');
@ -1398,6 +1460,7 @@ export class GalleryBlock {
}
} else {
// 處理音樂檔案
container.addClass('mvgb-audio-thumbnail');
// 如果有自訂縮圖,使用縮圖顯示
if (media.thumbnail) {
const img = activeDocument.createElement('img');
@ -1691,7 +1754,7 @@ export class GalleryBlock {
const content = await this.app.vault.read(targetFile);
// 尋找包含當前 gallery ID 的 gallery 區塊
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
let galleryContent = '';
let matchPosition = { start: 0, end: 0 };
@ -1760,7 +1823,7 @@ export class GalleryBlock {
const content = await this.app.vault.read(targetFile);
// 尋找包含當前 gallery ID 的 gallery 區塊
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
let matchPosition = { start: 0, end: 0 };
@ -1849,7 +1912,7 @@ export class GalleryBlock {
}
const content = await this.app.vault.read(activeFile);
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
while ((match = galleryBlockRegex.exec(content)) !== null) {
@ -1929,7 +1992,7 @@ export class GalleryBlock {
}
const content = await this.app.vault.read(activeFile);
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
while ((match = galleryBlockRegex.exec(content)) !== null) {
@ -2007,7 +2070,7 @@ export class GalleryBlock {
}
const content = await this.app.vault.read(activeFile);
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
while ((match = galleryBlockRegex.exec(content)) !== null) {
@ -2080,7 +2143,7 @@ export class GalleryBlock {
if (activeFile) {
const content = await this.app.vault.read(activeFile);
const galleryBlockRegex = /```gallery\n([\s\S]*?)```/g;
const galleryBlockRegex = /```gallery\r?\n([\s\S]*?)```/g;
let match;
while ((match = galleryBlockRegex.exec(content)) !== null) {

View file

@ -3,37 +3,39 @@ import MediaViewPlugin from './main';
import { t } from './translations';
export interface MediaViewSettings {
showImageInfo: boolean;
allowMediaDeletion: boolean;
autoOpenFirstImage: boolean;
openMediaBrowserOnClick: boolean;
disableClickToOpenMediaOnGallery: boolean;
muteVideoOnOpen: boolean;
galleryGridSize: string;
galleryGridSizeSmall: number;
galleryGridSizeMedium: number;
galleryGridSizeLarge: number;
itemsPerPage: number;
insertAtEnd: boolean;
displayOriginalSize: boolean;
autoPlayInterval: number;
showImageInfo: boolean; // 是否顯示圖片資訊 (例如尺寸、檔案大小等)
allowMediaDeletion: boolean; // 是否允許刪除媒體檔案
autoOpenFirstImage: boolean; // 當打開畫廊時是否自動開啟第一張圖片
openMediaBrowserOnClick: boolean; // 點擊圖片時是否打開媒體瀏覽器
disableClickToOpenMediaOnGallery: boolean; // 是否停用在畫廊中點擊圖片以打開媒體瀏覽器的功能
muteVideoOnOpen: boolean; // 打開影片時是否預設靜音
galleryGridSize: string; // 畫廊網格大小的預設等級 (small, medium, large)
galleryGridSizeSmall: number; // 小網格的大小 (像素)
galleryGridSizeMedium: number; // 中網格的大小 (像素)
galleryGridSizeLarge: number; // 大網格的大小 (像素)
itemsPerPage: number; // 每頁顯示的項目數量 (0 代表不分頁)
insertAtEnd: boolean; // 新加入的媒體是否插入在最後面
displayOriginalSize: boolean; // 檢視時是否顯示原始尺寸
autoPlayInterval: number; // 自動播放的時間間隔 (秒0 代表不自動播放)
galleryWaterfall: boolean; // 畫廊是否使用瀑布流顯示圖片
}
export const DEFAULT_SETTINGS: MediaViewSettings = {
showImageInfo: true,
showImageInfo: true, // 預設顯示圖片資訊
allowMediaDeletion: false, // 預設不允許刪除圖片
autoOpenFirstImage: false, // 預設不自動打開第一張圖片
openMediaBrowserOnClick: true,
disableClickToOpenMediaOnGallery: false,
muteVideoOnOpen: false,
galleryGridSize: 'medium',
galleryGridSizeSmall: 100,
galleryGridSizeMedium: 150,
galleryGridSizeLarge: 200,
openMediaBrowserOnClick: true, // 預設點擊圖片時打開媒體瀏覽器
disableClickToOpenMediaOnGallery: false, // 預設不停用畫廊點擊事件
muteVideoOnOpen: false, // 預設不靜音
galleryGridSize: 'medium', // 預設畫廊網格大小為中
galleryGridSizeSmall: 100, // 預設小網格大小為 100px
galleryGridSizeMedium: 150, // 預設中網格大小為 150px
galleryGridSizeLarge: 200, // 預設大網格大小為 200px
itemsPerPage: 0, // 預設不分頁
insertAtEnd: true, // 預設插入在最後
displayOriginalSize: false, // 預設不顯示原始尺寸
autoPlayInterval: 0, // 預設不自動播放
galleryWaterfall: false, // 預設不使用瀑布流 (使用正方形裁剪)
};
export class MediaViewSettingTab extends PluginSettingTab {
@ -48,6 +50,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
const { containerEl } = this;
containerEl.empty();
// 1. 是否顯示圖片資訊 (例如尺寸、檔案大小等)
new Setting(containerEl)
.setName(t('show_image_info'))
.setDesc(t('show_image_info_desc'))
@ -58,6 +61,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 2. 是否允許在媒體檢視器中直接刪除媒體檔案
new Setting(containerEl)
.setName(t('allow_media_deletion'))
.setDesc(t('allow_media_deletion_desc'))
@ -68,6 +72,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 3. 打開畫廊時是否自動開啟第一張圖片
new Setting(containerEl)
.setName(t('auto_open_first_image'))
.setDesc(t('auto_open_first_image_desc'))
@ -78,6 +83,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 4. 檢視時是否以原始大小尺寸顯示
new Setting(containerEl)
.setName(t('display_original_size'))
.setDesc(t('display_original_size_desc'))
@ -88,6 +94,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 5. 點擊圖片時是否打開媒體瀏覽器
new Setting(containerEl)
.setName(t('click_to_open_media'))
.setDesc(t('click_to_open_media_desc'))
@ -98,7 +105,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 禁用 Gallery 內圖片的點擊事件 (以便相容其他圖片類插件)
// 6. 是否停用畫廊內的圖片點擊事件 (用以相容其他圖片類外掛)
new Setting(containerEl)
.setName(t('disable_click_to_open_media_on_gallery'))
.setDesc(t('disable_click_to_open_media_on_gallery_desc'))
@ -109,6 +116,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 7. 打開影片檔案時是否預設靜音播放
new Setting(containerEl)
.setName(t('mute_video_on_open'))
.setDesc(t('mute_video_on_open_desc'))
@ -119,6 +127,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 8. 投影片自動播放的間隔時間 (秒0 代表停用)
new Setting(containerEl)
.setName(t('auto_play_interval'))
.setDesc(t('auto_play_interval_desc'))
@ -131,6 +140,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 9. 畫廊網格大小的預設等級 (小、中、大)
new Setting(containerEl)
.setName(t('grid_size'))
.setDesc(t('grid_size_desc'))
@ -144,6 +154,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 10. 小尺寸網格的自訂寬度 (像素)
new Setting(containerEl)
.setName(t('grid_size_small_width'))
.setDesc(t('grid_size_small_width_desc'))
@ -156,6 +167,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 11. 中尺寸網格的自訂寬度 (像素)
new Setting(containerEl)
.setName(t('grid_size_medium_width'))
.setDesc(t('grid_size_medium_width_desc'))
@ -168,6 +180,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 12. 大尺寸網格的自訂寬度 (像素)
new Setting(containerEl)
.setName(t('grid_size_large_width'))
.setDesc(t('grid_size_large_width_desc'))
@ -180,6 +193,18 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 13. 畫廊圖片是否使用瀑布流顯示
new Setting(containerEl)
.setName(t('gallery_waterfall'))
.setDesc(t('gallery_waterfall_desc'))
.addToggle(toggle => toggle
.setValue(this.plugin.settings.galleryWaterfall)
.onChange(async (value) => {
this.plugin.settings.galleryWaterfall = value;
await this.plugin.saveSettings();
}));
// 14. 畫廊分頁設定,每頁顯示的項目數量 (0 代表不啟用分頁)
new Setting(containerEl)
.setName(t('items_per_page'))
.setDesc(t('items_per_page_desc'))
@ -192,6 +217,7 @@ export class MediaViewSettingTab extends PluginSettingTab {
await this.plugin.saveSettings();
}));
// 15. 媒體檔案的插入位置 (最前面或最後面)
new Setting(containerEl)
.setName(t('insert_position'))
.addDropdown(dropdown => {

View file

@ -99,7 +99,11 @@ const TRANSLATIONS: Translations = {
'gallery_size': 'Gallery 尺寸',
'gallery_size_desc': '選擇 Gallery 中圖片的顯示大小',
'gallery_add_button': '顯示上傳按鈕',
'gallery_add_button_desc': '是否在 Gallery 中顯示上傳圖片的按鈕'
'gallery_add_button_desc': '是否在 Gallery 中顯示上傳圖片的按鈕',
'gallery_original_ratio': '原始比例顯示',
'gallery_original_ratio_desc': '開啟後圖片將以原始比例顯示,不限制為正方形',
'gallery_waterfall': '瀑布流顯示',
'gallery_waterfall_desc': '開啟後圖片將以瀑布流格式顯示'
},
'en': {
// Notifications
@ -181,7 +185,11 @@ const TRANSLATIONS: Translations = {
'gallery_size': 'Gallery size',
'gallery_size_desc': 'Choose the display size of images in the gallery',
'gallery_add_button': 'Show upload button',
'gallery_add_button_desc': 'Whether to show the upload button in the gallery'
'gallery_add_button_desc': 'Whether to show the upload button in the gallery',
'gallery_original_ratio': 'Display original ratio',
'gallery_original_ratio_desc': 'When enabled, images will be displayed in their original ratio instead of square',
'gallery_waterfall': 'Waterfall Layout',
'gallery_waterfall_desc': 'When enabled, images will be displayed in a waterfall (masonry) layout'
},
'zh': {
// 通知信息
@ -263,7 +271,11 @@ const TRANSLATIONS: Translations = {
'gallery_size': '相册尺寸',
'gallery_size_desc': '选择相册中图片的显示大小',
'gallery_add_button': '显示上传按钮',
'gallery_add_button_desc': '是否在相册中显示上传图片的按钮'
'gallery_add_button_desc': '是否在相册中显示上传图片的按钮',
'gallery_original_ratio': '原始比例顯示',
'gallery_original_ratio_desc': '開啟後圖片將以原始比例顯示,不限制為正方形',
'gallery_waterfall': '瀑布流顯示',
'gallery_waterfall_desc': '開啟後圖片將以瀑布流格式顯示'
},
'ja': {
// 通知メッジ
@ -341,6 +353,10 @@ const TRANSLATIONS: Translations = {
'gallery_size': 'ギャラリーサイズ',
'gallery_size_desc': 'ギャラリー内の画像表示サイズを選択',
'gallery_add_button': 'アップロードボタンを表示',
'gallery_add_button_desc': 'ギャラリーにアップロードボタンを表示するかどうか'
'gallery_add_button_desc': 'ギャラリーにアップロードボタンを表示するかどうか',
'gallery_original_ratio': '元の比率で表示',
'gallery_original_ratio_desc': '有効にすると、画像は正方形ではなく元の比率で表示されます',
'gallery_waterfall': 'ウォーターフォール表示',
'gallery_waterfall_desc': '有効にすると、画像はウォーターフォール(メーソンリー)レイアウトで表示されます'
},
};

View file

@ -122,8 +122,9 @@
.mv-video-indicator {
position: absolute;
top: 8px;
left: 8px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 32px;
height: 32px;
background: rgba(0, 0, 0, 0.6);
@ -184,7 +185,7 @@
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
background: rgba(0, 0, 0, 0.75);
z-index: 1000;
overflow-x: hidden;
overflow-y: hidden;
@ -195,7 +196,7 @@
}
.mv-full-media-view.is-thumbnail-open {
background: rgba(0, 0, 0, 0.7);
background: rgba(0, 0, 0, 0.75);
}
.mv-full-media-view.is-scroll-x {
@ -437,6 +438,45 @@
border-radius: 8px;
}
.mvgb-media-gallery-grid.waterfall,
.mvgb-media-gallery-grid.waterfall.size-small,
.mvgb-media-gallery-grid.waterfall.size-medium,
.mvgb-media-gallery-grid.waterfall.size-large {
display: flex;
flex-direction: row;
align-items: flex-start;
gap: 15px;
padding: 15px;
}
.mvgb-waterfall-column {
display: flex;
flex-direction: column;
flex: 1;
gap: 15px;
min-width: 0;
}
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container {
aspect-ratio: auto;
width: 100%;
}
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container.mvgb-note-thumbnail,
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container.mvgb-audio-thumbnail,
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container.mvgb-add-media-button,
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container.placeholder {
aspect-ratio: 1;
}
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container > img,
.mvgb-media-gallery-grid.waterfall .mv-media-thumbnail-container > video {
width: 100%;
height: auto;
object-fit: cover;
display: block;
}
.mvgb-gallery-controls {
display: flex;
justify-content: center;
@ -617,6 +657,15 @@
object-fit: cover;
}
.mv-gallery-content.waterfall .mv-media-thumbnail-container img,
.mv-gallery-content.waterfall .mv-media-thumbnail-container video {
object-fit: contain;
}
.mv-gallery-content.waterfall .mv-media-thumbnail-container {
background: transparent;
}
.mv-media-thumbnail-container.is-placeholder-hidden {
visibility: hidden;
}