Autocomplete metatags (#2063)
This commit is contained in:
@@ -21,6 +21,9 @@
|
||||
);
|
||||
|
||||
var prefixes = "-|~|general:|gen:|artist:|art:|copyright:|copy:|co:|character:|char:|ch:";
|
||||
var metatags = "order|-status|status|-rating|rating|-locked|locked|" +
|
||||
"-user|user|-approver|approver|commenter|comm|noter|artcomm|-fav|fav|ordfav|" +
|
||||
"sub|-pool|pool";
|
||||
|
||||
$fields_multiple.autocomplete({
|
||||
delay: 100,
|
||||
@@ -50,7 +53,7 @@
|
||||
}
|
||||
|
||||
var term = before_caret_text.match(/\S+/g).pop();
|
||||
var regexp = new RegExp("^(?:" + prefixes + ")(.*)$");
|
||||
var regexp = new RegExp("^(?:" + prefixes + ")(.*)$", "i");
|
||||
var match = term.match(regexp);
|
||||
if (match) {
|
||||
term = match[1];
|
||||
@@ -59,25 +62,55 @@
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: "/tags.json",
|
||||
data: {
|
||||
"search[order]": "count",
|
||||
"search[name_matches]": term + "*",
|
||||
"limit": 10
|
||||
},
|
||||
method: "get",
|
||||
success: function(data) {
|
||||
resp($.map(data, function(tag) {
|
||||
return {
|
||||
label: tag.name.replace(/_/g, " "),
|
||||
value: tag.name,
|
||||
category: tag.category,
|
||||
post_count: tag.post_count
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
regexp = new RegExp("^(" + metatags + "):(.*)$", "i");
|
||||
var match = term.match(regexp);
|
||||
var metatag;
|
||||
if (match) {
|
||||
metatag = match[1].toLowerCase();
|
||||
term = match[2];
|
||||
}
|
||||
|
||||
switch(metatag) {
|
||||
case "order":
|
||||
case "status":
|
||||
case "-status":
|
||||
case "rating":
|
||||
case "-rating":
|
||||
case "locked":
|
||||
case "-locked":
|
||||
Danbooru.Autocomplete.static_metatag_source(term, resp, metatag);
|
||||
break;
|
||||
}
|
||||
|
||||
if (term === "") {
|
||||
return;
|
||||
}
|
||||
|
||||
switch(metatag) {
|
||||
case "user":
|
||||
case "-user":
|
||||
case "approver":
|
||||
case "-approver":
|
||||
case "commenter":
|
||||
case "comm":
|
||||
case "noter":
|
||||
case "artcomm":
|
||||
case "fav":
|
||||
case "-fav":
|
||||
case "ordfav":
|
||||
Danbooru.Autocomplete.user_source(term, resp, metatag);
|
||||
break;
|
||||
case "sub":
|
||||
Danbooru.Autocomplete.subscription_source(term, resp);
|
||||
break;
|
||||
case "pool":
|
||||
case "-pool":
|
||||
Danbooru.Autocomplete.pool_source(term, resp, metatag);
|
||||
break;
|
||||
default:
|
||||
Danbooru.Autocomplete.normal_source(term, resp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -116,27 +149,174 @@
|
||||
}
|
||||
});
|
||||
|
||||
var render_tag = function(list, tag) {
|
||||
var $link = $("<a/>").addClass("tag-type-" + tag.category).text(tag.label);
|
||||
$link.attr("href", "/posts?tags=" + encodeURIComponent(tag.value));
|
||||
$link.click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
$.merge($fields_multiple, $fields_single).each(function(i, field) {
|
||||
$(field).data("uiAutocomplete")._renderItem = Danbooru.Autocomplete.render_item;
|
||||
});
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.render_item = function(list, item) {
|
||||
var $link = $("<a/>").text(item.label);
|
||||
$link.attr("href", "/posts?tags=" + encodeURIComponent(item.value));
|
||||
$link.click(function(e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
if (item.post_count !== undefined) {
|
||||
var count;
|
||||
if (tag.post_count >= 1000) {
|
||||
count = Math.floor(tag.post_count / 1000) + "k";
|
||||
if (item.post_count >= 1000) {
|
||||
count = Math.floor(item.post_count / 1000) + "k";
|
||||
} else {
|
||||
count = tag.post_count;
|
||||
count = item.post_count;
|
||||
}
|
||||
var $post_count = $("<span/>").addClass("post-count").css("float", "right").text(count);
|
||||
$link.append($post_count);
|
||||
}
|
||||
|
||||
return $("<li/>").data("item.autocomplete", tag).append($link).appendTo(list);
|
||||
};
|
||||
if (item.type === "tag") {
|
||||
$link.addClass("tag-type-" + item.category);
|
||||
} else if (item.type === "user") {
|
||||
var level_class = "user-" + item.level.toLowerCase();
|
||||
$link.addClass(level_class);
|
||||
if (Danbooru.meta("style-usernames") === "true") {
|
||||
$link.addClass("with-style");
|
||||
}
|
||||
} else if (item.type === "pool") {
|
||||
$link.addClass("pool-category-" + item.category);
|
||||
}
|
||||
|
||||
$.merge($fields_multiple, $fields_single).each(function(i, field) {
|
||||
$(field).data("uiAutocomplete")._renderItem = render_tag;
|
||||
return $("<li/>").data("item.autocomplete", item).append($link).appendTo(list);
|
||||
};
|
||||
|
||||
Danbooru.Autocomplete.normal_source = function(term, resp) {
|
||||
$.ajax({
|
||||
url: "/tags.json",
|
||||
data: {
|
||||
"search[order]": "count",
|
||||
"search[name_matches]": term + "*",
|
||||
"limit": 10
|
||||
},
|
||||
method: "get",
|
||||
success: function(data) {
|
||||
resp($.map(data, function(tag) {
|
||||
return {
|
||||
type: "tag",
|
||||
label: tag.name.replace(/_/g, " "),
|
||||
value: tag.name,
|
||||
category: tag.category,
|
||||
post_count: tag.post_count
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.static_metatags = {
|
||||
order: [
|
||||
"id", "id_desc",
|
||||
"score", "score_asc",
|
||||
"favcount", "favcount_asc",
|
||||
"comment", "comment_asc",
|
||||
"note", "note_asc",
|
||||
"artcomm", "artcomm_asc",
|
||||
"mpixels", "mpixels_asc",
|
||||
"portrait", "landscape",
|
||||
"filesize", "filesize_asc",
|
||||
"rank"
|
||||
],
|
||||
status: [
|
||||
"any", "deleted", "active", "pending", "flagged", "banned"
|
||||
],
|
||||
rating: [
|
||||
"safe", "questionable", "explicit"
|
||||
],
|
||||
locked: [
|
||||
"rating", "note", "status"
|
||||
]
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.static_metatag_source = function(term, resp, metatag) {
|
||||
var sub_metatags = this.static_metatags[metatag];
|
||||
|
||||
var regexp = new RegExp("^" + $.ui.autocomplete.escapeRegex(term), "i");
|
||||
var matches = $.grep(sub_metatags, function (sub_metatag) {
|
||||
return regexp.test(sub_metatag);
|
||||
});
|
||||
|
||||
resp($.map(matches, function(sub_metatag) {
|
||||
return metatag + ":" + sub_metatag;
|
||||
}));
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.user_source = function(term, resp, metatag) {
|
||||
$.ajax({
|
||||
url: "/users.json",
|
||||
data: {
|
||||
"search[order]": "post_upload_count",
|
||||
"search[name_matches]": term + "*",
|
||||
"limit": 10,
|
||||
},
|
||||
method: "get",
|
||||
success: function(data) {
|
||||
resp($.map(data, function(user) {
|
||||
return {
|
||||
type: "user",
|
||||
label: user.name.replace(/_/g, " "),
|
||||
value: metatag + ":" + user.name,
|
||||
level: user.level_string
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.subscription_source = function(term, resp) {
|
||||
var match = term.match(/^(.+?):(.*)$/);
|
||||
if (match) {
|
||||
var user_name = match[1];
|
||||
var subscription_name = match[2];
|
||||
|
||||
$.ajax({
|
||||
url: "/tag_subscriptions.json",
|
||||
data: {
|
||||
"search[creator_name]": user_name,
|
||||
"search[name_matches]": subscription_name + "*",
|
||||
"limit": 10
|
||||
},
|
||||
method: "get",
|
||||
success: function(data) {
|
||||
resp($.map(data, function(subscription) {
|
||||
return {
|
||||
label: subscription.name.replace(/_/g, " "),
|
||||
value: "sub:" + user_name + ":" + subscription.name
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Danbooru.Autocomplete.user_source(term, resp, "sub");
|
||||
}
|
||||
}
|
||||
|
||||
Danbooru.Autocomplete.pool_source = function(term, resp, metatag) {
|
||||
$.ajax({
|
||||
url: "/pools.json",
|
||||
data: {
|
||||
"search[order]": "post_count",
|
||||
"search[name_matches]": term,
|
||||
"limit": 10
|
||||
},
|
||||
method: "get",
|
||||
success: function(data) {
|
||||
resp($.map(data, function(pool) {
|
||||
return {
|
||||
type: "pool",
|
||||
label: pool.name.replace(/_/g, " "),
|
||||
value: metatag + ":" + pool.name,
|
||||
post_count: pool.post_count,
|
||||
category: pool.category
|
||||
};
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -75,6 +75,10 @@ class TagSubscription < ActiveRecord::Base
|
||||
where("creator_id = ?", user.id)
|
||||
end
|
||||
|
||||
def name_matches(name)
|
||||
where("lower(name) like ? escape E'\\\\'", name.to_escaped_for_sql_like)
|
||||
end
|
||||
|
||||
def search(params)
|
||||
q = scoped
|
||||
params = {} if params.blank?
|
||||
@@ -87,6 +91,10 @@ class TagSubscription < ActiveRecord::Base
|
||||
q = q.where("creator_id = ?", CurrentUser.user.id)
|
||||
end
|
||||
|
||||
if params[:name_matches]
|
||||
q = q.name_matches(params[:name_matches].mb_chars.downcase.strip.tr(" ", "_"))
|
||||
end
|
||||
|
||||
q = q.visible_to(CurrentUser.user)
|
||||
|
||||
q
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<meta name="new-post-navigation-layout" content="<%= CurrentUser.user.new_post_navigation_layout %>">
|
||||
<meta name="default-image-size" content="<%= CurrentUser.user.default_image_size %>">
|
||||
<meta name="enable-auto-complete" content="<%= CurrentUser.user.enable_auto_complete %>">
|
||||
<meta name="style-usernames" content="<%= CurrentUser.user.style_usernames? %>">
|
||||
<meta name="mobile-mode" content="<%= CurrentUser.mobile_mode? %>">
|
||||
<%= auto_discovery_link_tag :atom, posts_path(:format => "atom", :tags => params[:tags]) %>
|
||||
<%= stylesheet_link_tag "application", :media => "screen" %>
|
||||
|
||||
Reference in New Issue
Block a user