...
 
Commits (3)
......@@ -12,7 +12,8 @@
<sidebar></sidebar>
<set-instance-modal @update:show="showSetInstanceModal = $event" :show="showSetInstanceModal"></set-instance-modal>
<service-messages v-if="messages.length > 0"/>
<router-view :key="$route.fullPath"></router-view>
<queue v-if="$store.state.ui.queueExpanded"></queue>
<router-view :class="[{hidden: $store.state.ui.queueExpanded}]" :key="$route.fullPath"></router-view>
<div class="ui fitted divider"></div>
<app-footer
:version="version"
......@@ -37,6 +38,7 @@ import { WebSocketBridge } from 'django-channels'
import GlobalEvents from '@/components/utils/global-events'
import Sidebar from '@/components/Sidebar'
import AppFooter from '@/components/Footer'
import Queue from '@/components/Queue'
import ServiceMessages from '@/components/ServiceMessages'
import moment from 'moment'
import locales from './locales'
......@@ -58,6 +60,7 @@ export default {
GlobalEvents,
ServiceMessages,
SetInstanceModal,
Queue,
},
data () {
return {
......
<template>
<section class="main pusher" :aria-label="labels.queue">
<div class="ui vertical stripe segment">
<div class="ui container">
<h1 class="ui header">
<div class="content">
{{ labels.queue }}
<div class="sub header">
<div>
<translate translate-context="Sidebar/Queue/Text" :translate-params="{index: queue.currentIndex + 1, length: queue.tracks.length}">
Track %{ index } of %{ length }
</translate> -
<span :title="labels.duration">
{{ timeLeft }}
</span>
</div>
</div>
</div>
</h1>
<div class="ui stackable grid row">
<div class="ten wide column">
<table class="ui compact very basic fixed single line unstackable table">
<draggable v-model="tracks" tag="tbody" @update="reorder">
<tr
@click="$store.dispatch('queue/currentIndex', index)"
v-for="(track, index) in tracks"
:key="index"
:class="[{'active': index === queue.currentIndex}]">
<td class="right aligned">{{ index + 1}}</td>
<td class="center aligned">
<img class="ui mini image" v-if="track.album.cover && track.album.cover.original" :src="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
<img class="ui mini image" v-else src="../assets/audio/default-cover.png">
</td>
<td colspan="4">
<button class="title reset ellipsis" :title="track.title" :aria-label="labels.selectTrack">
<strong>{{ track.title }}</strong><br />
<span>
{{ track.artist.name }}
</span>
</button>
</td>
<td>
<template v-if="$store.getters['favorites/isFavorite'](track.id)">
<i class="pink heart icon"></i>
</template>
</td>
<td>
<button :title="labels.removeFromQueue" @click.stop="cleanTrack(index)" :class="['ui', {'inverted': index != queue.currentIndex}, 'really', 'tiny', 'basic', 'circular', 'icon', 'button']">
<i class="trash icon"></i>
</button>
</td>
</tr>
</draggable>
</table>
<div v-if="$store.state.radios.running" class="ui black message">
<div class="content">
<div class="header">
<i class="feed icon"></i> <translate translate-context="Sidebar/Player/Title">You have a radio playing</translate>
</div>
<p><translate translate-context="Sidebar/Player/Paragraph">New tracks will be appended here automatically.</translate></p>
<div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script>
import { mapState, mapGetters, mapActions } from "vuex"
import $ from 'jquery'
import moment from "moment"
import lodash from '@/lodash'
import draggable from "vuedraggable"
export default {
components: {
draggable
},
data () {
return {
tracksChangeBuffer: null,
}
},
computed: {
...mapState({
queue: state => state.queue
}),
tracks: {
get() {
return this.$store.state.queue.tracks
},
set(value) {
this.tracksChangeBuffer = value
}
},
labels () {
return {
queue: this.$pgettext('*/*/*', 'Queue'),
duration: this.$pgettext('*/*/*', 'Duration'),
}
},
timeLeft () {
let seconds = lodash.sum(
this.queue.tracks.slice(this.queue.currentIndex).map((t) => {
return (t.uploads || []).map((u) => {
return u.duration || 0
})[0] || 0
})
)
return moment(this.$store.state.ui.lastDate).add(seconds, 'seconds').fromNow(true)
},
},
methods: {
reorder: function(event) {
this.$store.commit("queue/reorder", {
tracks: this.tracksChangeBuffer,
oldIndex: event.oldIndex,
newIndex: event.newIndex
})
},
}
}
</script>
......@@ -177,50 +177,6 @@
</div>
</div>
</div>
<section :class="['ui', 'bottom', 'attached', {active: selectedTab === 'queue'}, 'tab']">
<table class="ui compact inverted very basic fixed single line unstackable table">
<draggable v-model="tracks" tag="tbody" @update="reorder">
<tr
@click="$store.dispatch('queue/currentIndex', index)"
v-for="(track, index) in tracks"
:key="index"
:class="[{'active': index === queue.currentIndex}]">
<td class="right aligned">{{ index + 1}}</td>
<td class="center aligned">
<img class="ui mini image" v-if="track.album.cover && track.album.cover.original" :src="$store.getters['instance/absoluteUrl'](track.album.cover.small_square_crop)">
<img class="ui mini image" v-else src="../assets/audio/default-cover.png">
</td>
<td colspan="4">
<button class="title reset ellipsis" :title="track.title" :aria-label="labels.selectTrack">
<strong>{{ track.title }}</strong><br />
<span>
{{ track.artist.name }}
</span>
</button>
</td>
<td>
<template v-if="$store.getters['favorites/isFavorite'](track.id)">
<i class="pink heart icon"></i>
</template>
</td>
<td>
<button :title="labels.removeFromQueue" @click.stop="cleanTrack(index)" :class="['ui', {'inverted': index != queue.currentIndex}, 'really', 'tiny', 'basic', 'circular', 'icon', 'button']">
<i class="trash icon"></i>
</button>
</td>
</tr>
</draggable>
</table>
<div v-if="$store.state.radios.running" class="ui black message">
<div class="content">
<div class="header">
<i class="feed icon"></i> <translate translate-context="Sidebar/Player/Title">You have a radio playing</translate>
</div>
<p><translate translate-context="Sidebar/Player/Paragraph">New tracks will be appended here automatically.</translate></p>
<div @click="$store.dispatch('radios/stop')" class="ui basic inverted red button"><translate translate-context="*/Player/Button.Label/Short, Verb">Stop radio</translate></div>
</div>
</div>
</section>
</nav>
<player @next="scrollToCurrent" @previous="scrollToCurrent"></player>
</aside>
......@@ -233,7 +189,6 @@ import Player from "@/components/audio/Player"
import Logo from "@/components/Logo"
import SearchBar from "@/components/audio/SearchBar"
import backend from "@/audio/backend"
import draggable from "vuedraggable"
import $ from "jquery"
......@@ -242,14 +197,12 @@ export default {
components: {
Player,
SearchBar,
Logo,
draggable
Logo
},
data() {
return {
selectedTab: "library",
backend: backend,
tracksChangeBuffer: null,
isCollapsed: true,
fetchInterval: null,
exploreExpanded: false,
......@@ -284,14 +237,6 @@ export default {
administration: this.$pgettext("Sidebar/Admin/Title/Noun", 'Administration'),
}
},
tracks: {
get() {
return this.$store.state.queue.tracks
},
set(value) {
this.tracksChangeBuffer = value
}
},
logoUrl() {
if (this.$store.state.auth.authenticated) {
return "library.index"
......@@ -304,13 +249,6 @@ export default {
...mapActions({
cleanTrack: "queue/cleanTrack"
}),
reorder: function(event) {
this.$store.commit("queue/reorder", {
tracks: this.tracksChangeBuffer,
oldIndex: event.oldIndex,
newIndex: event.newIndex
})
},
scrollToCurrent() {
let current = $(this.$el).find('[data-tab="queue"] .active')[0]
if (!current) {
......@@ -381,6 +319,7 @@ export default {
}
this.$nextTick(() => {
$(this.$el).find('.user-dropdown').dropdown({action: 'hide'})
$(this.$el).find('.admin-dropdown').dropdown({action: 'hide'})
})
}
},
......
This diff is collapsed.
<template>
<div class="main library pusher">
<nav class="ui secondary pointing menu" role="navigation" :aria-label="labels.secondaryMenu">
<router-link class="ui item" to="/library" exact>
<translate translate-context="*/Library/*/Verb">Browse</translate>
</router-link>
<router-link class="ui item" to="/library/albums" exact>
<translate translate-context="*/*/*">Albums</translate>
</router-link>
<router-link class="ui item" to="/library/artists" exact>
<translate translate-context="*/*/*/Noun">Artists</translate>
</router-link>
<router-link class="ui item" to="/library/radios" exact>
<translate translate-context="*/*/*">Radios</translate>
</router-link>
<router-link class="ui item" to="/library/playlists" exact>
<translate translate-context="*/*/*">Playlists</translate>
</router-link>
</nav>
<router-view :key="$route.fullPath"></router-view>
</div>
</template>
......
......@@ -14,4 +14,5 @@ export default {
remove: require('lodash/remove'),
reverse: require('lodash/reverse'),
isEqual: require('lodash/isEqual'),
sum: require('lodash/sum'),
}
......@@ -12,6 +12,7 @@ export default {
messageDisplayDuration: 10000,
messages: [],
theme: 'light',
queueExpanded: false,
notifications: {
inbox: 0,
pendingReviewEdits: 0,
......@@ -85,6 +86,9 @@ export default {
theme: (state, value) => {
state.theme = value
},
queueExpanded: (state, value) => {
state.queueExpanded = value
},
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > state.maxMessages) {
......
......@@ -118,7 +118,6 @@ body {
.footer {
@include media(">desktop") {
margin-left: $desktop-sidebar-width !important;
margin-top: 50px;
}
@include media(">widedesktop") {
......@@ -127,6 +126,9 @@ body {
transform: none !important;
}
.main.pusher.hidden {
display: none;
}
.main.pusher > .ui.secondary.menu {
margin-left: 0;
margin-right: 0;
......