summaryrefslogtreecommitdiff
path: root/web/js
diff options
context:
space:
mode:
Diffstat (limited to 'web/js')
-rw-r--r--web/js/app.js3
-rw-r--r--web/js/keyboard.js1
-rw-r--r--web/js/player.js27
3 files changed, 29 insertions, 2 deletions
diff --git a/web/js/app.js b/web/js/app.js
index 9c769c9..13cc824 100644
--- a/web/js/app.js
+++ b/web/js/app.js
@@ -1,7 +1,7 @@
import { API } from './api.js';
import { initKeyboard } from './keyboard.js';
import { initSelection, clearSelection, select, selectByElement, next, prev, currentIndex, currentElement, navUp, navDown, navLeft, navRight } from './selection.js';
-import { initPlayer, togglePlay, toggleFullscreen, toggleMinimize, toggleDetach, exitFullscreenIfNeeded, currentMediaId, currentMediaInfo, hasLoadedMedia, isPlaybackActive, seekRelative, selectAndPlay, zoomIn as playerZoomIn, zoomOut as playerZoomOut, toggleSlideshow as playerToggleSlideshow, isImageMode as playerIsImageMode } from './player.js';
+import { initPlayer, togglePlay, toggleFullscreen, toggleMinimize, toggleDetach, exitFullscreenIfNeeded, toggleCrop, currentMediaId, currentMediaInfo, hasLoadedMedia, isPlaybackActive, seekRelative, selectAndPlay, zoomIn as playerZoomIn, zoomOut as playerZoomOut, toggleSlideshow as playerToggleSlideshow, isImageMode as playerIsImageMode } from './player.js';
import { initSearch, focusSearch, trigger as triggerSearch, parseQuery } from './search.js';
import { initShuffle, toggle as toggleShuffle, isOn as isShuffle } from './shuffle.js';
import { initThemes } from './themes.js';
@@ -134,6 +134,7 @@ async function initApp() {
mediaInfo: () => toggleMediaInfo(),
fullscreen: () => toggleFullscreen(),
toggleMinimize: () => toggleMinimize(),
+ toggleCrop: () => toggleCrop(),
escape: () => { exitFullscreenIfNeeded(); closeLightbox(); const el = currentElement(); if (el) el.classList.remove('selected'); closeAllModals(); },
shuffle: () => { toggleShuffle(); loadMedia(); },
share: () => shareSelected(),
diff --git a/web/js/keyboard.js b/web/js/keyboard.js
index 951e573..dc3eb4e 100644
--- a/web/js/keyboard.js
+++ b/web/js/keyboard.js
@@ -214,6 +214,7 @@ export function initKeyboard(handlers) {
break;
case 'C': handlers.toggleMinimize?.(e); break;
case 'f': handlers.fullscreen?.(e); break;
+ case 'c': handlers.toggleCrop?.(e); break;
case 'Escape': handlers.escape?.(e); break;
case 'Backspace': handlers.backspace?.(e); break;
case 'r': handlers.shuffle?.(e); break;
diff --git a/web/js/player.js b/web/js/player.js
index 6da8954..fea4a19 100644
--- a/web/js/player.js
+++ b/web/js/player.js
@@ -21,6 +21,7 @@ let isPanning = false;
let panStart = { x: 0, y: 0 };
let slideshowTimer = null;
let slideshowPausedUntil = 0;
+let cropMode = false;
const els = () => ({
video: document.getElementById('media-video'),
@@ -47,6 +48,7 @@ const els = () => ({
volume: document.getElementById('volume-slider'),
timeElapsed: document.getElementById('time-elapsed'),
timeTotal: document.getElementById('time-total'),
+ cropIndicator: document.getElementById('crop-indicator'),
});
export function initPlayer(options = {}) {
@@ -134,6 +136,16 @@ export function initPlayer(options = {}) {
e.video.addEventListener('loadedmetadata', updateFloatingSize);
+ document.addEventListener('fullscreenchange', () => {
+ const p = e.player;
+ if (!p) return;
+ if (!document.fullscreenElement) {
+ p.classList.remove('crop-mode');
+ cropMode = false;
+ if (e.cropIndicator) e.cropIndicator.classList.add('hidden');
+ }
+ });
+
function setupVideoDebug(m) {
const events = ['loadstart','loadeddata','loadedmetadata','canplay','canplaythrough','playing','waiting','stalled','suspend','error','abort','emptied','ended'];
events.forEach(event => {
@@ -521,10 +533,23 @@ function updateMinimizedTitle() {
export function exitFullscreenIfNeeded() {
if (document.fullscreenElement) {
document.exitFullscreen().catch(() => {});
- els().player?.classList.remove('is-fullscreen');
+ const p = els().player;
+ if (p) p.classList.remove('is-fullscreen', 'crop-mode');
+ cropMode = false;
+ const ind = els().cropIndicator;
+ if (ind) ind.classList.add('hidden');
}
}
+export function toggleCrop() {
+ const e = els();
+ if (!e.player) return;
+ if (!document.fullscreenElement) return;
+ cropMode = !cropMode;
+ e.player.classList.toggle('crop-mode', cropMode);
+ if (e.cropIndicator) e.cropIndicator.classList.toggle('hidden', !cropMode);
+}
+
function startProgressTimer() {
stopProgressTimer();
if (!reportProgress) return;