Merge branch 'develop' into matthew/slate

This commit is contained in:
Matthew Hodgson 2018-05-15 01:00:07 +01:00
commit b60ccad29b
24 changed files with 340 additions and 50 deletions

View file

@ -85,7 +85,7 @@ export default class AppTile extends React.Component {
/**
* Does the widget support a given capability
* @param {[type]} capability Capability to check for
* @param {string} capability Capability to check for
* @return {Boolean} True if capability supported
*/
_hasCapability(capability) {
@ -364,9 +364,7 @@ export default class AppTile extends React.Component {
if (!this.widgetMessaging) {
this._onInitialLoad();
}
if (this._exposeWidgetMessaging) {
this._exposeWidgetMessaging(this.widgetMessaging);
}
this.setState({loading: false});
}
/**
@ -404,8 +402,6 @@ export default class AppTile extends React.Component {
}).catch((err) => {
console.log(`Failed to get capabilities for widget type ${this.props.type}`, this.props.id, err);
});
this.setState({loading: false});
}
_onWidgetAction(payload) {
@ -607,7 +603,7 @@ export default class AppTile extends React.Component {
}
// Picture snapshot - only show button when apps are maximised.
const showPictureSnapshotButton = this._hasCapability('screenshot') && this.props.show;
const showPictureSnapshotButton = this._hasCapability('m.capability.screenshot') && this.props.show;
const showPictureSnapshotIcon = 'img/camera_green.svg';
const popoutWidgetIcon = 'img/button-new-window.svg';
const windowStateIcon = (this.props.show ? 'img/minimize.svg' : 'img/maximize.svg');
@ -711,7 +707,7 @@ AppTile.propTypes = {
showDelete: PropTypes.bool,
// Optionally hide the popout widget icon
showPopout: PropTypes.bool,
// Widget apabilities to allow by default (without user confirmation)
// Widget capabilities to allow by default (without user confirmation)
// NOTE -- Use with caution. This is intended to aid better integration / UX
// basic widget capabilities, e.g. injecting sticker message events.
whitelistCapabilities: PropTypes.array,

View file

@ -107,6 +107,16 @@ export default class MStickerBody extends MImageBody {
placeholderFixupHeight = content.info.h + 'px';
}
// The pixel size of sticker images is generally larger than their intended display
// size so they render at native reolution on HiDPI displays. We therefore need to
// explicity set the size so they render at the intended size.
// XXX: This will be clobberred when we run fixupHeight(), but we need to do it
// here otherwise the stickers are momentarily displayed at the pixel size.
const imageStyle = {
height: content.info.h,
// leave the browser the calculate the width automatically
};
placeholderSize = placeholderSize + 'px';
// Body 'ref' required by MImageBody
@ -132,6 +142,7 @@ export default class MStickerBody extends MImageBody {
<img
className={'mx_MStickerBody_image ' + this.state.imageClasses}
src={contentUrl}
style={imageStyle}
ref='image'
alt={content.body}
onLoad={this._onImageLoad}

View file

@ -227,6 +227,8 @@ module.exports = React.createClass({
},
render: function() {
const enableScreenshots = SettingsStore.getValue("enableWidgetScreenshots", this.props.room.room_id);
const apps = this.state.apps.map(
(app, index, arr) => {
return (<AppTile
@ -242,6 +244,7 @@ module.exports = React.createClass({
creatorUserId={app.creatorUserId}
widgetPageTitle={(app.data && app.data.title) ? app.data.title : ''}
waitForIframeLoad={app.waitForIframeLoad}
whitelistCapabilities={enableScreenshots ? ["m.capability.screenshot"] : []}
/>);
});

View file

@ -34,6 +34,7 @@ export default class Stickerpicker extends React.Component {
this._onHideStickersClick = this._onHideStickersClick.bind(this);
this._launchManageIntegrations = this._launchManageIntegrations.bind(this);
this._removeStickerpickerWidgets = this._removeStickerpickerWidgets.bind(this);
this._updateWidget = this._updateWidget.bind(this);
this._onWidgetAction = this._onWidgetAction.bind(this);
this._onResize = this._onResize.bind(this);
this._onFinished = this._onFinished.bind(this);
@ -90,11 +91,12 @@ export default class Stickerpicker extends React.Component {
if (!this.state.imError) {
this.dispatcherRef = dis.register(this._onWidgetAction);
}
const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0];
this.setState({
stickerpickerWidget,
widgetId: stickerpickerWidget ? stickerpickerWidget.id : null,
});
// Track updates to widget state in account data
MatrixClientPeg.get().on('accountData', this._updateWidget);
// Initialise widget state from current account data
this._updateWidget();
}
componentWillUnmount() {
@ -116,11 +118,28 @@ export default class Stickerpicker extends React.Component {
});
}
_updateWidget() {
const stickerpickerWidget = Widgets.getStickerpickerWidgets()[0];
this.setState({
stickerpickerWidget,
widgetId: stickerpickerWidget ? stickerpickerWidget.id : null,
});
}
_onWidgetAction(payload) {
if (payload.action === "user_widget_updated") {
this.forceUpdate();
} else if (payload.action === "stickerpicker_close") {
this.setState({showStickers: false});
switch (payload.action) {
case "user_widget_updated":
this.forceUpdate();
break;
case "stickerpicker_close":
this.setState({showStickers: false});
break;
case "show_right_panel":
case "hide_right_panel":
case "show_left_panel":
case "hide_left_panel":
this.setState({showStickers: false});
break;
}
}
@ -223,7 +242,6 @@ export default class Stickerpicker extends React.Component {
);
} else {
// Default content to show if stickerpicker widget not added
console.warn("No available sticker picker widgets");
stickersContent = this._defaultStickerpickerContent();
}
return stickersContent;
@ -235,16 +253,33 @@ export default class Stickerpicker extends React.Component {
* @param {Event} e Event that triggered the function
*/
_onShowStickersClick(e) {
// XXX: Simplify by using a context menu that is positioned relative to the sticker picker button
const buttonRect = e.target.getBoundingClientRect();
// The window X and Y offsets are to adjust position when zoomed in to page
const x = buttonRect.right + window.pageXOffset - 42;
let x = buttonRect.right + window.pageXOffset - 41;
// Amount of horizontal space between the right of menu and the right of the viewport
// (10 = amount needed to make chevron centrally aligned)
const rightPad = 10;
// When the sticker picker would be displayed off of the viewport, adjust x
// (302 = width of context menu, including borders)
x = Math.min(x, document.body.clientWidth - (302 + rightPad));
// Offset the chevron location, which is relative to the left of the context menu
// (10 = offset when context menu would not be displayed off viewport)
// (8 = value required in practice (possibly 10 - 2 where the 2 = context menu borders)
const stickerPickerChevronOffset = Math.max(10, 8 + window.pageXOffset + buttonRect.left - x);
const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19;
this.setState({
showStickers: true,
stickerPickerX: x,
stickerPickerY: y,
stickerPickerChevronOffset,
});
}
@ -297,7 +332,7 @@ export default class Stickerpicker extends React.Component {
const stickerPicker = <ContextualMenu
elementClass={GenericElementContextMenu}
chevronOffset={10}
chevronOffset={this.state.stickerPickerChevronOffset}
chevronFace={'bottom'}
left={this.state.stickerPickerX}
top={this.state.stickerPickerY}