Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit d64b4f9

Browse files
committed
Add copy button
Signed-off-by: Šimon Brandner <[email protected]>
1 parent 2d74575 commit d64b4f9

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

res/css/views/context_menus/_MessageContextMenu.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,8 @@ limitations under the License.
8181
.mx_MessageContextMenu_iconUnpin::before {
8282
mask-image: url('$(res)/img/element-icons/room/pin.svg');
8383
}
84+
85+
.mx_MessageContextMenu_iconCopy::before {
86+
mask-image: url($copy-button-url);
87+
}
8488
}

src/components/views/context_menus/MessageContextMenu.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import ForwardDialog from "../dialogs/ForwardDialog";
3434
import { Action } from "../../../dispatcher/actions";
3535
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
3636
import { ButtonEvent } from '../elements/AccessibleButton';
37+
import { copyPlaintext } from '../../../utils/strings';
3738

3839
export function canCancel(eventStatus) {
3940
return eventStatus === EventStatus.QUEUED || eventStatus === EventStatus.NOT_SENT;
@@ -229,6 +230,11 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
229230
this.closeMenu();
230231
};
231232

233+
private onCopyClick = (): void => {
234+
copyPlaintext(this.getSelectedText());
235+
this.closeMenu();
236+
};
237+
232238
private getReactions(filter: (event: MatrixEvent) => boolean): Array<MatrixEvent> {
233239
const cli = MatrixClientPeg.get();
234240
const room = cli.getRoom(this.props.mxEvent.getRoomId());
@@ -246,6 +252,10 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
246252
return this.getReactions(e => e.status === EventStatus.NOT_SENT);
247253
}
248254

255+
private getSelectedText(): string {
256+
return window.getSelection().toString();
257+
}
258+
249259
render() {
250260
const cli = MatrixClientPeg.get();
251261
const me = cli.getUserId();
@@ -391,6 +401,23 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
391401
);
392402
}
393403

404+
let copyButton;
405+
if (this.props.rightClick && this.getSelectedText()) {
406+
copyButton = (
407+
<IconizedContextMenuOption
408+
iconClassName="mx_MessageContextMenu_iconCopy"
409+
label={_t("Copy")}
410+
onMouseDown={this.onCopyClick} // We use onMouseDown so that the selection isn't cleared when we click
411+
/>
412+
);
413+
}
414+
415+
const nativeItemsList = (
416+
<IconizedContextMenuOptionList>
417+
{ copyButton }
418+
</IconizedContextMenuOptionList>
419+
)
420+
394421
const commonItemsList = (
395422
<IconizedContextMenuOptionList>
396423
{ quoteButton }
@@ -420,6 +447,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
420447
className="mx_MessageContextMenu"
421448
compact={true}
422449
>
450+
{ nativeItemsList }
423451
{ commonItemsList }
424452
{ redactItemList }
425453
</IconizedContextMenu>

0 commit comments

Comments
 (0)