diff --git a/platypush/backend/http/webapp/src/components/Media/Controls.vue b/platypush/backend/http/webapp/src/components/Media/Controls.vue index 293335834d..222cdf2309 100644 --- a/platypush/backend/http/webapp/src/components/Media/Controls.vue +++ b/platypush/backend/http/webapp/src/components/Media/Controls.vue @@ -4,7 +4,7 @@ @click.prevent="searchAlbum" v-if="status?.state !== 'stop'">
- +
@@ -59,18 +59,18 @@
- +
- - - + +
-
- +
+
@@ -206,12 +206,27 @@ export default { return null }, + trackArtistId() { + return typeof this.track?.artist === 'object' ? this.track.artist.id : null + }, + + trackArtistName() { + if (typeof this.track?.artist === 'string') + return this.track.artist + + return this.track?.artist?.name || this.track?.artist?.title + }, + trackImage() { if (this.track?.images?.length) return this.track.images[0].url return this.track?.image || this.image }, + + trackTitle() { + return this.track?.title || this.track?.name || '[No Title]' + }, }, methods: { @@ -235,11 +250,11 @@ export default { }, searchArtist() { - if (!this.track?.artist) + if (!this.trackArtistName?.length) return const args = { - artist: this.track.artist, + artist: this.trackArtistName, } if (this.track.artist_uri) diff --git a/platypush/backend/http/webapp/src/components/panels/Media/Index.vue b/platypush/backend/http/webapp/src/components/panels/Media/Index.vue index f74729dc73..efebfa2b21 100644 --- a/platypush/backend/http/webapp/src/components/panels/Media/Index.vue +++ b/platypush/backend/http/webapp/src/components/panels/Media/Index.vue @@ -95,6 +95,10 @@ />
+ +
+ +
@@ -149,6 +153,7 @@ import Utils from "@/Utils"; import Browser from "@/components/panels/Media/Browser"; import Header from "@/components/panels/Media/Header"; import Info from "@/components/panels/Media/Info"; +import Loading from "@/components/Loading"; import MediaDownloads from "@/components/panels/Media/Downloads"; import MediaUtils from "@/components/Media/Utils"; import MediaView from "@/components/Media/View"; @@ -166,6 +171,7 @@ export default { Browser, Header, Info, + Loading, MediaDownloads, MediaView, Modal, @@ -205,6 +211,7 @@ export default { forceShowNav: false, infoTrack: null, loading: false, + opening: false, prevSelectedView: null, results: [], selectedPlayer: null, @@ -324,7 +331,7 @@ export default { return } - this.loading = true + this.opening = true try { if (!this.selectedPlayer.component.supports(item)) @@ -334,9 +341,9 @@ export default { item, this.selectedSubtitles, this.selectedPlayer, opts ) - await this.refresh() + await this.refresh(item) } finally { - this.loading = false + this.opening = false } }, @@ -383,15 +390,36 @@ export default { await this.download(item, {onlyAudio: true}) }, - async refresh() { - this.selectedPlayer.status = await this.selectedPlayer.component.status(this.selectedPlayer) + async refresh(item) { + let newStatus = { + ...(await this.selectedPlayer.component.status(this.selectedPlayer)), + ...(item || {}), + } + + this.setStatus(newStatus) + }, + + setStatus(status) { + const curStatus = this.selectedPlayer?.status || {} + let newStatus = {} + + if (curStatus.resource === status.resource) { + newStatus = { + ...curStatus, + ...status, + } + } else { + newStatus = status + } + + this.selectedPlayer.status = newStatus }, onStatusUpdate(status) { if (!this.selectedPlayer) return - this.selectedPlayer.status = status + this.setStatus(status) }, onPlayUrlModalOpen() { @@ -558,17 +586,7 @@ export default { async playUrl(url) { this.urlPlay = url - this.loading = true - - try { - await this.play({ - url: url, - }) - - this.$refs.playUrlModal.close() - } finally { - this.loading = false - } + await this.play({ url: url }) }, async refreshDownloads() { @@ -788,6 +806,7 @@ export default { height: 100%; display: flex; flex-direction: row-reverse; + position: relative; .view-container { display: flex; @@ -806,6 +825,24 @@ export default { height: calc(100% - #{$media-header-height} - #{$filter-header-height} - #{$media-ctrl-panel-height}); } } + + :deep(.media-loading-indicator) { + position: absolute; + top: 0; + left: 0; + width: 5em; + height: 5em; + border-radius: 50%; + background: rgba(0, 0, 0, 0); + display: flex; + justify-content: center; + align-items: center; + z-index: 10; + + .loading { + border-radius: 50%; + } + } } } diff --git a/platypush/backend/http/webapp/src/components/panels/Media/Info.vue b/platypush/backend/http/webapp/src/components/panels/Media/Info.vue index 575ef3226a..6dd195fbce 100644 --- a/platypush/backend/http/webapp/src/components/panels/Media/Info.vue +++ b/platypush/backend/http/webapp/src/components/panels/Media/Info.vue @@ -1,5 +1,7 @@ @@ -176,6 +210,7 @@ @@ -271,6 +345,7 @@ export default { .media-info { width: 100%; + max-width: 60em; } .row { diff --git a/platypush/backend/http/webapp/src/components/panels/Media/Item.vue b/platypush/backend/http/webapp/src/components/panels/Media/Item.vue index 1f1b73be5c..710e43acb2 100644 --- a/platypush/backend/http/webapp/src/components/panels/Media/Item.vue +++ b/platypush/backend/http/webapp/src/components/panels/Media/Item.vue @@ -1,35 +1,51 @@ @@ -39,9 +46,9 @@ import Collections from "@/components/panels/Media/Providers/Jellyfin/Collections"; import Loading from "@/components/Loading"; import Mixin from "@/components/panels/Media/Providers/Jellyfin/Mixin"; +import Music from "../Music/Index"; import NoItems from "@/components/elements/NoItems"; import Results from "@/components/panels/Media/Results"; -import SortButton from "@/components/panels/Media/Providers/Jellyfin/components/SortButton"; export default { mixins: [Mixin], @@ -49,9 +56,9 @@ export default { components: { Collections, Loading, + Music, NoItems, Results, - SortButton, }, computed: { @@ -92,18 +99,34 @@ export default { }, async refresh() { + // Don't fetch items if we're in the music view - + // we'll fetch them in the Music component + if (this.collection?.collection_type === 'music') + return + this.loading_ = true try { - this.items = this.collection?.id ? - ( - await this.request('media.jellyfin.get_items', { + if (this.collection?.collection_type === 'tvshows') { + this.items = ( + await this.request('media.jellyfin.get_collections', { parent_id: this.collection.id, - limit: 5000, }) - ) : (await this.request('media.jellyfin.get_collections')).map((collection) => ({ + ).map((collection) => ({ ...collection, item_type: 'collection', })) + } else { + this.items = this.collection?.id ? + ( + await this.request('media.jellyfin.get_items', { + parent_id: this.collection.id, + limit: 5000, + }) + ) : (await this.request('media.jellyfin.get_collections')).map((collection) => ({ + ...collection, + item_type: 'collection', + })) + } } finally { this.loading_ = false } @@ -136,5 +159,9 @@ export default { overflow: hidden; } } + + .music-wrapper { + height: 100%; + } } diff --git a/platypush/backend/http/webapp/src/components/panels/Media/Providers/Jellyfin/views/Music/Index.vue b/platypush/backend/http/webapp/src/components/panels/Media/Providers/Jellyfin/views/Music/Index.vue new file mode 100644 index 0000000000..2ccca18229 --- /dev/null +++ b/platypush/backend/http/webapp/src/components/panels/Media/Providers/Jellyfin/views/Music/Index.vue @@ -0,0 +1,411 @@ + + + + + diff --git a/platypush/backend/http/webapp/src/components/panels/Media/Results.vue b/platypush/backend/http/webapp/src/components/panels/Media/Results.vue index 32036754a9..19e9a38c3c 100644 --- a/platypush/backend/http/webapp/src/components/panels/Media/Results.vue +++ b/platypush/backend/http/webapp/src/components/panels/Media/Results.vue @@ -1,13 +1,15 @@