Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Implement RequiresClient capability for widgets #7005

Merged
merged 10 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"linkifyjs": "^2.1.9",
"lodash": "^4.17.20",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-widget-api": "^0.1.0-beta.16",
"matrix-widget-api": "^0.1.0-beta.17",
"minimist": "^1.2.5",
"opus-recorder": "^8.0.3",
"pako": "^2.0.3",
Expand Down
21 changes: 17 additions & 4 deletions src/components/views/elements/AppTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ interface IState {
error: Error;
menuDisplayed: boolean;
widgetPageTitle: string;
requiresClient: boolean;
}

import { logger } from "matrix-js-sdk/src/logger";
Expand Down Expand Up @@ -114,8 +115,10 @@ export default class AppTile extends React.Component<IProps, IState> {
this.persistKey = getPersistKey(this.props.app.id);
try {
this.sgWidget = new StopGapWidget(this.props);
this.sgWidget.on("preparing", this.onWidgetPrepared);
this.sgWidget.on("preparing", this.onWidgetPreparing);
this.sgWidget.on("ready", this.onWidgetReady);
// emits when the capabilites have been setup or changed
this.sgWidget.on("capabilitiesNotified", this.onWidgetCapabilitiesNotified);
} catch (e) {
logger.log("Failed to construct widget", e);
this.sgWidget = null;
Expand Down Expand Up @@ -155,6 +158,10 @@ export default class AppTile extends React.Component<IProps, IState> {
error: null,
menuDisplayed: false,
widgetPageTitle: this.props.widgetPageTitle,
// requiresClient is initially set to true. This avoids the broken state of the popout
// button being visible (for an instance) and than disappearing when the widget is loaded.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// button being visible (for an instance) and than disappearing when the widget is loaded.
// button being visible (for an instance) and then disappearing when the widget is loaded.

// requiresClient <-> hide the popout button
requiresClient: true,
jryans marked this conversation as resolved.
Show resolved Hide resolved
};
}

Expand Down Expand Up @@ -216,7 +223,7 @@ export default class AppTile extends React.Component<IProps, IState> {
}
try {
this.sgWidget = new StopGapWidget(newProps);
this.sgWidget.on("preparing", this.onWidgetPrepared);
this.sgWidget.on("preparing", this.onWidgetPreparing);
this.sgWidget.on("ready", this.onWidgetReady);
this.startWidget();
} catch (e) {
Expand Down Expand Up @@ -287,7 +294,7 @@ export default class AppTile extends React.Component<IProps, IState> {
if (this.sgWidget) this.sgWidget.stop({ forceDestroy: true });
}

private onWidgetPrepared = (): void => {
private onWidgetPreparing = (): void => {
this.setState({ loading: false });
};

Expand All @@ -297,6 +304,12 @@ export default class AppTile extends React.Component<IProps, IState> {
}
};

private onWidgetCapabilitiesNotified = (): void => {
this.setState({
jryans marked this conversation as resolved.
Show resolved Hide resolved
requiresClient: this.sgWidget.widgetApi.hasCapability(MatrixCapabilities.RequiresClient),
});
};

private onAction = (payload): void => {
if (payload.widgetId === this.props.app.id) {
switch (payload.action) {
Expand Down Expand Up @@ -512,7 +525,7 @@ export default class AppTile extends React.Component<IProps, IState> {
{ this.props.showTitle && this.getTileTitle() }
</span>
<span className="mx_AppTileMenuBarWidgets">
{ this.props.showPopout && <AccessibleButton
{ (this.props.showPopout && !this.state.requiresClient) && <AccessibleButton
className="mx_AppTileMenuBar_iconButton mx_AppTileMenuBar_iconButton_popout"
title={_t('Popout widget')}
onClick={this.onPopoutWidgetClick}
Expand Down
5 changes: 3 additions & 2 deletions src/stores/widgets/StopGapWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ export class ElementWidget extends Widget {
};
}

public getCompleteUrl(params: ITemplateParams, asPopout=false): string {
public getCompleteUrl(params: ITemplateParams, asPopout = false): string {
return runTemplate(asPopout ? this.popoutTemplateUrl : this.templateUrl, {
...this.rawDefinition,
data: this.rawData,
Expand All @@ -149,7 +149,7 @@ export class StopGapWidget extends EventEmitter {
private scalarToken: string;
private roomId?: string;
private kind: WidgetKind;
private readUpToMap: {[roomId: string]: string} = {}; // room ID to event ID
private readUpToMap: { [roomId: string]: string } = {}; // room ID to event ID

constructor(private appTileProps: IAppTileProps) {
super();
Expand Down Expand Up @@ -262,6 +262,7 @@ export class StopGapWidget extends EventEmitter {
this.messaging = new ClientWidgetApi(this.mockWidget, iframe, driver);
this.messaging.on("preparing", () => this.emit("preparing"));
this.messaging.on("ready", () => this.emit("ready"));
this.messaging.on("capabilitiesNotified", () => this.emit("capabilitiesNotified"));
this.messaging.on(`action:${WidgetApiFromWidgetAction.OpenModalWidget}`, this.onOpenModal);
WidgetMessagingStore.instance.storeMessaging(this.mockWidget, this.messaging);

Expand Down
4 changes: 3 additions & 1 deletion src/stores/widgets/StopGapWidgetDriver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ export class StopGapWidgetDriver extends WidgetDriver {
// Always allow screenshots to be taken because it's a client-induced flow. The widget can't
// spew screenshots at us and can't request screenshots of us, so it's up to us to provide the
// button if the widget says it supports screenshots.
this.allowedCapabilities = new Set([...allowedCapabilities, MatrixCapabilities.Screenshots]);
this.allowedCapabilities = new Set([...allowedCapabilities,
MatrixCapabilities.Screenshots,
MatrixCapabilities.RequiresClient]);

// Grant the permissions that are specific to given widget types
if (WidgetType.JITSI.matches(this.forWidget.type) && forWidgetKind === WidgetKind.Room) {
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5905,10 +5905,10 @@ matrix-react-test-utils@^0.2.3:
"@babel/traverse" "^7.13.17"
walk "^2.3.14"

matrix-widget-api@^0.1.0-beta.16:
version "0.1.0-beta.16"
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.16.tgz#32655f05cab48239b97fe4111a1d0858f2aad61a"
integrity sha512-9zqaNLaM14YDHfFb7WGSUOivGOjYw+w5Su84ZfOl6A4IUy1xT9QPp0nsSA8wNfz0LpxOIPn3nuoF8Tn/40F5tg==
matrix-widget-api@^0.1.0-beta.17:
version "0.1.0-beta.17"
resolved "https://registry.yarnpkg.com/matrix-widget-api/-/matrix-widget-api-0.1.0-beta.17.tgz#392be2bf42990e8f7e16aeadf2546f18681af49b"
integrity sha512-hyaDLQNvGvV67Ss23vI69y/ZwVMVz2160LJ2nYyhO0C4mk9zTl0Rbe9jNQ9B453V8MadHLiUUdjzoe++WW+6jA==
dependencies:
"@types/events" "^3.0.0"
events "^3.2.0"
Expand Down