diff --git a/src/ami.js/ctx.js b/src/ami.js/ctx.js index 4aba53f..6356ed9 100644 --- a/src/ami.js/ctx.js +++ b/src/ami.js/ctx.js @@ -6,7 +6,6 @@ #include messages.jsx #include notify.js #include reconnect.jsx -#include servers.js #include settings.js #include sockchat.js #include sound.js @@ -175,10 +174,9 @@ var AmiContext = function(title, auth, flashii, loading) { var emoticons = new AmiEmoticons; pub.emoticons = emoticons; - pub.servers = new AmiServers; pub.windowTitle = new AmiWindowTitle(title); - var sockChat = new AmiSockChat(auth); + var sockChat = new AmiSockChat(auth, flashii); pub.sockChat = sockChat; var chat = new AmiChat(pub, title, document.body); diff --git a/src/ami.js/flashii.js b/src/ami.js/flashii.js index 367c10f..a3428c3 100644 --- a/src/ami.js/flashii.js +++ b/src/ami.js/flashii.js @@ -94,6 +94,14 @@ const Flashii = function(baseUrl) { fii.v1 = {}; + const verifyChatServerId = id => { + if(typeof id === 'number') + id = id.toString(); + if(/^([^0-9]+)$/gu.test(id)) + throw new Error('id argument is not an acceptable chat server id.'); + return id; + }; + fii.v1.chat = {}; fii.v1.chat.login = function({ redirect=null, assign=true }) { return new Commitment(success => { @@ -111,6 +119,73 @@ const Flashii = function(baseUrl) { success(url); }); }; + fii.v1.chat.servers = function({ proto=null, secure=null, fields=null, fresh=false }) { + return new Commitment((success, fail) => { + const params = {}; + + if(proto !== null && typeof proto !== 'string') + throw new Error('proto must be a string or null'); + params['proto'] = proto; + + if(secure !== null) + params['secure'] = secure ? '1' : '0'; + + send({ method: 'GET', path: '/v1/chat/servers', fields, fresh, params }) + .success(({ status, body }) => { + if(status === 400) + throw new Error('An argument contains an unsupported value.'); + if(status > 299) + throw new Error(`Failed to fetch chat server list with error code ${status}.`); + + success(body); + }) + .fail(fail) + .run(); + }); + }; + fii.v1.chat.servers.server = function({ id, fields=null, fresh=false }) { + return new Commitment((success, fail) => { + id = verifyChatServerId(id); + + send({ method: 'GET', path: `/v1/chat/servers/${id}`, fields, fresh }) + .success(({ status, body }) => { + if(status === 400) + throw new Error('Fields argument contains unsupported value.'); + if(status === 404) + throw new Error('No chat server with that id could be found.'); + if(status > 299) + throw new Error(`Failed to fetch chat server with error code ${status}.`); + + success(body); + }) + .fail(fail) + .run(); + }); + }; + fii.v1.chat.servers.recommended = function({ proto, secure=null, fields=null, fresh=false }) { + return new Commitment((success, fail) => { + if(typeof proto !== 'string') + throw new Error('proto must be a string'); + + const params = { proto }; + if(secure !== null) + params['secure'] = secure ? '1' : '0'; + + send({ method: 'GET', path: '/v1/chat/servers/recommended', fields, fresh, params }) + .success(({ status, body }) => { + if(status === 400) + throw new Error('An argument contains an unsupported value.'); + if(status === 404) + throw new Error('Was unable to determine a server based on the requested parameters.'); + if(status > 299) + throw new Error(`Failed to fetch recommended chat server with error code ${status}.`); + + success(body); + }) + .fail(fail) + .run(); + }); + }; fii.v1.chat.token = function() { return new Commitment((success, fail) => { send({ method: 'GET', path: '/v1/chat/token', authed: true, fresh: true }) diff --git a/src/ami.js/servers.js b/src/ami.js/servers.js deleted file mode 100644 index 0321340..0000000 --- a/src/ami.js/servers.js +++ /dev/null @@ -1,21 +0,0 @@ -#include common.js - -var AmiServers = function() { - var servers = futami.get('servers').slice(0), - index = 0xFFFF; - - $arrayShuffle(servers); - - return { - getServer: function(callback) { - if(++index >= servers.length) - index = 0; - - var server = servers[index]; - if(server.indexOf('//') >= 0) - server = location.protocol.replace('http', 'ws') + server; - - callback(server); - }, - }; -}; diff --git a/src/ami.js/sockchat.js b/src/ami.js/sockchat.js index de06b0b..e4ae00e 100644 --- a/src/ami.js/sockchat.js +++ b/src/ami.js/sockchat.js @@ -1,8 +1,7 @@ #include auth.js -#include servers.js #include watcher.js -var AmiSockChat = function(auth) { +var AmiSockChat = function(auth, flashii) { if(!AmiIsAuth(auth)) throw new Error('auth param is not acceptable'); @@ -119,13 +118,16 @@ var AmiSockChat = function(auth) { wasConnected: wasConnected, }]); - ami.servers.getServer(function(server) { - sock = new WebSocket(server); - sock.addEventListener('open', onOpen); - sock.addEventListener('close', onClose); - sock.addEventListener('error', onError); - sock.addEventListener('message', onMessage); - }.bind(this)); + flashii.v1.chat.servers.recommended({ proto: 'sockchat' }) + .success(({ uri }) => { + sock = new WebSocket(uri); + sock.addEventListener('open', onOpen); + sock.addEventListener('close', onClose); + sock.addEventListener('error', onError); + sock.addEventListener('message', onMessage); + }) + .fail(ex => { onError(ex); }) + .run(); }; var formatBotMsg = function(type, args, isError) {