2018-08-11 01:47:10 -04:00
|
|
|
<template>
|
|
|
|
<nav class="navbar is-light is-fixed-top" role="navigation" aria-label="main navigation">
|
|
|
|
<div class="navbar-brand">
|
|
|
|
<router-link to="/playlists" class="navbar-item" active-class="is-active">
|
|
|
|
<span class="icon"><i class="mdi mdi-library-music"></i></span>
|
|
|
|
</router-link>
|
|
|
|
<router-link to="/music" class="navbar-item" active-class="is-active">
|
|
|
|
<span class="icon"><i class="mdi mdi-music"></i></span>
|
|
|
|
</router-link>
|
|
|
|
<router-link to="/podcasts" class="navbar-item" active-class="is-active" v-if="podcasts.tracks > 0">
|
|
|
|
<span class="icon"><i class="mdi mdi-microphone"></i></span>
|
|
|
|
</router-link>
|
|
|
|
<router-link to="/audiobooks" class="navbar-item" active-class="is-active" v-if="audiobooks.tracks > 0">
|
|
|
|
<span class="icon"><i class="mdi mdi-book-open-variant"></i></span>
|
|
|
|
</router-link>
|
2018-12-23 04:34:46 -05:00
|
|
|
<router-link to="/files" class="navbar-item" active-class="is-active">
|
|
|
|
<span class="icon"><i class="mdi mdi-folder-open"></i></span>
|
|
|
|
</router-link>
|
2018-08-11 01:47:10 -04:00
|
|
|
<router-link to="/search" class="navbar-item" active-class="is-active">
|
|
|
|
<span class="icon"><i class="mdi mdi-magnify"></i></span>
|
|
|
|
</router-link>
|
|
|
|
|
|
|
|
<div class="navbar-burger" @click="update_show_burger_menu" :class="{ 'is-active': show_burger_menu }">
|
|
|
|
<span></span>
|
|
|
|
<span></span>
|
|
|
|
<span></span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="navbar-menu" :class="{ 'is-active': show_burger_menu }">
|
|
|
|
<div class="navbar-start">
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="navbar-end">
|
|
|
|
<div class="navbar-item has-dropdown is-hoverable">
|
2019-07-06 02:31:00 -04:00
|
|
|
<a class="navbar-link is-arrowless"><span class="icon is-hidden-mobile is-hidden-tablet-only"><i class="mdi mdi-volume-high"></i></span> <span class="is-hidden-desktop has-text-weight-bold">Volume</span></a>
|
2018-08-11 01:47:10 -04:00
|
|
|
|
|
|
|
<div class="navbar-dropdown is-right">
|
|
|
|
<div class="navbar-item">
|
|
|
|
<div class="level is-mobile">
|
|
|
|
<div class="level-left fd-expanded">
|
|
|
|
<div class="level-item" style="flex-grow: 0;">
|
2019-02-16 00:48:45 -05:00
|
|
|
<a class="button is-white is-small" @click="toggle_mute_volume">
|
2019-02-18 07:06:09 -05:00
|
|
|
<span class="icon"><i class="mdi mdi-18px" :class="{ 'mdi-volume-off': player.volume <= 0, 'mdi-volume-high': player.volume > 0 }"></i></span>
|
2019-02-16 00:48:45 -05:00
|
|
|
</a>
|
2018-08-11 01:47:10 -04:00
|
|
|
</div>
|
|
|
|
<div class="level-item fd-expanded">
|
|
|
|
<div class="fd-expanded">
|
|
|
|
<p class="heading">Volume</p>
|
|
|
|
<range-slider
|
|
|
|
class="slider fd-has-action"
|
|
|
|
min="0"
|
|
|
|
max="100"
|
|
|
|
step="1"
|
|
|
|
:value="player.volume"
|
|
|
|
@change="set_volume">
|
|
|
|
</range-slider>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<hr class="navbar-divider">
|
|
|
|
<nav-bar-item-output v-for="output in outputs" :key="output.id" :output="output"></nav-bar-item-output>
|
|
|
|
|
2019-02-14 06:19:29 -05:00
|
|
|
<hr class="navbar-divider">
|
|
|
|
<div class="navbar-item">
|
|
|
|
<div class="level is-mobile">
|
|
|
|
<div class="level-left fd-expanded">
|
|
|
|
<div class="level-item" style="flex-grow: 0;">
|
|
|
|
<a class="button is-white is-small" :class="{ 'is-loading': loading }"><span class="icon fd-has-action" :class="{ 'has-text-grey-light': !playing && !loading, 'is-loading': loading }" @click="togglePlay"><i class="mdi mdi-18px mdi-radio-tower"></i></span></a>
|
|
|
|
</div>
|
|
|
|
<div class="level-item fd-expanded">
|
|
|
|
<div class="fd-expanded">
|
2019-02-18 06:54:43 -05:00
|
|
|
<p class="heading" :class="{ 'has-text-grey-light': !playing }">HTTP stream <a href="/stream.mp3"><span class="is-lowercase">(stream.mp3)</span></a></p>
|
2019-02-14 06:19:29 -05:00
|
|
|
<range-slider
|
|
|
|
class="slider fd-has-action"
|
|
|
|
min="0"
|
|
|
|
max="100"
|
|
|
|
step="1"
|
|
|
|
:disabled="!playing"
|
|
|
|
:value="stream_volume"
|
|
|
|
@change="set_stream_volume">
|
|
|
|
</range-slider>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
2018-08-11 01:47:10 -04:00
|
|
|
<hr class="navbar-divider">
|
|
|
|
<div class="navbar-item">
|
|
|
|
<div class="level is-mobile">
|
|
|
|
<div class="level-left">
|
|
|
|
<div class="level-item">
|
|
|
|
<div class="buttons has-addons">
|
|
|
|
<player-button-previous class="button"></player-button-previous>
|
|
|
|
<player-button-play-pause class="button"></player-button-play-pause>
|
|
|
|
<player-button-next class="button"></player-button-next>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="level-item">
|
|
|
|
<div class="buttons has-addons">
|
|
|
|
<player-button-repeat class="button is-light"></player-button-repeat>
|
|
|
|
<player-button-shuffle class="button is-light"></player-button-shuffle>
|
|
|
|
<player-button-consume class="button is-light"></player-button-consume>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="navbar-item has-dropdown is-hoverable">
|
2019-07-06 02:31:00 -04:00
|
|
|
<a class="navbar-link is-arrowless"><span class="icon is-hidden-mobile is-hidden-tablet-only"><i class="mdi mdi-settings"></i></span> <span class="is-hidden-desktop has-text-weight-bold">Settings</span></a>
|
2018-08-11 01:47:10 -04:00
|
|
|
|
|
|
|
<div class="navbar-dropdown is-right">
|
|
|
|
<a class="navbar-item" href="/admin.html">Admin</a>
|
|
|
|
<hr class="navbar-divider">
|
|
|
|
<a class="navbar-item" v-on:click="open_about">
|
|
|
|
<div>
|
|
|
|
<p class="title is-7">forked-daapd</p>
|
|
|
|
<p class="subtitle is-7">{{ config.version }}</p>
|
|
|
|
</div>
|
|
|
|
</a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</nav>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import webapi from '@/webapi'
|
2019-02-14 06:19:29 -05:00
|
|
|
import _audio from '@/audio'
|
2018-08-11 01:47:10 -04:00
|
|
|
import NavBarItemOutput from './NavBarItemOutput'
|
|
|
|
import PlayerButtonPlayPause from './PlayerButtonPlayPause'
|
|
|
|
import PlayerButtonNext from './PlayerButtonNext'
|
|
|
|
import PlayerButtonPrevious from './PlayerButtonPrevious'
|
|
|
|
import PlayerButtonShuffle from './PlayerButtonShuffle'
|
|
|
|
import PlayerButtonConsume from './PlayerButtonConsume'
|
|
|
|
import PlayerButtonRepeat from './PlayerButtonRepeat'
|
|
|
|
import RangeSlider from 'vue-range-slider'
|
|
|
|
import * as types from '@/store/mutation_types'
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'NavbarTop',
|
|
|
|
components: { NavBarItemOutput, PlayerButtonPlayPause, PlayerButtonNext, PlayerButtonPrevious, PlayerButtonShuffle, PlayerButtonConsume, PlayerButtonRepeat, RangeSlider },
|
|
|
|
|
|
|
|
data () {
|
|
|
|
return {
|
2019-02-14 06:19:29 -05:00
|
|
|
search_query: '',
|
2019-02-16 00:48:45 -05:00
|
|
|
old_volume: 0,
|
2019-02-14 06:19:29 -05:00
|
|
|
|
|
|
|
playing: false,
|
|
|
|
loading: false,
|
|
|
|
stream_volume: 10
|
2018-08-11 01:47:10 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
computed: {
|
|
|
|
outputs () {
|
|
|
|
return this.$store.state.outputs
|
|
|
|
},
|
|
|
|
|
|
|
|
player () {
|
|
|
|
return this.$store.state.player
|
|
|
|
},
|
|
|
|
|
|
|
|
config () {
|
|
|
|
return this.$store.state.config
|
|
|
|
},
|
|
|
|
|
|
|
|
library () {
|
|
|
|
return this.$store.state.library
|
|
|
|
},
|
|
|
|
|
|
|
|
audiobooks () {
|
|
|
|
return this.$store.state.audiobooks_count
|
|
|
|
},
|
|
|
|
|
|
|
|
podcasts () {
|
|
|
|
return this.$store.state.podcasts_count
|
|
|
|
},
|
|
|
|
|
|
|
|
show_burger_menu () {
|
|
|
|
return this.$store.state.show_burger_menu
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
methods: {
|
|
|
|
update_show_burger_menu: function () {
|
|
|
|
this.$store.commit(types.SHOW_BURGER_MENU, !this.show_burger_menu)
|
|
|
|
},
|
|
|
|
|
|
|
|
set_volume: function (newVolume) {
|
|
|
|
webapi.player_volume(newVolume)
|
|
|
|
},
|
|
|
|
|
2019-02-16 00:48:45 -05:00
|
|
|
toggle_mute_volume: function () {
|
|
|
|
if (this.player.volume > 0) {
|
|
|
|
this.set_volume(0)
|
|
|
|
} else {
|
|
|
|
this.set_volume(this.old_volume)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-08-11 01:47:10 -04:00
|
|
|
open_about: function () {
|
|
|
|
this.$store.commit(types.SHOW_BURGER_MENU, false)
|
|
|
|
this.$router.push({ path: '/about' })
|
2019-02-14 06:19:29 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
setupAudio: function () {
|
|
|
|
const a = _audio.setupAudio()
|
|
|
|
|
|
|
|
a.addEventListener('waiting', e => {
|
|
|
|
this.playing = false
|
|
|
|
this.loading = true
|
|
|
|
})
|
|
|
|
a.addEventListener('playing', e => {
|
|
|
|
this.playing = true
|
|
|
|
this.loading = false
|
|
|
|
})
|
|
|
|
a.addEventListener('ended', e => {
|
|
|
|
this.playing = false
|
|
|
|
this.loading = false
|
|
|
|
})
|
|
|
|
a.addEventListener('error', e => {
|
|
|
|
this.closeAudio()
|
|
|
|
this.$store.dispatch('add_notification', { text: 'HTTP stream error: failed to load stream or stopped loading due to network problem', type: 'danger' })
|
|
|
|
this.playing = false
|
|
|
|
this.loading = false
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
// close active audio
|
|
|
|
closeAudio: function () {
|
|
|
|
_audio.stopAudio()
|
|
|
|
this.playing = false
|
|
|
|
},
|
|
|
|
|
|
|
|
playChannel: function () {
|
|
|
|
if (this.playing) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
const channel = '/stream.mp3'
|
|
|
|
this.loading = true
|
|
|
|
_audio.playSource(channel)
|
|
|
|
_audio.setVolume(this.stream_volume / 100)
|
|
|
|
},
|
|
|
|
|
|
|
|
togglePlay: function () {
|
|
|
|
if (this.loading) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (this.playing) {
|
|
|
|
return this.closeAudio()
|
|
|
|
}
|
|
|
|
return this.playChannel()
|
|
|
|
},
|
|
|
|
|
|
|
|
set_stream_volume: function (newVolume) {
|
|
|
|
this.stream_volume = newVolume
|
|
|
|
_audio.setVolume(this.stream_volume / 100)
|
2018-08-11 01:47:10 -04:00
|
|
|
}
|
2019-02-14 06:19:29 -05:00
|
|
|
},
|
|
|
|
|
2019-02-16 00:48:45 -05:00
|
|
|
watch: {
|
|
|
|
'$store.state.player.volume' () {
|
|
|
|
if (this.player.volume > 0) {
|
|
|
|
this.old_volume = this.player.volume
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2019-02-14 06:19:29 -05:00
|
|
|
// on app mounted
|
|
|
|
mounted () {
|
|
|
|
this.setupAudio()
|
|
|
|
},
|
|
|
|
|
|
|
|
// on app destroyed
|
|
|
|
destroyed () {
|
|
|
|
this.closeAudio()
|
2018-08-11 01:47:10 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
</style>
|