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

Commit

Permalink
feat(chapters): Use chapter entries to navigate through playtime
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-heimbuch committed Jul 1, 2017
1 parent 9e17747 commit 847d69b
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 34 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
],
"scripts": {
"dist:clean": "mkdir -p dist && rm -rf dist/*",
"docs": "cd docs && bundle install && jekyll build && cd .. && cp -R docs/fixtures/* dist/fixtures",
"postinstall": "cd docs && bundle install",
"docs": "jekyll build --source docs --destination dist && cp -R docs/fixtures/* dist/fixtures",
"webpack:dev": "webpack-dashboard -- webpack-dev-server --content-base dist/ --progress --hot --inline --config src/webpack.config.js",
"webpack:build": "NODE_ENV='production' webpack --config src/webpack.config.js",
"build": "npm run webpack:build",
Expand Down
12 changes: 8 additions & 4 deletions src/components/player/progress-bar/Progress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@input="onInput"
@mousemove="onMouseMove"
@mouseout="onMouseOut"
/>
>
<span class="progress-range" :style="rangeStyle(theme)"></span>
<span class="progress-buffer" :style="bufferStyle(theme, buffer, duration)"></span>
<span v-for="(quantile, index) in quantiles" class="progress-track" :style="trackStyle(theme, duration, quantile)" :key="index"></span>
Expand Down Expand Up @@ -55,25 +55,29 @@
let playtime = this.$select('playtime')
let duration = this.$select('duration')
let theme = this.$select('theme')
let ghost = this.$select('ghost')
return {
playtime,
duration,
theme,
ghost,
buffer: this.$select('buffer'),
playstate: this.$select('playstate'),
thumbPosition: relativePosition(playtime, duration),
quantiles: this.$select('quantiles'),
ghost: this.$select('ghost'),
ghostPosition: 0,
ghostPosition: relativePosition(ghost.time, duration),
thumbActive: false
}
},
watch: {
playtime: function (time) {
this.thumbPosition = relativePosition(time, this.duration)
},
ghost: function (ghost) {
this.ghostPosition = relativePosition(ghost.time, this.duration)
}
},
methods: {
Expand All @@ -97,7 +101,7 @@
this.thumbAnimated = true
this.thumbActive = true
this.ghostPosition = relativePosition(event.offsetX, event.target.clientWidth)
store.dispatch(store.actions.simulatePlaytime(this.duration * event.offsetX / event.target.clientWidth))
store.dispatch(store.actions.enableGhostMode())
},
Expand Down
45 changes: 28 additions & 17 deletions src/components/tabs/chapters/ChapterEntry.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<template>
<div class="chapters--entry"
:style="chapterStyle(theme, chapter, hover)"
@click="onChapterClick(index)"
@mouseover="hover = true"
@mouseleave="hover = false">
@click="onChapterClick(ghost)"
@mouseout="onMouseOut"
@mousemove="onMouseMove">

<span class="index" v-if="hover" @click="onPlayButtonClick(index)">
<span class="index" v-if="hover">
<PlayIcon size="12" :color="theme.tabs.body.icon"></PlayIcon>
</span>
<span class="index" v-else>{{index + 1}}</span>
<span class="title truncate">{{chapter.title}}</span>
<span class="timer">{{remainingTime(chapter, ghost.active ? ghost.time : playtime)}}</span>

<span class="progress" :style="progressStyle(theme, chapter, ghost.active ? ghost.time : playtime)"></span>
<span class="progress" :style="progressStyle(theme, chapter, ghost, playtime)"></span>
</div>
</template>

Expand All @@ -36,12 +36,14 @@
return {}
}
const progressStyle = (theme, chapter, playtime) => {
if (!chapter.active || playtime > chapter.end) {
const progressStyle = (theme, chapter, ghost, playtime) => {
let time = ghost.active ? ghost.time : playtime
if (time < chapter.start || time > chapter.end) {
return {}
}
let progress = ((playtime - chapter.start) * 100) / (chapter.end - chapter.start)
let progress = ((time - chapter.start) * 100) / (chapter.end - chapter.start)
return {
'width': progress + '%',
Expand All @@ -57,20 +59,15 @@
return secondsToTime(chapter.end - chapter.start)
}
const onChapterClick = index => {
store.dispatch(store.actions.setChapter(index))
}
const onPlayButtonClick = index => {
store.dispatch(store.actions.setChapter(index))
const onChapterClick = ghost => {
store.dispatch(store.actions.updatePlaytime(ghost.time))
store.dispatch(store.actions.play())
}
export default {
data () {
return {
theme: this.$select('theme'),
chapters: this.$select('chapters'),
playtime: this.$select('playtime'),
ghost: this.$select('ghost'),
hover: false
Expand All @@ -81,7 +78,17 @@
progressStyle,
remainingTime,
onChapterClick,
onPlayButtonClick
onMouseOut () {
this.hover = false
store.dispatch(store.actions.disableGhostMode())
},
onMouseMove (event) {
this.hover = true
store.dispatch(store.actions.enableGhostMode())
store.dispatch(store.actions.simulatePlaytime(this.chapter.start + (this.chapter.end - this.chapter.start) * event.offsetX / event.target.clientWidth))
}
},
components: {
PlayIcon
Expand Down Expand Up @@ -110,24 +117,28 @@
justify-content: center;
text-align: center;
width: 30px;
pointer-events: none;
}
.title {
display: block;
width: calc(100% - 30px - 30px)
width: calc(100% - 30px);
pointer-events: none;
}
.timer {
display: block;
text-align: right;
@include font-monospace();
pointer-events: none;
}
.progress {
position: absolute;
left: 0;
bottom: 0;
height: 3px;
pointer-events: none;
}
}
</style>
8 changes: 7 additions & 1 deletion src/store/actions/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,14 @@ const setChapter = (chapterIndex) => ({
payload: chapterIndex
})

const updateChapter = (playtime) => ({
type: 'UPDATE_CHAPTER',
payload: playtime
})

export {
setChapter,
nextChapter,
previousChapter
previousChapter,
updateChapter
}
9 changes: 8 additions & 1 deletion src/store/actions/chapters.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'ava'
import { setChapter, nextChapter, previousChapter } from './chapters'
import { setChapter, nextChapter, previousChapter, updateChapter } from './chapters'

test(`nextChapter: creates the NEXT_CHAPTER action`, t => {
t.deepEqual(nextChapter(), {
Expand All @@ -19,3 +19,10 @@ test(`setChapter: creates the SET_CHAPTER action`, t => {
payload: 1
})
})

test(`setChapter: creates the UPDATE_CHAPTER action`, t => {
t.deepEqual(updateChapter(1), {
type: 'UPDATE_CHAPTER',
payload: 1
})
})
10 changes: 10 additions & 0 deletions src/store/effects/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import actions from '../actions'
export default (store, action) => {
const state = store.getState()
const chapters = get(state, 'chapters', [])
const ghost = get(state, 'ghost', {})
const current = currentChapter(chapters)
const currentIndex = currentChapterIndex(chapters)

Expand All @@ -26,5 +27,14 @@ export default (store, action) => {
case 'SET_CHAPTER':
store.dispatch(actions.updatePlaytime(current.start))
break
case 'SIMULATE_PLAYTIME':
store.dispatch(actions.updateChapter(action.payload))
break
case 'SET_PLAYTIME':
case 'UPDATE_PLAYTIME':
if (!ghost.active) {
store.dispatch(actions.updateChapter(action.payload))
}
break
}
}
2 changes: 1 addition & 1 deletion src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import reducers from './reducers'
import actions from './actions'
import effects from './effects'

Raven.config(sentry, { release: version }).install()
Raven.config(sentry, { release: version, ignoreUrls: ['localhost'] }).install()

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose

Expand Down
4 changes: 1 addition & 3 deletions src/store/reducers/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ const chapters = (state = [], action) => {
return chapters
.reduce(parseChapters(action.payload.duration), [])
.map(setActiveByPlaytime(action.payload.playtime || 0))
case 'SIMULATE_PLAYTIME':
case 'SET_PLAYTIME':
case 'UPDATE_PLAYTIME':
case 'UPDATE_CHAPTER':
const nextChapters = state.map(setActiveByPlaytime(action.payload))

if (currentChapterIndex(nextChapters) === -1) {
Expand Down
12 changes: 6 additions & 6 deletions src/store/reducers/chapters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ test(`INIT: it initializes the state with playtime`, t => {
t.deepEqual(result, chaptersExpectedResult)
})

test(`SET_PLAYTIME: it sets a chapter active depending on the current duration`, t => {
test(`UPDATE_CHAPTER: it sets a chapter active depending on the current duration`, t => {
chaptersExpectedResult[0].active = false
chaptersExpectedResult[1].active = true

const result = chapters(chaptersExpectedResult, {
type: 'SET_PLAYTIME',
type: 'UPDATE_CHAPTER',
payload: 10
})

Expand All @@ -79,12 +79,12 @@ test(`SET_PLAYTIME: it sets a chapter active depending on the current duration`,
t.deepEqual(result, expected)
})

test(`UPDATE_PLAYTIME: it sets a chapter active depending on the current duration`, t => {
test(`UPDATE_CHAPTER: it sets a chapter active depending on the current duration`, t => {
chaptersExpectedResult[0].active = false
chaptersExpectedResult[1].active = true

const result = chapters(chaptersExpectedResult, {
type: 'UPDATE_PLAYTIME',
type: 'UPDATE_CHAPTER',
payload: 10
})

Expand All @@ -96,12 +96,12 @@ test(`UPDATE_PLAYTIME: it sets a chapter active depending on the current duratio
t.deepEqual(result, expected)
})

test(`UPDATE_PLAYTIME: returns the state if no active chapter was found`, t => {
test(`UPDATE_CHAPTER: returns the state if no active chapter was found`, t => {
chaptersExpectedResult[0].active = false
chaptersExpectedResult[1].active = true

const result = chapters(chaptersExpectedResult, {
type: 'UPDATE_PLAYTIME',
type: 'UPDATE_CHAPTER',
payload: 7300
})

Expand Down

0 comments on commit 847d69b

Please sign in to comment.