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:
committed by
GitHub
parent
2d9982f9f0
commit
0899165d9e
@@ -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}>
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ export default class PowerSelector<K extends undefined | string> extends React.C
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.unmounted = false;
|
||||
this.initStateFromProps();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +89,7 @@ export default class ReplyChain extends React.Component<IProps, IState> {
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.unmounted = false;
|
||||
this.initialize();
|
||||
this.trySetExpandableQuotes();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user