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

Commit 054560b

Browse files
authored
Merge pull request #5435 from matrix-org/travis/window-widgets
Support arbitrary widgets sticking to the screen + sending stickers
2 parents 56ffa17 + 43be434 commit 054560b

File tree

6 files changed

+46
-61
lines changed

6 files changed

+46
-61
lines changed

src/components/views/elements/AppTile.js

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import PropTypes from 'prop-types';
2323
import {MatrixClientPeg} from '../../../MatrixClientPeg';
2424
import AccessibleButton from './AccessibleButton';
2525
import { _t } from '../../../languageHandler';
26-
import * as sdk from '../../../index';
2726
import AppPermission from './AppPermission';
2827
import AppWarning from './AppWarning';
2928
import Spinner from './Spinner';
@@ -375,19 +374,18 @@ export default class AppTile extends React.Component {
375374
/>
376375
</div>
377376
);
378-
// if the widget would be allowed to remain on screen, we must put it in
379-
// a PersistedElement from the get-go, otherwise the iframe will be
380-
// re-mounted later when we do.
381-
if (this.props.whitelistCapabilities.includes('m.always_on_screen')) {
382-
const PersistedElement = sdk.getComponent("elements.PersistedElement");
383-
// Also wrap the PersistedElement in a div to fix the height, otherwise
384-
// AppTile's border is in the wrong place
385-
appTileBody = <div className="mx_AppTile_persistedWrapper">
386-
<PersistedElement persistKey={this._persistKey}>
387-
{appTileBody}
388-
</PersistedElement>
389-
</div>;
390-
}
377+
378+
// all widgets can theoretically be allowed to remain on screen, so we wrap
379+
// them all in a PersistedElement from the get-go. If we wait, the iframe will
380+
// be re-mounted later, which means the widget has to start over, which is bad.
381+
382+
// Also wrap the PersistedElement in a div to fix the height, otherwise
383+
// AppTile's border is in the wrong place
384+
appTileBody = <div className="mx_AppTile_persistedWrapper">
385+
<PersistedElement persistKey={this._persistKey}>
386+
{appTileBody}
387+
</PersistedElement>
388+
</div>;
391389
}
392390
}
393391

@@ -474,10 +472,6 @@ AppTile.propTypes = {
474472
handleMinimisePointerEvents: PropTypes.bool,
475473
// Optionally hide the popout widget icon
476474
showPopout: PropTypes.bool,
477-
// Widget capabilities to allow by default (without user confirmation)
478-
// NOTE -- Use with caution. This is intended to aid better integration / UX
479-
// basic widget capabilities, e.g. injecting sticker message events.
480-
whitelistCapabilities: PropTypes.array,
481475
// Is this an instance of a user widget
482476
userWidget: PropTypes.bool,
483477
};
@@ -488,7 +482,6 @@ AppTile.defaultProps = {
488482
showTitle: true,
489483
showPopout: true,
490484
handleMinimisePointerEvents: false,
491-
whitelistCapabilities: [],
492485
userWidget: false,
493486
miniMode: false,
494487
};

src/components/views/elements/PersistentApp.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ export default class PersistentApp extends React.Component {
7171
appEvent.getStateKey(), appEvent.getContent(), appEvent.getSender(),
7272
persistentWidgetInRoomId, appEvent.getId(),
7373
);
74-
const capWhitelist = WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, persistentWidgetInRoomId);
7574
const AppTile = sdk.getComponent('elements.AppTile');
7675
return <AppTile
7776
key={app.id}
@@ -82,7 +81,6 @@ export default class PersistentApp extends React.Component {
8281
creatorUserId={app.creatorUserId}
8382
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
8483
waitForIframeLoad={app.waitForIframeLoad}
85-
whitelistCapabilities={capWhitelist}
8684
miniMode={true}
8785
showMenubar={false}
8886
/>;

src/components/views/right_panel/WidgetCard.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ const WidgetCard: React.FC<IProps> = ({ room, widgetId, onClose }) => {
103103
creatorUserId={app.creatorUserId}
104104
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
105105
waitForIframeLoad={app.waitForIframeLoad}
106-
whitelistCapabilities={WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, room.roomId)}
107106
/>
108107
</BaseCard>;
109108
};

src/components/views/rooms/AppsDrawer.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,6 @@ export default class AppsDrawer extends React.Component {
210210
if (!this.props.showApps) return <div />;
211211

212212
const apps = this.state.apps.map((app, index, arr) => {
213-
const capWhitelist = WidgetUtils.getCapWhitelistForAppTypeInRoomId(app.type, this.props.room.roomId);
214-
215213
return (<AppTile
216214
key={app.id}
217215
app={app}
@@ -221,7 +219,6 @@ export default class AppsDrawer extends React.Component {
221219
creatorUserId={app.creatorUserId}
222220
widgetPageTitle={WidgetUtils.getWidgetDataTitle(app)}
223221
waitForIframeLoad={app.waitForIframeLoad}
224-
whitelistCapabilities={capWhitelist}
225222
/>);
226223
});
227224

src/components/views/rooms/Stickerpicker.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ export default class Stickerpicker extends React.Component {
280280
showPopout={false}
281281
onMinimiseClick={this._onHideStickersClick}
282282
handleMinimisePointerEvents={true}
283-
whitelistCapabilities={['m.sticker', 'visibility']}
284283
userWidget={true}
285284
/>
286285
</PersistedElement>

src/stores/widgets/StopGapWidget.ts

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ interface IAppTileProps {
7575

7676
// TODO: Don't use this because it's wrong
7777
class ElementWidget extends Widget {
78-
constructor(w) {
79-
super(w);
78+
constructor(private rawDefinition: IWidget) {
79+
super(rawDefinition);
8080
}
8181

8282
public get templateUrl(): string {
@@ -137,12 +137,7 @@ class ElementWidget extends Widget {
137137

138138
public getCompleteUrl(params: ITemplateParams, asPopout=false): string {
139139
return runTemplate(asPopout ? this.popoutTemplateUrl : this.templateUrl, {
140-
// we need to supply a whole widget to the template, but don't have
141-
// easy access to the definition the superclass is using, so be sad
142-
// and gutwrench it.
143-
// This isn't a problem when the widget architecture is fixed and this
144-
// subclass gets deleted.
145-
...super['definition'], // XXX: Private member access
140+
...this.rawDefinition,
146141
data: this.rawData,
147142
}, params);
148143
}
@@ -351,18 +346,39 @@ export class StopGapWidget extends EventEmitter {
351346
MatrixClientPeg.get().on('event', this.onEvent);
352347
MatrixClientPeg.get().on('Event.decrypted', this.onEventDecrypted);
353348

354-
if (WidgetType.JITSI.matches(this.mockWidget.type)) {
355-
this.messaging.on("action:set_always_on_screen",
356-
(ev: CustomEvent<IStickyActionRequest>) => {
357-
if (this.messaging.hasCapability(MatrixCapabilities.AlwaysOnScreen)) {
349+
this.messaging.on(`action:${WidgetApiFromWidgetAction.UpdateAlwaysOnScreen}`,
350+
(ev: CustomEvent<IStickyActionRequest>) => {
351+
if (this.messaging.hasCapability(MatrixCapabilities.AlwaysOnScreen)) {
352+
if (WidgetType.JITSI.matches(this.mockWidget.type)) {
358353
CountlyAnalytics.instance.trackJoinCall(this.appTileProps.room.roomId, true, true);
359-
ActiveWidgetStore.setWidgetPersistence(this.mockWidget.id, ev.detail.data.value);
360-
ev.preventDefault();
361-
this.messaging.transport.reply(ev.detail, <IWidgetApiRequestEmptyData>{}); // ack
362354
}
363-
},
364-
);
365-
} else if (WidgetType.STICKERPICKER.matches(this.mockWidget.type)) {
355+
ActiveWidgetStore.setWidgetPersistence(this.mockWidget.id, ev.detail.data.value);
356+
ev.preventDefault();
357+
this.messaging.transport.reply(ev.detail, <IWidgetApiRequestEmptyData>{}); // ack
358+
}
359+
},
360+
);
361+
362+
// TODO: Replace this event listener with appropriate driver functionality once the API
363+
// establishes a sane way to send events back and forth.
364+
this.messaging.on(`action:${WidgetApiFromWidgetAction.SendSticker}`,
365+
(ev: CustomEvent<IStickerActionRequest>) => {
366+
if (this.messaging.hasCapability(MatrixCapabilities.StickerSending)) {
367+
// Acknowledge first
368+
ev.preventDefault();
369+
this.messaging.transport.reply(ev.detail, <IWidgetApiRequestEmptyData>{});
370+
371+
// Send the sticker
372+
defaultDispatcher.dispatch({
373+
action: 'm.sticker',
374+
data: ev.detail.data,
375+
widgetId: this.mockWidget.id,
376+
});
377+
}
378+
},
379+
);
380+
381+
if (WidgetType.STICKERPICKER.matches(this.mockWidget.type)) {
366382
this.messaging.on(`action:${ElementWidgetActions.OpenIntegrationManager}`,
367383
(ev: CustomEvent<IWidgetApiRequest>) => {
368384
// Acknowledge first
@@ -394,23 +410,6 @@ export class StopGapWidget extends EventEmitter {
394410
}
395411
},
396412
);
397-
398-
// TODO: Replace this event listener with appropriate driver functionality once the API
399-
// establishes a sane way to send events back and forth.
400-
this.messaging.on(`action:${WidgetApiFromWidgetAction.SendSticker}`,
401-
(ev: CustomEvent<IStickerActionRequest>) => {
402-
// Acknowledge first
403-
ev.preventDefault();
404-
this.messaging.transport.reply(ev.detail, <IWidgetApiRequestEmptyData>{});
405-
406-
// Send the sticker
407-
defaultDispatcher.dispatch({
408-
action: 'm.sticker',
409-
data: ev.detail.data,
410-
widgetId: this.mockWidget.id,
411-
});
412-
},
413-
);
414413
}
415414
}
416415

0 commit comments

Comments
 (0)