diff --git a/assets/js/autocomplete.js b/assets/js/autocomplete.js index 40d85dfb9..c4809a7c4 100644 --- a/assets/js/autocomplete.js +++ b/assets/js/autocomplete.js @@ -134,16 +134,19 @@ function listenAutocomplete() { document.addEventListener('input', event => { removeParent(); fetchLocalAutocomplete(event); + window.clearTimeout(timeout); if (localAc !== null && 'ac' in event.target.dataset) { inputField = event.target; originalTerm = `${inputField.value}`.toLowerCase(); const suggestions = localAc.topK(originalTerm, 5).map(({ name, imageCount }) => ({ label: `${name} (${imageCount})`, value: name })); - return showAutocomplete(suggestions, originalTerm, event.target); + + if (suggestions.length) { + return showAutocomplete(suggestions, originalTerm, event.target); + } } - window.clearTimeout(timeout); // Use a timeout to delay requests until the user has stopped typing timeout = window.setTimeout(() => { inputField = event.target; @@ -158,7 +161,11 @@ function listenAutocomplete() { } else { // inputField could get overwritten while the suggestions are being fetched - use event.target - getSuggestions(fetchedTerm).then(suggestions => showAutocomplete(suggestions, fetchedTerm, event.target)); + getSuggestions(fetchedTerm).then(suggestions => { + if (fetchedTerm === event.target.value) { + showAutocomplete(suggestions, fetchedTerm, event.target); + } + }); } } }, 300); diff --git a/assets/js/misc.js b/assets/js/misc.js index 283201e2b..5733e9540 100644 --- a/assets/js/misc.js +++ b/assets/js/misc.js @@ -11,8 +11,7 @@ function formResult({target, detail}) { const elements = { '#description-form': '.image-description', - '#uploader-form': '.image_uploader', - '#source-form': '#image-source' + '#uploader-form': '.image_uploader' }; function showResult(resultEl, formEl, response) { diff --git a/assets/js/sources.js b/assets/js/sources.js index 210382fc9..bb4ae3adc 100644 --- a/assets/js/sources.js +++ b/assets/js/sources.js @@ -1,6 +1,6 @@ import { inputDuplicatorCreator } from './input-duplicator'; -function imageSourcesCreator() { +function setupInputs() { inputDuplicatorCreator({ addButtonSelector: '.js-image-add-source', fieldSelector: '.js-image-source', @@ -9,4 +9,18 @@ function imageSourcesCreator() { }); } +function imageSourcesCreator() { + setupInputs(); + document.addEventListener('fetchcomplete', ({ target, detail }) => { + const sourceSauce = document.querySelector('.js-sourcesauce'); + + if (target.matches('#source-form')) { + detail.text().then(text => { + sourceSauce.outerHTML = text; + setupInputs(); + }); + } + }); +} + export { imageSourcesCreator }; diff --git a/lib/philomena/galleries.ex b/lib/philomena/galleries.ex index 2b08e3e13..d3c060cef 100644 --- a/lib/philomena/galleries.ex +++ b/lib/philomena/galleries.ex @@ -203,7 +203,7 @@ defmodule Philomena.Galleries do |> case do {:ok, result} -> Images.reindex_image(image) - notify_gallery(gallery) + notify_gallery(gallery, image) reindex_gallery(gallery) {:ok, result} @@ -261,11 +261,11 @@ defmodule Philomena.Galleries do |> Repo.aggregate(:max, :position) end - def notify_gallery(gallery) do - Exq.enqueue(Exq, "notifications", NotificationWorker, ["Galleries", gallery.id]) + def notify_gallery(gallery, image) do + Exq.enqueue(Exq, "notifications", NotificationWorker, ["Galleries", [gallery.id, image.id]]) end - def perform_notify(gallery_id) do + def perform_notify([gallery_id, image_id]) do gallery = get_gallery!(gallery_id) subscriptions = @@ -279,8 +279,8 @@ defmodule Philomena.Galleries do %{ actor_id: gallery.id, actor_type: "Gallery", - actor_child_id: nil, - actor_child_type: nil, + actor_child_id: image_id, + actor_child_type: "Image", action: "added images to" } ) diff --git a/lib/philomena/scrapers/twitter.ex b/lib/philomena/scrapers/twitter.ex index 929651b31..9575c4e51 100644 --- a/lib/philomena/scrapers/twitter.ex +++ b/lib/philomena/scrapers/twitter.ex @@ -1,5 +1,5 @@ defmodule Philomena.Scrapers.Twitter do - @url_regex ~r|\Ahttps?://(?:mobile\.)?twitter.com/([A-Za-z\d_]+)/status/([\d]+)/?| + @url_regex ~r|\Ahttps?://(?:mobile\.)?(?:twitter\|x).com/([A-Za-z\d_]+)/status/([\d]+)/?| @spec can_handle?(URI.t(), String.t()) :: true | false def can_handle?(_uri, url) do diff --git a/lib/philomena_web/controllers/autocomplete/tag_controller.ex b/lib/philomena_web/controllers/autocomplete/tag_controller.ex index e4f9db521..9d43e4702 100644 --- a/lib/philomena_web/controllers/autocomplete/tag_controller.ex +++ b/lib/philomena_web/controllers/autocomplete/tag_controller.ex @@ -30,7 +30,7 @@ defmodule PhilomenaWeb.Autocomplete.TagController do |> Elasticsearch.search_records(preload(Tag, :aliased_tag)) |> Enum.map(&(&1.aliased_tag || &1)) |> Enum.uniq_by(& &1.id) - |> Enum.filter(&(&1.images_count > 3)) + |> Enum.filter(&(&1.images_count > 0)) |> Enum.sort_by(&(-&1.images_count)) |> Enum.take(5) |> Enum.map(&%{label: "#{&1.name} (#{&1.images_count})", value: &1.name}) diff --git a/lib/philomena_web/templates/image/_source.html.slime b/lib/philomena_web/templates/image/_source.html.slime index f1be8bcc4..2d39b3064 100644 --- a/lib/philomena_web/templates/image/_source.html.slime +++ b/lib/philomena_web/templates/image/_source.html.slime @@ -1,4 +1,4 @@ -.block +.js-sourcesauce - has_sources = Enum.any?(@image.sources) = form_for @changeset, Routes.image_source_path(@conn, :update, @image), [method: "put", class: "hidden", id: "source-form", data: [remote: "true"]], fn f -> = if can?(@conn, :edit_metadata, @image) and !@conn.assigns.current_ban do diff --git a/lib/philomena_web/views/image_view.ex b/lib/philomena_web/views/image_view.ex index ba93a50c2..7034c8e78 100644 --- a/lib/philomena_web/views/image_view.ex +++ b/lib/philomena_web/views/image_view.ex @@ -305,13 +305,24 @@ defmodule PhilomenaWeb.ImageView do uri = URI.parse(source) case uri.host do - u when u in ["twitter.com", "www.twitter.com", "pbs.twimg.com", "twimg.com"] -> + u + when u in [ + "twitter.com", + "www.twitter.com", + "mobile.twitter.com", + "x.com", + "mobile.x.com", + "pbs.twimg.com", + "twimg.com" + ] -> "fab fa-twitter" - u when u in ["deviantart.com", "www.deviantart.com", "sta.sh", "www.sta.sh"] -> + u + when u in ["deviantart.com", "sta.sh", "www.sta.sh"] -> "fab fa-deviantart" - u when u in ["cdn.discordapp.com", "discordapp.com", "discord.com"] -> + u + when u in ["cdn.discordapp.com", "discordapp.com", "discord.com", "media.discordapp.net"] -> "fab fa-discord" u when u in ["youtube.com", "www.youtube.com"] -> @@ -329,7 +340,14 @@ defmodule PhilomenaWeb.ImageView do u when u in ["patreon.com", "www.patreon.com"] -> "fab fa-patreon" - u when u in ["ych.art", "ych.commishes.com", "commishes.com"] -> + u + when u in [ + "ych.art", + "ych.commishes.com", + "commishes.com", + "portfolio.commishes.com", + "commishes.io" + ] -> "fa fa-palette" u when u in ["artstation.com", "www.artstation.com"] -> @@ -354,7 +372,8 @@ defmodule PhilomenaWeb.ImageView do "furbooru.org", "inkbunny.net", "e621.net", - "e926.net" + "e926.net", + "sofurry.com" ] -> "fa fa-paw" @@ -373,16 +392,24 @@ defmodule PhilomenaWeb.ImageView do "vulpine.club", "yiff.life", "socel.net", - "octodon.social" + "octodon.social", + "filly.social", + "pone.social", + "hooves.social" ] -> "fab fa-mastodon" + u + when u in ["tumbex.com", "www.tumbex.com", "tumblr.com"] -> + "fab fa-tumblr" + link -> cond do Enum.member?(site_domains, link) -> "favicon-home" - String.contains?(link, "tumblr") -> "fab fa-tumblr" - String.contains?(link, "deviantart") -> "fab fa-deviantart" - String.contains?(link, "sofurry") -> "fa fa-paw" + String.ends_with?(link, ".tumblr.com") -> "fab fa-tumblr" + String.ends_with?(link, ".deviantart.com") -> "fab fa-deviantart" + String.ends_with?(link, ".sofurry.com") -> "fa fa-paw" + String.ends_with?(link, ".userapi.com") -> "fab fa-vk" true -> "fa fa-link" end end