From 72404d7216c5c3859518fa283fc312f45cd5fc1a Mon Sep 17 00:00:00 2001 From: Kerry Date: Tue, 14 Mar 2023 10:55:50 +1300 Subject: [PATCH] Apply `strictNullChecks` to `src/utils/beacon/*` (#10337) * strictnullchecks fixes in utils/beacon * user filterBoolean --- src/utils/beacon/bounds.ts | 9 ++++++--- src/utils/beacon/duration.ts | 11 +++++++---- src/utils/beacon/geolocation.ts | 2 +- src/utils/beacon/useLiveBeacons.ts | 9 +++++++-- test/utils/beacon/duration-test.ts | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/utils/beacon/bounds.ts b/src/utils/beacon/bounds.ts index ad1b515fb4..829f16d3ca 100644 --- a/src/utils/beacon/bounds.ts +++ b/src/utils/beacon/bounds.ts @@ -16,6 +16,7 @@ limitations under the License. import { Beacon } from "matrix-js-sdk/src/matrix"; +import { filterBoolean } from "../arrays"; import { parseGeoUri } from "../location"; export type Bounds = { @@ -36,9 +37,11 @@ export type Bounds = { * west of Greenwich has a negative longitude, min -180 */ export const getBeaconBounds = (beacons: Beacon[]): Bounds | undefined => { - const coords = beacons - .filter((beacon) => !!beacon.latestLocationState) - .map((beacon) => parseGeoUri(beacon.latestLocationState.uri)); + const coords = filterBoolean( + beacons.map((beacon) => + !!beacon.latestLocationState?.uri ? parseGeoUri(beacon.latestLocationState.uri) : undefined, + ), + ); if (!coords.length) { return; diff --git a/src/utils/beacon/duration.ts b/src/utils/beacon/duration.ts index 136207b6f3..a0a3686101 100644 --- a/src/utils/beacon/duration.ts +++ b/src/utils/beacon/duration.ts @@ -28,21 +28,24 @@ export const msUntilExpiry = (startTimestamp: number, durationMs: number): numbe Math.max(0, startTimestamp + durationMs - Date.now()); export const getBeaconMsUntilExpiry = (beaconInfo: BeaconInfoState): number => - msUntilExpiry(beaconInfo.timestamp, beaconInfo.timeout); + msUntilExpiry(beaconInfo.timestamp || 0, beaconInfo.timeout); export const getBeaconExpiryTimestamp = (beacon: Beacon): number => - beacon.beaconInfo.timestamp + beacon.beaconInfo.timeout; + (beacon.beaconInfo.timestamp || 0) + beacon.beaconInfo.timeout; export const sortBeaconsByLatestExpiry = (left: Beacon, right: Beacon): number => getBeaconExpiryTimestamp(right) - getBeaconExpiryTimestamp(left); // aka sort by timestamp descending export const sortBeaconsByLatestCreation = (left: Beacon, right: Beacon): number => - right.beaconInfo.timestamp - left.beaconInfo.timestamp; + (right.beaconInfo.timestamp || 0) - (left.beaconInfo.timestamp || 0); // a beacon's starting timestamp can be in the future // (either from small deviations in system clock times, or on purpose from another client) // a beacon is only live between its start timestamp and expiry // detect when a beacon is waiting to become live export const isBeaconWaitingToStart = (beacon: Beacon): boolean => - !beacon.isLive && beacon.beaconInfo.timestamp > Date.now() && getBeaconExpiryTimestamp(beacon) > Date.now(); + !beacon.isLive && + !!beacon.beaconInfo.timestamp && + beacon.beaconInfo.timestamp > Date.now() && + getBeaconExpiryTimestamp(beacon) > Date.now(); diff --git a/src/utils/beacon/geolocation.ts b/src/utils/beacon/geolocation.ts index 1fa3367b6f..3a55bbe2dc 100644 --- a/src/utils/beacon/geolocation.ts +++ b/src/utils/beacon/geolocation.ts @@ -93,7 +93,7 @@ export const genericPositionFromGeolocation = (geoPosition: GeolocationPosition) timestamp: Date.now(), latitude, longitude, - altitude, + altitude: altitude ?? undefined, accuracy, }; }; diff --git a/src/utils/beacon/useLiveBeacons.ts b/src/utils/beacon/useLiveBeacons.ts index 556e6b3dea..2e78841290 100644 --- a/src/utils/beacon/useLiveBeacons.ts +++ b/src/utils/beacon/useLiveBeacons.ts @@ -26,8 +26,13 @@ import { useEventEmitterState } from "../../hooks/useEventEmitter"; export const useLiveBeacons = (roomId: Room["roomId"], matrixClient: MatrixClient): Beacon[] => { const room = matrixClient.getRoom(roomId); - const liveBeacons = useEventEmitterState(room?.currentState, RoomStateEvent.BeaconLiveness, () => - room?.currentState?.liveBeaconIds.map((beaconIdentifier) => room.currentState.beacons.get(beaconIdentifier)), + const liveBeacons = useEventEmitterState( + room?.currentState, + RoomStateEvent.BeaconLiveness, + () => + room?.currentState?.liveBeaconIds.map( + (beaconIdentifier) => room.currentState.beacons.get(beaconIdentifier)!, + ) || [], ); return liveBeacons; diff --git a/test/utils/beacon/duration-test.ts b/test/utils/beacon/duration-test.ts index ed71865f29..e4ac952086 100644 --- a/test/utils/beacon/duration-test.ts +++ b/test/utils/beacon/duration-test.ts @@ -14,6 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { M_TIMESTAMP } from "matrix-js-sdk/src/@types/location"; import { Beacon } from "matrix-js-sdk/src/matrix"; import { msUntilExpiry, sortBeaconsByLatestExpiry, sortBeaconsByLatestCreation } from "../../../src/utils/beacon"; @@ -68,9 +69,25 @@ describe("beacon utils", () => { makeBeaconInfoEvent(aliceId, roomId, { timeout: HOUR_MS + 1, timestamp: now - HOUR_MS }, "$3"), ); + const noTimestampEvent = makeBeaconInfoEvent( + aliceId, + roomId, + { timeout: HOUR_MS + 1, timestamp: undefined }, + "$3", + ); + // beacon info helper defaults to date when timestamp is falsy + // hard set it to undefined + // @ts-ignore + noTimestampEvent.event.content[M_TIMESTAMP.name] = undefined; + const beaconNoTimestamp = new Beacon(noTimestampEvent); + it("sorts beacons by descending expiry time", () => { expect([beacon2, beacon3, beacon1].sort(sortBeaconsByLatestExpiry)).toEqual([beacon1, beacon2, beacon3]); }); + + it("sorts beacons with timestamps before beacons without", () => { + expect([beaconNoTimestamp, beacon3].sort(sortBeaconsByLatestExpiry)).toEqual([beacon3, beaconNoTimestamp]); + }); }); describe("sortBeaconsByLatestCreation()", () => {