flash
cf71bab92d
This has been in the works for over a month and might break things because it's a very radical change. If it causes you to be unable to join chat, report it on the forum or try joining using the legacy chat on https://sockchat.flashii.net.
376 lines
12 KiB
JavaScript
376 lines
12 KiB
JavaScript
#include animate.js
|
|
#include channels.js
|
|
#include messages.js
|
|
#include parsing.js
|
|
#include users.js
|
|
#include ui/baka.jsx
|
|
#include ui/emotes.js
|
|
#include ui/markup.js
|
|
#include ui/menus.js
|
|
#include ui/messages.jsx
|
|
|
|
const MamiSockChatHandlers = function(ctx, client, setLoadingOverlay, sockChatReconnect, pingIndicator, pingToggle) {
|
|
if(typeof ctx !== 'object' || ctx === null)
|
|
throw 'ctx must be an non-null object';
|
|
if(typeof client !== 'object' || client === null)
|
|
throw 'client must be an non-null object';
|
|
if(typeof setLoadingOverlay !== 'function')
|
|
throw 'setLoadingOverlay must be a function';
|
|
if(typeof sockChatReconnect !== 'function')
|
|
throw 'sockChatReconnect must be a function';
|
|
if(typeof pingIndicator !== 'object' || pingIndicator === null)
|
|
throw 'pingIndicator must be an non-null object';
|
|
if(!(pingToggle instanceof Element))
|
|
throw 'pingToggle must be an instance of Element';
|
|
|
|
const handlers = {};
|
|
let dumpEvents = false;
|
|
|
|
handlers['conn:open'] = ev => {
|
|
if(dumpEvents) console.log('conn:open', ev.detail);
|
|
|
|
setLoadingOverlay('spinner', 'Connecting...', 'Authenticating...', true);
|
|
};
|
|
|
|
let legacyUmiConnectFired = false;
|
|
handlers['conn:ready'] = ev => {
|
|
if(dumpEvents) console.log('conn:ready');
|
|
|
|
client.authenticate().then(() => {
|
|
if(!legacyUmiConnectFired) {
|
|
legacyUmiConnectFired = true;
|
|
ctx.globalEvents.dispatch('umi:connect');
|
|
}
|
|
});
|
|
};
|
|
|
|
handlers['conn:lost'] = ev => {
|
|
if(dumpEvents) console.log('conn:lost', ev.detail);
|
|
|
|
if(ctx.conMan.isActive || ctx.isUnloading || ev.detail.wasKicked)
|
|
return;
|
|
|
|
sockChatRestarting = ev.detail.isRestarting;
|
|
sockChatReconnect();
|
|
};
|
|
|
|
|
|
handlers['ping:send'] = () => {
|
|
if(dumpEvents) console.log('ping:send');
|
|
};
|
|
handlers['ping:long'] = ev => {
|
|
if(dumpEvents) console.log('ping:long', ev.detail);
|
|
|
|
sockChatReconnect();
|
|
};
|
|
handlers['ping:recv'] = ev => {
|
|
if(dumpEvents) console.log('ping:recv', ev.detail);
|
|
|
|
let strength = 3;
|
|
if(ev.detail.diff >= 800) --strength;
|
|
if(ev.detail.diff >= 400) --strength;
|
|
if(ev.detail.diff >= 200) --strength;
|
|
|
|
pingToggle.title = `${ev.detail.diff.toLocaleString()}ms`;
|
|
pingIndicator.setStrength(strength);
|
|
};
|
|
|
|
|
|
handlers['session:start'] = ev => {
|
|
if(dumpEvents) console.log('session:start', ev.detail);
|
|
|
|
sockChatRestarting = false;
|
|
|
|
const userInfo = new MamiUserInfo(
|
|
ev.detail.user.id,
|
|
ev.detail.user.name,
|
|
ev.detail.user.colour,
|
|
new MamiUserStatusInfo(ev.detail.user.status.isAway, ev.detail.user.status.message),
|
|
new MamiUserPermsInfo(
|
|
ev.detail.user.perms.rank, ev.detail.user.perms.kick,
|
|
ev.detail.user.perms.nick, ev.detail.user.perms.chan,
|
|
),
|
|
);
|
|
Umi.User.setCurrentUser(userInfo);
|
|
Umi.Users.Add(userInfo);
|
|
|
|
Umi.UI.Markup.Reset();
|
|
Umi.UI.Emoticons.Init();
|
|
Umi.Parsing.Init();
|
|
|
|
if(ctx.views.count() > 1)
|
|
ctx.views.pop(ctx => MamiAnimate({
|
|
async: true,
|
|
duration: 120,
|
|
easing: 'inOutSine',
|
|
start: () => {
|
|
ctx.toElem.style.zIndex = '100';
|
|
ctx.fromElem.style.pointerEvents = 'none';
|
|
ctx.fromElem.style.zIndex = '200';
|
|
},
|
|
update: t => {
|
|
ctx.fromElem.style.transform = `scale(${1 + (.25 * t)})`;
|
|
ctx.fromElem.style.opacity = 1 - (1 * t).toString();
|
|
},
|
|
end: () => {
|
|
ctx.toElem.style.zIndex = null;
|
|
},
|
|
}));
|
|
};
|
|
handlers['session:fail'] = ev => {
|
|
if(dumpEvents) console.log('session:fail', ev.detail);
|
|
|
|
if(ev.detail.baka !== undefined) {
|
|
new MamiForceDisconnectNotice(ev.detail.baka).pushOn(ctx.views);
|
|
return;
|
|
}
|
|
|
|
if(ev.detail.session.needsAuth) {
|
|
location.assign(futami.get('login'));
|
|
return;
|
|
}
|
|
|
|
setLoadingOverlay('cross', 'Failed!', ev.detail.session.outOfConnections ? 'Too many active connections.' : 'Unspecified reason.');
|
|
};
|
|
handlers['session:term'] = ev => {
|
|
if(dumpEvents) console.log('session:term', ev.detail);
|
|
|
|
new MamiForceDisconnectNotice(ev.detail.baka).pushOn(ctx.views);
|
|
};
|
|
|
|
|
|
handlers['user:add'] = ev => {
|
|
if(dumpEvents) console.log('user:add', ev.detail);
|
|
|
|
if(ev.detail.user.self)
|
|
return;
|
|
|
|
const userInfo = new MamiUserInfo(
|
|
ev.detail.user.id,
|
|
ev.detail.user.name,
|
|
ev.detail.user.colour,
|
|
new MamiUserStatusInfo(ev.detail.user.status.isAway, ev.detail.user.status.message),
|
|
new MamiUserPermsInfo(
|
|
ev.detail.user.perms.rank, ev.detail.user.perms.kick,
|
|
ev.detail.user.perms.nick, ev.detail.user.perms.chan,
|
|
),
|
|
);
|
|
Umi.Users.Add(userInfo);
|
|
|
|
if(ev.detail.msg !== undefined)
|
|
Umi.Messages.Add(new Umi.Message(
|
|
ev.detail.msg.id, ev.detail.msg.time, undefined, '', ev.detail.msg.channel, false,
|
|
{
|
|
isError: false,
|
|
type: ev.detail.msg.botInfo.type,
|
|
args: ev.detail.msg.botInfo.args,
|
|
target: userInfo,
|
|
}
|
|
));
|
|
};
|
|
handlers['user:remove'] = ev => {
|
|
if(dumpEvents) console.log('user:remove', ev.detail);
|
|
|
|
const userInfo = Umi.Users.Get(ev.detail.user.id);
|
|
if(userInfo === null)
|
|
return;
|
|
|
|
if(ev.detail.msg !== undefined)
|
|
Umi.Messages.Add(new Umi.Message(
|
|
ev.detail.msg.id,
|
|
ev.detail.msg.time,
|
|
undefined,
|
|
'',
|
|
ev.detail.msg.channel,
|
|
false,
|
|
{
|
|
isError: false,
|
|
type: ev.detail.msg.botInfo.type,
|
|
args: ev.detail.msg.botInfo.args,
|
|
target: userInfo,
|
|
},
|
|
));
|
|
|
|
Umi.Users.Remove(userInfo);
|
|
};
|
|
handlers['user:update'] = ev => {
|
|
if(dumpEvents) console.log('user:update', ev.detail);
|
|
|
|
const userInfo = Umi.Users.Get(ev.detail.user.id);
|
|
userInfo.name = ev.detail.user.name;
|
|
userInfo.colour = ev.detail.user.colour;
|
|
userInfo.avatarChangeTime = Date.now();
|
|
userInfo.status = new MamiUserStatusInfo(ev.detail.user.status.isAway, ev.detail.user.status.message);
|
|
userInfo.perms = new MamiUserPermsInfo(
|
|
ev.detail.user.perms.rank, ev.detail.user.perms.kick,
|
|
ev.detail.user.perms.nick, ev.detail.user.perms.chan,
|
|
);
|
|
Umi.Users.Update(userInfo.id, userInfo);
|
|
};
|
|
handlers['user:clear'] = () => {
|
|
if(dumpEvents) console.log('user:clear');
|
|
|
|
const self = Umi.User.getCurrentUser();
|
|
Umi.Users.Clear();
|
|
if(self !== undefined)
|
|
Umi.Users.Add(self);
|
|
};
|
|
|
|
|
|
handlers['chan:add'] = ev => {
|
|
if(dumpEvents) console.log('chan:add', ev.detail);
|
|
|
|
Umi.Channels.Add(new MamiChannelInfo(
|
|
ev.detail.channel.name,
|
|
ev.detail.channel.hasPassword,
|
|
ev.detail.channel.isTemporary,
|
|
));
|
|
};
|
|
handlers['chan:remove'] = ev => {
|
|
if(dumpEvents) console.log('chan:remove', ev.detail);
|
|
|
|
Umi.Channels.Remove(Umi.Channels.Get(ev.detail.channel.name));
|
|
};
|
|
handlers['chan:update'] = ev => {
|
|
if(dumpEvents) console.log('chan:update', ev.detail);
|
|
|
|
const chanInfo = Umi.Channels.Get(ev.detail.channel.previousName);
|
|
chanInfo.name = ev.detail.channel.name;
|
|
chanInfo.hasPassword = ev.detail.channel.hasPassword;
|
|
chanInfo.isTemporary = ev.detail.channel.isTemporary;
|
|
Umi.Channels.Update(ev.detail.channel.previousName, chanInfo);
|
|
};
|
|
handlers['chan:clear'] = () => {
|
|
if(dumpEvents) console.log('chan:clear');
|
|
|
|
Umi.Channels.Clear();
|
|
};
|
|
handlers['chan:focus'] = ev => {
|
|
if(dumpEvents) console.log('chan:focus', ev.detail);
|
|
|
|
Umi.Channels.Switch(Umi.Channels.Get(ev.detail.channel.name));
|
|
};
|
|
handlers['chan:join'] = ev => {
|
|
if(dumpEvents) console.log('chan:join', ev.detail);
|
|
|
|
const userInfo = new MamiUserInfo(
|
|
ev.detail.user.id,
|
|
ev.detail.user.name,
|
|
ev.detail.user.colour,
|
|
new MamiUserStatusInfo(ev.detail.user.status.isAway, ev.detail.user.status.message),
|
|
new MamiUserPermsInfo(
|
|
ev.detail.user.perms.rank, ev.detail.user.perms.kick,
|
|
ev.detail.user.perms.nick, ev.detail.user.perms.chan,
|
|
)
|
|
);
|
|
Umi.Users.Add(userInfo);
|
|
|
|
if(ev.detail.msg !== undefined)
|
|
Umi.Messages.Add(new Umi.Message(
|
|
ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false,
|
|
{
|
|
isError: false,
|
|
type: leave.msg.botInfo.type,
|
|
args: [ userInfo.name ],
|
|
target: userInfo,
|
|
},
|
|
));
|
|
};
|
|
handlers['chan:leave'] = ev => {
|
|
if(dumpEvents) console.log('chan:leave', ev.detail);
|
|
|
|
if(ev.detail.user.self)
|
|
return;
|
|
|
|
const userInfo = Umi.Users.Get(ev.detail.user.id);
|
|
if(userInfo === null)
|
|
return;
|
|
|
|
if(ev.detail.msg !== undefined)
|
|
Umi.Messages.Add(new Umi.Message(
|
|
ev.detail.msg.id, null, undefined, '', ev.detail.msg.channel, false,
|
|
{
|
|
isError: false,
|
|
type: ev.detail.msg.botInfo.type,
|
|
args: [ userInfo.name ],
|
|
target: userInfo,
|
|
},
|
|
));
|
|
|
|
Umi.Users.Remove(userInfo);
|
|
};
|
|
|
|
|
|
handlers['msg:add'] = ev => {
|
|
if(dumpEvents) console.log('msg:add', ev.detail);
|
|
|
|
const senderInfo = ev.detail.msg.sender;
|
|
const userInfo = senderInfo.name === undefined
|
|
? Umi.Users.Get(senderInfo.id)
|
|
: new MamiUserInfo(
|
|
senderInfo.id,
|
|
senderInfo.name,
|
|
senderInfo.colour,
|
|
new MamiUserStatusInfo(senderInfo.status.isAway, senderInfo.status.message),
|
|
new MamiUserPermsInfo(
|
|
senderInfo.perms.rank, senderInfo.perms.kick,
|
|
senderInfo.perms.nick, senderInfo.perms.chan,
|
|
)
|
|
);
|
|
|
|
// hack
|
|
let channelName = ev.detail.msg.channel;
|
|
if(channelName !== undefined && channelName.startsWith('@~')) {
|
|
const chanUserInfo = Umi.Users.Get(channelName.substring(2));
|
|
if(chanUserInfo !== null)
|
|
channelName = `@${chanUserInfo.name}`;
|
|
}
|
|
|
|
// also hack
|
|
if(ev.detail.msg.flags.isPM) {
|
|
if(Umi.Channels.Get(channelName) === null)
|
|
Umi.Channels.Add(new MamiChannelInfo(channelName, false, true, true));
|
|
|
|
// this should be raised for other channels too, but that is not possible yet
|
|
Umi.UI.Menus.Attention('channels');
|
|
}
|
|
|
|
Umi.Messages.Add(new Umi.Message(
|
|
ev.detail.msg.id,
|
|
ev.detail.msg.time,
|
|
userInfo,
|
|
ev.detail.msg.text,
|
|
channelName,
|
|
false,
|
|
ev.detail.msg.botInfo,
|
|
ev.detail.msg.flags.isAction,
|
|
ev.detail.msg.silent,
|
|
));
|
|
};
|
|
handlers['msg:remove'] = ev => {
|
|
if(dumpEvents) console.log('msg:remove', ev.detail);
|
|
|
|
Umi.Messages.Remove(Umi.Messages.Get(ev.detail.msg.id));
|
|
};
|
|
handlers['msg:clear'] = () => {
|
|
if(dumpEvents) console.log('msg:clear');
|
|
|
|
Umi.UI.Messages.RemoveAll();
|
|
};
|
|
|
|
|
|
return {
|
|
setDumpEvents: state => {
|
|
dumpEvents = !!state;
|
|
},
|
|
register: () => {
|
|
for(const name in handlers)
|
|
client.watch(name, handlers[name]);
|
|
},
|
|
unregister: () => {
|
|
for(const name in handlers)
|
|
client.unwatch(name, handlers[name]);
|
|
},
|
|
};
|
|
};
|