1
1
import Vue from 'vue' ;
2
- import { BaseItemDto , ItemFields } from '@jellyfin/client-axios' ;
2
+ import { BaseItemDto , ImageType , ItemFields } from '@jellyfin/client-axios' ;
3
3
import { defineStore } from 'pinia' ;
4
4
import { authStore } from '.' ;
5
5
6
6
export interface ItemsState {
7
7
byId : Record < string , BaseItemDto > ;
8
8
collectionById : Record < string , string [ ] > ;
9
+ playlistById : Record < string , string [ ] > ;
9
10
}
10
11
11
12
export const itemsStore = defineStore ( 'items' , {
12
13
state : ( ) => {
13
14
return {
14
15
byId : { } ,
15
- collectionById : { }
16
+ collectionById : { } ,
17
+ playlistById : { }
16
18
} as ItemsState ;
17
19
} ,
18
20
actions : {
@@ -69,6 +71,113 @@ export const itemsStore = defineStore('items', {
69
71
* @param children
70
72
* @returns - The children of the item
71
73
*/
74
+ async movePlaylistItem (
75
+ parent : BaseItemDto ,
76
+ localChild : BaseItemDto ,
77
+ index : number
78
+ ) : Promise < BaseItemDto [ ] > {
79
+ const auth = authStore ( ) ;
80
+
81
+ // You're probably asking "... but why?"
82
+
83
+ // Because when the Playback manager is playing these tracks,
84
+ // it seems to erase the PlaylistItemId from each of the items.
85
+ // So... I just get a new bunch of them to move things.
86
+
87
+ // Probably a better way to do it, but...
88
+ // ... I didn't feel like figuring that out right now.
89
+
90
+ // If you try to fix this, make sure that you can click "Play"
91
+ // on the playlist, then move tracks.
92
+
93
+ const children = await this . $nuxt . $api . playlists . getPlaylistItems ( {
94
+ userId : auth . currentUserId ,
95
+ playlistId : parent . Id as string ,
96
+ fields : [ ItemFields . PrimaryImageAspectRatio ] ,
97
+ enableImageTypes : [
98
+ ImageType . Primary ,
99
+ ImageType . Backdrop ,
100
+ ImageType . Banner ,
101
+ ImageType . Thumb
102
+ ]
103
+ } ) ;
104
+ const child = children . data . Items ?. find (
105
+ ( i ) => i . Id == localChild . Id
106
+ ) as BaseItemDto ;
107
+ await this . $nuxt . $api . playlists . moveItem ( {
108
+ playlistId : parent . Id as string ,
109
+ itemId : child . PlaylistItemId as string ,
110
+ newIndex : index
111
+ } ) ;
112
+ return ( await this . fetchAndAddPlaylist (
113
+ parent . Id as string
114
+ ) ) as BaseItemDto [ ] ;
115
+ } ,
116
+ addPlaylist ( parent : BaseItemDto , children : BaseItemDto [ ] ) : BaseItemDto [ ] {
117
+ if ( ! parent . Id ) {
118
+ throw new Error ( "Parent item doesn't have an Id" ) ;
119
+ }
120
+
121
+ const childIds = [ ] ;
122
+
123
+ for ( const child of children ) {
124
+ if ( child . Id ) {
125
+ if ( ! this . getItemById ( child . Id ) ) {
126
+ this . add ( child ) ;
127
+ }
128
+
129
+ childIds . push ( child . Id ) ;
130
+ }
131
+ }
132
+
133
+ Vue . set ( this . playlistById , parent . Id , childIds ) ;
134
+
135
+ return this . getChildrenOfParentPlaylist ( parent . Id ) as BaseItemDto [ ] ;
136
+ } ,
137
+ async fetchAndAddPlaylist (
138
+ parentId : string | undefined
139
+ ) : Promise < BaseItemDto [ ] > {
140
+ const auth = authStore ( ) ;
141
+
142
+ if ( parentId && ! this . getItemById ( parentId ) ) {
143
+ const parentItem = (
144
+ await this . $nuxt . $api . items . getItems ( {
145
+ userId : auth . currentUserId ,
146
+ ids : [ parentId ] ,
147
+ fields : Object . values ( ItemFields )
148
+ } )
149
+ ) . data ;
150
+
151
+ if ( ! parentItem . Items ?. [ 0 ] ) {
152
+ throw new Error ( "This parent doesn't exist" ) ;
153
+ }
154
+
155
+ this . add ( parentItem . Items [ 0 ] ) ;
156
+ }
157
+
158
+ const childItems = (
159
+ await this . $nuxt . $api . playlists . getPlaylistItems ( {
160
+ userId : auth . currentUserId ,
161
+ playlistId : parentId as string ,
162
+ fields : [ ItemFields . PrimaryImageAspectRatio ] ,
163
+ enableImageTypes : [
164
+ ImageType . Primary ,
165
+ ImageType . Backdrop ,
166
+ ImageType . Banner ,
167
+ ImageType . Thumb
168
+ ]
169
+ } )
170
+ ) . data ;
171
+
172
+ if ( childItems . Items ) {
173
+ const parent = this . getItemById ( parentId ) ;
174
+
175
+ return this . addPlaylist ( parent as BaseItemDto , childItems . Items ) ;
176
+ } else {
177
+ // I think this just means it's an empty playlist...?
178
+ return this . addPlaylist ( parent as BaseItemDto , [ ] ) ;
179
+ }
180
+ } ,
72
181
addCollection ( parent : BaseItemDto , children : BaseItemDto [ ] ) : BaseItemDto [ ] {
73
182
if ( ! parent . Id ) {
74
183
throw new Error ( "Parent item doesn't have an Id" ) ;
@@ -88,7 +197,7 @@ export const itemsStore = defineStore('items', {
88
197
89
198
Vue . set ( this . collectionById , parent . Id , childIds ) ;
90
199
91
- return this . getChildrenOfParent ( parent . Id ) as BaseItemDto [ ] ;
200
+ return this . getChildrenOfParentCollection ( parent . Id ) as BaseItemDto [ ] ;
92
201
} ,
93
202
/**
94
203
* Fetches a parent and its children and adds thecollection to the store
@@ -156,7 +265,7 @@ export const itemsStore = defineStore('items', {
156
265
return res ;
157
266
} ;
158
267
} ,
159
- getChildrenOfParent : ( state ) => {
268
+ getChildrenOfParentCollection : ( state ) => {
160
269
return ( id : string | undefined ) : BaseItemDto [ ] | undefined => {
161
270
if ( ! id ) {
162
271
throw new Error ( 'No itemId provided' ) ;
@@ -165,6 +274,24 @@ export const itemsStore = defineStore('items', {
165
274
const res = [ ] as BaseItemDto [ ] ;
166
275
const ids = state . collectionById [ id ] ;
167
276
277
+ if ( ids ?. length ) {
278
+ for ( const _id of ids ) {
279
+ res . push ( state . byId [ _id ] ) ;
280
+ }
281
+
282
+ return res ;
283
+ }
284
+ } ;
285
+ } ,
286
+ getChildrenOfParentPlaylist : ( state ) => {
287
+ return ( id : string | undefined ) : BaseItemDto [ ] | undefined => {
288
+ if ( ! id ) {
289
+ throw new Error ( 'No itemId provided' ) ;
290
+ }
291
+
292
+ const res = [ ] as BaseItemDto [ ] ;
293
+ const ids = state . playlistById [ id ] ;
294
+
168
295
if ( ids ?. length ) {
169
296
for ( const _id of ids ) {
170
297
res . push ( state . byId [ _id ] ) ;
0 commit comments