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
|
@ -327,7 +327,11 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
private shouldHideSender(): boolean {
|
||||
return this.props.room?.getInvitedAndJoinedMemberCount() <= 2 && this.props.layout === Layout.Bubble;
|
||||
return (
|
||||
!!this.props.room &&
|
||||
this.props.room.getInvitedAndJoinedMemberCount() <= 2 &&
|
||||
this.props.layout === Layout.Bubble
|
||||
);
|
||||
}
|
||||
|
||||
private calculateRoomMembersCount = (): void => {
|
||||
|
@ -465,7 +469,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
if (MatrixClientPeg.get().isUserIgnored(mxEv.getSender())) {
|
||||
if (MatrixClientPeg.get().isUserIgnored(mxEv.getSender()!)) {
|
||||
return false; // ignored = no show (only happens if the ignore happens after an event was received)
|
||||
}
|
||||
|
||||
|
@ -647,7 +651,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
for (let i = 0; i < events.length; i++) {
|
||||
const eventAndShouldShow = events[i];
|
||||
const { event, shouldShow } = eventAndShouldShow;
|
||||
const eventId = event.getId();
|
||||
const eventId = event.getId()!;
|
||||
const last = event === lastShownEvent;
|
||||
const { nextEventAndShouldShow, nextTile } = this.getNextEventInfo(events, i);
|
||||
|
||||
|
@ -745,7 +749,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
|
|||
!wantsDateSeparator &&
|
||||
shouldFormContinuation(prevEvent, mxEv, this.showHiddenEvents, this.context.timelineRenderingType);
|
||||
|
||||
const eventId = mxEv.getId();
|
||||
const eventId = mxEv.getId()!;
|
||||
const highlight = eventId === this.props.highlightedEventId;
|
||||
|
||||
const readReceipts = this.readReceiptsByEvent.get(eventId);
|
||||
|
@ -1075,7 +1079,7 @@ abstract class BaseGrouper {
|
|||
public readonly nextEventTile?: MatrixEvent | null,
|
||||
) {
|
||||
this.readMarker = panel.readMarkerForEvent(
|
||||
firstEventAndShouldShow.event.getId(),
|
||||
firstEventAndShouldShow.event.getId()!,
|
||||
firstEventAndShouldShow.event === lastShownEvent,
|
||||
);
|
||||
}
|
||||
|
@ -1143,7 +1147,7 @@ class CreationGrouper extends BaseGrouper {
|
|||
|
||||
public add({ event: ev, shouldShow }: EventAndShouldShow): void {
|
||||
const panel = this.panel;
|
||||
this.readMarker = this.readMarker || panel.readMarkerForEvent(ev.getId(), ev === this.lastShownEvent);
|
||||
this.readMarker = this.readMarker || panel.readMarkerForEvent(ev.getId()!, ev === this.lastShownEvent);
|
||||
if (!shouldShow) {
|
||||
return;
|
||||
}
|
||||
|
@ -1295,7 +1299,7 @@ class MainGrouper extends BaseGrouper {
|
|||
// We can ignore any events that don't actually have a message to display
|
||||
if (!hasText(ev, this.panel.showHiddenEvents)) return;
|
||||
}
|
||||
this.readMarker = this.readMarker || this.panel.readMarkerForEvent(ev.getId(), ev === this.lastShownEvent);
|
||||
this.readMarker = this.readMarker || this.panel.readMarkerForEvent(ev.getId()!, ev === this.lastShownEvent);
|
||||
if (!this.panel.showHiddenEvents && !shouldShow) {
|
||||
// absorb hidden events to not split the summary
|
||||
return;
|
||||
|
@ -1331,7 +1335,10 @@ class MainGrouper extends BaseGrouper {
|
|||
// This will prevent it from being re-created unnecessarily, and instead will allow new props to be provided.
|
||||
// In turn, the shouldComponentUpdate method on ELS can be used to prevent unnecessary renderings.
|
||||
const keyEvent = this.events.find((e) => this.panel.grouperKeyMap.get(e));
|
||||
const key = keyEvent ? this.panel.grouperKeyMap.get(keyEvent) : this.generateKey();
|
||||
const key =
|
||||
keyEvent && this.panel.grouperKeyMap.has(keyEvent)
|
||||
? this.panel.grouperKeyMap.get(keyEvent)!
|
||||
: this.generateKey();
|
||||
if (!keyEvent) {
|
||||
// Populate the weak map with the key.
|
||||
// Note that we only set the key on the specific event it refers to, since this group might get
|
||||
|
|
|
@ -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();
|
||||
eventIndexSize = stats.size;
|
||||
roomCount = stats.roomCount;
|
||||
} catch {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
}, []);
|
||||
|
||||
|
|
|
@ -553,6 +553,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
};
|
||||
|
||||
private rebuildSpaceHierarchy = (): void => {
|
||||
if (!this.matrixClient) return;
|
||||
const visibleSpaces = this.matrixClient
|
||||
.getVisibleRooms(this._msc3946ProcessDynamicPredecessor)
|
||||
.filter((r) => r.isSpaceRoom());
|
||||
|
@ -589,6 +590,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
};
|
||||
|
||||
private rebuildParentMap = (): void => {
|
||||
if (!this.matrixClient) return;
|
||||
const joinedSpaces = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor).filter((r) => {
|
||||
return r.isSpaceRoom() && r.getMyMembership() === "join";
|
||||
});
|
||||
|
@ -624,6 +626,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
};
|
||||
|
||||
private rebuildMetaSpaces = (): void => {
|
||||
if (!this.matrixClient) return;
|
||||
const enabledMetaSpaces = new Set(this.enabledMetaSpaces);
|
||||
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
|
||||
|
||||
|
@ -658,6 +661,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
};
|
||||
|
||||
private updateNotificationStates = (spaces?: SpaceKey[]): void => {
|
||||
if (!this.matrixClient) return;
|
||||
const enabledMetaSpaces = new Set(this.enabledMetaSpaces);
|
||||
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
|
||||
|
||||
|
@ -745,6 +749,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
|||
};
|
||||
|
||||
private onRoomsUpdate = (): void => {
|
||||
if (!this.matrixClient) return;
|
||||
const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor);
|
||||
|
||||
const prevRoomsBySpace = this.roomIdsBySpace;
|
||||
|
|
|
@ -133,7 +133,7 @@ describe("ThreadPanel", () => {
|
|||
jest.spyOn(mockClient, "getRoom").mockReturnValue(room);
|
||||
await room.createThreadsTimelineSets();
|
||||
const [allThreads, myThreads] = room.threadsTimelineSets;
|
||||
jest.spyOn(room, "createThreadsTimelineSets").mockReturnValue(Promise.resolve([allThreads, myThreads]));
|
||||
jest.spyOn(room, "createThreadsTimelineSets").mockReturnValue(Promise.resolve([allThreads!, myThreads!]));
|
||||
});
|
||||
|
||||
function toggleThreadFilter(container: HTMLElement, newFilter: ThreadFilterType) {
|
||||
|
@ -195,11 +195,11 @@ describe("ThreadPanel", () => {
|
|||
return event ? Promise.resolve(event) : Promise.reject();
|
||||
});
|
||||
const [allThreads, myThreads] = room.threadsTimelineSets;
|
||||
allThreads.addLiveEvent(otherThread.rootEvent);
|
||||
allThreads.addLiveEvent(mixedThread.rootEvent);
|
||||
allThreads.addLiveEvent(ownThread.rootEvent);
|
||||
myThreads.addLiveEvent(mixedThread.rootEvent);
|
||||
myThreads.addLiveEvent(ownThread.rootEvent);
|
||||
allThreads!.addLiveEvent(otherThread.rootEvent);
|
||||
allThreads!.addLiveEvent(mixedThread.rootEvent);
|
||||
allThreads!.addLiveEvent(ownThread.rootEvent);
|
||||
myThreads!.addLiveEvent(mixedThread.rootEvent);
|
||||
myThreads!.addLiveEvent(ownThread.rootEvent);
|
||||
|
||||
let events: EventData[] = [];
|
||||
const renderResult = render(<TestThreadPanel />);
|
||||
|
@ -245,7 +245,7 @@ describe("ThreadPanel", () => {
|
|||
return event ? Promise.resolve(event) : Promise.reject();
|
||||
});
|
||||
const [allThreads] = room.threadsTimelineSets;
|
||||
allThreads.addLiveEvent(otherThread.rootEvent);
|
||||
allThreads!.addLiveEvent(otherThread.rootEvent);
|
||||
|
||||
let events: EventData[] = [];
|
||||
const renderResult = render(<TestThreadPanel />);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue