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

Commit

Permalink
Merge pull request #346 from alexander-heimbuch/feature/persist-playtime
Browse files Browse the repository at this point in the history
Feature/persist playtime
  • Loading branch information
plutonik-a authored Mar 7, 2017
2 parents 455b703 + 17f78db commit 7c590ed
Show file tree
Hide file tree
Showing 27 changed files with 170 additions and 120 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"howler": "^2.0.2",
"iframe-resizer": "^3.5.7",
"lodash": "^4.17.3",
"object-hash": "^1.1.5",
"query-string": "^4.3.1",
"react": "15.3.0",
"react-dom": "15.3.0",
Expand Down
20 changes: 0 additions & 20 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,20 @@
import Vue from 'vue'
import head from 'lodash/head'

import { timeToSeconds } from 'utils/time'
import registerDirectives from './directives'

registerDirectives(Vue)

// Store
import store from 'store'
import * as effects from './effects'

// Media Driver
import mediaPlayer from './media-player'

// UI Components
import App from './components/App.vue'


export default config => {
// Initialize meta for store
store.dispatch(store.actions.init(config))

const media = mediaPlayer(config.audio, {
playtime: timeToSeconds(config.playtime),
setPlaytime: playtime => store.dispatch(store.actions.setPlaytime(playtime)),
setBufferState: buffer => store.dispatch(store.actions.setBuffer(buffer)),
setDuration: duration => store.dispatch(store.actions.setDuration(duration)),
onPlay: () => store.dispatch(store.actions.playEvent()),
onPause: () => store.dispatch(store.actions.pauseEvent()),
onStop: () => store.dispatch(store.actions.stopEvent()),
onLoad: () => store.dispatch(store.actions.loading())
})

effects.registerMediaEffects(media)
effects.registerIdleEffects()

window.PODLOVE_STORE = store

return new Vue({
Expand Down
2 changes: 1 addition & 1 deletion src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
@import 'font';
@import 'share';
@import 'marquee';
@import 'utils';
.podlove {
display: block;
Expand Down
2 changes: 1 addition & 1 deletion src/components/player/ProgressBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import store from 'store'
import color from 'color'
import ChaptersIndicator from './chapters/Indicator.vue'
import ChaptersIndicator from './chapters/ChapterIndicator.vue'
const interpolate = (num = 0) => Math.round(num * 100) / 100
Expand Down
6 changes: 3 additions & 3 deletions src/components/player/Timer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<script>
import store from 'store';
import { secondsToTime } from 'utils/time'
import CurrentChapter from './chapters/Current.vue'
import CurrentChapter from './chapters/CurrentChapter.vue'
const timerStyle = theme => ({
color: theme.player.timer.text
Expand Down Expand Up @@ -56,9 +56,9 @@ export default {
width: 100%;
justify-content: space-between;
font-weight: 100;
font-size: 0.8rem;
font-size: 13px;
overflow: hidden;
height: 1.2rem;
height: 20px;
transition: height $animation-duration;
&.start, &.idle {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="podlove-chapters--entry" :style="chapterStyle(theme, chapter)" @click="onChapterClick(chapter)">
<span class="podlove-chapters--entry--index">{{index + 1}}</span>
<span class="podlove-chapters--entry--title">{{chapter.title}}</span>
<span class="podlove-chapters--entry--title podlove-player--truncate">{{chapter.title}}</span>
<a class="podlove-chapters--entry--timer" href="javascript: void(0);">
<span v-if="timerMode === 'remaining' && chapter.active">-{{secondsToTime(chapter.end - playtime < 0 ? 0 : chapter.end - playtime)}}</span>
<span v-else>{{secondsToTime(chapter.end - chapter.start)}}</span>
Expand Down
2 changes: 1 addition & 1 deletion src/components/tabs/chapters/Chapters.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</template>

<script>
import ChapterEntry from './Entry.vue'
import ChapterEntry from './ChapterEntry.vue'
export default {
data() {
Expand Down
4 changes: 2 additions & 2 deletions src/directives/marquee.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const removeClass = (el, cssClass) => {
export default {
update (el, binding, vnode) {
if (el.parentNode.clientWidth >= el.clientWidth) {
el.className = removeClass(el, 'marquee')
el.className = removeClass(el, 'podlove-player--marquee')
return
}

Expand All @@ -31,6 +31,6 @@ export default {
}

el.marquee_text = el.innerText
el.className = addClass(el, 'marquee')
el.className = addClass(el, 'podlove-player--marquee')
}
}
17 changes: 0 additions & 17 deletions src/effects/idle.js

This file was deleted.

29 changes: 0 additions & 29 deletions src/effects/index.js

This file was deleted.

22 changes: 0 additions & 22 deletions src/effects/media.js

This file was deleted.

Empty file removed src/effects/storage.js
Empty file.
3 changes: 1 addition & 2 deletions src/embed/embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ const renderPlayer = (config, player) => anchor => {

iframeResizer({
checkOrigin: false,
log: false,
enablePublicMethods: true
log: false
}, injector)
}

Expand Down
8 changes: 3 additions & 5 deletions src/media-player/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import buffer from './buffer'
*/
let ticker

export default (audio = [], {playtime, setPlaytime, setBufferState, setDuration, onPlay, onPause, onStop, onLoad}) => {
export default (audio = [], {setPlaytime, setBufferState, setDuration, onPlay, onPause, onStop, onLoad}) => {
const player = new Howl({
src: audio,
html5: true,
Expand All @@ -24,8 +24,6 @@ export default (audio = [], {playtime, setPlaytime, setBufferState, setDuration,
// No api sugar for the audio node :/
audioNode = get(player, ['_sounds', 0, '_node'])
setDuration(player.duration())
player.seek(playtime)
// onLoad()
})

player.on('play', onPlay)
Expand All @@ -50,8 +48,8 @@ export default (audio = [], {playtime, setPlaytime, setBufferState, setDuration,

// Extend seek functionality to be capable of jumping in without loaded player
player.setPlaytime = playtime => {
if (player._state !== 'loaded') {
player.play()
if (player.state() === 'unloaded') {
player.load()
}

player.seek(playtime)
Expand Down
22 changes: 22 additions & 0 deletions src/store/effects/idle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import actions from '../actions'

let idle = null
const IDLE_TIMEOUT = 10 * 60 * 1000

export default (store, action) => {
switch (action.type) {
case 'INIT':
if (action.payload.playtime > 0) {
store.dispatch(actions.idle())
}
break
case 'PLAY':
clearTimeout(idle)
break
case 'PAUSE':
idle = setTimeout(() => {
store.dispatch(actions.idle())
}, IDLE_TIMEOUT)
break
}
}
11 changes: 11 additions & 0 deletions src/store/effects/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import mediaEffects from './media'
import idleEffects from './idle'
import storageEffects from './storage'

export default store => next => action => {
mediaEffects(store, action)
storageEffects(store, action)
idleEffects(store, action)

return next(action)
}
39 changes: 39 additions & 0 deletions src/store/effects/media.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import mediaPlayer from '../../media-player'
import actions from '../actions'

const initMediaPlayer = (dispatch, config) =>
mediaPlayer(config.audio, {
setPlaytime: playtime => dispatch(actions.setPlaytime(playtime)),
setBufferState: buffer => dispatch(actions.setBuffer(buffer)),
setDuration: duration => dispatch(actions.setDuration(duration)),
onPlay: () => dispatch(actions.playEvent()),
onPause: () => dispatch(actions.pauseEvent()),
onStop: () => dispatch(actions.stopEvent()),
onLoad: () => dispatch(actions.loading())
})

let mediaElement

export default (store, action) => {
const state = store.getState()

switch (action.type) {
case 'INIT':
mediaElement = initMediaPlayer(store.dispatch, action.payload)
break
case 'UI_PLAY':
mediaElement.setPlaytime(state.playtime)
mediaElement.play()
break
case 'UI_PAUSE':
mediaElement.pause()
break
case 'UI_RESTART':
mediaElement.setPlaytime(0)
mediaElement.play()
break
case 'UPDATE_PLAYTIME':
mediaElement.setPlaytime(action.payload)
break
}
}
24 changes: 24 additions & 0 deletions src/store/effects/storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import actions from '../actions'

import storage from 'utils/storage'
import hash from 'object-hash'

let podloveStorage

export default (store, action) => {
switch (action.type) {
case 'INIT':
podloveStorage = storage(hash(action.payload))

let storedPlaytime = podloveStorage.get('playtime')

if (storedPlaytime !== undefined) {
store.dispatch(actions.setPlaytime(storedPlaytime))
store.dispatch(actions.idle())
}
break
case 'SET_PLAYTIME':
podloveStorage.set('playtime', action.payload)
break
}
}
9 changes: 7 additions & 2 deletions src/store/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import Vue from 'vue'
import Revue from 'revue'
import { createStore } from 'redux'
import { createStore, applyMiddleware, compose } from 'redux'

import reducers from './reducers'
import actions from './actions'
import effects from './effects'

const reduxStore = createStore(reducers, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

const reduxStore = createStore(reducers, composeEnhancers(
applyMiddleware(effects)
))

const store = new Revue(Vue, reduxStore, actions)

Expand Down
7 changes: 0 additions & 7 deletions src/store/reducers/effects.js

This file was deleted.

3 changes: 1 addition & 2 deletions src/store/reducers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ import { combineReducers } from 'redux'

import * as init from './init'
import * as player from './player'
import * as effects from './effects'
import * as chapters from './chapters'
import * as tabs from './tabs'
import * as theme from './theme'
import * as share from './share'

export default combineReducers(
Object.assign({}, init, player, effects, chapters, tabs, theme, share)
Object.assign({}, init, player, chapters, tabs, theme, share)
)
2 changes: 1 addition & 1 deletion src/store/reducers/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { timeToSeconds } from 'utils/time'
const playtime = (state = 0, action) => {
switch (action.type) {
case 'INIT':
const playtime = get(action.payload, 'playtime', state)
const playtime = state > 0 ? state : get(action.payload, 'playtime', state)
return timeToSeconds(playtime)
case 'UPDATE_PLAYTIME':
return parseFloat(action.payload)
Expand Down
4 changes: 0 additions & 4 deletions src/styles/_marquee.scss

This file was deleted.

10 changes: 10 additions & 0 deletions src/styles/_utils.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.podlove-player--truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.podlove-player--marquee {
transform: translateX(0);
animation: stop-and-scroll 15s linear infinite;
}
Loading

0 comments on commit 7c590ed

Please sign in to comment.