2017-06-23 21:00:42 +00:00
< template >
< div class = "ui vertical left visible wide sidebar" >
< div class = "ui inverted segment header-wrapper" >
< search -bar >
< router -link :title ="'Funkwhale'" : to = "{name: 'index'}" >
< i class = "logo bordered inverted orange big icon" >
< logo class = "logo" > < / logo >
< / i >
< / r o u t e r - l i n k >
< / s e a r c h - b a r >
< / div >
< div class = "menu-area" >
< div class = "ui compact fluid two item inverted menu" >
2017-06-29 21:26:57 +00:00
< a class = "active item" data -tab = " library " > Browse < / a >
2017-06-23 21:00:42 +00:00
< a class = "item" data -tab = " queue " >
Queue & nbsp ;
< template v-if ="queue.tracks.length === 0" >
( empty )
< / template >
< template v-else >
( { { queue . currentIndex + 1 } } of { { queue . tracks . length } } )
< / template >
< / a >
< / div >
< / div >
< div class = "tabs" >
2017-06-29 21:26:57 +00:00
< div class = "ui bottom attached active tab" data -tab = " library " >
2017-06-23 21:00:42 +00:00
< div class = "ui inverted vertical fluid menu" >
2017-12-23 16:47:13 +00:00
< router -link class = "item" v-if ="$store.state.auth.authenticated" :to="{name: 'profile', params: {username: $store.state.auth.username}}"><i class="user icon" > < / i > Logged in as {{ $ store.state.auth.username }} < / router -link >
< router -link class = "item" v-if ="$store.state.auth.authenticated" :to="{name: 'logout'}"><i class="sign out icon" > < / i > Logout < / router -link >
2017-06-23 21:00:42 +00:00
< router -link class = "item" v -else : to = "{name: 'login'}" > < i class = "sign in icon" > < / i > Login < / r o u t e r - l i n k >
2017-06-29 21:26:57 +00:00
< router -link class = "item" : to = "{path: '/library'}" > < i class = "sound icon" > < / i > Browse library < / r o u t e r - l i n k >
2017-06-23 21:00:42 +00:00
< router -link class = "item" : to = "{path: '/favorites'}" > < i class = "heart icon" > < / i > Favorites < / r o u t e r - l i n k >
< / div >
< / div >
< div v-if ="queue.previousQueue " class="ui black icon message" >
< i class = "history icon" > < / i >
< div class = "content" >
< div class = "header" >
Do you want to restore your previous queue ?
< / div >
< p > { { queue . previousQueue . tracks . length } } tracks < / p >
< div class = "ui two buttons" >
< div @click ="queue.restore()" class = "ui basic inverted green button" > Yes < / div >
< div @click ="queue.removePrevious()" class = "ui basic inverted red button" > No < / div >
< / div >
< / div >
< / div >
< div class = "ui bottom attached tab" data -tab = " queue " >
< table class = "ui compact inverted very basic fixed single line table" >
2017-06-28 17:34:05 +00:00
< draggable v-model ="queue.tracks" element="tbody" @update="reorder" >
2017-12-23 15:41:19 +00:00
< tr @ click = "$store.dispatch('queue/currentIndex', index)" v-for ="(track, index) in queue.tracks" :key="index" :class="[{'active': index === queue.currentIndex}]" >
2017-06-28 17:34:05 +00:00
< td class = "right aligned" > { { index + 1 } } < / td >
< td class = "center aligned" >
< img class = "ui mini image" v-if ="track.album.cover" :src="backend.absoluteUrl(track.album.cover)" >
< img class = "ui mini image" v -else src = "../assets/audio/default-cover.png" >
< / td >
< td colspan = "4" >
< strong > { { track . title } } < / strong > < br / >
{ { track . artist . name } }
< / td >
< td >
< template v-if ="favoriteTracks.objects[track.id]" >
2017-12-23 15:41:19 +00:00
< i class = "pink heart icon" > < / i >
< / t e m p l a t e
2017-06-28 17:34:05 +00:00
< / td >
< td >
2017-12-23 15:41:19 +00:00
< i @click.stop ="cleanTrack(index)" class = "circular trash icon" > < / i >
2017-06-28 17:34:05 +00:00
< / td >
< / tr >
< / draggable >
2017-06-23 21:00:42 +00:00
< / table >
2017-12-23 15:41:19 +00:00
< div v-if ="$store.state.radios.running" class="ui black message" >
2017-06-23 21:00:42 +00:00
< div class = "content" >
< div class = "header" >
< i class = "feed icon" > < / i > You have a radio playing
< / div >
< p > New tracks will be appended here automatically . < / p >
2017-12-23 15:41:19 +00:00
< div @click ="$store.dispatch('radios/stop')" class = "ui basic inverted red button" > Stop radio < / div >
2017-06-23 21:00:42 +00:00
< / div >
< / div >
< / div >
< / div >
< div class = "ui inverted segment player-wrapper" >
< player > < / player >
< / div >
< / div >
< / template >
< script >
2017-12-23 15:41:19 +00:00
import { mapState , mapActions } from 'vuex'
2017-12-11 20:09:17 +00:00
2017-06-23 21:00:42 +00:00
import Player from '@/components/audio/Player'
import Logo from '@/components/Logo'
import SearchBar from '@/components/audio/SearchBar'
import backend from '@/audio/backend'
2017-06-28 17:34:05 +00:00
import draggable from 'vuedraggable'
2017-06-23 21:00:42 +00:00
import $ from 'jquery'
export default {
name : 'sidebar' ,
components : {
Player ,
SearchBar ,
2017-06-28 17:34:05 +00:00
Logo ,
2017-12-23 15:41:19 +00:00
draggable
2017-06-23 21:00:42 +00:00
} ,
data ( ) {
return {
2017-12-24 18:28:14 +00:00
backend : backend
2017-06-23 21:00:42 +00:00
}
} ,
mounted ( ) {
$ ( this . $el ) . find ( '.menu .item' ) . tab ( )
2017-06-28 17:34:05 +00:00
} ,
2017-12-23 15:41:19 +00:00
computed : {
... mapState ( {
queue : state => state . queue
} )
} ,
2017-06-28 17:34:05 +00:00
methods : {
2017-12-23 15:41:19 +00:00
... mapActions ( {
cleanTrack : 'queue/cleanTrack'
} ) ,
reorder : function ( oldValue , newValue ) {
this . $store . commit ( 'queue/reorder' , { oldValue , newValue } )
2017-06-28 17:34:05 +00:00
}
2017-06-23 21:00:42 +00:00
}
}
< / script >
<!-- Add "scoped" attribute to limit CSS to this component only -- >
< style scoped lang = "scss" >
$sidebar - color : # 1 B1C1D ;
. sidebar {
display : flex ;
flex - direction : column ;
justify - content : space - between ;
> div {
margin : 0 ;
background - color : $sidebar - color ;
}
. menu {
}
}
. menu - area {
padding : 0.5 rem ;
. menu . item : not ( . active ) : not ( : hover ) {
background - color : rgba ( 255 , 255 , 255 , 0.06 ) ;
}
}
. tabs {
overflow - y : auto ;
height : 0 px ;
}
. tab [ data - tab = "queue" ] {
tr {
cursor : pointer ;
}
}
. sidebar . segment {
margin : 0 ;
border - radius : 0 ;
}
. ui . inverted . segment . header - wrapper {
padding : 0 ;
padding - bottom : 1 rem ;
}
. tabs {
flex : 1 ;
}
. player - wrapper {
border - top : 1 px solid rgba ( 255 , 255 , 255 , 0.1 ) ! important ;
background - color : rgb ( 46 , 46 , 46 ) ! important ;
}
. logo {
cursor : pointer ;
display : inline - block ;
}
. ui . search {
display : inline - block ;
> a {
margin - right : 1.5 rem ;
}
}
< / style >