Conform more code to strict null checking (#10153)
* Conform more code to strict null checking * Conform more code to strict null checking * Iterate * Iterate
This commit is contained in:
parent
a4ff959aa1
commit
145a5a8a8d
89 changed files with 520 additions and 551 deletions
|
@ -91,7 +91,7 @@ function getLevelOrder(setting: ISetting): SettingLevel[] {
|
|||
|
||||
export type CallbackFn = (
|
||||
settingName: string,
|
||||
roomId: string,
|
||||
roomId: string | null,
|
||||
atLevel: SettingLevel,
|
||||
newValAtLevel: any,
|
||||
newVal: any,
|
||||
|
@ -133,7 +133,7 @@ export default class SettingsStore {
|
|||
// when the setting changes. We track which rooms we're monitoring though to ensure we
|
||||
// don't duplicate updates on the bus.
|
||||
private static watchers = new Map<string, WatchCallbackFn>();
|
||||
private static monitors = new Map<string, Map<string, string>>(); // { settingName => { roomId => callbackRef } }
|
||||
private static monitors = new Map<string, Map<string | null, string>>(); // { settingName => { roomId => callbackRef } }
|
||||
|
||||
// Counter used for generation of watcher IDs
|
||||
private static watcherCount = 1;
|
||||
|
@ -205,7 +205,7 @@ export default class SettingsStore {
|
|||
return;
|
||||
}
|
||||
|
||||
defaultWatchManager.unwatchSetting(SettingsStore.watchers.get(watcherReference));
|
||||
defaultWatchManager.unwatchSetting(SettingsStore.watchers.get(watcherReference)!);
|
||||
SettingsStore.watchers.delete(watcherReference);
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ export default class SettingsStore {
|
|||
if (!this.monitors.has(settingName)) this.monitors.set(settingName, new Map());
|
||||
|
||||
const registerWatcher = (): void => {
|
||||
this.monitors.get(settingName).set(
|
||||
this.monitors.get(settingName)!.set(
|
||||
roomId,
|
||||
SettingsStore.watchSetting(
|
||||
settingName,
|
||||
|
@ -242,7 +242,7 @@ export default class SettingsStore {
|
|||
);
|
||||
};
|
||||
|
||||
const rooms = Array.from(this.monitors.get(settingName).keys());
|
||||
const rooms = Array.from(this.monitors.get(settingName)!.keys());
|
||||
const hasRoom = rooms.find((r) => r === roomId || r === null);
|
||||
if (!hasRoom) {
|
||||
registerWatcher();
|
||||
|
@ -250,9 +250,9 @@ export default class SettingsStore {
|
|||
if (roomId === null) {
|
||||
// Unregister all existing watchers and register the new one
|
||||
rooms.forEach((roomId) => {
|
||||
SettingsStore.unwatchSetting(this.monitors.get(settingName).get(roomId));
|
||||
SettingsStore.unwatchSetting(this.monitors.get(settingName)!.get(roomId));
|
||||
});
|
||||
this.monitors.get(settingName).clear();
|
||||
this.monitors.get(settingName)!.clear();
|
||||
registerWatcher();
|
||||
} // else a watcher is already registered for the room, so don't bother registering it again
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ export default class SettingsStore {
|
|||
* The level to get the display name for; Defaults to 'default'.
|
||||
* @return {String} The display name for the setting, or null if not found.
|
||||
*/
|
||||
public static getDisplayName(settingName: string, atLevel = SettingLevel.DEFAULT): string {
|
||||
public static getDisplayName(settingName: string, atLevel = SettingLevel.DEFAULT): string | null {
|
||||
if (!SETTINGS[settingName] || !SETTINGS[settingName].displayName) return null;
|
||||
|
||||
let displayName = SETTINGS[settingName].displayName;
|
||||
|
@ -296,7 +296,7 @@ export default class SettingsStore {
|
|||
*/
|
||||
public static isFeature(settingName: string): boolean {
|
||||
if (!SETTINGS[settingName]) return false;
|
||||
return SETTINGS[settingName].isFeature;
|
||||
return !!SETTINGS[settingName].isFeature;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,7 +319,7 @@ export default class SettingsStore {
|
|||
}
|
||||
}
|
||||
|
||||
public static getLabGroup(settingName: string): LabGroup {
|
||||
public static getLabGroup(settingName: string): LabGroup | undefined {
|
||||
if (SettingsStore.isFeature(settingName)) {
|
||||
return (<IFeature>SETTINGS[settingName]).labsGroup;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ export default class SettingsStore {
|
|||
*/
|
||||
public static isEnabled(settingName: string): boolean {
|
||||
if (!SETTINGS[settingName]) return false;
|
||||
return SETTINGS[settingName].controller ? !SETTINGS[settingName].controller.settingDisabled : true;
|
||||
return !SETTINGS[settingName].controller?.settingDisabled ?? true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -559,7 +559,7 @@ export default class SettingsStore {
|
|||
throw new Error("Setting '" + settingName + "' does not appear to be a setting.");
|
||||
}
|
||||
|
||||
return level === SettingLevel.DEFAULT || setting.supportedLevels.includes(level);
|
||||
return level === SettingLevel.DEFAULT || !!setting.supportedLevels?.includes(level);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -568,7 +568,7 @@ export default class SettingsStore {
|
|||
* @param {string} settingName The setting name.
|
||||
* @return {SettingLevel}
|
||||
*/
|
||||
public static firstSupportedLevel(settingName: string): SettingLevel {
|
||||
public static firstSupportedLevel(settingName: string): SettingLevel | null {
|
||||
// Verify that the setting is actually a setting
|
||||
const setting = SETTINGS[settingName];
|
||||
if (!setting) {
|
||||
|
@ -723,10 +723,10 @@ export default class SettingsStore {
|
|||
logger.log(`--- END DEBUG`);
|
||||
}
|
||||
|
||||
private static getHandler(settingName: string, level: SettingLevel): SettingsHandler {
|
||||
private static getHandler(settingName: string, level: SettingLevel): SettingsHandler | null {
|
||||
const handlers = SettingsStore.getHandlers(settingName);
|
||||
if (!handlers[level]) return null;
|
||||
return handlers[level];
|
||||
return handlers[level]!;
|
||||
}
|
||||
|
||||
private static getHandlers(settingName: string): HandlerMap {
|
||||
|
|
|
@ -16,9 +16,9 @@ limitations under the License.
|
|||
|
||||
import { SettingLevel } from "./SettingLevel";
|
||||
|
||||
export type CallbackFn = (changedInRoomId: string, atLevel: SettingLevel, newValAtLevel: any) => void;
|
||||
export type CallbackFn = (changedInRoomId: string | null, atLevel: SettingLevel, newValAtLevel: any) => void;
|
||||
|
||||
const IRRELEVANT_ROOM: string = null;
|
||||
const IRRELEVANT_ROOM: string | null = null;
|
||||
|
||||
/**
|
||||
* Generalized management class for dealing with watchers on a per-handler (per-level)
|
||||
|
@ -26,13 +26,13 @@ const IRRELEVANT_ROOM: string = null;
|
|||
* class, which are then proxied outwards to any applicable watchers.
|
||||
*/
|
||||
export class WatchManager {
|
||||
private watchers = new Map<string, Map<string | symbol, CallbackFn[]>>(); // settingName -> roomId -> CallbackFn[]
|
||||
private watchers = new Map<string, Map<string | null, CallbackFn[]>>(); // settingName -> roomId -> CallbackFn[]
|
||||
|
||||
// Proxy for handlers to delegate changes to this manager
|
||||
public watchSetting(settingName: string, roomId: string | null, cb: CallbackFn): void {
|
||||
if (!this.watchers.has(settingName)) this.watchers.set(settingName, new Map());
|
||||
if (!this.watchers.get(settingName).has(roomId)) this.watchers.get(settingName).set(roomId, []);
|
||||
this.watchers.get(settingName).get(roomId).push(cb);
|
||||
if (!this.watchers.get(settingName)!.has(roomId)) this.watchers.get(settingName)!.set(roomId, []);
|
||||
this.watchers.get(settingName)!.get(roomId)!.push(cb);
|
||||
}
|
||||
|
||||
// Proxy for handlers to delegate changes to this manager
|
||||
|
@ -59,18 +59,18 @@ export class WatchManager {
|
|||
|
||||
if (!this.watchers.has(settingName)) return;
|
||||
|
||||
const roomWatchers = this.watchers.get(settingName);
|
||||
const callbacks = [];
|
||||
const roomWatchers = this.watchers.get(settingName)!;
|
||||
const callbacks: CallbackFn[] = [];
|
||||
|
||||
if (inRoomId !== null && roomWatchers.has(inRoomId)) {
|
||||
callbacks.push(...roomWatchers.get(inRoomId));
|
||||
callbacks.push(...roomWatchers.get(inRoomId)!);
|
||||
}
|
||||
|
||||
if (!inRoomId) {
|
||||
// Fire updates to all the individual room watchers too, as they probably care about the change higher up.
|
||||
callbacks.push(...Array.from(roomWatchers.values()).flat(1));
|
||||
} else if (roomWatchers.has(IRRELEVANT_ROOM)) {
|
||||
callbacks.push(...roomWatchers.get(IRRELEVANT_ROOM));
|
||||
callbacks.push(...roomWatchers.get(IRRELEVANT_ROOM)!);
|
||||
}
|
||||
|
||||
for (const callback of callbacks) {
|
||||
|
|
|
@ -20,6 +20,6 @@ import { SettingLevel } from "../SettingLevel";
|
|||
|
||||
export default class ReloadOnChangeController extends SettingController {
|
||||
public onChange(level: SettingLevel, roomId: string, newValue: any): void {
|
||||
PlatformPeg.get().reload();
|
||||
PlatformPeg.get()?.reload();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ export default abstract class SettingController {
|
|||
* @param {*} newValue The new value for the setting, may be null.
|
||||
* @return {boolean} Whether the settings change should be accepted.
|
||||
*/
|
||||
public async beforeChange(level: SettingLevel, roomId: string, newValue: any): Promise<boolean> {
|
||||
public async beforeChange(level: SettingLevel, roomId: string | null, newValue: any): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ export default abstract class SettingController {
|
|||
* @param {String} roomId The room ID, may be null.
|
||||
* @param {*} newValue The new value for the setting, may be null.
|
||||
*/
|
||||
public onChange(level: SettingLevel, roomId: string, newValue: any): void {
|
||||
public onChange(level: SettingLevel, roomId: string | null, newValue: any): void {
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import SettingsHandler from "./SettingsHandler";
|
|||
*/
|
||||
export default abstract class AbstractLocalStorageSettingsHandler extends SettingsHandler {
|
||||
// Shared cache between all subclass instances
|
||||
private static itemCache = new Map<string, string>();
|
||||
private static itemCache = new Map<string, string | null>();
|
||||
private static objectCache = new Map<string, object>();
|
||||
private static storageListenerBound = false;
|
||||
|
||||
|
@ -51,14 +51,14 @@ export default abstract class AbstractLocalStorageSettingsHandler extends Settin
|
|||
}
|
||||
}
|
||||
|
||||
protected getItem(key: string): string {
|
||||
protected getItem(key: string): string | null {
|
||||
if (!AbstractLocalStorageSettingsHandler.itemCache.has(key)) {
|
||||
const value = localStorage.getItem(key);
|
||||
AbstractLocalStorageSettingsHandler.itemCache.set(key, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
return AbstractLocalStorageSettingsHandler.itemCache.get(key);
|
||||
return AbstractLocalStorageSettingsHandler.itemCache.get(key)!;
|
||||
}
|
||||
|
||||
protected getBoolean(key: string): boolean | null {
|
||||
|
@ -72,7 +72,7 @@ export default abstract class AbstractLocalStorageSettingsHandler extends Settin
|
|||
protected getObject<T extends object>(key: string): T | null {
|
||||
if (!AbstractLocalStorageSettingsHandler.objectCache.has(key)) {
|
||||
try {
|
||||
const value = JSON.parse(localStorage.getItem(key));
|
||||
const value = JSON.parse(localStorage.getItem(key)!);
|
||||
AbstractLocalStorageSettingsHandler.objectCache.set(key, value);
|
||||
return value;
|
||||
} catch (err) {
|
||||
|
|
|
@ -40,7 +40,7 @@ export default class PlatformSettingsHandler extends SettingsHandler {
|
|||
this.store = {};
|
||||
// Load setting values as they are async and `getValue` must be synchronous
|
||||
Object.entries(SETTINGS).forEach(([key, setting]) => {
|
||||
if (setting.supportedLevels.includes(SettingLevel.PLATFORM) && payload.platform.supportsSetting(key)) {
|
||||
if (setting.supportedLevels?.includes(SettingLevel.PLATFORM) && payload.platform.supportsSetting(key)) {
|
||||
payload.platform.getSettingValue(key).then((value: any) => {
|
||||
this.store[key] = value;
|
||||
});
|
||||
|
@ -50,19 +50,19 @@ export default class PlatformSettingsHandler extends SettingsHandler {
|
|||
};
|
||||
|
||||
public canSetValue(settingName: string, roomId: string): boolean {
|
||||
return PlatformPeg.get().supportsSetting(settingName);
|
||||
return PlatformPeg.get()?.supportsSetting(settingName) ?? false;
|
||||
}
|
||||
|
||||
public getValue(settingName: string, roomId: string): any {
|
||||
return this.store[settingName];
|
||||
}
|
||||
|
||||
public setValue(settingName: string, roomId: string, newValue: any): Promise<void> {
|
||||
public async setValue(settingName: string, roomId: string, newValue: any): Promise<void> {
|
||||
this.store[settingName] = newValue; // keep cache up to date for synchronous access
|
||||
return PlatformPeg.get().setSettingValue(settingName, newValue);
|
||||
await PlatformPeg.get()?.setSettingValue(settingName, newValue);
|
||||
}
|
||||
|
||||
public isSupported(): boolean {
|
||||
return PlatformPeg.get().supportsSetting();
|
||||
return PlatformPeg.get()?.supportsSetting() ?? false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandl
|
|||
}
|
||||
|
||||
private onEvent = (event: MatrixEvent, state: RoomState, prevEvent: MatrixEvent): void => {
|
||||
const roomId = event.getRoomId();
|
||||
const roomId = event.getRoomId()!;
|
||||
const room = this.client.getRoom(roomId);
|
||||
|
||||
// Note: in tests and during the encryption setup on initial load we might not have
|
||||
|
@ -124,7 +124,7 @@ export default class RoomSettingsHandler extends MatrixClientBackedSettingsHandl
|
|||
let eventType = DEFAULT_SETTINGS_EVENT_TYPE;
|
||||
if (settingName === "urlPreviewsEnabled") eventType = "org.matrix.room.preview_urls";
|
||||
|
||||
return room?.currentState.maySendStateEvent(eventType, this.client.getUserId()) ?? false;
|
||||
return room?.currentState.maySendStateEvent(eventType, this.client.getUserId()!) ?? false;
|
||||
}
|
||||
|
||||
public isSupported(): boolean {
|
||||
|
|
|
@ -32,7 +32,7 @@ export default abstract class SettingsHandler {
|
|||
* @param {String} roomId The room ID to read from, may be null.
|
||||
* @returns {*} The setting value, or null if not found.
|
||||
*/
|
||||
public abstract getValue(settingName: string, roomId: string): any;
|
||||
public abstract getValue(settingName: string, roomId: string | null): any;
|
||||
|
||||
/**
|
||||
* Sets the value for a particular setting at this level for a particular room.
|
||||
|
@ -45,7 +45,7 @@ export default abstract class SettingsHandler {
|
|||
* @param {*} newValue The new value for the setting, may be null.
|
||||
* @returns {Promise} Resolves when the setting has been saved.
|
||||
*/
|
||||
public abstract setValue(settingName: string, roomId: string, newValue: any): Promise<void>;
|
||||
public abstract setValue(settingName: string, roomId: string | null, newValue: any): Promise<void>;
|
||||
|
||||
/**
|
||||
* Determines if the current user is able to set the value of the given setting
|
||||
|
@ -54,7 +54,7 @@ export default abstract class SettingsHandler {
|
|||
* @param {String} roomId The room ID to check in, may be null
|
||||
* @returns {boolean} True if the setting can be set by the user, false otherwise.
|
||||
*/
|
||||
public abstract canSetValue(settingName: string, roomId: string): boolean;
|
||||
public abstract canSetValue(settingName: string, roomId: string | null): boolean;
|
||||
|
||||
/**
|
||||
* Determines if this level is supported on this device.
|
||||
|
|
|
@ -30,7 +30,7 @@ export class FontWatcher implements IWatcher {
|
|||
// Externally we tell the user the font is size 15. Internally we use 10.
|
||||
public static readonly SIZE_DIFF = 5;
|
||||
|
||||
private dispatcherRef: string;
|
||||
private dispatcherRef: string | null;
|
||||
|
||||
public constructor() {
|
||||
this.dispatcherRef = null;
|
||||
|
@ -42,6 +42,7 @@ export class FontWatcher implements IWatcher {
|
|||
}
|
||||
|
||||
public stop(): void {
|
||||
if (!this.dispatcherRef) return;
|
||||
dis.unregister(this.dispatcherRef);
|
||||
}
|
||||
|
||||
|
@ -77,7 +78,7 @@ export class FontWatcher implements IWatcher {
|
|||
if (fontSize !== size) {
|
||||
SettingsStore.setValue("baseFontSize", null, SettingLevel.DEVICE, fontSize);
|
||||
}
|
||||
document.querySelector<HTMLElement>(":root").style.fontSize = toPx(fontSize);
|
||||
document.querySelector<HTMLElement>(":root")!.style.fontSize = toPx(fontSize);
|
||||
};
|
||||
|
||||
private setSystemFont = ({
|
||||
|
|
|
@ -26,9 +26,9 @@ import { ActionPayload } from "../../dispatcher/payloads";
|
|||
import { SettingLevel } from "../SettingLevel";
|
||||
|
||||
export default class ThemeWatcher {
|
||||
private themeWatchRef: string;
|
||||
private systemThemeWatchRef: string;
|
||||
private dispatcherRef: string;
|
||||
private themeWatchRef: string | null;
|
||||
private systemThemeWatchRef: string | null;
|
||||
private dispatcherRef: string | null;
|
||||
|
||||
private preferDark: MediaQueryList;
|
||||
private preferLight: MediaQueryList;
|
||||
|
@ -67,9 +67,9 @@ export default class ThemeWatcher {
|
|||
this.preferLight.removeEventListener("change", this.onChange);
|
||||
this.preferHighContrast.removeEventListener("change", this.onChange);
|
||||
}
|
||||
SettingsStore.unwatchSetting(this.systemThemeWatchRef);
|
||||
SettingsStore.unwatchSetting(this.themeWatchRef);
|
||||
dis.unregister(this.dispatcherRef);
|
||||
if (this.systemThemeWatchRef) SettingsStore.unwatchSetting(this.systemThemeWatchRef);
|
||||
if (this.themeWatchRef) SettingsStore.unwatchSetting(this.themeWatchRef);
|
||||
if (this.dispatcherRef) dis.unregister(this.dispatcherRef);
|
||||
}
|
||||
|
||||
private onChange = (): void => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue