@@ -25,7 +25,8 @@ class EdiromAudioPlayer extends HTMLElement {
2525 this . end = this . getAttribute ( 'end' ) ;
2626 this . playbackrate = this . getAttribute ( 'playbackrate' ) || 1 ;
2727 this . playbackmode = this . getAttribute ( 'playbackmode' ) || 'all' ;
28- this . displaymode = this . getAttribute ( 'displaymode' ) || 'controls-lg' ;
28+ this . progressbar = this . getAttribute ( 'progressbar' ) || 'false' ;
29+ this . playlist = this . getAttribute ( 'playlist' ) || 'false' ;
2930
3031 //Define a FontFace
3132 const font = new FontFace ( "Material Symbols Outlined" , "url(https://fonts.gstatic.com/s/materialsymbolsoutlined/v192/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOej.woff2)" , {
@@ -83,7 +84,7 @@ class EdiromAudioPlayer extends HTMLElement {
8384 * @returns {Array<string> } The list of observed attributes.
8485 */
8586 static get observedAttributes ( ) {
86- return [ 'track' , 'tracks' , 'height' , 'width' , 'state' , 'start' , 'end' , 'playbackrate' , 'playbackmode' , 'displaymode ' ] ;
87+ return [ 'track' , 'tracks' , 'height' , 'width' , 'state' , 'start' , 'end' , 'playbackrate' , 'playbackmode' , 'playlist' , 'progressbar '] ;
8788 }
8889
8990
@@ -162,9 +163,10 @@ class EdiromAudioPlayer extends HTMLElement {
162163 getPlayerHTML ( ) {
163164
164165 let playerInnerHTML ;
165- playerInnerHTML = this . getControlsHTML ( [ 'skip_previous' , 'play_arrow' , 'skip_next' , 'playlist_remove ' ] ) ;
166+ playerInnerHTML = this . getControlsHTML ( [ 'skip_previous' , 'play_arrow' , 'skip_next' , 'tune ' ] ) ;
166167 playerInnerHTML += this . getTimeHTML ( ) ;
167168 playerInnerHTML += this . getTracksHTML ( ) ;
169+ playerInnerHTML += this . getOverlayHTML ( ) ;
168170
169171 return '<div id="player" class="' + this . displaymode + '">' + playerInnerHTML + '</div>' ;
170172
@@ -215,6 +217,15 @@ class EdiromAudioPlayer extends HTMLElement {
215217 // Add icon to button
216218 buttonElem . innerHTML = '<span class="mso">' + button + '</span>' ;
217219
220+ // Add additional classes to buttons
221+ switch ( button ) {
222+ case 'tune' :
223+ buttonElem . classList . add ( 'toggleSettings' ) ;
224+ break ;
225+ default :
226+ break ;
227+ }
228+
218229 // Append button to controlsDiv
219230 controlsDiv . appendChild ( buttonElem ) ;
220231 } ) ;
@@ -255,6 +266,33 @@ class EdiromAudioPlayer extends HTMLElement {
255266 return '<div id="tracks">' + tracksHTML + '</div>' ;
256267 }
257268
269+ /**
270+ * Returns the HTML content for an overlay box that contains settings for changing the audio appearance.
271+ * @returns {string } The HTML content for the overlay box.
272+ */
273+ getOverlayHTML ( ) {
274+ let overlayHTML = `
275+ <div id="settingsOverlay" class="overlay">
276+ <div class="overlay-content">
277+ <span class="toggleSettings close-button" onclick="document.getElementById('settingsOverlay').style.display='none'">×</span>
278+ <div class="setting">
279+ <label for="playlist">Playlist</label>
280+ <input type="checkbox" id="playlistCheckbox" name="playlistCheckbox" value="showPlaylist">
281+ </div>
282+ <div class="setting">
283+ <label for="progress">Progress bar</label>
284+ <input type="checkbox" id="progressCheckbox" name="progressCheckbox" value="showProgress">
285+ </div>
286+ <div class="setting">
287+ <label for="speed">Playback rate <span id="currentPlaybackrate">1.0</span></label><br/>
288+ <input type="range" id="playbackrate-slider" name="playbackrate-slider" min="0.5" max="2" step="0.025" value="1">
289+ </div>
290+ </div>
291+ </div>
292+ ` ;
293+ return overlayHTML ;
294+ }
295+
258296 /**
259297 * Returns the CSS styles for the player.
260298 * @returns {string } The CSS styles for the player.
@@ -285,7 +323,11 @@ class EdiromAudioPlayer extends HTMLElement {
285323 #controls #fast_rewindButton {
286324 display: none;
287325 }
326+ #tracks{
327+ display: none;
328+ }
288329 #timeInfo {
330+ display: none;
289331 margin-top: 10px;
290332 }
291333 #timeInfo input {
@@ -322,6 +364,31 @@ class EdiromAudioPlayer extends HTMLElement {
322364 box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
323365 }
324366
367+ #settingsOverlay {
368+ display: none;
369+ position: fixed;
370+ width: 220px;
371+ padding-bottom: 20px;
372+ z-index: 1;
373+ background-color: #fff;
374+ border: 1px solid #ccc;
375+ font-size: .85em;
376+ font-family: Helvetica;
377+ color: #555;
378+ font-weight: bold;
379+ }
380+
381+ #settingsOverlay .close-button {
382+ position: absolute;
383+ top: 5px;
384+ right: 5px;
385+ font-size: 24px;
386+ cursor: pointer;
387+ }
388+
389+ #settingsOverlay .setting {
390+ margin: 20px 0px 0px 10px;
391+ }
325392
326393 /* height-dependent rules */
327394
@@ -418,59 +485,34 @@ class EdiromAudioPlayer extends HTMLElement {
418485 // handle playbackrate setting
419486 case 'playbackrate' :
420487 ( audioPlayer != null ) ? audioPlayer . playbackRate = newPropertyValue : console . log ( "Audio player not available" ) ;
488+ this . shadowRoot . querySelector ( '#currentPlaybackrate' ) . textContent = newPropertyValue ;
489+ this . shadowRoot . querySelector ( '#playbackrate-slider' ) . value = newPropertyValue ;
421490 break ;
422491
423- // handle playbackmode setting
424- case 'playbackmode' :
425-
492+ // handle progressbar setting
493+ case 'progressbar' :
494+ if ( this . shadowRoot . querySelector ( '#timeInfo' ) != null ) {
495+ if ( newPropertyValue == 'true' ) {
496+ this . shadowRoot . querySelector ( '#timeInfo' ) . style . display = 'block' ;
497+ this . shadowRoot . querySelector ( '#progressCheckbox' ) . checked = true ;
498+ } else {
499+ this . shadowRoot . querySelector ( '#timeInfo' ) . style . display = 'none' ;
500+ this . shadowRoot . querySelector ( '#progressCheckbox' ) . checked = false ;
501+ }
502+ }
426503 break ;
427504
428- // handle displaymode setting
429- case 'displaymode' :
430-
431- const tracksDiv = this . shadowRoot . querySelector ( '#tracks' ) ;
432- const sliderDiv = this . shadowRoot . querySelector ( '#timeInfo' ) ;
433- const tracksButton = this . shadowRoot . querySelector ( '#playlist_removeButton' ) ;
434-
435-
436- switch ( this . displaymode ) {
437- case 'hidden' :
438-
439- break ;
440- case 'controls-sm' :
441- if ( tracksDiv === null ) return ;
442- tracksDiv . style . display = 'none' ;
443- sliderDiv . style . display = 'none' ;
444- tracksButton . innerHTML = '<span class="mso">playlist_add</span>' ;
445-
446- break ;
447- case 'controls-md' :
448- if ( tracksDiv === null ) return ;
449- tracksDiv . style . display = 'none' ;
450- sliderDiv . style . display = 'block' ;
451- tracksButton . innerHTML = '<span class="mso">playlist_add</span>' ;
452- break ;
453- case 'controls-lg' :
454- if ( tracksDiv === null ) return ;
455- tracksDiv . style . display = 'block' ;
456- sliderDiv . style . display = 'block' ;
457- tracksButton . innerHTML = '<span class="mso">playlist_remove</span>' ;
458- break ;
459- case 'tracks-sm' :
460-
461- break ;
462- case 'tracks-md' :
463-
464- break ;
465- case 'tracks-lg' :
466-
467- break ;
468- default :
469-
470- console . log ( "Invalid displaymode: '" + this . displaymode + "'" ) ;
505+ // handle playlist setting
506+ case 'playlist' :
507+ if ( this . shadowRoot . querySelector ( '#tracks' ) != null ) {
508+ if ( newPropertyValue == 'true' ) {
509+ this . shadowRoot . querySelector ( '#tracks' ) . style . display = 'block' ;
510+ this . shadowRoot . querySelector ( '#playlistCheckbox' ) . checked = true ;
511+ } else {
512+ this . shadowRoot . querySelector ( '#tracks' ) . style . display = 'none' ;
513+ this . shadowRoot . querySelector ( '#playlistCheckbox' ) . checked = false ;
514+ }
471515 }
472-
473- break ;
474516
475517 // handle height setting
476518 case 'height' :
@@ -543,6 +585,25 @@ class EdiromAudioPlayer extends HTMLElement {
543585
544586 } ) ;
545587
588+ /**
589+ * Event listener for settings overlay
590+ * Listens to all elements with class .toggleSettings and toggles the display of the settings overlay
591+ */
592+ this . shadowRoot . querySelectorAll ( '.toggleSettings' ) . forEach ( el => {
593+ el . addEventListener ( 'click' , ( evt ) => {
594+ const overlay = this . shadowRoot . querySelector ( '#settingsOverlay' ) ;
595+
596+ // position overlay at lower right corner of tune button
597+ const tuneButton = this . shadowRoot . querySelector ( '#tuneButton' ) ;
598+ overlay . style . top = tuneButton . offsetTop + tuneButton . offsetHeight + 'px' ;
599+ overlay . style . left = tuneButton . offsetLeft + 'px' ;
600+
601+ // toggle display
602+ overlay . style . display = overlay . style . display === 'none' ? 'block' : 'none' ;
603+ } ) ;
604+ } ) ;
605+
606+
546607 /** Event listeners for audio player */
547608
548609 this . shadowRoot . querySelectorAll ( '#audioPlayer' ) . forEach ( el => {
@@ -627,14 +688,30 @@ class EdiromAudioPlayer extends HTMLElement {
627688 } ) ;
628689 } ) ;
629690
630- this . shadowRoot . querySelectorAll ( '#playlist_removeButton' ) . forEach ( el => {
631- el . addEventListener ( 'click' , ( evt ) => {
691+ /** Event listener for playbackrate slider */
692+ this . shadowRoot . querySelectorAll ( '#playbackrate-slider' ) . forEach ( el => {
693+ el . addEventListener ( 'input' , ( evt ) => {
694+ this . set ( 'playbackrate' , evt . target . value ) ;
695+ } ) ;
696+ } ) ;
697+
698+ /** Event listener for playlist checkbox */
699+ this . shadowRoot . querySelectorAll ( '#playlistCheckbox' ) . forEach ( el => {
700+ el . addEventListener ( 'change' , ( evt ) => {
632701 const tracksDiv = this . shadowRoot . querySelector ( '#tracks' ) ;
633- const tracksButton = this . shadowRoot . querySelector ( '#playlist_removeButton' ) ;
634- tracksButton . innerHTML = tracksDiv . style . display === 'none' ? '<span class="mso">playlist_remove</span>' : '<span class="mso">playlist_add</span>' ;
635- tracksDiv . style . display = tracksDiv . style . display === 'none' ? 'block' : 'none' ;
702+ tracksDiv . style . display = evt . target . checked ? 'block' : 'none' ;
703+ } ) ;
704+ } ) ;
705+
706+ /** Event listener for progress checkbox */
707+ this . shadowRoot . querySelectorAll ( '#progressCheckbox' ) . forEach ( el => {
708+ el . addEventListener ( 'change' , ( evt ) => {
709+ const progressSlider = this . shadowRoot . querySelector ( '#timeInfo' ) ;
710+ progressSlider . style . display = evt . target . checked ? 'block' : 'none' ;
636711 } ) ;
637712 } ) ;
713+
714+
638715
639716 }
640717}
0 commit comments