Chat updates (#92)
* Send PONG responses to PINGs * Split out client IDs for viewer counts vs. websocket IDs * WIP username change event * Display username changes * Revert commented out code * Add support for building from the current branch * Fix PONG * Make username changes have a unique ID * Add a version param to js to cachebust
This commit is contained in:
@@ -114,6 +114,11 @@ class Owncast {
|
||||
if (this.websocketReconnectTimer) {
|
||||
clearTimeout(this.websocketReconnectTimer);
|
||||
}
|
||||
|
||||
// If we're "online" then enable the chat.
|
||||
if (this.streamStatus && this.streamStatus.online) {
|
||||
this.messagingInterface.enableChat();
|
||||
}
|
||||
};
|
||||
ws.onclose = (e) => {
|
||||
// connection closed, discard old websocket and create a new one in 5s
|
||||
@@ -124,22 +129,36 @@ class Owncast {
|
||||
};
|
||||
// On ws error just close the socket and let it re-connect again for now.
|
||||
ws.onerror = e => {
|
||||
this.handleNetworkingError(`Stream status: ${e}`);
|
||||
this.handleNetworkingError(`Socket error: ${JSON.parse(e)}`);
|
||||
ws.close();
|
||||
};
|
||||
ws.onmessage = (e) => {
|
||||
const model = JSON.parse(e.data);
|
||||
// Ignore non-chat messages (such as keepalive PINGs)
|
||||
if (model.type !== SOCKET_MESSAGE_TYPES.CHAT) {
|
||||
return;
|
||||
|
||||
// Send PONGs
|
||||
if (model.type === SOCKET_MESSAGE_TYPES.PING) {
|
||||
this.sendPong(ws);
|
||||
return;
|
||||
} else if (model.type === SOCKET_MESSAGE_TYPES.CHAT) {
|
||||
const message = new Message(model);
|
||||
this.addMessage(message);
|
||||
} else if (model.type === SOCKET_MESSAGE_TYPES.NAME_CHANGE) {
|
||||
this.addMessage(model);
|
||||
}
|
||||
const message = new Message(model);
|
||||
this.addMessage(message);
|
||||
};
|
||||
this.websocket = ws;
|
||||
this.messagingInterface.setWebsocket(this.websocket);
|
||||
};
|
||||
|
||||
sendPong(ws) {
|
||||
try {
|
||||
const pong = { type: SOCKET_MESSAGE_TYPES.PONG };
|
||||
ws.send(JSON.stringify(pong));
|
||||
} catch (e) {
|
||||
console.log('PONG error:', e);
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(message) {
|
||||
const existing = this.vueApp.messages.filter(function (item) {
|
||||
return item.id === message.id;
|
||||
|
||||
@@ -142,6 +142,7 @@ class MessagingInterface {
|
||||
}
|
||||
|
||||
handleUpdateUsername() {
|
||||
const oldName = this.username;
|
||||
var newValue = this.inputChangeUserName.value;
|
||||
newValue = newValue.trim();
|
||||
// do other string cleanup?
|
||||
@@ -154,6 +155,10 @@ class MessagingInterface {
|
||||
setLocalStorage(KEY_AVATAR, this.imgUsernameAvatar.src);
|
||||
}
|
||||
this.handleHideChangeNameForm();
|
||||
|
||||
if (oldName !== newValue) {
|
||||
this.sendUsernameChange(oldName, newValue, this.imgUsernameAvatar.src);
|
||||
}
|
||||
}
|
||||
|
||||
handleUsernameKeydown(event) {
|
||||
@@ -164,6 +169,19 @@ class MessagingInterface {
|
||||
}
|
||||
}
|
||||
|
||||
sendUsernameChange(oldName, newName, image) {
|
||||
const nameChange = {
|
||||
type: SOCKET_MESSAGE_TYPES.NAME_CHANGE,
|
||||
oldName: oldName,
|
||||
newName: newName,
|
||||
image: image,
|
||||
};
|
||||
|
||||
const jsonMessage = JSON.stringify(nameChange);
|
||||
|
||||
this.websocket.send(jsonMessage)
|
||||
}
|
||||
|
||||
handleMessageInputKeydown(event) {
|
||||
var okCodes = [37,38,39,40,16,91,18,46,8];
|
||||
var value = this.formMessageInput.value.trim();
|
||||
@@ -213,6 +231,7 @@ class MessagingInterface {
|
||||
body: content,
|
||||
author: this.username,
|
||||
image: this.imgUsernameAvatar.src,
|
||||
type: SOCKET_MESSAGE_TYPES.CHAT,
|
||||
});
|
||||
const messageJSON = JSON.stringify(message);
|
||||
if (this.websocket) {
|
||||
|
||||
@@ -84,5 +84,5 @@ function messageBubbleColorForString(str) {
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
} : null;
|
||||
return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ', 0.3)';
|
||||
return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ', 0.4)';
|
||||
}
|
||||
@@ -6,7 +6,7 @@ const URL_PREFIX = LOCAL_TEST ? 'http://localhost:8080' : '';
|
||||
const URL_STATUS = `${URL_PREFIX}/status`;
|
||||
const URL_CHAT_HISTORY = `${URL_PREFIX}/chat`;
|
||||
const URL_STREAM = `${URL_PREFIX}/hls/stream.m3u8`;
|
||||
const URL_WEBSOCKET = LOCAL_TEST
|
||||
const URL_WEBSOCKET = LOCAL_TEST
|
||||
? 'wss://goth.land/entry'
|
||||
: `${location.protocol === 'https:' ? 'wss' : 'ws'}://${location.host}/entry`;
|
||||
|
||||
@@ -21,7 +21,9 @@ const URL_OWNCAST = 'https://github.com/gabek/owncast'; // used in footer
|
||||
// Webscoket setup
|
||||
const SOCKET_MESSAGE_TYPES = {
|
||||
CHAT: 'CHAT',
|
||||
PING: 'PING'
|
||||
PING: 'PING',
|
||||
NAME_CHANGE: 'NAME_CHANGE',
|
||||
PONG: 'PONG'
|
||||
}
|
||||
|
||||
// Video setup
|
||||
|
||||
Reference in New Issue
Block a user