diff --git a/webapp/alpha/index.html b/webapp/alpha/index.html index e95fe86..c6ded55 100644 --- a/webapp/alpha/index.html +++ b/webapp/alpha/index.html @@ -242,8 +242,14 @@
-

Title: {{ (meta.title) ? meta.title : '' }}

-

Artist: {{ (meta.artist) ? meta.artist : '' }}

+

+ Title: + {{ (meta.title) ? meta.title : '' }} +

+

+ Artist: + {{ (meta.artist) ? meta.artist : '' }} +

Album: {{ (meta.album) ? meta.album : '' }}

Year: {{ (meta.year) ? meta.year : '' }}

@@ -256,11 +262,16 @@
- DJ + DJ
+
+
{{playerStats.replayGainPreGainDb}}db
+ RG +
+ diff --git a/webapp/alpha/m.js b/webapp/alpha/m.js index c0fd882..691f315 100644 --- a/webapp/alpha/m.js +++ b/webapp/alpha/m.js @@ -476,5 +476,45 @@ function downloadFileplaylist(el) { document.getElementById('downform').innerHTML = ''; } +function getArtistz(el) { + const artist = el.getAttribute('data-artist'); + programState.push({ + state: 'artist', + name: artist, + previousScroll: document.getElementById('filelist').scrollTop, + // previousSearch: document.getElementById('search_folders').value + }); + + getArtistsAlbums(artist) +} + +async function getArtistsAlbums(artist, cb) { + setBrowserRootPanel(false, 'Albums',); + // document.getElementById('directoryName').innerHTML = 'Artist: ' + artist; + document.getElementById('filelist').innerHTML = getLoadingSvg(); + + try { + const response = await MSTREAMAPI.artistAlbums(artist); + let albums = ''; + response.albums.forEach(value => { + const albumString = value.name ? value.name : 'SINGLES'; + // 'value.name === null ? artist : null' is some clever shit that only passes in artist info when the album is null + // This is so we get the singles for this artist + // If the album is specified, we don't want to limit by artist + albums += renderAlbum(value.name, value.name === null ? artist : null, albumString, value.album_art_file, value.year); + currentBrowsingList.push({ type: 'album', name: value.name, artist: artist, album_art_file: value.album_art_file }) + }); + + document.getElementById('filelist').innerHTML = albums; + + // update lazy load plugin + // ll.update(); + }catch (err) { + document.getElementById('filelist').innerHTML = '
Server call failed
'; + return boilerplateFailure(err); + } +} + + loadFileExplorer(); init(); \ No newline at end of file diff --git a/webapp/alpha/spa.css b/webapp/alpha/spa.css index 58cd9f9..d33c50e 100644 --- a/webapp/alpha/spa.css +++ b/webapp/alpha/spa.css @@ -452,7 +452,7 @@ body { .button-block-1 { margin-top: 8px; - width: 160px; + width: 180px; display: flex; } @@ -679,4 +679,27 @@ body { .fixed-action-btn { z-index: 4000 !important; +} + +#rg-pregain-info { + font-weight: 800; + font-size: 16px; + font-family: 'Jura', sans-serif; + width: 34px; + transition: opacity 0.25s; + text-align: right; +} + +#rg-status { + transition: opacity 0.25s; +} + +.rpg { + margin-right: 10px; + cursor: pointer; +} + +.auto-dj { + cursor: pointer; + margin-left: 10px; } \ No newline at end of file diff --git a/webapp/alpha/vp.js b/webapp/alpha/vp.js index b1e99b5..f1f9481 100644 --- a/webapp/alpha/vp.js +++ b/webapp/alpha/vp.js @@ -247,7 +247,6 @@ const VUEPLAYERCORE = (() => { } }); - new Vue({ el: '#mstream-player', data: { @@ -256,6 +255,19 @@ const VUEPLAYERCORE = (() => { positionCache: MSTREAMPLAYER.positionCache, meta: MSTREAMPLAYER.playerStats.metadata, lastVol: 100, + replayGainToggle: false + }, + created: function () { + if (typeof(Storage) !== "undefined") { + const localVol = localStorage.getItem("volume"); + if (localVol !== null && !isNaN(localVol)) { + MSTREAMPLAYER.changeVolume(parseInt(localVol)); + } + MSTREAMPLAYER.setReplayGainActive(localStorage.getItem("replayGain") == "true"); + + const rgPregain = Number(localStorage.getItem("replayGainPreGainDb")); + MSTREAMPLAYER.setReplayGainPreGainDb(rgPregain === NaN ? 0 : rgPregain); + } }, computed: { currentTime: function() { @@ -300,6 +312,9 @@ const VUEPLAYERCORE = (() => { let percentage = (x / rect.width) * 100; if (percentage > 100) { percentage = 100; } // It's possible to 'drag' the progress bar to get over 100 percent MSTREAMPLAYER.changeVolume(percentage); + if (typeof(Storage) !== "undefined") { + localStorage.setItem("volume", percentage); + } }, seekTo: function(event) { const rect = this.$refs.progressWrapper.getBoundingClientRect(); @@ -325,6 +340,17 @@ const VUEPLAYERCORE = (() => { toggleAutoDJ: function () { MSTREAMPLAYER.toggleAutoDJ(); }, + goToArtist: function() { + const el = document.createElement('DIV'); + el.setAttribute('data-artist', this.meta.artist); + getArtistz(el); + }, + goToAlbum: function() { + const el = document.createElement('DIV'); + el.setAttribute('data-album', this.meta.album); + el.setAttribute('data-year', this.meta.year); + getAlbumsOnClick(el); + }, toggleMute: function () { if (this.playerStats.volume === 0) { MSTREAMPLAYER.changeVolume(this.lastVol); @@ -332,7 +358,43 @@ const VUEPLAYERCORE = (() => { this.lastVol = this.playerStats.volume; MSTREAMPLAYER.changeVolume(0); } - } + }, + toggleReplayGain: function () { + // With a series of clicks, allow the user to first activate ReplayGain, then progress through a list of + // settings for the desired level of pre-gain, and then finally disable ReplayGain again. + if (replayGainInfoTimeout) { clearTimeout(replayGainInfoTimeout); } + + var pregainInfoElement = document.getElementById('rg-pregain-info') + var rgStatusElement = document.getElementById('rg-status') + + if (!this.playerStats.replayGain) { + MSTREAMPLAYER.setReplayGainPreGainDb(replayGainPreGainSettings[0]); + MSTREAMPLAYER.setReplayGainActive(true); + } else { + const settingsIdx = replayGainPreGainSettings.indexOf(this.playerStats.replayGainPreGainDb); + if (settingsIdx == -1 || settingsIdx >= replayGainPreGainSettings.length - 1) { + MSTREAMPLAYER.setReplayGainActive(false); + // pregainInfoElement.style.opacity = "0.0"; + // rgStatusElement.style.opacity = "1.0"; + this.replayGainToggle = false; + } else { + MSTREAMPLAYER.setReplayGainPreGainDb(replayGainPreGainSettings[settingsIdx + 1]); + } + } + + if (this.playerStats.replayGain) { + this.replayGainToggle = true; + + replayGainInfoTimeout = setTimeout(() => { + this.replayGainToggle = false; + }, 1000); + } + + if (typeof(Storage) !== "undefined") { + localStorage.setItem("replayGain", this.playerStats.replayGain); + localStorage.setItem("replayGainPreGainDb", this.playerStats.replayGainPreGainDb); + } + }, } });