From 8b0c26fe672683e6c86a71fb0429804189e754d7 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 18:02:38 +0200 Subject: [PATCH 1/9] Websocket improvements --- src/app.js | 127 +++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/src/app.js b/src/app.js index d44b43e..741007c 100644 --- a/src/app.js +++ b/src/app.js @@ -1,15 +1,13 @@ import { invoke } from '@tauri-apps/api/core'; const HEARTBEAT_INTERVAL = 25000; +const RECONNECT_INTERVAL = 5000; export default { name: "App", data() { let token = null; - let message_ws = null; - let ms_counter = 0; - invoke('get_local_token') .then((res) => { token = JSON.parse(res)['token']; @@ -19,60 +17,8 @@ export default { let servers = JSON.parse(res); this.token = servers.token; token = servers.token; - - if(message_ws === null) { - let message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); - - message_ws.addEventListener("message", (event) => { - if(ms_counter === 0 ) { - ms_counter += 1; - console.log("[WEBSOCKET] Message from server (" + ms_counter + ")", event.data); - - invoke('spellcheck', { token: token, username: this.username, key: event.data }) - .then((res) => { - message_ws.send(res); - }).catch((err) => { - console.log(err); - }); - } else if(ms_counter === 1) { - ms_counter += 1; - if(event.data === 'CONNECTED') { - console.log('[WEBSOCKET CONNECTED]'); - message_ws.send('TOKEN:'+this.token); - } - } else if (ms_counter == 2) { - ms_counter += 1; - this.token = event.data; - }else if(ms_counter > 2) { - console.log("[WEBSOCKET MESSAGE]: " + event.data); - - if(event.data == "PONG") return; - - let splitm = event.data.split(':'); - let [sid, channel, username, ...message] = splitm; - message = message.join(':'); - - this.appState[ - this.appState.findIndex(obj => obj.serverID == sid) - ]['storedChannels'][ - this.appState[ - this.appState.findIndex(obj => obj.serverID == sid) - ]['storedChannels'].findIndex(obj => obj.channelTag === channel) - ]['messages'].unshift({ - 'username': username, - 'm_content': message - }); - } - }); - message_ws.addEventListener("open", () => { - setInterval(() => { - if(message_ws.readyState === WebSocket.OPEN) { - message_ws.send('PING'); - } - }, HEARTBEAT_INTERVAL); - }); - this.ws = message_ws; - } + this.initWebsocket(token); + invoke('write_credentials', { creds: JSON.stringify({ 'username': this.username, 'token': this.token }) }); for (let i = 0; i < servers['s_list'].length; i++) { @@ -130,6 +76,7 @@ export default { return { ws: null, + heartbeat: null, logInSelected: true, loggedin: true, lusername: "", @@ -553,6 +500,72 @@ export default { }).catch((err) => { console.log(err); }) + }, + initWebsocket(token){ + let message_ws = null; + let ms_counter = 0; + if(message_ws === null) { + let message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); + message_ws.addEventListener("message", (event) => { + if(ms_counter === 0 ) { + ms_counter += 1; + console.log("[WEBSOCKET] Message from server (" + ms_counter + ")", event.data); + + invoke('spellcheck', { token: token, username: this.username, key: event.data }) + .then((res) => { + message_ws.send(res); + }).catch((err) => { + console.log(err); + }); + } else if(ms_counter === 1) { + ms_counter += 1; + if(event.data === 'CONNECTED') { + console.log('[WEBSOCKET CONNECTED]'); + message_ws.send('TOKEN:'+this.token); + } + } else if (ms_counter == 2) { + ms_counter += 1; + this.token = event.data; + }else if(ms_counter > 2) { + console.log("[WEBSOCKET MESSAGE]: " + event.data); + + if(event.data == "PONG") return; + + let splitm = event.data.split(':'); + let [sid, channel, username, ...message] = splitm; + message = message.join(':'); + + this.appState[ + this.appState.findIndex(obj => obj.serverID == sid) + ]['storedChannels'][ + this.appState[ + this.appState.findIndex(obj => obj.serverID == sid) + ]['storedChannels'].findIndex(obj => obj.channelTag === channel) + ]['messages'].unshift({ + 'username': username, + 'm_content': message, + 'datetime': Date.now() + }); + } + }); + message_ws.addEventListener("open", () => { + if(this.reconnect != null) { + clearInterval(this.reconnect); + } + this.heartbeat = setInterval(() => { + if(message_ws.readyState === WebSocket.OPEN) { + message_ws.send('PING'); + } + }, HEARTBEAT_INTERVAL); + }); + + message_ws.addEventListener("close", () => { + console.log('[WEBSOCKET CONNECTION LOST. ATTEMPTING TO RECONNECT]'); + clearInterval(this.heartbeat); + setTimeout(() => { this.initWebsocket(this.token); }, RECONNECT_INTERVAL); + }); + this.ws = message_ws; + } } }, }; From 9b9d57663e5481cc070ca3cc635170d65325bc5c Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 18:20:27 +0200 Subject: [PATCH 2/9] Pad timestamp minutes --- src/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index 741007c..c1201a6 100644 --- a/src/app.js +++ b/src/app.js @@ -324,7 +324,7 @@ export default { let date = new Date(Number(timestamp)); let month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - return month[Number(date.getMonth())] + ' ' + date.getDate() + ' ' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes(); + return month[Number(date.getMonth())] + ' ' + date.getDate() + ' ' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes().toString().padStart(2, '0'); }, create_channel() { this.createChannelPopUp = !this.createChannelPopUp; From 325d32e17224842f154b64f21f06f5203fbe9a8f Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 22:32:06 +0200 Subject: [PATCH 3/9] Initial transfer of websocket code --- src/app.js | 89 +++++++++++++---------------------------------- src/websocket.jsx | 57 ++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 64 deletions(-) create mode 100644 src/websocket.jsx diff --git a/src/app.js b/src/app.js index c1201a6..f78ea9a 100644 --- a/src/app.js +++ b/src/app.js @@ -1,4 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; +import { wsConnection } from './websocket.jsx'; const HEARTBEAT_INTERVAL = 25000; const RECONNECT_INTERVAL = 5000; @@ -502,70 +503,30 @@ export default { }) }, initWebsocket(token){ - let message_ws = null; - let ms_counter = 0; - if(message_ws === null) { - let message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); - message_ws.addEventListener("message", (event) => { - if(ms_counter === 0 ) { - ms_counter += 1; - console.log("[WEBSOCKET] Message from server (" + ms_counter + ")", event.data); - - invoke('spellcheck', { token: token, username: this.username, key: event.data }) - .then((res) => { - message_ws.send(res); - }).catch((err) => { - console.log(err); - }); - } else if(ms_counter === 1) { - ms_counter += 1; - if(event.data === 'CONNECTED') { - console.log('[WEBSOCKET CONNECTED]'); - message_ws.send('TOKEN:'+this.token); - } - } else if (ms_counter == 2) { - ms_counter += 1; - this.token = event.data; - }else if(ms_counter > 2) { - console.log("[WEBSOCKET MESSAGE]: " + event.data); - - if(event.data == "PONG") return; - - let splitm = event.data.split(':'); - let [sid, channel, username, ...message] = splitm; - message = message.join(':'); - - this.appState[ - this.appState.findIndex(obj => obj.serverID == sid) - ]['storedChannels'][ - this.appState[ - this.appState.findIndex(obj => obj.serverID == sid) - ]['storedChannels'].findIndex(obj => obj.channelTag === channel) - ]['messages'].unshift({ - 'username': username, - 'm_content': message, - 'datetime': Date.now() - }); - } - }); - message_ws.addEventListener("open", () => { - if(this.reconnect != null) { - clearInterval(this.reconnect); - } - this.heartbeat = setInterval(() => { - if(message_ws.readyState === WebSocket.OPEN) { - message_ws.send('PING'); - } - }, HEARTBEAT_INTERVAL); - }); - - message_ws.addEventListener("close", () => { - console.log('[WEBSOCKET CONNECTION LOST. ATTEMPTING TO RECONNECT]'); - clearInterval(this.heartbeat); - setTimeout(() => { this.initWebsocket(this.token); }, RECONNECT_INTERVAL); + this.ws = new wsConnection(this.username); + this.ws.handshake(this.token).then( (res) => { this.token = res; + this.ws.message_ws.addEventListener("message", this.receiveMessage); } ); + + }, + receiveMessage(event){ + console.log("[WEBSOCKET MESSAGE]: " + event.data); + if(event.data == "PONG") return; + + let splitm = event.data.split(':'); + let [sid, channel, username, ...message] = splitm; + message = message.join(':'); + + this.appState[ + this.appState.findIndex(obj => obj.serverID == sid) + ]['storedChannels'][ + this.appState[ + this.appState.findIndex(obj => obj.serverID == sid) + ]['storedChannels'].findIndex(obj => obj.channelTag === channel) + ]['messages'].unshift({ + 'username': username, + 'm_content': message, + 'datetime': Date.now() }); - this.ws = message_ws; - } - } + } }, }; diff --git a/src/websocket.jsx b/src/websocket.jsx new file mode 100644 index 0000000..b9e9e89 --- /dev/null +++ b/src/websocket.jsx @@ -0,0 +1,57 @@ +import { invoke } from '@tauri-apps/api/core'; +const HEARTBEAT_INTERVAL = 25000; +const RECONNECT_INTERVAL = 5000; +const HANDSHAKE_LENGTH = 2; +export class wsConnection extends EventTarget{ + message_ws = null; + heartbeat = null; + username = null; + + constructor(username) { + super(); + this.username = username; + this.connectWebsocket(); + } + connectWebsocket() { + this.message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); + this.message_ws.addEventListener("open", () => { + this.heartbeat = setInterval(() => { + if(this.message_ws.readyState === WebSocket.OPEN) { + this.message_ws.send('PING'); + } + }, HEARTBEAT_INTERVAL); + }); + } + handshake(token, username = this.username) { + return new Promise(resolve => { + let ms_counter = 0; + function handler(event) { + if(ms_counter === 0 ) { + ms_counter += 1; + console.log("[WEBSOCKET] Message from server (" + ms_counter + ")", event.data); + invoke('spellcheck', { token: token, username: username, key: event.data }) + .then((res) => { + this.send(res); + }).catch((err) => { + console.log(err); + }); + } else if(ms_counter === 1) { + ms_counter += 1; + if(event.data === 'CONNECTED') { + console.log('[WEBSOCKET CONNECTED]'); + this.send('TOKEN:'+token); + } + } else if (ms_counter == 2) { + ms_counter += 1; + this.removeEventListener("message", handler); + resolve(event.data); + } + } + this.message_ws.addEventListener("message", handler); + } + ); + } + send(msg) { + this.message_ws.send(msg); + } +} \ No newline at end of file From dfccbbc33855f64f19b76f2fb27dfe95469329bd Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 22:55:43 +0200 Subject: [PATCH 4/9] Finish separating websocket module --- src/app.js | 12 ++++++------ src/websocket.jsx | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/app.js b/src/app.js index f78ea9a..a3a0519 100644 --- a/src/app.js +++ b/src/app.js @@ -504,15 +504,15 @@ export default { }, initWebsocket(token){ this.ws = new wsConnection(this.username); - this.ws.handshake(this.token).then( (res) => { this.token = res; - this.ws.message_ws.addEventListener("message", this.receiveMessage); } ); + this.ws.addEventListener("reqHandshake", () => { + this.ws.handshake(this.token).then( (res) => { this.token = res; this.ws.startReceive(); } ); + }); + this.ws.connectWebsocket(); + this.ws.addEventListener("message", this.receiveMessage); }, receiveMessage(event){ - console.log("[WEBSOCKET MESSAGE]: " + event.data); - if(event.data == "PONG") return; - - let splitm = event.data.split(':'); + let splitm = event.detail.split(':'); let [sid, channel, username, ...message] = splitm; message = message.join(':'); diff --git a/src/websocket.jsx b/src/websocket.jsx index b9e9e89..ade6c51 100644 --- a/src/websocket.jsx +++ b/src/websocket.jsx @@ -1,6 +1,6 @@ import { invoke } from '@tauri-apps/api/core'; const HEARTBEAT_INTERVAL = 25000; -const RECONNECT_INTERVAL = 5000; +const RECONNECT_INTERVAL = 3000; const HANDSHAKE_LENGTH = 2; export class wsConnection extends EventTarget{ message_ws = null; @@ -10,17 +10,22 @@ export class wsConnection extends EventTarget{ constructor(username) { super(); this.username = username; - this.connectWebsocket(); } connectWebsocket() { this.message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); this.message_ws.addEventListener("open", () => { + this.dispatchEvent(new CustomEvent("reqHandshake")); this.heartbeat = setInterval(() => { if(this.message_ws.readyState === WebSocket.OPEN) { this.message_ws.send('PING'); } }, HEARTBEAT_INTERVAL); }); + this.message_ws.addEventListener("close", () => { + console.log('[WEBSOCKET CONNECTION LOST. ATTEMPTING TO RECONNECT]'); + clearInterval(this.heartbeat); + setTimeout(() => { this.connectWebsocket(); }, RECONNECT_INTERVAL); + }); } handshake(token, username = this.username) { return new Promise(resolve => { @@ -54,4 +59,13 @@ export class wsConnection extends EventTarget{ send(msg) { this.message_ws.send(msg); } + startReceive() { + this.message_ws.addEventListener("message", (event) => { + console.log("[WEBSOCKET MESSAGE]: " + event.data); + if(event.data == "PONG") return; + this.dispatchEvent(new CustomEvent("message", { + detail: event.data + })); + }); + } } \ No newline at end of file From 6a88bd354d010a9ed7a8e49817b8b65f80af3de8 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 23:39:25 +0200 Subject: [PATCH 5/9] Remove unused constants --- src/app.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/app.js b/src/app.js index a3a0519..9121686 100644 --- a/src/app.js +++ b/src/app.js @@ -1,9 +1,6 @@ import { invoke } from '@tauri-apps/api/core'; import { wsConnection } from './websocket.jsx'; -const HEARTBEAT_INTERVAL = 25000; -const RECONNECT_INTERVAL = 5000; - export default { name: "App", data() { @@ -505,7 +502,7 @@ export default { initWebsocket(token){ this.ws = new wsConnection(this.username); this.ws.addEventListener("reqHandshake", () => { - this.ws.handshake(this.token).then( (res) => { this.token = res; this.ws.startReceive(); } ); + this.ws.handshake(this.token).then( (res) => { console.log(this); this.token = res; this.ws.startReceive(); } ); }); this.ws.connectWebsocket(); this.ws.addEventListener("message", this.receiveMessage); From 08a55efe6b88dfe977cddfd035552b64c8105326 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 23:41:28 +0200 Subject: [PATCH 6/9] Remove unused argument --- src/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app.js b/src/app.js index 6aab79c..d5d6c87 100644 --- a/src/app.js +++ b/src/app.js @@ -500,7 +500,7 @@ export default { console.log(err); }) }, - initWebsocket(token){ + initWebsocket(){ this.ws = new wsConnection(this.username); this.ws.addEventListener("reqHandshake", () => { this.ws.handshake(this.token).then( (res) => { console.log(this); this.token = res; this.ws.startReceive(); } ); From 23a920b3f6fbea6972915819e8ff09d11575c8d0 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Wed, 3 Dec 2025 23:55:58 +0200 Subject: [PATCH 7/9] Small adjustments --- src/app.js | 2 +- src/websocket.jsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app.js b/src/app.js index d5d6c87..f934676 100644 --- a/src/app.js +++ b/src/app.js @@ -503,7 +503,7 @@ export default { initWebsocket(){ this.ws = new wsConnection(this.username); this.ws.addEventListener("reqHandshake", () => { - this.ws.handshake(this.token).then( (res) => { console.log(this); this.token = res; this.ws.startReceive(); } ); + this.ws.handshake(this.token).then( (res) => { this.token = res; this.ws.startReceive(); } ); }); this.ws.connectWebsocket(); this.ws.addEventListener("message", this.receiveMessage); diff --git a/src/websocket.jsx b/src/websocket.jsx index ade6c51..40c77f5 100644 --- a/src/websocket.jsx +++ b/src/websocket.jsx @@ -2,6 +2,8 @@ import { invoke } from '@tauri-apps/api/core'; const HEARTBEAT_INTERVAL = 25000; const RECONNECT_INTERVAL = 3000; const HANDSHAKE_LENGTH = 2; +const WEBSOCKET_URL = "wss://onlinedi.vision/wss"; + export class wsConnection extends EventTarget{ message_ws = null; heartbeat = null; @@ -12,7 +14,7 @@ export class wsConnection extends EventTarget{ this.username = username; } connectWebsocket() { - this.message_ws = new WebSocket("wss://onlinedi.vision/wss?username="+this.username); + this.message_ws = new WebSocket(WEBSOCKET_URL+"?username="+this.username); this.message_ws.addEventListener("open", () => { this.dispatchEvent(new CustomEvent("reqHandshake")); this.heartbeat = setInterval(() => { @@ -46,7 +48,7 @@ export class wsConnection extends EventTarget{ console.log('[WEBSOCKET CONNECTED]'); this.send('TOKEN:'+token); } - } else if (ms_counter == 2) { + } else if (ms_counter == HANDSHAKE_LENGTH) { ms_counter += 1; this.removeEventListener("message", handler); resolve(event.data); From ba844e054c5acbdbb9ec505a1fa891e770d8a202 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Thu, 4 Dec 2025 13:24:55 +0200 Subject: [PATCH 8/9] Remove leftover var --- src/app.js | 1 - src/{websocket.jsx => websocket.js} | 0 2 files changed, 1 deletion(-) rename src/{websocket.jsx => websocket.js} (100%) diff --git a/src/app.js b/src/app.js index f934676..a80ec1a 100644 --- a/src/app.js +++ b/src/app.js @@ -75,7 +75,6 @@ export default { return { ws: null, - heartbeat: null, logInSelected: true, loggedin: true, lusername: "", diff --git a/src/websocket.jsx b/src/websocket.js similarity index 100% rename from src/websocket.jsx rename to src/websocket.js From d63bfb899bbeed51d0c4e87f0e0be0fc201234f8 Mon Sep 17 00:00:00 2001 From: Doru991 Date: Thu, 4 Dec 2025 13:28:41 +0200 Subject: [PATCH 9/9] Small fixes --- src/app.js | 2 +- src/websocket.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/app.js b/src/app.js index a80ec1a..90962ca 100644 --- a/src/app.js +++ b/src/app.js @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; -import { wsConnection } from './websocket.jsx'; +import { wsConnection } from './websocket.js'; import { reloadApp } from './AppWrapper.vue' export default { diff --git a/src/websocket.js b/src/websocket.js index 40c77f5..69d96bb 100644 --- a/src/websocket.js +++ b/src/websocket.js @@ -25,7 +25,9 @@ export class wsConnection extends EventTarget{ }); this.message_ws.addEventListener("close", () => { console.log('[WEBSOCKET CONNECTION LOST. ATTEMPTING TO RECONNECT]'); - clearInterval(this.heartbeat); + if(this.heartbeat != null) { + clearInterval(this.heartbeat); + } setTimeout(() => { this.connectWebsocket(); }, RECONNECT_INTERVAL); }); }