Move the dial pad button next to Explore button from Create Room context menu (#6237)
This commit moves the dial pad from a context menu to sit right by the explore button, in line with the designs in the linked issue. The dial pad button is only shown when PSTN support is detected.
This commit is contained in:
parent
8f6d31b73c
commit
a8e2c1bc2a
5 changed files with 60 additions and 57 deletions
|
@ -111,6 +111,29 @@ $roomListCollapsedWidth: 68px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx_LeftPanel_dialPadButton {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: $roomlist-button-bg-color;
|
||||||
|
position: relative;
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 8px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
mask-image: url('$(res)/img/element-icons/call/dialpad.svg');
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
background: $secondary-fg-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mx_LeftPanel_exploreButton {
|
.mx_LeftPanel_exploreButton {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -185,6 +208,12 @@ $roomListCollapsedWidth: 68px;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
.mx_LeftPanel_dialPadButton {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: 8px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
.mx_LeftPanel_exploreButton {
|
.mx_LeftPanel_exploreButton {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|
3
res/img/element-icons/call/dialpad.svg
Normal file
3
res/img/element-icons/call/dialpad.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg width="12" height="18" viewBox="0 0 12 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6 14.25C5.175 14.25 4.5 14.925 4.5 15.75C4.5 16.575 5.175 17.25 6 17.25C6.825 17.25 7.5 16.575 7.5 15.75C7.5 14.925 6.825 14.25 6 14.25ZM1.5 0.75C0.675 0.75 0 1.425 0 2.25C0 3.075 0.675 3.75 1.5 3.75C2.325 3.75 3 3.075 3 2.25C3 1.425 2.325 0.75 1.5 0.75ZM1.5 5.25C0.675 5.25 0 5.925 0 6.75C0 7.575 0.675 8.25 1.5 8.25C2.325 8.25 3 7.575 3 6.75C3 5.925 2.325 5.25 1.5 5.25ZM1.5 9.75C0.675 9.75 0 10.425 0 11.25C0 12.075 0.675 12.75 1.5 12.75C2.325 12.75 3 12.075 3 11.25C3 10.425 2.325 9.75 1.5 9.75ZM10.5 3.75C11.325 3.75 12 3.075 12 2.25C12 1.425 11.325 0.75 10.5 0.75C9.675 0.75 9 1.425 9 2.25C9 3.075 9.675 3.75 10.5 3.75ZM6 9.75C5.175 9.75 4.5 10.425 4.5 11.25C4.5 12.075 5.175 12.75 6 12.75C6.825 12.75 7.5 12.075 7.5 11.25C7.5 10.425 6.825 9.75 6 9.75ZM10.5 9.75C9.675 9.75 9 10.425 9 11.25C9 12.075 9.675 12.75 10.5 12.75C11.325 12.75 12 12.075 12 11.25C12 10.425 11.325 9.75 10.5 9.75ZM10.5 5.25C9.675 5.25 9 5.925 9 6.75C9 7.575 9.675 8.25 10.5 8.25C11.325 8.25 12 7.575 12 6.75C12 5.925 11.325 5.25 10.5 5.25ZM6 5.25C5.175 5.25 4.5 5.925 4.5 6.75C4.5 7.575 5.175 8.25 6 8.25C6.825 8.25 7.5 7.575 7.5 6.75C7.5 5.925 6.825 5.25 6 5.25ZM6 0.75C5.175 0.75 4.5 1.425 4.5 2.25C4.5 3.075 5.175 3.75 6 3.75C6.825 3.75 7.5 3.075 7.5 2.25C7.5 1.425 6.825 0.75 6 0.75Z" fill="#737D8C"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -24,6 +24,7 @@ import CustomRoomTagPanel from "./CustomRoomTagPanel";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import RoomList from "../views/rooms/RoomList";
|
import RoomList from "../views/rooms/RoomList";
|
||||||
|
import CallHandler from "../../CallHandler";
|
||||||
import { HEADER_HEIGHT } from "../views/rooms/RoomSublist";
|
import { HEADER_HEIGHT } from "../views/rooms/RoomSublist";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import UserMenu from "./UserMenu";
|
import UserMenu from "./UserMenu";
|
||||||
|
@ -124,6 +125,10 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
this.setState({ activeSpace });
|
this.setState({ activeSpace });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private onDialPad = () => {
|
||||||
|
dis.fire(Action.OpenDialPad);
|
||||||
|
}
|
||||||
|
|
||||||
private onExplore = () => {
|
private onExplore = () => {
|
||||||
dis.fire(Action.ViewRoomDirectory);
|
dis.fire(Action.ViewRoomDirectory);
|
||||||
};
|
};
|
||||||
|
@ -397,7 +402,20 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderSearchExplore(): React.ReactNode {
|
private renderSearchDialExplore(): React.ReactNode {
|
||||||
|
let dialPadButton = null;
|
||||||
|
|
||||||
|
// If we have dialer support, show a button to bring up the dial pad
|
||||||
|
// to start a new call
|
||||||
|
if (CallHandler.sharedInstance().getSupportsPstnProtocol()) {
|
||||||
|
dialPadButton =
|
||||||
|
<AccessibleTooltipButton
|
||||||
|
className={classNames("mx_LeftPanel_dialPadButton", {})}
|
||||||
|
onClick={this.onDialPad}
|
||||||
|
title={_t("Open dial pad")}
|
||||||
|
/>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="mx_LeftPanel_filterContainer"
|
className="mx_LeftPanel_filterContainer"
|
||||||
|
@ -410,6 +428,9 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
onKeyDown={this.onKeyDown}
|
onKeyDown={this.onKeyDown}
|
||||||
onSelectRoom={this.selectRoom}
|
onSelectRoom={this.selectRoom}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{dialPadButton}
|
||||||
|
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
className={classNames("mx_LeftPanel_exploreButton", {
|
className={classNames("mx_LeftPanel_exploreButton", {
|
||||||
mx_LeftPanel_exploreButton_space: !!this.state.activeSpace,
|
mx_LeftPanel_exploreButton_space: !!this.state.activeSpace,
|
||||||
|
@ -458,7 +479,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
{leftLeftPanel}
|
{leftLeftPanel}
|
||||||
<aside className="mx_LeftPanel_roomListContainer">
|
<aside className="mx_LeftPanel_roomListContainer">
|
||||||
{this.renderHeader()}
|
{this.renderHeader()}
|
||||||
{this.renderSearchExplore()}
|
{this.renderSearchDialExplore()}
|
||||||
{this.renderBreadcrumbs()}
|
{this.renderBreadcrumbs()}
|
||||||
<RoomListNumResults onVisibilityChange={this.refreshStickyHeaders} />
|
<RoomListNumResults onVisibilityChange={this.refreshStickyHeaders} />
|
||||||
<div className="mx_LeftPanel_roomListWrapper">
|
<div className="mx_LeftPanel_roomListWrapper">
|
||||||
|
|
|
@ -45,7 +45,6 @@ import { objectShallowClone, objectWithOnly } from "../../../utils/objects";
|
||||||
import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../context_menus/IconizedContextMenu";
|
import { IconizedContextMenuOption, IconizedContextMenuOptionList } from "../context_menus/IconizedContextMenu";
|
||||||
import AccessibleButton from "../elements/AccessibleButton";
|
import AccessibleButton from "../elements/AccessibleButton";
|
||||||
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
|
import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
|
||||||
import CallHandler from "../../../CallHandler";
|
|
||||||
import SpaceStore, {ISuggestedRoom, SUGGESTED_ROOMS} from "../../../stores/SpaceStore";
|
import SpaceStore, {ISuggestedRoom, SUGGESTED_ROOMS} from "../../../stores/SpaceStore";
|
||||||
import {showAddExistingRooms, showCreateNewRoom, showSpaceInvite} from "../../../utils/space";
|
import {showAddExistingRooms, showCreateNewRoom, showSpaceInvite} from "../../../utils/space";
|
||||||
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
import {replaceableComponent} from "../../../utils/replaceableComponent";
|
||||||
|
@ -103,38 +102,6 @@ interface ITagAestheticsMap {
|
||||||
[tagId: TagID]: ITagAesthetics;
|
[tagId: TagID]: ITagAesthetics;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have no dialer support, we just show the create chat dialog
|
|
||||||
const dmOnAddRoom = (dispatcher?: Dispatcher<ActionPayload>) => {
|
|
||||||
(dispatcher || defaultDispatcher).dispatch({action: 'view_create_chat'});
|
|
||||||
};
|
|
||||||
|
|
||||||
// If we have dialer support, show a context menu so the user can pick between
|
|
||||||
// the dialer and the create chat dialog
|
|
||||||
const dmAddRoomContextMenu = (onFinished: () => void) => {
|
|
||||||
return <IconizedContextMenuOptionList first>
|
|
||||||
<IconizedContextMenuOption
|
|
||||||
label={_t("Start a Conversation")}
|
|
||||||
iconClassName="mx_RoomList_iconPlus"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
onFinished();
|
|
||||||
defaultDispatcher.dispatch({action: "view_create_chat"});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<IconizedContextMenuOption
|
|
||||||
label={_t("Open dial pad")}
|
|
||||||
iconClassName="mx_RoomList_iconDialpad"
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
onFinished();
|
|
||||||
defaultDispatcher.fire(Action.OpenDialPad);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconizedContextMenuOptionList>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const TAG_AESTHETICS: ITagAestheticsMap = {
|
const TAG_AESTHETICS: ITagAestheticsMap = {
|
||||||
[DefaultTagID.Invite]: {
|
[DefaultTagID.Invite]: {
|
||||||
sectionLabel: _td("Invites"),
|
sectionLabel: _td("Invites"),
|
||||||
|
@ -151,8 +118,9 @@ const TAG_AESTHETICS: ITagAestheticsMap = {
|
||||||
isInvite: false,
|
isInvite: false,
|
||||||
defaultHidden: false,
|
defaultHidden: false,
|
||||||
addRoomLabel: _td("Start chat"),
|
addRoomLabel: _td("Start chat"),
|
||||||
// Either onAddRoom or addRoomContextMenu are set depending on whether we
|
onAddRoom: (dispatcher?: Dispatcher<ActionPayload>) => {
|
||||||
// have dialer support.
|
(dispatcher || defaultDispatcher).dispatch({action: 'view_create_chat'});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[DefaultTagID.Untagged]: {
|
[DefaultTagID.Untagged]: {
|
||||||
sectionLabel: _td("Rooms"),
|
sectionLabel: _td("Rooms"),
|
||||||
|
@ -271,7 +239,6 @@ function customTagAesthetics(tagId: TagID): ITagAesthetics {
|
||||||
export default class RoomList extends React.PureComponent<IProps, IState> {
|
export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
private dispatcherRef;
|
private dispatcherRef;
|
||||||
private customTagStoreRef;
|
private customTagStoreRef;
|
||||||
private tagAesthetics: ITagAestheticsMap;
|
|
||||||
private roomStoreToken: fbEmitter.EventSubscription;
|
private roomStoreToken: fbEmitter.EventSubscription;
|
||||||
|
|
||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
|
@ -282,10 +249,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
isNameFiltering: !!RoomListStore.instance.getFirstNameFilterCondition(),
|
isNameFiltering: !!RoomListStore.instance.getFirstNameFilterCondition(),
|
||||||
suggestedRooms: SpaceStore.instance.suggestedRooms,
|
suggestedRooms: SpaceStore.instance.suggestedRooms,
|
||||||
};
|
};
|
||||||
|
|
||||||
// shallow-copy from the template as we need to make modifications to it
|
|
||||||
this.tagAesthetics = objectShallowClone(TAG_AESTHETICS);
|
|
||||||
this.updateDmAddRoomAction();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentDidMount(): void {
|
public componentDidMount(): void {
|
||||||
|
@ -311,17 +274,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
private updateDmAddRoomAction() {
|
|
||||||
const dmTagAesthetics = objectShallowClone(TAG_AESTHETICS[DefaultTagID.DM]);
|
|
||||||
if (CallHandler.sharedInstance().getSupportsPstnProtocol()) {
|
|
||||||
dmTagAesthetics.addRoomContextMenu = dmAddRoomContextMenu;
|
|
||||||
} else {
|
|
||||||
dmTagAesthetics.onAddRoom = dmOnAddRoom;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tagAesthetics[DefaultTagID.DM] = dmTagAesthetics;
|
|
||||||
}
|
|
||||||
|
|
||||||
private onAction = (payload: ActionPayload) => {
|
private onAction = (payload: ActionPayload) => {
|
||||||
if (payload.action === Action.ViewRoomDelta) {
|
if (payload.action === Action.ViewRoomDelta) {
|
||||||
const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload;
|
const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload;
|
||||||
|
@ -335,7 +287,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (payload.action === Action.PstnSupportUpdated) {
|
} else if (payload.action === Action.PstnSupportUpdated) {
|
||||||
this.updateDmAddRoomAction();
|
|
||||||
this.updateLists();
|
this.updateLists();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -524,7 +475,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
|
||||||
|
|
||||||
const aesthetics: ITagAesthetics = isCustomTag(orderedTagId)
|
const aesthetics: ITagAesthetics = isCustomTag(orderedTagId)
|
||||||
? customTagAesthetics(orderedTagId)
|
? customTagAesthetics(orderedTagId)
|
||||||
: this.tagAesthetics[orderedTagId];
|
: TAG_AESTHETICS[orderedTagId];
|
||||||
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);
|
if (!aesthetics) throw new Error(`Tag ${orderedTagId} does not have aesthetics`);
|
||||||
|
|
||||||
// The cost of mounting/unmounting this component offsets the cost
|
// The cost of mounting/unmounting this component offsets the cost
|
||||||
|
|
|
@ -1581,8 +1581,6 @@
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
"Voice call": "Voice call",
|
"Voice call": "Voice call",
|
||||||
"Video call": "Video call",
|
"Video call": "Video call",
|
||||||
"Start a Conversation": "Start a Conversation",
|
|
||||||
"Open dial pad": "Open dial pad",
|
|
||||||
"Invites": "Invites",
|
"Invites": "Invites",
|
||||||
"Favourites": "Favourites",
|
"Favourites": "Favourites",
|
||||||
"People": "People",
|
"People": "People",
|
||||||
|
@ -2661,6 +2659,7 @@
|
||||||
"Explore Public Rooms": "Explore Public Rooms",
|
"Explore Public Rooms": "Explore Public Rooms",
|
||||||
"Create a Group Chat": "Create a Group Chat",
|
"Create a Group Chat": "Create a Group Chat",
|
||||||
"Upgrade to %(hostSignupBrand)s": "Upgrade to %(hostSignupBrand)s",
|
"Upgrade to %(hostSignupBrand)s": "Upgrade to %(hostSignupBrand)s",
|
||||||
|
"Open dial pad": "Open dial pad",
|
||||||
"Failed to reject invitation": "Failed to reject invitation",
|
"Failed to reject invitation": "Failed to reject invitation",
|
||||||
"Cannot create rooms in this community": "Cannot create rooms in this community",
|
"Cannot create rooms in this community": "Cannot create rooms in this community",
|
||||||
"You do not have permission to create rooms in this community.": "You do not have permission to create rooms in this community.",
|
"You do not have permission to create rooms in this community.": "You do not have permission to create rooms in this community.",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue