lots of progress on client display integration

This commit is contained in:
2023-11-02 19:58:33 +01:00
parent 34bf27d20d
commit 8d4cc4696c
7 changed files with 247 additions and 91 deletions

View File

@@ -26,9 +26,10 @@ let changedStatus = [];
let currentDetails = { let currentDetails = {
'songQueue': [], 'songQueue': [],
'currentlyPlaying': '', 'playingSong': {},
'pos': 0, 'pos': 0,
'isPlaying': false 'isPlaying': false,
'queuePos': 0,
}; };
let connectedMain = {}; let connectedMain = {};
@@ -84,7 +85,7 @@ const sendUpdate = ( update ) => {
} }
} }
const allowedTypes = [ 'playingSong', 'isPlaying', 'songQueue', 'pos' ]; const allowedTypes = [ 'playingSong', 'isPlaying', 'songQueue', 'pos', 'queuePos' ];
app.post( '/statusUpdate', ( req, res ) => { app.post( '/statusUpdate', ( req, res ) => {
if ( allowedTypes.includes( req.body.type ) ) { if ( allowedTypes.includes( req.body.type ) ) {
currentDetails[ req.body.type ] = req.body.data; currentDetails[ req.body.type ] = req.body.data;
@@ -110,8 +111,8 @@ app.get( '/clientStatusUpdate/:status', ( req, res ) => {
} ); } );
app.get( '/openSongs', ( req, res ) => { app.get( '/openSongs', ( req, res ) => {
res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' ); // res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
// res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' ); res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } ); // res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
} ); } );

View File

@@ -1,3 +1,52 @@
:root, :root.light {
--primary-color: #2c3e50;
--accent-background: rgb(30, 30, 82);
--secondary-color: white;
--background-color: white;
--popup-color: rgb(224, 224, 224);
--accent-color: #42b983;
--hover-color: rgb(165, 165, 165);
--accent-background-hover: rgb(124, 140, 236);
--overlay-color: rgba(0, 0, 0, 0.7);
--border-color: rgb(100, 100, 100);
--highlight-backdrop: rgb(143, 134, 192);
--hint-color: rgb(174, 210, 221);
--PI: 3.14159265358979;
}
:root.dark {
--primary-color: white;
--accent-background: rgb(56, 56, 112);
--secondary-color: white;
--background-color: rgb(32, 32, 32);
--popup-color: rgb(58, 58, 58);
--accent-color: #42b983;
--hover-color: rgb(83, 83, 83);
--accent-background-hover: #4380a8;
--overlay-color: rgba(104, 104, 104, 0.575);
--border-color: rgb(190, 190, 190);
--highlight-backdrop: rgb(85, 63, 207);
--hint-color: rgb(88, 91, 110);
}
@media ( prefers-color-scheme: dark ) {
:root {
--primary-color: white;
--accent-background: rgb(56, 56, 112);
--secondary-color: white;
--background-color: rgb(32, 32, 32);
--popup-color: rgb(58, 58, 58);
--accent-color: #42b983;
--hover-color: rgb(83, 83, 83);
--accent-background-hover: #4380a8;
--overlay-color: rgba(104, 104, 104, 0.575);
--border-color: rgb(190, 190, 190);
--highlight-backdrop: rgb(85, 63, 207);
--hint-color: rgb(88, 91, 110);
}
}
.material-symbols-outlined { .material-symbols-outlined {
font-variation-settings: font-variation-settings:
'FILL' 0, 'FILL' 0,
@@ -6,89 +55,119 @@
'opsz' 24 'opsz' 24
} }
.voting-wrapper { body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
font-family: sans-serif;
}
.content {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.playing-symbols {
position: absolute;
left: 10vw;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
width: 5vw;
height: 5vw;
background-color: rgba( 0, 0, 0, 0.6 );
}
.playing-symbols-wrapper {
width: 4vw;
height: 5vw;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
} }
.voting { .playing-bar {
border-radius: 500px; height: 60%;
border: 1px black solid; background-color: white;
font-size: 150%; width: 10%;
cursor: pointer; border-radius: 50px;
margin: auto;
} }
.voting-counter { #bar-1 {
animation: music-playing 0.9s infinite ease-in-out;
}
#bar-2 {
animation: music-playing 0.9s infinite ease-in-out;
animation-delay: 0.3s;
}
#bar-3 {
animation: music-playing 0.9s infinite ease-in-out;
animation-delay: 0.6s;
}
@keyframes music-playing {
0% {
transform: scaleY( 1 );
}
50% {
transform: scaleY( 0.5 );
}
100% {
transform: scaleY( 1 );
}
}
.song-list-wrapper {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.song-list {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
width: 80%;
margin: 2px;
padding: 1vh;
border: 1px var( --border-color ) solid;
}
.song-details-wrapper {
margin: 0; margin: 0;
font-size: 150%; display: block;
margin-left: 10px; margin-left: 10px;
margin-right: 10px; margin-right: auto;
} }
body { .song-list .song-image {
display: flex; width: 5vw;
align-items: center; height: 5vw;
justify-content: center; object-fit: cover;
flex-direction: column; object-position: center;
font-size: 5vw;
} }
.content { .pause-icon {
justify-content: flex-start; width: 5vw;
} height: 5vw;
object-fit: cover;
.input { object-position: center;
width: 30vw; font-size: 5vw !important;
padding: 20px; user-select: none;
border-radius: 20px;
border: none;
margin-bottom: 1vh;
margin-top: 5px;
}
.entry {
border: black 2px solid;
padding: 1% 10%;
width: 40vw;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.selected {
background-color: green;
}
.comment {
width: 50%;
text-align: center;
}
.wrapper {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-bottom: 5vh;
}
.bottom-bar {
position: fixed;
width: 100%;
margin: 0;
background-color: lightgray;
left: 0;
bottom: 0;
display: flex;
justify-content: center;
padding: 0;
padding-top: 0.5vh;
padding-bottom: 5vh,
}
.content {
display: block !important;
} }

View File

@@ -11,8 +11,24 @@
</head> </head>
<body> <body>
<div class="content" id="app"> <div class="content" id="app">
<div class="wrapper" v-if="hasLoaded">
<h1>Ok</h1> <h1>Ok</h1>
<div class="song-list-wrapper" v-if="hasLoaded">
<div v-for="song in songQueue" class="song-list">
<span class="material-symbols-outlined song-image" v-if="!song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying )">music_note</span>
<img v-else-if="song.hasCoverArt && ( playingSong.filename !== song.filename || isPlaying )" :src="'/getSongCover?filename=' + song.filename" class="song-image">
<div v-if="playingSong.filename === song.filename && isPlaying" class="playing-symbols">
<div class="playing-symbols-wrapper">
<div class="playing-bar" id="bar-1"></div>
<div class="playing-bar" id="bar-2"></div>
<div class="playing-bar" id="bar-3"></div>
</div>
</div>
<span class="material-symbols-outlined pause-icon" v-if="!isPlaying && playingSong.filename === song.filename">pause</span>
<div class="song-details-wrapper">
<h3>{{ song.title }}</h3>
<p>{{ song.artist }}</p>
</div>
</div>
<!-- <img :src="" alt=""> --> <!-- <img :src="" alt=""> -->
</div> </div>
<div v-else> <div v-else>

View File

@@ -5,15 +5,27 @@ createApp( {
data() { data() {
return { return {
hasLoaded: false, hasLoaded: false,
songs: {}, songs: [],
playingSong: {}, playingSong: {},
isPlaying: false, isPlaying: false,
pos: 0,
queuePos: 0,
}; };
}, },
computed: {
songQueue() {
let ret = [];
for ( let song in this.songs ) {
if ( parseInt( song ) >= this.queuePos ) {
ret.push( this.songs[ song ] );
}
}
return ret;
}
},
methods: { methods: {
connect() { connect() {
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } ); let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
let self = this;
source.onmessage = ( e ) => { source.onmessage = ( e ) => {
let data; let data;
@@ -23,18 +35,22 @@ createApp( {
data = { 'type': e.data }; data = { 'type': e.data };
} }
if ( data.type === 'basics' ) { if ( data.type === 'basics' ) {
console.log( 'basics' ); this.isPlaying = data.data.isPlaying ?? false;
console.log( data.data ); this.playingSong = data.data.playingSong ?? {};
this.songs = data.data.songQueue ?? [];
this.pos = data.data.pos ?? 0;
this.queuePos = data.data.queuePos ?? 0;
} else if ( data.type === 'pos' ) { } else if ( data.type === 'pos' ) {
this.pos = data.data;
} else if ( data.type === 'isPlaying' ) { } else if ( data.type === 'isPlaying' ) {
this.isPlaying = data.data;
} else if ( data.type === 'songQueue' ) { } else if ( data.type === 'songQueue' ) {
this.songs = data.data;
} else if ( data.type === 'currentlyPlaying' ) { } else if ( data.type === 'playingSong' ) {
this.playingSong = data.data;
} else if ( data.type === 'queuePos' ) {
this.queuePos = data.data;
} }
console.log( data.data );
}; };
source.onopen = () => { source.onopen = () => {

View File

@@ -76,7 +76,9 @@
.fancy-view-song-art { .fancy-view-song-art {
height: 40vh; height: 40vh;
width: auto; width: 40vh;
object-fit: cover;
object-position: center;
margin-bottom: 20px; margin-bottom: 20px;
} }

View File

@@ -35,11 +35,12 @@
<style> <style>
.playing-symbols { .playing-symbols {
position: absolute; position: absolute;
left: 9.95vw; left: 10%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
flex-direction: row; flex-direction: row;
margin: 0;
width: 5vw; width: 5vw;
height: 5vw; height: 5vw;
background-color: rgba( 0, 0, 0, 0.6 ); background-color: rgba( 0, 0, 0, 0.6 );
@@ -56,7 +57,7 @@
.playing-bar { .playing-bar {
height: 60%; height: 60%;
background-color: var( --primary-color ); background-color: white;
width: 10%; width: 10%;
border-radius: 50px; border-radius: 50px;
margin: auto; margin: auto;
@@ -226,6 +227,17 @@
this.$emit( 'com', { 'type': 'pause' } ); this.$emit( 'com', { 'type': 'pause' } );
} }
} }
let fetchOptions = {
method: 'post',
body: JSON.stringify( { 'type': 'queuePos', 'data': this.songPos } ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
},
};
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
console.error( err );
} );
} else if ( status.type === 'previous' ) { } else if ( status.type === 'previous' ) {
if ( this.songPos > 0 ) { if ( this.songPos > 0 ) {
this.songPos -= 1; this.songPos -= 1;
@@ -291,6 +303,17 @@
this.isLoadingSongs = false; this.isLoadingSongs = false;
this.hasLoadedSongs = true; this.hasLoadedSongs = true;
this.$emit( 'com', { 'type': 'songsLoaded' } ); this.$emit( 'com', { 'type': 'songsLoaded' } );
let fetchOptions = {
method: 'post',
body: JSON.stringify( { 'type': 'songQueue', 'data': this.songQueue } ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
},
};
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
console.error( err );
} );
} ); } );
} else if ( res.status === 404 ) { } else if ( res.status === 404 ) {
this.isLoadingSongs = false; this.isLoadingSongs = false;
@@ -312,6 +335,17 @@
} }
this.currentlyPlaying = song.filename; this.currentlyPlaying = song.filename;
this.update( { 'type': 'playback', 'status': true } ); this.update( { 'type': 'playback', 'status': true } );
let fetchOptions = {
method: 'post',
body: JSON.stringify( { 'type': 'queuePos', 'data': this.songPos } ),
headers: {
'Content-Type': 'application/json',
'charset': 'utf-8'
},
};
fetch( 'http://localhost:8081/statusUpdate', fetchOptions ).catch( err => {
console.error( err );
} );
}, },
pause( song ) { pause( song ) {
this.update( { 'type': 'playback', 'status': false } ); this.update( { 'type': 'playback', 'status': false } );

View File

@@ -184,6 +184,8 @@ export default {
} else { } else {
musicPlayer.currentTime = 0; musicPlayer.currentTime = 0;
this.control( 'play' ); this.control( 'play' );
this.playbackPos = musicPlayer.currentTime;
this.sendUpdate( 'pos' );
} }
} }
} }
@@ -248,6 +250,7 @@ export default {
this.playbackPosBeautified += secondCount; this.playbackPosBeautified += secondCount;
} }
}, 0.02 ); }, 0.02 );
this.sendUpdate( 'isPlaying' );
} else if ( action === 'pause' ) { } else if ( action === 'pause' ) {
this.$emit( 'update', { 'type': 'playback', 'status': false } ); this.$emit( 'update', { 'type': 'playback', 'status': false } );
musicPlayer.pause(); musicPlayer.pause();
@@ -255,8 +258,11 @@ export default {
clearInterval( this.progressTracker ); clearInterval( this.progressTracker );
} catch ( err ) {}; } catch ( err ) {};
this.isPlaying = false; this.isPlaying = false;
this.sendUpdate( 'isPlaying' );
} else if ( action === 'replay10' ) { } else if ( action === 'replay10' ) {
musicPlayer.currentTime = musicPlayer.currentTime > 10 ? musicPlayer.currentTime - 10 : 0; musicPlayer.currentTime = musicPlayer.currentTime > 10 ? musicPlayer.currentTime - 10 : 0;
this.playbackPos = musicPlayer.currentTime;
this.sendUpdate( 'pos' );
} else if ( action === 'forward10' ) { } else if ( action === 'forward10' ) {
if ( musicPlayer.currentTime < ( musicPlayer.duration - 10 ) ) { if ( musicPlayer.currentTime < ( musicPlayer.duration - 10 ) ) {
musicPlayer.currentTime = musicPlayer.currentTime + 10; musicPlayer.currentTime = musicPlayer.currentTime + 10;
@@ -265,6 +271,8 @@ export default {
this.control( 'next' ); this.control( 'next' );
} else { } else {
musicPlayer.currentTime = 0; musicPlayer.currentTime = 0;
this.playbackPos = musicPlayer.currentTime;
this.sendUpdate( 'pos' );
} }
} }
} else if ( action === 'reset' ) { } else if ( action === 'reset' ) {