Merge pull request #45 from nikandlv/development

Playerbar button and queue update
master
Nikan Dalvand 2019-08-02 00:49:25 +04:30 committed by GitHub
commit c5b9a8d11f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 89 deletions

View File

@ -1,5 +1,5 @@
<template> <template>
<span @click="onClick" role="button" class="icon-button" :class="className"> <span @click="onClick" role="button" class="icon-button" :class="{className, 'disabled': disabled}">
<slot name="icon"></slot> <slot name="icon"></slot>
<slot></slot> <slot></slot>
</span> </span>
@ -14,7 +14,7 @@ export default {
onClick: this.click || (() => {}) onClick: this.click || (() => {})
} }
}, },
props: ['variant', 'click'] props: ['variant', 'click', 'disabled']
} }
</script> </script>
@ -35,6 +35,9 @@ export default {
outline: unset outline: unset
color: grey color: grey
transition: all .2s ease-in-out transition: all .2s ease-in-out
&.disabled
background-color: rgba(0,0,0,.15) !important
pointer-events: none
&.large &.large
width: 48px width: 48px
height: 48px height: 48px
@ -51,7 +54,7 @@ export default {
width: 24px width: 24px
height: 24px height: 24px
transition: fill 200ms transition: fill 200ms
fill: gray fill: white
&:hover &:hover
background-color: rgba(0,0,0,0.05) background-color: rgba(0,0,0,0.05)
&:focus,&:active &:focus,&:active

View File

@ -1,10 +1,10 @@
<template> <template>
<section> <section>
<section class="player"> <section class="player">
<img @load="onArtworkLoad" class="artwork" :src="currentlyPlaying.artwork" /> <img @load="onArtworkLoad" class="artwork" :src="playerQueue[this.currentlyPlaying].artwork" />
<div> <div>
<p class="title">{{currentlyPlaying.title}}</p> <p class="title">{{playerQueue[this.currentlyPlaying].title}}</p>
<p class="artist">{{currentlyPlaying.artist}}</p> <p class="artist">{{playerQueue[this.currentlyPlaying].artist}}</p>
</div> </div>
<div class="visualizer"> <div class="visualizer">
<div id="visualizer"></div> <div id="visualizer"></div>
@ -19,14 +19,14 @@
<svg v-show="isFavorited" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path class="colorable" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg> <svg v-show="isFavorited" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path class="colorable" d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z"/></svg>
<svg v-show="!isFavorited" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path class="colorable" d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"/></svg> <svg v-show="!isFavorited" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path class="colorable" d="M16.5 3c-1.74 0-3.41.81-4.5 2.09C10.91 3.81 9.24 3 7.5 3 4.42 3 2 5.42 2 8.5c0 3.78 3.4 6.86 8.55 11.54L12 21.35l1.45-1.32C18.6 15.36 22 12.28 22 8.5 22 5.42 19.58 3 16.5 3zm-4.4 15.55l-.1.1-.1-.1C7.14 14.24 4 11.39 4 8.5 4 6.5 5.5 5 7.5 5c1.54 0 3.04.99 3.57 2.36h1.87C13.46 5.99 14.96 5 16.5 5c2 0 3.5 1.5 3.5 3.5 0 2.89-3.14 5.74-7.9 10.05z"/></svg>
</IconButton> </IconButton>
<IconButton variant="contained"> <IconButton variant="contained" :click="playPrevious" :disabled="(currentlyPlaying == 0)">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 18V6l-8.5 6 8.5 6zm.5-6l8.5 6V6l-8.5 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
</IconButton> </IconButton>
<IconButton variant="contained large" :click="togglePlay"> <IconButton variant="contained large" :click="togglePlay">
<svg v-show="playingStatus" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg> <svg v-show="playingStatus" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
<svg v-show="!playingStatus" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg> <svg v-show="!playingStatus" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
</IconButton> </IconButton>
<IconButton variant="contained"> <IconButton variant="contained" :click="playNext" :disabled="(currentlyPlaying + 1) >= playerQueue.length">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M4 18l8.5-6L4 6v12zm9-12v12l8.5-6L13 6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
</IconButton> </IconButton>
<IconButton variant="contained" :click="toggleFullscreenStatus"> <IconButton variant="contained" :click="toggleFullscreenStatus">
@ -61,8 +61,12 @@ export default {
isFullscreen: false isFullscreen: false
} }
}, },
computed: mapGetters(['fullscreenStatus', 'currentlyPlaying']), computed: mapGetters(['fullscreenStatus', 'currentlyPlaying', 'playerQueue']),
mounted () { mounted () {
this.drawVisualizer()
},
methods: {
drawVisualizer () {
let progress = this.$el.getElementsByClassName('progress')[0] let progress = this.$el.getElementsByClassName('progress')[0]
this.wavesurfer = WaveSurfer.create({ this.wavesurfer = WaveSurfer.create({
container: '#visualizer', container: '#visualizer',
@ -90,7 +94,7 @@ export default {
}) })
] ]
}) })
this.wavesurfer.load(this.currentlyPlaying.stream) this.wavesurfer.load(this.playerQueue[this.currentlyPlaying].stream)
this.wavesurfer.on('ready', () => { this.wavesurfer.on('ready', () => {
this.duration = formatSeconds(this.getDuration()) this.duration = formatSeconds(this.getDuration())
this.wavesurfer.container.style['height'] = '100%' this.wavesurfer.container.style['height'] = '100%'
@ -132,7 +136,6 @@ export default {
currentWidth = progressWave.style.width currentWidth = progressWave.style.width
}) })
}, },
methods: {
onArtworkLoad () { onArtworkLoad () {
let img = this.$el.getElementsByTagName('img')[0] let img = this.$el.getElementsByTagName('img')[0]
let controlIcons = this.$el.getElementsByClassName('control-buttons')[0].children let controlIcons = this.$el.getElementsByClassName('control-buttons')[0].children
@ -164,6 +167,14 @@ export default {
} }
}) })
}, },
playNext () {
this.playQueueItem(this.currentlyPlaying + 1)
this.wavesurfer.load(this.playerQueue[this.currentlyPlaying].stream)
},
playPrevious () {
this.playQueueItem(this.currentlyPlaying - 1)
this.wavesurfer.load(this.playerQueue[this.currentlyPlaying].stream)
},
play () { play () {
this.wavesurfer.play() this.wavesurfer.play()
}, },
@ -201,7 +212,7 @@ export default {
toggleFavorite () { toggleFavorite () {
this.isFavorited = !this.isFavorited this.isFavorited = !this.isFavorited
}, },
...mapActions(['toggleFullscreenStatus']) ...mapActions(['toggleFullscreenStatus', 'playQueueItem'])
} }
} }
</script> </script>

View File

@ -2,11 +2,14 @@ import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { createPersistedState, createSharedMutations } from 'vuex-electron' import { createPersistedState, createSharedMutations } from 'vuex-electron'
import Store from 'electron-store'
import modules from './modules' import modules from './modules'
let clear = false
if (clear) {
const store = new Store({ name: 'vuex' })
store.clear()
}
Vue.use(Vuex) Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
modules, modules,
plugins: [ plugins: [

View File

@ -1,28 +1,52 @@
const state = { const state = {
fullscreen_mode: false, fullscreen_mode: false,
currently_playing: { currently_playing: 0,
queue: [
{
id: 8, id: 8,
title: 'Yellow', title: 'Yellow',
artist: 'Rich Brian', artist: 'Rich Brian',
artwork: '/static/demo/yellow.jpeg', artwork: '/static/demo/yellow.jpeg',
stream: '/static/demo/music.mp3' stream: '/static/demo/music.mp3'
},
{
id: 8,
title: 'Yellow',
artist: 'Rich Brian',
artwork: '/static/demo/habiba.jpg',
stream: '/static/demo/music.mp3'
},
{
id: 8,
title: 'Ali sorena',
artist: 'Negar',
artwork: 'http://sakhamusic.ir/wp-content/uploads/2016/03/Ali-Sorena-%E2%80%93-Negar.jpg',
stream: 'http://dl.sakhamusic.ir/94/esfand/09/03%20Negar%20(Prod.%20Ehsan%20Ziya)_2.mp3'
} }
]
} }
const getters = { const getters = {
fullscreenStatus: (state) => state.fullscreen_mode, fullscreenStatus: (state) => state.fullscreen_mode,
currentlyPlaying: (state) => state.currently_playing currentlyPlaying: (state) => state.currently_playing,
playerQueue: (state) => state.queue
} }
const mutations = { const mutations = {
TOGGLE_FULLSCREEN (state) { TOGGLE_FULLSCREEN (state) {
state.fullscreen_mode = !state.fullscreen_mode state.fullscreen_mode = !state.fullscreen_mode
},
PLAY_QUEUE_ITEM (state, index) {
state.currently_playing = index
} }
} }
const actions = { const actions = {
toggleFullscreenStatus ({ commit }) { toggleFullscreenStatus ({ commit }) {
commit('TOGGLE_FULLSCREEN') commit('TOGGLE_FULLSCREEN')
},
playQueueItem ({ commit }, index) {
commit('PLAY_QUEUE_ITEM', index)
} }
} }