diff --git a/src/cards/NowPlayingCard.svelte b/src/cards/NowPlayingCard.svelte new file mode 100644 index 0000000000000000000000000000000000000000..39fad7167530f476fc89273a0be56d8c3035adf4 --- /dev/null +++ b/src/cards/NowPlayingCard.svelte @@ -0,0 +1,74 @@ +<script lang="ts"> + import Card, { Content } from '@smui/card' + import Button, { Icon, Label } from '@smui/button' + import { hasEpisodeTitle } from '../common/Common.svelte' + import Display from '../common/Display.svelte' + import DateTime from '../common/DateTime.svelte' + + export let episode: { [id: string]: string } = {} + export let prefixOnAir: string + export let renderhtml: boolean // Attention: to avoid XSS attack vectors use with trusted API sources only + export let callbackButton: Function +</script> + +<style lang="scss"> + /* SMUI components need to be selected via global namespace */ + :global(.aura-card.media-player-widget .button-play) { + width: 100%; + } + :global(.aura-card.media-player-widget + .play-icon-delim + .aura-icon-small.icon-play) { + background-color: var(--mdc-theme-primary); + margin-left: 8px; + } + :global(.aura-card.media-player-widget .widget-content) { + padding: 0; + } +</style> + +<template> + <Card class="aura-card media-player-widget"> + <Content class="widget-content"> + <div id="player-description" class="sr-only"> + Click the button to open the media player in a popup window. + </div> + <Button + on:click={() => callbackButton()} + class="button-play" + target="_blank" + tabindex={0} + aria-label="Play: {episode.note_title}" + aria-describedby="player-description"> + <Label> + + <span class="lead-on-air"> + {prefixOnAir} + <DateTime + start={episode.start} + end={episode.end} + displayTimeOnly={true} + displayEnd={true} /> + <span class="play-icon-delim"> + <Icon class="aura-icon-small icon-play" /> + </span> + </span> + + <!-- #FIXME show name should be something like "show_name" or "episode.show.name" in API --> + {#if episode.name} + <span class="episode-show-name"> + <Display value={episode.name} {renderhtml} /> + </span> + {#if hasEpisodeTitle(episode)} - {/if} + {/if} + {#if hasEpisodeTitle(episode)} + <span class="episode-title"> + <Display value={episode.note_title} {renderhtml} /> + </span> + {/if} + + </Label> + </Button> + </Content> + </Card> +</template> diff --git a/src/components/NowPlayingWidget.svelte b/src/components/NowPlayingWidget.svelte new file mode 100644 index 0000000000000000000000000000000000000000..95d7e7b4aa7e26441295d9c9efe87103d2440bc2 --- /dev/null +++ b/src/components/NowPlayingWidget.svelte @@ -0,0 +1,74 @@ +<script context="module" lang="ts"> + // declare var auraOpenMediaPlayer: Function + declare global { + interface Window { + auraOpenMediaPlayer?: Function + } + } + + /* Open the media player popup window */ + window.auraOpenMediaPlayer = (popupUrl: string, popupSettings: string) => { + let player = window.open(popupUrl, 'aura_media_player_popup', popupSettings) + console.log('Created player popup', player) + if (player) player.focus() + else console.log('Error while creating player popup') + } +</script> + +<script lang="ts"> + import { onMount } from 'svelte' + import Spinner from '../common/Spinner.svelte' + import NowPlayingCard from '../cards/NowPlayingCard.svelte' + import { continuousFetch } from '../common/Common.svelte' + + export let api: string = 'https://prog-info.o94.at/api.php' + export let endpoint: string = 'current' + export let popupUrl: string = '/player_popup.html' + export let popupSettings: string = + 'location=no,height=660,width=344,scrollbars=no,status=no' + export let refreshtime: number = 60 + export let prefixOnAir: string = 'LIVE' + export let renderhtml = false // Attention: to avoid XSS attack vectors use with trusted API sources only + + let episode: { [id: string]: string } = {} + + /* Initialize the component */ + onMount(() => { + let url = `${api}/${endpoint}` + continuousFetch(url, refreshtime, processResponse) + }) + + /* Callback to process the API response */ + function processResponse(data: { [id: string]: string }) { + console.log('CurrentShow API Response: ', data) + /** #FIXME o94 Specific Workaround **/ + if (data.name == 'o94 musik') { + data.name = 'o94 Musik' + // data.note_title = "Random Order"; + } + episode = data + } + + /* Call the window function to open media player popup */ + function popup() { + if (window.auraOpenMediaPlayer) + window.auraOpenMediaPlayer(popupUrl, popupSettings) + else console.log("Error: window has no function 'auraOpenMediaPlayer'") + } +</script> + +<style lang="scss"> + +</style> + +<template> + {#if episode} + <NowPlayingCard + {episode} + {prefixOnAir} + {renderhtml} + callbackButton={() => popup()} /> + {:else} + <Spinner /> + {/if} +</template> diff --git a/src/main.ts b/src/main.ts index 5fdf6f27b6743b4a0356cc8fec48518b81b2ae18..93dc0670951dc89fbc44bdb1865076f916a68f19 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,6 +13,7 @@ import HostDetail from './components/HostDetail.svelte'; import HostList from './components/HostList.svelte'; import MediaPlayer from './components/MediaPlayer.svelte'; import MediaPlayerButton from './components/MediaPlayerButton.svelte'; +import NowPlayingWidget from './components/NowPlayingWidget.svelte'; import OnlineStatus from './components/OnlineStatus.svelte'; import Player from './components/Player.svelte'; import Programme from './components/Programme.svelte'; @@ -23,9 +24,13 @@ import TrackService from './components/TrackService.svelte'; /** Inject non web-components into HTML **/ declare const window: any; + window.OnlineStatus = function (options : any) { return new OnlineStatus(options); }; +window.AuraNowPlayingWidget = function (options : any) { + return new NowPlayingWidget(options); +}; window.AuraPlayer = function (options : any) { return new Player(options); };