Prevent flicker.

This commit is contained in:
Will Hunt 2025-07-15 15:23:10 +01:00
parent 09261c53b8
commit e0d176790c
3 changed files with 35 additions and 28 deletions

View File

@ -606,19 +606,24 @@ function DownloadButton({
setCanDownload(true);
return;
}
// Get the hint. If the hint is static then we can immediately set it,
// otherwise set to false until the promise completes.
const hints = ModuleApi.customComponents.getHintsForMessage(mxEvent);
// Disable downloading as soon as we know there is a hint.
setCanDownload(false);
hints
.allowDownloadingMedia()
.then((downloadable) => {
setCanDownload(downloadable);
})
.catch((ex) => {
logger.error(`Failed to check if media from ${mxEvent.getId()} could be downloaded`, ex);
// Err on the side of safety.
setCanDownload(false);
});
if (typeof hints.allowDownloadingMedia === "boolean") {
setCanDownload(hints.allowDownloadingMedia);
} else {
setCanDownload(false);
hints
.allowDownloadingMedia()
.then((downloadable) => {
setCanDownload(downloadable);
})
.catch((ex) => {
logger.error(`Failed to check if media from ${mxEvent.getId()} could be downloaded`, ex);
// Err on the side of safety.
setCanDownload(false);
});
}
}, [mxEvent]);
function showError(e: unknown): void {

View File

@ -43,21 +43,23 @@ export default class DownloadActionButton extends React.PureComponent<IProps, IS
public constructor(props: IProps) {
super(props);
const moduleHints = ModuleApi.customComponents.getHintsForMessage(props.mxEvent);
const hints = ModuleApi.customComponents.getHintsForMessage(props.mxEvent);
const downloadState: Pick<IState, "canDownload"> = { canDownload: null };
moduleHints
.allowDownloadingMedia()
.then((canDownload) => {
this.setState({
canDownload,
if (typeof hints.allowDownloadingMedia === "boolean") {
downloadState.canDownload = hints.allowDownloadingMedia;
} else {
downloadState.canDownload = false;
hints
.allowDownloadingMedia()
.then((downloadable) => {
this.setState({ canDownload: downloadable });
})
.catch((ex) => {
logger.error(`Failed to check if media from ${props.mxEvent.getId()} could be downloaded`, ex);
// Err on the side of safety.
this.setState({ canDownload: false });
});
})
.catch((ex) => {
logger.error(`Failed to check if media from ${props.mxEvent.getId()} could be downloaded`, ex);
this.setState({
canDownload: false,
});
});
}
this.state = {
loading: false,

View File

@ -31,13 +31,13 @@ interface CustomMessageComponentProps extends Omit<ModuleCustomMessageComponentP
}
interface CustomMessageRenderHints extends Omit<ModuleCustomCustomMessageRenderHints, "allowDownloadingMedia"> {
// Note. This just makes it easier to use this API on Element Web as we already have the moduleized event stored.
allowDownloadingMedia?: () => Promise<boolean>;
// Note. This just makes it easier to use this API on Element Web as we already have the modularized event stored.
allowDownloadingMedia?: (() => Promise<boolean>) | boolean;
}
const DEFAULT_HINTS: Required<CustomMessageRenderHints> = {
allowEditingEvent: true,
allowDownloadingMedia: () => Promise.resolve(true),
allowDownloadingMedia: true,
};
export class CustomComponentsApi implements ICustomComponentsApi {