mirror of
https://github.com/janishutz/MusicPlayerV2.git
synced 2025-11-25 13:04:23 +00:00
final fixes
This commit is contained in:
@@ -451,7 +451,7 @@
|
|||||||
niceDuration.value += secondCounts;
|
niceDuration.value += secondCounts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 50 );
|
}, 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepNiceDurationTime = ( playingSong: Song ) => {
|
const prepNiceDurationTime = ( playingSong: Song ) => {
|
||||||
@@ -596,8 +596,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener( 'beforeunload', () => {
|
window.addEventListener( 'beforeunload', async () => {
|
||||||
notificationHandler.disconnect();
|
await notificationHandler.disconnect();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
defineExpose( {
|
defineExpose( {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
<span class="material-symbols-outlined move-icon" @click="moveSong( song.id, 'down' )" title="Move song down" v-if="canBeMoved( 'down', song.id )">arrow_downward</span>
|
<span class="material-symbols-outlined move-icon" @click="moveSong( song.id, 'down' )" title="Move song down" v-if="canBeMoved( 'down', song.id )">arrow_downward</span>
|
||||||
<h3 class="song-title">{{ song.title }}</h3>
|
<h3 class="song-title">{{ song.title }}</h3>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" placeholder="Additional information for remote display" v-model="song.additionalInfo" @focusin="kbControl( 'on' )" @focusout="kbControl( 'off' )">
|
<input type="text" placeholder="Additional information for remote display" title="Additional information for remote display" v-model="song.additionalInfo" @focusin="kbControl( 'on' )" @focusout="kbControl( 'off' )">
|
||||||
<p class="playing-in">{{ getTimeUntil( song ) }}</p>
|
<p class="playing-in">{{ getTimeUntil( song ) }}</p>
|
||||||
</div>
|
</div>
|
||||||
<button @click="deleteSong( song.id )" class="small-buttons" title="Remove this song from the queue" v-if="canBeMoved( 'down', song.id ) || canBeMoved( 'up', song.id )"><span class="material-symbols-outlined">delete</span></button>
|
<button @click="deleteSong( song.id )" class="small-buttons" title="Remove this song from the queue" v-if="canBeMoved( 'down', song.id ) || canBeMoved( 'up', song.id )"><span class="material-symbols-outlined">delete</span></button>
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class SocketConnection {
|
|||||||
eventSource?: EventSource;
|
eventSource?: EventSource;
|
||||||
toBeListenedForItems: SSEMap;
|
toBeListenedForItems: SSEMap;
|
||||||
reconnectRetryCount: number;
|
reconnectRetryCount: number;
|
||||||
|
openConnectionsCount: number;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this.socket = io( localStorage.getItem( 'url' ) ?? '', {
|
this.socket = io( localStorage.getItem( 'url' ) ?? '', {
|
||||||
@@ -30,6 +31,7 @@ class SocketConnection {
|
|||||||
this.useSocket = localStorage.getItem( 'music-player-config' ) === 'ws';
|
this.useSocket = localStorage.getItem( 'music-player-config' ) === 'ws';
|
||||||
this.toBeListenedForItems = {};
|
this.toBeListenedForItems = {};
|
||||||
this.reconnectRetryCount = 0;
|
this.reconnectRetryCount = 0;
|
||||||
|
this.openConnectionsCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,40 +53,55 @@ class SocketConnection {
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
|
if ( this.openConnectionsCount < 1 && !this.isConnected ) {
|
||||||
if ( res.status === 200 ) {
|
this.openConnectionsCount += 1;
|
||||||
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
|
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
|
||||||
|
if ( res.status === 200 ) {
|
||||||
|
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
|
||||||
|
|
||||||
this.eventSource.onmessage = ( e ) => {
|
this.eventSource.onopen = () => {
|
||||||
const d = JSON.parse( e.data );
|
|
||||||
if ( this.toBeListenedForItems[ d.type ] ) {
|
|
||||||
this.toBeListenedForItems[ d.type ]( d.data );
|
|
||||||
} else if ( d.type === 'basics' ) {
|
|
||||||
this.isConnected = true;
|
this.isConnected = true;
|
||||||
resolve( d.data );
|
this.reconnectRetryCount = 0;
|
||||||
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Connection successfully established!' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.eventSource.onmessage = ( e ) => {
|
||||||
|
const d = JSON.parse( e.data );
|
||||||
|
if ( this.toBeListenedForItems[ d.type ] ) {
|
||||||
|
this.toBeListenedForItems[ d.type ]( d.data );
|
||||||
|
} else if ( d.type === 'basics' ) {
|
||||||
|
resolve( d.data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventSource.onerror = () => {
|
||||||
|
if ( this.isConnected ) {
|
||||||
|
this.isConnected = false;
|
||||||
|
this.openConnectionsCount -= 1;
|
||||||
|
this.eventSource?.close();
|
||||||
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
|
||||||
|
// console.debug( e );
|
||||||
|
|
||||||
|
this.eventSource = undefined;
|
||||||
|
|
||||||
|
this.reconnectRetryCount += 1;
|
||||||
|
setTimeout( () => {
|
||||||
|
this.connect();
|
||||||
|
}, 500 * this.reconnectRetryCount );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Could not connect due to error ' + res.status );
|
||||||
|
reject( 'ERR_ROOM_CONNECTING' );
|
||||||
}
|
}
|
||||||
|
} ).catch( () => {
|
||||||
this.eventSource.onerror = ( e ) => {
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Could not connect due to error.' );
|
||||||
if ( this.isConnected ) {
|
|
||||||
this.isConnected = false;
|
|
||||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
|
|
||||||
console.debug( e );
|
|
||||||
|
|
||||||
this.eventSource = undefined;
|
|
||||||
|
|
||||||
this.reconnectRetryCount += 1;
|
|
||||||
setTimeout( () => {
|
|
||||||
this.connect();
|
|
||||||
}, 500 * this.reconnectRetryCount );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
reject( 'ERR_ROOM_CONNECTING' );
|
reject( 'ERR_ROOM_CONNECTING' );
|
||||||
}
|
} );
|
||||||
} ).catch( () => {
|
} else {
|
||||||
reject( 'ERR_ROOM_CONNECTING' );
|
console.log( '[ SSE Connection ]: Trimmed connections' );
|
||||||
} );
|
reject( 'ERR_TOO_MANY_CONNECTIONS' );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alert( 'Could not reconnect to the share. Please reload the page to retry!' );
|
alert( 'Could not reconnect to the share. Please reload the page to retry!' );
|
||||||
@@ -146,6 +163,17 @@ class SocketConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStatus (): boolean {
|
||||||
|
if ( this.useSocket ) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
if ( this.eventSource ) {
|
||||||
|
return this.eventSource!.OPEN && this.isConnected;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SocketConnection;
|
export default SocketConnection;
|
||||||
@@ -21,6 +21,9 @@ class NotificationHandler {
|
|||||||
eventSource?: EventSource;
|
eventSource?: EventSource;
|
||||||
toBeListenedForItems: SSEMap;
|
toBeListenedForItems: SSEMap;
|
||||||
reconnectRetryCount: number;
|
reconnectRetryCount: number;
|
||||||
|
lastEmitTimestamp: number;
|
||||||
|
openConnectionsCount: number;
|
||||||
|
pendingRequestCount: number;
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
this.socket = io( localStorage.getItem( 'url' ) ?? '', {
|
this.socket = io( localStorage.getItem( 'url' ) ?? '', {
|
||||||
@@ -32,6 +35,9 @@ class NotificationHandler {
|
|||||||
this.useSocket = localStorage.getItem( 'music-player-config' ) === 'ws';
|
this.useSocket = localStorage.getItem( 'music-player-config' ) === 'ws';
|
||||||
this.toBeListenedForItems = {};
|
this.toBeListenedForItems = {};
|
||||||
this.reconnectRetryCount = 0;
|
this.reconnectRetryCount = 0;
|
||||||
|
this.lastEmitTimestamp = 0;
|
||||||
|
this.pendingRequestCount = 0;
|
||||||
|
this.openConnectionsCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,42 +84,50 @@ class NotificationHandler {
|
|||||||
sseConnect (): Promise<void> {
|
sseConnect (): Promise<void> {
|
||||||
return new Promise( ( resolve, reject ) => {
|
return new Promise( ( resolve, reject ) => {
|
||||||
if ( this.reconnectRetryCount < 5 ) {
|
if ( this.reconnectRetryCount < 5 ) {
|
||||||
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
|
if ( this.openConnectionsCount < 1 && !this.isConnected ) {
|
||||||
if ( res.status === 200 ) {
|
this.openConnectionsCount += 1;
|
||||||
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
|
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
|
||||||
this.eventSource.onopen = () => {
|
if ( res.status === 200 ) {
|
||||||
this.isConnected = true;
|
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
|
||||||
this.reconnectRetryCount = 0;
|
this.eventSource.onopen = () => {
|
||||||
resolve();
|
this.isConnected = true;
|
||||||
}
|
this.reconnectRetryCount = 0;
|
||||||
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Connection successfully established!' );
|
||||||
this.eventSource.onmessage = ( e ) => {
|
resolve();
|
||||||
const d = JSON.parse( e.data );
|
|
||||||
if ( this.toBeListenedForItems[ d.type ] ) {
|
|
||||||
this.toBeListenedForItems[ d.type ]( d.data );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
this.eventSource.onerror = ( e ) => {
|
this.eventSource.onmessage = ( e ) => {
|
||||||
if ( this.isConnected ) {
|
const d = JSON.parse( e.data );
|
||||||
this.isConnected = false;
|
if ( this.toBeListenedForItems[ d.type ] ) {
|
||||||
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
|
this.toBeListenedForItems[ d.type ]( d.data );
|
||||||
console.debug( e );
|
}
|
||||||
|
|
||||||
this.eventSource = undefined;
|
|
||||||
|
|
||||||
this.reconnectRetryCount += 1;
|
|
||||||
setTimeout( () => {
|
|
||||||
this.sseConnect();
|
|
||||||
}, 500 * this.reconnectRetryCount );
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} else {
|
this.eventSource.onerror = ( e ) => {
|
||||||
|
if ( this.isConnected ) {
|
||||||
|
this.isConnected = false;
|
||||||
|
this.eventSource?.close();
|
||||||
|
this.openConnectionsCount -= 1;
|
||||||
|
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
|
||||||
|
console.debug( e );
|
||||||
|
|
||||||
|
this.eventSource = undefined;
|
||||||
|
|
||||||
|
this.reconnectRetryCount += 1;
|
||||||
|
setTimeout( () => {
|
||||||
|
this.sseConnect();
|
||||||
|
}, 500 * this.reconnectRetryCount );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
reject( 'ERR_ROOM_CONNECTING' );
|
||||||
|
}
|
||||||
|
} ).catch( () => {
|
||||||
reject( 'ERR_ROOM_CONNECTING' );
|
reject( 'ERR_ROOM_CONNECTING' );
|
||||||
}
|
} );
|
||||||
} ).catch( () => {
|
} else {
|
||||||
reject( 'ERR_ROOM_CONNECTING' );
|
resolve();
|
||||||
} );
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( confirm( 'Connection lost and it could not be reestablished. Please click ok to retry or press cancel to stop retrying. Your share will be deleted as a result thereof.' ) ) {
|
if ( confirm( 'Connection lost and it could not be reestablished. Please click ok to retry or press cancel to stop retrying. Your share will be deleted as a result thereof.' ) ) {
|
||||||
this.reconnectRetryCount = 0;
|
this.reconnectRetryCount = 0;
|
||||||
@@ -136,19 +150,34 @@ class NotificationHandler {
|
|||||||
if ( this.useSocket ) {
|
if ( this.useSocket ) {
|
||||||
this.socket.emit( event, { 'roomToken': this.roomToken, 'roomName': this.roomName, 'data': data } );
|
this.socket.emit( event, { 'roomToken': this.roomToken, 'roomName': this.roomName, 'data': data } );
|
||||||
} else {
|
} else {
|
||||||
fetch( localStorage.getItem( 'url' ) + '/socket/update', {
|
const now = new Date().getTime();
|
||||||
method: 'post',
|
if ( this.lastEmitTimestamp < now - 250 ) {
|
||||||
body: JSON.stringify( { 'event': event, 'roomName': this.roomName, 'roomToken': this.roomToken, 'data': data } ),
|
this.lastEmitTimestamp = now;
|
||||||
credentials: 'include',
|
this.sendEmitConventionally( event, data );
|
||||||
headers: {
|
} else {
|
||||||
'Content-Type': 'application/json',
|
this.pendingRequestCount += 1;
|
||||||
'charset': 'utf-8'
|
setTimeout( () => {
|
||||||
}
|
this.pendingRequestCount = 0;
|
||||||
} ).catch( () => {} );
|
this.lastEmitTimestamp = now;
|
||||||
|
this.sendEmitConventionally( event, data );
|
||||||
|
}, 250 * this.pendingRequestCount );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sendEmitConventionally ( event: string, data: any ): void {
|
||||||
|
fetch( localStorage.getItem( 'url' ) + '/socket/update', {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify( { 'event': event, 'roomName': this.roomName, 'roomToken': this.roomToken, 'data': data } ),
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'charset': 'utf-8'
|
||||||
|
}
|
||||||
|
} ).catch( () => {} );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a listener function for an event
|
* Register a listener function for an event
|
||||||
* @param {string} event The event to listen for
|
* @param {string} event The event to listen for
|
||||||
@@ -169,7 +198,7 @@ class NotificationHandler {
|
|||||||
* Disconnect from the server
|
* Disconnect from the server
|
||||||
* @returns {any}
|
* @returns {any}
|
||||||
*/
|
*/
|
||||||
disconnect (): void {
|
async disconnect (): Promise<void> {
|
||||||
if ( this.isConnected ) {
|
if ( this.isConnected ) {
|
||||||
if ( this.useSocket ) {
|
if ( this.useSocket ) {
|
||||||
this.socket.emit( 'delete-room', {
|
this.socket.emit( 'delete-room', {
|
||||||
@@ -180,6 +209,7 @@ class NotificationHandler {
|
|||||||
if ( !res.status ) {
|
if ( !res.status ) {
|
||||||
alert( 'Unable to delete the room you were just in. The name will be blocked until the next server restart!' );
|
alert( 'Unable to delete the room you were just in. The name will be blocked until the next server restart!' );
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} );
|
} );
|
||||||
} else {
|
} else {
|
||||||
fetch( localStorage.getItem( 'url' ) + '/socket/deleteRoom', {
|
fetch( localStorage.getItem( 'url' ) + '/socket/deleteRoom', {
|
||||||
@@ -196,7 +226,10 @@ class NotificationHandler {
|
|||||||
} else {
|
} else {
|
||||||
alert( 'Unable to delete the room you were just in. The name will be blocked until the next server restart!' );
|
alert( 'Unable to delete the room you were just in. The name will be blocked until the next server restart!' );
|
||||||
}
|
}
|
||||||
} ).catch( () => {} );
|
return;
|
||||||
|
} ).catch( () => {
|
||||||
|
return;
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,12 +149,28 @@
|
|||||||
if ( isNaN( progressBar.value ) ) {
|
if ( isNaN( progressBar.value ) ) {
|
||||||
progressBar.value = 0;
|
progressBar.value = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( playlist.value[ playingSong.value ].duration + 10 - pos.value < 0 ) {
|
||||||
|
stopTimeTracker();
|
||||||
|
alert( 'It looks like if you have been disconnected! We are trying to reconnect you now!' );
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
}, 100 );
|
}, 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
const stopTimeTracker = () => {
|
const stopTimeTracker = () => {
|
||||||
clearInterval( timeTracker );
|
clearInterval( timeTracker );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener( 'visibilitychange', () => {
|
||||||
|
if ( !document.hidden ) {
|
||||||
|
if ( !conn.getStatus ) {
|
||||||
|
stopTimeTracker();
|
||||||
|
alert( 'It looks like if you have been disconnected! We are trying to reconnect you now!' );
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} );
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@@ -233,7 +249,7 @@
|
|||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
width: 65%;
|
width: 65%;
|
||||||
text-align: justify;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pause-icon {
|
.pause-icon {
|
||||||
@@ -315,7 +331,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.additional-info {
|
.additional-info {
|
||||||
font-size: 250%;
|
font-size: 1.2rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -283,7 +283,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
text-align: justify;
|
text-align: left;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +379,7 @@
|
|||||||
display: block;
|
display: block;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
text-align: justify;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.song-list .song-image {
|
.song-list .song-image {
|
||||||
|
|||||||
Reference in New Issue
Block a user