mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 11:44:49 +08:00
FEATURE: Basic support for threads.net onebox (#22471)
This commit is contained in:
parent
dc46acb851
commit
3fd327c458
|
@ -1010,3 +1010,81 @@ aside.onebox.preview-error .site-icon {
|
|||
height: 16px;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.onebox.threadsstatus .onebox-body {
|
||||
.thumbnail,
|
||||
.thumbnail.onebox-avatar {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.threads-screen-name {
|
||||
font-size: var(--font-down-1);
|
||||
}
|
||||
h4 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.thread-contents .thread-description {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
p,
|
||||
.thread-contents {
|
||||
clear: left;
|
||||
padding: 1em 0;
|
||||
|
||||
.quoted {
|
||||
border: 1px solid var(--primary-low);
|
||||
padding: 0.5em 1em;
|
||||
margin-top: 1em;
|
||||
white-space: normal;
|
||||
|
||||
.quoted-link {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.quoted-title {
|
||||
font-weight: bold;
|
||||
margin: 0.5em 0;
|
||||
padding: 0;
|
||||
|
||||
span {
|
||||
font-weight: lighter;
|
||||
color: var(--primary-medium);
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.date {
|
||||
display: flex;
|
||||
line-height: var(--line-height-small);
|
||||
|
||||
.timestamp {
|
||||
color: var(--primary-medium);
|
||||
}
|
||||
}
|
||||
|
||||
.like,
|
||||
.replies {
|
||||
align-items: center;
|
||||
color: var(--primary-medium);
|
||||
display: flex;
|
||||
margin-left: 0.75em;
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.is-reply {
|
||||
color: var(--primary-medium);
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,6 +165,7 @@ require_relative "engine/google_play_app_onebox"
|
|||
require_relative "engine/image_onebox"
|
||||
require_relative "engine/video_onebox"
|
||||
require_relative "engine/audio_onebox"
|
||||
require_relative "engine/threads_status_onebox"
|
||||
require_relative "engine/stack_exchange_onebox"
|
||||
require_relative "engine/twitter_status_onebox"
|
||||
require_relative "engine/wikimedia_onebox"
|
||||
|
|
91
lib/onebox/engine/threads_status_onebox.rb
Normal file
91
lib/onebox/engine/threads_status_onebox.rb
Normal file
|
@ -0,0 +1,91 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Onebox
|
||||
module Engine
|
||||
class ThreadsStatusOnebox
|
||||
include Engine
|
||||
include LayoutSupport
|
||||
include HTML
|
||||
|
||||
matches_regexp(%r{^https?://www\.threads\.net/t/(?<id>[\d\w_-]+)/?.*?$})
|
||||
always_https
|
||||
|
||||
def self.priority
|
||||
1
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def link
|
||||
raw.css("link[rel='canonical']").first["href"]
|
||||
end
|
||||
|
||||
def likes
|
||||
@og[:description].split(" ").first
|
||||
end
|
||||
|
||||
def replies
|
||||
@og[:description].split(", ").drop(1).join(", ").split(" repl").first
|
||||
end
|
||||
|
||||
def description
|
||||
text = @og[:description].split(". ").drop(1).join(". ")
|
||||
linkify_mentions(text)
|
||||
end
|
||||
|
||||
def title
|
||||
@og[:title].split(" (@").first
|
||||
end
|
||||
|
||||
def screen_name
|
||||
@og[:title].split(" (@").drop(1).join(" (@").split(") on Threads")[0]
|
||||
end
|
||||
|
||||
def avatar
|
||||
poster_response =
|
||||
begin
|
||||
Onebox::Helpers.fetch_response("https://www.threads.net/@#{screen_name}")
|
||||
rescue StandardError
|
||||
return nil
|
||||
end
|
||||
poster_html = Nokogiri.HTML(poster_response)
|
||||
poster_data = ::Onebox::OpenGraph.new(poster_html).data
|
||||
poster_data[:image]
|
||||
end
|
||||
|
||||
def image
|
||||
@og[:image]
|
||||
end
|
||||
|
||||
def favicon
|
||||
raw.css("link[rel='icon']").first["href"]
|
||||
end
|
||||
|
||||
def linkify_mentions(text)
|
||||
text.gsub(/@([\w\d]+)/, "<a href='https://www.threads.net/@\\1'>@\\1</a>")
|
||||
end
|
||||
|
||||
def data
|
||||
@og = ::Onebox::OpenGraph.new(raw).data
|
||||
|
||||
@data ||= {
|
||||
favicon: favicon,
|
||||
link: link,
|
||||
description: description,
|
||||
image: image,
|
||||
title: title,
|
||||
screen_name: screen_name,
|
||||
avatar: avatar,
|
||||
likes: likes,
|
||||
replies: replies,
|
||||
}
|
||||
|
||||
# if the image is the same as the avatar, don't show it
|
||||
# means it's a thread with no image
|
||||
@data[:image] = nil if @data[:image].split("?").first == @data[:avatar].split("?").first
|
||||
|
||||
@data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
lib/onebox/templates/threadsstatus.mustache
Normal file
30
lib/onebox/templates/threadsstatus.mustache
Normal file
|
@ -0,0 +1,30 @@
|
|||
{{#avatar}}<img src="{{avatar}}" class="thumbnail onebox-avatar">{{/avatar}}
|
||||
<h4><a href="{{link}}" target="_blank" rel="noopener">{{title}}</a></h4>
|
||||
<div class="threads-screen-name"><a href="{{link}}" target="_blank" rel="noopener">@{{screen_name}}</a></div>
|
||||
|
||||
<div class="thread-contents">
|
||||
<span class="thread-description">{{{description}}}</span>
|
||||
{{#image}}
|
||||
<div class="scale-images"><img src="{{image}}"></div>
|
||||
{{/image}}
|
||||
</div>
|
||||
|
||||
<div class="date">
|
||||
{{#likes}}
|
||||
<span class="like">
|
||||
<svg viewBox="0 0 512 512" width="14px" height="16px" aria-hidden="true">
|
||||
<path d="M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z"></path>
|
||||
</svg>
|
||||
{{likes}}
|
||||
</span>
|
||||
{{/likes}}
|
||||
|
||||
{{#replies}}
|
||||
<span class="replies">
|
||||
<svg viewBox="0 0 640 512" width="14px" height="16px" aria-hidden="true">
|
||||
<path d="M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z"></path>
|
||||
</svg>
|
||||
{{replies}}
|
||||
</span>
|
||||
{{/replies}}
|
||||
</div>
|
88
spec/fixtures/onebox/threadsstatus_featured_image.response
vendored
Normal file
88
spec/fixtures/onebox/threadsstatus_featured_image.response
vendored
Normal file
File diff suppressed because one or more lines are too long
85
spec/fixtures/onebox/threadsstatus_profile.response
vendored
Normal file
85
spec/fixtures/onebox/threadsstatus_profile.response
vendored
Normal file
File diff suppressed because one or more lines are too long
84
spec/fixtures/onebox/threadsstatus_without_image.response
vendored
Normal file
84
spec/fixtures/onebox/threadsstatus_without_image.response
vendored
Normal file
File diff suppressed because one or more lines are too long
94
spec/lib/onebox/engine/threads_status_onebox_spec.rb
Normal file
94
spec/lib/onebox/engine/threads_status_onebox_spec.rb
Normal file
|
@ -0,0 +1,94 @@
|
|||
# frozen_string_literal: true
|
||||
RSpec.describe Onebox::Engine::ThreadsStatusOnebox do
|
||||
context "with a thread with only text" do
|
||||
let(:link) { "https://www.threads.net/t/CuVvRcttG57" }
|
||||
let(:html) { described_class.new(link).to_html }
|
||||
|
||||
before do
|
||||
stub_request(:get, link).to_return(
|
||||
status: 200,
|
||||
body: onebox_response("threadsstatus_without_image"),
|
||||
)
|
||||
stub_request(:get, "https://www.threads.net/@rafael_falco").to_return(
|
||||
status: 200,
|
||||
body: onebox_response("threadsstatus_without_image"),
|
||||
)
|
||||
end
|
||||
|
||||
it "includes threads content" do
|
||||
expect(html).to include("trazer a lista de follows")
|
||||
end
|
||||
|
||||
it "includes name" do
|
||||
expect(html).to include("Rafael Silva")
|
||||
end
|
||||
|
||||
it "includes username" do
|
||||
expect(html).to include("@rafael_falco")
|
||||
end
|
||||
|
||||
it "includes user avatar" do
|
||||
expect(html).to include(
|
||||
"https://scontent.cdninstagram.com/v/t51.2885-19/358195671_1485179698889636_5420020496346583344_n.jpg?stp=dst-jpg_s150x150&_nc_ht=scontent.cdninstagram.com&_nc_cat=108&_nc_ohc=UbFgg6blcOUAX8XVrUj&edm=APs17CUBAAAA&ccb=7-5&oh=00_AfDTSDE1W16bDEOUCofc_RLwOXbwfwL83BafmR_f4_ou6g&oe=64AB848C&_nc_sid=10d13b",
|
||||
)
|
||||
end
|
||||
|
||||
it "includes twitter link" do
|
||||
expect(html).to include("https://www.threads.net/t/CuVvRcttG57")
|
||||
end
|
||||
|
||||
it "includes twitter likes" do
|
||||
expect(html).to include("3")
|
||||
end
|
||||
|
||||
it "includes twitter retweets" do
|
||||
expect(html).to include("1")
|
||||
end
|
||||
end
|
||||
|
||||
context "with a thread containing an image" do
|
||||
let(:link) { "https://www.threads.net/t/CuWRRrQuql9" }
|
||||
let(:html) { described_class.new(link).to_html }
|
||||
|
||||
before do
|
||||
stub_request(:get, link).to_return(
|
||||
status: 200,
|
||||
body: onebox_response("threadsstatus_featured_image"),
|
||||
)
|
||||
stub_request(:get, "https://www.threads.net/@joyqiuu").to_return(
|
||||
status: 200,
|
||||
body: onebox_response("threadsstatus_profile"),
|
||||
)
|
||||
end
|
||||
|
||||
it "includes threads content" do
|
||||
expect(html).to include("10M users later")
|
||||
end
|
||||
|
||||
it "includes name" do
|
||||
expect(html).to include("Joy Qiu")
|
||||
end
|
||||
|
||||
it "includes username" do
|
||||
expect(html).to include("@joyqiuu")
|
||||
end
|
||||
|
||||
it "includes user avatar" do
|
||||
expect(html).to include(
|
||||
"https://scontent.cdninstagram.com/v/t51.2885-19/358167674_306426985144380_6235341132840289293_n.jpg?stp=dst-jpg_s640x640&_nc_ht=scontent.cdninstagram.com&_nc_cat=1&_nc_ohc=KqFQdmSjeMsAX-OWNHA&edm=APs17CUBAAAA&ccb=7-5&oh=00_AfDrfi6q0GGPALemTc0YzaE-Bnxm0GJ3QTrswCox095yRA&oe=64AC85F1&_nc_sid=10d13b",
|
||||
)
|
||||
end
|
||||
|
||||
it "includes twitter link" do
|
||||
expect(html).to include("https://www.threads.net/t/CuWRRrQuql9")
|
||||
end
|
||||
|
||||
it "includes twitter likes" do
|
||||
expect(html).to include("5.8K")
|
||||
end
|
||||
|
||||
it "includes twitter retweets" do
|
||||
expect(html).to include("449")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user