Added looping controls
This commit is contained in:
parent
fcf75260e0
commit
f6c939db4c
|
@ -8,6 +8,7 @@ Changelog
|
|||
- Shortcuts: can now use the ``f`` shortcut to toggle the currently playing track
|
||||
as a favorite (#53)
|
||||
- Shortcuts: avoid collisions between shortcuts by using the exact modifier (#53)
|
||||
- Player: Added looping controls and shortcuts (#52)
|
||||
|
||||
|
||||
0.2.6 (2017-12-15)
|
||||
|
|
|
@ -17,6 +17,7 @@ class Queue {
|
|||
this.currentTrack = null
|
||||
this.ended = true
|
||||
this.state = {
|
||||
looping: 0, // 0 -> no, 1 -> on track, 2 -> on queue
|
||||
volume: cache.get('volume', 0.5)
|
||||
}
|
||||
this.audio = {
|
||||
|
@ -267,12 +268,22 @@ class Queue {
|
|||
|
||||
handleAudioEnded (e) {
|
||||
this.recordListen(this.currentTrack)
|
||||
if (this.state.looping === 1) {
|
||||
// we loop on the same track
|
||||
logger.default.info('Looping on the same track')
|
||||
return this.play(this.currentIndex)
|
||||
}
|
||||
if (this.currentIndex < this.tracks.length - 1) {
|
||||
logger.default.info('Audio track ended, playing next one')
|
||||
this.next()
|
||||
return this.next()
|
||||
} else {
|
||||
logger.default.info('We reached the end of the queue')
|
||||
this.ended = true
|
||||
if (this.state.looping === 2) {
|
||||
logger.default.info('Going back to the beginning of the queue')
|
||||
return this.play(0)
|
||||
} else {
|
||||
this.ended = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,6 +308,14 @@ class Queue {
|
|||
}
|
||||
}
|
||||
|
||||
toggleLooping () {
|
||||
if (this.state.looping > 1) {
|
||||
this.state.looping = 0
|
||||
} else {
|
||||
this.state.looping += 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let queue = new Queue()
|
||||
|
|
|
@ -39,21 +39,71 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls ui grid">
|
||||
<div class="volume-control four wide center aligned column">
|
||||
<input type="range" step="0.05" min="0" max="1" v-model="sliderVolume" />
|
||||
<div class="two wide column controls ui grid">
|
||||
<div
|
||||
@click="queue.previous()"
|
||||
title="Previous track"
|
||||
class="two wide column control"
|
||||
:disabled="!hasPrevious">
|
||||
<i :class="['ui', {'disabled': !hasPrevious}, 'step', 'backward', 'big', 'icon']" ></i>
|
||||
</div>
|
||||
<div
|
||||
v-if="!queue.audio.state.playing"
|
||||
@click="pauseOrPlay"
|
||||
title="Play track"
|
||||
class="two wide column control">
|
||||
<i :class="['ui', 'play', {'disabled': !queue.currentTrack}, 'big', 'icon']"></i>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
@click="pauseOrPlay"
|
||||
title="Pause track"
|
||||
class="two wide column control">
|
||||
<i :class="['ui', 'pause', {'disabled': !queue.currentTrack}, 'big', 'icon']"></i>
|
||||
</div>
|
||||
<div
|
||||
@click="queue.next()"
|
||||
title="Next track"
|
||||
class="two wide column control"
|
||||
:disabled="!hasNext">
|
||||
<i :class="['ui', {'disabled': !hasPrevious}, 'step', 'forward', 'big', 'icon']" ></i>
|
||||
</div>
|
||||
<div class="two wide column control volume-control">
|
||||
<i title="Unmute" @click="queue.setVolume(1)" v-if="currentVolume === 0" class="volume off secondary icon"></i>
|
||||
<i title="Mute" @click="queue.setVolume(0)" v-else-if="currentVolume < 0.5" class="volume down secondary icon"></i>
|
||||
<i title="Mute" @click="queue.setVolume(0)" v-else class="volume up secondary icon"></i>
|
||||
<input type="range" step="0.05" min="0" max="1" v-model="sliderVolume" />
|
||||
</div>
|
||||
<div class="eight wide center aligned column">
|
||||
<i title="Previous track" @click="queue.previous()" :class="['ui', {'disabled': !hasPrevious}, 'step', 'backward', 'big', 'icon']" :disabled="!hasPrevious"></i>
|
||||
<i title="Play track" v-if="!queue.audio.state.playing" :class="['ui', 'play', {'disabled': !queue.currentTrack}, 'big', 'icon']" @click="pauseOrPlay"></i>
|
||||
<i title="Pause track" v-else :class="['ui', 'pause', {'disabled': !queue.currentTrack}, 'big', 'icon']" @click="pauseOrPlay"></i>
|
||||
<i title="Next track" @click="queue.next()" :class="['ui', 'step', 'forward', {'disabled': !hasNext}, 'big', 'icon']" :disabled="!hasNext"></i>
|
||||
<div class="two wide column control looping">
|
||||
<i
|
||||
title="Looping disabled. Click to switch to single-track looping."
|
||||
v-if="queue.state.looping === 0"
|
||||
@click="queue.state.looping = 1"
|
||||
:disabled="!queue.currentTrack"
|
||||
:class="['ui', {'disabled': !queue.currentTrack}, 'step', 'repeat', 'secondary', 'icon']"></i>
|
||||
<i
|
||||
title="Looping on a single track. Click to switch to whole queue looping."
|
||||
v-if="queue.state.looping === 1"
|
||||
@click="queue.state.looping = 2"
|
||||
:disabled="!queue.currentTrack"
|
||||
class="repeat secondary icon">
|
||||
<span class="ui circular tiny orange label">1</span>
|
||||
</i>
|
||||
<i
|
||||
title="Looping on whole queue. Click to disable looping."
|
||||
v-if="queue.state.looping === 2"
|
||||
@click="queue.state.looping = 0"
|
||||
:disabled="!queue.currentTrack"
|
||||
class="repeat orange secondary icon">
|
||||
</i>
|
||||
</div>
|
||||
<div class="four wide center aligned column">
|
||||
<i title="Clear your queue" @click="queue.clean()" :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" :disabled="queue.tracks.length === 0"></i>
|
||||
<div class="three wide column"></div>
|
||||
<div
|
||||
@click="queue.clean()"
|
||||
:disabled="queue.tracks.length === 0"
|
||||
title="Clear your queue"
|
||||
class="two wide column control">
|
||||
<i :class="['ui', 'trash', 'secondary', {'disabled': queue.tracks.length === 0}, 'icon']" ></i>
|
||||
</div>
|
||||
</div>
|
||||
<GlobalEvents
|
||||
|
@ -63,6 +113,7 @@
|
|||
@keydown.ctrl.down.prevent.exact="queue.incrementVolume(-0.1)"
|
||||
@keydown.ctrl.up.prevent.exact="queue.incrementVolume(0.1)"
|
||||
@keydown.f.prevent.exact="favoriteTracks.toggle(queue.currentTrack.id)"
|
||||
@keydown.l.prevent.exact="queue.toggleLooping"
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
@ -187,14 +238,32 @@ export default {
|
|||
.volume-control {
|
||||
position: relative;
|
||||
.icon {
|
||||
margin: 0;
|
||||
// margin: 0;
|
||||
}
|
||||
[type="range"] {
|
||||
max-width: 75%;
|
||||
max-width: 100%;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 10%;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
}
|
||||
&:hover {
|
||||
[type="range"] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.looping.control {
|
||||
i {
|
||||
position: relative;
|
||||
}
|
||||
.label {
|
||||
position: absolute;
|
||||
font-size: 0.7rem;
|
||||
bottom: -0.7rem;
|
||||
right: -0.7rem;
|
||||
}
|
||||
}
|
||||
.ui.feed.icon {
|
||||
|
|
Loading…
Reference in New Issue