FEATURE: Add copy quote button to post selection menu (#25139)
Merges the design experiment at https://meta.discourse.org/t/post-quote-copy-to-clipboard-button-feedback/285376 into core. This adds a new button by default to the menu that pops up when text is selected in a post. The normal Quote button that is shown when selecting text within a post will open the composer with the quote markdown prefilled. This new "Copy Quote" button copies the quote markdown directly to the user’s clipboard. This is useful for when you want to copy the quote elsewhere – to another topic or a chat message for instance – without having to manually copy from the opened composer, which then has to be dismissed afterwards. An example of quote markdown: ``` [quote="someuser, post:7, topic:285376"] In this moment, I am euphoric. [/quote] ```
This commit is contained in:
parent
a720bdc72b
commit
51016e56dd
|
@ -12,8 +12,13 @@ import PluginOutlet from "discourse/components/plugin-outlet";
|
|||
import concatClass from "discourse/helpers/concat-class";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import Sharing from "discourse/lib/sharing";
|
||||
import { postUrl, setCaretPosition } from "discourse/lib/utilities";
|
||||
import {
|
||||
clipboardCopy,
|
||||
postUrl,
|
||||
setCaretPosition,
|
||||
} from "discourse/lib/utilities";
|
||||
import { getAbsoluteURL } from "discourse-common/lib/get-url";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
export function fixQuotes(str) {
|
||||
// u+201c, u+201d = “ ”
|
||||
|
@ -27,6 +32,7 @@ export default class PostTextSelectionToolbar extends Component {
|
|||
@service site;
|
||||
@service siteSettings;
|
||||
@service appEvents;
|
||||
@service toasts;
|
||||
|
||||
@tracked isFastEditing = false;
|
||||
|
||||
|
@ -96,6 +102,17 @@ export default class PostTextSelectionToolbar extends Component {
|
|||
event.stopPropagation();
|
||||
}
|
||||
|
||||
@action
|
||||
async copyQuoteToClipboard() {
|
||||
const text = await this.args.data.buildQuote();
|
||||
clipboardCopy(text);
|
||||
this.toasts.success({
|
||||
duration: 3000,
|
||||
data: { message: I18n.t("post.quote_copied_to_clibboard") },
|
||||
});
|
||||
await this.args.data.hideToolbar();
|
||||
}
|
||||
|
||||
@action
|
||||
async closeFastEdit() {
|
||||
this.isFastEditing = false;
|
||||
|
@ -216,6 +233,16 @@ export default class PostTextSelectionToolbar extends Component {
|
|||
/>
|
||||
{{/if}}
|
||||
|
||||
{{#if @data.canCopyQuote}}
|
||||
<DButton
|
||||
@icon="copy"
|
||||
@label="post.quote_copy"
|
||||
@title="post.quote_copy"
|
||||
class="btn-flat copy-quote"
|
||||
{{on "click" this.copyQuoteToClipboard}}
|
||||
/>
|
||||
{{/if}}
|
||||
|
||||
<PluginOutlet
|
||||
@name="quote-share-buttons-before"
|
||||
@connectorTagName="span"
|
||||
|
|
|
@ -204,6 +204,7 @@ export default class PostTextSelection extends Component {
|
|||
trapTab: false,
|
||||
data: {
|
||||
canEditPost: this.canEditPost,
|
||||
canCopyQuote: this.canCopyQuote,
|
||||
editPost: this.args.editPost,
|
||||
supportsFastEdit,
|
||||
topic: this.args.topic,
|
||||
|
@ -258,6 +259,10 @@ export default class PostTextSelection extends Component {
|
|||
return this.siteSettings.enable_fast_edit && this.post?.can_edit;
|
||||
}
|
||||
|
||||
get canCopyQuote() {
|
||||
return this.siteSettings.enable_quote_copy;
|
||||
}
|
||||
|
||||
// on Desktop, shows the bar at the beginning of the selection
|
||||
// on Mobile, shows the bar at the end of the selection
|
||||
@cached
|
||||
|
|
|
@ -3456,6 +3456,8 @@ en:
|
|||
quote_reply_shortcut: "Quote (or press q)"
|
||||
quote_edit: "Edit"
|
||||
quote_edit_shortcut: "Edit (or press e)"
|
||||
quote_copy: "Copy Quote"
|
||||
quote_copied_to_clibboard: "Quote copied to clipboard"
|
||||
quote_share: "Share"
|
||||
edit_reason: "Reason: "
|
||||
post_number: "post %{number}"
|
||||
|
|
|
@ -2353,7 +2353,8 @@ en:
|
|||
watched_words_regular_expressions: "Watched words are regular expressions."
|
||||
|
||||
enable_diffhtml_preview: "Experimental feature which uses diffHTML to sync preview instead of full re-render"
|
||||
enable_fast_edit: "Enables small selection of a post text to be edited inline."
|
||||
enable_fast_edit: "Adds a button to the post selection menu to edit a small selection inline."
|
||||
enable_quote_copy: "Adds a button to post selection menu to copy the selection to clipboard as a markdown quote."
|
||||
|
||||
old_post_notice_days: "Days before post notice becomes old"
|
||||
new_user_notice_tl: "Minimum trust level required to see new user post notices."
|
||||
|
|
|
@ -1130,6 +1130,9 @@ posting:
|
|||
enable_fast_edit:
|
||||
default: true
|
||||
client: true
|
||||
enable_quote_copy:
|
||||
default: true
|
||||
client: true
|
||||
old_post_notice_days:
|
||||
default: 14
|
||||
max: 36500
|
||||
|
|
|
@ -173,6 +173,14 @@ module PageObjects
|
|||
@fast_edit_component.fast_edit_input
|
||||
end
|
||||
|
||||
def copy_quote_button_selector
|
||||
".quote-button .copy-quote"
|
||||
end
|
||||
|
||||
def copy_quote_button
|
||||
find(copy_quote_button_selector)
|
||||
end
|
||||
|
||||
def click_mention(post, mention)
|
||||
within post_by_number(post) do
|
||||
find("a.mention-group", text: mention).click
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Post selection | Copy quote", type: :system do
|
||||
let(:topic_page) { PageObjects::Pages::Topic.new }
|
||||
let(:cdp) { PageObjects::CDP.new }
|
||||
|
||||
fab!(:topic)
|
||||
fab!(:post) { Fabricate(:post, topic: topic, raw: "Hello world it's time for quoting!") }
|
||||
fab!(:current_user) { Fabricate(:admin) }
|
||||
|
||||
before do
|
||||
sign_in(current_user)
|
||||
cdp.allow_clipboard
|
||||
end
|
||||
|
||||
it "copies the selection from the post the clipboard" do
|
||||
topic_page.visit_topic(topic)
|
||||
|
||||
select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 10)
|
||||
topic_page.copy_quote_button.click
|
||||
|
||||
expect(cdp.read_clipboard.chomp).to eq(<<~QUOTE.chomp)
|
||||
[quote=\"#{post.user.username}, post:1, topic:#{topic.id}\"]\nHello worl\n[/quote]\n
|
||||
QUOTE
|
||||
end
|
||||
|
||||
it "does not show the copy quote button if it has been disabled" do
|
||||
SiteSetting.enable_quote_copy = false
|
||||
topic_page.visit_topic(topic)
|
||||
|
||||
select_text_range("#{topic_page.post_by_number_selector(1)} .cooked p", 0, 10)
|
||||
expect(page).not_to have_css(topic_page.copy_quote_button_selector)
|
||||
end
|
||||
end
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
describe "Fast edit", type: :system do
|
||||
describe "Post selection | Fast edit", type: :system do
|
||||
let(:topic_page) { PageObjects::Pages::Topic.new }
|
||||
let(:fast_editor) { PageObjects::Components::FastEditor.new }
|
||||
fab!(:topic)
|
Loading…
Reference in New Issue