@@ -34,6 +34,7 @@ import ForwardDialog from "../dialogs/ForwardDialog";
3434import { Action } from "../../../dispatcher/actions" ;
3535import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks' ;
3636import { ButtonEvent } from '../elements/AccessibleButton' ;
37+ import { copyPlaintext } from '../../../utils/strings' ;
3738
3839export 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