apply strictnullchecks to src/components/views/beacon/* (#10272)

pull/28788/head^2
Kerry 2023-03-02 22:58:05 +13:00 committed by GitHub
parent ffa047be68
commit de6a1a661c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 30 deletions

View File

@ -42,14 +42,14 @@ const BeaconListItem: React.FC<Props & HTMLProps<HTMLLIElement>> = ({ beacon, ..
const matrixClient = useContext(MatrixClientContext); const matrixClient = useContext(MatrixClientContext);
const room = matrixClient.getRoom(beacon.roomId); const room = matrixClient.getRoom(beacon.roomId);
if (!latestLocationState || !beacon.isLive) { if (!latestLocationState || !beacon.isLive || !room) {
return null; return null;
} }
const isSelfLocation = beacon.beaconInfo.assetType === LocationAssetType.Self; const isSelfLocation = beacon.beaconInfo?.assetType === LocationAssetType.Self;
const beaconMember = isSelfLocation ? room.getMember(beacon.beaconInfoOwner) : undefined; const beaconMember = isSelfLocation ? room.getMember(beacon.beaconInfoOwner) : null;
const humanizedUpdateTime = humanizeTime(latestLocationState.timestamp); const humanizedUpdateTime = (latestLocationState.timestamp && humanizeTime(latestLocationState.timestamp)) || "";
return ( return (
<li className="mx_BeaconListItem" {...rest}> <li className="mx_BeaconListItem" {...rest}>
@ -62,7 +62,7 @@ const BeaconListItem: React.FC<Props & HTMLProps<HTMLLIElement>> = ({ beacon, ..
<BeaconStatus <BeaconStatus
className="mx_BeaconListItem_status" className="mx_BeaconListItem_status"
beacon={beacon} beacon={beacon}
label={beaconMember?.name || beacon.beaconInfo.description || beacon.beaconInfoOwner} label={beaconMember?.name || beacon.beaconInfo?.description || beacon.beaconInfoOwner}
displayStatus={BeaconDisplayStatus.Active} displayStatus={BeaconDisplayStatus.Active}
> >
{/* eat events from interactive share buttons {/* eat events from interactive share buttons

View File

@ -27,11 +27,11 @@ interface Props {
beacon: Beacon; beacon: Beacon;
} }
const useBeaconName = (beacon: Beacon): string => { const useBeaconName = (beacon: Beacon): string | undefined => {
const matrixClient = useContext(MatrixClientContext); const matrixClient = useContext(MatrixClientContext);
if (beacon.beaconInfo.assetType !== LocationAssetType.Self) { if (beacon.beaconInfo?.assetType !== LocationAssetType.Self) {
return beacon.beaconInfo.description; return beacon.beaconInfo?.description;
} }
const room = matrixClient.getRoom(beacon.roomId); const room = matrixClient.getRoom(beacon.roomId);
const member = room?.getMember(beacon.beaconInfoOwner); const member = room?.getMember(beacon.beaconInfoOwner);

View File

@ -54,7 +54,7 @@ interface FocusedBeaconState {
beacon?: Beacon; beacon?: Beacon;
} }
const getBoundsCenter = (bounds: Bounds): string | undefined => { const getBoundsCenter = (bounds?: Bounds): string | undefined => {
if (!bounds) { if (!bounds) {
return; return;
} }
@ -70,10 +70,10 @@ const useMapPosition = (
{ beacon, ts }: FocusedBeaconState, { beacon, ts }: FocusedBeaconState,
): { ): {
bounds?: Bounds; bounds?: Bounds;
centerGeoUri: string; centerGeoUri?: string;
} => { } => {
const [bounds, setBounds] = useState<Bounds | undefined>(getBeaconBounds(liveBeacons)); const [bounds, setBounds] = useState<Bounds | undefined>(getBeaconBounds(liveBeacons));
const [centerGeoUri, setCenterGeoUri] = useState<string>( const [centerGeoUri, setCenterGeoUri] = useState<string | undefined>(
beacon?.latestLocationState?.uri || getBoundsCenter(bounds), beacon?.latestLocationState?.uri || getBoundsCenter(bounds),
); );

View File

@ -45,12 +45,12 @@ const DialogOwnBeaconStatus: React.FC<Props> = ({ roomId }) => {
const matrixClient = useContext(MatrixClientContext); const matrixClient = useContext(MatrixClientContext);
const room = matrixClient.getRoom(roomId); const room = matrixClient.getRoom(roomId);
if (!beacon?.isLive) { if (!beacon?.isLive || !room) {
return null; return null;
} }
const isSelfLocation = beacon.beaconInfo.assetType === LocationAssetType.Self; const isSelfLocation = beacon.beaconInfo?.assetType === LocationAssetType.Self;
const beaconMember = isSelfLocation ? room.getMember(beacon.beaconInfoOwner) : undefined; const beaconMember = isSelfLocation ? room.getMember(beacon.beaconInfoOwner) : null;
return ( return (
<div className="mx_DialogOwnBeaconStatus"> <div className="mx_DialogOwnBeaconStatus">

View File

@ -25,7 +25,7 @@ import { Icon as LiveLocationIcon } from "../../../../res/img/location/live-loca
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import dispatcher from "../../../dispatcher/dispatcher"; import dispatcher from "../../../dispatcher/dispatcher";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
interface Props { interface Props {
isMinimized?: boolean; isMinimized?: boolean;
@ -121,7 +121,7 @@ const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
); );
const onWarningClick = relevantBeacon const onWarningClick = relevantBeacon
? () => { ? (_e: ButtonEvent) => {
dispatcher.dispatch<ViewRoomPayload>({ dispatcher.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: relevantBeacon.roomId, room_id: relevantBeacon.roomId,
@ -131,7 +131,7 @@ const LeftPanelLiveShareWarning: React.FC<Props> = ({ isMinimized }) => {
highlighted: true, highlighted: true,
}); });
} }
: undefined; : null;
const label = getLabel(hasStoppingErrors, hasLocationPublishErrors); const label = getLabel(hasStoppingErrors, hasLocationPublishErrors);

View File

@ -40,13 +40,19 @@ const getUpdateInterval = (ms: number): number => {
const useMsRemaining = (beacon: Beacon): number => { const useMsRemaining = (beacon: Beacon): number => {
const beaconInfo = useEventEmitterState(beacon, BeaconEvent.Update, () => beacon.beaconInfo); const beaconInfo = useEventEmitterState(beacon, BeaconEvent.Update, () => beacon.beaconInfo);
const [msRemaining, setMsRemaining] = useState(() => getBeaconMsUntilExpiry(beaconInfo)); const [msRemaining, setMsRemaining] = useState(() => (beaconInfo ? getBeaconMsUntilExpiry(beaconInfo) : 0));
useEffect(() => { useEffect(() => {
if (!beaconInfo) {
return;
}
setMsRemaining(getBeaconMsUntilExpiry(beaconInfo)); setMsRemaining(getBeaconMsUntilExpiry(beaconInfo));
}, [beaconInfo]); }, [beaconInfo]);
const updateMsRemaining = useCallback(() => { const updateMsRemaining = useCallback(() => {
if (!beaconInfo) {
return;
}
const ms = getBeaconMsUntilExpiry(beaconInfo); const ms = getBeaconMsUntilExpiry(beaconInfo);
setMsRemaining(ms); setMsRemaining(ms);
}, [beaconInfo]); }, [beaconInfo]);

View File

@ -42,7 +42,7 @@ const OwnBeaconStatus: React.FC<Props & HTMLProps<HTMLDivElement>> = ({ beacon,
stoppingInProgress, stoppingInProgress,
onStopSharing, onStopSharing,
onResetLocationPublishError, onResetLocationPublishError,
} = useOwnLiveBeacons([beacon?.identifier]); } = useOwnLiveBeacons(beacon?.identifier ? [beacon?.identifier] : []);
// combine display status with errors that only occur for user's own beacons // combine display status with errors that only occur for user's own beacons
const ownDisplayStatus = hasLocationPublishError || hasStopSharingError ? BeaconDisplayStatus.Error : displayStatus; const ownDisplayStatus = hasLocationPublishError || hasStopSharingError ? BeaconDisplayStatus.Error : displayStatus;

View File

@ -28,9 +28,9 @@ interface Props {
} }
const ShareLatestLocation: React.FC<Props> = ({ latestLocationState }) => { const ShareLatestLocation: React.FC<Props> = ({ latestLocationState }) => {
const [coords, setCoords] = useState(null); const [coords, setCoords] = useState<GeolocationCoordinates | undefined>();
useEffect(() => { useEffect(() => {
if (!latestLocationState) { if (!latestLocationState?.uri) {
return; return;
} }
const coords = parseGeoUri(latestLocationState.uri); const coords = parseGeoUri(latestLocationState.uri);

View File

@ -40,7 +40,5 @@ export const getBeaconDisplayStatus = (
if (!latestLocationState) { if (!latestLocationState) {
return BeaconDisplayStatus.Loading; return BeaconDisplayStatus.Loading;
} }
if (latestLocationState) { return BeaconDisplayStatus.Active;
return BeaconDisplayStatus.Active;
}
}; };

View File

@ -23,11 +23,11 @@ import { sortBeaconsByLatestExpiry } from "./duration";
type LiveBeaconsState = { type LiveBeaconsState = {
beacon?: Beacon; beacon?: Beacon;
onStopSharing?: () => void; onStopSharing: () => void;
onResetLocationPublishError?: () => void; onResetLocationPublishError: () => void;
stoppingInProgress?: boolean; stoppingInProgress: boolean;
hasStopSharingError?: boolean; hasStopSharingError: boolean;
hasLocationPublishError?: boolean; hasLocationPublishError: boolean;
}; };
/** /**

View File

@ -29,6 +29,14 @@ jest.mock("../../../../src/utils/beacon/useOwnLiveBeacons", () => ({
useOwnLiveBeacons: jest.fn(), useOwnLiveBeacons: jest.fn(),
})); }));
const defaultLiveBeaconsState = {
onStopSharing: jest.fn(),
onResetLocationPublishError: jest.fn(),
stoppingInProgress: false,
hasStopSharingError: false,
hasLocationPublishError: false,
};
describe("<OwnBeaconStatus />", () => { describe("<OwnBeaconStatus />", () => {
const defaultProps = { const defaultProps = {
displayStatus: BeaconDisplayStatus.Loading, displayStatus: BeaconDisplayStatus.Loading,
@ -43,7 +51,7 @@ describe("<OwnBeaconStatus />", () => {
beforeEach(() => { beforeEach(() => {
jest.spyOn(global.Date, "now").mockReturnValue(123456789); jest.spyOn(global.Date, "now").mockReturnValue(123456789);
mocked(useOwnLiveBeacons).mockClear().mockReturnValue({}); mocked(useOwnLiveBeacons).mockClear().mockReturnValue(defaultLiveBeaconsState);
defaultBeacon = new Beacon(makeBeaconInfoEvent(userId, roomId)); defaultBeacon = new Beacon(makeBeaconInfoEvent(userId, roomId));
}); });
@ -57,6 +65,7 @@ describe("<OwnBeaconStatus />", () => {
it("renders stop button", () => { it("renders stop button", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
onStopSharing: jest.fn(), onStopSharing: jest.fn(),
}); });
renderComponent({ displayStatus, beacon: defaultBeacon }); renderComponent({ displayStatus, beacon: defaultBeacon });
@ -68,6 +77,7 @@ describe("<OwnBeaconStatus />", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
const onStopSharing = jest.fn(); const onStopSharing = jest.fn();
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
onStopSharing, onStopSharing,
}); });
renderComponent({ displayStatus, beacon: defaultBeacon }); renderComponent({ displayStatus, beacon: defaultBeacon });
@ -90,6 +100,7 @@ describe("<OwnBeaconStatus />", () => {
it("renders in error mode", () => { it("renders in error mode", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
hasLocationPublishError: true, hasLocationPublishError: true,
onResetLocationPublishError: jest.fn(), onResetLocationPublishError: jest.fn(),
}); });
@ -103,6 +114,7 @@ describe("<OwnBeaconStatus />", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
const onResetLocationPublishError = jest.fn(); const onResetLocationPublishError = jest.fn();
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
hasLocationPublishError: true, hasLocationPublishError: true,
onResetLocationPublishError, onResetLocationPublishError,
}); });
@ -117,6 +129,7 @@ describe("<OwnBeaconStatus />", () => {
it("renders in error mode", () => { it("renders in error mode", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
hasLocationPublishError: false, hasLocationPublishError: false,
hasStopSharingError: true, hasStopSharingError: true,
onStopSharing: jest.fn(), onStopSharing: jest.fn(),
@ -131,6 +144,7 @@ describe("<OwnBeaconStatus />", () => {
const displayStatus = BeaconDisplayStatus.Active; const displayStatus = BeaconDisplayStatus.Active;
const onStopSharing = jest.fn(); const onStopSharing = jest.fn();
mocked(useOwnLiveBeacons).mockReturnValue({ mocked(useOwnLiveBeacons).mockReturnValue({
...defaultLiveBeaconsState,
hasStopSharingError: true, hasStopSharingError: true,
onStopSharing, onStopSharing,
}); });