Unify widget header actions with those in right panel (#7734)
This commit is contained in:
parent
fdbdde83c2
commit
59cdd3edc0
6 changed files with 77 additions and 44 deletions
|
@ -133,8 +133,7 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_RoomSummaryCard_app_pinToggle,
|
.mx_RoomSummaryCard_app_pinToggle,
|
||||||
.mx_RoomSummaryCard_app_maximise,
|
.mx_RoomSummaryCard_app_maximiseToggle,
|
||||||
.mx_RoomSummaryCard_app_minimise,
|
|
||||||
.mx_RoomSummaryCard_app_options {
|
.mx_RoomSummaryCard_app_options {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -176,7 +175,7 @@ limitations under the License.
|
||||||
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
|
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mx_RoomSummaryCard_app_maximise {
|
.mx_RoomSummaryCard_app_maximiseToggle {
|
||||||
right: 32px; //24 + 8
|
right: 32px; //24 + 8
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -184,25 +183,14 @@ limitations under the License.
|
||||||
mask-image: url("$(res)/img/element-icons/maximise-expand.svg");
|
mask-image: url("$(res)/img/element-icons/maximise-expand.svg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.mx_RoomSummaryCard_app_minimise {
|
|
||||||
right: 32px; //24 + 8
|
|
||||||
&::before {
|
|
||||||
mask-size: 14px;
|
|
||||||
mask-image: url("$(res)/img/element-icons/minimise-collapse.svg");
|
|
||||||
background-color: $accent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_RoomSummaryCard_app_options {
|
.mx_RoomSummaryCard_app_options {
|
||||||
right: 32px; //24 + 8
|
right: 56px; //2*24 + 8
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
|
mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
|
||||||
}
|
}
|
||||||
&.mx_RoomSummaryCard_maximised_widget {
|
|
||||||
right: 56px; //2*24 + 8
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_RoomSummaryCard_Button_pinned {
|
&.mx_RoomSummaryCard_Button_pinned {
|
||||||
|
@ -215,6 +203,16 @@ limitations under the License.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.mx_RoomSummaryCard_Button_maximised {
|
||||||
|
&::after {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_RoomSummaryCard_app_maximiseToggle::before {
|
||||||
|
background-color: $accent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.mx_RoomSummaryCard_icon_app {
|
.mx_RoomSummaryCard_icon_app {
|
||||||
padding-right: 72px;
|
padding-right: 72px;
|
||||||
|
|
|
@ -231,14 +231,24 @@ $MinWidth: 240px;
|
||||||
background-color: $topleftmenu-color;
|
background-color: $topleftmenu-color;
|
||||||
margin: 0 5px;
|
margin: 0 5px;
|
||||||
|
|
||||||
&.mx_AppTileMenuBar_iconButton_minWidget {
|
&.mx_AppTileMenuBar_iconButton_close {
|
||||||
mask-size: auto 10px;
|
|
||||||
mask-image: url("$(res)/img/element-icons/minimise-collapse.svg");
|
|
||||||
}
|
|
||||||
|
|
||||||
&.mx_AppTileMenuBar_iconButton_maxWidget {
|
|
||||||
mask-size: auto 10px;
|
mask-size: auto 10px;
|
||||||
mask-image: url("$(res)/img/element-icons/maximise-expand.svg");
|
mask-image: url("$(res)/img/element-icons/maximise-expand.svg");
|
||||||
|
background-color: $accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_AppTileMenuBar_iconButton_maximise {
|
||||||
|
mask-size: auto 10px;
|
||||||
|
mask-image: url("$(res)/img/element-icons/maximise-expand.svg");
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_AppTileMenuBar_iconButton_unpin {
|
||||||
|
mask-image: url("$(res)/img/element-icons/room/pin-upright.svg");
|
||||||
|
background-color: $accent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_AppTileMenuBar_iconButton_pin {
|
||||||
|
mask-image: url("$(res)/img/element-icons/room/pin-upright.svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
&.mx_AppTileMenuBar_iconButton_popout {
|
&.mx_AppTileMenuBar_iconButton_popout {
|
||||||
|
|
|
@ -83,7 +83,7 @@ interface IProps {
|
||||||
// sets the pointer-events property on the iframe
|
// sets the pointer-events property on the iframe
|
||||||
pointerEvents?: string;
|
pointerEvents?: string;
|
||||||
widgetPageTitle?: string;
|
widgetPageTitle?: string;
|
||||||
hideMaximiseButton?: boolean;
|
showLayoutButtons?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -115,6 +115,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
userWidget: false,
|
userWidget: false,
|
||||||
miniMode: false,
|
miniMode: false,
|
||||||
threadId: null,
|
threadId: null,
|
||||||
|
showLayoutButtons: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
private contextMenuButton = createRef<any>();
|
private contextMenuButton = createRef<any>();
|
||||||
|
@ -507,7 +508,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
{ target: '_blank', href: this.sgWidget.popoutUrl, rel: 'noreferrer noopener' }).click();
|
{ target: '_blank', href: this.sgWidget.popoutUrl, rel: 'noreferrer noopener' }).click();
|
||||||
};
|
};
|
||||||
|
|
||||||
private onMaxMinWidgetClick = (): void => {
|
private onToggleMaximisedClick = (): void => {
|
||||||
const targetContainer =
|
const targetContainer =
|
||||||
WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center)
|
WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Center)
|
||||||
? Container.Right
|
? Container.Right
|
||||||
|
@ -515,6 +516,14 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer);
|
WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onTogglePinnedClick = (): void => {
|
||||||
|
const targetContainer =
|
||||||
|
WidgetLayoutStore.instance.isInContainer(this.props.room, this.props.app, Container.Top)
|
||||||
|
? Container.Right
|
||||||
|
: Container.Top;
|
||||||
|
WidgetLayoutStore.instance.moveToContainer(this.props.room, this.props.app, targetContainer);
|
||||||
|
};
|
||||||
|
|
||||||
private onContextMenuClick = (): void => {
|
private onContextMenuClick = (): void => {
|
||||||
this.setState({ menuDisplayed: true });
|
this.setState({ menuDisplayed: true });
|
||||||
};
|
};
|
||||||
|
@ -647,22 +656,37 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let maxMinButton;
|
const layoutButtons: React.ReactNodeArray = [];
|
||||||
if (!this.props.hideMaximiseButton) {
|
if (this.props.showLayoutButtons) {
|
||||||
const widgetIsMaximised = WidgetLayoutStore.instance.
|
const isMaximised = WidgetLayoutStore.instance.
|
||||||
isInContainer(this.props.room, this.props.app, Container.Center);
|
isInContainer(this.props.room, this.props.app, Container.Center);
|
||||||
const className = classNames({
|
const maximisedClasses = classNames({
|
||||||
"mx_AppTileMenuBar_iconButton": true,
|
"mx_AppTileMenuBar_iconButton": true,
|
||||||
"mx_AppTileMenuBar_iconButton_minWidget": widgetIsMaximised,
|
"mx_AppTileMenuBar_iconButton_close": isMaximised,
|
||||||
"mx_AppTileMenuBar_iconButton_maxWidget": !widgetIsMaximised,
|
"mx_AppTileMenuBar_iconButton_maximise": !isMaximised,
|
||||||
});
|
});
|
||||||
maxMinButton = <AccessibleButton
|
layoutButtons.push(<AccessibleButton
|
||||||
className={className}
|
className={maximisedClasses}
|
||||||
title={
|
title={
|
||||||
widgetIsMaximised ? _t('Close') : _t('Maximise widget')
|
isMaximised ? _t("Close") : _t("Maximise")
|
||||||
}
|
}
|
||||||
onClick={this.onMaxMinWidgetClick}
|
onClick={this.onToggleMaximisedClick}
|
||||||
/>;
|
/>);
|
||||||
|
|
||||||
|
const isPinned = WidgetLayoutStore.instance.
|
||||||
|
isInContainer(this.props.room, this.props.app, Container.Top);
|
||||||
|
const pinnedClasses = classNames({
|
||||||
|
"mx_AppTileMenuBar_iconButton": true,
|
||||||
|
"mx_AppTileMenuBar_iconButton_unpin": isPinned,
|
||||||
|
"mx_AppTileMenuBar_iconButton_pin": !isPinned,
|
||||||
|
});
|
||||||
|
layoutButtons.push(<AccessibleButton
|
||||||
|
className={pinnedClasses}
|
||||||
|
title={
|
||||||
|
isPinned ? _t("Unpin") : _t("Pin")
|
||||||
|
}
|
||||||
|
onClick={this.onTogglePinnedClick}
|
||||||
|
/>);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment>
|
return <React.Fragment>
|
||||||
|
@ -673,7 +697,7 @@ export default class AppTile extends React.Component<IProps, IState> {
|
||||||
{ this.props.showTitle && this.getTileTitle() }
|
{ this.props.showTitle && this.getTileTitle() }
|
||||||
</span>
|
</span>
|
||||||
<span className="mx_AppTileMenuBarWidgets">
|
<span className="mx_AppTileMenuBarWidgets">
|
||||||
{ maxMinButton }
|
{ layoutButtons }
|
||||||
{ (this.props.showPopout && !this.state.requiresClient) && <AccessibleButton
|
{ (this.props.showPopout && !this.state.requiresClient) && <AccessibleButton
|
||||||
className="mx_AppTileMenuBar_iconButton mx_AppTileMenuBar_iconButton_popout"
|
className="mx_AppTileMenuBar_iconButton mx_AppTileMenuBar_iconButton_popout"
|
||||||
title={_t('Popout widget')}
|
title={_t('Popout widget')}
|
||||||
|
|
|
@ -135,16 +135,12 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
|
||||||
pinTitle = isPinned ? _t("Unpin") : _t("Pin");
|
pinTitle = isPinned ? _t("Unpin") : _t("Pin");
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", {
|
|
||||||
mx_RoomSummaryCard_Button_pinned: isPinned,
|
|
||||||
});
|
|
||||||
|
|
||||||
const isMaximised = WidgetLayoutStore.instance.isInContainer(room, app, Container.Center);
|
const isMaximised = WidgetLayoutStore.instance.isInContainer(room, app, Container.Center);
|
||||||
const toggleMaximised = isMaximised
|
const toggleMaximised = isMaximised
|
||||||
? () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); }
|
? () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); }
|
||||||
: () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Center); };
|
: () => { WidgetLayoutStore.instance.moveToContainer(room, app, Container.Center); };
|
||||||
|
|
||||||
const maximiseTitle = isMaximised ? _t("Close") : _t("Maximise widget");
|
const maximiseTitle = isMaximised ? _t("Close") : _t("Maximise");
|
||||||
|
|
||||||
let openTitle = "";
|
let openTitle = "";
|
||||||
if (isPinned) {
|
if (isPinned) {
|
||||||
|
@ -153,6 +149,11 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
|
||||||
openTitle =_t("Close this widget to view it in this panel");
|
openTitle =_t("Close this widget to view it in this panel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const classes = classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", {
|
||||||
|
mx_RoomSummaryCard_Button_pinned: isPinned,
|
||||||
|
mx_RoomSummaryCard_Button_maximised: isMaximised,
|
||||||
|
});
|
||||||
|
|
||||||
return <div className={classes} ref={handle}>
|
return <div className={classes} ref={handle}>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className="mx_RoomSummaryCard_icon_app"
|
className="mx_RoomSummaryCard_icon_app"
|
||||||
|
@ -169,7 +170,7 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
|
||||||
</AccessibleTooltipButton>
|
</AccessibleTooltipButton>
|
||||||
|
|
||||||
{ canModifyWidget && <ContextMenuTooltipButton
|
{ canModifyWidget && <ContextMenuTooltipButton
|
||||||
className="mx_RoomSummaryCard_app_options mx_RoomSummaryCard_maximised_widget"
|
className="mx_RoomSummaryCard_app_options"
|
||||||
isExpanded={menuDisplayed}
|
isExpanded={menuDisplayed}
|
||||||
onClick={openMenu}
|
onClick={openMenu}
|
||||||
title={_t("Options")}
|
title={_t("Options")}
|
||||||
|
@ -184,7 +185,7 @@ const AppRow: React.FC<IAppRowProps> = ({ app, room }) => {
|
||||||
yOffset={-24}
|
yOffset={-24}
|
||||||
/>
|
/>
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className={isMaximised ? "mx_RoomSummaryCard_app_minimise" : "mx_RoomSummaryCard_app_maximise"}
|
className="mx_RoomSummaryCard_app_maximiseToggle"
|
||||||
onClick={toggleMaximised}
|
onClick={toggleMaximised}
|
||||||
title={maximiseTitle}
|
title={maximiseTitle}
|
||||||
yOffset={-24}
|
yOffset={-24}
|
||||||
|
|
|
@ -304,7 +304,7 @@ export default class Stickerpicker extends React.PureComponent<IProps, IState> {
|
||||||
showPopout={false}
|
showPopout={false}
|
||||||
handleMinimisePointerEvents={true}
|
handleMinimisePointerEvents={true}
|
||||||
userWidget={true}
|
userWidget={true}
|
||||||
hideMaximiseButton={true}
|
showLayoutButtons={false}
|
||||||
/>
|
/>
|
||||||
</PersistedElement>
|
</PersistedElement>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1947,7 +1947,7 @@
|
||||||
"Chat": "Chat",
|
"Chat": "Chat",
|
||||||
"Room Info": "Room Info",
|
"Room Info": "Room Info",
|
||||||
"You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets",
|
"You can only pin up to %(count)s widgets|other": "You can only pin up to %(count)s widgets",
|
||||||
"Maximise widget": "Maximise widget",
|
"Maximise": "Maximise",
|
||||||
"Unpin this widget to view it in this panel": "Unpin this widget to view it in this panel",
|
"Unpin this widget to view it in this panel": "Unpin this widget to view it in this panel",
|
||||||
"Close this widget to view it in this panel": "Close this widget to view it in this panel",
|
"Close this widget to view it in this panel": "Close this widget to view it in this panel",
|
||||||
"Set my room layout for everyone": "Set my room layout for everyone",
|
"Set my room layout for everyone": "Set my room layout for everyone",
|
||||||
|
|
Loading…
Reference in a new issue