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

View File

@@ -1,5 +1,7 @@
import { CANCELLED_STATUS } from 'discourse/lib/autocomplete'; import { CANCELLED_STATUS } from 'discourse/lib/autocomplete';
import Category from 'discourse/models/category'; 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 cache = {};
var cacheTime; var cacheTime;
@@ -27,7 +29,18 @@ function searchTags(term, categories, limit) {
var returnVal = CANCELLED_STATUS; var returnVal = CANCELLED_STATUS;
oldSearch.then((r) => { 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); returnVal = cats.concat(tags);
}).always(() => { }).always(() => {
oldSearch = null; oldSearch = null;
@@ -55,7 +68,10 @@ export function search(term, siteSettings) {
const limit = 5; const limit = 5;
var categories = Category.search(term, { limit }); var categories = Category.search(term, { limit });
var numOfCategories = categories.length; 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) { if (numOfCategories !== limit && siteSettings.tagging_enabled) {
return searchTags(term, categories, limit - numOfCategories); return searchTags(term, categories, limit - numOfCategories);

View File

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

View File

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

View File

@@ -91,7 +91,8 @@ module PrettyText
if !is_tag && category = Category.query_from_hashtag_slug(text) if !is_tag && category = Category.query_from_hashtag_slug(text)
[category.url_with_id, 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] ["#{Discourse.base_url}/tags/#{tag.name}", text]
else else
nil nil

View File

@@ -717,16 +717,22 @@ describe PrettyText do
expect(cooked).to eq(n expected) expect(cooked).to eq(n expected)
end 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')]) 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> "<span class=\"hashtag\">#unknown::tag</span>",
HTML "<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)") cooked = PrettyText.cook("[`a` #known::tag here](http://somesite.com)")