Conform more of the codebase to strictNullChecks (#10607)
* Conform more of the codebase to `strictNullChecks` * Conform more of the codebase to `strictNullChecks` * Fix types * Conform more of the codebase to `strictNullChecks` * Conform more of the codebase to `strictNullChecks`
This commit is contained in:
parent
9d8d610f31
commit
56e4ae41f8
19 changed files with 71 additions and 68 deletions
|
@ -182,7 +182,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
{
|
||||
key: "number",
|
||||
test: ({ value }) => {
|
||||
const parsedSize = parseInt(value, 10);
|
||||
const parsedSize = parseInt(value!, 10);
|
||||
return validateNumberInRange(1, 2000)(parsedSize);
|
||||
},
|
||||
invalid: () => {
|
||||
|
@ -218,7 +218,7 @@ const ExportDialog: React.FC<IProps> = ({ room, onFinished }) => {
|
|||
{
|
||||
key: "number",
|
||||
test: ({ value }) => {
|
||||
const parsedSize = parseInt(value, 10);
|
||||
const parsedSize = parseInt(value!, 10);
|
||||
return validateNumberInRange(1, 10 ** 8)(parsedSize);
|
||||
},
|
||||
invalid: () => {
|
||||
|
|
|
@ -38,7 +38,7 @@ interface IProps {
|
|||
}
|
||||
|
||||
const FeedbackDialog: React.FC<IProps> = (props: IProps) => {
|
||||
const feedbackRef = useRef<Field>();
|
||||
const feedbackRef = useRef<Field>(null);
|
||||
const [comment, setComment] = useState<string>("");
|
||||
const [canContact, toggleCanContact] = useStateToggle(false);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import { SettingLevel } from "../../../settings/SettingLevel";
|
|||
|
||||
interface IProps {
|
||||
// Current room
|
||||
roomId: string;
|
||||
roomId: string | null;
|
||||
minWidth: number;
|
||||
maxWidth: number;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ export default class BridgeTile extends React.PureComponent<IProps> {
|
|||
<Pill
|
||||
type={PillType.UserMention}
|
||||
room={this.props.room}
|
||||
url={makeUserPermalink(content.creator)}
|
||||
url={makeUserPermalink(content.creator!)}
|
||||
shouldShowPillAvatar={SettingsStore.getValue("Pill.shouldShowPillAvatar")}
|
||||
/>
|
||||
),
|
||||
|
|
|
@ -213,7 +213,7 @@ export default class ChangePassword extends React.Component<IProps, IState> {
|
|||
const modal = Modal.createDialog(SetEmailDialog, {
|
||||
title: _t("Do you want to set an email address?"),
|
||||
});
|
||||
return modal.finished.then(([confirmed]) => confirmed);
|
||||
return modal.finished.then(([confirmed]) => !!confirmed);
|
||||
}
|
||||
|
||||
private onExportE2eKeysClicked = (): void => {
|
||||
|
|
|
@ -94,9 +94,9 @@ export default class CrossSigningPanel extends React.PureComponent<{}, IState> {
|
|||
const secretStorage = cli.crypto!.secretStorage;
|
||||
const crossSigningPublicKeysOnDevice = Boolean(crossSigning.getId());
|
||||
const crossSigningPrivateKeysInStorage = Boolean(await crossSigning.isStoredInSecretStorage(secretStorage));
|
||||
const masterPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("master")));
|
||||
const selfSigningPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("self_signing")));
|
||||
const userSigningPrivateKeyCached = !!(pkCache && (await pkCache.getCrossSigningKeyCache("user_signing")));
|
||||
const masterPrivateKeyCached = !!(await pkCache?.getCrossSigningKeyCache?.("master"));
|
||||
const selfSigningPrivateKeyCached = !!(await pkCache?.getCrossSigningKeyCache?.("self_signing"));
|
||||
const userSigningPrivateKeyCached = !!(await pkCache?.getCrossSigningKeyCache?.("user_signing"));
|
||||
const homeserverSupportsCrossSigning = await cli.doesServerSupportUnstableFeature(
|
||||
"org.matrix.e2e_cross_signing",
|
||||
);
|
||||
|
|
|
@ -51,7 +51,7 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
|
|||
super(props);
|
||||
this.state = {
|
||||
renaming: false,
|
||||
displayName: props.device.display_name,
|
||||
displayName: props.device.display_name ?? "",
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -103,11 +103,11 @@ export default class DevicesPanelEntry extends React.Component<IProps, IState> {
|
|||
});
|
||||
} else {
|
||||
const cli = MatrixClientPeg.get();
|
||||
const userId = cli.getUserId()!;
|
||||
const userId = cli.getSafeUserId();
|
||||
const verificationRequestPromise = cli.requestVerification(userId, [this.props.device.device_id]);
|
||||
Modal.createDialog(VerificationRequestDialog, {
|
||||
verificationRequestPromise,
|
||||
member: cli.getUser(userId),
|
||||
member: cli.getUser(userId) ?? undefined,
|
||||
onFinished: async (): Promise<void> => {
|
||||
const request = await verificationRequestPromise;
|
||||
request.cancel();
|
||||
|
|
|
@ -26,7 +26,6 @@ import EventIndexPeg from "../../../indexing/EventIndexPeg";
|
|||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import SeshatResetDialog from "../dialogs/SeshatResetDialog";
|
||||
import InlineSpinner from "../elements/InlineSpinner";
|
||||
import { IIndexStats } from "../../../indexing/BaseEventIndexManager";
|
||||
|
||||
interface IState {
|
||||
enabling: boolean;
|
||||
|
@ -49,15 +48,9 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
|
||||
public updateCurrentRoom = async (): Promise<void> => {
|
||||
const eventIndex = EventIndexPeg.get();
|
||||
let stats: IIndexStats | undefined;
|
||||
|
||||
try {
|
||||
stats = await eventIndex?.getStats();
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we will
|
||||
// try later again and probably succeed.
|
||||
return;
|
||||
}
|
||||
const stats = await eventIndex?.getStats().catch(() => {});
|
||||
// This call may fail if sporadically, not a huge issue as we will try later again and probably succeed.
|
||||
if (!stats) return;
|
||||
|
||||
this.setState({
|
||||
eventIndexSize: stats.size,
|
||||
|
@ -88,14 +81,13 @@ export default class EventIndexPanel extends React.Component<{}, IState> {
|
|||
if (eventIndex !== null) {
|
||||
eventIndex.on("changedCheckpoint", this.updateCurrentRoom);
|
||||
|
||||
try {
|
||||
const stats = await eventIndex.getStats();
|
||||
const stats = await eventIndex.getStats().catch(() => {});
|
||||
// This call may fail if sporadically, not a huge issue as we
|
||||
// will try later again in the updateCurrentRoom call and
|
||||
// probably succeed.
|
||||
if (stats) {
|
||||
eventIndexSize = stats.size;
|
||||
roomCount = stats.roomCount;
|
||||
} catch {
|
||||
// This call may fail if sporadically, not a huge issue as we
|
||||
// will try later again in the updateCurrentRoom call and
|
||||
// probably succeed.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
private onValidateFontSize = async ({ value }: Pick<IFieldState, "value">): Promise<IValidationResult> => {
|
||||
const parsedSize = parseFloat(value);
|
||||
const parsedSize = parseFloat(value!);
|
||||
const min = FontWatcher.MIN_SIZE + FontWatcher.SIZE_DIFF;
|
||||
const max = FontWatcher.MAX_SIZE + FontWatcher.SIZE_DIFF;
|
||||
|
||||
|
@ -98,7 +98,7 @@ export default class FontScalingPanel extends React.Component<IProps, IState> {
|
|||
};
|
||||
}
|
||||
|
||||
SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, parseInt(value, 10) - FontWatcher.SIZE_DIFF);
|
||||
SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, parseInt(value!, 10) - FontWatcher.SIZE_DIFF);
|
||||
|
||||
return { valid: true, feedback: _t("Use between %(min)s pt and %(max)s pt", { min, max }) };
|
||||
};
|
||||
|
|
|
@ -61,7 +61,7 @@ const JoinRuleSettings: React.FC<IProps> = ({
|
|||
|
||||
const disabled = !room.currentState.mayClientSendStateEvent(EventType.RoomJoinRules, cli);
|
||||
|
||||
const [content, setContent] = useLocalEcho<IJoinRuleEventContent>(
|
||||
const [content, setContent] = useLocalEcho<IJoinRuleEventContent | undefined>(
|
||||
() => room.currentState.getStateEvents(EventType.RoomJoinRules, "")?.getContent(),
|
||||
(content) => cli.sendStateEvent(room.roomId, EventType.RoomJoinRules, content, ""),
|
||||
onError,
|
||||
|
@ -70,10 +70,10 @@ const JoinRuleSettings: React.FC<IProps> = ({
|
|||
const { join_rule: joinRule = JoinRule.Invite } = content || {};
|
||||
const restrictedAllowRoomIds =
|
||||
joinRule === JoinRule.Restricted
|
||||
? content.allow?.filter((o) => o.type === RestrictedAllowType.RoomMembership).map((o) => o.room_id)
|
||||
? content?.allow?.filter((o) => o.type === RestrictedAllowType.RoomMembership).map((o) => o.room_id)
|
||||
: undefined;
|
||||
|
||||
const editRestrictedRoomIds = async (): Promise<string[]> => {
|
||||
const editRestrictedRoomIds = async (): Promise<string[] | undefined> => {
|
||||
let selected = restrictedAllowRoomIds;
|
||||
if (!selected?.length && SpaceStore.instance.activeSpaceRoom) {
|
||||
selected = [SpaceStore.instance.activeSpaceRoom.roomId];
|
||||
|
@ -207,7 +207,7 @@ const JoinRuleSettings: React.FC<IProps> = ({
|
|||
"Anyone in <spaceName/> can find and join. You can select other spaces too.",
|
||||
{},
|
||||
{
|
||||
spaceName: () => <b>{SpaceStore.instance.activeSpaceRoom.name}</b>,
|
||||
spaceName: () => <b>{SpaceStore.instance.activeSpaceRoom!.name}</b>,
|
||||
},
|
||||
);
|
||||
} else {
|
||||
|
@ -229,7 +229,7 @@ const JoinRuleSettings: React.FC<IProps> = ({
|
|||
}
|
||||
|
||||
const onChange = async (joinRule: JoinRule): Promise<void> => {
|
||||
const beforeJoinRule = content.join_rule;
|
||||
const beforeJoinRule = content?.join_rule;
|
||||
|
||||
let restrictedAllowRoomIds: string[] | undefined;
|
||||
if (joinRule === JoinRule.Restricted) {
|
||||
|
|
|
@ -31,7 +31,6 @@ import { chromeFileInputFix } from "../../../utils/BrowserWorkarounds";
|
|||
import PosthogTrackers from "../../../PosthogTrackers";
|
||||
|
||||
interface IState {
|
||||
userId?: string;
|
||||
originalDisplayName: string;
|
||||
displayName: string;
|
||||
originalAvatarUrl: string | null;
|
||||
|
@ -41,16 +40,16 @@ interface IState {
|
|||
}
|
||||
|
||||
export default class ProfileSettings extends React.Component<{}, IState> {
|
||||
private readonly userId: string;
|
||||
private avatarUpload: React.RefObject<HTMLInputElement> = createRef();
|
||||
|
||||
public constructor(props: {}) {
|
||||
super(props);
|
||||
|
||||
const client = MatrixClientPeg.get();
|
||||
this.userId = MatrixClientPeg.get().getSafeUserId();
|
||||
let avatarUrl = OwnProfileStore.instance.avatarMxc;
|
||||
if (avatarUrl) avatarUrl = mediaFromMxc(avatarUrl).getSquareThumbnailHttp(96);
|
||||
this.state = {
|
||||
userId: client.getUserId()!,
|
||||
originalDisplayName: OwnProfileStore.instance.displayName ?? "",
|
||||
displayName: OwnProfileStore.instance.displayName ?? "",
|
||||
originalAvatarUrl: avatarUrl,
|
||||
|
@ -150,7 +149,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
|
|||
const reader = new FileReader();
|
||||
reader.onload = (ev) => {
|
||||
this.setState({
|
||||
avatarUrl: ev.target?.result,
|
||||
avatarUrl: ev.target?.result ?? undefined,
|
||||
avatarFile: file,
|
||||
enableProfileSave: true,
|
||||
});
|
||||
|
@ -159,7 +158,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
|
|||
};
|
||||
|
||||
public render(): React.ReactNode {
|
||||
const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(this.state.userId, {
|
||||
const userIdentifier = UserIdentifierCustomisations.getDisplayUserIdentifier(this.userId, {
|
||||
withDisplayName: true,
|
||||
});
|
||||
|
||||
|
@ -198,7 +197,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
|
|||
</div>
|
||||
<AvatarSetting
|
||||
avatarUrl={avatarUrl}
|
||||
avatarName={this.state.displayName || this.state.userId}
|
||||
avatarName={this.state.displayName || this.userId}
|
||||
avatarAltText={_t("Profile picture")}
|
||||
uploadAvatar={this.uploadAvatar}
|
||||
removeAvatar={this.removeAvatar}
|
||||
|
|
|
@ -379,12 +379,12 @@ export default class SecureBackupPanel extends React.PureComponent<{}, IState> {
|
|||
|
||||
return <div key={i}>{sigStatus}</div>;
|
||||
});
|
||||
if (backupSigStatus.sigs.length === 0) {
|
||||
if (!backupSigStatus?.sigs?.length) {
|
||||
backupSigStatuses = _t("Backup is not signed by any of your sessions");
|
||||
}
|
||||
|
||||
let trustedLocally;
|
||||
if (backupSigStatus.trusted_locally) {
|
||||
let trustedLocally: string | undefined;
|
||||
if (backupSigStatus?.trusted_locally) {
|
||||
trustedLocally = _t("This backup is trusted because it has been restored on this session");
|
||||
}
|
||||
|
||||
|
|
|
@ -105,13 +105,13 @@ const DeviceDetails: React.FC<Props> = ({
|
|||
|
||||
const showPushNotificationSection = !!pusher || !!localNotificationSettings;
|
||||
|
||||
function isPushNotificationsEnabled(pusher: IPusher, notificationSettings: LocalNotificationSettings): boolean {
|
||||
if (pusher) return pusher[PUSHER_ENABLED.name];
|
||||
function isPushNotificationsEnabled(pusher?: IPusher, notificationSettings?: LocalNotificationSettings): boolean {
|
||||
if (pusher) return !!pusher[PUSHER_ENABLED.name];
|
||||
if (localNotificationSettings) return !localNotificationSettings.is_silenced;
|
||||
return true;
|
||||
}
|
||||
|
||||
function isCheckboxDisabled(pusher: IPusher, notificationSettings: LocalNotificationSettings): boolean {
|
||||
function isCheckboxDisabled(pusher?: IPusher, notificationSettings?: LocalNotificationSettings): boolean {
|
||||
if (localNotificationSettings) return false;
|
||||
if (pusher && !supportsMSC3881) return true;
|
||||
return false;
|
||||
|
|
|
@ -47,8 +47,8 @@ const deviceTypeLabel: Record<DeviceType, string> = {
|
|||
};
|
||||
|
||||
export const DeviceTypeIcon: React.FC<Props> = ({ isVerified, isSelected, deviceType }) => {
|
||||
const Icon = deviceTypeIcon[deviceType] || deviceTypeIcon[DeviceType.Unknown];
|
||||
const label = deviceTypeLabel[deviceType] || deviceTypeLabel[DeviceType.Unknown];
|
||||
const Icon = deviceTypeIcon[deviceType!] || deviceTypeIcon[DeviceType.Unknown];
|
||||
const label = deviceTypeLabel[deviceType!] || deviceTypeLabel[DeviceType.Unknown];
|
||||
return (
|
||||
<div
|
||||
className={classNames("mx_DeviceTypeIcon", {
|
||||
|
|
|
@ -212,9 +212,9 @@ const SpaceCreateMenu: React.FC<{
|
|||
const [busy, setBusy] = useState<boolean>(false);
|
||||
|
||||
const [name, setName] = useState("");
|
||||
const spaceNameField = useRef<Field>();
|
||||
const spaceNameField = useRef<Field>(null);
|
||||
const [alias, setAlias] = useState("");
|
||||
const spaceAliasField = useRef<RoomAliasField>();
|
||||
const spaceAliasField = useRef<RoomAliasField>(null);
|
||||
const [avatar, setAvatar] = useState<File | undefined>(undefined);
|
||||
const [topic, setTopic] = useState<string>("");
|
||||
|
||||
|
|
|
@ -331,9 +331,9 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(
|
|||
|
||||
const SpacePanel: React.FC = () => {
|
||||
const [isPanelCollapsed, setPanelCollapsed] = useState(true);
|
||||
const ref = useRef<HTMLDivElement>();
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
useLayoutEffect(() => {
|
||||
UIStore.instance.trackElementDimensions("SpacePanel", ref.current);
|
||||
if (ref.current) UIStore.instance.trackElementDimensions("SpacePanel", ref.current);
|
||||
return () => UIStore.instance.stopTrackingElementDimensions("SpacePanel");
|
||||
}, []);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue