DEV: Simplify watched word code (#13103)

* DEV: Use site setting instead

* DEV: Use .length instead of a different property

* DEV: Simplify watched word code
This commit is contained in:
Bianca Nenciu 2021-05-27 19:20:26 +03:00 committed by GitHub
parent 571ee4537a
commit b56e9ad656
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 85 additions and 149 deletions

View File

@ -19,12 +19,13 @@ export default Component.extend({
canReplace: equal("actionKey", "replace"),
canTag: equal("actionKey", "tag"),
@discourseComputed("regularExpressions")
placeholderKey(regularExpressions) {
return (
"admin.watched_words.form.placeholder" +
(regularExpressions ? "_regexp" : "")
);
@discourseComputed("siteSettings.watched_words_regular_expressions")
placeholderKey(watchedWordsRegularExpressions) {
if (watchedWordsRegularExpressions) {
return "admin.watched_words.form.placeholder_regexp";
} else {
return "admin.watched_words.form.placeholder";
}
},
@observes("word")

View File

@ -12,20 +12,14 @@ import showModal from "discourse/lib/show-modal";
export default Controller.extend({
adminWatchedWords: controller(),
actionNameKey: null,
showWordsList: or(
"adminWatchedWords.filtered",
"adminWatchedWords.showWords"
),
downloadLink: fmt(
"actionNameKey",
"/admin/customize/watched_words/action/%@/download"
),
showWordsList: or("adminWatchedWords.showWords", "adminWatchedWords.filter"),
findAction(actionName) {
return (this.get("adminWatchedWords.model") || []).findBy(
"nameKey",
actionName
);
return (this.adminWatchedWords.model || []).findBy("nameKey", actionName);
},
@discourseComputed("actionNameKey", "adminWatchedWords.model")
@ -33,57 +27,56 @@ export default Controller.extend({
return this.findAction(actionName);
},
@discourseComputed("currentAction.words.[]", "adminWatchedWords.model")
filteredContent(words) {
return words || [];
},
@discourseComputed("actionNameKey")
actionDescription(actionNameKey) {
return I18n.t("admin.watched_words.action_descriptions." + actionNameKey);
},
@discourseComputed("currentAction.count")
wordCount(count) {
return count || 0;
},
actions: {
recordAdded(arg) {
const a = this.findAction(this.actionNameKey);
if (a) {
a.words.unshiftObject(arg);
a.incrementProperty("count");
schedule("afterRender", () => {
// remove from other actions lists
let match = null;
this.get("adminWatchedWords.model").forEach((action) => {
if (match) {
return;
}
if (action.nameKey !== this.actionNameKey) {
match = action.words.findBy("id", arg.id);
if (match) {
action.words.removeObject(match);
action.decrementProperty("count");
}
}
});
});
const action = this.findAction(this.actionNameKey);
if (!action) {
return;
}
action.words.unshiftObject(arg);
schedule("afterRender", () => {
// remove from other actions lists
let match = null;
this.adminWatchedWords.model.forEach((otherAction) => {
if (match) {
return;
}
if (otherAction.nameKey !== this.actionNameKey) {
match = otherAction.words.findBy("id", arg.id);
if (match) {
otherAction.words.removeObject(match);
}
}
});
});
},
recordRemoved(arg) {
if (this.currentAction) {
this.currentAction.words.removeObject(arg);
this.currentAction.decrementProperty("count");
}
},
uploadComplete() {
WatchedWord.findAll().then((data) => {
this.set("adminWatchedWords.model", data);
this.adminWatchedWords.set("model", data);
});
},
test() {
WatchedWord.findAll().then((data) => {
this.adminWatchedWords.set("model", data);
showModal("admin-watched-word-test", {
admin: true,
model: this.currentAction,
});
});
},
@ -102,25 +95,12 @@ export default Controller.extend({
}).then(() => {
const action = this.findAction(actionKey);
if (action) {
action.setProperties({
words: [],
count: 0,
});
action.set("words", []);
}
});
}
}
);
},
test() {
WatchedWord.findAll().then((data) => {
this.set("adminWatchedWords.model", data);
showModal("admin-watched-word-test", {
admin: true,
model: this.currentAction,
});
});
},
},
});

View File

@ -1,71 +1,56 @@
import Controller from "@ember/controller";
import EmberObject from "@ember/object";
import EmberObject, { action } from "@ember/object";
import { INPUT_DELAY } from "discourse-common/config/environment";
import { alias } from "@ember/object/computed";
import discourseDebounce from "discourse-common/lib/debounce";
import { isEmpty } from "@ember/utils";
import { observes } from "discourse-common/utils/decorators";
export default Controller.extend({
filter: null,
filtered: false,
showWords: false,
disableShowWords: alias("filtered"),
regularExpressions: null,
filterContentNow() {
if (!!isEmpty(this.allWatchedWords)) {
_filterContent() {
if (isEmpty(this.allWatchedWords)) {
return;
}
let filter;
if (this.filter) {
filter = this.filter.toLowerCase();
}
if (filter === undefined || filter.length < 1) {
if (!this.filter) {
this.set("model", this.allWatchedWords);
return;
}
const matchesByAction = [];
const filter = this.filter.toLowerCase();
const model = [];
this.allWatchedWords.forEach((wordsForAction) => {
const wordRecords = wordsForAction.words.filter((wordRecord) => {
return wordRecord.word.indexOf(filter) > -1;
});
matchesByAction.pushObject(
model.pushObject(
EmberObject.create({
nameKey: wordsForAction.nameKey,
name: wordsForAction.name,
words: wordRecords,
count: wordRecords.length,
})
);
});
this.set("model", matchesByAction);
this.set("model", model);
},
@observes("filter")
filterContent() {
discourseDebounce(
this,
function () {
this.filterContentNow();
this.set("filtered", !isEmpty(this.filter));
},
INPUT_DELAY
);
discourseDebounce(this, this._filterContent, INPUT_DELAY);
},
actions: {
clearFilter() {
this.setProperties({ filter: "" });
},
@action
clearFilter() {
this.set("filter", "");
},
toggleMenu() {
$(".admin-detail").toggleClass("mobile-closed mobile-open");
},
@action
toggleMenu() {
$(".admin-detail").toggleClass("mobile-closed mobile-open");
},
});

View File

@ -31,27 +31,21 @@ WatchedWord.reopenClass({
findAll() {
return ajax("/admin/customize/watched_words.json").then((list) => {
const actions = {};
list.words.forEach((s) => {
if (!actions[s.action]) {
actions[s.action] = [];
}
actions[s.action].pushObject(WatchedWord.create(s));
list.actions.forEach((action) => {
actions[action] = [];
});
list.actions.forEach((a) => {
if (!actions[a]) {
actions[a] = [];
}
list.words.forEach((watchedWord) => {
actions[watchedWord.action].pushObject(WatchedWord.create(watchedWord));
});
return Object.keys(actions).map((n) => {
return Object.keys(actions).map((nameKey) => {
return EmberObject.create({
nameKey: n,
name: I18n.t("admin.watched_words.actions." + n),
words: actions[n],
count: actions[n].length,
regularExpressions: list.regular_expressions,
compiledRegularExpression: list.compiled_regular_expressions[n],
nameKey,
name: I18n.t("admin.watched_words.actions." + nameKey),
words: actions[nameKey],
compiledRegularExpression: list.compiled_regular_expressions[nameKey],
});
});
});

View File

@ -4,17 +4,12 @@ import I18n from "I18n";
export default DiscourseRoute.extend({
model(params) {
this.controllerFor("adminWatchedWordsAction").set(
"actionNameKey",
params.action_id
);
let filteredContent = this.controllerFor("adminWatchedWordsAction").get(
"filteredContent"
);
const controller = this.controllerFor("adminWatchedWordsAction");
controller.set("actionNameKey", params.action_id);
return EmberObject.create({
nameKey: params.action_id,
name: I18n.t("admin.watched_words.actions." + params.action_id),
words: filteredContent,
words: controller.filteredContent,
});
},
});

View File

@ -10,17 +10,8 @@ export default DiscourseRoute.extend({
return WatchedWord.findAll();
},
setupController(controller, model) {
controller.set("model", model);
if (model && model.length) {
controller.set("regularExpressions", model[0].get("regularExpressions"));
}
},
afterModel(watchedWordsList) {
this.controllerFor("adminWatchedWords").set(
"allWatchedWords",
watchedWordsList
);
afterModel(model) {
const controller = this.controllerFor("adminWatchedWords");
controller.set("allWatchedWords", model);
},
});

View File

@ -25,19 +25,19 @@
{{watched-word-form
actionKey=actionNameKey
action=(action "recordAdded")
filteredContent=filteredContent
regularExpressions=adminWatchedWords.regularExpressions}}
filteredContent=currentAction.words
}}
{{#if wordCount}}
{{#if currentAction.words}}
<label class="show-words-checkbox">
{{input type="checkbox" checked=adminWatchedWords.showWords disabled=adminWatchedWords.disableShowWords}}
{{i18n "admin.watched_words.show_words" count=wordCount}}
{{i18n "admin.watched_words.show_words" count=currentAction.words.length}}
</label>
{{/if}}
{{#if showWordsList}}
<div class="watched-words-list">
{{#each filteredContent as |word| }}
{{#each currentAction.words as |word| }}
<div class="watched-word-box">{{admin-watched-word actionKey=actionNameKey word=word action=(action "recordRemoved")}}</div>
{{/each}}
</div>

View File

@ -12,7 +12,7 @@
<li class={{action.nameKey}}>
{{#link-to "adminWatchedWords.action" action.nameKey}}
{{action.name}}
{{#if action.count}}<span class="count">({{action.count}})</span>{{/if}}
{{#if action.words}}<span class="count">({{action.words.length}})</span>{{/if}}
{{/link-to}}
</li>
{{/each}}

View File

@ -27,11 +27,6 @@ function censorTree(state, censor) {
}
export function setup(helper) {
helper.registerOptions((opts, siteSettings) => {
opts.watchedWordsRegularExpressions =
siteSettings.watched_words_regular_expressions;
});
helper.registerPlugin((md) => {
const censoredRegexp = md.options.discourse.censoredRegexp;

View File

@ -1,3 +1,5 @@
const MAX_MATCHES = 100;
function isLinkOpen(str) {
return /^<a[>\s]/i.test(str);
}
@ -9,14 +11,13 @@ function isLinkClose(str) {
function findAllMatches(text, matchers) {
const matches = [];
const maxMatches = 100;
let count = 0;
matchers.forEach((matcher) => {
let match;
while (
(match = matcher.pattern.exec(text)) !== null &&
count++ < maxMatches
count++ < MAX_MATCHES
) {
matches.push({
index: match.index,

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
class WatchedWordListSerializer < ApplicationSerializer
attributes :actions, :words, :regular_expressions, :compiled_regular_expressions
attributes :actions, :words, :compiled_regular_expressions
def actions
SiteSetting.tagging_enabled ? WatchedWord.actions.keys
@ -14,12 +14,6 @@ class WatchedWordListSerializer < ApplicationSerializer
end
end
# No point making this site setting `client: true` when it's only used
# in the admin section
def regular_expressions
SiteSetting.watched_words_regular_expressions?
end
def compiled_regular_expressions
expressions = {}
actions.each do |action|