media assets: add options to download or reverse search the image.
This commit is contained in:
@@ -1,15 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# A component that shows a "..." button that when clicked displays a popup menu.
|
||||
class PopupMenuComponent < ApplicationComponent
|
||||
include ViewComponent::SlotableV2
|
||||
|
||||
attr_reader :classes
|
||||
attr_reader :hide_on_click, :classes
|
||||
|
||||
renders_one :button
|
||||
renders_many :items
|
||||
renders_many :items, ->(hide_on_click: nil, &block) do
|
||||
tag.li(block.call, "data-hide-on-click": hide_on_click)
|
||||
end
|
||||
|
||||
# @param hide_on_click [Boolean] If true, then automatically hide the menu when anything inside the menu is clicked.
|
||||
# @param classes [String] A list of CSS classes for the root element.
|
||||
def initialize(classes: nil)
|
||||
def initialize(hide_on_click: true, classes: nil)
|
||||
@hide_on_click = hide_on_click
|
||||
@classes = classes
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<div class="popup-menu inline-block <%= classes %>">
|
||||
<%= tag.div class: "popup-menu inline-block #{classes}".strip, "data-hide-on-click": hide_on_click do %>
|
||||
<a class="popup-menu-button inline-block rounded p-1" href="javascript:void(0)">
|
||||
<% if button.present? %>
|
||||
<%= button %>
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<ul class="popup-menu-content">
|
||||
<% items.each do |item| %>
|
||||
<li><%= item %></li>
|
||||
<%= item %>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -180,7 +180,8 @@ module ApplicationHelper
|
||||
time_tag(time.strftime("%Y-%m-%d %H:%M"), time)
|
||||
end
|
||||
|
||||
def external_link_to(url, text = url, truncate: nil, strip: false, **link_options)
|
||||
def external_link_to(url, text = url, truncate: nil, strip: false, **link_options, &block)
|
||||
text = capture { yield } if block_given?
|
||||
text = text.gsub(%r{\Ahttps?://}i, "") if strip == :scheme
|
||||
text = text.gsub(%r{\Ahttps?://(?:www\.)?}i, "") if strip == :subdomain
|
||||
text = text.truncate(truncate) if truncate
|
||||
|
||||
@@ -381,6 +381,10 @@ module IconHelper
|
||||
svg_icon_tag("table-icon", "M0 96C0 60.65 28.65 32 64 32H448C483.3 32 512 60.65 512 96V416C512 451.3 483.3 480 448 480H64C28.65 480 0 451.3 0 416V96zM64 160H128V96H64V160zM448 96H192V160H448V96zM64 288H128V224H64V288zM448 224H192V288H448V224zM64 416H128V352H64V416zM448 352H192V416H448V352z", viewbox: "0 0 512 512", **options)
|
||||
end
|
||||
|
||||
def download_icon(**options)
|
||||
svg_icon_tag("download-icon", "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32V274.7l-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7V32zM64 352c-35.3 0-64 28.7-64 64v32c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V416c0-35.3-28.7-64-64-64H346.5l-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352H64zM432 456c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z", viewbox: "0 0 512 512", **options)
|
||||
end
|
||||
|
||||
def image_icon(**options)
|
||||
svg_icon_tag("image-icon", "M447.1 32h-384C28.64 32-.0091 60.65-.0091 96v320c0 35.35 28.65 64 63.1 64h384c35.35 0 64-28.65 64-64V96C511.1 60.65 483.3 32 447.1 32zM111.1 96c26.51 0 48 21.49 48 48S138.5 192 111.1 192s-48-21.49-48-48S85.48 96 111.1 96zM446.1 407.6C443.3 412.8 437.9 416 432 416H82.01c-6.021 0-11.53-3.379-14.26-8.75c-2.73-5.367-2.215-11.81 1.334-16.68l70-96C142.1 290.4 146.9 288 152 288s9.916 2.441 12.93 6.574l32.46 44.51l93.3-139.1C293.7 194.7 298.7 192 304 192s10.35 2.672 13.31 7.125l128 192C448.6 396 448.9 402.3 446.1 407.6z", viewbox: "0 0 512 512", **options)
|
||||
end
|
||||
|
||||
@@ -26,8 +26,14 @@ class PopupMenuComponent {
|
||||
|
||||
// Hides the menu when a menu item is clicked.
|
||||
static onMenuItemClicked(event) {
|
||||
let tippy = $(event.target).parents("[data-tippy-root]").get(0)._tippy;
|
||||
tippy.hide();
|
||||
let menuHideOnClick = $(event.target).parents(".popup-menu").data("hide-on-click");
|
||||
let itemHideOnClick = $(event.target).parents("li").data("hide-on-click");
|
||||
let hideOnClick = itemHideOnClick !== undefined ? itemHideOnClick : menuHideOnClick;
|
||||
|
||||
if (hideOnClick) {
|
||||
let tippy = $(event.target).parents("[data-tippy-root]").get(0)._tippy;
|
||||
tippy.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
<% if policy(@media_asset).can_see_image? %>
|
||||
<% component.with_footer do %>
|
||||
<div class="flex flex-none h-6 items-center justify-center text-xs">
|
||||
<span class="mr-2">
|
||||
<div class="flex flex-none gap-2 h-6 items-center justify-center text-xs">
|
||||
<span>
|
||||
<% if @media_asset.post.present? %>
|
||||
<%= link_to image_icon_tag("danbooru-logo.png", class: "h-4"), @media_asset.post, class: "inline-block align-top" %>
|
||||
<% end %>
|
||||
@@ -31,6 +31,50 @@
|
||||
(<%= duration_to_hhmmss(@media_asset.duration) %>)
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<span>
|
||||
<%= render PopupMenuComponent.new(hide_on_click: false) do |menu| %>
|
||||
<% menu.item(hide_on_click: true) do %>
|
||||
<%= link_to "#{@media_asset.original.file_url}?download=1", download: @media_asset.original.file_name do %>
|
||||
<%= download_icon %> Download
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<hr class="border">
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<%= external_link_to "https://saucenao.com/search.php?url=#{CGI.escape(@media_asset.original.file_url)}", target: "_blank" do %>
|
||||
<%= search_icon %> SauceNAO
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<%= external_link_to "https://yandex.com/images/search?rpt=imageview&url=#{CGI.escape(@media_asset.original.file_url)}", target: "_blank" do %>
|
||||
<%= search_icon %> Yandex
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<%= external_link_to "https://lens.google.com/uploadbyurl?url=#{CGI.escape(@media_asset.original.file_url)}", target: "_blank" do %>
|
||||
<%= search_icon %> Google
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<%= external_link_to "https://www.bing.com/images/searchbyimage?cbir=sbi&imgurl=#{CGI.escape(@media_asset.original.file_url)}", target: "_blank" do %>
|
||||
<%= search_icon %> Bing
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% menu.item do %>
|
||||
<%= link_to iqdb_queries_path(search: { media_asset_id: @media_asset.id }), target: "_blank" do %>
|
||||
<%= search_icon %> <%= Danbooru.config.app_name %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
Reference in New Issue
Block a user