message updates no longer crashing
This commit is contained in:
parent
84c05330ba
commit
6e38c4202a
@ -20,9 +20,11 @@ electronMain.initialize();
|
||||
|
||||
(async () => {
|
||||
await electron.app.whenReady();
|
||||
|
||||
LOG.silly('electron app is ready');
|
||||
|
||||
await LOG.ensureSourceMaps();
|
||||
LOG.silly('base log source maps loaded');
|
||||
|
||||
const window = new electron.BrowserWindow({
|
||||
width: 1580,//1080,
|
||||
height: 720,
|
||||
|
@ -70,10 +70,8 @@ export default class Actions {
|
||||
async fetchAndUpdateMessagesRecent(q: Q, server: ClientController, channel: Channel | { id: string }) {
|
||||
await Util.withPotentialErrorWarnOnCancel(q, {
|
||||
taskFunc: async () => {
|
||||
LOG.debug('active server is s#' + this.ui.activeServer?.id);
|
||||
LOG.debug('active channel is ch#' + this.ui.activeChannel?.id);
|
||||
if (this.ui.activeServer === null || this.ui.activeServer.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== channel.id) return;
|
||||
let messages = await server.grabRecentMessages(channel.id, Globals.MESSAGES_PER_REQUEST);
|
||||
await this.ui.setMessages(server, channel, messages, { atTop: messages.length < Globals.MESSAGES_PER_REQUEST, atBottom: true });
|
||||
},
|
||||
@ -89,7 +87,7 @@ export default class Actions {
|
||||
await Util.withPotentialErrorWarnOnCancel(q, {
|
||||
taskFunc: async () => {
|
||||
if (this.ui.activeServer === null || this.ui.activeServer.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== channel.id) return;
|
||||
let topPair = this.ui.getTopMessagePair();
|
||||
if (topPair == null) return;
|
||||
let messages = await server.fetchMessagesBefore(channel.id, topPair.message.id, Globals.MESSAGES_PER_REQUEST);
|
||||
@ -112,7 +110,7 @@ export default class Actions {
|
||||
await Util.withPotentialErrorWarnOnCancel(q, {
|
||||
taskFunc: async () => {
|
||||
if (this.ui.activeServer === null || this.ui.activeServer.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== server.id) return;
|
||||
if (this.ui.activeChannel === null || this.ui.activeChannel.id !== channel.id) return;
|
||||
let bottomPair = this.ui.getBottomMessagePair();
|
||||
if (bottomPair == null) return;
|
||||
let messages = await server.fetchMessagesAfter(channel.id, bottomPair.message.id, Globals.MESSAGES_PER_REQUEST);
|
||||
|
@ -14,6 +14,7 @@ import { Message, Member, Channel, Changes, ConnectionInfo, CacheServerData, Ser
|
||||
import DBCache from './db-cache';
|
||||
import ResourceRAMCache from './resource-ram-cache';
|
||||
import RecentMessageRAMCache from './message-ram-cache';
|
||||
import { channel } from 'diagnostics_channel';
|
||||
|
||||
// Events:
|
||||
// 'connected' function() called when connected to the server
|
||||
@ -23,11 +24,11 @@ import RecentMessageRAMCache from './message-ram-cache';
|
||||
// 'update-server' function(serverData) called when the server metadata updates
|
||||
|
||||
// 'deleted-members' function(members) called when members were deleted on the server-side
|
||||
// 'updated-members' function(data: Array [ { oldDataPoint, newDataPoint } ]) called when a member was updated on the server-side
|
||||
// 'updated-members' function(data: Array [ { oldMember, newMember } ]) called when a member was updated on the server-side
|
||||
// 'added-members' function(members) called when members were added on the server-side
|
||||
|
||||
// 'deleted-channels' function(channels) called when channels were deleted on the server-side
|
||||
// 'updated-channels' function(data: Array [ { oldDataPoint, newDataPoint } ]) called when a channel was updated on the server-side
|
||||
// 'updated-channels' function(data: Array [ { oldChannel, newChannel } ]) called when a channel was updated on the server-side
|
||||
// 'added-channels' function(channels) called when channels are added on the server-side
|
||||
|
||||
// 'new-message' function(message) called when a message is received in a channel
|
||||
@ -54,7 +55,7 @@ import RecentMessageRAMCache from './message-ram-cache';
|
||||
|
||||
// async setStatus(status) Set the current logged in user's status
|
||||
// async setDisplayName(displayName) Sets the current logged in user's display name
|
||||
// async setAvatar(avatarBu{ updated: { oldDataPoint: T, newDataPoint: T }[], added: T[], removed: T[] }
|
||||
// async setAvatar(avatarBuff)
|
||||
// async updateChannel(channelId, name, flavorText) Updates a channel's name and flavor text
|
||||
|
||||
// async queryTokens() Queries for the login tokens as [ { token, member_id, created, expires }, ... ]
|
||||
@ -162,7 +163,7 @@ export default class ClientController extends EventEmitter {
|
||||
await this.ensureMembers();
|
||||
let oldMember = this.members.get(member.id);
|
||||
if (oldMember) {
|
||||
this.emit('updated-members', [ { oldDataPoint: oldMember, newDataPoint: member } ]);
|
||||
this.emit('updated-members', [ { oldMember: oldMember, newMember: member } ]);
|
||||
} else {
|
||||
this.emit('added-members', [ member ]);
|
||||
}
|
||||
@ -171,7 +172,7 @@ export default class ClientController extends EventEmitter {
|
||||
await this.ensureChannels();
|
||||
let oldChannel = this.channels.get(channel.id);
|
||||
if (oldChannel) {
|
||||
this.emit('updated-channels', [ { oldDataPoint: oldChannel, newDataPoint: channel } ]);
|
||||
this.emit('updated-channels', [ { oldChannel: oldChannel, newChannel: channel } ]);
|
||||
} else {
|
||||
this.emit('added-channels', [ channel ]);
|
||||
}
|
||||
@ -193,9 +194,9 @@ export default class ClientController extends EventEmitter {
|
||||
}
|
||||
await DBCache.updateServerMembers(this.id, Array.from(this.members.values()));
|
||||
});
|
||||
this.on('updated-members', async (data: { oldDataPoint: Member, newDataPoint: Member }[]) => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
this.members.set(newDataPoint.id, newDataPoint);
|
||||
this.on('updated-members', async (data: { oldMember: Member, newMember: Member }[]) => {
|
||||
for (const { oldMember, newMember } of data) {
|
||||
this.members.set(newMember.id, newMember);
|
||||
}
|
||||
await DBCache.updateServerMembers(this.id, Array.from(this.members.values()));
|
||||
});
|
||||
@ -212,9 +213,9 @@ export default class ClientController extends EventEmitter {
|
||||
}
|
||||
await DBCache.updateServerChannels(this.id, Array.from(this.channels.values()));
|
||||
});
|
||||
this.on('updated-channels', async (data: { oldDataPoint: Channel, newDataPoint: Channel }[]) => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
this.channels.set(newDataPoint.id, newDataPoint);
|
||||
this.on('updated-channels', async (data: { oldChannel: Channel, newChannel: Channel }[]) => {
|
||||
for (const { oldChannel, newChannel } of data) {
|
||||
this.channels.set(newChannel.id, newChannel);
|
||||
}
|
||||
await DBCache.updateServerChannels(this.id, Array.from(this.channels.values()));
|
||||
});
|
||||
@ -236,13 +237,12 @@ export default class ClientController extends EventEmitter {
|
||||
// Alternatively, just store the date in the message and use order-by
|
||||
this._recentMessages.dropChannel(this.id, channel.id);
|
||||
});
|
||||
this.on('updated-messages', async (data: { oldDataPoint: Message, newDataPoint: Message }[]) => {
|
||||
LOG.debug('updated-messages: ', data);
|
||||
for (let { oldDataPoint, newDataPoint } of data) {
|
||||
this._recentMessages.updateMessage(this.id, oldDataPoint, newDataPoint);
|
||||
this.on('updated-messages', async (channel: Channel, data: { oldMessage: Message, newMessage: Message }[]) => {
|
||||
for (let { oldMessage, newMessage } of data) {
|
||||
this._recentMessages.updateMessage(this.id, oldMessage, newMessage);
|
||||
}
|
||||
});
|
||||
this.on('deleted-messages', async (messages: Message[]) => {
|
||||
this.on('deleted-messages', async (_channel: Channel, messages: Message[]) => {
|
||||
for (let message of messages) {
|
||||
this._recentMessages.deleteMessage(this.id, message);
|
||||
}
|
||||
@ -515,7 +515,7 @@ export default class ClientController extends EventEmitter {
|
||||
|
||||
async grabRecentMessages(channelId: string, number: number): Promise<Message[]> {
|
||||
let cached = this._recentMessages.getRecentMessages(this.id, channelId, number);
|
||||
if (cached != null) return cached;
|
||||
if (cached !== null) return cached;
|
||||
return await this.fetchMessagesRecent(channelId, number);
|
||||
}
|
||||
|
||||
@ -621,7 +621,7 @@ export default class ClientController extends EventEmitter {
|
||||
this.emit('added-members', changes.added);
|
||||
}
|
||||
if (changes.updated.length > 0) {
|
||||
this.emit('updated-members', changes.updated);
|
||||
this.emit('updated-members', changes.updated.map(change => ({ oldMember: change.oldDataPoint, newMember: change.newDataPoint })));
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -662,7 +662,7 @@ export default class ClientController extends EventEmitter {
|
||||
this.emit('added-channels', changes.added);
|
||||
}
|
||||
if (changes.updated.length > 0) {
|
||||
this.emit('updated-channels', changes.updated);
|
||||
this.emit('updated-channels', changes.updated.map(change => ({ oldChannel: change.oldDataPoint, newChannel: change.newDataPoint })));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -38,6 +38,9 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
document.body.classList.remove('preload');
|
||||
|
||||
(async () => {
|
||||
await LOG.ensureSourceMaps();
|
||||
LOG.silly('web client log source maps loaded');
|
||||
|
||||
await DBCache.connect();
|
||||
await DBCache.init();
|
||||
|
||||
@ -149,12 +152,12 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
await ui.deleteMembers(server, members);
|
||||
});
|
||||
|
||||
controller.on('updated-members', async (server: ClientController, data: { oldDataPoint: Member, newDataPoint: Member }[]) => {
|
||||
controller.on('updated-members', async (server: ClientController, data: { oldMember: Member, newMember: Member }[]) => {
|
||||
LOG.debug(data.length + ' updated members s#' + server.id);
|
||||
await ui.updateMembers(server, data);
|
||||
if (
|
||||
ui.activeConnection !== null &&
|
||||
data.find((c: any) => c.newDataPoint.id === (ui.activeConnection as ConnectionInfo).id)
|
||||
data.find(change => change.newMember.id === (ui.activeConnection as ConnectionInfo).id)
|
||||
) {
|
||||
await actions.fetchAndUpdateConnection(server);
|
||||
}
|
||||
@ -170,7 +173,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
await ui.deleteChannels(server, channels);
|
||||
});
|
||||
|
||||
controller.on('updated-channels', async (server: ClientController, data: { oldDataPoint: Channel, newDataPoint: Channel }[]) => {
|
||||
controller.on('updated-channels', async (server: ClientController, data: { oldChannel: Channel, newChannel: Channel }[]) => {
|
||||
LOG.debug(data.length + ' updated channels');
|
||||
await ui.updateChannels(actions, server, data);
|
||||
});
|
||||
@ -187,7 +190,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
await ui.deleteMessages(server, channel, messages);
|
||||
});
|
||||
|
||||
controller.on('updated-messages', async (server: ClientController, channel: Channel, data: { oldDataPoint: Message, newDataPoint: Message }[]) => {
|
||||
controller.on('updated-messages', async (server: ClientController, channel: Channel, data: { oldMessage: Message, newMessage: Message }[]) => {
|
||||
LOG.debug(data.length + ' updated messages');
|
||||
// messages were updated on the server-side
|
||||
await ui.updateMessages(server, channel, data);
|
||||
@ -218,12 +221,12 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||
// messages that were updated (currently extraneous)
|
||||
// Note: this should never happen since these should be handled by updated-messages
|
||||
// Note: this may be used to replace dummy pre-sent messages
|
||||
let toUpdate: { newDataPoint: Message, oldDataPoint: Message }[] = [];
|
||||
let toUpdate: { newMessage: Message, oldMessage: Message }[] = [];
|
||||
for (let addedMessage of addedBefore.values()) {
|
||||
if (ui.messagePairs.has(addedMessage.id)) {
|
||||
toUpdate.push({
|
||||
newDataPoint: addedMessage,
|
||||
oldDataPoint: (ui.messagePairs.get(addedMessage.id) as { message: Message, element: HTMLElement }).message
|
||||
newMessage: addedMessage,
|
||||
oldMessage: (ui.messagePairs.get(addedMessage.id) as { message: Message, element: HTMLElement }).message
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -263,10 +263,9 @@ export default class UI {
|
||||
});
|
||||
}
|
||||
|
||||
public async updateChannels(actions: Actions, server: ClientController, data: { oldDataPoint: Channel, newDataPoint: Channel }[]): Promise<void> {
|
||||
public async updateChannels(actions: Actions, server: ClientController, data: { oldChannel: Channel, newChannel: Channel }[]): Promise<void> {
|
||||
await this.lockChannels(server, () => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
let newChannel = newDataPoint;
|
||||
for (const { oldChannel, newChannel } of data) {
|
||||
let oldElement = this.q.$('#channel-list .channel[meta-id="' + newChannel.id + '"]');
|
||||
let newElement = createChannel(this.document, this.q, this, actions, server, newChannel);
|
||||
oldElement.parentElement?.replaceChild(newElement, oldElement);
|
||||
@ -359,10 +358,9 @@ export default class UI {
|
||||
});
|
||||
}
|
||||
|
||||
public async updateMembers(server: ClientController, data: { oldDataPoint: Member, newDataPoint: Member }[]): Promise<void> {
|
||||
public async updateMembers(server: ClientController, data: { oldMember: Member, newMember: Member }[]): Promise<void> {
|
||||
await this.lockMembers(server, () => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
let newMember = newDataPoint;
|
||||
for (const { oldMember, newMember } of data) {
|
||||
let oldElement = this.q.$_('#server-members .member[meta-id="' + newMember.id + '"]');
|
||||
if (oldElement) {
|
||||
let newElement = createMember(this.q, server, newMember);
|
||||
@ -373,8 +371,7 @@ export default class UI {
|
||||
});
|
||||
if (this.activeChannel === null) return;
|
||||
await this.lockMessages(server, this.activeChannel, () => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
let newMember = newDataPoint;
|
||||
for (const { oldMember, newMember } of data) {
|
||||
let newStyle = newMember.roleColor ? 'color: ' + newMember.roleColor : null;
|
||||
let newName = newMember.displayName;
|
||||
// the extra query selectors may be overkill
|
||||
@ -635,11 +632,9 @@ export default class UI {
|
||||
});
|
||||
}
|
||||
|
||||
public async updateMessages(server: ClientController, channel: Channel, data: { oldDataPoint: Message, newDataPoint: Message }[]): Promise<void> {
|
||||
public async updateMessages(server: ClientController, channel: Channel, data: { oldMessage: Message, newMessage: Message }[]): Promise<void> {
|
||||
await this.lockMessages(server, channel, () => {
|
||||
for (const { oldDataPoint, newDataPoint } of data) {
|
||||
let oldMessage = oldDataPoint;
|
||||
let newMessage = newDataPoint;
|
||||
for (const { oldMessage, newMessage } of data) {
|
||||
if (this.messagePairs.has(oldMessage.id)) {
|
||||
let oldElement = (this.messagePairs.get(oldMessage.id) as { message: Message, element: HTMLElement }).element;
|
||||
let prevElement = Q.previousElement(oldElement);
|
||||
|
@ -146,6 +146,8 @@ export default class Logger {
|
||||
private name: string;
|
||||
private console: Console;
|
||||
private sourceMaps = new Map<string, SourceMapConsumer>();
|
||||
private hasSourceMaps = false;
|
||||
private sourceMapsWaiters: (() => void)[] = [];
|
||||
|
||||
private constructor(name: string, processConsole?: Console) {
|
||||
this.name = name;
|
||||
@ -158,10 +160,25 @@ export default class Logger {
|
||||
(async () => {
|
||||
let sourceMaps = await getStaticSourceMaps();
|
||||
log.sourceMaps = sourceMaps;
|
||||
log.onGetSourceMaps();
|
||||
})();
|
||||
return log;
|
||||
}
|
||||
|
||||
private onGetSourceMaps() {
|
||||
this.hasSourceMaps = true;
|
||||
for (let sourceMapWaiter of this.sourceMapsWaiters) {
|
||||
sourceMapWaiter();
|
||||
}
|
||||
}
|
||||
|
||||
public async ensureSourceMaps(): Promise<void> {
|
||||
if (this.hasSourceMaps) return;
|
||||
return new Promise((resolve) => {
|
||||
this.sourceMapsWaiters.push(resolve);
|
||||
});
|
||||
}
|
||||
|
||||
/** Logs a message and potentially corresponding data */
|
||||
private log(level: LoggerLevel, message: string | null, data?: Error | any): void {
|
||||
let frames: StackTrace.Frame[] = StackTrace.parse(new Error());
|
||||
|
5
todo.txt
5
todo.txt
@ -1,3 +1,6 @@
|
||||
Moved to https://cowfield.atlassian.net
|
||||
|
||||
|
||||
------ Minimum Viable Product ------
|
||||
|
||||
Clean up TypeScript type names
|
||||
@ -6,6 +9,8 @@ Clean up HTML / CSS
|
||||
|
||||
Get rid of all static classes that store state
|
||||
|
||||
There's a bug with 'undefined' when
|
||||
|
||||
Unit tests would be pretty nice for the cache stuff
|
||||
|
||||
Get rid of the duplicate fetch metadata query at startup (fetch-server)
|
||||
|
Loading…
Reference in New Issue
Block a user