diff options
author | Eugen Rochko <eugen@zeonfederated.com> | 2019-02-11 04:19:49 +0100 |
---|---|---|
committer | Yamagishi Kazutoshi <ykzts@desire.sh> | 2019-02-11 12:19:49 +0900 |
commit | 3cfadd875cc91b3fb893681ed7c2ef86148b3f85 (patch) | |
tree | 536415c4e3d102fbd44c6dd1c48d99cf5722b88f | |
parent | 3031b8a8f22a74a1b691cfe8a31a816ae9cc480d (diff) |
Add "copy link" item to status action bars (#9983)
Fix #6848
-rw-r--r-- | app/javascript/mastodon/components/status_action_bar.js | 22 | ||||
-rw-r--r-- | app/javascript/mastodon/features/status/components/action_bar.js | 21 |
2 files changed, 43 insertions, 0 deletions
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js index 0995a1490..16c7caf1c 100644 --- a/app/javascript/mastodon/components/status_action_bar.js +++ b/app/javascript/mastodon/components/status_action_bar.js @@ -32,6 +32,7 @@ const messages = defineMessages({ embed: { id: 'status.embed', defaultMessage: 'Embed' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' }, + copy: { id: 'status.copy', defaultMessage: 'Copy link to status' }, }); const obfuscatedCount = count => { @@ -141,6 +142,25 @@ class StatusActionBar extends ImmutablePureComponent { this.props.onMuteConversation(this.props.status); } + handleCopy = () => { + const url = this.props.status.get('url'); + const textarea = document.createElement('textarea'); + + textarea.textContent = url; + textarea.style.position = 'fixed'; + + document.body.appendChild(textarea); + + try { + textarea.select(); + document.execCommand('copy'); + } catch (e) { + + } finally { + document.body.removeChild(textarea); + } + } + render () { const { status, intl, withDismiss } = this.props; @@ -156,6 +176,7 @@ class StatusActionBar extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.open), action: this.handleOpen }); if (publicStatus) { + menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy }); menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed }); } @@ -184,6 +205,7 @@ class StatusActionBar extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport }); + if (isStaff) { menu.push(null); menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` }); diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index d3b725283..73be1fc5f 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -28,6 +28,7 @@ const messages = defineMessages({ embed: { id: 'status.embed', defaultMessage: 'Embed' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' }, + copy: { id: 'status.copy', defaultMessage: 'Copy link to status' }, }); export default @injectIntl @@ -113,6 +114,25 @@ class ActionBar extends React.PureComponent { this.props.onEmbed(this.props.status); } + handleCopy = () => { + const url = this.props.status.get('url'); + const textarea = document.createElement('textarea'); + + textarea.textContent = url; + textarea.style.position = 'fixed'; + + document.body.appendChild(textarea); + + try { + textarea.select(); + document.execCommand('copy'); + } catch (e) { + + } finally { + document.body.removeChild(textarea); + } + } + render () { const { status, intl } = this.props; @@ -122,6 +142,7 @@ class ActionBar extends React.PureComponent { let menu = []; if (publicStatus) { + menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy }); menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed }); menu.push(null); } |