diff --git a/static/galene.html b/static/galene.html
index a5d464e..8ffe699 100644
--- a/static/galene.html
+++ b/static/galene.html
@@ -105,9 +105,11 @@
-
-
+
diff --git a/static/galene.js b/static/galene.js
index 4747f13..411366b 100644
--- a/static/galene.js
+++ b/static/galene.js
@@ -32,6 +32,9 @@ let groupStatus = {};
/** @type {string} */
let token = null;
+/** @type {boolean} */
+let connectingAgain = false;
+
/**
* @typedef {Object} settings
* @property {boolean} [localMute]
@@ -289,27 +292,39 @@ function setConnected(connected) {
} else {
userbox.classList.add('invisible');
connectionbox.classList.remove('invisible');
- displayError('Disconnected', 'error');
+ if(!connectingAgain)
+ displayError('Disconnected', 'error');
hideVideo();
window.onresize = null;
}
}
/**
- * @this {ServerConnection}
- */
+ * @this {ServerConnection}
+ */
async function gotConnected() {
- let username, credentials;
+ setConnected(true);
+ let again = connectingAgain;
+ connectingAgain = false;
+ await join(again);
+}
+
+/**
+ * @param {boolean} again
+ */
+async function join(again) {
+ let username = getInputElement('username').value.trim();
+ let credentials;
if(token) {
credentials = {
type: 'token',
token: token,
};
- token = null;
+ if(!again)
+ // the first time around, we need to join with no username in
+ // order to give the server a chance to reply with 'need-username'.
+ username = null;
} else {
- setConnected(true);
-
- username = getInputElement('username').value.trim();
let pw = getInputElement('password').value;
getInputElement('password').value = '';
if(!groupStatus.authServer)
@@ -324,7 +339,7 @@ async function gotConnected() {
}
try {
- await this.join(group, username, credentials);
+ await serverConnection.join(group, username, credentials);
} catch(e) {
console.error(e);
displayError(e);
@@ -2314,29 +2329,42 @@ function setTitle(title) {
* @param {Array} perms
* @param {Object} status
* @param {Object} data
+ * @param {string} error
* @param {string} message
*/
-async function gotJoined(kind, group, perms, status, data, message) {
+async function gotJoined(kind, group, perms, status, data, error, message) {
let present = presentRequested;
presentRequested = null;
switch(kind) {
case 'fail':
- displayError('The server said: ' + message);
+ if(error === 'need-username' || error === 'duplicate-username') {
+ setVisibility('passwordform', false);
+ connectingAgain = true;
+ } else {
+ token = null;
+ }
+ if(error !== 'need-username')
+ displayError('The server said: ' + message);
this.close();
setButtonsVisibility();
return;
case 'redirect':
this.close();
+ token = null;
document.location.href = message;
return;
case 'leave':
this.close();
+ token = null;
setButtonsVisibility();
return;
case 'join':
case 'change':
- groupStatus = status;
+ token = null;
+ // don't discard endPoint and friends
+ for(let key in status)
+ groupStatus[key] = status[key];
setTitle((status && status.displayName) || capitalise(group));
displayUsername();
setButtonsVisibility();
@@ -2344,11 +2372,14 @@ async function gotJoined(kind, group, perms, status, data, message) {
return;
break;
default:
+ token = null;
displayError('Unknown join message');
this.close();
return;
}
+ token = null;
+
let input = /** @type{HTMLTextAreaElement} */
(document.getElementById('input'));
input.placeholder = 'Type /help for help';
@@ -3622,12 +3653,8 @@ document.getElementById('userform').onsubmit = async function(e) {
e.preventDefault();
if(connecting)
return;
- connecting = true;
- try {
- await serverConnect();
- } finally {
- connecting = false;
- }
+
+ setVisibility('passwordform', true);
if(getInputElement('presentboth').checked)
presentRequested = 'both';
@@ -3635,8 +3662,15 @@ document.getElementById('userform').onsubmit = async function(e) {
presentRequested = 'mike';
else
presentRequested = null;
-
getInputElement('presentoff').checked = true;
+
+ // Connect to the server, gotConnected will join.
+ connecting = true;
+ try {
+ await serverConnect();
+ } finally {
+ connecting = false;
+ }
};
document.getElementById('disconnectbutton').onclick = function(e) {
@@ -3759,14 +3793,15 @@ async function start() {
addFilters();
setMediaChoices(false).then(e => reflectSettings());
- if(parms.has('token')) {
+ if(parms.has('token'))
token = parms.get('token');
+
+ if(token) {
await serverConnect();
} else if(groupStatus.authPortal) {
window.location.href = groupStatus.authPortal;
} else {
- let container = document.getElementById("login-container");
- container.classList.remove('invisible');
+ setVisibility('login-container', true);
}
setViewportHeight();
}
diff --git a/static/protocol.js b/static/protocol.js
index 89b5701..3dfb3b3 100644
--- a/static/protocol.js
+++ b/static/protocol.js
@@ -179,7 +179,7 @@ function ServerConnection() {
*
* kind is one of 'join', 'fail', 'change' or 'leave'.
*
- * @type{(this: ServerConnection, kind: string, group: string, permissions: Array, status: Object, data: Object, message: string) => void}
+ * @type{(this: ServerConnection, kind: string, group: string, permissions: Array, status: Object, data: Object, error: string, message: string) => void}
*/
this.onjoined = null;
/**
@@ -321,7 +321,7 @@ ServerConnection.prototype.connect = async function(url) {
sc.onuser.call(sc, id, 'delete');
}
if(sc.group && sc.onjoined)
- sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '');
+ sc.onjoined.call(sc, 'leave', sc.group, [], {}, {}, '', '');
sc.group = null;
sc.username = null;
if(sc.onclose)
@@ -393,7 +393,7 @@ ServerConnection.prototype.connect = async function(url) {
sc.onjoined.call(sc, m.kind, m.group,
m.permissions || [],
m.status, m.data,
- m.value || null);
+ m.error || null, m.value || null);
break;
case 'user':
switch(m.kind) {
@@ -505,8 +505,10 @@ ServerConnection.prototype.join = async function(group, username, credentials, d
type: 'join',
kind: 'join',
group: group,
- username: username,
};
+ if(typeof username !== 'undefined' && username !== null)
+ m.username = username;
+
if((typeof credentials) === 'string') {
m.password = credentials;
} else {