Merge pull request #3957 from evazion/fix-related-tags

Related tags: build html server-side, eliminate cookies
This commit is contained in:
Albert Yi
2018-10-24 17:34:14 -07:00
committed by GitHub
24 changed files with 282 additions and 426 deletions

View File

@@ -1,5 +1,5 @@
class ArtistUrlsController < ApplicationController
respond_to :json, :xml, :html
respond_to :js, :json, :xml, :html
before_action :member_only, except: [:index]
def index

View File

@@ -46,7 +46,6 @@ class PostsController < ApplicationController
@post = Post.find(params[:id])
@post.update(post_params) if @post.visible?
save_recent_tags
respond_with_post_after_update(@post)
end
@@ -96,15 +95,6 @@ private
params[:tags] || (params[:post] && params[:post][:tags])
end
def save_recent_tags
if @post
tags = Tag.scan_tags(@post.tag_string)
tags = (TagAlias.to_aliased(tags) + Tag.scan_tags(cookies[:recent_tags])).uniq.slice(0, 30)
cookies[:recent_tags] = tags.join(" ")
cookies[:recent_tags_with_categories] = Tag.categories_for(tags).to_a.flatten.join(" ")
end
end
def respond_with_post_after_update(post)
respond_with(post) do |format|
format.html do

View File

@@ -1,10 +1,9 @@
class RelatedTagsController < ApplicationController
respond_to :json
respond_to :html, :only=>[:show]
respond_to :json, :xml, :js, :html, except: [:update]
before_action :require_reportbooru_key, only: [:update]
def show
@query = RelatedTagQuery.new(params[:query].to_s.downcase, params[:category])
@query = RelatedTagQuery.new(query: params[:query], category: params[:category], user: CurrentUser.user)
respond_with(@query) do |format|
format.json do
render :json => @query.to_json

View File

@@ -58,21 +58,11 @@ class UploadsController < ApplicationController
flash[:notice] = @service.warnings.join(".\n \n")
end
save_recent_tags
respond_with(@upload)
end
private
def save_recent_tags
if @upload
tags = Tag.scan_tags(@upload.tag_string)
tags = (TagAlias.to_aliased(tags) + Tag.scan_tags(cookies[:recent_tags])).compact.uniq.slice(0, 30)
cookies[:recent_tags] = tags.join(" ")
cookies[:recent_tags_with_categories] = Tag.categories_for(tags).to_a.flatten.join(" ")
end
end
def upload_params
permitted_params = %i[
file source tag_string rating status parent_id artist_commentary_title

View File

@@ -66,8 +66,6 @@ class UsersController < ApplicationController
@user = User.find(params[:id])
check_privilege(@user)
@user.update(user_params(:update))
cookies.delete(:favorite_tags)
cookies.delete(:favorite_tags_with_categories)
if @user.errors.any?
flash[:notice] = @user.errors.full_messages.join("; ")
else

View File

@@ -38,7 +38,7 @@ export { default as Note } from '../src/javascripts/notes.js';
export { default as Post } from '../src/javascripts/posts.js.erb';
export { default as PostModeMenu } from '../src/javascripts/post_mode_menu.js';
export { default as PostTooltip } from '../src/javascripts/post_tooltips.js';
export { default as RelatedTag } from '../src/javascripts/related_tag.js.erb';
export { default as RelatedTag } from '../src/javascripts/related_tag.js';
export { default as Shortcuts } from '../src/javascripts/shortcuts.js';
export { default as Upload } from '../src/javascripts/uploads.js';
export { default as Utility } from '../src/javascripts/utility.js';

View File

@@ -1,6 +1,5 @@
import Utility from './utility'
import Hammer from 'hammerjs'
import RelatedTag from './related_tag.js.erb'
import Cookie from './cookie'
import Note from './notes'
import SavedSearch from './saved_searches'
@@ -83,11 +82,6 @@ Post.initialize_edit_dialog = function() {
Post.open_edit_dialog();
e.preventDefault();
});
$("#toggle-related-tags-link").on("click.danbooru", function(e) {
RelatedTag.toggle();
e.preventDefault();
});
}
Post.open_edit_dialog = function() {
@@ -99,14 +93,11 @@ Post.open_edit_dialog = function() {
$("#comments").hide();
$("#post-sections li").removeClass("active");
$("#post-edit-link").parent("li").addClass("active");
$("#related-tags-container").show();
var $tag_string = $("#post_tag_string,#upload_tag_string");
$("div.input").has($tag_string).prevAll().hide();
$("#open-edit-dialog").hide();
$("#toggle-related-tags-link").show().click();
var dialog = $("<div/>").attr("id", "edit-dialog");
$("#form").appendTo(dialog);
dialog.dialog({
@@ -158,17 +149,18 @@ Post.open_edit_dialog = function() {
$tag_string.css({"resize": "none", "width": "100%"});
$tag_string.focus().selectEnd().height($tag_string[0].scrollHeight);
$(document).trigger("danbooru:open-post-edit-dialog");
}
Post.close_edit_dialog = function(e, ui) {
$("#form").appendTo($("#c-posts #edit,#c-uploads #a-new"));
$("#edit-dialog").remove();
RelatedTag.show();
$("#toggle-related-tags-link").hide();
var $tag_string = $("#post_tag_string,#upload_tag_string");
$("div.input").has($tag_string).prevAll().show();
$("#open-edit-dialog").show();
$tag_string.css({"resize": "", "width": ""});
$(document).trigger("danbooru:close-post-edit-dialog");
}
Post.initialize_similar = function() {
@@ -434,9 +426,8 @@ Post.initialize_post_sections = function() {
$("#edit").show();
$("#comments").hide();
$("#post_tag_string").focus().selectEnd().height($("#post_tag_string")[0].scrollHeight);
$("#related-tags-button").trigger("click");
$("#fetch-data-manual").trigger("click");
$("#recommended").hide();
$(document).trigger("danbooru:open-post-edit-tab");
} else if (e.target.hash === "#recommended") {
$("#comments").hide();
$("#edit").hide();

View File

@@ -0,0 +1,148 @@
import Uploads from './uploads';
import Utility from './utility';
let RelatedTag = {};
RelatedTag.initialize_all = function() {
$(document).on("click.danbooru", ".related-tags-button", RelatedTag.on_click_related_tags_button);
$(document).on("click.danbooru", ".related-tags a.search-tag", RelatedTag.toggle_tag);
$(document).on("click.danbooru", "#show-related-tags-link", RelatedTag.show);
$(document).on("click.danbooru", "#hide-related-tags-link", RelatedTag.hide);
$(document).on("keyup.danbooru.relatedTags", "#upload_tag_string, #post_tag_string", RelatedTag.update_selected);
$(document).on("danbooru:update-source-data", RelatedTag.on_update_source_data);
$(document).on("danbooru:open-post-edit-dialog", RelatedTag.hide);
$(document).on("danbooru:close-post-edit-dialog", RelatedTag.show);
// Initialize the recent/favorite/translated/artist tag columns once, the first time the related tags are shown.
$(document).one("danbooru:show-related-tags", RelatedTag.initialize_recent_and_favorite_tags);
$(document).one("danbooru:show-related-tags", Uploads.fetch_data_manual);
// Show the related tags automatically when the "Edit" tab is opened, or by default on the uploads page.
$(document).on("danbooru:open-post-edit-tab", RelatedTag.show);
if ($("#c-uploads #a-new").length) {
RelatedTag.show();
}
}
RelatedTag.initialize_recent_and_favorite_tags = function(event) {
$.get("/related_tag.js", { user_tags: true });
}
RelatedTag.on_click_related_tags_button = function (event) {
$.get("/related_tag.js", { query: RelatedTag.current_tag(), category: $(event.target).data("category") });
RelatedTag.show();
}
RelatedTag.on_update_source_data = function (event, { related_tags_html }) {
$(".source-related-tags-columns").replaceWith(related_tags_html);
RelatedTag.update_selected();
}
RelatedTag.current_tag = function() {
// 1. abc def | -> def
// 2. abc def| -> def
// 3. abc de|f -> def
// 4. abc |def -> def
// 5. abc| def -> abc
// 6. ab|c def -> abc
// 7. |abc def -> abc
// 8. | abc def -> abc
var $field = $("#upload_tag_string,#post_tag_string");
var string = $field.val();
var n = string.length;
var a = $field.prop('selectionStart');
var b = $field.prop('selectionStart');
if ((a > 0) && (a < (n - 1)) && (!/\s/.test(string[a])) && (/\s/.test(string[a - 1]))) {
// 4 is the only case where we need to scan forward. in all other cases we
// can drag a backwards, and then drag b forwards.
while ((b < n) && (!/\s/.test(string[b]))) {
b++;
}
} else if (string.search(/\S/) > b) { // case 8
b = string.search(/\S/);
while ((b < n) && (!/\s/.test(string[b]))) {
b++;
}
} else {
while ((a > 0) && ((/\s/.test(string[a])) || (string[a] === undefined))) {
a--;
b--;
}
while ((a > 0) && (!/\s/.test(string[a - 1]))) {
a--;
b--;
}
while ((b < (n - 1)) && (!/\s/.test(string[b]))) {
b++;
}
}
b++;
return string.slice(a, b);
}
RelatedTag.update_selected = function(e) {
var current_tags = $("#upload_tag_string,#post_tag_string").val().toLowerCase().match(/\S+/g) || [];
var $all_tags = $(".related-tags a.search-tag");
$all_tags.removeClass("selected");
$all_tags.each(function(i, tag) {
if (current_tags.indexOf(tag.textContent.replace(/ /g, "_")) > -1) {
$(tag).addClass("selected");
}
});
}
RelatedTag.tags_include = function(name) {
var current = $("#upload_tag_string,#post_tag_string").val().toLowerCase().match(/\S+/g) || [];
return $.inArray(name.toLowerCase(), current) > -1;
}
RelatedTag.toggle_tag = function(e) {
var $field = $("#upload_tag_string,#post_tag_string");
var tag = $(e.target).html().replace(/ /g, "_").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&amp;/g, "&");
if (RelatedTag.tags_include(tag)) {
var escaped_tag = Utility.regexp_escape(tag);
$field.val($field.val().replace(new RegExp("(^|\\s)" + escaped_tag + "($|\\s)", "gi"), "$1$2"));
} else {
$field.val($field.val() + " " + tag);
}
$field.val($field.val().trim().replace(/ +/g, " ") + " ");
RelatedTag.update_selected();
// The timeout is needed on Chrome since it will clobber the field attribute otherwise
setTimeout(function () { $field.prop('selectionStart', $field.val().length);}, 100);
e.preventDefault();
}
RelatedTag.show = function(e) {
$(document).trigger("danbooru:show-related-tags");
$("#related-tags-container").removeClass("hidden").addClass("visible");
if (e) {
e.preventDefault();
}
}
RelatedTag.hide = function(e) {
$("#related-tags-container").removeClass("visible").addClass("hidden");
if (e) {
e.preventDefault();
}
}
$(function() {
RelatedTag.initialize_all();
});
export default RelatedTag

View File

@@ -1,331 +0,0 @@
import Upload from './uploads';
import Utility from './utility';
import Cookie from './cookie';
let RelatedTag = {};
RelatedTag.initialize_all = function() {
if ($("#c-posts #a-show").length || $("#c-uploads #a-new").length) {
this.initialize_buttons();
$("#upload_tag_string,#post_tag_string").on("keyup.danbooru.relatedTags", RelatedTag.update_selected);
$("#related-tags-container").on("click.danbooru", "#artist-related-tags-column a.del", RelatedTag.disable_artist_url)
}
}
RelatedTag.initialize_buttons = function() {
this.common_bind("#related-tags-button", "");
<% TagCategory.related_button_list.each do |category| %>
RelatedTag.common_bind("#related-<%= category %>-button", "<%= category %>"); // eslint-disable-line indent
<% end %>
}
RelatedTag.tags_include = function(name) {
var current = $("#upload_tag_string,#post_tag_string").val().toLowerCase().match(/\S+/g) || [];
return $.inArray(name.toLowerCase(), current) > -1;
}
RelatedTag.common_bind = function(button_name, category) {
$(button_name).on("click.danbooru", function(e) {
var $dest = $("#related-tags");
$dest.empty();
RelatedTag.build_recent_and_frequent($dest);
$dest.append("<em>Loading...</em>");
$.get("/related_tag.json", {
"query": RelatedTag.current_tag(),
"category": category
}, RelatedTag.process_response);
e.preventDefault();
});
}
RelatedTag.current_tag = function() {
// 1. abc def | -> def
// 2. abc def| -> def
// 3. abc de|f -> def
// 4. abc |def -> def
// 5. abc| def -> abc
// 6. ab|c def -> abc
// 7. |abc def -> abc
// 8. | abc def -> abc
var $field = $("#upload_tag_string,#post_tag_string");
var string = $field.val();
var n = string.length;
var a = $field.prop('selectionStart');
var b = $field.prop('selectionStart');
if ((a > 0) && (a < (n - 1)) && (!/\s/.test(string[a])) && (/\s/.test(string[a - 1]))) {
// 4 is the only case where we need to scan forward. in all other cases we
// can drag a backwards, and then drag b forwards.
while ((b < n) && (!/\s/.test(string[b]))) {
b++;
}
} else if (string.search(/\S/) > b) { // case 8
b = string.search(/\S/);
while ((b < n) && (!/\s/.test(string[b]))) {
b++;
}
} else {
while ((a > 0) && ((/\s/.test(string[a])) || (string[a] === undefined))) {
a--;
b--;
}
while ((a > 0) && (!/\s/.test(string[a - 1]))) {
a--;
b--;
}
while ((b < (n - 1)) && (!/\s/.test(string[b]))) {
b++;
}
}
b++;
return string.slice(a, b);
}
RelatedTag.process_response = function(data) {
RelatedTag.recent_search = data;
RelatedTag.build_all();
}
RelatedTag.update_selected = function(e) {
var current_tags = $("#upload_tag_string,#post_tag_string").val().toLowerCase().match(/\S+/g) || [];
var $all_tags = $("#related-tags a");
$all_tags.removeClass("selected");
$all_tags.each(function(i, tag) {
if (current_tags.indexOf(tag.textContent.replace(/ /g, "_")) > -1) {
$(tag).addClass("selected");
}
});
}
RelatedTag.build_all = function() {
if (RelatedTag.recent_search === null || RelatedTag.recent_search === undefined) {
return;
}
RelatedTag.show();
var query = RelatedTag.recent_search.query;
var related_tags = RelatedTag.recent_search.tags;
var wiki_page_tags = RelatedTag.recent_search.wiki_page_tags;
var other_wikis = RelatedTag.recent_search.other_wikis;
var $dest = $("#related-tags");
$dest.empty();
this.build_recent_and_frequent($dest);
$dest.append(this.build_html(query, related_tags, "general"));
this.build_translated($dest);
if (wiki_page_tags.length) {
$dest.append(RelatedTag.build_html("wiki:" + query, wiki_page_tags, "wiki"));
}
$.each(other_wikis, function(i, wiki) {
$dest.append(RelatedTag.build_html("wiki:" + wiki.title, wiki.wiki_page_tags, "otherwiki" + i.toString()));
});
if (RelatedTag.recent_artists) {
var tags = [];
if (RelatedTag.recent_artists.length === 0) {
tags.push([" none", 0]);
} else if (RelatedTag.recent_artists.length === 1) {
tags.push([RelatedTag.recent_artists[0].name, 1]);
if (RelatedTag.recent_artists[0].is_banned === true) {
tags.push(["BANNED_ARTIST", "banned"]);
}
$.each(RelatedTag.recent_artists[0].sorted_urls, function(i, url) {
var x = url.url;
if (!url.is_active) {
x = "-" + x;
}
tags.push([" " + x, 0]);
});
} else if (RelatedTag.recent_artists.length >= 10) {
tags.push([" none", 0]);
} else {
$.each(RelatedTag.recent_artists, function(i, artist) {
tags.push([artist.name, 1]);
});
}
$dest.append(RelatedTag.build_html("artist", tags, "artist", true));
}
}
RelatedTag.build_recent_and_frequent = function($dest) {
var recent_tags = Cookie.get("recent_tags_with_categories");
var favorite_tags = Cookie.get("favorite_tags_with_categories");
if (recent_tags.length) {
$dest.append(this.build_html("recent", this.other_tags(recent_tags), "recent"));
}
if (favorite_tags.length) {
$dest.append(this.build_html("frequent", this.other_tags(favorite_tags), "frequent"));
}
}
RelatedTag.other_tags = function(string) {
if (string && string.length) {
return $.map(string.match(/\S+ \d+/g), function(x, i) {
var submatch = x.match(/(\S+) (\d+)/);
return [[submatch[1], submatch[2]]];
});
} else {
return [];
}
}
RelatedTag.build_translated = function($dest) {
if (RelatedTag.translated_tags && RelatedTag.translated_tags.length) {
$dest.append(this.build_html("Translated Tags", RelatedTag.translated_tags, "translated"));
}
}
RelatedTag.build_html = function(query, related_tags, name, is_wide_column) {
if (query === null || query === "") {
return "";
}
query = query.replace(/_/g, " ");
var header = $("<em/>");
var match = query.match(/^wiki:(.+)/);
if (match) {
header.html($("<a/>").attr("href", "/wiki_pages?title=" + encodeURIComponent(match[1])).attr("target", "_blank").text(query));
} else {
header.text(query);
}
var $div = $("<div/>");
$div.attr("id", name + "-related-tags-column");
$div.addClass("tag-column");
if (is_wide_column) {
$div.addClass("wide-column");
}
var $ul = $("<ul/>");
$ul.append(
$("<li/>").append(
header
)
);
$.each(related_tags, function(i, tag) {
if (tag[0][0] !== " ") {
var $link = $("<a/>");
$link.text(tag[0].replace(/_/g, " "));
$link.addClass("tag-type-" + tag[1]);
$link.attr("href", "/posts?tags=" + encodeURIComponent(tag[0]));
$link.on("click.danbooru", RelatedTag.toggle_tag);
if (RelatedTag.tags_include(tag[0])) {
$link.addClass("selected");
}
$ul.append(
$("<li/>").append($link)
);
} else {
var text = tag[0];
var desc = "";
if (text.match(/^ -http/)) {
text = text.substring(1, 1000);
desc = text.replace(/^-https?:\/\//, "");
if (desc.length > 30) {
desc = desc.substring(0, 30) + "...";
}
$ul.append(
$("<li>").append(
$("<del>").text(desc)
)
);
} else if (text.match(/^ http/)) {
text = text.substring(1, 1000);
desc = text.replace(/^https?:\/\//, "");
if (desc.length > 30) {
desc = desc.substring(0, 30) + "...";
}
$ul.append(
$("<li>").append([
$("<a>").text(desc).attr("href", text).attr("target", "_blank"),
" ",
$("<a>").attr("href", text).addClass("del").append(
$("<i>").addClass("fas fa-minus-circle")
)
])
);
} else {
$ul.append($("<li/>").text(text));
}
}
});
$div.append($ul);
return $div;
}
RelatedTag.toggle_tag = function(e) {
var $field = $("#upload_tag_string,#post_tag_string");
var tag = $(e.target).html().replace(/ /g, "_").replace(/&gt;/g, ">").replace(/&lt;/g, "<").replace(/&amp;/g, "&");
if (RelatedTag.tags_include(tag)) {
var escaped_tag = Utility.regexp_escape(tag);
$field.val($field.val().replace(new RegExp("(^|\\s)" + escaped_tag + "($|\\s)", "gi"), "$1$2"));
} else {
$field.val($field.val() + " " + tag);
}
$field.val($field.val().trim().replace(/ +/g, " ") + " ");
RelatedTag.update_selected();
// The timeout is needed on Chrome since it will clobber the field attribute otherwise
setTimeout(function () { $field.prop('selectionStart', $field.val().length);}, 100);
e.preventDefault();
}
RelatedTag.toggle = function() {
if ($("#related-tags").is(":visible")) {
RelatedTag.hide();
} else {
RelatedTag.show();
$("#related-tags-button").trigger("click");
$("#find-artist-button").trigger("click");
}
}
RelatedTag.show = function() {
$("#related-tags").show()
$("#toggle-related-tags-link").text("«");
$("#edit-dialog").height("auto");
}
RelatedTag.hide = function() {
$("#related-tags").hide();
$("#toggle-related-tags-link").text("»");
}
RelatedTag.disable_artist_url = function(e) {
var url = e.currentTarget.href;
$.each(RelatedTag.recent_artists[0].sorted_urls, function(k, v) {
if (v.normalized_url === url || v.url === url) {
if (!confirm("This will mark the URL as inactive. Continue?")) {
return;
}
$.ajax("/artist_urls/" + v.id, {
method: "PUT",
data: {
artist_url: {
is_active: false
}
}
}).done(Upload.fetch_data_manual);
}
});
return false;
}
$(function() {
RelatedTag.initialize_all();
});
export default RelatedTag

View File

@@ -5,6 +5,7 @@ let Upload = {};
Upload.initialize_all = function() {
if ($("#c-uploads,#c-posts").length) {
this.initialize_enter_on_tags();
$("#upload_source").on("change.danbooru", Upload.fetch_data_manual);
$(document).on("click.danbooru", "#fetch-data-manual", Upload.fetch_data_manual);
}
@@ -14,10 +15,8 @@ Upload.initialize_all = function() {
} else {
$("#image").on("load.danbooru error.danbooru", this.initialize_image);
}
this.initialize_info_bookmarklet();
this.initialize_similar();
this.initialize_submit();
$(() => $("#related-tags-button").click()); // delay so we don't click until button is bound (#3895).
$("#toggle-artist-commentary").on("click.danbooru", function(e) {
Upload.toggle_commentary();
@@ -77,11 +76,6 @@ Upload.initialize_similar = function() {
});
}
Upload.initialize_info_bookmarklet = function() {
$("#upload_source").on("change.danbooru", Upload.fetch_data_manual);
$("#fetch-data-manual").click();
}
Upload.update_scale = function() {
var $image = $("#image");
var ratio = $image.data("scale-factor");

View File

@@ -3,8 +3,10 @@
div#related-tags-container {
padding-right: 2em;
h1 {
font-size: $h3_size;
&.visible a#show-related-tags-link,
&.hidden a#hide-related-tags-link,
&.hidden div.related-tags {
display: none;
}
}

View File

@@ -1,11 +1,16 @@
class RelatedTagQuery
attr_reader :query, :category
attr_reader :query, :category, :user
def initialize(query, category = nil)
@query = TagAlias.to_aliased(query.strip).join(" ")
def initialize(query: nil, category: nil, user: nil)
@user = user
@query = TagAlias.to_aliased(query.to_s.downcase.strip).join(" ")
@category = category
end
def pretty_name
query.tr("_", " ")
end
def tags
if query =~ /\*/
pattern_matching_tags
@@ -18,6 +23,21 @@ class RelatedTagQuery
end
end
# Returns the top 20 most frequently added tags within the last 20 edits made by the user in the last hour.
def recent_tags(since: 1.hour.ago, max_edits: 20, max_tags: 20)
return [] unless user.present? && PostArchive.enabled?
versions = PostArchive.where(updater_id: user.id).where("updated_at > ?", since).order(id: :desc).limit(max_edits)
tags = versions.flat_map(&:added_tags)
tags = tags.reject { |tag| Tag.is_metatag?(tag) }
tags = tags.group_by(&:itself).transform_values(&:size).sort_by { |tag, count| [-count, tag] }.map(&:first)
tags.take(max_tags)
end
def favorite_tags
user&.favorite_tags.to_s.split
end
def wiki_page_tags
results = wiki_page.try(:tags) || []
results.reject! do |name|
@@ -27,17 +47,12 @@ class RelatedTagQuery
end
def other_wiki_category_tags
if Tag.category_for(query) != Tag.categories.copyright
return []
end
listtags = (wiki_page.try(:tags) || []).select {|name| name =~ /^list_of_/i }
results = listtags.map do |name|
listlinks = WikiPage.titled(name).first.try(:tags) || []
if listlinks.length > 0
{"title" => name, "wiki_page_tags" => map_with_category_data(listlinks)}
end
end
results.reject {|list| list.nil?}
return [] unless Tag.category_for(query) == Tag.categories.copyright
other_wikis = wiki_page&.tags.to_a.grep(/^list_of_/i)
other_wikis = other_wikis.map { |name| WikiPage.titled(name).first }
other_wikis = other_wikis.select { |wiki| wiki.tags.present? }
other_wikis
end
def tags_for_html

View File

@@ -28,7 +28,6 @@ class SessionLoader
update_last_logged_in_at
update_last_ip_addr
set_time_zone
store_favorite_tags_in_cookies
CurrentUser.user.unban! if CurrentUser.user.ban_expired?
end
@@ -92,14 +91,6 @@ private
cookies[:password_hash] && cookies.signed[:user_name] && User.authenticate_cookie_hash(cookies.signed[:user_name], cookies[:password_hash])
end
def store_favorite_tags_in_cookies
if (cookies[:favorite_tags].blank? || cookies[:favorite_tags_with_categories].blank?) && CurrentUser.user.favorite_tags.present?
favorite_tags = CurrentUser.user.favorite_tags.slice(0, 1024)
cookies[:favorite_tags] = favorite_tags
cookies[:favorite_tags_with_categories] = Tag.categories_for(favorite_tags.split(/[[:space:]]+/)).to_a.flatten.join(" ")
end
end
def update_last_logged_in_at
return if CurrentUser.is_anonymous?
return if CurrentUser.last_logged_in_at && CurrentUser.last_logged_in_at > 1.week.ago

View File

@@ -0,0 +1 @@
Danbooru.Upload.fetch_data_manual();

View File

@@ -82,20 +82,12 @@
<span id="open-edit-dialog" class="ui-icon ui-icon-arrow-1-ne" title="detach" style="display: none;" data-shortcut="shift+e"/>
</div>
<%= button_tag "Related tags", :id => "related-tags-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %>
<% TagCategory.related_button_list.each do |category| %>
<%= button_tag "#{TagCategory.related_button_mapping[category]}", :id => "related-#{category}-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %>
<% end %>
<%= render "related_tags/buttons" %>
</div>
<div class="input">
<%= submit_tag "Submit", :class => "ui-button ui-widget ui-corner-all" %>
</div>
<div id="related-tags-container">
<h1>Related Tags <a href="#" id="toggle-related-tags-link" style="display: none;">&laquo;</a></h1>
<div id="related-tags" class="related-tags">
</div>
</div>
<%= render "related_tags/container" %>
<% end %>

View File

@@ -0,0 +1,5 @@
<%= button_tag "Related tags", type: :button, class: "related-tags-button ui-button ui-widget ui-corner-all sub gradient" %>
<% TagCategory.related_button_list.each do |category| %>
<%= button_tag TagCategory.related_button_mapping[category], type: :button, "data-category": category, class: "related-tags-button ui-button ui-widget ui-corner-all sub gradient" %>
<% end %>

View File

@@ -0,0 +1,13 @@
<div id="related-tags-container" class="visible">
<h3>
Related Tags
<a href="#" id="show-related-tags-link">»</a>
<a href="#" id="hide-related-tags-link">«</a>
</h3>
<div class="related-tags">
<%= render "related_tags/user_tags", related_tags: nil %>
<%= render "related_tags/current_tags", related_tags: nil %>
<%= render "related_tags/source_tags", source: nil %>
</div>
</div>

View File

@@ -0,0 +1,10 @@
<div class="current-related-tags-columns">
<% if related_tags.present? %>
<%= render "related_tags/tag_column", tags: related_tags.tags, class: "general-related-tags-column", title: related_tags.pretty_name %>
<%= render "related_tags/tag_column", tags: related_tags.wiki_page_tags, class: "wiki-related-tags-column", title: link_to("wiki:#{related_tags.pretty_name}", show_or_new_wiki_pages_path(title: related_tags.query)) %>
<% related_tags.other_wiki_category_tags.each do |wiki| %>
<%= render "related_tags/tag_column", tags: wiki.tags, class: "other-wiki-related-tags-column", title: link_to("wiki:#{wiki.pretty_title}", show_or_new_wiki_pages_path(title: wiki.title)) %>
<% end %>
<% end %>
</div>

View File

@@ -0,0 +1,34 @@
<div class="source-related-tags-columns">
<% if source.present? %>
<%= render "related_tags/tag_column", tags: source.translated_tags.map(&:first), title: "Translated Tags" %>
<div class="tag-column wide-column artist-related-tags-column">
<h6>Artist</h6>
<% if source.artists.size == 0 %>
none
<% else %>
<% if source.artists.any?(&:is_banned?) %>
<%= TagSetPresenter.new(["banned_artist"]).tag_list_html(name_only: true) %>
<% end %>
<% source.artists.each do |artist| %>
<%= TagSetPresenter.new([artist.name]).tag_list_html(name_only: true) %>
<ul>
<% artist.sorted_urls.each do |url| %>
<li>
<% if url.is_active %>
<%= external_link_to url.url, truncate: 30 %>
<%= link_to tag.i(class: "fas fa-minus-circle"), artist_url_path(id: url.id, artist_url: { is_active: false }), remote: true, method: :put, "data-confirm": "This will mark the URL as inactive. Continue?" %>
<% else %>
<del><%= truncate(url.url, length: 30) %></del>
<% end %>
</li>
<% end %>
</ul>
<% end %>
<% end %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,8 @@
<%# tags, title, class (optional) %>
<div class="tag-column <%= local_assigns[:class] || "#{title.parameterize}-related-tags-column" %>">
<% if tags.present? %>
<h6><%= title %></h6>
<%= TagSetPresenter.new(tags).tag_list_html(name_only: true) %>
<% end %>
</div>

View File

@@ -0,0 +1,6 @@
<div class="user-related-tags-columns">
<% if related_tags.present? %>
<%= render "related_tags/tag_column", tags: related_tags.recent_tags, title: "Recent" %>
<%= render "related_tags/tag_column", tags: related_tags.favorite_tags, title: "Frequent" %>
<% end %>
</div>

View File

@@ -0,0 +1,7 @@
<% if params[:user_tags] %>
$(".user-related-tags-columns").replaceWith("<%= j render "user_tags", related_tags: @query %>");
<% else %>
$(".current-related-tags-columns").replaceWith("<%= j render "current_tags", related_tags: @query %>");
<% end %>
Danbooru.RelatedTag.update_selected();

View File

@@ -1,8 +1,9 @@
$("#source-info").replaceWith("<%= j render "info", source: @source %>");
Danbooru.RelatedTag.recent_artists = <%= raw @source.artists.to_json(include: :sorted_urls) %>;
Danbooru.RelatedTag.translated_tags = <%= raw @source.translated_tags.to_json %>;
Danbooru.RelatedTag.build_all();
$(document).trigger("danbooru:update-source-data", {
source: <%= raw @source.to_json %>,
related_tags_html: "<%= j render "related_tags/source_tags", source: @source %>",
});
if ($("#c-uploads #a-new").length) {
$("#upload_artist_commentary_title").val(<%= raw @source.dtext_artist_commentary_title.to_json %>);

View File

@@ -97,22 +97,14 @@
<span id="open-edit-dialog" class="ui-icon ui-icon-arrow-1-ne" title="detach" style="display: none;" data-shortcut="shift+e"/>
</div>
<%= button_tag "Related tags", :id => "related-tags-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %>
<% TagCategory.related_button_list.each do |category| %>
<%= button_tag "#{TagCategory.related_button_mapping[category]}", :id => "related-#{category}-button", :type => "button", :class => "ui-button ui-widget ui-corner-all sub gradient" %>
<% end %>
<%= render "related_tags/buttons" %>
</div>
<div class="input">
<%= submit_tag "Submit", :id => "submit-button", :class => "large ui-button ui-widget ui-corner-all gradient", data: {disable_with: false} %>
</div>
<div id="related-tags-container">
<h1>Related Tags <a href="#" id="toggle-related-tags-link" style="display: none;">&laquo;</a></h1>
<div id="related-tags" class="related-tags">
</div>
</div>
<%= render "related_tags/container" %>
<% end %>
<% else %>
<h2 style="margin-bottom: 1em;">You <%= CurrentUser.user.upload_limited_reason %></h2>