final fixes

This commit is contained in:
2024-08-19 13:36:49 +02:00
parent bd2e4cdac4
commit b989111849
6 changed files with 157 additions and 80 deletions

View File

@@ -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( {

View File

@@ -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>

View File

@@ -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,25 +53,34 @@ class SocketConnection {
} }
} ); } );
} else { } else {
if ( this.openConnectionsCount < 1 && !this.isConnected ) {
this.openConnectionsCount += 1;
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => { fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
if ( res.status === 200 ) { if ( res.status === 200 ) {
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } ); this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
this.eventSource.onopen = () => {
this.isConnected = true;
this.reconnectRetryCount = 0;
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Connection successfully established!' );
}
this.eventSource.onmessage = ( e ) => { this.eventSource.onmessage = ( e ) => {
const d = JSON.parse( e.data ); const d = JSON.parse( e.data );
if ( this.toBeListenedForItems[ d.type ] ) { if ( this.toBeListenedForItems[ d.type ] ) {
this.toBeListenedForItems[ d.type ]( d.data ); this.toBeListenedForItems[ d.type ]( d.data );
} else if ( d.type === 'basics' ) { } else if ( d.type === 'basics' ) {
this.isConnected = true;
resolve( d.data ); resolve( d.data );
} }
} }
this.eventSource.onerror = ( e ) => { this.eventSource.onerror = () => {
if ( this.isConnected ) { if ( this.isConnected ) {
this.isConnected = false; this.isConnected = false;
this.openConnectionsCount -= 1;
this.eventSource?.close();
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' ); console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
console.debug( e ); // console.debug( e );
this.eventSource = undefined; this.eventSource = undefined;
@@ -80,11 +91,17 @@ class SocketConnection {
} }
}; };
} else { } else {
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Could not connect due to error ' + res.status );
reject( 'ERR_ROOM_CONNECTING' ); reject( 'ERR_ROOM_CONNECTING' );
} }
} ).catch( () => { } ).catch( () => {
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Could not connect due to error.' );
reject( 'ERR_ROOM_CONNECTING' ); reject( 'ERR_ROOM_CONNECTING' );
} ); } );
} else {
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;

View File

@@ -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,12 +84,15 @@ 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 ) {
if ( this.openConnectionsCount < 1 && !this.isConnected ) {
this.openConnectionsCount += 1;
fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => { fetch( localStorage.getItem( 'url' ) + '/socket/joinRoom?room=' + this.roomName, { credentials: 'include' } ).then( res => {
if ( res.status === 200 ) { if ( res.status === 200 ) {
this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } ); this.eventSource = new EventSource( localStorage.getItem( 'url' ) + '/socket/connection?room=' + this.roomName, { withCredentials: true } );
this.eventSource.onopen = () => { this.eventSource.onopen = () => {
this.isConnected = true; this.isConnected = true;
this.reconnectRetryCount = 0; this.reconnectRetryCount = 0;
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Connection successfully established!' );
resolve(); resolve();
} }
@@ -97,6 +106,8 @@ class NotificationHandler {
this.eventSource.onerror = ( e ) => { this.eventSource.onerror = ( e ) => {
if ( this.isConnected ) { if ( this.isConnected ) {
this.isConnected = false; this.isConnected = false;
this.eventSource?.close();
this.openConnectionsCount -= 1;
console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' ); console.log( '[ SSE Connection ] - ' + new Date().toISOString() + ': Reconnecting due to connection error!' );
console.debug( e ); console.debug( e );
@@ -114,6 +125,9 @@ class NotificationHandler {
} ).catch( () => { } ).catch( () => {
reject( 'ERR_ROOM_CONNECTING' ); reject( 'ERR_ROOM_CONNECTING' );
} ); } );
} else {
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,6 +150,23 @@ 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 {
const now = new Date().getTime();
if ( this.lastEmitTimestamp < now - 250 ) {
this.lastEmitTimestamp = now;
this.sendEmitConventionally( event, data );
} else {
this.pendingRequestCount += 1;
setTimeout( () => {
this.pendingRequestCount = 0;
this.lastEmitTimestamp = now;
this.sendEmitConventionally( event, data );
}, 250 * this.pendingRequestCount );
}
}
}
}
sendEmitConventionally ( event: string, data: any ): void {
fetch( localStorage.getItem( 'url' ) + '/socket/update', { fetch( localStorage.getItem( 'url' ) + '/socket/update', {
method: 'post', method: 'post',
body: JSON.stringify( { 'event': event, 'roomName': this.roomName, 'roomToken': this.roomToken, 'data': data } ), body: JSON.stringify( { 'event': event, 'roomName': this.roomName, 'roomToken': this.roomToken, 'data': data } ),
@@ -146,8 +177,6 @@ class NotificationHandler {
} }
} ).catch( () => {} ); } ).catch( () => {} );
} }
}
}
/** /**
* Register a listener function for an event * Register a listener function for an event
@@ -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;
} );
} }
} }
} }

View File

@@ -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;
} }

View File

@@ -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 {