swarm-ui: key message rows on an arrival id and follow the tail on it
At the 2000-message cap the count stops changing, so the page stopped following the newest message, and every row's index key shifted on each arrival, remounting all of them. Each message now gets an id when it arrives; the rows key on it and the scroll follows the newest id. Rows are memoised on the message, and the events of one frame join the list in a single update.
This commit is contained in:
parent
447498fef7
commit
bdeec3f744
1 changed files with 114 additions and 19 deletions
|
|
@ -13,6 +13,23 @@ export interface SwarmMessage {
|
|||
body_format?: "markdown" | "diff";
|
||||
}
|
||||
|
||||
/**
|
||||
* A message with the id the page gave it when it arrived. The id only grows,
|
||||
* so it names a row for as long as the message is on the page, however many
|
||||
* older ones drop off the front.
|
||||
*/
|
||||
export interface ArrivedMessage extends SwarmMessage {
|
||||
id: number;
|
||||
}
|
||||
|
||||
/** `batch` numbered from `firstId` on, in order. */
|
||||
export function numbered(
|
||||
batch: SwarmMessage[],
|
||||
firstId: number,
|
||||
): ArrivedMessage[] {
|
||||
return batch.map((m, i) => ({ ...m, id: firstId + i }));
|
||||
}
|
||||
|
||||
/** The history windows the page offers, in minutes; 0 is live only. */
|
||||
export const WINDOWS: { minutes: number; label: string }[] = [
|
||||
{ minutes: 0, label: "live only" },
|
||||
|
|
@ -33,10 +50,10 @@ export function messagesUrl(sinceMinutes: number): string {
|
|||
* The messages that name `query` in their sender or recipient, as a
|
||||
* case-insensitive substring; all of them when `query` is blank.
|
||||
*/
|
||||
export function filterMessages(
|
||||
messages: SwarmMessage[],
|
||||
export function filterMessages<T extends SwarmMessage>(
|
||||
messages: T[],
|
||||
query: string,
|
||||
): SwarmMessage[] {
|
||||
): T[] {
|
||||
const q = query.trim().toLowerCase();
|
||||
if (q === "") return messages;
|
||||
return messages.filter(
|
||||
|
|
@ -45,7 +62,10 @@ export function filterMessages(
|
|||
}
|
||||
|
||||
/** At most `max` messages, the newest ones, when there are more. */
|
||||
export function newest(messages: SwarmMessage[], max: number): SwarmMessage[] {
|
||||
export function newest<T extends SwarmMessage>(
|
||||
messages: T[],
|
||||
max: number,
|
||||
): T[] {
|
||||
return messages.length > max
|
||||
? messages.slice(messages.length - max)
|
||||
: messages;
|
||||
|
|
|
|||
Loading…
Reference in a new issue