diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss index 03146e03252..b8f4aeb6e7b 100644 --- a/res/css/views/rooms/_RoomTile.scss +++ b/res/css/views/rooms/_RoomTile.scss @@ -193,6 +193,10 @@ limitations under the License. mask-image: url('$(res)/img/element-icons/settings.svg'); } + .mx_RoomTile_iconCopyLink::before { + mask-image: url('$(res)/img/element-icons/link.svg'); + } + .mx_RoomTile_iconInvite::before { mask-image: url('$(res)/img/element-icons/room/invite.svg'); } diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index b3d869cd910..15536f260d0 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -105,6 +105,8 @@ import VerificationRequestToast from '../views/toasts/VerificationRequestToast'; import PerformanceMonitor, { PerformanceEntryNames } from "../../performance"; import UIStore, { UI_EVENTS } from "../../stores/UIStore"; import SoftLogout from './auth/SoftLogout'; +import { makeRoomPermalink } from "../../utils/permalinks/Permalinks"; +import { copyPlaintext } from "../../utils/strings"; /** constants for MatrixChat.state.view */ export enum Views { @@ -627,6 +629,9 @@ export default class MatrixChat extends React.PureComponent { case 'forget_room': this.forgetRoom(payload.room_id); break; + case 'copy_room': + this.copyRoom(payload.room_id); + break; case 'reject_invite': Modal.createTrackedDialog('Reject invitation', '', QuestionDialog, { title: _t('Reject invitation'), @@ -1193,6 +1198,17 @@ export default class MatrixChat extends React.PureComponent { }); } + private async copyRoom(roomId: string) { + const roomLink = makeRoomPermalink(roomId); + const success = await copyPlaintext(roomLink); + if (!success) { + Modal.createTrackedDialog("Unable to copy room link", "", ErrorDialog, { + title: _t("Unable to copy room link"), + description: _t("Unable to copy a link to the room to the clipboard."), + }); + } + } + /** * Starts a chat with the welcome user, if the user doesn't already have one * @returns {string} The room ID of the new room, or null if no room was created diff --git a/src/components/views/rooms/RoomTile.tsx b/src/components/views/rooms/RoomTile.tsx index 9be0274dd51..b1c9ed4d981 100644 --- a/src/components/views/rooms/RoomTile.tsx +++ b/src/components/views/rooms/RoomTile.tsx @@ -358,6 +358,17 @@ export default class RoomTile extends React.PureComponent { this.setState({ generalMenuPosition: null }); // hide the menu }; + private onCopyRoomClick = (ev: ButtonEvent) => { + ev.preventDefault(); + ev.stopPropagation(); + + dis.dispatch({ + action: 'copy_room', + room_id: this.props.room.roomId, + }); + this.setState({ generalMenuPosition: null }); // hide the menu + }; + private onInviteClick = (ev: ButtonEvent) => { ev.preventDefault(); ev.stopPropagation(); @@ -517,6 +528,11 @@ export default class RoomTile extends React.PureComponent { iconClassName="mx_RoomTile_iconInvite" /> ) : null} +