diff --git a/assets/js/_helpers.js b/assets/js/_helpers.js index ad7dcb914..3f79bf542 100644 --- a/assets/js/_helpers.js +++ b/assets/js/_helpers.js @@ -145,16 +145,14 @@ window.helpers = window.helpers || { }, options.retry_timeout); }; - if (callbacks.onError) - callbacks._onError = callbacks.onError; + callbacks._onError = callbacks.onError; callbacks.onError = function (xhr) { if (callbacks._onError) callbacks._onError(); retry(); }; - if (callbacks.onTimeout) - callbacks._onTimeout = callbacks.onTimeout; + callbacks._onTimeout = callbacks.onTimeout; callbacks.onTimeout = function (xhr) { if (callbacks._onTimeout) callbacks._onTimeout(); diff --git a/assets/js/player.js b/assets/js/player.js index 5bff7ee55..832c7d0e4 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -42,9 +42,10 @@ embed_url = location.origin + '/embed/' + video_data.id + embed_url.search; var save_player_pos_key = 'save_player_pos'; videojs.Vhs.xhr.beforeRequest = function(options) { - if (options.uri.includes('videoplayback') && options.uri.includes('local=true')) { - options.uri = options.uri + '?local=true'; - } + // set local if requested not videoplayback + if (!options.uri.includes('videoplayback')) + if (!options.uri.includes('local=true')) + options.uri += '?local=true'; return options; }; @@ -402,7 +403,7 @@ if (!video_data.params.listen && video_data.params.annotations) { }); } -function increase_volume(delta) { +function change_volume(delta) { const curVolume = player.volume(); const newVolume = curVolume + delta; helpers.clamp(newVolume, 0, 1); @@ -565,10 +566,10 @@ addEventListener('keydown', function (e) { case 'MediaStop': action = stop; break; case 'ArrowUp': - if (isPlayerFocused) action = increase_volume.bind(this, 0.1); + if (isPlayerFocused) action = change_volume.bind(this, 0.1); break; case 'ArrowDown': - if (isPlayerFocused) action = increase_volume.bind(this, -0.1); + if (isPlayerFocused) action = change_volume.bind(this, -0.1); break; case 'm': @@ -659,7 +660,7 @@ addEventListener('keydown', function (e) { var wheelMove = event.wheelDelta || -event.detail; var volumeSign = Math.sign(wheelMove); - increase_volume(volumeSign * 0.05); // decrease/increase by 5% + change_volume(volumeSign * 0.05); // decrease/increase by 5% } player.on('mousewheel', mouseScroll); diff --git a/assets/js/themes.js b/assets/js/themes.js index 7e86e9ac0..eedf63a45 100644 --- a/assets/js/themes.js +++ b/assets/js/themes.js @@ -2,58 +2,39 @@ var toggle_theme = document.getElementById('toggle_theme'); toggle_theme.href = 'javascript:void(0)'; +const STORAGE_KEY_THEME = 'dark_mode'; +const THEME_DARK = 'dark'; +const THEME_LIGHT = 'light'; +const THEME_SYSTEM = ''; + +// TODO: theme state controlled by system toggle_theme.addEventListener('click', function () { - var dark_mode = document.body.classList.contains('light-theme'); - - set_mode(dark_mode); - helpers.storage.set('dark_mode', dark_mode ? 'dark' : 'light'); - + const isDarkTheme = helpers.storage.get(STORAGE_KEY_THEME) === THEME_DARK; + setTheme(isDarkTheme ? THEME_LIGHT : THEME_DARK); helpers.xhr('GET', '/toggle_theme?redirect=false', {}, {}); }); -// Handles theme change event caused by other tab -addEventListener('storage', function (e) { - if (e.key === 'dark_mode') { - update_mode(e.newValue); - } -}); -addEventListener('DOMContentLoaded', function () { - const dark_mode = document.getElementById('dark_mode_pref').textContent; - // Update storage if dark mode preference changed on preferences page - helpers.storage.set('dark_mode', dark_mode); - update_mode(dark_mode); +// Ask system about dark theme +var systemDarkTheme = matchMedia('(prefers-color-scheme: dark)'); +systemDarkTheme.addListener(function () { + // Ignore system events if theme set manually + if (!helpers.storage.get(STORAGE_KEY_THEME)) + setTheme(THEME_SYSTEM); }); -var darkScheme = matchMedia('(prefers-color-scheme: dark)'); -var lightScheme = matchMedia('(prefers-color-scheme: light)'); +/** @param {THEME_DARK|THEME_LIGHT|THEME_SYSTEM} theme */ +function setTheme(theme) { + if (theme !== THEME_SYSTEM) + helpers.storage.set(STORAGE_KEY_THEME, theme); -darkScheme.addListener(scheme_switch); -lightScheme.addListener(scheme_switch); - -function scheme_switch (e) { - // ignore this method if we have a preference set - if (helpers.storage.get('dark_mode')) return; - - if (!e.matches) return; - - if (e.media.includes('dark')) { - set_mode(true); - } else if (e.media.includes('light')) { - set_mode(false); - } -} - -function set_mode (bool) { - if (bool) { - // dark + if (theme === THEME_DARK || (theme === THEME_SYSTEM && systemDarkTheme.matches)) { toggle_theme.children[0].setAttribute('class', 'icon ion-ios-sunny'); document.body.classList.remove('no-theme'); document.body.classList.remove('light-theme'); document.body.classList.add('dark-theme'); } else { - // light toggle_theme.children[0].setAttribute('class', 'icon ion-ios-moon'); document.body.classList.remove('no-theme'); document.body.classList.remove('dark-theme'); @@ -61,18 +42,13 @@ function set_mode (bool) { } } -function update_mode (mode) { - if (mode === 'true' /* for backwards compatibility */ || mode === 'dark') { - // If preference for dark mode indicated - set_mode(true); - } - else if (mode === 'false' /* for backwards compatibility */ || mode === 'light') { - // If preference for light mode indicated - set_mode(false); - } - else if (document.getElementById('dark_mode_pref').textContent === '' && matchMedia('(prefers-color-scheme: dark)').matches) { - // If no preference indicated here and no preference indicated on the preferences page (backend), but the browser tells us that the operating system has a dark theme - set_mode(true); - } - // else do nothing, falling back to the mode defined by the `dark_mode` preference on the preferences page (backend) -} +// Handles theme change event caused by other tab +addEventListener('storage', function (e) { + if (e.key === STORAGE_KEY_THEME) setTheme(e.newValue); +}); + +// Set theme from preferences on page load +addEventListener('DOMContentLoaded', function () { + const prefTheme = document.getElementById('dark_mode_pref').textContent; + setTheme(prefTheme); +}); diff --git a/assets/js/watch.js b/assets/js/watch.js index ff0f7822b..45492241b 100644 --- a/assets/js/watch.js +++ b/assets/js/watch.js @@ -102,13 +102,6 @@ function continue_autoplay(event) { } } -function number_with_separator(val) { - while (/(\d+)(\d{3})/.test(val.toString())) { - val = val.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2'); - } - return val; -} - function get_playlist(plid) { var playlist = document.getElementById('playlist'); @@ -248,9 +241,13 @@ function get_youtube_comments() {
'.supplant({ contentHtml: response.contentHtml, redditComments: video_data.reddit_comments_text, - commentsText: video_data.comments_text.supplant( - { commentCount: number_with_separator(response.commentCount) } - ) + commentsText: video_data.comments_text.supplant({ + // toLocaleString correctly splits number with local thousands separator. e.g.: + // '1,234,567.89' for user with English locale + // '1 234 567,89' for user with Russian locale + // '1.234.567,89' for user with Portuguese locale + commentCount: response.commentCount.toLocaleString() + }) }); comments.children[0].children[0].children[0].onclick = toggle_comments;