Lock screen to landscape on fullscreen, unlock on exit

On mobile, entering fullscreen now also locks the screen orientation to
landscape via the Screen Orientation API. Exiting fullscreen unlocks it,
allowing the device to return to portrait. Applied to both the video
player and audio player. Gracefully ignored on browsers that don't
support screen.orientation.lock (e.g. iOS Safari).

Also includes the playlist auto-scroll fix (committed separately).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ghassan 2026-05-16 23:14:28 +03:00
parent 6e7d5d178a
commit 4887d0c517
5 changed files with 23 additions and 15 deletions

View File

@ -1118,6 +1118,10 @@ document.addEventListener('fullscreenchange', () => {
const exit = fsBtn.querySelector('.ytp-svg-fs-exit');
enter.style.display = isFullscreen ? 'none' : '';
exit.style.display = isFullscreen ? '' : 'none';
if (screen.orientation && screen.orientation.lock) {
if (isFullscreen) screen.orientation.lock('landscape').catch(function(){});
else screen.orientation.unlock();
}
});
// ── Theater mode ──────────────────────────────────────

View File

@ -513,6 +513,10 @@ document.addEventListener('fullscreenchange', () => {
wrap.classList.toggle('ytp-fullscreen', fs);
fsBtn.querySelector('.ytp-svg-fs-enter').style.display = fs ? 'none' : '';
fsBtn.querySelector('.ytp-svg-fs-exit').style.display = fs ? '' : 'none';
if (screen.orientation && screen.orientation.lock) {
if (fs) screen.orientation.lock('landscape').catch(function(){});
else screen.orientation.unlock();
}
});
// ── Keyboard shortcuts ────────────────────────────────────────

View File

@ -546,7 +546,7 @@
PL_CURRENT=d.id;
plRender();
plHighlight(d.id);
plHighlight(d.id, true);
if(pushHist!==false) history.pushState({plVideoId:d.id,url:url},'',url);
plSwapContent(url);
@ -584,12 +584,11 @@
} catch(e){ console.warn('plSwapContent',e); }
}
function plHighlight(activeId){
function plHighlight(activeId, scroll){
document.querySelectorAll('.sidebar-video-card[data-pl-id]').forEach(function(c){
c.classList.toggle('current-video',parseInt(c.dataset.plId)===activeId);
});
var a=document.querySelector('.sidebar-video-card.current-video');
if(a) a.scrollIntoView({behavior:'smooth',block:'nearest'});
if(scroll){ var a=document.querySelector('.sidebar-video-card.current-video'); if(a) a.scrollIntoView({behavior:'smooth',block:'nearest'}); }
}
function plRender(){
@ -628,7 +627,7 @@
var v=document.getElementById('videoPlayer');
if(v&&plLoop==='one') v.loop=true;
plRender();
plHighlight(PL_CURRENT);
plHighlight(PL_CURRENT, false);
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',plInit); else plInit();
})();

View File

@ -2619,7 +2619,7 @@
PL_CURRENT=d.id;
plRender();
plHighlight(d.id);
plHighlight(d.id, true);
if(pushHist!==false) history.pushState({plVideoId:d.id,url:url},'',url);
plSwapContent(url);
@ -2657,12 +2657,11 @@
} catch(e){ console.warn('plSwapContent',e); }
}
function plHighlight(activeId){
function plHighlight(activeId, scroll){
document.querySelectorAll('.sidebar-video-card[data-pl-id]').forEach(function(c){
c.classList.toggle('current-video',parseInt(c.dataset.plId)===activeId);
});
var a=document.querySelector('.sidebar-video-card.current-video');
if(a) a.scrollIntoView({behavior:'smooth',block:'nearest'});
if(scroll){ var a=document.querySelector('.sidebar-video-card.current-video'); if(a) a.scrollIntoView({behavior:'smooth',block:'nearest'}); }
}
function plRender(){
@ -2700,7 +2699,7 @@
var v=document.getElementById('videoPlayer');
if(v&&plLoop==='one') v.loop=true;
plRender();
plHighlight(PL_CURRENT);
plHighlight(PL_CURRENT, false);
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',plInit); else plInit();
})();

View File

@ -566,7 +566,7 @@
PL_CURRENT = d.id;
if(audio&&plLoop==='one') audio.loop=true; else if(audio) audio.loop=false;
plRender();
plHighlight(d.id);
plHighlight(d.id, true);
// history
if(pushHist!==false) history.pushState({plVideoId:d.id,url:url},'',url);
@ -615,12 +615,14 @@
}
// ── sidebar highlight ────────────────────────────────────
function plHighlight(activeId) {
function plHighlight(activeId, scroll) {
document.querySelectorAll('.sidebar-video-card[data-pl-id]').forEach(function(c){
c.classList.toggle('current-video', parseInt(c.dataset.plId)===activeId);
});
var active=document.querySelector('.sidebar-video-card.current-video');
if(active) active.scrollIntoView({behavior:'smooth',block:'nearest'});
if(scroll) {
var active=document.querySelector('.sidebar-video-card.current-video');
if(active) active.scrollIntoView({behavior:'smooth',block:'nearest'});
}
}
// ── render control button states ─────────────────────────
@ -658,7 +660,7 @@
var a=document.getElementById('audioEl');
if(a&&plLoop==='one') a.loop=true;
plRender();
plHighlight(PL_CURRENT);
plHighlight(PL_CURRENT, false);
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',plInit); else plInit();
})();