mirror of
https://codeberg.org/emersion/gamja.git
synced 2024-11-14 19:05:01 -05:00
Introduce per-server user map
This allows us to store information about users in a signle place, instead of putting it in user buffers. This is required to display metadata about users in the channel members list.
This commit is contained in:
parent
e7f8620933
commit
c66ce61029
3 changed files with 49 additions and 40 deletions
|
@ -1234,11 +1234,17 @@ export default class App extends Component {
|
||||||
|
|
||||||
let bufferHeader = null;
|
let bufferHeader = null;
|
||||||
if (activeBuffer) {
|
if (activeBuffer) {
|
||||||
|
let activeUser = null;
|
||||||
|
if (activeBuffer.type == BufferType.NICK) {
|
||||||
|
activeUser = activeServer.users.get(activeBuffer.name);
|
||||||
|
}
|
||||||
|
|
||||||
bufferHeader = html`
|
bufferHeader = html`
|
||||||
<section id="buffer-header">
|
<section id="buffer-header">
|
||||||
<${BufferHeader}
|
<${BufferHeader}
|
||||||
buffer=${activeBuffer}
|
buffer=${activeBuffer}
|
||||||
server=${activeServer}
|
server=${activeServer}
|
||||||
|
user=${activeUser}
|
||||||
isBouncer=${isBouncer}
|
isBouncer=${isBouncer}
|
||||||
bouncerNetwork=${activeBouncerNetwork}
|
bouncerNetwork=${activeBouncerNetwork}
|
||||||
onChannelClick=${this.handleChannelClick}
|
onChannelClick=${this.handleChannelClick}
|
||||||
|
|
|
@ -125,23 +125,25 @@ export default function BufferHeader(props) {
|
||||||
`;
|
`;
|
||||||
break;
|
break;
|
||||||
case BufferType.NICK:
|
case BufferType.NICK:
|
||||||
if (props.buffer.who) {
|
if (props.user) {
|
||||||
let who = props.buffer.who;
|
|
||||||
|
|
||||||
let realname = stripANSI(who.realname || "");
|
|
||||||
|
|
||||||
let status = UserStatus.HERE;
|
let status = UserStatus.HERE;
|
||||||
if (who.away) {
|
if (props.user.offline) {
|
||||||
|
status = UserStatus.OFFLINE;
|
||||||
|
} else if (props.user.away) {
|
||||||
status = UserStatus.GONE;
|
status = UserStatus.GONE;
|
||||||
}
|
}
|
||||||
if (props.buffer.offline) {
|
|
||||||
status = UserStatus.OFFLINE;
|
let realname = props.buffer.name;
|
||||||
|
if (props.user.realname) {
|
||||||
|
realname = stripANSI(props.user.realname || "");
|
||||||
}
|
}
|
||||||
|
|
||||||
description = html`<${NickStatus} status=${status}/> ${realname} (${who.username}@${who.hostname})`;
|
let mask = null;
|
||||||
} else if (props.buffer.offline) {
|
if (props.user.username && props.user.hostname) {
|
||||||
// User is offline, but we don't have WHO information
|
mask = `(${props.user.username}@${props.user.hostname})`;
|
||||||
description = html`<${NickStatus} status=${UserStatus.OFFLINE}/> ${props.buffer.name}`;
|
}
|
||||||
|
|
||||||
|
description = html`<${NickStatus} status=${status}/> ${realname} ${mask}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
actions = html`
|
actions = html`
|
||||||
|
|
57
state.js
57
state.js
|
@ -248,6 +248,7 @@ export const State = {
|
||||||
id,
|
id,
|
||||||
status: ServerStatus.DISCONNECTED,
|
status: ServerStatus.DISCONNECTED,
|
||||||
isupport: new Map(),
|
isupport: new Map(),
|
||||||
|
users: new irc.CaseMapMap(null, irc.CaseMapping.RFC1459),
|
||||||
});
|
});
|
||||||
return [id, { servers }];
|
return [id, { servers }];
|
||||||
},
|
},
|
||||||
|
@ -278,8 +279,6 @@ export const State = {
|
||||||
serverInfo: null, // if server
|
serverInfo: null, // if server
|
||||||
topic: null, // if channel
|
topic: null, // if channel
|
||||||
members: new irc.CaseMapMap(null, client.cm), // if channel
|
members: new irc.CaseMapMap(null, client.cm), // if channel
|
||||||
who: null, // if nick
|
|
||||||
offline: false, // if nick
|
|
||||||
messages: [],
|
messages: [],
|
||||||
unread: Unread.NONE,
|
unread: Unread.NONE,
|
||||||
prevReadReceipt: null,
|
prevReadReceipt: null,
|
||||||
|
@ -295,6 +294,17 @@ export const State = {
|
||||||
function updateBuffer(name, updater) {
|
function updateBuffer(name, updater) {
|
||||||
return State.updateBuffer(state, { server: serverID, name }, updater);
|
return State.updateBuffer(state, { server: serverID, name }, updater);
|
||||||
}
|
}
|
||||||
|
function updateUser(name, updater) {
|
||||||
|
return updateServer((server) => {
|
||||||
|
let users = new irc.CaseMapMap(server.users);
|
||||||
|
let updated = updateState(users.get(name), updater);
|
||||||
|
if (!updated) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
users.set(name, updated);
|
||||||
|
return { users };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Don't update our internal state if it's a chat history message
|
// Don't update our internal state if it's a chat history message
|
||||||
if (irc.findBatchByType(msg, "chathistory")) {
|
if (irc.findBatchByType(msg, "chathistory")) {
|
||||||
|
@ -321,7 +331,12 @@ export const State = {
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
buffers,
|
buffers,
|
||||||
...updateServer({ isupport: new Map(client.isupport) }),
|
...updateServer((server) => {
|
||||||
|
return {
|
||||||
|
isupport: new Map(client.isupport),
|
||||||
|
users: new irc.CaseMapMap(server.users, client.cm),
|
||||||
|
};
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
case irc.RPL_NOTOPIC:
|
case irc.RPL_NOTOPIC:
|
||||||
channel = msg.params[1];
|
channel = msg.params[1];
|
||||||
|
@ -356,16 +371,17 @@ export const State = {
|
||||||
nick: msg.params[5],
|
nick: msg.params[5],
|
||||||
away: msg.params[6] == 'G', // H for here, G for gone
|
away: msg.params[6] == 'G', // H for here, G for gone
|
||||||
realname: last.slice(last.indexOf(" ") + 1),
|
realname: last.slice(last.indexOf(" ") + 1),
|
||||||
|
offline: false,
|
||||||
};
|
};
|
||||||
return updateBuffer(who.nick, { who, offline: false });
|
return updateUser(who.nick, who);
|
||||||
case irc.RPL_ENDOFWHO:
|
case irc.RPL_ENDOFWHO:
|
||||||
target = msg.params[1];
|
target = msg.params[1];
|
||||||
if (!client.isChannel(target) && target.indexOf("*") < 0) {
|
if (!client.isChannel(target) && target.indexOf("*") < 0) {
|
||||||
// Not a channel nor a mask, likely a nick
|
// Not a channel nor a mask, likely a nick
|
||||||
return updateBuffer(target, (buf) => {
|
return updateUser(target, (user) => {
|
||||||
// TODO: mark user offline if we have old WHO info but this
|
// TODO: mark user offline if we have old WHO info but this
|
||||||
// WHO reply is empty
|
// WHO reply is empty
|
||||||
if (buf.who) {
|
if (user) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return { offline: true };
|
return { offline: true };
|
||||||
|
@ -404,26 +420,15 @@ export const State = {
|
||||||
return { members };
|
return { members };
|
||||||
});
|
});
|
||||||
case "SETNAME":
|
case "SETNAME":
|
||||||
return updateBuffer(msg.prefix.name, (buf) => {
|
return updateUser(msg.prefix.name, { realname: msg.params[0] });
|
||||||
let who = { ...buf.who, realname: msg.params[0] };
|
|
||||||
return { who };
|
|
||||||
});
|
|
||||||
case "CHGHOST":
|
case "CHGHOST":
|
||||||
return updateBuffer(msg.prefix.name, (buf) => {
|
return updateUser(msg.prefix.name, {
|
||||||
let who = {
|
username: msg.params[0],
|
||||||
...buf.who,
|
hostname: msg.params[1],
|
||||||
username: msg.params[0],
|
|
||||||
hostname: msg.params[1],
|
|
||||||
};
|
|
||||||
return { who };
|
|
||||||
});
|
});
|
||||||
case "AWAY":
|
case "AWAY":
|
||||||
let awayMessage = msg.params[0];
|
let awayMessage = msg.params[0];
|
||||||
|
return updateUser(msg.prefix.name, { away: !!awayMessage });
|
||||||
return updateBuffer(msg.prefix.name, (buf) => {
|
|
||||||
let who = { ...buf.who, away: !!awayMessage };
|
|
||||||
return { who };
|
|
||||||
});
|
|
||||||
case "TOPIC":
|
case "TOPIC":
|
||||||
channel = msg.params[0];
|
channel = msg.params[0];
|
||||||
topic = msg.params[1];
|
topic = msg.params[1];
|
||||||
|
@ -459,9 +464,7 @@ export const State = {
|
||||||
|
|
||||||
for (let target of targets) {
|
for (let target of targets) {
|
||||||
let prefix = irc.parsePrefix(target);
|
let prefix = irc.parsePrefix(target);
|
||||||
let update = updateBuffer(prefix.name, (buf) => {
|
let update = updateUser(prefix.name, { offline: false });
|
||||||
return { offline: false };
|
|
||||||
});
|
|
||||||
state = { ...state, ...update };
|
state = { ...state, ...update };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,9 +474,7 @@ export const State = {
|
||||||
|
|
||||||
for (let target of targets) {
|
for (let target of targets) {
|
||||||
let prefix = irc.parsePrefix(target);
|
let prefix = irc.parsePrefix(target);
|
||||||
let update = updateBuffer(prefix.name, (buf) => {
|
let update = updateUser(prefix.name, { offline: true });
|
||||||
return { offline: true };
|
|
||||||
});
|
|
||||||
state = { ...state, ...update };
|
state = { ...state, ...update };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue