message_list_data: Fix TypeScript noUncheckedIndexedAccess errors.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2024-05-30 10:07:59 -07:00
parent d8a7d65647
commit ad763ee7a7
1 changed files with 24 additions and 37 deletions

View File

@ -1,3 +1,5 @@
import assert from "minimalistic-assert";
import * as blueslip from "./blueslip"; import * as blueslip from "./blueslip";
import {FetchStatus} from "./fetch_status"; import {FetchStatus} from "./fetch_status";
import type {Filter} from "./filter"; import type {Filter} from "./filter";
@ -127,12 +129,7 @@ export class MessageListData {
if (i === undefined) { if (i === undefined) {
return undefined; return undefined;
} }
return this._items[i - 1]?.id;
if (i === 0) {
return undefined;
}
return this._items[i - 1].id;
} }
next(): number | undefined { next(): number | undefined {
@ -141,28 +138,14 @@ export class MessageListData {
if (i === undefined) { if (i === undefined) {
return undefined; return undefined;
} }
return this._items[i + 1]?.id;
if (i + 1 >= this._items.length) {
return undefined;
}
return this._items[i + 1].id;
} }
is_at_end(): boolean { is_at_end(): boolean {
if (this._selected_id === -1) { if (this._selected_id === -1) {
return false; return false;
} }
return this.last()?.id === this._selected_id;
const n = this._items.length;
if (n === 0) {
return false;
}
const last_msg = this._items[n - 1];
return last_msg.id === this._selected_id;
} }
clear(): void { clear(): void {
@ -444,49 +427,53 @@ export class MessageListData {
let closest = this._lower_bound(id); let closest = this._lower_bound(id);
if (closest < items.length && id === items[closest].id) { if (id === items[closest]?.id) {
return items[closest].id; return id;
} }
const potential_closest_matches = []; const potential_closest_matches = [];
if (closest > 0 && this._is_localonly_id(items[closest - 1].id)) { let prev_item;
while (
(prev_item = items[closest - 1]) !== undefined &&
this._is_localonly_id(prev_item.id)
) {
// Since we treated all blocks of local ids as their left-most-non-local message // Since we treated all blocks of local ids as their left-most-non-local message
// for lower_bound purposes, find the real leftmost index (first non-local id) // for lower_bound purposes, find the real leftmost index (first non-local id)
do {
potential_closest_matches.push(closest); potential_closest_matches.push(closest);
closest -= 1; closest -= 1;
} while (closest > 0 && this._is_localonly_id(items[closest - 1].id));
} }
potential_closest_matches.push(closest); potential_closest_matches.push(closest);
if (closest === items.length) { let item = items[closest];
closest = closest - 1; if (item === undefined) {
item = items[closest - 1];
} else { } else {
// Any of the ids that we skipped over (due to them being local-only) might be the // Any of the ids that we skipped over (due to them being local-only) might be the
// closest ID to the desired one, in case there is no exact match. // closest ID to the desired one, in case there is no exact match.
potential_closest_matches.unshift(closest - 1); potential_closest_matches.unshift(closest - 1);
let best_match = items[closest].id; let best_match = item.id;
for (const potential_idx of potential_closest_matches) { for (const potential_idx of potential_closest_matches) {
if (potential_idx < 0) { if (potential_idx < 0) {
continue; continue;
} }
const item = items[potential_idx]; const potential_item = items[potential_idx];
if (item === undefined) { if (potential_item === undefined) {
blueslip.warn("Invalid potential_idx: " + potential_idx); blueslip.warn("Invalid potential_idx: " + potential_idx);
continue; continue;
} }
const potential_match = item.id; const potential_match = potential_item.id;
// If the potential id is the closest to the requested, save that one // If the potential id is the closest to the requested, save that one
if (Math.abs(id - potential_match) < Math.abs(best_match - id)) { if (Math.abs(id - potential_match) < Math.abs(best_match - id)) {
best_match = potential_match; best_match = potential_match;
closest = potential_idx; item = potential_item;
} }
} }
} }
return items[closest].id; assert(item !== undefined);
return item.id;
} }
advance_past_messages(msg_ids: number[]): void { advance_past_messages(msg_ids: number[]): void {