Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added saving and loading of playqueue. #139

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 41 additions & 1 deletion src/player/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { shuffle, shuffled, trackListEquals, formatArtists } from '@/shared/util
import { API } from '@/shared/api'
import { AudioController } from '@/player/audio'
import { useMainStore } from '@/shared/store'
import { last } from 'lodash-es'

localStorage.removeItem('player.mute')
const storedQueue = JSON.parse(localStorage.getItem('queue') || '[]')
Expand All @@ -24,6 +25,7 @@ interface State {
shuffle: boolean;
volume: number; // integer between 0 and 1 representing the volume of the player
podcastPlaybackRate: number;
lastSavePlayQueueTime: number;
}

function persistQueue(state: State) {
Expand All @@ -45,6 +47,7 @@ export const playerModule: Module<State, any> = {
shuffle: localStorage.getItem('player.shuffle') === 'true',
volume: storedVolume,
podcastPlaybackRate: storedPodcastPlaybackRate,
lastSavePlayQueueTime: Date.now(),
},

mutations: {
Expand Down Expand Up @@ -148,7 +151,10 @@ export const playerModule: Module<State, any> = {
setPodcastPlaybackRate(state, value) {
state.podcastPlaybackRate = value
localStorage.setItem('player.podcastPlaybackRate', String(value))
}
},
setLastSavePlayQueueTime(state, value: any) {
state.lastSavePlayQueueTime = value
},
},

actions: {
Expand Down Expand Up @@ -281,6 +287,16 @@ export function createPlayerStore(mainStore: ReturnType<typeof useMainStore>, ap
}
})
setupAudio(store, mainStore, api)
if (!store.state.player.queue.length) {
const pq = api.getPlayQueue()
pq.then((pq) => {
if (pq.tracks.length) {
store.commit('player/setQueue', pq.tracks)
store.commit('player/setQueueIndex', pq.currentTrack)
audio.seek(pq.currentTrackPosition / 1000)
}
})
}
return store
}

Expand Down Expand Up @@ -382,5 +398,29 @@ function setupAudio(store: Store<any>, mainStore: ReturnType<typeof useMainStore
}
}
})

// Save play queue on queue change, current track change, play/pause
store.watch(
(state) => [state.player.queue, state.player.queueIndex, state.player.isPlaying],
() => {
store.commit('player/setLastSavePlayQueueTime', Date.now())
const tracks = store.state.player.queue.map((track: any) => track.id)
const currentTrack = store.state.player.queueIndex
const currentTrackPosition = store.state.player.currentTime * 1000
return api.savePlayQueue(tracks, currentTrack, currentTrackPosition)
})

// Save play queue on current time change but only if no save in last 30s
store.watch(
(state) => [state.player.currentTime],
() => {
if (Date.now() - store.state.player.lastSavePlayQueueTime >= 30000) {
store.commit('player/setLastSavePlayQueueTime', Date.now())
const tracks = store.state.player.queue.map((track: any) => track.id)
const currentTrack = store.state.player.queueIndex
const currentTrackPosition = store.state.player.currentTime * 1000
return api.savePlayQueue(tracks, currentTrack, currentTrackPosition)
}
})
}
}
32 changes: 32 additions & 0 deletions src/shared/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ export interface Playlist {
tracks?: Track[]
}

export interface PlayQueue {
tracks: Track[]
currentTrack: number
currentTrackPosition: number
}

export class UnsupportedOperationError extends Error { }

export class API {
Expand Down Expand Up @@ -286,6 +292,32 @@ export class API {
await this.fetch('rest/updatePlaylist', params)
}

async savePlayQueue(tracks: string[], current: number, position: number) {
if (tracks.length !== 0) {
const params = {
id: tracks,
current: tracks[current],
position: position,
}
await this.fetch('rest/savePlayQueue', params)
}
}

async getPlayQueue(): Promise<PlayQueue> {
const response = await this.fetch('rest/getPlayQueue')
let i = 0
for (i = 0; i < response.playQueue?.entry?.length; i++) {
if (response.playQueue.entry[i].id === response.playQueue.current) {
break
}
}
return {
tracks: (response.playQueue?.entry || []).map(this.normalizeTrack, this),
currentTrack: i,
currentTrackPosition: response.playQueue?.position || 0,
}
}

async getRandomSongs(): Promise<Track[]> {
const params = {
size: 200,
Expand Down