Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 5bbdfe9

Browse files
committed
allow simple copying of embeds
1 parent 6c81ca8 commit 5bbdfe9

File tree

7 files changed

+64
-3
lines changed

7 files changed

+64
-3
lines changed

app/models/ai_artifact.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ def self.iframe_for(id, version = nil)
2222
<<~HTML
2323
<div class='ai-artifact'>
2424
<iframe src='#{url(id, version)}' frameborder="0" height="100%" width="100%"></iframe>
25-
<a href='#{url(id, version)}' target='_blank'>#{I18n.t("discourse_ai.ai_artifact.link")}</a>
25+
<div class='ai-artifact-controls'>
26+
<a href='#{url(id, version)}' class='link-artifact' target='_blank'>#{I18n.t("discourse_ai.ai_artifact.link")}</a>
27+
<a href class='copy-embed' data-url="#{url(id, version)}">#{I18n.t("discourse_ai.ai_artifact.copy_embed")}</a>
28+
</div>
2629
</div>
2730
HTML
2831
end

app/views/discourse_ai/ai_bot/shared_ai_conversations/show.html.erb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,22 @@
5959
document.querySelectorAll('pre code').forEach((el) => {
6060
hljs.highlightElement(el);
6161
});
62+
63+
document.querySelectorAll('.ai-artifact-controls .copy-embed').forEach((el) => {
64+
el.addEventListener('click', (e) => {
65+
e.preventDefault();
66+
const url = el.dataset.url;
67+
const embedCode = `<iframe src="${url}" width="100%" height="600" frameborder="0"></iframe>`;
68+
navigator.clipboard.writeText(embedCode).then(() => {
69+
el.textContent = '<%= I18n.t("discourse_ai.ai_artifact.copied") %>';
70+
setTimeout(() => {
71+
el.textContent = '<%= I18n.t("discourse_ai.ai_artifact.copy_embed") %>';
72+
}, 2000);
73+
}).catch(err => {
74+
console.error('Failed to copy: ', err);
75+
});
76+
});
77+
});
6278
</script>
6379
</body>
6480
</html>

assets/javascripts/discourse/components/modal/share-full-topic-modal.gjs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Component from "@glimmer/component";
22
import { tracked } from "@glimmer/tracking";
3+
import { on } from "@ember/modifier";
34
import { action } from "@ember/object";
45
import { service } from "@ember/service";
56
import { htmlSafe } from "@ember/template";
@@ -88,14 +89,39 @@ export default class ShareModal extends Component {
8889
});
8990
}
9091

92+
@action
93+
async maybeCopyEmbed(event) {
94+
if (!event.target.classList.contains("copy-embed")) {
95+
return true;
96+
}
97+
event.stopPropagation();
98+
event.preventDefault();
99+
const iframeEmbed = `<iframe src="${event.target.dataset.url}" width="600px" height="600px" frameborder="0"></iframe>`;
100+
const promise = new Promise((resolve) => {
101+
resolve(iframeEmbed);
102+
});
103+
104+
await clipboardCopyAsync(() => promise);
105+
106+
this.toasts.success({
107+
duration: 3000,
108+
data: {
109+
message: i18n("discourse_ai.ai_bot.embed_copied"),
110+
},
111+
});
112+
}
113+
91114
<template>
92115
<DModal
93116
class="ai-share-full-topic-modal"
94117
@title={{i18n "discourse_ai.ai_bot.share_full_topic_modal.title"}}
95118
@closeModal={{@closeModal}}
96119
>
97120
<:body>
98-
<div class="ai-share-full-topic-modal__body">
121+
<div
122+
class="ai-share-full-topic-modal__body"
123+
{{on "click" this.maybeCopyEmbed}}
124+
>
99125
{{this.htmlContext}}
100126
</div>
101127
</:body>

assets/stylesheets/modules/ai-bot/common/ai-artifact.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,10 @@ html.ai-artifact-expanded {
134134
z-index: z("fullscreen");
135135
}
136136
}
137+
138+
.ai-share-full-topic-modal__body {
139+
.ai-artifact-controls {
140+
display: flex;
141+
justify-content: space-between;
142+
}
143+
}

config/locales/client.en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ en:
689689
shortcut_title: "Start a PM with an AI bot"
690690
share: "Copy AI conversation"
691691
conversation_shared: "Conversation copied"
692+
embed_copied: "Embed copied to clipboard"
692693
debug_ai: "View raw AI request and response"
693694
sidebar_empty: "Bot conversation history will appear here."
694695
debug_ai_modal:

config/locales/server.en.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,12 @@ en:
223223
max_keys_exceeded:
224224
one: "You can only have %{max} key in the artifact."
225225
other: "You can only have %{max} keys in the artifact."
226-
link: "Show Artifact in new tab"
226+
link: "Show in new tab"
227+
copy_embed: "Copy embed"
227228
view_source: "View Source"
228229
view_changes: "View Changes"
229230
change_description: "Change Description"
231+
copied: "Copied to clipboard"
230232
unknown_model: "Unknown AI model"
231233

232234
tools:

public/ai-share/share.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,3 +632,9 @@ aside.onebox h3 {
632632
height: 600px;
633633
max-height: 600px;
634634
}
635+
636+
.ai-artifact-controls {
637+
display: flex;
638+
justify-content: space-between;
639+
}
640+

0 commit comments

Comments
 (0)