mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 07:05:57 -05:00
[web-src] Add a settings page to the player web interface to change web
interface specific options
This commit is contained in:
parent
2cc310b646
commit
9ab1677f1f
@ -106,6 +106,7 @@ export default {
|
||||
vm.update_outputs()
|
||||
vm.update_player_status()
|
||||
vm.update_library_stats()
|
||||
vm.update_settings()
|
||||
vm.update_queue()
|
||||
vm.update_spotify()
|
||||
}
|
||||
@ -166,6 +167,12 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
update_settings: function () {
|
||||
webapi.settings().then(({ data }) => {
|
||||
this.$store.commit(types.UPDATE_SETTINGS, data)
|
||||
})
|
||||
},
|
||||
|
||||
update_spotify: function () {
|
||||
webapi.spotify().then(({ data }) => {
|
||||
this.$store.commit(types.UPDATE_SPOTIFY, data)
|
||||
|
@ -121,17 +121,13 @@
|
||||
|
||||
<!-- Settings drop down -->
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<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>
|
||||
<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">forked-daapd</span></a>
|
||||
|
||||
<div class="navbar-dropdown is-right">
|
||||
<a class="navbar-item" href="/admin.html">Admin</a>
|
||||
<hr class="navbar-divider">
|
||||
<navbar-item-link to="/about">
|
||||
<div>
|
||||
<p class="title is-7">forked-daapd</p>
|
||||
<p class="subtitle is-7">{{ config.version }}</p>
|
||||
</div>
|
||||
</navbar-item-link>
|
||||
<navbar-item-link to="/settings/webinterface">Settings</navbar-item-link>
|
||||
<navbar-item-link to="/about">About</navbar-item-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
202
web-src/src/pages/SettingsPageWebinterface.vue
Normal file
202
web-src/src/pages/SettingsPageWebinterface.vue
Normal file
@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<content-with-heading>
|
||||
<template slot="heading-left">
|
||||
<div class="title is-4">Settings</div>
|
||||
</template>
|
||||
|
||||
<template slot="heading-right">
|
||||
</template>
|
||||
|
||||
<template slot="content">
|
||||
<div class="heading fd-has-margin-bottom">Now playing page</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" :checked="settings_option_show_composer_now_playing" @change="set_timer_show_composer_now_playing" ref="checkbox_show_composer">
|
||||
Show composer
|
||||
<i class="is-size-7"
|
||||
:class="{
|
||||
'has-text-info': statusUpdateShowComposerNowPlaying === 'success',
|
||||
'has-text-danger': statusUpdateShowComposerNowPlaying === 'error'
|
||||
}">{{ info_option_show_composer_now_playing }}</i>
|
||||
</label>
|
||||
<p class="help has-text-justified">
|
||||
If enabled the composer of the current playing track is shown on the "now playing page"
|
||||
</p>
|
||||
</div>
|
||||
<fieldset :disabled="!settings_option_show_composer_now_playing">
|
||||
<div class="field">
|
||||
<label class="label has-text-weight-normal">
|
||||
Show composer only for listed genres
|
||||
<i class="is-size-7"
|
||||
:class="{
|
||||
'has-text-info': statusUpdateShowComposerForGenre === 'success',
|
||||
'has-text-danger': statusUpdateShowComposerForGenre === 'error'
|
||||
}">{{ info_option_show_composer_for_genre }}</i>
|
||||
</label>
|
||||
<div class="control">
|
||||
<input class="input" type="text" placeholder="Genres"
|
||||
:value="settings_option_show_composer_for_genre"
|
||||
@input="set_timer_show_composer_for_genre"
|
||||
ref="field_composer_for_genre">
|
||||
</div>
|
||||
<p class="help">
|
||||
Comma separated list of genres the composer should be displayed on the "now playing page".
|
||||
</p>
|
||||
<p class="help">
|
||||
Leave empty to always show the composer.
|
||||
</p>
|
||||
<p class="help">
|
||||
The genre tag of the current track is matched by checking, if one of the defined genres are included.
|
||||
For example setting to <code>classical, soundtrack</code> will show the composer for tracks with
|
||||
a genre tag of "Contemporary Classical".<br>
|
||||
</p>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
</template>
|
||||
</content-with-heading>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentWithHeading from '@/templates/ContentWithHeading'
|
||||
import webapi from '@/webapi'
|
||||
import * as types from '@/store/mutation_types'
|
||||
|
||||
export default {
|
||||
name: 'SettingsPageWebinterface',
|
||||
components: { ContentWithHeading },
|
||||
|
||||
data () {
|
||||
return {
|
||||
timerDelay: 2000,
|
||||
timerIdShowComposerNowPlaying: -1,
|
||||
timerIdShowComposerForGenre: -1,
|
||||
|
||||
// <empty>: default/no changes, 'success': update succesful, 'error': update failed
|
||||
statusUpdateShowComposerNowPlaying: '',
|
||||
statusUpdateShowComposerForGenre: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
settings_category_webinterface () {
|
||||
return this.$store.getters.settings_webinterface
|
||||
},
|
||||
settings_option_show_composer_now_playing () {
|
||||
return this.$store.getters.settings_option_show_composer_now_playing
|
||||
},
|
||||
settings_option_show_composer_for_genre () {
|
||||
return this.$store.getters.settings_option_show_composer_for_genre
|
||||
},
|
||||
info_option_show_composer_for_genre () {
|
||||
if (this.statusUpdateShowComposerForGenre === 'success') {
|
||||
return '(setting saved)'
|
||||
} else if (this.statusUpdateShowComposerForGenre === 'error') {
|
||||
return '(error saving setting)'
|
||||
}
|
||||
return ''
|
||||
},
|
||||
info_option_show_composer_now_playing () {
|
||||
if (this.statusUpdateShowComposerNowPlaying === 'success') {
|
||||
return '(setting saved)'
|
||||
} else if (this.statusUpdateShowComposerNowPlaying === 'error') {
|
||||
return '(error saving setting)'
|
||||
}
|
||||
return ''
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
set_timer_show_composer_now_playing () {
|
||||
if (this.timerIdShowComposerNowPlaying > 0) {
|
||||
window.clearTimeout(this.timerIdShowComposerNowPlaying)
|
||||
this.timerIdShowComposerNowPlaying = -1
|
||||
}
|
||||
|
||||
this.statusUpdateShowComposerNowPlaying = ''
|
||||
const newValue = this.$refs.checkbox_show_composer.checked
|
||||
if (newValue !== this.settings_option_show_composer_now_playing) {
|
||||
this.timerIdShowComposerNowPlaying = window.setTimeout(this.update_show_composer_now_playing, this.timerDelay)
|
||||
}
|
||||
},
|
||||
|
||||
update_show_composer_now_playing () {
|
||||
this.timerIdShowComposerNowPlaying = -1
|
||||
|
||||
const newValue = this.$refs.checkbox_show_composer.checked
|
||||
if (newValue === this.settings_option_show_composer_now_playing) {
|
||||
this.statusUpdateShowComposerNowPlaying = ''
|
||||
return
|
||||
}
|
||||
|
||||
const option = {
|
||||
category: this.settings_category_webinterface.name,
|
||||
name: 'show_composer_now_playing',
|
||||
value: newValue
|
||||
}
|
||||
webapi.settings_update(this.settings_category_webinterface.name, option).then(() => {
|
||||
this.$store.commit(types.UPDATE_SETTINGS_OPTION, option)
|
||||
this.statusUpdateShowComposerNowPlaying = 'success'
|
||||
}).catch(() => {
|
||||
this.statusUpdateShowComposerNowPlaying = 'error'
|
||||
this.$refs.checkbox_show_composer.checked = this.settings_option_show_composer_now_playing
|
||||
}).finally(() => {
|
||||
this.timerIdShowComposerNowPlaying = window.setTimeout(this.clear_status_show_composer_now_playing, this.timerDelay)
|
||||
})
|
||||
},
|
||||
|
||||
set_timer_show_composer_for_genre () {
|
||||
if (this.timerIdShowComposerForGenre > 0) {
|
||||
window.clearTimeout(this.timerIdShowComposerForGenre)
|
||||
this.timerIdShowComposerForGenre = -1
|
||||
}
|
||||
|
||||
this.statusUpdateShowComposerForGenre = ''
|
||||
const newValue = this.$refs.field_composer_for_genre.value
|
||||
if (newValue !== this.settings_option_show_composer_for_genre) {
|
||||
this.timerIdShowComposerForGenre = window.setTimeout(this.update_show_composer_for_genre, this.timerDelay)
|
||||
}
|
||||
},
|
||||
|
||||
update_show_composer_for_genre () {
|
||||
this.timerIdShowComposerForGenre = -1
|
||||
|
||||
const newValue = this.$refs.field_composer_for_genre.value
|
||||
if (newValue === this.settings_option_show_composer_for_genre) {
|
||||
this.statusUpdateShowComposerForGenre = ''
|
||||
return
|
||||
}
|
||||
|
||||
const option = {
|
||||
category: this.settings_category_webinterface.name,
|
||||
name: 'show_composer_for_genre',
|
||||
value: newValue
|
||||
}
|
||||
webapi.settings_update(this.settings_category_webinterface.name, option).then(() => {
|
||||
this.$store.commit(types.UPDATE_SETTINGS_OPTION, option)
|
||||
this.statusUpdateShowComposerForGenre = 'success'
|
||||
}).catch(() => {
|
||||
this.statusUpdateShowComposerForGenre = 'error'
|
||||
this.$refs.field_composer_for_genre.value = this.settings_option_show_composer_for_genre
|
||||
}).finally(() => {
|
||||
this.timerIdShowComposerForGenre = window.setTimeout(this.clear_status_show_composer_for_genre, this.timerDelay)
|
||||
})
|
||||
},
|
||||
|
||||
clear_status_show_composer_for_genre () {
|
||||
this.statusUpdateShowComposerForGenre = ''
|
||||
},
|
||||
|
||||
clear_status_show_composer_now_playing () {
|
||||
this.statusUpdateShowComposerNowPlaying = ''
|
||||
}
|
||||
},
|
||||
|
||||
filters: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
@ -31,6 +31,7 @@ import SpotifyPageArtist from '@/pages/SpotifyPageArtist'
|
||||
import SpotifyPageAlbum from '@/pages/SpotifyPageAlbum'
|
||||
import SpotifyPagePlaylist from '@/pages/SpotifyPagePlaylist'
|
||||
import SpotifyPageSearch from '@/pages/SpotifyPageSearch'
|
||||
import SettingsPageWebinterface from '@/pages/SettingsPageWebinterface'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
@ -212,6 +213,11 @@ export const router = new VueRouter({
|
||||
path: '/search/spotify',
|
||||
name: 'Spotify Search',
|
||||
component: SpotifyPageSearch
|
||||
},
|
||||
{
|
||||
path: '/settings/webinterface',
|
||||
name: 'Settings Webinterface',
|
||||
component: SettingsPageWebinterface
|
||||
}
|
||||
],
|
||||
scrollBehavior (to, from, savedPosition) {
|
||||
|
@ -11,6 +11,9 @@ export default new Vuex.Store({
|
||||
'version': '',
|
||||
'buildoptions': [ ]
|
||||
},
|
||||
settings: {
|
||||
'categories': []
|
||||
},
|
||||
library: {
|
||||
'artists': 0,
|
||||
'albums': 0,
|
||||
@ -58,6 +61,33 @@ export default new Vuex.Store({
|
||||
return item.id === state.player.item_id
|
||||
})
|
||||
return (item === undefined) ? {} : item
|
||||
},
|
||||
|
||||
settings_webinterface: state => {
|
||||
if (state.settings) {
|
||||
return state.settings.categories.find(elem => elem.name === 'webinterface')
|
||||
}
|
||||
return null
|
||||
},
|
||||
|
||||
settings_option_show_composer_now_playing: (state, getters) => {
|
||||
if (getters.settings_webinterface) {
|
||||
const option = getters.settings_webinterface.options.find(elem => elem.name === 'show_composer_now_playing')
|
||||
if (option) {
|
||||
return option.value
|
||||
}
|
||||
}
|
||||
return false
|
||||
},
|
||||
|
||||
settings_option_show_composer_for_genre: (state, getters) => {
|
||||
if (getters.settings_webinterface) {
|
||||
const option = getters.settings_webinterface.options.find(elem => elem.name === 'show_composer_for_genre')
|
||||
if (option) {
|
||||
return option.value
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
|
||||
@ -65,6 +95,14 @@ export default new Vuex.Store({
|
||||
[types.UPDATE_CONFIG] (state, config) {
|
||||
state.config = config
|
||||
},
|
||||
[types.UPDATE_SETTINGS] (state, settings) {
|
||||
state.settings = settings
|
||||
},
|
||||
[types.UPDATE_SETTINGS_OPTION] (state, option) {
|
||||
const settingCategory = state.settings.categories.find(elem => elem.name === option.category)
|
||||
const settingOption = settingCategory.options.find(elem => elem.name === option.name)
|
||||
settingOption.value = option.value
|
||||
},
|
||||
[types.UPDATE_LIBRARY_STATS] (state, libraryStats) {
|
||||
state.library = libraryStats
|
||||
},
|
||||
|
@ -1,4 +1,6 @@
|
||||
export const UPDATE_CONFIG = 'UPDATE_CONFIG'
|
||||
export const UPDATE_SETTINGS = 'UPDATE_SETTINGS'
|
||||
export const UPDATE_SETTINGS_OPTION = 'UPDATE_SETTINGS_OPTION'
|
||||
export const UPDATE_LIBRARY_STATS = 'UPDATE_LIBRARY_STATS'
|
||||
export const UPDATE_LIBRARY_AUDIOBOOKS_COUNT = 'UPDATE_LIBRARY_AUDIOBOOKS_COUNT'
|
||||
export const UPDATE_LIBRARY_PODCASTS_COUNT = 'UPDATE_LIBRARY_PODCASTS_COUNT'
|
||||
|
@ -13,6 +13,14 @@ export default {
|
||||
return axios.get('/api/config')
|
||||
},
|
||||
|
||||
settings () {
|
||||
return axios.get('/api/settings')
|
||||
},
|
||||
|
||||
settings_update (categoryName, option) {
|
||||
return axios.put('/api/settings/' + categoryName + '/' + option.name, option)
|
||||
},
|
||||
|
||||
library_stats () {
|
||||
return axios.get('/api/library')
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user