Skip to content

Commit 40521b3

Browse files
authored
Merge pull request #208 from joyofrails/feat/snippet-download
Snippet screenshot download
2 parents afcc745 + a9db5bc commit 40521b3

File tree

15 files changed

+185
-37
lines changed

15 files changed

+185
-37
lines changed

app/controllers/share/snippet_screenshots_controller.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@ def new
1515
def create
1616
@snippet = Snippet.find(params[:snippet_id])
1717
@snippet.attach_screenshot_from_base64(params[:screenshot])
18-
redirect_to new_share_snippet_tweet_path(@snippet, auto: true), notice: "Screenshot successful".emojoy
18+
redirect_to intent_url, notice: "Screenshot successful".emojoy
19+
end
20+
21+
def intent_url
22+
case params[:intent]
23+
when "share"
24+
new_share_snippet_tweet_url(@snippet, auto: true)
25+
else
26+
share_snippet_url(@snippet)
27+
end
1928
end
2029
end

app/javascript/controllers/snippets/screenshot.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ export default class extends Controller<HTMLFormElement> {
4040
const data = await this.drawScreenshot();
4141

4242
event.detail.fetchOptions.body.append('screenshot', data);
43+
44+
const searchParams = new URLSearchParams(window.location.search);
45+
['auto', 'intent'].forEach((key) => {
46+
if (searchParams.get(key)) {
47+
event.detail.fetchOptions.body.append(key, searchParams.get(key));
48+
}
49+
});
4350
}
4451

4552
event.detail.resume();

app/javascript/controllers/snippets/tweet.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,33 +21,31 @@ const WINDOW_OPTIONS = {
2121
const WINDOW_OPTIONS_ARGUMENT = Object.entries(WINDOW_OPTIONS)
2222
.map(([key, value]) => `${key}=${value}`)
2323
.join(',');
24-
export default class extends Controller {
24+
export default class extends Controller<HTMLAnchorElement> {
2525
static values = {
26-
url: String,
2726
auto: Boolean,
27+
url: String,
2828
};
2929

30-
declare urlValue: string;
31-
declare autoValue: boolean;
30+
declare readonly autoValue: boolean;
31+
declare readonly urlValue: string;
3232

3333
connect() {
3434
console.log('Connect!');
3535

3636
if (this.autoValue) {
37-
this.tweet();
37+
this.element.click();
3838
Turbo.visit(this.urlValue);
3939
}
4040
}
4141

42-
tweet() {
43-
console.log('Tweet!');
44-
45-
const url = this.urlValue;
46-
47-
const tweetText = encodeURIComponent(`Created with @joyofrails ${url}`);
42+
tweet = (event: Event) => {
43+
if (event) {
44+
event.preventDefault();
45+
}
4846

49-
const tweetUrl = `https://x.com/intent/post?text=${tweetText}`;
47+
const tweetUrl = (this.element as HTMLAnchorElement).href;
5048

5149
window.open(tweetUrl, '_blank', WINDOW_OPTIONS_ARGUMENT);
52-
}
50+
};
5351
}

app/javascript/css/components/button.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@
5555
background-color: var(--joy-button-tertiary-active);
5656
}
5757
}
58+
&.transparent {
59+
color: inherit;
60+
border: 1px solid var(--joy-button-transparent-active);
61+
background-color: var(--joy-button-transparent);
62+
&:hover {
63+
background-color: var(--joy-button-transparent-hover);
64+
}
65+
&:active {
66+
background-color: var(--joy-button-transparent-active);
67+
}
68+
}
69+
&.tertiary {
70+
border: 1px solid var(--joy-button-tertiary);
71+
background-color: var(--joy-button-tertiary);
72+
&:hover {
73+
background-color: var(--joy-button-tertiary-hover);
74+
}
75+
&:active {
76+
background-color: var(--joy-button-tertiary-active);
77+
}
78+
}
5879
&.warn {
5980
background-color: var(--joy-button-warn);
6081
&:hover {

app/javascript/css/config/theme.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@
8585
--joy-button-tertiary: var(--color-slate-500);
8686
--joy-button-tertiary-hover: var(--color-slate-600);
8787
--joy-button-tertiary-active: var(--color-slate-700);
88+
--joy-button-transparent: none;
89+
--joy-button-transparent-hover: var(--joy-color-100);
90+
--joy-button-transparent-active: var(--joy-color-200);
8891
--joy-button-warn: var(--color-red-500);
8992
--joy-button-warn-hover: var(--color-red-400);
9093
}
@@ -123,4 +126,8 @@
123126
--joy-link-visited: var(--joy-link-3);
124127
--joy-link-decoration: var(--joy-link-8);
125128
--joy-link-active: var(--joy-link-5);
129+
130+
--joy-button-transparent: none;
131+
--joy-button-transparent-hover: var(--joy-color-950);
132+
--joy-button-transparent-active: var(--joy-color-900);
126133
}

app/views/components/code_block/atom_aware.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ def view_template
1212
end
1313

1414
def content_type?(type)
15-
helpers.headers["Content-Type"].to_s =~ %r{#{Regexp.escape(type)}}
15+
helpers&.headers&.[]("Content-Type").to_s =~ %r{#{Regexp.escape(type)}}
1616
end
1717
end
Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
class Share::SnippetTweets::Tweet < ApplicationComponent
2-
include Phlex::Rails::Helpers::ButtonTag
3-
include Phlex::Rails::Helpers::ClassNames
42
include PhlexConcerns::FlexBlock
53

64
def initialize(snippet, auto: false)
@@ -9,30 +7,17 @@ def initialize(snippet, auto: false)
97
end
108

119
def view_template
12-
div(
13-
class: "snippet-tweet grid-content",
14-
data: {
15-
controller: "snippet-tweet",
16-
snippet_tweet_url_value: tweet_url,
17-
snippet_tweet_auto_value: auto?.to_s
18-
}
19-
) do
10+
div(class: "snippet-tweet grid-content") do
2011
render CodeBlock::Snippet.new(
2112
@snippet,
2213
screenshot: true
2314
)
2415

2516
flex_block do
26-
button_tag "Share",
27-
class: class_names("button", "primary"),
28-
data: {action: "click->snippet-tweet#tweet"}
17+
render Share::SnippetTweets::TweetButton.new(@snippet, auto: auto?)
2918
end
3019
end
3120
end
3221

33-
def tweet_url
34-
share_snippet_url(@snippet)
35-
end
36-
3722
def auto? = !!@auto
3823
end
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Share::SnippetTweets::TweetButton < ApplicationComponent
2+
def initialize(snippet, auto: false)
3+
@snippet = snippet
4+
@auto = auto
5+
end
6+
7+
def view_template
8+
a(
9+
href: tweet_url,
10+
class: "button primary",
11+
data: {
12+
controller: "snippet-tweet",
13+
action: "click->snippet-tweet#tweet",
14+
snippet_tweet_auto_value: auto?.to_s,
15+
snippet_tweet_url_value: share_url
16+
}
17+
) do
18+
"Share"
19+
end
20+
end
21+
22+
def tweet_url
23+
"https://x.com/intent/post?text=#{encode(tweet_text)}"
24+
end
25+
26+
def share_url
27+
share_snippet_url(@snippet)
28+
end
29+
30+
def tweet_text
31+
"Created with @joyofrails #{share_url}"
32+
end
33+
34+
def encode(text)
35+
URI.encode_www_form_component(text)
36+
end
37+
38+
def auto? = !!@auto
39+
end

app/views/share/snippets/toolbar.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,21 @@ def initialize(snippet, current_user: nil)
1010

1111
def view_template
1212
flex_block do
13-
link_to "Share", share_url, class: "button primary"
13+
render Share::SnippetTweets::TweetButton.new(@snippet)
14+
15+
a(
16+
href: download_url,
17+
class: "button transparent"
18+
) { "Download" }
19+
1420
if @current_user&.can_edit?(@snippet)
15-
link_to "Edit this snippet", edit_share_snippet_path(@snippet),
21+
a(
22+
href: edit_share_snippet_path(@snippet),
1623
class: "button secondary",
1724
data: {turbo_frame: "snippet_form"}
25+
) do
26+
"Edit this snippet"
27+
end
1828
end
1929
end
2030
end
@@ -23,7 +33,15 @@ def share_url
2333
if @snippet.screenshot.attached?
2434
new_share_snippet_tweet_path(@snippet, auto: "true")
2535
else
26-
new_share_snippet_screenshot_path(@snippet, auto: "true")
36+
new_share_snippet_screenshot_path(@snippet, auto: "true", intent: "share")
37+
end
38+
end
39+
40+
def download_url
41+
if @snippet.screenshot.attached?
42+
rails_blob_url(@snippet.screenshot, disposition: "attachment")
43+
else
44+
new_share_snippet_screenshot_path(@snippet, auto: "true", intent: "download")
2745
end
2846
end
2947
end

spec/factories/snippets.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
factory :snippet do
33
source { "puts \"Hello, world!\"" }
44
language { "ruby" }
5+
filename { "example.rb" }
56
author { build(:user) }
67
end
78
end

0 commit comments

Comments
 (0)