Merge pull request #1104 from chme/web_next

Player web interface v0.8.1
This commit is contained in:
Christian Meffert 2020-10-19 06:15:40 +02:00 committed by GitHub
commit 9a3840f507
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1497 additions and 1249 deletions

View File

@ -1 +1 @@
<!DOCTYPE html><html class="has-navbar-fixed-top has-navbar-fixed-bottom"><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>forked-daapd-web 2</title><link rel=apple-touch-icon sizes=120x120 href=apple-touch-icon.png?ver1.1><link rel=icon type=image/png sizes=32x32 href=favicon-32x32.png><link rel=icon type=image/png sizes=16x16 href=favicon-16x16.png><link rel=manifest href=site.webmanifest><link rel=mask-icon href=safari-pinned-tab.svg color=#5bbad5><meta name=msapplication-TileColor content=#da532c><meta name=theme-color content=#ffffff><link href=player/css/app.css rel=preload as=style><link href=player/css/chunk-vendors.css rel=preload as=style><link href=player/js/app.js rel=modulepreload as=script><link href=player/js/chunk-vendors.js rel=modulepreload as=script><link href=player/css/chunk-vendors.css rel=stylesheet><link href=player/css/app.css rel=stylesheet></head><body><div id=app></div><script type=module src=player/js/chunk-vendors.js></script><script type=module src=player/js/app.js></script><script>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script><script src=player/js/chunk-vendors-legacy.js nomodule></script><script src=player/js/app-legacy.js nomodule></script></body></html>
<!DOCTYPE html><html class="has-navbar-fixed-top has-navbar-fixed-bottom"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>forked-daapd-web 2</title><link rel="apple-touch-icon" sizes="120x120" href="apple-touch-icon.png?ver1.1"><link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png"><link rel="manifest" href="site.webmanifest"><link rel="mask-icon" href="safari-pinned-tab.svg" color="#5bbad5"><meta name="msapplication-TileColor" content="#da532c"><meta name="theme-color" content="#ffffff"><link href="player/css/app.css" rel="preload" as="style"><link href="player/css/chunk-vendors.css" rel="preload" as="style"><link href="player/js/app.js" rel="modulepreload" as="script"><link href="player/js/chunk-vendors.js" rel="modulepreload" as="script"><link href="player/css/chunk-vendors.css" rel="stylesheet"><link href="player/css/app.css" rel="stylesheet"></head><body><div id="app"></div><script type="module" src="player/js/chunk-vendors.js"></script><script type="module" src="player/js/app.js"></script><script>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()},!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script><script src="player/js/chunk-vendors-legacy.js" nomodule></script><script src="player/js/app-legacy.js" nomodule></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2162
web-src/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "forked-daapd-web",
"version": "0.8.0",
"version": "0.8.1",
"private": true,
"description": "forked-daapd web interface",
"author": "chme <christian.meffert@googlemail.com>",
@ -12,11 +12,11 @@
},
"dependencies": {
"axios": "^0.20.0",
"bulma": "^0.9.0",
"bulma": "^0.9.1",
"bulma-switch": "^2.0.0",
"core-js": "^3.6.5",
"mdi": "^2.2.43",
"moment": "^2.28.0",
"moment": "^2.29.1",
"moment-duration-format": "^2.3.2",
"npm": "^6.14.8",
"reconnectingwebsocket": "^1.0.0",
@ -28,26 +28,26 @@
"vue-observe-visibility": "^0.4.6",
"vue-progressbar": "^0.7.5",
"vue-range-slider": "^0.6.0",
"vue-router": "^3.4.3",
"vue-scrollto": "^2.18.2",
"vue-router": "^3.4.7",
"vue-scrollto": "^2.19.1",
"vue-tiny-lazyload-img": "^0.1.0",
"vuedraggable": "^2.24.1",
"vuedraggable": "^2.24.2",
"vuex": "^3.5.1"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.6",
"@vue/cli-plugin-eslint": "^4.5.6",
"@vue/cli-service": "^4.5.6",
"@vue/cli-plugin-babel": "^4.5.7",
"@vue/cli-plugin-eslint": "^4.5.7",
"@vue/cli-service": "^4.5.7",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "^7.9.0",
"eslint-plugin-import": "^2.22.0",
"eslint": "^7.11.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.26.11",
"sass-loader": "^10.0.2",
"eslint-plugin-vue": "^7.0.1",
"sass": "^1.27.0",
"sass-loader": "^10.0.3",
"vue-template-compiler": "^2.6.12"
},
"license": "GPL-2.0"

View File

@ -9,6 +9,10 @@
<div style="margin-top:0.7rem;">
<h1 class="title is-6">{{ props.album.name }}</h1>
<h2 class="subtitle is-7 has-text-grey"><b>{{ props.album.artist }}</b></h2>
<h2 class="subtitle is-7 has-text-grey has-text-weight-normal"
v-if="props.album.date_released && props.album.media_kind === 'music'">
{{ props.album.date_released | time('L') }}
</h2>
</div>
</div>
<div class="media-right" style="padding-top:0.7rem;">

View File

@ -13,7 +13,7 @@
</div>
<footer class="card-footer">
<a class="card-footer-item has-text-dark" @click="$emit('close')">
<span class="icon"><i class="mdi mdi-cancel"></i></span> <span class="is-size-7">Cancel</span>
<span class="icon"><i class="mdi mdi-cancel"></i></span> <span class="is-size-7">{{ close_action ? close_action : 'Cancel' }}</span>
</a>
<a v-if="delete_action" class="card-footer-item has-background-danger has-text-white has-text-weight-bold" @click="$emit('delete')">
<span class="icon"><i class="mdi mdi-delete"></i></span> <span class="is-size-7">{{ delete_action }}</span>
@ -33,7 +33,7 @@
<script>
export default {
name: 'ModalDialog',
props: ['show', 'title', 'ok_action', 'delete_action']
props: ['show', 'title', 'ok_action', 'delete_action', 'close_action']
}
</script>

View File

@ -60,7 +60,7 @@ export default {
this.loading = true
webapi.library_add(this.url).then(() => {
this.$emit('close')
this.$emit('podcast_added')
this.$emit('podcast-added')
this.url = ''
}).catch(() => {
this.loading = false

View File

@ -131,7 +131,7 @@ export default {
mark_played: function () {
webapi.library_album_track_update(this.album.id, { play_count: 'played' }).then(({ data }) => {
this.$emit('play_count_changed')
this.$emit('play-count-changed')
this.$emit('close')
})
},

View File

@ -158,14 +158,14 @@ export default {
mark_new: function () {
webapi.library_track_update(this.track.id, { play_count: 'reset' }).then(() => {
this.$emit('play_count_changed')
this.$emit('play-count-changed')
this.$emit('close')
})
},
mark_played: function () {
webapi.library_track_update(this.track.id, { play_count: 'increment' }).then(() => {
this.$emit('play_count_changed')
this.$emit('play-count-changed')
this.$emit('close')
})
}

View File

@ -36,7 +36,7 @@
<div class="navbar-end">
<!-- Settings drop down -->
<!-- Burger menu entries -->
<div class="navbar-item has-dropdown is-hoverable"
:class="{ 'is-active': show_settings_menu }"
@click="on_click_outside_settings">
@ -61,7 +61,10 @@
<hr class="fd-navbar-divider">
<navbar-item-link to="/settings/webinterface">Settings</navbar-item-link>
<navbar-item-link to="/about">Update Library</navbar-item-link>
<a class="navbar-item" @click.stop.prevent="show_update_library = true; show_settings_menu = false; show_burger_menu = false">
Update Library
</a>
<navbar-item-link to="/about">About</navbar-item-link>
<div class="navbar-item is-hidden-desktop" style="margin-bottom: 2.5rem;"></div>
</div>
@ -69,6 +72,29 @@
</div>
</div>
<modal-dialog
:show="show_update_library"
title="Update library"
:ok_action="library.updating ? '' : 'Rescan'"
close_action="Close"
@ok="update_library"
@close="show_update_library = false">
<template slot="modal-content">
<div v-if="!library.updating">
<p class="mb-3">Scan for new, deleted and modified files</p>
<div class="field">
<label class="checkbox is-size-7 is-small">
<input type="checkbox" v-model="rescan_metadata">
Rescan metadata for unmodified files
</label>
</div>
</div>
<div v-else>
<p class="mb-3">Library update in progress ...</p>
</div>
</template>
</modal-dialog>
<div class="is-overlay" v-show="show_settings_menu"
style="z-index:10; width: 100vw; height:100vh;"
@click="show_settings_menu = false"></div>
@ -77,15 +103,19 @@
<script>
import NavbarItemLink from './NavbarItemLink'
import ModalDialog from '@/components/ModalDialog'
import * as types from '@/store/mutation_types'
import webapi from '@/webapi'
export default {
name: 'NavbarTop',
components: { NavbarItemLink },
components: { NavbarItemLink, ModalDialog },
data () {
return {
show_settings_menu: false
show_settings_menu: false,
show_update_library: false,
rescan_metadata: false
}
},
@ -160,6 +190,14 @@ export default {
methods: {
on_click_outside_settings () {
this.show_settings_menu = !this.show_settings_menu
},
update_library () {
if (this.rescan_metadata) {
webapi.library_rescan()
} else {
webapi.library_update()
}
}
},

View File

@ -21,6 +21,8 @@ export default class Albums {
return album.time_added.substring(0, 4)
} else if (this.options.sort === 'Recently released') {
return album.date_released ? album.date_released.substring(0, 4) : '0000'
} else if (this.options.sort === 'Release date') {
return album.date_released ? album.date_released.substring(0, 4) : '0000'
}
return album.name_sort.charAt(0).toUpperCase()
}
@ -57,6 +59,16 @@ export default class Albums {
}
return b.date_released.localeCompare(a.date_released)
})
} else if (this.options.sort === 'Release date') {
albumsSorted = [...albumsSorted].sort((a, b) => {
if (!a.date_released) {
return -1
}
if (!b.date_released) {
return 1
}
return a.date_released.localeCompare(b.date_released)
})
}
this.sortedAndFiltered = albumsSorted
}

View File

@ -151,6 +151,9 @@ section.hero + section.fd-content {
min-width: 0;
min-height: 0;
overflow: hidden;
/* Padding matches the drop-shadow size of the image */
padding: 10px;
}
.fd-cover-image img {

View File

@ -1,5 +1,13 @@
<template>
<content-with-heading>
<template slot="options">
<div class="columns">
<div class="column">
<p class="heading" style="margin-bottom: 24px;">Sort by</p>
<dropdown-menu v-model="sort" :options="sort_options"></dropdown-menu>
</div>
</div>
</template>
<template slot="heading-left">
<p class="title is-4">{{ artist.name }}</p>
</template>
@ -15,7 +23,7 @@
</template>
<template slot="content">
<p class="heading has-text-centered-mobile">{{ artist.album_count }} albums | <a class="has-text-link" @click="open_tracks">{{ artist.track_count }} tracks</a></p>
<list-albums :albums="albums.items"></list-albums>
<list-albums :albums="albums_list"></list-albums>
<modal-dialog-artist :show="show_artist_details_modal" :artist="artist" @close="show_artist_details_modal = false" />
</template>
</content-with-heading>
@ -26,7 +34,10 @@ import { LoadDataBeforeEnterMixin } from './mixin'
import ContentWithHeading from '@/templates/ContentWithHeading'
import ListAlbums from '@/components/ListAlbums'
import ModalDialogArtist from '@/components/ModalDialogArtist'
import DropdownMenu from '@/components/DropdownMenu'
import webapi from '@/webapi'
import * as types from '@/store/mutation_types'
import Albums from '@/lib/Albums'
const artistData = {
load: function (to) {
@ -45,17 +56,36 @@ const artistData = {
export default {
name: 'PageArtist',
mixins: [LoadDataBeforeEnterMixin(artistData)],
components: { ContentWithHeading, ListAlbums, ModalDialogArtist },
components: { ContentWithHeading, ListAlbums, ModalDialogArtist, DropdownMenu },
data () {
return {
artist: {},
albums: {},
albums: { items: [] },
sort_options: ['Name', 'Release date'],
show_artist_details_modal: false
}
},
computed: {
albums_list () {
return new Albums(this.albums.items, {
sort: this.sort,
group: false
})
},
sort: {
get () {
return this.$store.state.artist_albums_sort
},
set (value) {
this.$store.commit(types.ARTIST_ALBUMS_SORT, value)
}
}
},
methods: {
open_tracks: function () {
this.$router.push({ path: '/music/artists/' + this.artist.id + '/tracks' })

View File

@ -69,8 +69,8 @@ export default {
data () {
return {
recently_added: {},
recently_played: {},
recently_added: { items: [] },
recently_played: { items: [] },
show_track_details_modal: false,
selected_track: {}

View File

@ -40,14 +40,14 @@
:show="show_details_modal"
:track="selected_track"
@close="show_details_modal = false"
@play_count_changed="reload_tracks" />
@play-count-changed="reload_tracks" />
<modal-dialog-album
:show="show_album_details_modal"
:album="album"
:media_kind="'podcast'"
:new_tracks="new_tracks"
@close="show_album_details_modal = false"
@play_count_changed="reload_tracks"
@play-count-changed="reload_tracks"
@remove_podcast="open_remove_podcast_dialog" />
<modal-dialog
:show="show_remove_podcast_modal"

View File

@ -32,7 +32,7 @@
</a>
</template>
</list-item-track>
<modal-dialog-track :show="show_track_details_modal" :track="selected_track" @close="show_track_details_modal = false" @play_count_changed="reload_new_episodes" />
<modal-dialog-track :show="show_track_details_modal" :track="selected_track" @close="show_track_details_modal = false" @play-count-changed="reload_new_episodes" />
</template>
</content-with-heading>
@ -53,13 +53,13 @@
</template>
<template slot="content">
<list-albums :albums="albums.items"
@play_count_changed="reload_new_episodes()"
@play-count-changed="reload_new_episodes()"
@podcast-deleted="reload_podcasts()">
</list-albums>
<modal-dialog-add-rss
:show="show_url_modal"
@close="show_url_modal = false"
@podcast_added="reload_podcasts()" />
@podcast-added="reload_podcasts()" />
</template>
</content-with-heading>
</div>
@ -96,7 +96,7 @@ export default {
data () {
return {
albums: {},
albums: { items: [] },
new_episodes: { items: [] },
show_url_modal: false,

View File

@ -29,7 +29,7 @@
<tabs-search></tabs-search>
<!-- Tracks -->
<content-with-heading v-if="show_tracks">
<content-with-heading v-if="show_tracks && tracks.total">
<template slot="heading-left">
<p class="title is-4">Tracks</p>
</template>
@ -42,12 +42,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_tracks">Show all {{ tracks.total.toLocaleString() }} tracks</a>
</p>
</nav>
<p v-if="!tracks.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_tracks && !tracks.total" class="mt-6">
<template slot="content">
<p><i>No tracks found</i></p>
</template>
</content-text>
<!-- Artists -->
<content-with-heading v-if="show_artists">
<content-with-heading v-if="show_artists && artists.total">
<template slot="heading-left">
<p class="title is-4">Artists</p>
</template>
@ -60,12 +64,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_artists">Show all {{ artists.total.toLocaleString() }} artists</a>
</p>
</nav>
<p v-if="!artists.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_artists && !artists.total">
<template slot="content">
<p><i>No artists found</i></p>
</template>
</content-text>
<!-- Albums -->
<content-with-heading v-if="show_albums">
<content-with-heading v-if="show_albums && albums.total">
<template slot="heading-left">
<p class="title is-4">Albums</p>
</template>
@ -78,12 +86,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_albums">Show all {{ albums.total.toLocaleString() }} albums</a>
</p>
</nav>
<p v-if="!albums.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_albums && !albums.total">
<template slot="content">
<p><i>No albums found</i></p>
</template>
</content-text>
<!-- Playlists -->
<content-with-heading v-if="show_playlists">
<content-with-heading v-if="show_playlists && playlists.total">
<template slot="heading-left">
<p class="title is-4">Playlists</p>
</template>
@ -96,12 +108,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_playlists">Show all {{ playlists.total.toLocaleString() }} playlists</a>
</p>
</nav>
<p v-if="!playlists.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_playlists && !playlists.total">
<template slot="content">
<p><i>No playlists found</i></p>
</template>
</content-text>
<!-- Podcasts -->
<content-with-heading v-if="show_podcasts">
<content-with-heading v-if="show_podcasts && podcasts.total">
<template slot="heading-left">
<p class="title is-4">Podcasts</p>
</template>
@ -114,12 +130,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_podcasts">Show all {{ podcasts.total.toLocaleString() }} podcasts</a>
</p>
</nav>
<p v-if="!podcasts.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_podcasts && !podcasts.total">
<template slot="content">
<p><i>No podcasts found</i></p>
</template>
</content-text>
<!-- Audiobooks -->
<content-with-heading v-if="show_audiobooks">
<content-with-heading v-if="show_audiobooks && audiobooks.total">
<template slot="heading-left">
<p class="title is-4">Audiobooks</p>
</template>
@ -132,14 +152,19 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_audiobooks">Show all {{ audiobooks.total.toLocaleString() }} audiobooks</a>
</p>
</nav>
<p v-if="!audiobooks.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_audiobooks && !audiobooks.total">
<template slot="content">
<p><i>No audiobooks found</i></p>
</template>
</content-text>
</div>
</template>
<script>
import ContentWithHeading from '@/templates/ContentWithHeading'
import ContentText from '@/templates/ContentText'
import TabsSearch from '@/components/TabsSearch'
import ListTracks from '@/components/ListTracks'
import ListArtists from '@/components/ListArtists'
@ -150,7 +175,7 @@ import * as types from '@/store/mutation_types'
export default {
name: 'PageSearch',
components: { ContentWithHeading, TabsSearch, ListTracks, ListArtists, ListAlbums, ListPlaylists },
components: { ContentWithHeading, ContentText, TabsSearch, ListTracks, ListArtists, ListAlbums, ListPlaylists },
data () {
return {
@ -225,6 +250,7 @@ export default {
return
}
this.search_query = route.query.query
this.searchMusic(route.query)
this.searchAudiobooks(route.query)
this.searchPodcasts(route.query)

View File

@ -12,7 +12,7 @@
Select the top navigation bar menu items
</p>
<div class="notification is-size-7">
Be aware that if you select more items than can be shown on your screen will result in the burger menu item to disapear.
If you select more items than can be shown on your screen then the burger menu will disappear.
</div>
<settings-checkbox category_name="webinterface" option_name="show_menu_item_playlists">
<template slot="label"> Playlists</template>

View File

@ -26,7 +26,7 @@
<tabs-search></tabs-search>
<!-- Tracks -->
<content-with-heading v-if="show_tracks">
<content-with-heading v-if="show_tracks && tracks.total">
<template slot="heading-left">
<p class="title is-4">Tracks</p>
</template>
@ -47,12 +47,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_tracks">Show all {{ tracks.total.toLocaleString() }} tracks</a>
</p>
</nav>
<p v-if="!tracks.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_tracks && !tracks.total" class="mt-6">
<template slot="content">
<p><i>No tracks found</i></p>
</template>
</content-text>
<!-- Artists -->
<content-with-heading v-if="show_artists">
<content-with-heading v-if="show_artists && artists.total">
<template slot="heading-left">
<p class="title is-4">Artists</p>
</template>
@ -73,12 +77,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_artists">Show all {{ artists.total.toLocaleString() }} artists</a>
</p>
</nav>
<p v-if="!artists.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_artists && !artists.total">
<template slot="content">
<p><i>No artists found</i></p>
</template>
</content-text>
<!-- Albums -->
<content-with-heading v-if="show_albums">
<content-with-heading v-if="show_albums && albums.total">
<template slot="heading-left">
<p class="title is-4">Albums</p>
</template>
@ -112,12 +120,16 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_albums">Show all {{ albums.total.toLocaleString() }} albums</a>
</p>
</nav>
<p v-if="!albums.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_albums && !albums.total">
<template slot="content">
<p><i>No albums found</i></p>
</template>
</content-text>
<!-- Playlists -->
<content-with-heading v-if="show_playlists">
<content-with-heading v-if="show_playlists && playlists.total">
<template slot="heading-left">
<p class="title is-4">Playlists</p>
</template>
@ -138,14 +150,19 @@
<a class="button is-light is-small is-rounded" v-on:click="open_search_playlists">Show all {{ playlists.total.toLocaleString() }} playlists</a>
</p>
</nav>
<p v-if="!playlists.total">No results</p>
</template>
</content-with-heading>
<content-text v-if="show_playlists && !playlists.total">
<template slot="content">
<p><i>No playlists found</i></p>
</template>
</content-text>
</div>
</template>
<script>
import ContentWithHeading from '@/templates/ContentWithHeading'
import ContentText from '@/templates/ContentText'
import TabsSearch from '@/components/TabsSearch'
import SpotifyListItemTrack from '@/components/SpotifyListItemTrack'
import SpotifyListItemArtist from '@/components/SpotifyListItemArtist'
@ -163,7 +180,7 @@ import InfiniteLoading from 'vue-infinite-loading'
export default {
name: 'SpotifyPageSearch',
components: { ContentWithHeading, TabsSearch, SpotifyListItemTrack, SpotifyListItemArtist, SpotifyListItemAlbum, SpotifyListItemPlaylist, SpotifyModalDialogTrack, SpotifyModalDialogArtist, SpotifyModalDialogAlbum, SpotifyModalDialogPlaylist, InfiniteLoading, CoverArtwork },
components: { ContentWithHeading, ContentText, TabsSearch, SpotifyListItemTrack, SpotifyListItemArtist, SpotifyListItemAlbum, SpotifyListItemPlaylist, SpotifyModalDialogTrack, SpotifyModalDialogArtist, SpotifyModalDialogAlbum, SpotifyModalDialogPlaylist, InfiniteLoading, CoverArtwork },
data () {
return {
@ -248,6 +265,7 @@ export default {
return
}
this.search_query = this.query.query
this.search_param.limit = this.query.limit ? this.query.limit : 50
this.search_param.offset = this.query.offset ? this.query.offset : 0

View File

@ -90,7 +90,7 @@ export const router = new VueRouter({
path: '/music/artists/:artist_id',
name: 'Artist',
component: PageArtist,
meta: { show_progress: true }
meta: { show_progress: true, has_index: true }
},
{
path: '/music/artists/:artist_id/tracks',

View File

@ -55,6 +55,7 @@ export default new Vuex.Store({
hide_singles: false,
hide_spotify: false,
artists_sort: 'Name',
artist_albums_sort: 'Name',
albums_sort: 'Name',
show_only_next_items: false,
show_burger_menu: false,
@ -192,6 +193,9 @@ export default new Vuex.Store({
[types.ARTISTS_SORT] (state, sort) {
state.artists_sort = sort
},
[types.ARTIST_ALBUMS_SORT] (state, sort) {
state.artist_albums_sort = sort
},
[types.ALBUMS_SORT] (state, sort) {
state.albums_sort = sort
},

View File

@ -21,6 +21,7 @@ export const ADD_RECENT_SEARCH = 'ADD_RECENT_SEARCH'
export const HIDE_SINGLES = 'HIDE_SINGLES'
export const HIDE_SPOTIFY = 'HIDE_SPOTIFY'
export const ARTISTS_SORT = 'ARTISTS_SORT'
export const ARTIST_ALBUMS_SORT = 'ARTIST_ALBUMS_SORT'
export const ALBUMS_SORT = 'ALBUMS_SORT'
export const SHOW_ONLY_NEXT_ITEMS = 'SHOW_ONLY_NEXT_ITEMS'
export const SHOW_BURGER_MENU = 'SHOW_BURGER_MENU'

View File

@ -0,0 +1,20 @@
<template>
<section class="section fd-content py-3">
<div class="container">
<div class="columns is-centered">
<div class="column is-four-fifths">
<slot name="content"></slot>
</div>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'ContentText'
}
</script>
<style>
</style>

View File

@ -4,7 +4,7 @@
<div class="columns is-centered">
<div class="column is-four-fifths">
<section v-if="$slots['options']">
<div v-observe-visibility="observer_options"></div>
<div v-observe-visibility="observer_options" style="height:2px;"></div>
<slot name="options"></slot>
<nav class="buttons is-centered" style="margin-bottom: 6px; margin-top: 16px;">
<a v-if="!options_visible" class="button is-small is-white" @click="scroll_to_top"><span class="icon is-small"><i class="mdi mdi-chevron-up"></i></span></a>