UX: Only include tag hashtag postfix when necessary.

https://meta.discourse.org/t/links-to-tags-not-working-in-final-post-unless-autocompleted/69884/6?u=tgxworld
This commit is contained in:
Guo Xiang Tan 2017-10-03 13:54:50 +08:00
parent 85c5bb4ea4
commit 3e53dbcade
6 changed files with 35 additions and 25 deletions

View File

@ -1,10 +1,7 @@
/*global Mousetrap:true */
import { default as computed, on, observes } from 'ember-addons/ember-computed-decorators';
import Category from 'discourse/models/category';
import { categoryHashtagTriggerRule } from 'discourse/lib/category-hashtags';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import { cookAsync } from 'discourse/lib/text';
import { translations } from 'pretty-text/emoji/data';
import { emojiSearch, isSkinTonableEmoji } from 'pretty-text/emoji';
@ -322,11 +319,7 @@ export default Ember.Component.extend({
template: findRawTemplate('category-tag-autocomplete'),
key: '#',
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
return obj.text;
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);

View File

@ -1,5 +1,7 @@
import { CANCELLED_STATUS } from 'discourse/lib/autocomplete';
import Category from 'discourse/models/category';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
var cache = {};
var cacheTime;
@ -27,7 +29,18 @@ function searchTags(term, categories, limit) {
var returnVal = CANCELLED_STATUS;
oldSearch.then((r) => {
var tags = r.results.map((tag) => { return { text: tag.text, count: tag.count }; });
const categoryNames = cats.map(c => c.model.get('name'));
const tags = r.results.map((tag) => {
const tagName = tag.text;
return {
name: tagName,
text: (categoryNames.includes(tagName) ? `${tagName}${TAG_HASHTAG_POSTFIX}` : tagName),
count: tag.count,
};
});
returnVal = cats.concat(tags);
}).always(() => {
oldSearch = null;
@ -55,7 +68,10 @@ export function search(term, siteSettings) {
const limit = 5;
var categories = Category.search(term, { limit });
var numOfCategories = categories.length;
categories = categories.map((category) => { return { model: category }; });
categories = categories.map((category) => {
return { model: category, text: Category.slugFor(category, SEPARATOR) };
});
if (numOfCategories !== limit && siteSettings.tagging_enabled) {
return searchTags(term, categories, limit - numOfCategories);

View File

@ -1,7 +1,5 @@
import { ajax } from 'discourse/lib/ajax';
import { findRawTemplate } from 'discourse/lib/raw-templates';
import { TAG_HASHTAG_POSTFIX } from 'discourse/lib/tag-hashtags';
import { SEPARATOR } from 'discourse/lib/category-hashtags';
import Category from 'discourse/models/category';
import { search as searchCategoryTag } from 'discourse/lib/category-tag-search';
import userSearch from 'discourse/lib/user-search';
@ -148,11 +146,7 @@ export function applySearchAutocomplete($input, siteSettings, appEvents, options
width: '100%',
treatAsTextarea: true,
transformComplete(obj) {
if (obj.model) {
return Category.slugFor(obj.model, SEPARATOR);
} else {
return `${obj.text}${TAG_HASHTAG_POSTFIX}`;
}
return obj.text;
},
dataSource(term) {
return searchCategoryTag(term, siteSettings);

View File

@ -5,7 +5,7 @@
{{#if option.model}}
<a href>{{category-link option.model allowUncategorized="true" link="false"}}</a>
{{else}}
<a href>{{d-icon 'tag'}}{{option.text}} x {{option.count}}</a>
<a href>{{d-icon 'tag'}}{{option.name}} x {{option.count}}</a>
{{/if}}
</li>
{{/each}}

View File

@ -91,7 +91,8 @@ module PrettyText
if !is_tag && category = Category.query_from_hashtag_slug(text)
[category.url_with_id, text]
elsif is_tag && tag = Tag.find_by_name(text.gsub!("#{tag_postfix}", ''))
elsif (!is_tag && tag = Tag.find_by(name: text)) ||
(is_tag && tag = Tag.find_by(name: text.gsub!("#{tag_postfix}", '')))
["#{Discourse.base_url}/tags/#{tag.name}", text]
else
nil

View File

@ -717,16 +717,22 @@ describe PrettyText do
expect(cooked).to eq(n expected)
end
it "produces tag links" do
it "produces hashtag links" do
category = Fabricate(:category, name: 'testing')
category2 = Fabricate(:category, name: 'known')
Fabricate(:topic, tags: [Fabricate(:tag, name: 'known')])
cooked = PrettyText.cook(" #unknown::tag #known::tag")
cooked = PrettyText.cook(" #unknown::tag #known #known::tag #testing")
html = <<~HTML
<p><span class=\"hashtag\">#unknown::tag</span> <a class=\"hashtag\" href=\"http://test.localhost/tags/known\">#<span>known</span></a></p>
HTML
[
"<span class=\"hashtag\">#unknown::tag</span>",
"<a class=\"hashtag\" href=\"#{category2.url_with_id}\">#<span>known</span></a>",
"<a class=\"hashtag\" href=\"http://test.localhost/tags/known\">#<span>known</span></a>",
"<a class=\"hashtag\" href=\"#{category.url_with_id}\">#<span>testing</span></a>"
].each do |element|
expect(cooked).to eq(html.strip)
expect(cooked).to include(element)
end
cooked = PrettyText.cook("[`a` #known::tag here](http://somesite.com)")