Conform more code to strictNullChecks (#10374)

* Apply `strictNullChecks` to `src/components/views/room_settings/*`

* Restore tsconfig.json

* Conform more code to `strictNullChecks`

* Iterate

* Update matrix-widget-api

* Conform more code to `strictNullChecks`
This commit is contained in:
Michael Telatynski 2023-03-16 11:07:29 +00:00 committed by GitHub
parent 9c816bb720
commit 1c9ea423c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 223 additions and 179 deletions

View file

@ -46,7 +46,7 @@ interface IKeyboardShortcutProps {
export const KeyboardShortcut: React.FC<IKeyboardShortcutProps> = ({ value, className = "mx_KeyboardShortcut" }) => {
if (!value) return null;
const modifiersElement = [];
const modifiersElement: JSX.Element[] = [];
if (value.ctrlOrCmdKey) {
modifiersElement.push(<KeyboardKey key="ctrlOrCmdKey" name={IS_MAC ? Key.META : Key.CONTROL} />);
} else if (value.ctrlKey) {

View file

@ -41,7 +41,7 @@ import SdkConfig from "../../../SdkConfig";
import AccessibleButton from "../elements/AccessibleButton";
import TagComposer from "../elements/TagComposer";
import { objectClone } from "../../../utils/objects";
import { arrayDiff } from "../../../utils/arrays";
import { arrayDiff, filterBoolean } from "../../../utils/arrays";
import { clearAllNotifications, getLocalNotificationAccountDataEventType } from "../../../utils/notifications";
import {
updateExistingPushRulesWithActions,
@ -167,7 +167,7 @@ const maximumVectorState = (
if (!definition.syncedRuleIds?.length) {
return undefined;
}
const vectorState = definition.syncedRuleIds.reduce<VectorState>((maxVectorState, ruleId) => {
const vectorState = definition.syncedRuleIds.reduce<VectorState | undefined>((maxVectorState, ruleId) => {
// already set to maximum
if (maxVectorState === VectorState.Loud) {
return maxVectorState;
@ -345,7 +345,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
for (const rule of defaultRules[category]) {
const definition: VectorPushRuleDefinition = VectorPushRulesDefinitions[rule.rule_id];
const vectorState = definition.ruleToVectorState(rule);
preparedNewState.vectorPushRules[category].push({
preparedNewState.vectorPushRules[category]!.push({
ruleId: rule.rule_id,
rule,
vectorState,
@ -355,7 +355,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
// Quickly sort the rules for display purposes
preparedNewState.vectorPushRules[category].sort((a, b) => {
preparedNewState.vectorPushRules[category]!.sort((a, b) => {
let idxA = RULE_DISPLAY_ORDER.indexOf(a.ruleId);
let idxB = RULE_DISPLAY_ORDER.indexOf(b.ruleId);
@ -367,7 +367,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
});
if (category === KEYWORD_RULE_CATEGORY) {
preparedNewState.vectorPushRules[category].push({
preparedNewState.vectorPushRules[category]!.push({
ruleId: KEYWORD_RULE_ID,
description: _t("Messages containing keywords"),
vectorState: preparedNewState.vectorKeywordRuleInfo.vectorState,
@ -540,8 +540,8 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
private async setKeywords(keywords: string[], originalRules: IAnnotatedPushRule[]): Promise<void> {
try {
// De-duplicate and remove empties
keywords = Array.from(new Set(keywords)).filter((k) => !!k);
const oldKeywords = Array.from(new Set(originalRules.map((r) => r.pattern))).filter((k) => !!k);
keywords = filterBoolean(Array.from(new Set(keywords)));
const oldKeywords = filterBoolean(Array.from(new Set(originalRules.map((r) => r.pattern))));
// Note: Technically because of the UI interaction (at the time of writing), the diff
// will only ever be +/-1 so we don't really have to worry about efficiently handling
@ -555,13 +555,13 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
}
let ruleVectorState = this.state.vectorKeywordRuleInfo.vectorState;
let ruleVectorState = this.state.vectorKeywordRuleInfo?.vectorState;
if (ruleVectorState === VectorState.Off) {
// When the current global keywords rule is OFF, we need to look at
// the flavor of existing rules to apply the same actions
// when creating the new rule.
if (originalRules.length) {
ruleVectorState = PushRuleVectorState.contentRuleVectorStateKind(originalRules[0]);
ruleVectorState = PushRuleVectorState.contentRuleVectorStateKind(originalRules[0]) ?? undefined;
} else {
ruleVectorState = VectorState.On; // default
}
@ -776,7 +776,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
/>
);
const fieldsetRows = this.state.vectorPushRules[category]?.map((r) => (
const fieldsetRows = this.state.vectorPushRules?.[category]?.map((r) => (
<fieldset
key={category + r.ruleId}
data-testid={category + r.ruleId}
@ -840,7 +840,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
</tr>
));
if (!rows.length) return null; // no targets to show
if (!rows?.length) return null; // no targets to show
return (
<div className="mx_UserNotifSettings_floatingSection">

View file

@ -72,7 +72,7 @@ interface IProps {
interface IState {
defaultIdServer?: string;
currentClientIdServer: string;
currentClientIdServer?: string;
idServer?: string;
error?: string;
busy: boolean;

View file

@ -402,14 +402,14 @@ export default class RolesRoomSettingsTab extends React.Component<IProps> {
{banned.map((member) => {
const banEvent = member.events.member?.getContent();
const sender = room?.getMember(member.events.member.getSender());
let bannedBy = member.events.member.getSender(); // start by falling back to mxid
let bannedBy = member.events.member?.getSender(); // start by falling back to mxid
if (sender) bannedBy = sender.name;
return (
<BannedUser
key={member.userId}
canUnban={canBanUsers}
member={member}
reason={banEvent.reason}
reason={banEvent?.reason}
by={bannedBy}
/>
);

View file

@ -61,7 +61,7 @@ interface IProps {
interface IState {
language: string;
spellCheckEnabled: boolean;
spellCheckEnabled?: boolean;
spellCheckLanguages: string[];
haveIdServer: boolean;
serverSupportsSeparateAddAndBind?: boolean;
@ -406,7 +406,7 @@ export default class GeneralUserSettingsTab extends React.Component<IProps, ISta
<div className="mx_SettingsTab_section mx_SettingsTab_section_spellcheck">
<span className="mx_SettingsTab_subheading">
{_t("Spell check")}
<ToggleSwitch checked={this.state.spellCheckEnabled} onChange={this.onSpellCheckEnabledChange} />
<ToggleSwitch checked={!!this.state.spellCheckEnabled} onChange={this.onSpellCheckEnabledChange} />
</span>
{this.state.spellCheckEnabled && !IS_MAC && (
<SpellCheckSettings

View file

@ -56,7 +56,7 @@ const confirmSignOut = async (sessionsToSignOutCount: number): Promise<boolean>
});
const [confirmed] = await finished;
return confirmed;
return !!confirmed;
};
const useSignOut = (

View file

@ -61,7 +61,7 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
private refreshMediaDevices = async (stream?: MediaStream): Promise<void> => {
this.setState({
mediaDevices: await MediaDeviceHandler.getDevices(),
mediaDevices: (await MediaDeviceHandler.getDevices()) ?? null,
[MediaDeviceKindEnum.AudioOutput]: MediaDeviceHandler.getAudioOutput(),
[MediaDeviceKindEnum.AudioInput]: MediaDeviceHandler.getAudioInput(),
[MediaDeviceKindEnum.VideoInput]: MediaDeviceHandler.getVideoInput(),
@ -105,8 +105,8 @@ export default class VoiceUserSettingsTab extends React.Component<{}, IState> {
}
private renderDropdown(kind: MediaDeviceKindEnum, label: string): ReactNode {
const devices = this.state.mediaDevices[kind].slice(0);
if (devices.length === 0) return null;
const devices = this.state.mediaDevices?.[kind].slice(0);
if (!devices?.length) return null;
const defaultDevice = MediaDeviceHandler.getDefaultDevice(devices);
return (