mirror of
https://github.com/jech/galene.git
synced 2024-11-09 18:25:58 +01:00
Send user permissions to client.
We now maintain the user list in the serverConnection.
This commit is contained in:
parent
d0ef6a2c0f
commit
f0a39fca48
8 changed files with 120 additions and 54 deletions
|
@ -47,10 +47,12 @@ from the server; the field `kind` indicates the kind of message.
|
|||
|
||||
Once you have joined a group (see below), the remaining callbacks may
|
||||
trigger. The `onuser` callback is used to indicate that a user has joined
|
||||
or left the current group. The `onchat` callback indicates that a chat
|
||||
message has been posted to the group, and `onclearchat` indicates that the
|
||||
chat history has been cleared. Finally, `ondownstream` is called when the
|
||||
server pushes a stream to the client; see the section below about streams.
|
||||
or left the current group, or that their attributes have changed; the
|
||||
user's state can be found in the `users` dictionary. The `onchat`
|
||||
callback indicates that a chat message has been posted to the group, and
|
||||
`onclearchat` indicates that the chat history has been cleared. Finally,
|
||||
`ondownstream` is called when the server pushes a stream to the client;
|
||||
see the section below about streams.
|
||||
|
||||
You may now connect to the server.
|
||||
|
||||
|
|
|
@ -115,9 +115,10 @@ users a `user` message:
|
|||
```javascript
|
||||
{
|
||||
type: 'user',
|
||||
kind: 'add' or 'delete',
|
||||
kind: 'add' or 'change' or 'delete',
|
||||
id: id,
|
||||
username: username
|
||||
username: username,
|
||||
permissions: permissions
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ func (client *Client) Permissions() group.ClientPermissions {
|
|||
return group.ClientPermissions{}
|
||||
}
|
||||
|
||||
func (client *Client) PushClient(id, username string, add bool) error {
|
||||
func (client *Client) PushClient(id, username string, permissions group.ClientPermissions, kind string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,6 @@ type Client interface {
|
|||
SetPermissions(ClientPermissions)
|
||||
OverridePermissions(*Group) bool
|
||||
PushConn(g *Group, id string, conn conn.Up, tracks []conn.UpTrack, replace string) error
|
||||
PushClient(id, username string, add bool) error
|
||||
PushClient(id, username string, permissions ClientPermissions, kind string) error
|
||||
Kick(id, user, message string) error
|
||||
}
|
||||
|
|
|
@ -485,11 +485,13 @@ func AddClient(group string, c Client) (*Group, error) {
|
|||
g.clients[c.Id()] = c
|
||||
g.timestamp = time.Now()
|
||||
|
||||
id := c.Id()
|
||||
u := c.Username()
|
||||
c.PushClient(c.Id(), u, true)
|
||||
p := c.Permissions()
|
||||
c.PushClient(c.Id(), u, p, "add")
|
||||
for _, cc := range clients {
|
||||
c.PushClient(cc.Id(), cc.Username(), true)
|
||||
cc.PushClient(c.Id(), u, true)
|
||||
c.PushClient(cc.Id(), cc.Username(), cc.Permissions(), "add")
|
||||
cc.PushClient(id, u, p, "add")
|
||||
}
|
||||
|
||||
return g, nil
|
||||
|
@ -535,7 +537,7 @@ func DelClient(c Client) {
|
|||
|
||||
go func(clients []Client) {
|
||||
for _, cc := range clients {
|
||||
cc.PushClient(c.Id(), c.Username(), false)
|
||||
cc.PushClient(c.Id(), c.Username(), c.Permissions(), "delete")
|
||||
}
|
||||
}(clients)
|
||||
|
||||
|
|
|
@ -106,16 +106,13 @@ func (c *webClient) OverridePermissions(g *group.Group) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func (c *webClient) PushClient(id, username string, add bool) error {
|
||||
kind := "add"
|
||||
if !add {
|
||||
kind = "delete"
|
||||
}
|
||||
func (c *webClient) PushClient(id, username string, permissions group.ClientPermissions, kind string) error {
|
||||
return c.write(clientMessage{
|
||||
Type: "user",
|
||||
Kind: kind,
|
||||
Id: id,
|
||||
Username: username,
|
||||
Permissions: &permissions,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -989,6 +986,14 @@ func handleAction(c *webClient, a interface{}) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
id := c.Id()
|
||||
user := c.Username()
|
||||
clients := g.GetClients(nil)
|
||||
go func(clients []group.Client) {
|
||||
for _, cc := range clients {
|
||||
cc.PushClient(id, user, perms, "change")
|
||||
}
|
||||
}(clients)
|
||||
case kickAction:
|
||||
return group.KickError{
|
||||
a.id, a.username, a.message,
|
||||
|
|
|
@ -293,13 +293,11 @@ function setConnected(connected) {
|
|||
let userbox = document.getElementById('profile');
|
||||
let connectionbox = document.getElementById('login-container');
|
||||
if(connected) {
|
||||
resetUsers();
|
||||
clearChat();
|
||||
userbox.classList.remove('invisible');
|
||||
connectionbox.classList.add('invisible');
|
||||
displayUsername();
|
||||
} else {
|
||||
resetUsers();
|
||||
fillLogin();
|
||||
userbox.classList.add('invisible');
|
||||
connectionbox.classList.remove('invisible');
|
||||
|
@ -1654,9 +1652,6 @@ function resizePeers() {
|
|||
}
|
||||
}
|
||||
|
||||
/** @type{Object<string,string>} */
|
||||
let users = {};
|
||||
|
||||
/**
|
||||
* Lexicographic order, with case differences secondary.
|
||||
* @param{string} a
|
||||
|
@ -1683,9 +1678,6 @@ function stringCompare(a, b) {
|
|||
function addUser(id, name) {
|
||||
if(!name)
|
||||
name = null;
|
||||
if(id in users)
|
||||
throw new Error('Duplicate user id');
|
||||
users[id] = name;
|
||||
|
||||
let div = document.getElementById('users');
|
||||
let user = document.createElement('div');
|
||||
|
@ -1697,7 +1689,9 @@ function addUser(id, name) {
|
|||
let us = div.children;
|
||||
for(let i = 0; i < us.length; i++) {
|
||||
let child = us[i];
|
||||
let childname = users[child.id.slice('user-'.length)] || null;
|
||||
let childuser =
|
||||
serverConnection.users[child.id.slice('user-'.length)] || null;
|
||||
let childname = (childuser && childuser.username) || null;
|
||||
if(!childname || stringCompare(childname, name) > 0) {
|
||||
div.insertBefore(user, child);
|
||||
return;
|
||||
|
@ -1711,36 +1705,38 @@ function addUser(id, name) {
|
|||
* @param {string} id
|
||||
* @param {string} name
|
||||
*/
|
||||
function delUser(id, name) {
|
||||
if(!name)
|
||||
name = null;
|
||||
if(!(id in users))
|
||||
throw new Error('Unknown user id');
|
||||
if(users[id] !== name)
|
||||
throw new Error('Inconsistent user name');
|
||||
delete(users[id]);
|
||||
function changeUser(id, name) {
|
||||
let user = document.getElementById('user-' + id);
|
||||
if(!user) {
|
||||
console.warn('Unknown user ' + id);
|
||||
return;
|
||||
}
|
||||
user.textContent = name ? name : '(anon)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
*/
|
||||
function delUser(id) {
|
||||
let div = document.getElementById('users');
|
||||
let user = document.getElementById('user-' + id);
|
||||
div.removeChild(user);
|
||||
}
|
||||
|
||||
function resetUsers() {
|
||||
for(let id in users)
|
||||
delUser(id, users[id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {string} kind
|
||||
* @param {string} name
|
||||
*/
|
||||
function gotUser(id, kind, name) {
|
||||
function gotUser(id, kind) {
|
||||
switch(kind) {
|
||||
case 'add':
|
||||
addUser(id, name);
|
||||
addUser(id, serverConnection.users[id].username);
|
||||
break;
|
||||
case 'delete':
|
||||
delUser(id, name);
|
||||
delUser(id);
|
||||
break;
|
||||
case 'change':
|
||||
changeUser(id, serverConnection.users[id].username);
|
||||
break;
|
||||
default:
|
||||
console.warn('Unknown user kind', kind);
|
||||
|
@ -1986,8 +1982,10 @@ function addToChatbox(peerId, dest, nick, time, privileged, kind, message) {
|
|||
let header = document.createElement('p');
|
||||
if(peerId || nick || dest) {
|
||||
let user = document.createElement('span');
|
||||
let u = serverConnection.users[dest];
|
||||
let name = (u && u.username);
|
||||
user.textContent = dest ?
|
||||
`${nick||'(anon)'} \u2192 ${users[dest]||'(anon)'}` :
|
||||
`${nick||'(anon)'} \u2192 ${name || '(anon)'}` :
|
||||
(nick || '(anon)');
|
||||
user.classList.add('message-user');
|
||||
header.appendChild(user);
|
||||
|
@ -2246,11 +2244,12 @@ function parseCommand(line) {
|
|||
* @param {string} user
|
||||
*/
|
||||
function findUserId(user) {
|
||||
if(user in users)
|
||||
if(user in serverConnection.users)
|
||||
return user;
|
||||
|
||||
for(let id in users) {
|
||||
if(users[id] === user)
|
||||
for(let id in serverConnection.users) {
|
||||
let u = serverConnection.users[id];
|
||||
if(u && u.username === user)
|
||||
return id;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -60,6 +60,12 @@ function newLocalId() {
|
|||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} user
|
||||
* @property {string} username
|
||||
* @property {Object<string,boolean>} permissions
|
||||
*/
|
||||
|
||||
/**
|
||||
* ServerConnection encapsulates a websocket connection to the server and
|
||||
* all the associated streams.
|
||||
|
@ -81,8 +87,16 @@ function ServerConnection() {
|
|||
this.group = null;
|
||||
/**
|
||||
* The username we joined as.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
this.username = null;
|
||||
/**
|
||||
* The set of users in this group, including ourself.
|
||||
*
|
||||
* @type {Object<string,user>}
|
||||
*/
|
||||
this.users = {};
|
||||
/**
|
||||
* The underlying websocket.
|
||||
*
|
||||
|
@ -136,9 +150,10 @@ function ServerConnection() {
|
|||
*/
|
||||
this.onclose = null;
|
||||
/**
|
||||
* onuser is called whenever a user is added or removed from the group
|
||||
* onuser is called whenever a user in the group changes. The users
|
||||
* array has already been updated.
|
||||
*
|
||||
* @type{(this: ServerConnection, id: string, kind: string, username: string) => void}
|
||||
* @type{(this: ServerConnection, id: string, kind: string) => void}
|
||||
*/
|
||||
this.onuser = null;
|
||||
/**
|
||||
|
@ -260,6 +275,11 @@ ServerConnection.prototype.connect = async function(url) {
|
|||
let c = sc.down[id];
|
||||
c.close();
|
||||
}
|
||||
for(let id in sc.users) {
|
||||
delete(sc.users[id]);
|
||||
if(sc.onuser)
|
||||
sc.onuser.call(sc, id, 'delete');
|
||||
}
|
||||
if(sc.group && sc.onjoined)
|
||||
sc.onjoined.call(sc, 'leave', sc.group, {}, '');
|
||||
sc.group = null;
|
||||
|
@ -303,14 +323,51 @@ ServerConnection.prototype.connect = async function(url) {
|
|||
sc.username = m.username;
|
||||
sc.permissions = m.permissions || [];
|
||||
sc.rtcConfiguration = m.rtcConfiguration || null;
|
||||
if(m.kind == 'leave') {
|
||||
for(let id in sc.users) {
|
||||
delete(sc.users[id]);
|
||||
if(sc.onuser)
|
||||
sc.onuser.call(sc, id, 'delete');
|
||||
}
|
||||
}
|
||||
if(sc.onjoined)
|
||||
sc.onjoined.call(sc, m.kind, m.group,
|
||||
m.permissions || {},
|
||||
m.value || null);
|
||||
break;
|
||||
case 'user':
|
||||
switch(m.kind) {
|
||||
case 'add':
|
||||
if(m.id in sc.users)
|
||||
console.warn(`Duplicate user ${m.id} ${m.username}`);
|
||||
sc.users[m.id] = {
|
||||
username: m.username,
|
||||
permissions: m.permissions,
|
||||
};
|
||||
break;
|
||||
case 'change':
|
||||
if(!(m.id in sc.users)) {
|
||||
console.warn(`Unknown user ${m.id} ${m.username}`);
|
||||
sc.users[m.id] = {
|
||||
username: m.username,
|
||||
permissions: m.permissions,
|
||||
};
|
||||
} else {
|
||||
sc.users[m.id].username = m.username;
|
||||
sc.users[m.id].permissions = m.permissions;
|
||||
}
|
||||
break;
|
||||
case 'delete':
|
||||
if(!(m.id in sc.users))
|
||||
console.warn(`Unknown user ${m.id} ${m.username}`);
|
||||
delete(sc.users[m.id]);
|
||||
break;
|
||||
default:
|
||||
console.warn(`Unknown user action ${m.kind}`);
|
||||
return;
|
||||
}
|
||||
if(sc.onuser)
|
||||
sc.onuser.call(sc, m.id, m.kind, m.username);
|
||||
sc.onuser.call(sc, m.id, m.kind);
|
||||
break;
|
||||
case 'chat':
|
||||
if(sc.onchat)
|
||||
|
|
Loading…
Reference in a new issue