Move state update listeners from constructor to componentDidMount (#28341)

* Move state update listeners from constructor to componentDidMount

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2024-11-01 17:39:08 +00:00
committed by GitHub
parent 2d9982f9f0
commit 0899165d9e
72 changed files with 377 additions and 309 deletions

View File

@@ -134,29 +134,20 @@ export default class AppTile extends React.Component<IProps, IState> {
private iframe?: HTMLIFrameElement; // ref to the iframe (callback style)
private allowedWidgetsWatchRef?: string;
private persistKey: string;
private sgWidget: StopGapWidget | null;
private sgWidget?: StopGapWidget;
private dispatcherRef?: string;
private unmounted = false;
public constructor(props: IProps, context: ContextType<typeof MatrixClientContext>) {
super(props, context);
// Tiles in miniMode are floating, and therefore not docked
if (!this.props.miniMode) {
ActiveWidgetStore.instance.dockWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
}
// The key used for PersistedElement
this.persistKey = getPersistKey(WidgetUtils.getWidgetUid(this.props.app));
try {
this.sgWidget = new StopGapWidget(this.props);
this.setupSgListeners();
} catch (e) {
logger.log("Failed to construct widget", e);
this.sgWidget = null;
this.sgWidget = undefined;
}
this.state = this.getNewState(props);
@@ -303,6 +294,20 @@ export default class AppTile extends React.Component<IProps, IState> {
}
public componentDidMount(): void {
this.unmounted = false;
// Tiles in miniMode are floating, and therefore not docked
if (!this.props.miniMode) {
ActiveWidgetStore.instance.dockWidget(
this.props.app.id,
isAppWidget(this.props.app) ? this.props.app.roomId : null,
);
}
if (this.sgWidget) {
this.setupSgListeners();
}
// Only fetch IM token on mount if we're showing and have permission to load
if (this.sgWidget && this.state.hasPermissionToLoad) {
this.startWidget();
@@ -374,7 +379,7 @@ export default class AppTile extends React.Component<IProps, IState> {
this.startWidget();
} catch (e) {
logger.error("Failed to construct widget", e);
this.sgWidget = null;
this.sgWidget = undefined;
}
}
@@ -607,7 +612,7 @@ export default class AppTile extends React.Component<IProps, IState> {
};
public render(): React.ReactNode {
let appTileBody: JSX.Element;
let appTileBody: JSX.Element | undefined;
// Note that there is advice saying allow-scripts shouldn't be used with allow-same-origin
// because that would allow the iframe to programmatically remove the sandbox attribute, but
@@ -650,7 +655,7 @@ export default class AppTile extends React.Component<IProps, IState> {
<AppWarning errorMsg={_t("widget|error_loading")} />
</div>
);
} else if (!this.state.hasPermissionToLoad && this.props.room) {
} else if (!this.state.hasPermissionToLoad && this.props.room && this.sgWidget) {
// only possible for room widgets, can assert this.props.room here
const isEncrypted = this.context.isRoomEncrypted(this.props.room.roomId);
appTileBody = (
@@ -677,7 +682,7 @@ export default class AppTile extends React.Component<IProps, IState> {
<AppWarning errorMsg={_t("widget|error_mixed_content")} />
</div>
);
} else {
} else if (this.sgWidget) {
appTileBody = (
<>
<div className={appTileBodyClass} style={appTileBodyStyles}>

View File

@@ -41,10 +41,6 @@ export interface ExistingSourceIProps {
}
export class ExistingSource extends React.Component<ExistingSourceIProps> {
public constructor(props: ExistingSourceIProps) {
super(props);
}
private onClick = (): void => {
this.props.onSelect(this.props.source);
};

View File

@@ -127,7 +127,9 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
// the current search query
searchQuery: "",
};
}
public componentDidMount(): void {
// Listen for all clicks on the document so we can close the
// menu when the user clicks somewhere else
document.addEventListener("click", this.onDocumentClick, false);

View File

@@ -15,10 +15,6 @@ interface IProps extends Omit<React.ComponentProps<typeof TextWithTooltip>, "tab
}
export default class LinkWithTooltip extends React.Component<IProps> {
public constructor(props: IProps) {
super(props);
}
public render(): React.ReactNode {
const { children, tooltip, ...props } = this.props;

View File

@@ -79,7 +79,7 @@ interface IProps {
*/
export default class PersistedElement extends React.Component<IProps> {
private resizeObserver: ResizeObserver;
private dispatcherRef: string;
private dispatcherRef?: string;
private childContainer?: HTMLDivElement;
private child?: HTMLDivElement;
@@ -87,13 +87,6 @@ export default class PersistedElement extends React.Component<IProps> {
super(props);
this.resizeObserver = new ResizeObserver(this.repositionChild);
// Annoyingly, a resize observer is insufficient, since we also care
// about when the element moves on the screen without changing its
// dimensions. Doesn't look like there's a ResizeObserver equivalent
// for this, so we bodge it by listening for document resize and
// the timeline_resize action.
window.addEventListener("resize", this.repositionChild);
this.dispatcherRef = dis.register(this.onAction);
if (this.props.moveRef) this.props.moveRef.current = this.repositionChild;
}
@@ -132,6 +125,14 @@ export default class PersistedElement extends React.Component<IProps> {
};
public componentDidMount(): void {
// Annoyingly, a resize observer is insufficient, since we also care
// about when the element moves on the screen without changing its
// dimensions. Doesn't look like there's a ResizeObserver equivalent
// for this, so we bodge it by listening for document resize and
// the timeline_resize action.
window.addEventListener("resize", this.repositionChild);
this.dispatcherRef = dis.register(this.onAction);
this.updateChild();
this.renderApp();
}

View File

@@ -68,6 +68,7 @@ export default class PowerSelector<K extends undefined | string> extends React.C
}
public componentDidMount(): void {
this.unmounted = false;
this.initStateFromProps();
}

View File

@@ -89,6 +89,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
}
public componentDidMount(): void {
this.unmounted = false;
this.initialize();
this.trySetExpandableQuotes();
}

View File

@@ -16,10 +16,6 @@ interface IProps extends HTMLAttributes<HTMLSpanElement> {
}
export default class TextWithTooltip extends React.Component<IProps> {
public constructor(props: IProps) {
super(props);
}
public render(): React.ReactNode {
const { className, children, tooltip, tooltipProps } = this.props;