Compare commits

...

10 Commits

Author SHA1 Message Date
github-actions[bot] 1e73ba4754 [web] Rebuild web interface 2024-04-23 20:04:32 +00:00
Alain Nussbaumer b20bdda8e9 [web] Lint source code 2024-04-23 22:02:18 +02:00
Alain Nussbaumer 7d7d38b946 [web] Fix untranslated button 2024-04-23 21:44:35 +02:00
Alain Nussbaumer 4268f41a51 [web] Fix bug preventing the removal of a podcast 2024-04-23 21:14:37 +02:00
Alain Nussbaumer bab6146345 [web] Lint source code 2024-04-23 20:52:57 +02:00
Alain Nussbaumer 978e344ce2 [web] Lint source code 2024-04-23 20:33:42 +02:00
Alain Nussbaumer f156bb357a [web] Lint source code 2024-04-23 20:27:50 +02:00
Alain Nussbaumer 3f3ab829c0 [web] Lint source code 2024-04-23 20:26:08 +02:00
Alain Nussbaumer 195135b1b6 [web] Lint source code 2024-04-23 20:16:11 +02:00
Alain Nussbaumer 4c70105b5e [web] Simplify naming of component property 2024-04-23 20:10:59 +02:00
27 changed files with 65 additions and 65 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -19,7 +19,6 @@ export default [
rules: { rules: {
camelcase: 'off', camelcase: 'off',
'consistent-this': 'off', 'consistent-this': 'off',
'default-param-last': 'off',
'id-length': 'off', 'id-length': 'off',
'max-lines': 'off', 'max-lines': 'off',
'max-lines-per-function': 'off', 'max-lines-per-function': 'off',
@ -32,15 +31,11 @@ export default [
'no-shadow': 'off', 'no-shadow': 'off',
'no-ternary': 'off', 'no-ternary': 'off',
'no-undef': 'off', 'no-undef': 'off',
'no-undefined': 'off',
'no-unused-expressions': 'off',
'no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }], 'no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }],
'no-useless-assignment': 'off', 'no-useless-assignment': 'off',
'one-var': 'off', 'one-var': 'off',
'prefer-destructuring': 'off',
'prefer-named-capture-group': 'off', 'prefer-named-capture-group': 'off',
'sort-keys': 'off', 'sort-keys': 'off',
'sort-vars': 'off',
'vue/html-self-closing': 'off', 'vue/html-self-closing': 'off',
'vue/max-attributes-per-line': 'off', 'vue/max-attributes-per-line': 'off',
'vue/prop-name-casing': 'off', 'vue/prop-name-casing': 'off',

View File

@ -144,19 +144,15 @@ export default {
protocol = 'wss://' protocol = 'wss://'
} }
let wsUrl = `${protocol + window.location.hostname}:${ let wsUrl = `${protocol}${window.location.hostname}:${this.$store.state.config.websocket_port}`
this.$store.state.config.websocket_port
}`
if (import.meta.env.DEV && import.meta.env.VITE_OWNTONE_URL) { if (import.meta.env.DEV && import.meta.env.VITE_OWNTONE_URL) {
/* /*
* If we are running in development mode, construct the websocket * If we are running in development mode, construct the websocket
* url from the host of the environment variable VITE_OWNTONE_URL * url from the host of the environment variable VITE_OWNTONE_URL
*/ */
const owntoneUrl = new URL(import.meta.env.VITE_OWNTONE_URL) const url = new URL(import.meta.env.VITE_OWNTONE_URL)
wsUrl = `${protocol + owntoneUrl.hostname}:${ wsUrl = `${protocol}${url.hostname}:${this.$store.state.config.websocket_port}`
this.$store.state.config.websocket_port
}`
} }
const socket = new ReconnectingWebSocket(wsUrl, 'notify', { const socket = new ReconnectingWebSocket(wsUrl, 'notify', {

View File

@ -1,6 +1,6 @@
<template> <template>
<figure> <figure>
<img v-lazy="{ src: artwork_url, lifecycle }" @click="$emit('click')" /> <img v-lazy="{ src: url, lifecycle }" @click="$emit('click')" />
</figure> </figure>
</template> </template>
@ -12,7 +12,7 @@ export default {
props: { props: {
album: { default: '', type: String }, album: { default: '', type: String },
artist: { default: '', type: String }, artist: { default: '', type: String },
artwork_url: { default: '', type: String } url: { default: '', type: String }
}, },
emits: ['click'], emits: ['click'],

View File

@ -10,7 +10,7 @@
<div v-else class="media is-align-items-center" @click="open(item.item)"> <div v-else class="media is-align-items-center" @click="open(item.item)">
<div v-if="show_artwork" class="media-left"> <div v-if="show_artwork" class="media-left">
<cover-artwork <cover-artwork
:artwork_url="item.item.artwork_url" :url="item.item.artwork_url"
:artist="item.item.artist" :artist="item.item.artist"
:album="item.item.name" :album="item.item.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-small-image" class="is-clickable fd-has-shadow fd-cover fd-cover-small-image"
@ -47,6 +47,7 @@
@play-count-changed="play_count_changed()" @play-count-changed="play_count_changed()"
/> />
<modal-dialog <modal-dialog
:close_action="$t('page.podcast.cancel')"
:delete_action="$t('page.podcast.remove')" :delete_action="$t('page.podcast.remove')"
:show="show_remove_podcast_modal" :show="show_remove_podcast_modal"
:title="$t('page.podcast.remove-podcast')" :title="$t('page.podcast.remove-podcast')"
@ -120,7 +121,7 @@ export default {
}, },
open_remove_podcast_dialog() { open_remove_podcast_dialog() {
webapi webapi
.library_album_tracks(this.selected_album.id, { limit: 1 }) .library_album_tracks(this.selected_item.id, { limit: 1 })
.then(({ data }) => { .then(({ data }) => {
webapi.library_track_playlists(data.items[0].id).then(({ data }) => { webapi.library_track_playlists(data.items[0].id).then(({ data }) => {
;[this.rss_playlist_to_remove] = data.items.filter( ;[this.rss_playlist_to_remove] = data.items.filter(

View File

@ -3,7 +3,7 @@
<div class="media is-align-items-center" @click="open(item)"> <div class="media is-align-items-center" @click="open(item)">
<div v-if="show_artwork" class="media-left is-clickable"> <div v-if="show_artwork" class="media-left is-clickable">
<cover-artwork <cover-artwork
:artwork_url="artwork_url(item)" :url="artwork_url(item)"
:artist="item.artist" :artist="item.artist"
:album="item.name" :album="item.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-small-image" class="is-clickable fd-has-shadow fd-cover fd-cover-small-image"

View File

@ -129,9 +129,11 @@ export default {
) { ) {
return index return index
} }
currentVerse.time < currentTime if (currentVerse.time < currentTime) {
? (start = index + 1) start = index + 1
: (end = index - 1) } else {
end = index - 1
}
} }
return -1 return -1
} }
@ -141,7 +143,9 @@ export default {
}, },
watch: { watch: {
verse_index() { verse_index() {
this.autoScrolling && this.scroll_to_verse() if (this.autoScrolling) {
this.scroll_to_verse()
}
this.lastIndex = this.verse_index this.lastIndex = this.verse_index
} }
}, },

View File

@ -45,7 +45,7 @@
export default { export default {
name: 'ModalDialog', name: 'ModalDialog',
props: { props: {
close_action: { default: 'dialog.cancel', type: String }, close_action: { default: '', type: String },
delete_action: { default: '', type: String }, delete_action: { default: '', type: String },
ok_action: { default: '', type: String }, ok_action: { default: '', type: String },
show: Boolean, show: Boolean,

View File

@ -6,7 +6,7 @@
<div class="card"> <div class="card">
<div class="card-content"> <div class="card-content">
<cover-artwork <cover-artwork
:artwork_url="item.artwork_url" :url="item.artwork_url"
:artist="item.artist" :artist="item.artist"
:album="item.name" :album="item.name"
class="fd-has-shadow fd-cover fd-cover-normal-image mb-5" class="fd-has-shadow fd-cover fd-cover-normal-image mb-5"

View File

@ -6,7 +6,7 @@
<div class="card"> <div class="card">
<div class="card-content"> <div class="card-content">
<cover-artwork <cover-artwork
:artwork_url="artwork_url(item)" :url="artwork_url(item)"
:artist="item.artist" :artist="item.artist"
:album="item.name" :album="item.name"
class="fd-has-shadow fd-cover fd-cover-normal-image mb-5" class="fd-has-shadow fd-cover fd-cover-normal-image mb-5"

View File

@ -8,7 +8,6 @@
} }
}, },
"dialog": { "dialog": {
"cancel": "Abbrechen",
"add": { "add": {
"rss": { "rss": {
"add": "Hinzufügen", "add": "Hinzufügen",
@ -385,6 +384,7 @@
"count": "{count} Playlist|{count} Playlisten" "count": "{count} Playlist|{count} Playlisten"
}, },
"podcast": { "podcast": {
"cancel": "Abbrechen",
"play": "Spielen", "play": "Spielen",
"remove": "Entfernen", "remove": "Entfernen",
"remove-info-1": "Diesen Podcast wirklich dauerhaft aus der Bibliothek löschen?", "remove-info-1": "Diesen Podcast wirklich dauerhaft aus der Bibliothek löschen?",

View File

@ -8,7 +8,6 @@
} }
}, },
"dialog": { "dialog": {
"cancel": "Cancel",
"add": { "add": {
"rss": { "rss": {
"add": "Add", "add": "Add",
@ -385,6 +384,7 @@
"count": "{count} playlist|{count} playlist|{count} playlists" "count": "{count} playlist|{count} playlist|{count} playlists"
}, },
"podcast": { "podcast": {
"cancel": "Cancel",
"play": "Play", "play": "Play",
"remove": "Remove", "remove": "Remove",
"remove-info-1": "Permanently remove this podcast from your library?", "remove-info-1": "Permanently remove this podcast from your library?",

View File

@ -8,7 +8,6 @@
} }
}, },
"dialog": { "dialog": {
"cancel": "Annuler",
"add": { "add": {
"rss": { "rss": {
"add": "Ajouter", "add": "Ajouter",
@ -385,6 +384,7 @@
"count": "{count} liste de lecture|{count} liste de lecture|{count} listes de lecture" "count": "{count} liste de lecture|{count} liste de lecture|{count} listes de lecture"
}, },
"podcast": { "podcast": {
"cancel": "Annuler",
"play": "Lire", "play": "Lire",
"remove": "Supprimer", "remove": "Supprimer",
"remove-info-1": "Supprimer ce podcast de manière permanente de la bibliothèque ?", "remove-info-1": "Supprimer ce podcast de manière permanente de la bibliothèque ?",

View File

@ -8,7 +8,6 @@
} }
}, },
"dialog": { "dialog": {
"cancel": "取消",
"add": { "add": {
"rss": { "rss": {
"add": "添加", "add": "添加",
@ -385,6 +384,7 @@
"count": "{count} 个播放列表|{count} 个播放列表" "count": "{count} 个播放列表|{count} 个播放列表"
}, },
"podcast": { "podcast": {
"cancel": "取消",
"play": "播放", "play": "播放",
"remove": "移除", "remove": "移除",
"remove-info-1": "从资料库中永久移除该播客?", "remove-info-1": "从资料库中永久移除该播客?",

View File

@ -50,7 +50,7 @@ const timeIndex = (string) => {
return times.find((item) => isNaN(diff) || diff < item.difference)?.text(date) return times.find((item) => isNaN(diff) || diff < item.difference)?.text(date)
} }
const createIndexer = ({ field, type = undefined } = {}) => { const createIndexer = ({ field, type } = {}) => {
switch (type) { switch (type) {
case String: case String:
return (item) => characterIndex(item[field]) return (item) => characterIndex(item[field])
@ -66,7 +66,10 @@ const createIndexer = ({ field, type = undefined } = {}) => {
} }
export class GroupedList { export class GroupedList {
constructor({ items = [], total = 0, offset = 0, limit = -1 } = {}, options) { constructor(
{ items = [], total = 0, offset = 0, limit = -1 } = {},
options = {}
) {
this.items = items this.items = items
this.total = total this.total = total
this.offset = offset this.offset = offset

View File

@ -21,7 +21,7 @@
</template> </template>
<template #heading-right> <template #heading-right>
<cover-artwork <cover-artwork
:artwork_url="album.artwork_url" :url="album.artwork_url"
:artist="album.artist" :artist="album.artist"
:album="album.name" :album="album.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image" class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image"

View File

@ -25,7 +25,7 @@
</template> </template>
<template #heading-right> <template #heading-right>
<cover-artwork <cover-artwork
:artwork_url="artwork_url(album)" :url="artwork_url(album)"
:artist="album.artists[0].name" :artist="album.artists[0].name"
:album="album.name" :album="album.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image" class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image"

View File

@ -71,11 +71,11 @@ const dataObject = {
}, },
set(vm, response) { set(vm, response) {
vm.artist = response[0] vm.artist = response.shift()
vm.albums = [] vm.albums = []
vm.total = 0 vm.total = 0
vm.offset = 0 vm.offset = 0
vm.append_albums(response[1]) vm.append_albums(response.shift())
} }
} }

View File

@ -21,7 +21,7 @@
</template> </template>
<template #heading-right> <template #heading-right>
<cover-artwork <cover-artwork
:artwork_url="album.artwork_url" :url="album.artwork_url"
:artist="album.artist" :artist="album.artist"
:album="album.name" :album="album.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image" class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image"

View File

@ -62,7 +62,7 @@ const dataObject = {
}, },
set(vm, response) { set(vm, response) {
vm.genre = response[0].data.genres.items[0] vm.genre = response[0].data.genres.items.shift()
vm.albums = new GroupedList(response[1].data.albums, { vm.albums = new GroupedList(response[1].data.albums, {
index: { field: 'name_sort', type: String } index: { field: 'name_sort', type: String }
}) })

View File

@ -73,7 +73,7 @@ const dataObject = {
}, },
set(vm, response) { set(vm, response) {
vm.genre = response[0].data.genres.items[0] vm.genre = response[0].data.genres.items.shift()
vm.tracks_list = new GroupedList(response[1].data.tracks) vm.tracks_list = new GroupedList(response[1].data.tracks)
} }
} }

View File

@ -3,7 +3,7 @@
<div v-if="track.id > 0" class="hero-body is-flex is-align-items-center"> <div v-if="track.id > 0" class="hero-body is-flex is-align-items-center">
<div class="container has-text-centered" style="max-width: 500px"> <div class="container has-text-centered" style="max-width: 500px">
<cover-artwork <cover-artwork
:artwork_url="track.artwork_url" :url="track.artwork_url"
:artist="track.artist" :artist="track.artist"
:album="track.album" :album="track.album"
class="is-clickable fd-has-shadow fd-cover-big-image" class="is-clickable fd-has-shadow fd-cover-big-image"

View File

@ -72,11 +72,11 @@ const dataObject = {
}, },
set(vm, response) { set(vm, response) {
vm.playlist = response[0] vm.playlist = response.shift()
vm.tracks = [] vm.tracks = []
vm.total = 0 vm.total = 0
vm.offset = 0 vm.offset = 0
vm.append_tracks(response[1]) vm.append_tracks(response.shift())
} }
} }

View File

@ -19,7 +19,7 @@
</template> </template>
<template #heading-right> <template #heading-right>
<cover-artwork <cover-artwork
:artwork_url="album.artwork_url" :url="album.artwork_url"
:artist="album.artist" :artist="album.artist"
:album="album.name" :album="album.name"
class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image" class="is-clickable fd-has-shadow fd-cover fd-cover-medium-image"
@ -47,6 +47,7 @@
<modal-dialog <modal-dialog
:show="show_remove_podcast_modal" :show="show_remove_podcast_modal"
:title="$t('page.podcast.remove-podcast')" :title="$t('page.podcast.remove-podcast')"
:close_action="$t('page.podcast.cancel')"
:delete_action="$t('page.podcast.remove')" :delete_action="$t('page.podcast.remove')"
@close="show_remove_podcast_modal = false" @close="show_remove_podcast_modal = false"
@delete="remove_podcast" @delete="remove_podcast"

View File

@ -190,12 +190,12 @@ export default {
this.$store.dispatch('add_recent_search', this.search_query) this.$store.dispatch('add_recent_search', this.search_query)
}, },
search_items(type) { search_items(type) {
const music = type !== 'audiobook' && type !== 'podcast', const music = type !== 'audiobook' && type !== 'podcast'
kind = music ? 'music' : type, const kind = music ? 'music' : type
parameters = { const parameters = {
type: music ? type : 'album', limit: this.search_limit,
limit: this.search_limit type: music ? type : 'album'
} }
if (this.search_query.startsWith('query:')) { if (this.search_query.startsWith('query:')) {
parameters.expression = `(${this.search_query.replace(/^query:/u, '').trim()}) and media_kind is ${kind}` parameters.expression = `(${this.search_query.replace(/^query:/u, '').trim()}) and media_kind is ${kind}`
} else if (music) { } else if (music) {

View File

@ -39,7 +39,7 @@ export default {
}, },
library_add(url) { library_add(url) {
return axios.post('./api/library/add', undefined, { params: { url } }) return axios.post('./api/library/add', null, { params: { url } })
}, },
library_album(albumId) { library_album(albumId) {
@ -47,7 +47,7 @@ export default {
}, },
library_album_track_update(albumId, attributes) { library_album_track_update(albumId, attributes) {
return axios.put(`./api/library/albums/${albumId}/tracks`, undefined, { return axios.put(`./api/library/albums/${albumId}/tracks`, null, {
params: attributes params: attributes
}) })
}, },
@ -151,7 +151,7 @@ export default {
}, },
library_playlist_delete(playlistId) { library_playlist_delete(playlistId) {
return axios.delete(`./api/library/playlists/${playlistId}`, undefined) return axios.delete(`./api/library/playlists/${playlistId}`, null)
}, },
library_playlist_folder(playlistId = 0) { library_playlist_folder(playlistId = 0) {
@ -189,7 +189,7 @@ export default {
}, },
library_rescan(scan_kind) { library_rescan(scan_kind) {
return axios.put('./api/rescan', undefined, { params: { scan_kind } }) return axios.put('./api/rescan', null, { params: { scan_kind } })
}, },
library_stats() { library_stats() {
@ -205,13 +205,13 @@ export default {
}, },
library_track_update(trackId, attributes = {}) { library_track_update(trackId, attributes = {}) {
return axios.put(`./api/library/tracks/${trackId}`, undefined, { return axios.put(`./api/library/tracks/${trackId}`, null, {
params: attributes params: attributes
}) })
}, },
library_update(scan_kind) { library_update(scan_kind) {
return axios.put('./api/update', undefined, { params: { scan_kind } }) return axios.put('./api/update', null, { params: { scan_kind } })
}, },
output_toggle(outputId) { output_toggle(outputId) {
@ -253,7 +253,7 @@ export default {
}, },
player_play(options = {}) { player_play(options = {}) {
return axios.put('./api/player/play', undefined, { params: options }) return axios.put('./api/player/play', null, { params: options })
}, },
player_play_expression(expression, shuffle, position) { player_play_expression(expression, shuffle, position) {
@ -264,7 +264,7 @@ export default {
playback_from_position: position, playback_from_position: position,
shuffle shuffle
} }
return axios.post('./api/queue/items/add', undefined, { params }) return axios.post('./api/queue/items/add', null, { params })
}, },
player_play_uri(uris, shuffle, position) { player_play_uri(uris, shuffle, position) {
@ -275,7 +275,7 @@ export default {
shuffle, shuffle,
uris uris
} }
return axios.post('./api/queue/items/add', undefined, { params }) return axios.post('./api/queue/items/add', null, { params })
}, },
player_previous() { player_previous() {
@ -350,7 +350,7 @@ export default {
queue_expression_add(expression) { queue_expression_add(expression) {
return axios return axios
.post('./api/queue/items/add', undefined, { params: { expression } }) .post('./api/queue/items/add', null, { params: { expression } })
.then((response) => { .then((response) => {
store.dispatch('add_notification', { store.dispatch('add_notification', {
text: t('server.appended-tracks', { text: t('server.appended-tracks', {
@ -371,7 +371,7 @@ export default {
params.position = store.getters.now_playing.position + 1 params.position = store.getters.now_playing.position + 1
} }
return axios return axios
.post('./api/queue/items/add', undefined, { params }) .post('./api/queue/items/add', null, { params })
.then((response) => { .then((response) => {
store.dispatch('add_notification', { store.dispatch('add_notification', {
text: t('server.appended-tracks', { text: t('server.appended-tracks', {
@ -394,7 +394,7 @@ export default {
queue_save_playlist(name) { queue_save_playlist(name) {
return axios return axios
.post('./api/queue/save', undefined, { params: { name } }) .post('./api/queue/save', null, { params: { name } })
.then((response) => { .then((response) => {
store.dispatch('add_notification', { store.dispatch('add_notification', {
text: t('server.queue-saved', { name }), text: t('server.queue-saved', { name }),