Skip to content
This repository has been archived by the owner on May 24, 2021. It is now read-only.

Commit

Permalink
feat(live-mode): Add live mode
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-heimbuch committed Oct 13, 2017
1 parent 9848fda commit c24a817
Show file tree
Hide file tree
Showing 20 changed files with 1,446 additions and 519 deletions.
4 changes: 2 additions & 2 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies:
- npm rebuild node-sass
- gem install bundler
pre:
- yarn global add publish-release
- echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
cache_directories:
- ~/.cache/yarn

Expand Down Expand Up @@ -53,5 +53,5 @@ deployment:
commands:
- yarn dist:clean
- yarn build
- yarn deploy:release
- npm publish --access public
- yarn deploy:cdn
53 changes: 53 additions & 0 deletions docs/live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
layout: page
title: Live
navigation: 6
---

# Live Mode

<p id="example"></p>
<script src="{{ 'embed.js' | relative_url }}"></script>
<script>
podlovePlayer('#example', {
mode: 'live',
title: 'Livestream',
subtitle: 'Wir sind ein CreativeCommons-Webradio, das sich zur Aufgabe gemacht hat freie Musik zu verbreiten und die Hörer durch die vielen Beteiligungsmöglichkeiten direkt zu einem Teil unserer Sendungen zu machen.',
link: 'https://theradio.cc',
poster: 'https://theradio.cc/wp-content/uploads/2014/01/9e7d1d68285200b9d3c0-150x150.jpg',
show: {
title: 'TheRadio.cc',
link: 'https://theradio.cc'
},
audio: [{
url: 'http://mp3.theradio.cc/',
mimeType: 'audio/mp3'
}, {
url: 'http://ogg.theradio.cc/',
mimeType: 'audio/ogg'
}]
});
</script>

## Config

```javascript
{
mode: 'live',
title: 'Livestream',
subtitle: 'Wir sind ein CreativeCommons-Webradio, das sich zur Aufgabe gemacht hat freie Musik zu verbreiten und die Hörer durch die vielen Beteiligungsmöglichkeiten direkt zu einem Teil unserer Sendungen zu machen.',
link: 'https://theradio.cc',
poster: 'https://theradio.cc/wp-content/uploads/2014/01/9e7d1d68285200b9d3c0-150x150.jpg',
show: {
title: 'TheRadio.cc',
link: 'https://theradio.cc'
},
audio: [{
url: 'http://mp3.theradio.cc/',
mimeType: 'audio/mp3'
}, {
url: 'http://ogg.theradio.cc/',
mimeType: 'audio/ogg'
}]
}
```
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"deploy:surge": "surge --project ./dist --domain podlove-player.surge.sh",
"changelog": "standard-changelog"
},
"files": [
"dist/"
],
"dependencies": {
"babel-polyfill": "6.26.0",
"bluebird": "3.5.0",
Expand All @@ -55,8 +58,7 @@
"detect-browser": "1.6.2",
"foundation-sites": "6.3.1",
"hashcode": "1.0.3",
"howler": "2.0.3",
"html5-audio-driver": "0.6.3",
"@podlove/html5-audio-driver": "0.6.3",
"iframe-resizer": "3.5.7",
"keyboardjs": "2.3.3",
"lodash": "4.17.4",
Expand Down
8 changes: 0 additions & 8 deletions scripts/deploy-release.sh

This file was deleted.

2 changes: 1 addition & 1 deletion src/media/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { audio, events as audioEvents, actions as audioActions } from 'html5-audio-driver'
import { audio, events as audioEvents, actions as audioActions } from '@podlove/html5-audio-driver'

export default (audioFiles) => {
const audioElement = audio(audioFiles)
Expand Down
94 changes: 94 additions & 0 deletions src/store/effects/components.episode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { get } from 'lodash'
import actions from '../actions'

const hasChapters = chapters => chapters.length > 0
const hasMeta = (show, episode) => episode.poster || show.poster || show.title || episode.title || episode.subtitle
const hasFiles = files => files.length > 0

export default (store, action) => {
switch (action.type) {
case 'LOADING':
store.dispatch(actions.showLoadingButton())
break
case 'LOADED':
if (action.payload.paused) {
store.dispatch(actions.showPauseButton())
} else {
store.dispatch(actions.showPlayingButton())
}
break
case 'PLAY':
// Default behaviour
store.dispatch(actions.showPlayingButton())
store.dispatch(actions.toggleProgressBar(true))
store.dispatch(actions.toggleChapterControls(true))
store.dispatch(actions.toggleSteppersControls(true))

// Error Fallbacks
store.dispatch(actions.toggleInfo(true))
store.dispatch(actions.toggleError(false))
break
case 'PAUSE':
store.dispatch(actions.showPauseButton())
break
case 'IDLE':
store.dispatch(actions.showPauseButton())
store.dispatch(actions.toggleChapterControls(true))
store.dispatch(actions.toggleSteppersControls(true))
store.dispatch(actions.toggleProgressBar(true))
break
case 'INIT':
const state = store.getState()
const chapters = get(state, 'chapters', [])
const downloadFiles = get(state, 'download.files', [])
const episode = get(state, 'episode', {})
const show = get(state, 'show', {})
const runtime = get(state, 'runtime', {})

// Tabs
if (hasChapters(chapters)) {
store.dispatch(actions.toggleComponentTab('chapters', true))
}

if (hasFiles(downloadFiles)) {
store.dispatch(actions.toggleComponentTab('download', true))
}

// Meta
if (hasMeta(show, episode)) {
store.dispatch(actions.toggleInfo(true))
}

// Audio Modifiers
if (runtime.platform === 'desktop') {
store.dispatch(actions.toggleVolumeSlider(true))
}

// Everything else without conditions
store.dispatch(actions.toggleComponentTab('share', true))
store.dispatch(actions.toggleComponentTab('info', true))
store.dispatch(actions.toggleComponentTab('audio', true))
store.dispatch(actions.toggleRateSlider(true))
store.dispatch(actions.toggleInfoPoster(true))
break
case 'END':
store.dispatch(actions.showReplayButton())
break
case 'ERROR_LOAD':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.showRetryButton())
store.dispatch(actions.toggleProgressBar(false))
store.dispatch(actions.toggleChapterControls(false))
store.dispatch(actions.toggleSteppersControls(false))
break
case 'ERROR_MISSING_AUDIO_FILES':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.toggleButtonControl(false))
store.dispatch(actions.toggleProgressBar(false))
store.dispatch(actions.toggleChapterControls(false))
store.dispatch(actions.toggleSteppersControls(false))
break
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import test from 'ava'
import sinon from 'sinon'

import components from './components'
import components from './components.episode'

let store, state

Expand Down
97 changes: 7 additions & 90 deletions src/store/effects/components.js
Original file line number Diff line number Diff line change
@@ -1,95 +1,12 @@
import { get } from 'lodash'
import actions from '../actions'

const hasChapters = chapters => chapters.length > 0
const hasMeta = (show, episode) => episode.poster || show.poster || show.title || episode.title || episode.subtitle
const hasFiles = files => files.length > 0
import episodeComponents from './components.episode'
import liveComponents from './components.live'

export default (store, action) => {
switch (action.type) {
case 'LOADING':
store.dispatch(actions.showLoadingButton())
break
case 'LOADED':
if (action.payload.paused) {
store.dispatch(actions.showPauseButton())
} else {
store.dispatch(actions.showPlayingButton())
}
break
case 'PLAY':
// Default behaviour
store.dispatch(actions.showPlayingButton())
store.dispatch(actions.toggleProgressBar(true))
store.dispatch(actions.toggleChapterControls(true))
store.dispatch(actions.toggleSteppersControls(true))

// Error Fallbacks
store.dispatch(actions.toggleInfo(true))
store.dispatch(actions.toggleError(false))
break
case 'PAUSE':
store.dispatch(actions.showPauseButton())
break
case 'IDLE':
store.dispatch(actions.showPauseButton())
store.dispatch(actions.toggleChapterControls(true))
store.dispatch(actions.toggleSteppersControls(true))
store.dispatch(actions.toggleProgressBar(true))
break
case 'INIT':
const state = store.getState()
const chapters = get(state, 'chapters', [])
const downloadFiles = get(state, 'download.files', [])
const episode = get(state, 'episode', {})
const show = get(state, 'show', {})
const runtime = get(state, 'runtime', {})

// Tabs
if (hasChapters(chapters)) {
store.dispatch(actions.toggleComponentTab('chapters', true))
}

if (hasFiles(downloadFiles)) {
store.dispatch(actions.toggleComponentTab('download', true))
}

// Meta
if (hasMeta(show, episode)) {
store.dispatch(actions.toggleInfo(true))
}

// Audio Modifiers
if (runtime.platform === 'desktop') {
store.dispatch(actions.toggleVolumeSlider(true))
}
const state = store.getState()

// Everything else without conditions
store.dispatch(actions.toggleComponentTab('share', true))
store.dispatch(actions.toggleComponentTab('info', true))
store.dispatch(actions.toggleComponentTab('audio', true))
store.dispatch(actions.toggleRateSlider(true))
store.dispatch(actions.toggleRateSlider(true))
store.dispatch(actions.toggleInfoPoster(true))
break
case 'END':
store.dispatch(actions.showReplayButton())
break
case 'ERROR_LOAD':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.showRetryButton())
store.dispatch(actions.toggleProgressBar(false))
store.dispatch(actions.toggleChapterControls(false))
store.dispatch(actions.toggleSteppersControls(false))
break
case 'ERROR_MISSING_AUDIO_FILES':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.toggleButtonControl(false))
store.dispatch(actions.toggleProgressBar(false))
store.dispatch(actions.toggleChapterControls(false))
store.dispatch(actions.toggleSteppersControls(false))
break
if (state.mode === 'live') {
liveComponents(store, action)
} else {
episodeComponents(store, action)
}
}
68 changes: 68 additions & 0 deletions src/store/effects/components.live.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { get } from 'lodash'
import actions from '../actions'

const hasMeta = (show, episode) => episode.poster || show.poster || show.title || episode.title || episode.subtitle

export default (store, action) => {
switch (action.type) {
case 'LOADING':
store.dispatch(actions.showLoadingButton())
break
case 'LOADED':
if (action.payload.paused) {
store.dispatch(actions.showPauseButton())
} else {
store.dispatch(actions.showPlayingButton())
}
break
case 'PLAY':
// Default behaviour
store.dispatch(actions.showPlayingButton())

// Error Fallbacks
store.dispatch(actions.toggleInfo(true))
store.dispatch(actions.toggleError(false))
break
case 'PAUSE':
store.dispatch(actions.showPauseButton())
break
case 'IDLE':
store.dispatch(actions.showPauseButton())
store.dispatch(actions.toggleChapterControls(true))
store.dispatch(actions.toggleSteppersControls(true))
store.dispatch(actions.toggleProgressBar(true))
break
case 'INIT':
const state = store.getState()
const episode = get(state, 'episode', {})
const show = get(state, 'show', {})
const runtime = get(state, 'runtime', {})

// Meta
if (hasMeta(show, episode)) {
store.dispatch(actions.toggleInfo(true))
}

// Audio Modifiers
if (runtime.platform === 'desktop') {
store.dispatch(actions.toggleVolumeSlider(true))
}

// Everything else without conditions
store.dispatch(actions.toggleComponentTab('info', true))
store.dispatch(actions.toggleComponentTab('audio', true))
store.dispatch(actions.toggleInfoPoster(true))
store.dispatch(actions.showPauseButton())
break
case 'ERROR_LOAD':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.showRetryButton())
break
case 'ERROR_MISSING_AUDIO_FILES':
store.dispatch(actions.toggleInfo(false))
store.dispatch(actions.toggleError(true))
store.dispatch(actions.toggleButtonControl(false))
break
}
}
Loading

0 comments on commit c24a817

Please sign in to comment.