diff --git a/js/shared/darkthemelegacysupport.js b/js/shared/darkthemelegacysupport.js index 04a2b683f..dc24d4607 100644 --- a/js/shared/darkthemelegacysupport.js +++ b/js/shared/darkthemelegacysupport.js @@ -5,14 +5,14 @@ * later. See the COPYING file. * * @author Pauli Järvinen - * @copyright Pauli Järvinen 2022 + * @copyright Pauli Järvinen 2022, 2023 */ OCA.Music = OCA.Music || {}; /** @namespace */ -OCA.Music.DarkThemeLegacySupport = { - applyOnElement: function(element) { +OCA.Music.DarkThemeLegacySupport = class { + static applyOnElement(element) { if (getComputedStyle(element).getPropertyValue('--background-invert-if-dark') == '') { // The property is not available => Nextcloud < 25 or ownCloud. diff --git a/js/shared/dummyaudio.js b/js/shared/dummyaudio.js index 0f59c4391..5673045b2 100644 --- a/js/shared/dummyaudio.js +++ b/js/shared/dummyaudio.js @@ -5,19 +5,19 @@ * later. See the COPYING file. * * @author Pauli Järvinen - * @copyright Pauli Järvinen 2022 + * @copyright Pauli Järvinen 2022, 2023 */ OCA.Music = OCA.Music || {}; /** @namespace */ -OCA.Music.DummyAudio = { +OCA.Music.DummyAudio = class { /** * Get 6 seconds of low-quality MP3 white noise in base64 format. Audio shorter than 5 s might not be * enough to activate the mediaSession integration on all browsers, as wouldn't a completely silent audio. */ - getData: function() { + static getData() { return 'data:audio/mpeg;base64,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'; } }; \ No newline at end of file diff --git a/js/shared/gaplessplayer.js b/js/shared/gaplessplayer.js index bea9c3d1e..ae299fbe1 100644 --- a/js/shared/gaplessplayer.js +++ b/js/shared/gaplessplayer.js @@ -5,133 +5,137 @@ * later. See the COPYING file. * * @author Pauli Järvinen - * @copyright Pauli Järvinen 2022 + * @copyright Pauli Järvinen 2022, 2023 */ OCA.Music = OCA.Music || {}; -OCA.Music.GaplessPlayer = function() { - let m_self = this; - let m_currentPlayer = new OCA.Music.PlayerWrapper(); - let m_nextPlayer = new OCA.Music.PlayerWrapper(); - _.extend(this, OC.Backbone.Events); +OCA.Music.GaplessPlayer = class { + #currentPlayer = new OCA.Music.PlayerWrapper(); + #nextPlayer = new OCA.Music.PlayerWrapper(); - function propagateEvent(eventName, arg) { - // propagate events only for the currently active instance - if (this === m_currentPlayer) { - m_self.trigger(eventName, arg, this.getUrl()); - } + constructor() { + _.extend(this, OC.Backbone.Events); + this.#setupEventPropagation(this.#currentPlayer); + this.#setupEventPropagation(this.#nextPlayer); } - m_currentPlayer.on('all', propagateEvent); - m_nextPlayer.on('all', propagateEvent); + #setupEventPropagation(player) { + let self = this; + player.on('all', function(eventName, arg) { + // propagate events only for the currently active instance + if (player === self.#currentPlayer) { + self.trigger(eventName, arg, player.getUrl()); + } + }); + } - this.play = function() { - m_currentPlayer.play(); - }; + play() { + this.#currentPlayer.play(); + } - this.pause = function() { - m_currentPlayer.pause(); - }; + pause() { + this.#currentPlayer.pause(); + } - this.stop = function() { - m_currentPlayer.stop(); - }; + stop() { + this.#currentPlayer.stop(); + } - this.isPlaying = function() { - return m_currentPlayer.isPlaying(); - }; + isPlaying() { + return this.#currentPlayer.isPlaying(); + } - this.seekingSupported = function() { - return m_currentPlayer.seekingSupported(); - }; + seekingSupported() { + return this.#currentPlayer.seekingSupported(); + } - this.seekMsecs = function(msecs) { - m_currentPlayer.seekMsecs(msecs); - }; + seekMsecs(msecs) { + this.#currentPlayer.seekMsecs(msecs); + } - this.seek = function(ratio) { - m_currentPlayer.seek(ratio); - }; + seek(ratio) { + this.#currentPlayer.seek(ratio); + } - this.seekForward = function(msecs /*optional*/) { - m_currentPlayer.seekForward(msecs); - }; + seekForward(msecs /*optional*/) { + this.#currentPlayer.seekForward(msecs); + } - this.seekBackward = function(msecs /*optional*/) { - m_currentPlayer.seekForward(msecs); - }; + seekBackward(msecs /*optional*/) { + this.#currentPlayer.seekForward(msecs); + } - this.playPosition = function() { - return m_currentPlayer.playPosition(); - }; + playPosition() { + return this.#currentPlayer.playPosition(); + } - this.setVolume = function(percentage) { - m_currentPlayer.setVolume(percentage); - m_nextPlayer.setVolume(percentage); - }; + setVolume(percentage) { + this.#currentPlayer.setVolume(percentage); + this.#nextPlayer.setVolume(percentage); + } - this.playbackRateAdjustible = function() { - return m_currentPlayer.playbackRateAdjustible(); - }; + playbackRateAdjustible() { + return this.#currentPlayer.playbackRateAdjustible(); + } - this.setPlaybackRate = function(rate) { - m_currentPlayer.setPlaybackRate(rate); - m_nextPlayer.setPlaybackRate(rate); - }; + setPlaybackRate(rate) { + this.#currentPlayer.setPlaybackRate(rate); + this.#nextPlayer.setPlaybackRate(rate); + } - this.canPlayMime = function(mime) { - return m_currentPlayer.canPlayMime(mime); - }; + canPlayMime(mime) { + return this.#currentPlayer.canPlayMime(mime); + } - this.isReady = function() { - return m_currentPlayer.isReady(); - }; + isReady() { + return this.#currentPlayer.isReady(); + } - this.getDuration = function() { - return m_currentPlayer.getDuration(); - }; + getDuration() { + return this.#currentPlayer.getDuration(); + } - this.getBufferPercent = function() { - return m_currentPlayer.getBufferPercent(); - }; + getBufferPercent() { + return this.#currentPlayer.getBufferPercent(); + } - this.getUrl = function() { - return m_currentPlayer.getUrl(); - }; + getUrl() { + return this.#currentPlayer.getUrl(); + } - this.fromUrl = function(url, mime) { - swapPlayer(); + fromUrl(url, mime) { + this.#swapPlayer(); - if (m_currentPlayer.getUrl() != url) { - m_currentPlayer.fromUrl(url, mime); + if (this.#currentPlayer.getUrl() != url) { + this.#currentPlayer.fromUrl(url, mime); } else { // The player already has the correct URL loaded or being loaded. Ensure the playing starts from the // beginning and fire the relevant events. - if (m_currentPlayer.isReady()) { - m_self.trigger('ready', undefined, url); + if (this.#currentPlayer.isReady()) { + this.trigger('ready', undefined, url); } - if (m_currentPlayer.getDuration() > 0) { - m_self.trigger('duration', m_currentPlayer.getDuration(), url); + if (this.#currentPlayer.getDuration() > 0) { + this.trigger('duration', this.#currentPlayer.getDuration(), url); } - m_currentPlayer.seek(0); - if (m_currentPlayer.getBufferPercent() > 0) { - m_self.trigger('buffer', m_currentPlayer.getBufferPercent(), url); + this.#currentPlayer.seek(0); + if (this.#currentPlayer.getBufferPercent() > 0) { + this.trigger('buffer', this.#currentPlayer.getBufferPercent(), url); } } - }; + } - this.fromExtUrl = function(url, isHls) { - m_currentPlayer.fromExtUrl(url, isHls); - }; + fromExtUrl(url, isHls) { + this.#currentPlayer.fromExtUrl(url, isHls); + } - this.prepareUrl = function(url, mime) { - if (m_nextPlayer.getUrl() != url) { - m_nextPlayer.fromUrl(url, mime); + prepareUrl(url, mime) { + if (this.#nextPlayer.getUrl() != url) { + this.#nextPlayer.fromUrl(url, mime); } - }; + } - function swapPlayer() { - [m_currentPlayer, m_nextPlayer] = [m_nextPlayer, m_currentPlayer]; + #swapPlayer() { + [this.#currentPlayer, this.#nextPlayer] = [this.#nextPlayer, this.#currentPlayer]; } }; diff --git a/js/shared/utils.js b/js/shared/utils.js index 41d4f6795..e866e9a1e 100644 --- a/js/shared/utils.js +++ b/js/shared/utils.js @@ -5,37 +5,37 @@ * later. See the COPYING file. * * @author Pauli Järvinen - * @copyright Pauli Järvinen 2018 - 2022 + * @copyright Pauli Järvinen 2018 - 2023 */ OCA.Music = OCA.Music || {}; /** @namespace */ -OCA.Music.Utils = { +OCA.Music.Utils = class { /** * Originally in ownCloud and in Nextcloud up to version 13, the #app-content element acted as the main scroll container. * Nextcloud 14 changed this so that the document became the main scrollable container, and this needed some adjustments * to the Music app. Then, Nextcloud 25 changed this back to the original system. */ - getScrollContainer: function() { + static getScrollContainer() { const appContent = $('#app-content'); return (appContent.css('overflow-y') === 'auto') ? appContent : $(window.document); - }, + } /** * Nextcloud versions up to 13 and all ownCloud versions use the "legacy layout structure" which requires some * adjustments on our side, too. */ - isLegacyLayout: function() { + static isLegacyLayout() { return $('#content-wrapper').length > 0; - }, + } /** * Check if the given HTML element is any kind of text input element. * Refactored version of the original source at https://stackoverflow.com/a/38795917 */ - isTextEntryElement: function(element) { + static isTextEntryElement(element) { let tagName = element.tagName.toLowerCase(); if (tagName === 'textarea') { return true; @@ -48,54 +48,54 @@ OCA.Music.Utils = { } else { return false; } - }, + } /** * Get the selected locale of the user from Nextcloud/ownCloud personal settings */ - getLocale: function() { + static getLocale() { return OC.getLocale().replaceAll('_', '-'); // OC returns e.g. 'en_US' but the javascript APIs expect 'en-US' - }, + } /** * Capitalizes the firts character of the given string */ - capitalize: function(str) { + static capitalize(str) { return str && str[0].toUpperCase() + str.slice(1); - }, + } /** * Convert string to boolean */ - parseBoolean: function(value) { + static parseBoolean(value) { value = String(value).toLowerCase(); const falsyValues = ['false', 'no', 'off', '0', 'undefined', 'null']; return falsyValues.indexOf(value) < 0; - }, + } /** * Creates a track title from the file name, dropping the file extension and any * track number possibly found from the beginning of the file name. */ - titleFromFilename: function(filename) { + static titleFromFilename(filename) { // parsing logic is ported form parseFileName in utility/scanner.php let match = filename.match(/^((\d+)\s*[.-]\s+)?(.+)\.(\w{1,4})$/); return match ? match[3] : filename; - }, + } /** * Given a file base name, returns the "stem" i.e. the name without extension */ - dropFileExtension: function(filename) { + static dropFileExtension(filename) { return filename.replace(/\.[^/.]+$/, ''); - }, + } /** * Join two path fragments together, ensuring there is a single '/' between them. * The first fragment may or may not end with '/' and the second fragment may or may * not start with '/'. */ - joinPath: function(first, second) { + static joinPath(first, second) { if (first.endsWith('/')) { first = first.slice(0, -1); } @@ -103,14 +103,14 @@ OCA.Music.Utils = { second = second.slice(1); } return first + '/' + second; - }, + } /** * Format the given seconds value as play time. The format includes hours if and only if the * given input time is more than one hour. The output format looks like 1:01 or 1:01:01. * That is, unlike the rest of the parts, the part before the first ':' does not have a leading zero. */ - formatPlayTime: function(input_s) { + static formatPlayTime(input_s) { // Format the given integer with two digits, prepending with a leading zero if necessary let fmtTwoDigits = function(integer) { return (integer < 10 ? '0' : '') + integer; @@ -125,34 +125,34 @@ OCA.Music.Utils = { } else { return minutes + ':' + fmtTwoDigits(seconds); } - }, + } /** * Given a date-and-time string in UTC, return it in local timezone following the locale settings * of the user (from Nextcloud/ownCloud personal settings). */ - formatDateTime: function(timestamp) { + static formatDateTime(timestamp) { if (!timestamp) { return null; } else { let date = new Date(timestamp + 'Z'); return date.toLocaleString(OCA.Music.Utils.getLocale()); } - }, + } /** * Format a file size given as bytes in human-readable format. * Source: https://stackoverflow.com/a/20732091/4348850 */ - formatFileSize: function(size) { + static formatFileSize(size) { let i = (size == 0) ? 0 : Math.floor( Math.log(size) / Math.log(1024) ); return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'KiB', 'MiB', 'GiB', 'TiB'][i]; - }, + } /** * Format baud rate given as bit per second to kilobits per second with integer precission */ - formatBitrate: function(bitsPerSecond) { + static formatBitrate(bitsPerSecond) { return (bitsPerSecond / 1000).toFixed() + ' kbps'; } }; \ No newline at end of file