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

Commit

Permalink
feat(ghost-chapter): Add ghost mode to chapters
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-heimbuch committed Jul 8, 2017
1 parent 446776d commit 0202f50
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 14 deletions.
45 changes: 34 additions & 11 deletions src/components/tabs/chapters/ChapterEntry.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="chapters--entry"
<div class="chapters--entry" :class="{active: chapter.active}"
:style="chapterStyle(theme, chapter, hover)"
@mouseover="onMouseOver"
@mouseleave="onMouseLeave">
Expand All @@ -10,10 +10,11 @@
<div class="chapter--progress"
@mouseout="onMouseOut"
@mousemove="onMouseMove"
@click="onChapterClick(ghost)">
@click="onChapterClick(index, ghost)">
<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, playtime)"></span>
<span class="timer">{{remainingTime(chapter, ghost, playtime)}}</span>
<span class="progress" :style="progressStyle(theme, chapter, playtime)"></span>
<span class="progress" :style="progressGhostStyle(theme, chapter, ghost)"></span>
</div>
</div>
</template>
Expand All @@ -38,30 +39,46 @@
return {}
}
const progressStyle = (theme, chapter, ghost, playtime) => {
let time = ghost.active ? ghost.time : playtime
if (!chapter.active || time > chapter.end) {
const progressStyle = (theme, chapter, playtime) => {
if (!chapter.active || playtime > chapter.end) {
return {}
}
let progress = ((time - chapter.start) * 100) / (chapter.end - chapter.start)
let progress = ((playtime - chapter.start) * 100) / (chapter.end - chapter.start)
return {
'width': progress + '%',
'background-color': theme.tabs.body.progress
}
}
const remainingTime = (chapter, playtime) => {
const progressGhostStyle = (theme, chapter, ghost) => {
if (!ghost.active || ghost.time > chapter.end || ghost.time < chapter.start) {
return {}
}
let progress = ((ghost.time - chapter.start) * 100) / (chapter.end - chapter.start)
return {
'width': progress + '%',
'background-color': color(theme.tabs.body.progress).fade(0.6)
}
}
const remainingTime = (chapter, ghost, playtime) => {
if (chapter.active) {
return `-${secondsToTime(chapter.end - playtime)}`
}
if (ghost.active && ghost.time > chapter.start && ghost.time < chapter.end) {
return `-${secondsToTime(chapter.end - ghost.time)}`
}
return secondsToTime(chapter.end - chapter.start)
}
const onChapterClick = ghost => {
const onChapterClick = (index, ghost) => {
store.dispatch(store.actions.setChapter(index))
store.dispatch(store.actions.updatePlaytime(ghost.time))
store.dispatch(store.actions.play())
}
Expand All @@ -83,6 +100,8 @@
methods: {
chapterStyle,
progressStyle,
progressGhostStyle,
remainingTime,
onChapterClick,
onChapterPlayClick,
Expand Down Expand Up @@ -126,6 +145,10 @@
transition: background $animation-duration, color $animation-duration;
&.active {
font-weight: 500;
}
.index {
display: flex;
align-items: center;
Expand Down
3 changes: 0 additions & 3 deletions src/store/effects/chapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ 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) {
Expand Down
102 changes: 102 additions & 0 deletions src/store/effects/chapters.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import test from 'ava'
import sinon from 'sinon'
import chapters from './chapters'

let store, state

test.beforeEach(t => {
state = {
chapters: [{
start: 0,
end: 1000,
}, {
start: 1000,
end: 2000
}, {
start: 2000,
end: 3000
}],
duration: 3000,
playtime: 2500,
ghost: {
active: false
}
}

store = {
dispatch: sinon.stub(),
getState: () => (state)
}
})

test(`chaptersEffects: it exports a effect function`, t => {
t.is(typeof chapters, 'function')
})

test(`chaptersEffects: it triggers UPDATE_PLAYTIME if PREVIOUS_CHAPTER is dispatched`, t => {
state.chapters[0].active = true
chapters(store, {type: 'PREVIOUS_CHAPTER'})

state.chapters[0].active = false
state.chapters[2].active = true
chapters(store, {type: 'PREVIOUS_CHAPTER'})

t.deepEqual(store.dispatch.getCall(0).args[0], {
type: 'UPDATE_PLAYTIME',
payload: 0
})

t.deepEqual(store.dispatch.getCall(1).args[0], {
type: 'UPDATE_PLAYTIME',
payload: 2000
})
})

test(`chaptersEffects: it triggers UPDATE_PLAYTIME if NEXT_CHAPTER is dispatched`, t => {
state.chapters[2].active = true
chapters(store, {type: 'NEXT_CHAPTER'})

state.chapters[2].active = false
state.chapters[1].active = true
chapters(store, {type: 'NEXT_CHAPTER'})

t.deepEqual(store.dispatch.getCall(0).args[0], {
type: 'UPDATE_PLAYTIME',
payload: 3000
})

t.deepEqual(store.dispatch.getCall(1).args[0], {
type: 'UPDATE_PLAYTIME',
payload: 1000
})
})

test(`chaptersEffects: it triggers UPDATE_PLAYTIME if SET_CHAPTER is dispatched`, t => {
state.chapters[1].active = true
chapters(store, {type: 'SET_CHAPTER'})

t.deepEqual(store.dispatch.getCall(0).args[0], {
type: 'UPDATE_PLAYTIME',
payload: 1000
})
})

test(`chaptersEffects: it triggers UPDATE_CHAPTER if SET_PLAYTIME is dispatched`, t => {
chapters(store, {type: 'SET_PLAYTIME', payload: 1000})
chapters(store, {type: 'UPDATE_PLAYTIME', payload: 1000})
state.ghost.active = true

chapters(store, {type: 'SET_PLAYTIME', payload: 1000})
chapters(store, {type: 'UPDATE_PLAYTIME', payload: 1000})
t.is(store.dispatch.getCalls().length, 2)

t.deepEqual(store.dispatch.getCall(0).args[0], {
type: 'UPDATE_CHAPTER',
payload: 1000
})

t.deepEqual(store.dispatch.getCall(1).args[0], {
type: 'UPDATE_CHAPTER',
payload: 1000
})
})

0 comments on commit 0202f50

Please sign in to comment.