diff --git a/frontend/src/app.js b/frontend/src/app.js index ee4b14f..957251f 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -138,7 +138,13 @@ const sendUpdate = ( update ) => { connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'pos', 'data': currentDetails[ 'pos' ] } ) + '\n\n' ); } } else if ( update === 'playingSong' ) { - currentDetails[ update ][ 'startTime' ] = new Date().getTime(); + if ( !currentDetails[ 'playingSong' ] ) { + currentDetails[ 'playingSong' ] = {}; + } + currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime(); + for ( let client in connectedClients ) { + connectedClients[ client ].write( 'data: ' + JSON.stringify( { 'type': 'pos', 'data': currentDetails[ 'pos' ] } ) + '\n\n' ); + } } else if ( update === 'isPlaying' ) { currentDetails[ 'playingSong' ][ 'startTime' ] = new Date().getTime(); for ( let client in connectedClients ) { diff --git a/frontend/src/appleMusicRoutes.js b/frontend/src/appleMusicRoutes.js index 9fb0af1..f863dcb 100644 --- a/frontend/src/appleMusicRoutes.js +++ b/frontend/src/appleMusicRoutes.js @@ -8,6 +8,8 @@ */ const path = require( 'path' ); +const fs = require( 'fs' ); +const csv = require( 'csv-parser' ); const dialog = require( 'electron' ).dialog; const analyzeFile = ( filepath ) => { @@ -27,6 +29,8 @@ const analyzeFile = ( filepath ) => { } ); } else if ( filepath.includes( '.json' ) ) { resolve( JSON.parse( fs.readFileSync( filepath ) ) ); + } else { + reject( 'NO_CSV_OR_JSON_FILE' ); } } ); } @@ -58,14 +62,22 @@ module.exports = ( app ) => { title: 'Open file with additional data on the songs', filters: [ { - name: 'CSV', extensions: [ '.csv' ], - name: 'JSON', extensions: [ '.json' ] + name: 'All supported files (.csv, .json)', + extensions: [ 'csv', 'json' ], + }, + { + name: 'JSON', + extensions: [ 'json' ], + }, + { + name: 'CSV', + extensions: [ 'csv' ], } - ] - } ); + ], + } )[ 0 ]; analyzeFile( filepath ).then( analyzedFile => { - res.send( analyzeFile ); - } ).catch( err => { + res.send( analyzedFile ); + } ).catch( () => { res.status( 500 ).send( 'no csv / json file' ); } ) } ); diff --git a/frontend/src/client/appleMusic/index.html b/frontend/src/client/appleMusic/index.html index a22b534..27f371c 100644 --- a/frontend/src/client/appleMusic/index.html +++ b/frontend/src/client/appleMusic/index.html @@ -40,18 +40,19 @@
- skip_previous - replay_10 + skip_previous + replay_10 play_arrow pause play_disabled - forward_10 - skip_next - shuffle - shuffle_on - repeat - repeat_one_on - repeat_on + forward_10 + skip_next + shuffle + shuffle_on + repeat + repeat_one_on + repeat_on + upload
info
@@ -62,7 +63,7 @@
- + music_note

{{ playingSong.title ?? 'No song selected' }}

@@ -76,8 +77,8 @@
-
+
diff --git a/frontend/src/client/appleMusic/index.js b/frontend/src/client/appleMusic/index.js index ab19e0b..549901f 100644 --- a/frontend/src/client/appleMusic/index.js +++ b/frontend/src/client/appleMusic/index.js @@ -22,7 +22,8 @@ const app = Vue.createApp( { localIP: '', hasLoadedPlaylists: false, isPreparingToPlay: false, - filenameForAdditionalInfo: '', + additionalSongInfo: {}, + hasFinishedInit: false, // slider offset: 0, @@ -69,23 +70,12 @@ const app = Vue.createApp( { this.musicKit.shuffleMode = MusicKit.PlayerShuffleMode.off; this.musicKit.addEventListener( 'nowPlayingItemDidChange', ( e ) => { this.control( 'play' ); + this.hasFinishedInit = true; // Assemble this.playingSong // TODO: Also add additional items to queue if there are new // items that weren't previously shown (limitation of MusicKitJS). if ( e.item ) { - this.playingSong = { - 'artist': e.item.attributes.artistName, - 'title': e.item.attributes.name, - 'year': e.item.attributes.releaseDate, - // Think about bpm analysis - // 'bpm': metadata[ 'common' ][ 'bpm' ], - 'genre': e.item.attributes.genreNames, - 'duration': Math.round( e.item.attributes.durationInMillis / 1000 ), - 'filename': this.songQueue[ this.musicKit.nowPlayingItemIndex ].filename, - 'coverArtOrigin': 'api', - 'hasCoverArt': true, - 'queuePos': this.musicKit.nowPlayingItemIndex, - } + this.playingSong = this.songQueue[ this.musicKit.nowPlayingItemIndex ]; let url = e.item.attributes.artwork.url; url = url.replace( '{w}', e.item.attributes.artwork.width ); url = url.replace( '{h}', e.item.attributes.artwork.height ); @@ -144,18 +134,38 @@ const app = Vue.createApp( { } else return false; }, getAdditionalSongInfo() { - // TODO: Implement - if ( this.filenameForAdditionalInfo ) { - + if ( Object.keys( this.additionalSongInfo ).length < 1 ) { + fetch( '/apple-music/getAdditionalData' ).then( res => { + if ( res.status === 200 ) { + res.json().then( json => { + this.additionalSongInfo = json; + this.handleAdditionalData(); + } ); + } + } ); + } + }, + handleAdditionalData () { + if ( Object.keys( this.additionalSongInfo ).length > 0 ) { + for ( let item in this.songQueue ) { + if ( this.additionalSongInfo[ item ] ) { + for ( let d in this.additionalSongInfo[ item ] ) { + if ( !this.songQueue[ item ][ d ] ) { + this.songQueue[ item ][ d ] = this.additionalSongInfo[ item ][ d ]; + } + } + } + } + this.playingSong = this.songQueue[ this.musicKit.nowPlayingItemIndex ]; + this.sendUpdate( 'songQueue' ); + this.sendUpdate( 'playingSong' ); } }, selectPlaylist( id ) { this.isPreparingToPlay = true; this.musicKit.setQueue( { playlist: id } ).then( () => { try { - this.control( 'play' ); this.loadPlaylist(); - // TODO: Load additional data from file this.hasSelectedPlaylist = true; this.isPreparingToPlay = false; } catch( err ) { @@ -251,8 +261,9 @@ const app = Vue.createApp( { url = url.replace( '{w}', songQueue[ item ].attributes.artwork.width ); url = url.replace( '{h}', songQueue[ item ].attributes.artwork.height ); this.songQueue[ item ][ 'coverArtURL' ] = url; + this.handleAdditionalData(); + this.sendUpdate( 'songQueue' ); } - this.sendUpdate( 'songQueue' ); }, control( action ) { if ( action === 'play' ) {