diff --git a/app/components/source_data_component.rb b/app/components/source_data_component.rb
index 848902c8d..a287fb863 100644
--- a/app/components/source_data_component.rb
+++ b/app/components/source_data_component.rb
@@ -2,9 +2,15 @@
class SourceDataComponent < ApplicationComponent
attr_reader :source
- delegate :spinner_icon, to: :helpers
+ delegate :spinner_icon, :external_site_icon, to: :helpers
def initialize(source:)
@source = source
end
+
+ def profile_urls(artist)
+ artist.urls.active.reject(&:secondary_url?).sort_by do |artist_url|
+ [artist_url.priority, artist_url.domain, artist_url.url]
+ end
+ end
end
diff --git a/app/components/source_data_component/source_data_component.html.erb b/app/components/source_data_component/source_data_component.html.erb
index 57f1c0981..0bd693257 100644
--- a/app/components/source_data_component/source_data_component.html.erb
+++ b/app/components/source_data_component/source_data_component.html.erb
@@ -3,46 +3,55 @@
<%= spinner_icon class: "source-data-loading" %>
<% if @source.present? %>
-
-
-
- Artist
-
-
- <% if @source.artist_name.blank? %>
- None
- <% else %>
- <%= external_link_to @source.profile_url, @source.artist_name, class: "source-data-artist-profile" %>
+
+
+ <% if @source.artist_name.blank? %>
+
+ | Artist |
+ None |
+
+ <% elsif @source.artists.empty? %>
+
+ | Artist |
+
+ <%= external_link_to @source.profile_url, @source.artist_name %>
+ (<%= link_to "Create new artist", new_artist_path(artist: { source: @source.canonical_url }) %>)
+ |
+
+ <% else %>
+ <% @source.artists.each do |artist| %>
+
+ | Artist |
+
+ <%= link_to artist.name, artist_path(artist), class: tag_class(artist.tag) %>
- <% if @source.artists.empty? %>
- (<%= link_to "Create new artist", new_artist_path(artist: { source: @source.canonical_url }), class: "source-data-create-new-artist" %>)
+
+ <% profile_urls(artist).each do |artist_url| %>
+ <%= external_link_to artist_url.url, external_site_icon(artist_url.site_name), title: artist_url.url %>
+ <% end %>
+
+ |
+
+ <% end %>
+ <% end %>
+
+
+ | Tags |
+
+ <% if @source.tags.empty? %>
+ None
<% else %>
- (
- <% @source.artists.each do |artist| %>
- - <%= link_to artist.name, artist_path(artist), class: tag_class(artist.tag) %>
+
+ <% @source.tags.each do |tag, href| %>
+ -
+ <%= external_link_to href, tag, class: "source-data-tag" %>
+
<% end %>
- )
+
<% end %>
- <% end %>
-
-
-
- |
+
+
+
<% end %>
diff --git a/app/components/source_data_component/source_data_component.scss b/app/components/source_data_component/source_data_component.scss
index 85585914a..48cea3c06 100644
--- a/app/components/source_data_component/source_data_component.scss
+++ b/app/components/source_data_component/source_data_component.scss
@@ -6,15 +6,27 @@ div.source-data {
&.loading .source-data-content { display: none; }
&.loading .source-data-fetch { display: none; }
- ul {
+ th {
+ padding-right: 1rem;
+ padding-bottom: 0.25rem;
+ }
+
+ td {
+ vertical-align: top;
+ }
+
+ .icon {
+ height: 1rem;
+ font-size: 1rem;
+ vertical-align: bottom;
+ }
+
+ .source-data-tag {
display: inline-block;
- }
-
- dt, dd, li {
- display: inline;
- }
-
- dt, .source-data-tags li {
- margin-right: 1em;
+ background-color: var(--wiki-page-other-name-background-color);
+ padding: 0 0.25rem;
+ margin-right: 0.25rem;
+ margin-bottom: 0.25rem;
+ border-radius: 0.25rem;
}
}
diff --git a/app/helpers/icon_helper.rb b/app/helpers/icon_helper.rb
index aa6f2f63f..e300e4820 100644
--- a/app/helpers/icon_helper.rb
+++ b/app/helpers/icon_helper.rb
@@ -11,6 +11,11 @@ module IconHelper
end
end
+ def image_icon_tag(filename, class: nil, **options)
+ klass = binding.local_variable_get(:class)
+ tag.img(src: "/images/#{filename}", class: "icon #{klass}", **options)
+ end
+
# fontawesome.com/icons/arrow-alt-up
def upvote_icon(**options)
svg_icon_tag("upvote-icon", "M272 480h-96c-13.3 0-24-10.7-24-24V256H48.2c-21.4 0-32.1-25.8-17-41L207 39c9.4-9.4 24.6-9.4 34 0l175.8 176c15.1 15.1 4.4 41-17 41H296v200c0 13.3-10.7 24-24 24z", **options)
@@ -148,4 +153,83 @@ module IconHelper
def plus_icon(**options)
icon_tag("fas fa-plus", **options)
end
+
+ def globe_icon(**options)
+ icon_tag("fas fa-globe", **options)
+ end
+
+ def discord_icon(**options)
+ image_icon_tag("discord-logo.png", **options)
+ end
+
+ def github_icon(**options)
+ image_icon_tag("github-logo.png", **options)
+ end
+
+ def twitter_icon(**options)
+ image_icon_tag("twitter-logo.png", **options)
+ end
+
+ def external_site_icon(site_name, **options)
+ case site_name
+ when "ArtStation"
+ image_icon_tag("artstation-logo.png", **options)
+ when "BCY"
+ image_icon_tag("bcy-logo.png", **options)
+ when "Booth.pm"
+ image_icon_tag("booth-pm-logo.png", **options)
+ when "Circle.ms"
+ image_icon_tag("circle-ms-logo.png", **options)
+ when "DLSite"
+ image_icon_tag("dlsite-logo.png", **options)
+ when "Deviant Art"
+ image_icon_tag("deviantart-logo.png", **options)
+ when "Facebook"
+ image_icon_tag("facebook-logo.png", **options)
+ when "Fantia"
+ image_icon_tag("fantia-logo.png", **options)
+ when "FC2"
+ image_icon_tag("fc2-logo.png", **options)
+ when "Gumroad"
+ image_icon_tag("gumroad-logo.png", **options)
+ when "Instagram"
+ image_icon_tag("instagram-logo.png", **options)
+ when "Lofter"
+ image_icon_tag("lofter-logo.png", **options)
+ when "Melonbooks"
+ image_icon_tag("melonbooks-logo.png", **options)
+ when "Nico Seiga"
+ image_icon_tag("nicoseiga-logo.png", **options)
+ when "Nijie"
+ image_icon_tag("nijie-logo.png", **options)
+ when "Patreon"
+ image_icon_tag("patreon-logo.png", **options)
+ when "pawoo.net"
+ image_icon_tag("pawoo-logo.png", **options)
+ when "Pixiv"
+ image_icon_tag("pixiv-logo.png", **options)
+ when "Pixiv Fanbox"
+ image_icon_tag("pixiv-fanbox-logo.png", **options)
+ when "Pixiv Sketch"
+ image_icon_tag("pixiv-sketch-logo.png", **options)
+ when "Privatter"
+ image_icon_tag("privatter-logo.png", **options)
+ when "Skeb"
+ image_icon_tag("skeb-logo.png", **options)
+ when "Tinami"
+ image_icon_tag("tinami-logo.png", **options)
+ when "Tumblr"
+ image_icon_tag("tumblr-logo.png", **options)
+ when "Twitter"
+ image_icon_tag("twitter-logo.png", **options)
+ when "Toranoana"
+ image_icon_tag("toranoana-logo.png", **options)
+ when "Weibo"
+ image_icon_tag("weibo-logo.png", **options)
+ when "Youtube"
+ image_icon_tag("youtube-logo.png", **options)
+ else
+ globe_icon(**options)
+ end
+ end
end
diff --git a/app/logical/sources/strategies/base.rb b/app/logical/sources/strategies/base.rb
index 15f476a15..52a190bd5 100644
--- a/app/logical/sources/strategies/base.rb
+++ b/app/logical/sources/strategies/base.rb
@@ -60,7 +60,47 @@ module Sources
end
def site_name
- Addressable::URI.heuristic_parse(url)&.host
+ host = Addressable::URI.heuristic_parse(url)&.host
+
+ # XXX should go in dedicated strategies.
+ case host
+ when /bcy\.net\z/i
+ "BCY"
+ when /booth\.pm\z/i
+ "Booth.pm"
+ when /circle\.ms\z/i
+ "Circle.ms"
+ when /dlsite\.(com|net)\z/i
+ "DLSite"
+ when /facebook\.com\z/i
+ "Facebook"
+ when /fantia\.jp\z/i
+ "Fantia"
+ when /fc2\.com\z/i
+ "FC2"
+ when /gumroad\.com\z/i
+ "Gumroad"
+ when /instagram\.com\z/i
+ "Instagram"
+ when /lofter\.com\z/i
+ "Lofter"
+ when /melonbooks\.co\.jp\z/i
+ "Melonbooks"
+ when /patreon\.com\z/i
+ "Patreon"
+ when /privatter\.net\z/i
+ "Privatter"
+ when /skeb\.jp\z/i
+ "Skeb"
+ when /tinami\.com\z/i
+ "Tinami"
+ when /toranoana\.(jp|shop)\z/i
+ "Toranoana"
+ when /youtube\.com\z/i
+ "Youtube"
+ else
+ host
+ end
rescue Addressable::URI::InvalidURIError
nil
end
diff --git a/app/logical/sources/strategies/pixiv.rb b/app/logical/sources/strategies/pixiv.rb
index 10e5e7e69..ad961ba11 100644
--- a/app/logical/sources/strategies/pixiv.rb
+++ b/app/logical/sources/strategies/pixiv.rb
@@ -90,7 +90,12 @@ module Sources
end
def site_name
- "Pixiv"
+ # XXX pixiv sketch should be in a separate strategy
+ if parsed_url.host.in?(%w[sketch.pixiv.net img-sketch.pixiv.net img-sketch.pximg.net])
+ "Pixiv Sketch"
+ else
+ "Pixiv"
+ end
end
def image_urls
diff --git a/app/models/artist_url.rb b/app/models/artist_url.rb
index fa9b359fb..3eda90b18 100644
--- a/app/models/artist_url.rb
+++ b/app/models/artist_url.rb
@@ -7,6 +7,7 @@ class ArtistUrl < ApplicationRecord
scope :url_matches, ->(url) { url_attribute_matches(:url, url) }
scope :normalized_url_matches, ->(url) { url_attribute_matches(:normalized_url, url) }
+ scope :active, -> { where(is_active: true) }
def self.parse_prefix(url)
prefix, url = url.match(/\A(-)?(.*)/)[1, 2]
@@ -68,24 +69,51 @@ class ArtistUrl < ApplicationRecord
end
end
- def priority
- if normalized_url =~ /pixiv\.net\/member\.php/
- 10
+ def domain
+ uri = Addressable::URI.parse(normalized_url)
+ uri.domain
+ end
- elsif normalized_url =~ /seiga\.nicovideo\.jp\/user\/illust/
- 10
-
- elsif normalized_url =~ /twitter\.com/ && normalized_url !~ /status/
- 15
-
- elsif normalized_url =~ /tumblr|patreon|deviantart|artstation/
- 20
+ def site_name
+ source = Sources::Strategies.find(normalized_url)
+ source.site_name
+ end
+ # A secondary URL is an artist URL that we don't normally want to display,
+ # usually because it's redundant with the primary profile URL.
+ def secondary_url?
+ case url
+ when %r!pixiv\.net/stacc!i
+ true
+ when %r!pixiv\.net/fanbox!i
+ true
+ when %r!twitter\.com/intent!i
+ true
+ when %r!lohas\.nicoseiga\.jp!i
+ true
+ when %r!(?:www|com|dic)\.nicovideo\.jp!i
+ true
+ when %r!pawoo\.net/web/accounts!i
+ true
+ when %r!www\.artstation\.com!i
+ true
else
- 100
+ false
end
end
+ # The sort order of sites in artist URL lists.
+ def priority
+ sites = %w[
+ Pixiv Twitter
+ ArtStation Deviant\ Art Nico\ Seiga Nijie pawoo.net Pixiv\ Fanbox Pixiv\ Sketch Tinami Tumblr
+ Booth.pm Facebook Fantia FC2 Gumroad Instagram Lofter Patreon Privatter Skeb Weibo Youtube
+ Circle.ms DLSite Melonbooks Toranoana
+ ]
+
+ sites.index(site_name) || 1000
+ end
+
def normalize
# Perform some normalization with Addressable on the URL itself
# - Converts scheme and hostname to downcase
diff --git a/app/views/static/_footer.html.erb b/app/views/static/_footer.html.erb
index e9a91bb27..6678391cb 100644
--- a/app/views/static/_footer.html.erb
+++ b/app/views/static/_footer.html.erb
@@ -6,17 +6,17 @@
<% if Danbooru.config.source_code_url.present? %>
<%= link_to Danbooru.config.source_code_url, title: "Running commit: #{Rails.application.config.x.git_hash&.first(9)}", class: "social-icon" do %>
-
+ <%= github_icon %>
<% end %>
<% end %>
<% if Danbooru.config.twitter_username.present? %>
<%= link_to "https://twitter.com/#{Danbooru.config.twitter_username}", class: "social-icon" do %>
-
+ <%= twitter_icon %>
<% end %>
<% end %>
<% if Danbooru.config.discord_server_url.present? %>
<%= link_to Danbooru.config.discord_server_url, class: "social-icon" do %>
-
+ <%= discord_icon %>
<% end %>
<% end %>
diff --git a/public/images/artstation-logo.png b/public/images/artstation-logo.png
new file mode 100644
index 000000000..8893af08e
Binary files /dev/null and b/public/images/artstation-logo.png differ
diff --git a/public/images/bcy-logo.png b/public/images/bcy-logo.png
new file mode 100644
index 000000000..a578c6b31
Binary files /dev/null and b/public/images/bcy-logo.png differ
diff --git a/public/images/booth-pm-logo.png b/public/images/booth-pm-logo.png
new file mode 100644
index 000000000..95563868a
Binary files /dev/null and b/public/images/booth-pm-logo.png differ
diff --git a/public/images/circle-ms-logo.png b/public/images/circle-ms-logo.png
new file mode 100644
index 000000000..4a0050e57
Binary files /dev/null and b/public/images/circle-ms-logo.png differ
diff --git a/public/images/deviantart-logo.png b/public/images/deviantart-logo.png
new file mode 100644
index 000000000..c51bd70d5
Binary files /dev/null and b/public/images/deviantart-logo.png differ
diff --git a/public/images/dlsite-logo.png b/public/images/dlsite-logo.png
new file mode 100644
index 000000000..e82c32d1a
Binary files /dev/null and b/public/images/dlsite-logo.png differ
diff --git a/public/images/facebook-logo.png b/public/images/facebook-logo.png
new file mode 100644
index 000000000..d6b266e15
Binary files /dev/null and b/public/images/facebook-logo.png differ
diff --git a/public/images/fantia-logo.png b/public/images/fantia-logo.png
new file mode 100755
index 000000000..5d3b5f854
Binary files /dev/null and b/public/images/fantia-logo.png differ
diff --git a/public/images/fc2-logo.png b/public/images/fc2-logo.png
new file mode 100644
index 000000000..261122bb8
Binary files /dev/null and b/public/images/fc2-logo.png differ
diff --git a/public/images/gumroad-logo.png b/public/images/gumroad-logo.png
new file mode 100644
index 000000000..d19669a44
Binary files /dev/null and b/public/images/gumroad-logo.png differ
diff --git a/public/images/instagram-logo.png b/public/images/instagram-logo.png
new file mode 100644
index 000000000..47ed0f19f
Binary files /dev/null and b/public/images/instagram-logo.png differ
diff --git a/public/images/lofter-logo.png b/public/images/lofter-logo.png
new file mode 100644
index 000000000..f9ba0efc9
Binary files /dev/null and b/public/images/lofter-logo.png differ
diff --git a/public/images/melonbooks-logo.png b/public/images/melonbooks-logo.png
new file mode 100644
index 000000000..feb58937e
Binary files /dev/null and b/public/images/melonbooks-logo.png differ
diff --git a/public/images/nicoseiga-logo.png b/public/images/nicoseiga-logo.png
new file mode 100644
index 000000000..b96d64c74
Binary files /dev/null and b/public/images/nicoseiga-logo.png differ
diff --git a/public/images/nijie-logo.png b/public/images/nijie-logo.png
new file mode 100644
index 000000000..0df8a7557
Binary files /dev/null and b/public/images/nijie-logo.png differ
diff --git a/public/images/patreon-logo.png b/public/images/patreon-logo.png
new file mode 100644
index 000000000..baf5cc33b
Binary files /dev/null and b/public/images/patreon-logo.png differ
diff --git a/public/images/pawoo-logo.png b/public/images/pawoo-logo.png
new file mode 100644
index 000000000..4706d053c
Binary files /dev/null and b/public/images/pawoo-logo.png differ
diff --git a/public/images/pixiv-fanbox-logo.png b/public/images/pixiv-fanbox-logo.png
new file mode 100644
index 000000000..3de3aac89
Binary files /dev/null and b/public/images/pixiv-fanbox-logo.png differ
diff --git a/public/images/pixiv-logo.png b/public/images/pixiv-logo.png
new file mode 100644
index 000000000..8a9c9925b
Binary files /dev/null and b/public/images/pixiv-logo.png differ
diff --git a/public/images/pixiv-sketch-logo.png b/public/images/pixiv-sketch-logo.png
new file mode 100755
index 000000000..9d98c65b1
Binary files /dev/null and b/public/images/pixiv-sketch-logo.png differ
diff --git a/public/images/privatter-logo.png b/public/images/privatter-logo.png
new file mode 100644
index 000000000..47178f636
Binary files /dev/null and b/public/images/privatter-logo.png differ
diff --git a/public/images/skeb-logo.png b/public/images/skeb-logo.png
new file mode 100644
index 000000000..447451309
Binary files /dev/null and b/public/images/skeb-logo.png differ
diff --git a/public/images/tinami-logo.png b/public/images/tinami-logo.png
new file mode 100644
index 000000000..c62889732
Binary files /dev/null and b/public/images/tinami-logo.png differ
diff --git a/public/images/toranoana-logo.png b/public/images/toranoana-logo.png
new file mode 100644
index 000000000..440b23ab0
Binary files /dev/null and b/public/images/toranoana-logo.png differ
diff --git a/public/images/tumblr-logo.png b/public/images/tumblr-logo.png
new file mode 100644
index 000000000..57b3d65b9
Binary files /dev/null and b/public/images/tumblr-logo.png differ
diff --git a/public/images/weibo-logo.png b/public/images/weibo-logo.png
new file mode 100644
index 000000000..6b693e887
Binary files /dev/null and b/public/images/weibo-logo.png differ
diff --git a/public/images/youtube-logo.png b/public/images/youtube-logo.png
new file mode 100644
index 000000000..4344327fa
Binary files /dev/null and b/public/images/youtube-logo.png differ