diff --git a/README.md b/README.md index 20f6c2d..50b72ba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Media Viewer -[中文](README_zhTW.md) | English | [日本語](README_ja.md) +English | [日本語](README_ja.md) | [中文](README_zhTW.md) ## Introduction diff --git a/README_ja.md b/README_ja.md index c3e6976..80b5891 100644 --- a/README_ja.md +++ b/README_ja.md @@ -1,6 +1,6 @@ # Media Viewer -[中文](README_zhTW.md) | [English](README.md) | 日本語 +[English](README.md) | 日本語 | [中文](README_zhTW.md) ## はじめに diff --git a/README_zhTW.md b/README_zhTW.md index 5a881c8..9e6b9d9 100644 --- a/README_zhTW.md +++ b/README_zhTW.md @@ -1,6 +1,6 @@ # Media Viewer -中文 | [English](README.md) | [日本語](README_ja.md) +[English](README.md) | [日本語](README_ja.md) | 中文 ## 介紹 diff --git a/manifest.json b/manifest.json index fc57a3c..5dfda22 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "mediaviewer", "name": "Media Viewer", - "version": "1.9.4", + "version": "1.9.5", "minAppVersion": "1.1.0", "description": "View and manage media files within your notes.", "author": "Devon22", diff --git a/package-lock.json b/package-lock.json index 4b83e94..71f1843 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "mediaviewer", - "version": "1.9.4", + "version": "1.9.5", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/package.json b/package.json index 4a7f8c9..5b695c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mediaviewer", - "version": "1.9.4", + "version": "1.9.5", "description": "This is a sample plugin for Obsidian (https://obsidian.md)", "main": "main.js", "scripts": { diff --git a/src/fullscreen.ts b/src/fullscreen.ts index bfb4b7d..2f8e392 100644 --- a/src/fullscreen.ts +++ b/src/fullscreen.ts @@ -23,6 +23,8 @@ export class FullScreenModal extends Modal { fullVideo: HTMLVideoElement; galleryCloseButton: HTMLButtonElement; handleWheel: ((event: WheelEvent) => void) | null; + autoPlayTimer: number | null; + isAutoPlaying: boolean; constructor(app: App, plugin: MediaViewPlugin, openType = 'command') { super(app); @@ -34,6 +36,8 @@ export class FullScreenModal extends Modal { this.openType = openType; this.modalEl.addClass('mv-media-viewer-modal'); this.handleWheel = null; //儲存滾輪事件處理程序 + this.autoPlayTimer = null; //儲存自動播放計時器 + this.isAutoPlaying = false; //自動播放狀態 } async scanMedia(): Promise { @@ -293,6 +297,12 @@ export class FullScreenModal extends Modal { return; } + // 記住當前的自動播放狀態 + const wasAutoPlaying = this.isAutoPlaying; + + // 清除現有的自動播放計時器(如果存在) + this.clearAutoPlayTimer(); + // 移除舊的資訊面板(如果存在) const oldInfo = this.fullMediaView.querySelector('.mv-image-info-panel'); if (oldInfo) oldInfo.remove(); @@ -325,9 +335,14 @@ export class FullScreenModal extends Modal { } // 顯示圖片資訊 - if (this.plugin.settings.showImageInfo || this.plugin.settings.allowMediaDeletion) { + if (this.plugin.settings.showImageInfo || this.plugin.settings.allowMediaDeletion || this.plugin.settings.autoPlayInterval > 0) { this.showImageInfo(media); } + + // 如果之前是自動播放狀態,則繼續自動播放 + if (wasAutoPlaying) { + this.startAutoPlay(); + } } async showImageInfo(media: Media) { @@ -348,6 +363,30 @@ export class FullScreenModal extends Modal { await this.deleteMedia(this.currentIndex); }; } + + // 添加自動播放按鈕(只在設定值不為 0 時顯示) + if (this.plugin.settings.autoPlayInterval > 0) { + const autoPlayButton = infoPanel.createEl('a', { + // 根據當前的自動播放狀態設定按鈕文字 + text: this.isAutoPlaying ? t('stop_auto_play') : t('auto_play'), + cls: 'mv-info-item', + attr: { + href: '#', + 'data-action': 'autoplay' // 新增 data-action 屬性以便於選取 + } + }); + autoPlayButton.onclick = (e) => { + e.preventDefault(); + e.stopPropagation(); + if (this.isAutoPlaying) { + this.stopAutoPlay(); + autoPlayButton.textContent = t('auto_play'); + } else { + this.startAutoPlay(); + autoPlayButton.textContent = t('stop_auto_play'); + } + }; + } if (this.plugin.settings.showImageInfo) { // 取得檔案名稱 @@ -392,6 +431,9 @@ export class FullScreenModal extends Modal { return; } + // 清除自動播放計時器 + this.stopAutoPlay(); + this.fullMediaView.style.display = 'none'; this.galleryCloseButton.style.display = 'flex'; this.isZoomed = false; @@ -531,21 +573,27 @@ export class FullScreenModal extends Modal { }; // 鍵盤事件 - this.scope.register(null, 'ArrowLeft', () => { - if (this.isImage || this.fullVideo.currentTime <= 0) { + this.scope.register(null, 'ArrowLeft', (evt) => { + if (evt.ctrlKey && !this.isImage && this.fullVideo) { + // Alt+左方向鍵:影片倒退 5 秒 + this.fullVideo.currentTime = Math.max(0, this.fullVideo.currentTime - 5); + evt.preventDefault(); + } else { + // 普通左方向鍵:切換到上一個媒體 this.currentIndex = (this.currentIndex - 1 + this.mediaUrls.length) % this.mediaUrls.length; this.showMedia(this.currentIndex); - } else { - this.fullVideo.currentTime -= 5; } }); - this.scope.register(null, 'ArrowRight', () => { - if (this.isImage || this.fullVideo.currentTime >= this.fullVideo.duration) { + this.scope.register(null, 'ArrowRight', (evt) => { + if (evt.ctrlKey && !this.isImage && this.fullVideo) { + // Alt+右方向鍵:影片前進 5 秒 + this.fullVideo.currentTime = Math.min(this.fullVideo.duration, this.fullVideo.currentTime + 5); + evt.preventDefault(); + } else { + // 普通右方向鍵:切換到下一個媒體 this.currentIndex = (this.currentIndex + 1) % this.mediaUrls.length; this.showMedia(this.currentIndex); - } else { - this.fullVideo.currentTime += 5; } }); @@ -730,7 +778,56 @@ export class FullScreenModal extends Modal { } } + // 啟動自動播放功能 + startAutoPlay() { + // 清除現有計時器(如果存在) + this.clearAutoPlayTimer(); + + // 檢查是否啟用自動播放 + const interval = this.plugin.settings.autoPlayInterval; + if (interval > 0) { + // 設定新的計時器 + this.autoPlayTimer = window.setTimeout(() => { + // 播放下一張圖片 + const nextIndex = (this.currentIndex + 1) % this.mediaUrls.length; + this.showMedia(nextIndex); + }, interval * 1000) as number; // 轉換為毫秒,並確保類型為 number + + // 設定自動播放狀態為開啟 + this.isAutoPlaying = true; + + // 更新按鈕文字(如果存在) + const autoPlayButton = this.fullMediaView.querySelector('.mv-info-item[data-action="autoplay"]'); + if (autoPlayButton) { + autoPlayButton.textContent = t('stop_auto_play'); + } + } + } + + // 停止自動播放 + stopAutoPlay() { + this.clearAutoPlayTimer(); + this.isAutoPlaying = false; + + // 更新按鈕文字(如果存在) + const autoPlayButton = this.fullMediaView.querySelector('.mv-info-item[data-action="autoplay"]'); + if (autoPlayButton) { + autoPlayButton.textContent = t('auto_play'); + } + } + + // 清除自動播放計時器 + clearAutoPlayTimer() { + if (this.autoPlayTimer) { + window.clearTimeout(this.autoPlayTimer); + this.autoPlayTimer = null; + } + } + onClose() { + // 確保關閉時清除計時器 + this.stopAutoPlay(); + const { contentEl } = this; contentEl.empty(); } diff --git a/src/galleryBlockGenerate.ts b/src/galleryBlockGenerate.ts index 4e73823..2edb777 100644 --- a/src/galleryBlockGenerate.ts +++ b/src/galleryBlockGenerate.ts @@ -116,10 +116,10 @@ export class GalleryBlockGenerateModal extends Modal { .setCta() .onClick(() => { const galleryBlock = ['```gallery']; - galleryBlock.push(`title: ${this.title}`); - galleryBlock.push(`size: ${this.size}`); - galleryBlock.push(`addButton: ${this.addButton}`); - galleryBlock.push(`pagination: ${this.pagination}`); + if(this.title !== '') galleryBlock.push(`title: ${this.title}`); + if(this.size !== 'medium') galleryBlock.push(`size: ${this.size}`); + if(this.addButton) galleryBlock.push(`addButton: ${this.addButton}`); + if(this.pagination > 0) galleryBlock.push(`pagination: ${this.pagination}`); if (this.selectedText) galleryBlock.push(this.selectedText); galleryBlock.push('```\n'); diff --git a/src/settings.ts b/src/settings.ts index ad03e67..47ff7b0 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -16,12 +16,13 @@ export interface MediaViewSettings { itemsPerPage: number; insertAtEnd: boolean; displayOriginalSize: boolean; + autoPlayInterval: number; } export const DEFAULT_SETTINGS: MediaViewSettings = { showImageInfo: true, - allowMediaDeletion: false, - autoOpenFirstImage: false, + allowMediaDeletion: false, // 預設不允許刪除圖片 + autoOpenFirstImage: false, // 預設不自動打開第一張圖片 openMediaBrowserOnClick: true, disableClickToOpenMediaOnGallery: false, muteVideoOnOpen: false, @@ -29,9 +30,10 @@ export const DEFAULT_SETTINGS: MediaViewSettings = { galleryGridSizeSmall: 100, galleryGridSizeMedium: 150, galleryGridSizeLarge: 200, - itemsPerPage: 0, + itemsPerPage: 0, // 預設不分頁 insertAtEnd: true, // 預設插入在最後 - displayOriginalSize: false, + displayOriginalSize: false, // 預設不顯示原始尺寸 + autoPlayInterval: 0, // 預設不自動播放 }; export class MediaViewSettingTab extends PluginSettingTab { @@ -117,6 +119,18 @@ export class MediaViewSettingTab extends PluginSettingTab { await this.plugin.saveSettings(); })); + new Setting(containerEl) + .setName(t('auto_play_interval')) + .setDesc(t('auto_play_interval_desc')) + .addText(text => text + .setPlaceholder('0') + .setValue(String(this.plugin.settings.autoPlayInterval)) + .onChange(async (value) => { + const numValue = parseInt(value); + this.plugin.settings.autoPlayInterval = isNaN(numValue) ? 0 : Math.max(0, numValue); + await this.plugin.saveSettings(); + })); + new Setting(containerEl) .setName(t('grid_size')) .setDesc(t('grid_size_desc')) diff --git a/src/translations.ts b/src/translations.ts index e855159..2f7e847 100644 --- a/src/translations.ts +++ b/src/translations.ts @@ -37,6 +37,8 @@ const TRANSLATIONS: Translations = { 'drag_and_drop': '拖曳圖片到這裡或點擊選擇檔案', 'paste_from_clipboard': '從剪貼簿貼上圖片', 'add_image': '新增圖片', + 'auto_play': '自動播放', + 'stop_auto_play': '停止播放', // 設定 'allow_media_deletion': '允許刪除媒體檔案', @@ -73,6 +75,8 @@ const TRANSLATIONS: Translations = { 'insert_position': '圖片插入位置', 'insert_at_end': '插入在最後', 'insert_at_start': '插入在最前', + 'auto_play_interval': '自動播放間隔', + 'auto_play_interval_desc': '設定自動播放的間隔秒數(0:不自動播放)', // 命令 'open_media_viewer': '打開媒體瀏覽器', @@ -103,6 +107,8 @@ const TRANSLATIONS: Translations = { 'drag_and_drop': 'Drag and drop images here or click to select files', 'paste_from_clipboard': 'Paste image from clipboard', 'add_image': 'Add image', + 'auto_play': 'Auto Play', + 'stop_auto_play': 'Stop Auto Play', // Settings 'allow_media_deletion': 'Allow media deletion', @@ -139,6 +145,8 @@ const TRANSLATIONS: Translations = { 'insert_position': 'Image insert position', 'insert_at_end': 'Insert at end', 'insert_at_start': 'Insert at start', + 'auto_play_interval': 'Auto play interval', + 'auto_play_interval_desc': 'Set the interval in seconds for auto play (0: no auto play)', // Commands 'open_media_viewer': 'Open media viewer', @@ -169,6 +177,8 @@ const TRANSLATIONS: Translations = { 'drag_and_drop': '拖曳图片到这裡或点击选择图片', 'paste_from_clipboard': '从剪贴板粘贴图片', 'add_image': '新增图片', + 'auto_play': '自动播放', + 'stop_auto_play': '停止播放', // 设置 'allow_media_deletion': '允许删除媒体文件', @@ -205,6 +215,8 @@ const TRANSLATIONS: Translations = { 'insert_position': '图片插入位置', 'insert_at_end': '插入在最后', 'insert_at_start': '插入在最前', + 'auto_play_interval': '自动播放间隔', + 'auto_play_interval_desc': '设置自动播放的间隔秒数(0:不自动播放)', // 命令 'open_media_viewer': '打开媒体浏览器', diff --git a/versions.json b/versions.json index 88d1e35..3ede861 100644 --- a/versions.json +++ b/versions.json @@ -1,3 +1,3 @@ { - "1.9.4": "1.1.0" + "1.9.5": "1.1.0" } \ No newline at end of file