Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • dev-old
  • dev-old-david
  • develop
  • lars-tests
  • master
  • master-old
  • topic/filesystem-fallbacks
  • topic/tank_connection
  • topic/tank_connection_david
  • user/equinox/docker
10 results

Target

Select target project
  • aura/engine
  • hermannschwaerzler/engine
  • sumpfralle/aura-engine
3 results
Select Git revision
  • 122-synchronized-ci
  • feat-use-docker-main-tag
  • fix-aura-sysuser
  • fix-broken-pipe-153
  • fix-docker-release
  • fix-push-latest-with-tag
  • fix-streamchannel-retries
  • gitlab-templates
  • improve-test-coverage-137
  • improve-test-coverage-143
  • main
  • orm-less-scheduling
  • remove-mailer
  • update-changelog-alpha3
  • virtual-timeslots-131
  • 1.0.0-alpha1
  • 1.0.0-alpha2
  • 1.0.0-alpha3
  • 1.0.0-alpha4
  • 1.0.0-alpha5
20 results
Show changes
Showing
with 886 additions and 0 deletions
html, body {
position: relative;
width: 100%;
height: 100%;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
input[type="range"] {
height: 0;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Aura Engine - Studio Clock</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/aura-clock-bundle.css'>
<script defer src='/build/aura-clock-bundle.js'></script>
</head>
<body style="background-color: black;">
<aura-clock
name="Studio Clock"
logo="https://o94.at/themes/custom/radio_orange/logo1.png"
logosize="180px"
api="http://localhost:3333/api/v1/"
css="http://localhost:3333/css/aura.css">
</aura-clock>
</body>
</html>
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/aura-clock-bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file - better for performance
css: css => {
css.write('public/build/aura-clock-bundle.css');
},
customElement: true
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
<svelte:options tag="aura-clock"/>
<main bind:this={rootElement}></main>
<script>
import { onMount } from 'svelte';
export let css = "";
export let api = "http://localhost:3333/api/v1";
export let name = "Studio Clock";
export let logo = "https://gitlab.servus.at/aura/meta/-/raw/master/images/aura-logo.png";
export let logosize = "100px";
export let noScheduleMessage = "Nothing scheduled!";
let time = new Date();
let queryCurrent = "/clock";
let rootElement;
let data;
let currentTrack = null;
let timeLeft;
// these automatically update when `time`
// changes, because of the `$:` prefix
$: hours = time.getHours();
$: minutes = time.getMinutes();
$: seconds = time.getSeconds();
data = fetchApi(queryCurrent);
onMount(() => {
const interval = setInterval(() => {
time = new Date();
timeLeft -= 1;
if (timeLeft <= 0 || data == null) {
currentTrack = null;
data = null;
data = fetchApi(queryCurrent);
}
}, 1000);
return () => {
clearInterval(interval);
};
});
async function fetchApi(query) {
let response;
let data;
try {
response = await fetch(api+query);
} catch {
throw new Error("Cannot connect to Engine!");
}
try {
data = await response.json();
} catch(e) {
console.log("Error while converting response to JSON!", e);
throw new Error(response.statusText);
}
if (response.ok) {
return data;
} else {
console.log("Error:", data);
throw new Error(data.message);
}
}
function initComponent(info) {
/* Load external CSS */
if (css != null)
loadExternalCss(rootElement, css);
/* Set currently loaded data */
if (currentTrack == null && info != null && info.track != null) {
currentTrack = info;
let t = time - Date.parse(info.track_start);
t = parseInt(t/1000);
timeLeft = info.track.duration - t - 3; /* FIXME improve timings in coordination with scheduler/trackservice/LQS */
console.log("Current Data", info);
}
return "";
}
function displayTitle(track) {
if (track != null) {
let artist = "";
if (track.artist != "")
artist = track.artist + " - ";
return artist + track.title;
}
return "";
}
function formatTime(seconds) {
if (seconds != null && Number.isInteger(seconds)) {
let d = new Date(null);
d.setSeconds(seconds);
let s;
if (seconds > 3600)
s = d.toISOString().substr(11, 8);
else
s = d.toISOString().substr(14, 5);
return s;
}
return "";
}
function displayShowName(show) {
let name = ""
if (show == null || show.name == null) {
name = '<span class="error">'+noScheduleMessage+'</span>';
} else {
name = show.name;
}
return name;
}
function displayShowSchedule(schedule) {
let str = "";
if (schedule != null && schedule.schedule_start != null) {
let scheduleStart = ""
let scheduleEnd = "";
if (schedule.schedule_start != null) {
let scheduleStart = new Date(Date.parse(schedule.schedule_start));
scheduleStart = scheduleStart.toLocaleTimeString(navigator.language, {
hour: '2-digit',
minute:'2-digit'
});
str = "(" + scheduleStart;
}
if (schedule.schedule_end != null) {
scheduleEnd = new Date(Date.parse(schedule.schedule_end));
scheduleEnd = scheduleEnd.toLocaleTimeString(navigator.language, {
hour: '2-digit',
minute:'2-digit'
});
str = str + " - " + scheduleEnd + ")";
} else {
str += ")";
}
}
return str;
}
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;
}
function loadExternalCss(root, file) {
let element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", file);
root.appendChild(element);
}
</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);
height: calc(100% - 500px);
margin: 100px;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/* border: 2px solid #333; */
flex-direction: row;
}
#left-column {
width: 30%;
padding: 25px;
}
#right-column {
width: 70%;
padding: 25px 25px 25px 50px;
}
#current-schedule,
#next-schedule {
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.9em;
padding-left: 53px;
}
#current-track * {
font-size: 1.5em;
}
.play-icon,
.track-time-left {
margin: 25px 50px;
}
.is-active {
color: green;
padding-left: 0;
}
.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: rgb(66, 66, 66);
fill: black;
}
.minor {
stroke: rgb(132, 132, 132);
stroke-width: 0.5;
}
.major {
stroke: rgb(162, 162, 162);
stroke-width: 1;
}
.hour {
stroke: rgba(255, 255, 255, 0.705);
}
.minute {
stroke: rgba(255, 255, 255, 0.705);
}
.second, .second-counterweight {
stroke: rgb(180,0,0);
}
.second-counterweight {
/* stroke-width: 3; */
}
footer {
width: 100%;
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="{logo}" style="width:{logosize}" alt="Radio Station" align="left" />
<h1 id="station-name">{name}</h1>
</div>
<div id="studio-clock">
<div id="left-column" class="column">
<svg viewBox='-50 -50 100 100'>
<circle class='clock-face' r='48'/>
<!-- markers -->
{#each [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55] as minute}
<line
class='major'
y1='35'
y2='45'
transform='rotate({30 * minute})'
/>
{#each [1, 2, 3, 4] as offset}
<line
class='minor'
y1='42'
y2='45'
transform='rotate({6 * (minute + offset)})'
/>
{/each}
{/each}
<!-- hour hand -->
<line
class='hour'
y1='2'
y2='-20'
transform='rotate({30 * hours + minutes / 2})'
/>
<!-- minute hand -->
<line
class='minute'
y1='4'
y2='-30'
transform='rotate({6 * minutes + seconds / 10})'
/>
<!-- second hand -->
<g transform='rotate({6 * seconds})'>
<line class='second' y1='10' y2='-38'/>
<line class='second-counterweight' y1='10' y2='2'/>
</g>
</svg>
</div>
<div id="right-column" class="column">
{#await data}
<div class="spinner-border mt-5" role="status">
<span class="sr-only">Loading...</span>
</div>
{:then value}
{initComponent(value)}
{#if value.current.show}
<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.show.type}, <b>Host:</b> {value.current.show.host}</div>-->
</div>
<div id="playlist">
{#if value.current.playlist}
<ol>
{#each value.current.playlist.entries as entry, index}
{#if isActive(entry, value.track)}
<li id="current-playlist-entry" class="playlist-entry is-active">
<!-- <span class="play-icon">&#9654;</span> -->
<span class="track-title">{displayTitle(entry)}</span>
<span class="track-time-left">({formatTime(timeLeft)})</span>
</li>
{:else}
<li class="playlist-entry">
<span class="track-title">{displayTitle(entry)}</span>
<span class="track-duration">({formatTime(entry.duration)})</span>
</li>
{/if}
{/each}
</ol>
{:else}
<div id="current-track" class="is-active">
<h2>
<span class="track-title">{displayTitle(value.track)}</span>
<span class="track-time-left">{formatTime(timeLeft)}</span>
</h2>
</div>
{/if}
</div>
<div id="next-schedule">
<h3 class="schedule-title">Next: {@html displayShowName(value.next.show)} {displayShowSchedule(value)}</h3>
</div>
{/if}
{:catch error}
<div class="error"><p>{error}</p></div>
{/await}
</div>
</div>
<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
import StudioClock from './StudioClock.svelte';
/node_modules/
/public/build/
.DS_Store
# Aura Player
A collection of JavaScript components to integrate Aura to your Website.
Provided components:
* Track Service
## Requirements
* Node (>= 13.0)
## Install
npm install
## Run
Development
npm run dev
Production
npm run build
Use the generated components in your own website.
## Resources
* Svelte Docs - https://svelte.dev/docs
\ No newline at end of file
This diff is collapsed.
{
"name": "aura-player",
"version": "1.0.0",
"author": {
"name": "David Trattnig",
"email": "david.trattnig@subsquare.at",
"url": "https://subsquare.at"
},
"license": "AGPL-3.0-only",
"homepage": "https://gitlab.servus.at/aura/meta",
"repository": {
"type": "git",
"url": "git@gitlab.servus.at:aura/engine.git"
},
"scripts": {
"build": "rollup -c",
"dev": "rollup -c -w",
"start": "sirv public"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^11.0.0",
"@rollup/plugin-node-resolve": "^7.0.0",
"rollup": "^1.20.0",
"rollup-plugin-livereload": "^1.0.0",
"rollup-plugin-svelte": "^5.0.3",
"rollup-plugin-terser": "^5.1.2",
"svelte": "^3.0.0"
},
"dependencies": {
"sirv-cli": "^0.4.4"
}
}
contrib/aura-player/public/favicon.png

18.8 KiB

html, body {
position: relative;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
color: #333;
margin: 0;
padding: 8px;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
a {
color: rgb(0,100,200);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:visited {
color: rgb(0,80,160);
}
label {
display: block;
}
input, button, select, textarea {
font-family: inherit;
font-size: inherit;
padding: 0.4em;
margin: 0 0 0.5em 0;
box-sizing: border-box;
border: 1px solid #ccc;
border-radius: 2px;
}
input:disabled {
color: #ccc;
}
input[type="range"] {
height: 0;
}
button {
color: #333;
background-color: #f4f4f4;
outline: none;
}
button:disabled {
color: #999;
}
button:not(:disabled):active {
background-color: #ddd;
}
button:focus {
border-color: #666;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Aura Track Service</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>
<link rel='stylesheet' href='/build/aura-player-bundle.css'>
<script defer src='/build/aura-player-bundle.js'></script>
</head>
<body>
<aura-trackservice api="http://localhost:3333/api/v1/" name="Track Service" />
</body>
</html>
import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
const production = !process.env.ROLLUP_WATCH;
export default {
input: 'src/main.js',
output: {
sourcemap: true,
format: 'iife',
name: 'app',
file: 'public/build/aura-player-bundle.js'
},
plugins: [
svelte({
// enable run-time checks when not in production
dev: !production,
// we'll extract any component CSS out into
// a separate file — better for performance
css: css => {
css.write('public/build/aura-player-bundle.css');
},
customElement: true
}),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration —
// consult the documentation for details:
// https://github.com/rollup/rollup-plugin-commonjs
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload('public'),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser()
],
watch: {
clearScreen: false
}
};
function serve() {
let started = false;
return {
writeBundle() {
if (!started) {
started = true;
require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
stdio: ['ignore', 'inherit', 'inherit'],
shell: true
});
}
}
};
}
\ No newline at end of file
This diff is collapsed.
import TrackService from './TrackService.svelte';
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.