mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
lots of progress on client display integration
This commit is contained in:
@@ -26,9 +26,10 @@ let changedStatus = [];
|
||||
|
||||
let currentDetails = {
|
||||
'songQueue': [],
|
||||
'currentlyPlaying': '',
|
||||
'playingSong': {},
|
||||
'pos': 0,
|
||||
'isPlaying': false
|
||||
'isPlaying': false,
|
||||
'queuePos': 0,
|
||||
};
|
||||
|
||||
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 ) => {
|
||||
if ( allowedTypes.includes( req.body.type ) ) {
|
||||
currentDetails[ req.body.type ] = req.body.data;
|
||||
@@ -110,8 +111,8 @@ app.get( '/clientStatusUpdate/:status', ( req, res ) => {
|
||||
} );
|
||||
|
||||
app.get( '/openSongs', ( req, res ) => {
|
||||
res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
||||
// res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
||||
// res.send( '{ "data": [ "/home/janis/Music/KB2022" ] }' );
|
||||
res.send( '{ "data": [ "/mnt/storage/SORTED/Music/audio/KB2022" ] }' );
|
||||
// res.send( { 'data': dialog.showOpenDialogSync( { properties: [ 'openDirectory' ], title: 'Open music library folder' } ) } );
|
||||
} );
|
||||
|
||||
|
||||
@@ -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 {
|
||||
font-variation-settings:
|
||||
'FILL' 0,
|
||||
@@ -6,89 +55,119 @@
|
||||
'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;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.voting {
|
||||
border-radius: 500px;
|
||||
border: 1px black solid;
|
||||
font-size: 150%;
|
||||
cursor: pointer;
|
||||
.playing-bar {
|
||||
height: 60%;
|
||||
background-color: white;
|
||||
width: 10%;
|
||||
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;
|
||||
font-size: 150%;
|
||||
display: block;
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
.song-list .song-image {
|
||||
width: 5vw;
|
||||
height: 5vw;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
font-size: 5vw;
|
||||
}
|
||||
|
||||
.content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 30vw;
|
||||
padding: 20px;
|
||||
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;
|
||||
.pause-icon {
|
||||
width: 5vw;
|
||||
height: 5vw;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
font-size: 5vw !important;
|
||||
user-select: none;
|
||||
}
|
||||
@@ -11,8 +11,24 @@
|
||||
</head>
|
||||
<body>
|
||||
<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=""> -->
|
||||
</div>
|
||||
<div v-else>
|
||||
|
||||
@@ -5,15 +5,27 @@ createApp( {
|
||||
data() {
|
||||
return {
|
||||
hasLoaded: false,
|
||||
songs: {},
|
||||
songs: [],
|
||||
playingSong: {},
|
||||
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: {
|
||||
connect() {
|
||||
let source = new EventSource( '/clientDisplayNotifier', { withCredentials: true } );
|
||||
let self = this;
|
||||
|
||||
source.onmessage = ( e ) => {
|
||||
let data;
|
||||
@@ -23,18 +35,22 @@ createApp( {
|
||||
data = { 'type': e.data };
|
||||
}
|
||||
if ( data.type === 'basics' ) {
|
||||
console.log( 'basics' );
|
||||
console.log( data.data );
|
||||
this.isPlaying = data.data.isPlaying ?? false;
|
||||
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' ) {
|
||||
|
||||
this.pos = data.data;
|
||||
} else if ( data.type === 'isPlaying' ) {
|
||||
|
||||
this.isPlaying = data.data;
|
||||
} else if ( data.type === 'songQueue' ) {
|
||||
|
||||
} else if ( data.type === 'currentlyPlaying' ) {
|
||||
|
||||
this.songs = data.data;
|
||||
} else if ( data.type === 'playingSong' ) {
|
||||
this.playingSong = data.data;
|
||||
} else if ( data.type === 'queuePos' ) {
|
||||
this.queuePos = data.data;
|
||||
}
|
||||
console.log( data.data );
|
||||
};
|
||||
|
||||
source.onopen = () => {
|
||||
|
||||
@@ -76,7 +76,9 @@
|
||||
|
||||
.fancy-view-song-art {
|
||||
height: 40vh;
|
||||
width: auto;
|
||||
width: 40vh;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,11 +35,12 @@
|
||||
<style>
|
||||
.playing-symbols {
|
||||
position: absolute;
|
||||
left: 9.95vw;
|
||||
left: 10%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
margin: 0;
|
||||
width: 5vw;
|
||||
height: 5vw;
|
||||
background-color: rgba( 0, 0, 0, 0.6 );
|
||||
@@ -56,7 +57,7 @@
|
||||
|
||||
.playing-bar {
|
||||
height: 60%;
|
||||
background-color: var( --primary-color );
|
||||
background-color: white;
|
||||
width: 10%;
|
||||
border-radius: 50px;
|
||||
margin: auto;
|
||||
@@ -226,6 +227,17 @@
|
||||
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' ) {
|
||||
if ( this.songPos > 0 ) {
|
||||
this.songPos -= 1;
|
||||
@@ -291,6 +303,17 @@
|
||||
this.isLoadingSongs = false;
|
||||
this.hasLoadedSongs = true;
|
||||
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 ) {
|
||||
this.isLoadingSongs = false;
|
||||
@@ -312,6 +335,17 @@
|
||||
}
|
||||
this.currentlyPlaying = song.filename;
|
||||
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 ) {
|
||||
this.update( { 'type': 'playback', 'status': false } );
|
||||
|
||||
@@ -184,6 +184,8 @@ export default {
|
||||
} else {
|
||||
musicPlayer.currentTime = 0;
|
||||
this.control( 'play' );
|
||||
this.playbackPos = musicPlayer.currentTime;
|
||||
this.sendUpdate( 'pos' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,6 +250,7 @@ export default {
|
||||
this.playbackPosBeautified += secondCount;
|
||||
}
|
||||
}, 0.02 );
|
||||
this.sendUpdate( 'isPlaying' );
|
||||
} else if ( action === 'pause' ) {
|
||||
this.$emit( 'update', { 'type': 'playback', 'status': false } );
|
||||
musicPlayer.pause();
|
||||
@@ -255,8 +258,11 @@ export default {
|
||||
clearInterval( this.progressTracker );
|
||||
} catch ( err ) {};
|
||||
this.isPlaying = false;
|
||||
this.sendUpdate( 'isPlaying' );
|
||||
} else if ( action === 'replay10' ) {
|
||||
musicPlayer.currentTime = musicPlayer.currentTime > 10 ? musicPlayer.currentTime - 10 : 0;
|
||||
this.playbackPos = musicPlayer.currentTime;
|
||||
this.sendUpdate( 'pos' );
|
||||
} else if ( action === 'forward10' ) {
|
||||
if ( musicPlayer.currentTime < ( musicPlayer.duration - 10 ) ) {
|
||||
musicPlayer.currentTime = musicPlayer.currentTime + 10;
|
||||
@@ -265,6 +271,8 @@ export default {
|
||||
this.control( 'next' );
|
||||
} else {
|
||||
musicPlayer.currentTime = 0;
|
||||
this.playbackPos = musicPlayer.currentTime;
|
||||
this.sendUpdate( 'pos' );
|
||||
}
|
||||
}
|
||||
} else if ( action === 'reset' ) {
|
||||
|
||||
Reference in New Issue
Block a user