mirror of
https://github.com/jech/galene.git
synced 2024-11-22 16:45:58 +01:00
Make the value field of client messages carry arbitrary types.
This commit is contained in:
parent
5e831ab536
commit
d09c0f0a80
4 changed files with 64 additions and 56 deletions
|
@ -83,7 +83,7 @@ type ChatHistoryEntry struct {
|
||||||
User string
|
User string
|
||||||
Time int64
|
Time int64
|
||||||
Kind string
|
Kind string
|
||||||
Value string
|
Value interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -620,7 +620,7 @@ func (g *Group) ClearChatHistory() {
|
||||||
g.history = nil
|
g.history = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Group) AddToChatHistory(id, user string, time int64, kind, value string) {
|
func (g *Group) AddToChatHistory(id, user string, time int64, kind string, value interface{}) {
|
||||||
g.mu.Lock()
|
g.mu.Lock()
|
||||||
defer g.mu.Unlock()
|
defer g.mu.Unlock()
|
||||||
|
|
||||||
|
|
|
@ -27,13 +27,12 @@ func errorToWSCloseMessage(id string, err error) (*clientMessage, []byte) {
|
||||||
code = websocket.CloseNormalClosure
|
code = websocket.CloseNormalClosure
|
||||||
case group.ProtocolError:
|
case group.ProtocolError:
|
||||||
code = websocket.CloseProtocolError
|
code = websocket.CloseProtocolError
|
||||||
s := e.Error()
|
|
||||||
m = &clientMessage{
|
m = &clientMessage{
|
||||||
Type: "usermessage",
|
Type: "usermessage",
|
||||||
Kind: "error",
|
Kind: "error",
|
||||||
Dest: id,
|
Dest: id,
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
Value: &s,
|
Value: e.Error(),
|
||||||
}
|
}
|
||||||
text = e.Error()
|
text = e.Error()
|
||||||
case group.UserError, group.KickError:
|
case group.UserError, group.KickError:
|
||||||
|
@ -171,7 +170,7 @@ type clientMessage struct {
|
||||||
Privileged bool `json:"privileged,omitempty"`
|
Privileged bool `json:"privileged,omitempty"`
|
||||||
Permissions *group.ClientPermissions `json:"permissions,omitempty"`
|
Permissions *group.ClientPermissions `json:"permissions,omitempty"`
|
||||||
Group string `json:"group,omitempty"`
|
Group string `json:"group,omitempty"`
|
||||||
Value *string `json:"value,omitempty"`
|
Value interface{} `json:"value,omitempty"`
|
||||||
Time int64 `json:"time,omitempty"`
|
Time int64 `json:"time,omitempty"`
|
||||||
Offer *webrtc.SessionDescription `json:"offer,omitempty"`
|
Offer *webrtc.SessionDescription `json:"offer,omitempty"`
|
||||||
Answer *webrtc.SessionDescription `json:"answer,omitempty"`
|
Answer *webrtc.SessionDescription `json:"answer,omitempty"`
|
||||||
|
@ -808,11 +807,10 @@ func clientLoop(c *webClient, ws *websocket.Conn) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case addLabelAction:
|
case addLabelAction:
|
||||||
label := a.label
|
|
||||||
c.write(clientMessage{
|
c.write(clientMessage{
|
||||||
Type: "label",
|
Type: "label",
|
||||||
Id: a.id,
|
Id: a.id,
|
||||||
Value: &label,
|
Value: a.label,
|
||||||
})
|
})
|
||||||
case pushConnsAction:
|
case pushConnsAction:
|
||||||
g := c.group
|
g := c.group
|
||||||
|
@ -1063,7 +1061,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
Kind: "fail",
|
Kind: "fail",
|
||||||
Group: m.Group,
|
Group: m.Group,
|
||||||
Permissions: &group.ClientPermissions{},
|
Permissions: &group.ClientPermissions{},
|
||||||
Value: &s,
|
Value: s,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if redirect := g.Redirect(); redirect != "" {
|
if redirect := g.Redirect(); redirect != "" {
|
||||||
|
@ -1074,7 +1072,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
Kind: "redirect",
|
Kind: "redirect",
|
||||||
Group: m.Group,
|
Group: m.Group,
|
||||||
Permissions: &group.ClientPermissions{},
|
Permissions: &group.ClientPermissions{},
|
||||||
Value: &redirect,
|
Value: redirect,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
c.group = g
|
c.group = g
|
||||||
|
@ -1090,13 +1088,12 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
}
|
}
|
||||||
h := c.group.GetChatHistory()
|
h := c.group.GetChatHistory()
|
||||||
for _, m := range h {
|
for _, m := range h {
|
||||||
message := m.Value
|
|
||||||
err := c.write(clientMessage{
|
err := c.write(clientMessage{
|
||||||
Type: "chat",
|
Type: "chat",
|
||||||
Id: m.Id,
|
Id: m.Id,
|
||||||
Username: m.User,
|
Username: m.User,
|
||||||
Time: m.Time,
|
Time: m.Time,
|
||||||
Value: &message,
|
Value: m.Value,
|
||||||
Kind: m.Kind,
|
Kind: m.Kind,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1184,12 +1181,9 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
tm := group.ToJSTime(time.Now())
|
tm := group.ToJSTime(time.Now())
|
||||||
|
|
||||||
if m.Type == "chat" {
|
if m.Type == "chat" {
|
||||||
if m.Value == nil {
|
|
||||||
return group.ProtocolError("missing value")
|
|
||||||
}
|
|
||||||
if m.Dest == "" {
|
if m.Dest == "" {
|
||||||
g.AddToChatHistory(
|
g.AddToChatHistory(
|
||||||
m.Id, m.Username, tm, m.Kind, *m.Value,
|
m.Id, m.Username, tm, m.Kind, m.Value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1249,8 +1243,9 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
return c.error(group.UserError("not authorised"))
|
return c.error(group.UserError("not authorised"))
|
||||||
}
|
}
|
||||||
message := ""
|
message := ""
|
||||||
if m.Value != nil {
|
v, ok := m.Value.(string)
|
||||||
message = *m.Value
|
if ok {
|
||||||
|
message = v
|
||||||
}
|
}
|
||||||
g.SetLocked(m.Kind == "lock", message)
|
g.SetLocked(m.Kind == "lock", message)
|
||||||
case "record":
|
case "record":
|
||||||
|
@ -1299,7 +1294,7 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
Dest: c.id,
|
Dest: c.id,
|
||||||
Username: "Server",
|
Username: "Server",
|
||||||
Time: group.ToJSTime(time.Now()),
|
Time: group.ToJSTime(time.Now()),
|
||||||
Value: &s,
|
Value: s,
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
return group.ProtocolError("unknown group action")
|
return group.ProtocolError("unknown group action")
|
||||||
|
@ -1329,8 +1324,9 @@ func handleClientMessage(c *webClient, m clientMessage) error {
|
||||||
return c.error(group.UserError("not authorised"))
|
return c.error(group.UserError("not authorised"))
|
||||||
}
|
}
|
||||||
message := ""
|
message := ""
|
||||||
if m.Value != nil {
|
v, ok := m.Value.(string)
|
||||||
message = *m.Value
|
if ok {
|
||||||
|
message = v
|
||||||
}
|
}
|
||||||
err := kickClient(g, m.Id, m.Username, m.Dest, message)
|
err := kickClient(g, m.Id, m.Username, m.Dest, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -1420,7 +1416,7 @@ func (c *webClient) Warn(oponly bool, message string) error {
|
||||||
Kind: "warning",
|
Kind: "warning",
|
||||||
Dest: c.id,
|
Dest: c.id,
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
Value: &message,
|
Value: message,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1456,13 +1452,12 @@ func (c *webClient) close(data []byte) error {
|
||||||
func errorMessage(id string, err error) *clientMessage {
|
func errorMessage(id string, err error) *clientMessage {
|
||||||
switch e := err.(type) {
|
switch e := err.(type) {
|
||||||
case group.UserError:
|
case group.UserError:
|
||||||
message := e.Error()
|
|
||||||
return &clientMessage{
|
return &clientMessage{
|
||||||
Type: "usermessage",
|
Type: "usermessage",
|
||||||
Kind: "error",
|
Kind: "error",
|
||||||
Dest: id,
|
Dest: id,
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
Value: &message,
|
Value: e.Error(),
|
||||||
}
|
}
|
||||||
case group.KickError:
|
case group.KickError:
|
||||||
message := e.Message
|
message := e.Message
|
||||||
|
@ -1476,7 +1471,7 @@ func errorMessage(id string, err error) *clientMessage {
|
||||||
Username: e.Username,
|
Username: e.Username,
|
||||||
Dest: id,
|
Dest: id,
|
||||||
Privileged: true,
|
Privileged: true,
|
||||||
Value: &message,
|
Value: message,
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1549,6 +1549,43 @@ async function gotJoined(kind, group, perms, message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} id
|
||||||
|
* @param {string} dest
|
||||||
|
* @param {string} username
|
||||||
|
* @param {number} time
|
||||||
|
* @param {boolean} privileged
|
||||||
|
* @param {string} kind
|
||||||
|
* @param {unknown} message
|
||||||
|
*/
|
||||||
|
function gotUserMessage(id, dest, username, time, privileged, kind, message) {
|
||||||
|
switch(kind) {
|
||||||
|
case 'error':
|
||||||
|
case 'warning':
|
||||||
|
case 'info':
|
||||||
|
let from = id ? (username || 'Anonymous') : 'The Server';
|
||||||
|
if(privileged)
|
||||||
|
displayError(`${from} said: ${message}`, kind);
|
||||||
|
else
|
||||||
|
console.error(`Got unprivileged message of kind ${kind}`);
|
||||||
|
break;
|
||||||
|
case 'mute':
|
||||||
|
console.log(id, dest, username);
|
||||||
|
if(privileged) {
|
||||||
|
setLocalMute(true, true);
|
||||||
|
let by = username ? ' by ' + username : '';
|
||||||
|
displayWarning(`You have been muted${by}`);
|
||||||
|
} else {
|
||||||
|
console.error(`Got unprivileged message of kind ${kind}`);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.warn(`Got unknown user message ${kind}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const urlRegexp = /https?:\/\/[-a-zA-Z0-9@:%/._\\+~#&()=?]+[-a-zA-Z0-9@:%/_\\+~#&()=]/g;
|
const urlRegexp = /https?:\/\/[-a-zA-Z0-9@:%/._\\+~#&()=?]+[-a-zA-Z0-9@:%/_\\+~#&()=]/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1622,7 +1659,7 @@ let lastMessage = {};
|
||||||
* @param {string} nick
|
* @param {string} nick
|
||||||
* @param {number} time
|
* @param {number} time
|
||||||
* @param {string} kind
|
* @param {string} kind
|
||||||
* @param {string} message
|
* @param {unknown} message
|
||||||
*/
|
*/
|
||||||
function addToChatbox(peerId, dest, nick, time, privileged, kind, message) {
|
function addToChatbox(peerId, dest, nick, time, privileged, kind, message) {
|
||||||
let userpass = getUserPass();
|
let userpass = getUserPass();
|
||||||
|
@ -1641,7 +1678,7 @@ function addToChatbox(peerId, dest, nick, time, privileged, kind, message) {
|
||||||
container.classList.add('message-private');
|
container.classList.add('message-private');
|
||||||
|
|
||||||
if(kind !== 'me') {
|
if(kind !== 'me') {
|
||||||
let p = formatLines(message.split('\n'));
|
let p = formatLines(message.toString().split('\n'));
|
||||||
let doHeader = true;
|
let doHeader = true;
|
||||||
if(!peerId && !dest && !nick) {
|
if(!peerId && !dest && !nick) {
|
||||||
doHeader = false;
|
doHeader = false;
|
||||||
|
@ -1689,7 +1726,7 @@ function addToChatbox(peerId, dest, nick, time, privileged, kind, message) {
|
||||||
user.textContent = nick || '(anon)';
|
user.textContent = nick || '(anon)';
|
||||||
user.classList.add('message-me-user');
|
user.classList.add('message-me-user');
|
||||||
let content = document.createElement('span');
|
let content = document.createElement('span');
|
||||||
formatLine(message).forEach(elt => {
|
formatLine(message.toString()).forEach(elt => {
|
||||||
content.appendChild(elt);
|
content.appendChild(elt);
|
||||||
});
|
});
|
||||||
content.classList.add('message-me-content');
|
content.classList.add('message-me-content');
|
||||||
|
@ -2300,32 +2337,8 @@ async function serverConnect() {
|
||||||
serverConnection.onjoined = gotJoined;
|
serverConnection.onjoined = gotJoined;
|
||||||
serverConnection.onchat = addToChatbox;
|
serverConnection.onchat = addToChatbox;
|
||||||
serverConnection.onclearchat = clearChat;
|
serverConnection.onclearchat = clearChat;
|
||||||
serverConnection.onusermessage = function(id, dest, username, time, privileged, kind, message) {
|
serverConnection.onusermessage = gotUserMessage;
|
||||||
switch(kind) {
|
|
||||||
case 'error':
|
|
||||||
case 'warning':
|
|
||||||
case 'info':
|
|
||||||
let from = id ? (username || 'Anonymous') : 'The Server';
|
|
||||||
if(privileged)
|
|
||||||
displayError(`${from} said: ${message}`, kind);
|
|
||||||
else
|
|
||||||
console.error(`Got unprivileged message of kind ${kind}`);
|
|
||||||
break;
|
|
||||||
case 'mute':
|
|
||||||
console.log(id, dest, username);
|
|
||||||
if(privileged) {
|
|
||||||
setLocalMute(true, true);
|
|
||||||
let by = username ? ' by ' + username : '';
|
|
||||||
displayWarning(`You have been muted${by}`);
|
|
||||||
} else {
|
|
||||||
console.error(`Got unprivileged message of kind ${kind}`);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
console.warn(`Got unknown user message ${kind}`);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let url = `ws${location.protocol === 'https:' ? 's' : ''}://${location.host}/ws`;
|
let url = `ws${location.protocol === 'https:' ? 's' : ''}://${location.host}/ws`;
|
||||||
try {
|
try {
|
||||||
await serverConnection.connect(url);
|
await serverConnection.connect(url);
|
||||||
|
|
|
@ -142,7 +142,7 @@ function ServerConnection() {
|
||||||
/**
|
/**
|
||||||
* onchat is called whenever a new chat message is received.
|
* onchat is called whenever a new chat message is received.
|
||||||
*
|
*
|
||||||
* @type {(this: ServerConnection, id: string, dest: string, username: string, time: number, privileged: boolean, kind: string, message: string) => void}
|
* @type {(this: ServerConnection, id: string, dest: string, username: string, time: number, privileged: boolean, kind: string, message: unknown) => void}
|
||||||
*/
|
*/
|
||||||
this.onchat = null;
|
this.onchat = null;
|
||||||
/**
|
/**
|
||||||
|
@ -154,7 +154,7 @@ function ServerConnection() {
|
||||||
* 'id' is non-null, 'privileged' indicates whether the message was
|
* 'id' is non-null, 'privileged' indicates whether the message was
|
||||||
* sent by an operator.
|
* sent by an operator.
|
||||||
*
|
*
|
||||||
* @type {(this: ServerConnection, id: string, dest: string, username: string, time: number, privileged: boolean, kind: string, message: string) => void}
|
* @type {(this: ServerConnection, id: string, dest: string, username: string, time: number, privileged: boolean, kind: string, message: unknown) => void}
|
||||||
*/
|
*/
|
||||||
this.onusermessage = null;
|
this.onusermessage = null;
|
||||||
/**
|
/**
|
||||||
|
@ -177,7 +177,7 @@ function ServerConnection() {
|
||||||
* @property {boolean} [privileged]
|
* @property {boolean} [privileged]
|
||||||
* @property {Object<string,boolean>} [permissions]
|
* @property {Object<string,boolean>} [permissions]
|
||||||
* @property {string} [group]
|
* @property {string} [group]
|
||||||
* @property {string} [value]
|
* @property {unknown} [value]
|
||||||
* @property {RTCSessionDescriptionInit} [offer]
|
* @property {RTCSessionDescriptionInit} [offer]
|
||||||
* @property {RTCSessionDescriptionInit} [answer]
|
* @property {RTCSessionDescriptionInit} [answer]
|
||||||
* @property {RTCIceCandidate} [candidate]
|
* @property {RTCIceCandidate} [candidate]
|
||||||
|
|
Loading…
Reference in a new issue