autocomplete: recognize Japanese tags in autocomplete.
Allowing typing Japanese tags in autocomplete. For example, typing 東方 in autocomplete will be completed to the touhou tag. Typing ぶくぶ will complete to the bkub tag. This works using wiki page and artist other names. Effectively, any name listed as an other name in a wiki or artist page will be treated like an alias for autocomplete purposes. This is limited to non-ASCII other names, to prevent English other names from interfering with regular tag searches.
This commit is contained in:
@@ -72,8 +72,11 @@ class AutocompleteService
|
||||
results = results.uniq.sort_by { |r| [r[:antecedent].length, -r[:post_count]] }.take(limit)
|
||||
elsif string.include?("*")
|
||||
results = tag_matches(string)
|
||||
results = tag_other_name_matches(string) if results.blank?
|
||||
else
|
||||
results = tag_matches(string + "*")
|
||||
string += "*"
|
||||
results = tag_matches(string)
|
||||
results = tag_other_name_matches(string) if results.blank?
|
||||
results = tag_autocorrect_matches(string) if results.blank?
|
||||
end
|
||||
|
||||
@@ -81,6 +84,8 @@ class AutocompleteService
|
||||
end
|
||||
|
||||
def tag_matches(string)
|
||||
return [] if string =~ /[^[:ascii:]]/
|
||||
|
||||
name_matches = Tag.nonempty.name_matches(string).order(post_count: :desc).limit(limit)
|
||||
alias_matches = Tag.nonempty.alias_matches(string).order(post_count: :desc).limit(limit)
|
||||
union = "((#{name_matches.to_sql}) UNION (#{alias_matches.to_sql})) AS tags"
|
||||
@@ -100,6 +105,7 @@ class AutocompleteService
|
||||
end
|
||||
|
||||
def tag_autocorrect_matches(string)
|
||||
string = string.delete("*")
|
||||
tags = Tag.nonempty.autocorrect_matches(string).limit(limit)
|
||||
|
||||
tags.map do |tag|
|
||||
@@ -107,6 +113,21 @@ class AutocompleteService
|
||||
end
|
||||
end
|
||||
|
||||
def tag_other_name_matches(string)
|
||||
return [] unless string =~ /[^[:ascii:]]/
|
||||
|
||||
artists = Artist.undeleted.any_other_name_like(string)
|
||||
wikis = WikiPage.undeleted.other_names_match(string)
|
||||
tags = Tag.where(name: wikis.select(:title)).or(Tag.where(name: artists.select(:name)))
|
||||
tags = tags.nonempty.order(post_count: :desc).limit(limit).includes(:wiki_page, :artist)
|
||||
|
||||
tags.map do |tag|
|
||||
other_names = tag.artist&.other_names.to_a + tag.wiki_page&.other_names.to_a
|
||||
antecedent = other_names.find { |other_name| other_name.ilike?(string) }
|
||||
{ type: "tag", label: tag.pretty_name, value: tag.name, category: tag.category, post_count: tag.post_count, antecedent: antecedent }
|
||||
end
|
||||
end
|
||||
|
||||
def autocomplete_metatag(metatag, value)
|
||||
results = case metatag.to_sym
|
||||
when :user, :approver, :commenter, :comm, :noter, :noteupdater, :commentaryupdater,
|
||||
|
||||
@@ -45,7 +45,7 @@ class WikiPage < ApplicationRecord
|
||||
|
||||
def other_names_match(name)
|
||||
if name =~ /\*/
|
||||
subquery = WikiPage.from("unnest(other_names) AS other_name").where_ilike("other_name", name)
|
||||
subquery = WikiPage.from("unnest(other_names) AS other_name").where_ilike("other_name", normalize_other_name(name))
|
||||
where(id: subquery)
|
||||
else
|
||||
other_names_include(name)
|
||||
|
||||
@@ -97,6 +97,33 @@ class AutocompleteServiceTest < ActiveSupport::TestCase
|
||||
assert_autocomplete_includes("mole_under_eye", "~/mue", :tag_query)
|
||||
end
|
||||
|
||||
should "autocomplete tags from wiki and artist other names" do
|
||||
create(:tag, name: "touhou")
|
||||
create(:tag, name: "bkub", category: Tag.categories.artist)
|
||||
create(:wiki_page, title: "touhou", other_names: %w[東方 东方 동방])
|
||||
create(:artist, name: "bkub", other_names: %w[大川ぶくぶ フミンバイン])
|
||||
|
||||
assert_autocomplete_equals(["touhou"], "東", :tag_query)
|
||||
assert_autocomplete_equals(["touhou"], "东", :tag_query)
|
||||
assert_autocomplete_equals(["touhou"], "동", :tag_query)
|
||||
|
||||
assert_autocomplete_equals(["touhou"], "*東*", :tag_query)
|
||||
assert_autocomplete_equals(["touhou"], "東*", :tag_query)
|
||||
assert_autocomplete_equals([], "*東", :tag_query)
|
||||
|
||||
assert_autocomplete_equals(["touhou"], "*方*", :tag_query)
|
||||
assert_autocomplete_equals(["touhou"], "*方", :tag_query)
|
||||
assert_autocomplete_equals([], "方", :tag_query)
|
||||
|
||||
assert_autocomplete_equals(["bkub"], "*大*", :tag_query)
|
||||
assert_autocomplete_equals(["bkub"], "大", :tag_query)
|
||||
assert_autocomplete_equals([], "*大", :tag_query)
|
||||
|
||||
assert_autocomplete_equals(["bkub"], "*川*", :tag_query)
|
||||
assert_autocomplete_equals([], "*川", :tag_query)
|
||||
assert_autocomplete_equals([], "川", :tag_query)
|
||||
end
|
||||
|
||||
should "autocomplete wildcard searches" do
|
||||
create(:tag, name: "mole", post_count: 150)
|
||||
create(:tag, name: "mole_under_eye", post_count: 100)
|
||||
|
||||
Reference in New Issue
Block a user