diff --git a/contrib/aura-clock/src/StudioClock.svelte b/contrib/aura-clock/src/StudioClock.svelte index 44cd0368ed15c502ba8da8aca5a6e3cc570ff83e..a6b32c4d01602b5254a4b0b679cda105cdac9c12 100644 --- a/contrib/aura-clock/src/StudioClock.svelte +++ b/contrib/aura-clock/src/StudioClock.svelte @@ -1,7 +1,10 @@ <script> import { onMount } from 'svelte'; export let apiUrl = "http://localhost:3333/api/v1"; - + export let stationName = "Studio Clock"; + export let stationLogo = "https://gitlab.servus.at/aura/meta/-/raw/master/images/aura-logo.png"; + export let stationLogoSize = "100px"; + export let noScheduleMessage = "Nothing scheduled!"; let time = new Date(); let queryCurrent = "/clock"; @@ -40,9 +43,15 @@ async function fetchApi(query) { - let response = await fetch(apiUrl+query); + let response; let data; + try { + response = await fetch(apiUrl+query); + } catch { + throw new Error("Cannot connect to Engine!"); + } + try { data = await response.json(); } catch(e) { @@ -65,7 +74,7 @@ let t = time - Date.parse(info.track_start); t = parseInt(t/1000); - timeLeft = info.track.duration - t - 4; + timeLeft = info.track.duration - t - 3; /* FIXME improve timings in coordination with scheduler/trackservice/LQS */ console.log("Current Data", info); } return ""; @@ -99,7 +108,7 @@ function displayShowName(show) { let name = "" if (show == null || show.name == null) { - name = '<span class="error">No show scheduled!</span>'; + name = '<span class="error">'+noScheduleMessage+'</span>'; } else { name = show.name; } @@ -138,6 +147,8 @@ function isActive(entry, currentTrack) { if (currentTrack != null && entry.id == currentTrack.id) { + // Scroll to current playlist entry + location.hash = "#current-playlist-entry"; return true; } return false; @@ -148,13 +159,36 @@ </script> <style> + + #station-header { + width: 100%; + height: 50px; + /* margin: 20px 100px; */ + padding: 40px 100px; + } + + #station-name { + margin: 0; + font-size: 3em; + line-height: 80px; + } + + #station-logo { + align-content: left; + text-align: right; + margin: 0 40px 0 10px; + opacity: 0.5; + filter: invert(100%); + } + #studio-clock { width: calc(100% - 200px); - margin:100px; + height: calc(100% - 500px); + margin: 100px; display: -webkit-flex; display: -ms-flexbox; display: flex; - border: 2px solid #333; + /* border: 2px solid #333; */ flex-direction: row; } @@ -165,7 +199,7 @@ #right-column { width: 70%; - padding: 25px; + padding: 25px 25px 25px 50px; } #current-schedule, @@ -173,20 +207,66 @@ margin: 0 0 40px 20px; } + #next-schedule { + background-color:rgb(24, 24, 24); + margin-right: 20px; + padding: 12px; + } + + #current-schedule .schedule-title { + color: #ccc; + font-size: 3.5em; + } + #next-schedule .schedule-title { + color: gray !important; + font-size: 2em; + } + #playlist { border: 2px solid #333; margin: 20px 20px 40px 20px; padding: 10px; + height: calc(80% - 100px); + overflow-y: auto; + scroll-behavior: smooth; + background-color: #111; + display: flex; + align-items: center; + } + + #playlist::-webkit-scrollbar-track + { + border-radius: 10px; + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: rgb(77, 73, 73); + } + + #playlist::-webkit-scrollbar + { + width: 12px; + background-color: rgb(0, 0, 0); + } + + #playlist::-webkit-scrollbar-thumb + { + border-radius: 10px; + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3); + background-color: rgb(34, 32, 32); } .playlist-entry { - font-size: 1.4em; + font-size: 1.5em; padding-left: 53px; } + #current-track * { + font-size: 1.75em; + /* margin: 20% 0; */ + } + .play-icon, .track-time-left { - margin: 12px; + margin: 25px 50px; } .is-active { @@ -194,38 +274,53 @@ padding-left: 0; } - .is-active::before { - content: "\00a0\00a0â–¶\00a0\00a0"; + .is-active .track-title::before { + content: "\00a0\00a0â–¶\00a0\00a0\00a0"; font-size: larger; color: green; } + .is-active .track-time-left { + color: rgb(43, 241, 36); + background-color: #222; + padding: 5px 15px; + } + + .error { + font-size: 1.3em; + color:red; + height:100%; + display : flex; + align-items : center; + justify-content: center; + } + svg { width: 100%; height: 100%; } .clock-face { - stroke: #333; - fill: white; + stroke: rgb(66, 66, 66); + fill: black; } .minor { - stroke: #999; + stroke: rgb(132, 132, 132); stroke-width: 0.5; } .major { - stroke: #333; + stroke: rgb(162, 162, 162); stroke-width: 1; } .hour { - stroke: #333; + stroke: rgba(255, 255, 255, 0.705); } .minute { - stroke: #666; + stroke: rgba(255, 255, 255, 0.705); } .second, .second-counterweight { @@ -233,7 +328,7 @@ } .second-counterweight { - stroke-width: 3; + /* stroke-width: 3; */ } footer { @@ -241,9 +336,30 @@ text-align: center; font-size: 0.8em; color: gray; + opacity: 0.5; } + + footer a { + color: gray; + text-decoration: underline; + } + + footer #aura-logo { + /* opacity: 0.5; */ + filter: invert(100%); + width: 75px; + margin: 0 0 20px 0; + } + </style> + + +<div id="station-header"> + <img id="station-logo" src="{stationLogo}" style="width:{stationLogoSize}" alt="Radio Station" align="left" /> + <h1 id="station-name">{stationName}</h1> +</div> + <div id="studio-clock"> <div id="left-column" class="column"> <svg viewBox='-50 -50 100 100'> @@ -306,9 +422,9 @@ <div id="current-schedule"> <h1 class="schedule-title">{@html displayShowName(value.current.show)} {displayShowSchedule(value.current)}</h1> - <div class="schedule-details"> - <b>Type:</b> {value.current.type}, <b>Host:</b> {value.current.host}</div> - </div> + <!-- <div class="schedule-details"> + <b>Type:</b> {value.current.show.type}, <b>Host:</b> {value.current.show.host}</div>--> + </div> <div id="playlist"> {#if value.current.playlist} @@ -316,7 +432,7 @@ {#each value.current.playlist.entries as entry, index} {#if isActive(entry, value.track)} - <li class="playlist-entry is-active"> + <li id="current-playlist-entry" class="playlist-entry is-active"> <!-- <span class="play-icon">▶</span> --> <span class="track-title">{displayTitle(entry)}</span> <span class="track-time-left">({formatTime(timeLeft)})</span> @@ -335,28 +451,29 @@ </ol> {:else} - <div id="current-track"> + <div id="current-track" class="is-active"> <h2> - <span class="track-title is-active">{displayTitle(value.track)}</span> - <span class="track-time-left">({formatTime(timeLeft)})</span> + <span class="track-title">{displayTitle(value.track)}</span> + <span class="track-time-left">{formatTime(timeLeft)}</span> </h2> </div> {/if} </div> <div id="next-schedule"> - <h2 class="schedule-title">Next: {@html displayShowName(value.next.show)} {displayShowSchedule(value)}</h2> - <div class="schedule-details"> - <b>Type:</b> {value.next.type}, <b>Host:</b> {value.next.host} - </div> + <h3 class="schedule-title">Next: {@html displayShowName(value.next.show)} {displayShowSchedule(value)}</h3> </div> {/if} {:catch error} - <p style="color:red">{error}</p> + <div class="error"><p>{error}</p></div> {/await} </div> </div> -<footer>Studio Clock is powered by <a href="https://gitlab.servus.at/autoradio">Aura Engine</a></footer> \ No newline at end of file +<footer> + <a href="https://gitlab.servus.at/aura/meta"><img id="aura-logo" src="https://gitlab.servus.at/aura/meta/-/raw/master/images/aura-logo.png" alt="Aura Logo" /></a> + <br/> + Studio Clock is powered by <a href="https://gitlab.servus.at/autoradio">Aura Engine</a> +</footer> \ No newline at end of file