Obliterate widgets when they are minimized

Fixes https://github.com/vector-im/riot-web/issues/12810

We do this to all widgets as we can't guarantee what sorts of other widgets might need similar treatment.
pull/21833/head
Travis Ralston 2020-04-09 14:31:46 -06:00
parent 74291e8c2d
commit db3c7a8f1c
1 changed files with 33 additions and 14 deletions

View File

@ -269,7 +269,9 @@ export default class AppTile extends React.Component {
if (this.props.show && this.state.hasPermissionToLoad) { if (this.props.show && this.state.hasPermissionToLoad) {
this.setScalarToken(); this.setScalarToken();
} }
} else if (nextProps.show && !this.props.show) { }
if (nextProps.show && !this.props.show) {
// We assume that persisted widgets are loaded and don't need a spinner. // We assume that persisted widgets are loaded and don't need a spinner.
if (this.props.waitForIframeLoad && !PersistedElement.isMounted(this._persistKey)) { if (this.props.waitForIframeLoad && !PersistedElement.isMounted(this._persistKey)) {
this.setState({ this.setState({
@ -280,7 +282,9 @@ export default class AppTile extends React.Component {
if (this.state.hasPermissionToLoad) { if (this.state.hasPermissionToLoad) {
this.setScalarToken(); this.setScalarToken();
} }
} else if (nextProps.widgetPageTitle !== this.props.widgetPageTitle) { }
if (nextProps.widgetPageTitle !== this.props.widgetPageTitle) {
this.setState({ this.setState({
widgetPageTitle: nextProps.widgetPageTitle, widgetPageTitle: nextProps.widgetPageTitle,
}); });
@ -332,6 +336,28 @@ export default class AppTile extends React.Component {
}); });
} }
/**
* Ends all widget interaction, such as cancelling calls and disabling webcams.
* @private
*/
_endWidgetActions() {
// HACK: This is a really dirty way to ensure that Jitsi cleans up
// its hold on the webcam. Without this, the widget holds a media
// stream open, even after death. See https://github.com/vector-im/riot-web/issues/7351
if (this._appFrame.current) {
// In practice we could just do `+= ''` to trick the browser
// into thinking the URL changed, however I can foresee this
// being optimized out by a browser. Instead, we'll just point
// the iframe at a page that is reasonably safe to use in the
// event the iframe doesn't wink away.
// This is relative to where the Riot instance is located.
this._appFrame.current.src = 'about:blank';
}
// Delete the widget from the persisted store for good measure.
PersistedElement.destroyElement(this._persistKey);
}
/* If user has permission to modify widgets, delete the widget, /* If user has permission to modify widgets, delete the widget,
* otherwise revoke access for the widget to load in the user's browser * otherwise revoke access for the widget to load in the user's browser
*/ */
@ -353,18 +379,7 @@ export default class AppTile extends React.Component {
} }
this.setState({deleting: true}); this.setState({deleting: true});
// HACK: This is a really dirty way to ensure that Jitsi cleans up this._endWidgetActions();
// its hold on the webcam. Without this, the widget holds a media
// stream open, even after death. See https://github.com/vector-im/riot-web/issues/7351
if (this._appFrame.current) {
// In practice we could just do `+= ''` to trick the browser
// into thinking the URL changed, however I can foresee this
// being optimized out by a browser. Instead, we'll just point
// the iframe at a page that is reasonably safe to use in the
// event the iframe doesn't wink away.
// This is relative to where the Riot instance is located.
this._appFrame.current.src = 'about:blank';
}
WidgetUtils.setRoomWidget( WidgetUtils.setRoomWidget(
this.props.room.roomId, this.props.room.roomId,
@ -529,6 +544,10 @@ export default class AppTile extends React.Component {
if (this.props.userWidget) { if (this.props.userWidget) {
this._onMinimiseClick(); this._onMinimiseClick();
} else { } else {
if (this.props.show) {
// if we were being shown, end the widget as we're about to be minimized.
this._endWidgetActions();
}
dis.dispatch({ dis.dispatch({
action: 'appsDrawer', action: 'appsDrawer',
show: !this.props.show, show: !this.props.show,