DEV: Wrap `Ember.run.debounce`. (#11352)
We want to wrap the `Ember.run.debounce` function and internally call `Ember.run` instead when running tests. This commit changes discourseDebounce to work the same way as `Ember.run.debounce`. Now that `discourseDebounce` works exactly like `Ember.run.debounce`, let's replace it and only use `DiscourseDebounce` from now on. Move debounce to discourse-common to be able to reuse it in different bundles Keep old debounce file for backwards-compatibility
This commit is contained in:
parent
fb2e24a77a
commit
8b426431a4
|
@ -1,7 +1,7 @@
|
|||
import { observes, on } from "discourse-common/utils/decorators";
|
||||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
|
||||
export default Component.extend({
|
||||
|
@ -33,9 +33,7 @@ export default Component.extend({
|
|||
}
|
||||
},
|
||||
|
||||
@on("init")
|
||||
@observes("logs.[]")
|
||||
_updateFormattedLogs: discourseDebounce(function () {
|
||||
_updateFormattedLogsFunc: function () {
|
||||
const logs = this.logs;
|
||||
if (logs.length === 0) {
|
||||
return;
|
||||
|
@ -57,7 +55,13 @@ export default Component.extend({
|
|||
this.renderLogs();
|
||||
|
||||
scheduleOnce("afterRender", this, this._scrollDown);
|
||||
}, 150),
|
||||
},
|
||||
|
||||
@on("init")
|
||||
@observes("logs.[]")
|
||||
_updateFormattedLogs() {
|
||||
discourseDebounce(this, this._updateFormattedLogsFunc, 150);
|
||||
},
|
||||
|
||||
renderLogs() {
|
||||
const formattedLogs = this.formattedLogs;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { debounce, schedule } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
import { number } from "discourse/lib/formatter";
|
||||
import { schedule } from "@ember/runloop";
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ["admin-report-chart"],
|
||||
|
@ -14,7 +15,7 @@ export default Component.extend({
|
|||
this._super(...arguments);
|
||||
|
||||
this.resizeHandler = () =>
|
||||
debounce(this, this._scheduleChartRendering, 500);
|
||||
discourseDebounce(this, this._scheduleChartRendering, 500);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
|
@ -34,7 +35,7 @@ export default Component.extend({
|
|||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
debounce(this, this._scheduleChartRendering, 100);
|
||||
discourseDebounce(this, this._scheduleChartRendering, 100);
|
||||
},
|
||||
|
||||
_scheduleChartRendering() {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { debounce, schedule } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
import { number } from "discourse/lib/formatter";
|
||||
import { schedule } from "@ember/runloop";
|
||||
|
||||
export default Component.extend({
|
||||
classNames: ["admin-report-chart", "admin-report-stacked-chart"],
|
||||
|
@ -11,7 +12,7 @@ export default Component.extend({
|
|||
this._super(...arguments);
|
||||
|
||||
this.resizeHandler = () =>
|
||||
debounce(this, this._scheduleChartRendering, 500);
|
||||
discourseDebounce(this, this._scheduleChartRendering, 500);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
|
@ -31,7 +32,7 @@ export default Component.extend({
|
|||
didReceiveAttrs() {
|
||||
this._super(...arguments);
|
||||
|
||||
debounce(this, this._scheduleChartRendering, 100);
|
||||
discourseDebounce(this, this._scheduleChartRendering, 100);
|
||||
},
|
||||
|
||||
_scheduleChartRendering() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
|
||||
const { get } = Ember;
|
||||
|
||||
|
@ -34,7 +34,7 @@ export default Controller.extend({
|
|||
|
||||
actions: {
|
||||
filterReports(filter) {
|
||||
debounce(this, this._performFiltering, filter, INPUT_DELAY);
|
||||
discourseDebounce(this, this._performFiltering, filter, INPUT_DELAY);
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default AdminEmailLogsController.extend({
|
||||
@observes("filter.{status,user,address,type}")
|
||||
filterEmailLogs: discourseDebounce(function () {
|
||||
this.loadLogs();
|
||||
}, INPUT_DELAY),
|
||||
filterEmailLogs() {
|
||||
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import IncomingEmail from "admin/models/incoming-email";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default AdminEmailLogsController.extend({
|
||||
@observes("filter.{status,from,to,subject}")
|
||||
filterIncomingEmails: discourseDebounce(function () {
|
||||
this.loadLogs(IncomingEmail);
|
||||
}, INPUT_DELAY),
|
||||
filterIncomingEmails() {
|
||||
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
|
||||
},
|
||||
|
||||
actions: {
|
||||
loadMore() {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import IncomingEmail from "admin/models/incoming-email";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default AdminEmailLogsController.extend({
|
||||
@observes("filter.{status,from,to,subject,error}")
|
||||
filterIncomingEmails: discourseDebounce(function () {
|
||||
this.loadLogs(IncomingEmail);
|
||||
}, INPUT_DELAY),
|
||||
filterIncomingEmails() {
|
||||
discourseDebounce(this, this.loadLogs, IncomingEmail, INPUT_DELAY);
|
||||
},
|
||||
|
||||
actions: {
|
||||
loadMore() {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default AdminEmailLogsController.extend({
|
||||
@observes("filter.{status,user,address,type,reply_key}")
|
||||
filterEmailLogs: discourseDebounce(function () {
|
||||
this.loadLogs();
|
||||
}, INPUT_DELAY),
|
||||
filterEmailLogs() {
|
||||
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import AdminEmailLogsController from "admin/controllers/admin-email-logs";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default AdminEmailLogsController.extend({
|
||||
@observes("filter.{status,user,address,type}")
|
||||
filterEmailLogs: discourseDebounce(function () {
|
||||
this.loadLogs();
|
||||
}, INPUT_DELAY),
|
||||
filterEmailLogs() {
|
||||
discourseDebounce(this, this.loadLogs, INPUT_DELAY);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,7 +3,7 @@ import I18n from "I18n";
|
|||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import ScreenedIpAddress from "admin/models/screened-ip-address";
|
||||
import bootbox from "bootbox";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { exportEntity } from "discourse/lib/export-csv";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import { outputExportResult } from "discourse/lib/export-result";
|
||||
|
@ -13,13 +13,17 @@ export default Controller.extend({
|
|||
filter: null,
|
||||
savedIpAddress: null,
|
||||
|
||||
@observes("filter")
|
||||
show: discourseDebounce(function () {
|
||||
_debouncedShow() {
|
||||
this.set("loading", true);
|
||||
ScreenedIpAddress.findAll(this.filter).then((result) => {
|
||||
this.setProperties({ model: result, loading: false });
|
||||
});
|
||||
}, INPUT_DELAY),
|
||||
},
|
||||
|
||||
@observes("filter")
|
||||
show() {
|
||||
discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
|
||||
},
|
||||
|
||||
actions: {
|
||||
allow(record) {
|
||||
|
|
|
@ -3,20 +3,24 @@ import I18n from "I18n";
|
|||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import Permalink from "admin/models/permalink";
|
||||
import bootbox from "bootbox";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
export default Controller.extend({
|
||||
loading: false,
|
||||
filter: null,
|
||||
|
||||
@observes("filter")
|
||||
show: discourseDebounce(function () {
|
||||
_debouncedShow() {
|
||||
Permalink.findAll(this.filter).then((result) => {
|
||||
this.set("model", result);
|
||||
this.set("loading", false);
|
||||
});
|
||||
}, INPUT_DELAY),
|
||||
},
|
||||
|
||||
@observes("filter")
|
||||
show() {
|
||||
discourseDebounce(this, this._debouncedShow, INPUT_DELAY);
|
||||
},
|
||||
|
||||
actions: {
|
||||
recordAdded(arg) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import Controller from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
|
@ -112,13 +112,19 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
@observes("filter", "onlyOverridden", "model")
|
||||
filterContent: discourseDebounce(function () {
|
||||
if (this._skipBounce) {
|
||||
this.set("_skipBounce", false);
|
||||
} else {
|
||||
this.filterContentNow(this.categoryNameKey);
|
||||
}
|
||||
}, INPUT_DELAY),
|
||||
filterContent() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
() => {
|
||||
if (this._skipBounce) {
|
||||
this.set("_skipBounce", false);
|
||||
} else {
|
||||
this.filterContentNow(this.categoryNameKey);
|
||||
}
|
||||
},
|
||||
INPUT_DELAY
|
||||
);
|
||||
},
|
||||
|
||||
actions: {
|
||||
clearFilter() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Controller from "@ember/controller";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
let lastSearch;
|
||||
|
||||
export default Controller.extend({
|
||||
|
@ -28,14 +28,14 @@ export default Controller.extend({
|
|||
toggleOverridden() {
|
||||
this.toggleProperty("overridden");
|
||||
this.set("searching", true);
|
||||
debounce(this, this._performSearch, 400);
|
||||
discourseDebounce(this, this._performSearch, 400);
|
||||
},
|
||||
|
||||
search() {
|
||||
const q = this.q;
|
||||
if (q !== lastSearch) {
|
||||
this.set("searching", true);
|
||||
debounce(this, this._performSearch, 400);
|
||||
discourseDebounce(this, this._performSearch, 400);
|
||||
lastSearch = q;
|
||||
}
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@ import CanCheckEmails from "discourse/mixins/can-check-emails";
|
|||
import Controller from "@ember/controller";
|
||||
import I18n from "I18n";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { i18n } from "discourse/lib/computed";
|
||||
|
||||
export default Controller.extend(CanCheckEmails, {
|
||||
|
@ -32,9 +32,9 @@ export default Controller.extend(CanCheckEmails, {
|
|||
},
|
||||
|
||||
@observes("listFilter")
|
||||
_filterUsers: discourseDebounce(function () {
|
||||
this.resetFilters();
|
||||
}, INPUT_DELAY),
|
||||
_filterUsers() {
|
||||
discourseDebounce(this, this.resetFilters, INPUT_DELAY);
|
||||
},
|
||||
|
||||
resetFilters() {
|
||||
this._page = 1;
|
||||
|
|
|
@ -2,7 +2,7 @@ import Controller from "@ember/controller";
|
|||
import EmberObject from "@ember/object";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
||||
|
@ -48,10 +48,16 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
@observes("filter")
|
||||
filterContent: discourseDebounce(function () {
|
||||
this.filterContentNow();
|
||||
this.set("filtered", !isEmpty(this.filter));
|
||||
}, INPUT_DELAY),
|
||||
filterContent() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
this.filterContentNow();
|
||||
this.set("filtered", !isEmpty(this.filter));
|
||||
},
|
||||
INPUT_DELAY
|
||||
);
|
||||
},
|
||||
|
||||
actions: {
|
||||
clearFilter() {
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
import { debounce, run } from "@ember/runloop";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
/**
|
||||
Debounce a Javascript function. This means if it's called many times in a time limit it
|
||||
should only be executed once (at the end of the limit counted from the last call made).
|
||||
Original function will be called with the context and arguments from the last call made.
|
||||
**/
|
||||
|
||||
export default function () {
|
||||
if (isTesting()) {
|
||||
return run(...arguments);
|
||||
} else {
|
||||
return debounce(...arguments);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import Component from "@ember/component";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { get } from "@ember/object";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { next } from "@ember/runloop";
|
||||
|
@ -30,31 +30,38 @@ export default Component.extend({
|
|||
this.set("loading", false);
|
||||
},
|
||||
|
||||
search: discourseDebounce(function (title) {
|
||||
const currentTopicId = this.currentTopicId;
|
||||
search(title) {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
const currentTopicId = this.currentTopicId;
|
||||
|
||||
if (isEmpty(title)) {
|
||||
this.setProperties({ messages: null, loading: false });
|
||||
return;
|
||||
}
|
||||
if (isEmpty(title)) {
|
||||
this.setProperties({ messages: null, loading: false });
|
||||
return;
|
||||
}
|
||||
|
||||
searchForTerm(title, {
|
||||
typeFilter: "private_messages",
|
||||
searchForId: true,
|
||||
restrictToArchetype: "private_message",
|
||||
}).then((results) => {
|
||||
if (results && results.posts && results.posts.length > 0) {
|
||||
this.set(
|
||||
"messages",
|
||||
results.posts
|
||||
.mapBy("topic")
|
||||
.filter((t) => t.get("id") !== currentTopicId)
|
||||
);
|
||||
} else {
|
||||
this.setProperties({ messages: null, loading: false });
|
||||
}
|
||||
});
|
||||
}, 300),
|
||||
searchForTerm(title, {
|
||||
typeFilter: "private_messages",
|
||||
searchForId: true,
|
||||
restrictToArchetype: "private_message",
|
||||
}).then((results) => {
|
||||
if (results && results.posts && results.posts.length > 0) {
|
||||
this.set(
|
||||
"messages",
|
||||
results.posts
|
||||
.mapBy("topic")
|
||||
.filter((t) => t.get("id") !== currentTopicId)
|
||||
);
|
||||
} else {
|
||||
this.setProperties({ messages: null, loading: false });
|
||||
}
|
||||
});
|
||||
},
|
||||
title,
|
||||
300
|
||||
);
|
||||
},
|
||||
|
||||
actions: {
|
||||
chooseMessage(message) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import Component from "@ember/component";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { next } from "@ember/runloop";
|
||||
import { searchForTerm } from "discourse/lib/search";
|
||||
|
@ -64,37 +64,46 @@ export default Component.extend({
|
|||
this.set("loading", false);
|
||||
},
|
||||
|
||||
search: discourseDebounce(function (title) {
|
||||
if (!this.element || this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
search(title) {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
if (!this.element || this.isDestroying || this.isDestroyed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEmpty(title) && isEmpty(this.additionalFilters)) {
|
||||
this.setProperties({ topics: null, loading: false });
|
||||
return;
|
||||
}
|
||||
if (isEmpty(title) && isEmpty(this.additionalFilters)) {
|
||||
this.setProperties({ topics: null, loading: false });
|
||||
return;
|
||||
}
|
||||
|
||||
const currentTopicId = this.currentTopicId;
|
||||
const titleWithFilters = `${title} ${this.additionalFilters}`;
|
||||
let searchParams = {};
|
||||
const currentTopicId = this.currentTopicId;
|
||||
const titleWithFilters = `${title} ${this.additionalFilters}`;
|
||||
let searchParams = {};
|
||||
|
||||
if (!isEmpty(title)) {
|
||||
searchParams.typeFilter = "topic";
|
||||
searchParams.restrictToArchetype = "regular";
|
||||
searchParams.searchForId = true;
|
||||
}
|
||||
if (!isEmpty(title)) {
|
||||
searchParams.typeFilter = "topic";
|
||||
searchParams.restrictToArchetype = "regular";
|
||||
searchParams.searchForId = true;
|
||||
}
|
||||
|
||||
searchForTerm(titleWithFilters, searchParams).then((results) => {
|
||||
if (results && results.posts && results.posts.length > 0) {
|
||||
this.set(
|
||||
"topics",
|
||||
results.posts.mapBy("topic").filter((t) => t.id !== currentTopicId)
|
||||
);
|
||||
} else {
|
||||
this.setProperties({ topics: null, loading: false });
|
||||
}
|
||||
});
|
||||
}, 300),
|
||||
searchForTerm(titleWithFilters, searchParams).then((results) => {
|
||||
if (results && results.posts && results.posts.length > 0) {
|
||||
this.set(
|
||||
"topics",
|
||||
results.posts
|
||||
.mapBy("topic")
|
||||
.filter((t) => t.id !== currentTopicId)
|
||||
);
|
||||
} else {
|
||||
this.setProperties({ topics: null, loading: false });
|
||||
}
|
||||
});
|
||||
},
|
||||
title,
|
||||
300
|
||||
);
|
||||
},
|
||||
|
||||
actions: {
|
||||
chooseTopic(topic) {
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
import {
|
||||
cancel,
|
||||
debounce,
|
||||
later,
|
||||
run,
|
||||
schedule,
|
||||
throttle,
|
||||
} from "@ember/runloop";
|
||||
import { cancel, later, run, schedule, throttle } from "@ember/runloop";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import Component from "@ember/component";
|
||||
import Composer from "discourse/models/composer";
|
||||
import KeyEnterEscape from "discourse/mixins/key-enter-escape";
|
||||
import afterTransition from "discourse/lib/after-transition";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { headerHeight } from "discourse/components/site-header";
|
||||
import { iOSWithVisualViewport } from "discourse/lib/utilities";
|
||||
import positioningWorkaround from "discourse/lib/safari-hacks";
|
||||
|
@ -76,7 +70,7 @@ export default Component.extend(KeyEnterEscape, {
|
|||
return;
|
||||
}
|
||||
|
||||
debounce(this, this.debounceMove, 300);
|
||||
discourseDebounce(this, this.debounceMove, 300);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import {
|
|||
inCodeBlock,
|
||||
tinyAvatar,
|
||||
} from "discourse/lib/utilities";
|
||||
import { debounce, later, next, run, schedule, throttle } from "@ember/runloop";
|
||||
import discourseComputed, {
|
||||
observes,
|
||||
on,
|
||||
|
@ -28,12 +27,14 @@ import {
|
|||
fetchUnseenMentions,
|
||||
linkSeenMentions,
|
||||
} from "discourse/lib/link-mentions";
|
||||
import { later, next, run, schedule, throttle } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import Composer from "discourse/models/composer";
|
||||
import EmberObject from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import bootbox from "bootbox";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { findRawTemplate } from "discourse-common/lib/raw-templates";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
|
@ -905,7 +906,7 @@ export default Component.extend({
|
|||
// Paint mentions
|
||||
const unseenMentions = linkSeenMentions($preview, this.siteSettings);
|
||||
if (unseenMentions.length) {
|
||||
debounce(
|
||||
discourseDebounce(
|
||||
this,
|
||||
this._renderUnseenMentions,
|
||||
$preview,
|
||||
|
@ -920,7 +921,7 @@ export default Component.extend({
|
|||
// Paint category and tag hashtags
|
||||
const unseenHashtags = linkSeenHashtags($preview);
|
||||
if (unseenHashtags.length > 0) {
|
||||
debounce(this, this._renderUnseenHashtags, $preview, 450);
|
||||
discourseDebounce(this, this._renderUnseenHashtags, $preview, 450);
|
||||
}
|
||||
|
||||
// Paint oneboxes
|
||||
|
@ -947,7 +948,7 @@ export default Component.extend({
|
|||
}
|
||||
};
|
||||
|
||||
debounce(this, paintFunc, 450);
|
||||
discourseDebounce(this, paintFunc, 450);
|
||||
|
||||
// Short upload urls need resolution
|
||||
resolveAllShortUrls(ajax, this.siteSettings, $preview[0]);
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { alias, or } from "@ember/object/computed";
|
||||
import { debounce, next, schedule } from "@ember/runloop";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { next, schedule } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import EmberObject from "@ember/object";
|
||||
import I18n from "I18n";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import { load } from "pretty-text/oneboxer";
|
||||
import { lookupCache } from "pretty-text/oneboxer-cache";
|
||||
|
@ -22,7 +23,7 @@ export default Component.extend({
|
|||
}
|
||||
|
||||
if (this.get("composer.titleLength") > 0) {
|
||||
debounce(this, this._titleChanged, 10);
|
||||
discourseDebounce(this, this._titleChanged, 10);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -83,7 +84,7 @@ export default Component.extend({
|
|||
this._checkForUrl()
|
||||
);
|
||||
} else {
|
||||
debounce(this, this._checkForUrl, 500);
|
||||
discourseDebounce(this, this._checkForUrl, 500);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -5,13 +5,13 @@ import {
|
|||
inCodeBlock,
|
||||
safariHacksDisabled,
|
||||
} from "discourse/lib/utilities";
|
||||
import { debounce, later, next, schedule, scheduleOnce } from "@ember/runloop";
|
||||
import discourseComputed, {
|
||||
observes,
|
||||
on,
|
||||
} from "discourse-common/utils/decorators";
|
||||
import { emojiSearch, isSkinTonableEmoji } from "pretty-text/emoji";
|
||||
import { emojiUrlFor, generateCookFunction } from "discourse/lib/text";
|
||||
import { later, next, schedule, scheduleOnce } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
import Mousetrap from "mousetrap";
|
||||
|
@ -19,6 +19,7 @@ import { Promise } from "rsvp";
|
|||
import { SKIP } from "discourse/lib/autocomplete";
|
||||
import { categoryHashtagTriggerRule } from "discourse/lib/category-hashtags";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { findRawTemplate } from "discourse-common/lib/raw-templates";
|
||||
import { getRegister } from "discourse-common/lib/get-owner";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
|
@ -414,7 +415,7 @@ export default Component.extend({
|
|||
if (isTesting()) {
|
||||
this._updatePreview();
|
||||
} else {
|
||||
debounce(this, this._updatePreview, 30);
|
||||
discourseDebounce(this, this._updatePreview, 30);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import I18n from "I18n";
|
|||
import { action } from "@ember/object";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { convertIconClass } from "discourse-common/lib/icon-library";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { htmlSafe } from "@ember/template";
|
||||
|
@ -34,7 +34,7 @@ export default Component.extend({
|
|||
@observes("model.flair_icon")
|
||||
_loadSVGIcon(flairIcon) {
|
||||
if (flairIcon) {
|
||||
debounce(this, this._loadIcon, 1000);
|
||||
discourseDebounce(this, this._loadIcon, 1000);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import Component from "@ember/component";
|
|||
import EmberObject from "@ember/object";
|
||||
import Group from "discourse/models/group";
|
||||
import I18n from "I18n";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { not } from "@ember/object/computed";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
@ -64,40 +64,46 @@ export default Component.extend({
|
|||
);
|
||||
},
|
||||
|
||||
checkGroupName: discourseDebounce(function () {
|
||||
if (isEmpty(this.nameInput)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Group.checkName(this.nameInput)
|
||||
.then((response) => {
|
||||
const validationName = "uniqueNameValidation";
|
||||
|
||||
if (response.available) {
|
||||
this.set(
|
||||
validationName,
|
||||
EmberObject.create({
|
||||
ok: true,
|
||||
reason: I18n.t("admin.groups.new.name.available"),
|
||||
})
|
||||
);
|
||||
|
||||
this.set("disableSave", false);
|
||||
this.set("model.name", this.nameInput);
|
||||
} else {
|
||||
let reason;
|
||||
|
||||
if (response.errors) {
|
||||
reason = response.errors.join(" ");
|
||||
} else {
|
||||
reason = I18n.t("admin.groups.new.name.not_available");
|
||||
}
|
||||
|
||||
this.set(validationName, this._failedInputValidation(reason));
|
||||
checkGroupName() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
if (isEmpty(this.nameInput)) {
|
||||
return;
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
}, 500),
|
||||
|
||||
Group.checkName(this.nameInput)
|
||||
.then((response) => {
|
||||
const validationName = "uniqueNameValidation";
|
||||
|
||||
if (response.available) {
|
||||
this.set(
|
||||
validationName,
|
||||
EmberObject.create({
|
||||
ok: true,
|
||||
reason: I18n.t("admin.groups.new.name.available"),
|
||||
})
|
||||
);
|
||||
|
||||
this.set("disableSave", false);
|
||||
this.set("model.name", this.nameInput);
|
||||
} else {
|
||||
let reason;
|
||||
|
||||
if (response.errors) {
|
||||
reason = response.errors.join(" ");
|
||||
} else {
|
||||
reason = I18n.t("admin.groups.new.name.not_available");
|
||||
}
|
||||
|
||||
this.set(validationName, this._failedInputValidation(reason));
|
||||
}
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
_failedInputValidation(reason) {
|
||||
this.set("disableSave", true);
|
||||
|
|
|
@ -9,7 +9,7 @@ import Sharing from "discourse/lib/sharing";
|
|||
import { action } from "@ember/object";
|
||||
import { alias } from "@ember/object/computed";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { getAbsoluteURL } from "discourse-common/lib/get-url";
|
||||
import { schedule } from "@ember/runloop";
|
||||
import toMarkdown from "discourse/lib/to-markdown";
|
||||
|
@ -183,10 +183,9 @@ export default Component.extend({
|
|||
|
||||
const { isWinphone, isAndroid } = this.capabilities;
|
||||
const wait = isWinphone || isAndroid ? INPUT_DELAY : 25;
|
||||
const onSelectionChanged = discourseDebounce(
|
||||
() => this._selectionChanged(),
|
||||
wait
|
||||
);
|
||||
const onSelectionChanged = () => {
|
||||
discourseDebounce(this, this._selectionChanged, wait);
|
||||
};
|
||||
|
||||
$(document)
|
||||
.on("mousedown.quote-button", (e) => {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { cloak, uncloak } from "discourse/widgets/post-stream";
|
||||
import { debounce, next, scheduleOnce } from "@ember/runloop";
|
||||
import { next, scheduleOnce } from "@ember/runloop";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import MountWidget from "discourse/components/mount-widget";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isWorkaroundActive } from "discourse/lib/safari-hacks";
|
||||
import offsetCalculator from "discourse/lib/offset-calculator";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
@ -309,12 +310,13 @@ export default MountWidget.extend({
|
|||
},
|
||||
|
||||
_debouncedScroll() {
|
||||
debounce(this, this._scrollTriggered, 10);
|
||||
discourseDebounce(this, this._scrollTriggered, 10);
|
||||
},
|
||||
|
||||
didInsertElement() {
|
||||
this._super(...arguments);
|
||||
const debouncedScroll = () => debounce(this, this._scrollTriggered, 10);
|
||||
const debouncedScroll = () =>
|
||||
discourseDebounce(this, this._scrollTriggered, 10);
|
||||
|
||||
this._previouslyNearby = {};
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { cancel, debounce, next } from "@ember/runloop";
|
||||
import { cancel, next } from "@ember/runloop";
|
||||
import { isLTR, isRTL, siteDir } from "discourse/lib/text-direction";
|
||||
import I18n from "I18n";
|
||||
import TextField from "@ember/component/text-field";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
|
||||
const DEBOUNCE_MS = 500;
|
||||
|
||||
|
@ -38,7 +39,11 @@ export default TextField.extend({
|
|||
}
|
||||
if (this.onChange) {
|
||||
cancel(this._timer);
|
||||
this._timer = debounce(this, this._debouncedChange, DEBOUNCE_MS);
|
||||
this._timer = discourseDebounce(
|
||||
this,
|
||||
this._debouncedChange,
|
||||
DEBOUNCE_MS
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -3,9 +3,10 @@ import PanEvents, {
|
|||
SWIPE_VELOCITY,
|
||||
SWIPE_VELOCITY_THRESHOLD,
|
||||
} from "discourse/mixins/pan-events";
|
||||
import { debounce, later } from "@ember/runloop";
|
||||
import Component from "@ember/component";
|
||||
import EmberObject from "@ember/object";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { later } from "@ember/runloop";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
import showModal from "discourse/lib/show-modal";
|
||||
|
||||
|
@ -53,7 +54,7 @@ export default Component.extend(PanEvents, {
|
|||
},
|
||||
|
||||
_checkSize() {
|
||||
debounce(this, this._performCheckSize, 300, true);
|
||||
discourseDebounce(this, this._performCheckSize, 300, true);
|
||||
},
|
||||
|
||||
// we need to store this so topic progress has something to init with
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
authorizesOneOrMoreExtensions,
|
||||
uploadIcon,
|
||||
} from "discourse/lib/uploads";
|
||||
import { cancel, debounce, run } from "@ember/runloop";
|
||||
import { cancel, run } from "@ember/runloop";
|
||||
import {
|
||||
cannotPostAgain,
|
||||
durationTextFromSeconds,
|
||||
|
@ -22,6 +22,7 @@ import { Promise } from "rsvp";
|
|||
import bootbox from "bootbox";
|
||||
import { buildQuote } from "discourse/lib/quote";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { emojiUnescape } from "discourse/lib/text";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import { getOwner } from "discourse-common/lib/get-owner";
|
||||
|
@ -1162,7 +1163,11 @@ export default Controller.extend({
|
|||
// in test debounce is Ember.run, this will cause
|
||||
// an infinite loop
|
||||
if (!isTesting()) {
|
||||
this._saveDraftDebounce = debounce(this, this._saveDraft, 2000);
|
||||
this._saveDraftDebounce = discourseDebounce(
|
||||
this,
|
||||
this._saveDraft,
|
||||
2000
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this._saveDraftPromise = model.saveDraft().finally(() => {
|
||||
|
@ -1188,7 +1193,7 @@ export default Controller.extend({
|
|||
if (Date.now() - this._lastDraftSaved > 15000) {
|
||||
this._saveDraft();
|
||||
} else {
|
||||
let method = isTesting() ? run : debounce;
|
||||
let method = isTesting() ? run : discourseDebounce;
|
||||
this._saveDraftDebounce = method(this, this._saveDraft, 2000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { action } from "@ember/object";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { gt } from "@ember/object/computed";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
||||
|
@ -19,9 +19,15 @@ export default Controller.extend({
|
|||
showActions: false,
|
||||
|
||||
@observes("filterInput")
|
||||
_setFilter: discourseDebounce(function () {
|
||||
this.set("filter", this.filterInput);
|
||||
}, 500),
|
||||
_setFilter() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
this.set("filter", this.filterInput);
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
@observes("order", "asc", "filter")
|
||||
_filtersChanged() {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseComputed, { observes } from "discourse-common/utils/decorators";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
||||
export default Controller.extend({
|
||||
|
@ -17,9 +17,15 @@ export default Controller.extend({
|
|||
loading: false,
|
||||
|
||||
@observes("filterInput")
|
||||
_setFilter: discourseDebounce(function () {
|
||||
this.set("filter", this.filterInput);
|
||||
}, 500),
|
||||
_setFilter() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
this.set("filter", this.filterInput);
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
@observes("order", "desc", "filter")
|
||||
_filtersChanged() {
|
||||
|
|
|
@ -2,8 +2,8 @@ import Controller, { inject as controller } from "@ember/controller";
|
|||
import I18n from "I18n";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import { action } from "@ember/object";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
|
||||
export default Controller.extend({
|
||||
application: controller(),
|
||||
|
@ -45,7 +45,7 @@ export default Controller.extend({
|
|||
|
||||
@action
|
||||
onFilterChanged(filter) {
|
||||
debounce(this, this._debouncedFilter, filter, INPUT_DELAY);
|
||||
discourseDebounce(this, this._debouncedFilter, filter, INPUT_DELAY);
|
||||
},
|
||||
|
||||
@action
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { cancel, debounce, schedule } from "@ember/runloop";
|
||||
import { cancel, schedule } from "@ember/runloop";
|
||||
import Controller from "@ember/controller";
|
||||
import ModalFunctionality from "discourse/mixins/modal-functionality";
|
||||
import { bind } from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { prefixProtocol } from "discourse/lib/url";
|
||||
import { searchForTerm } from "discourse/lib/search";
|
||||
|
@ -177,7 +178,7 @@ export default Controller.extend(ModalFunctionality, {
|
|||
}
|
||||
},
|
||||
search() {
|
||||
this._debounced = debounce(this, this.triggerSearch, 400);
|
||||
this._debounced = discourseDebounce(this, this.triggerSearch, 400);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -18,7 +18,7 @@ import bootbox from "bootbox";
|
|||
import { bufferedProperty } from "discourse/mixins/buffered-content";
|
||||
import { buildQuote } from "discourse/lib/quote";
|
||||
import { deepMerge } from "discourse-common/lib/object";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { escapeExpression } from "discourse/lib/utilities";
|
||||
import { extractLinkMeta } from "discourse/lib/render-topic-featured-link";
|
||||
import isElementInViewport from "discourse/lib/is-element-in-viewport";
|
||||
|
@ -1500,15 +1500,22 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
);
|
||||
},
|
||||
|
||||
_scrollToPost: discourseDebounce(function (postNumber) {
|
||||
const $post = $(`.topic-post article#post_${postNumber}`);
|
||||
_scrollToPost(postNumber) {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
const $post = $(`.topic-post article#post_${postNumber}`);
|
||||
|
||||
if ($post.length === 0 || isElementInViewport($post)) {
|
||||
return;
|
||||
}
|
||||
if ($post.length === 0 || isElementInViewport($post)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$("html, body").animate({ scrollTop: $post.offset().top }, 1000);
|
||||
}, 500),
|
||||
$("html, body").animate({ scrollTop: $post.offset().top }, 1000);
|
||||
},
|
||||
postNumber,
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
unsubscribe() {
|
||||
// never unsubscribe when navigating from topic to topic
|
||||
|
|
|
@ -5,7 +5,7 @@ import I18n from "I18n";
|
|||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import Invite from "discourse/models/invite";
|
||||
import bootbox from "bootbox";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||
|
||||
export default Controller.extend({
|
||||
|
@ -26,13 +26,19 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
@observes("searchTerm")
|
||||
_searchTermChanged: discourseDebounce(function () {
|
||||
Invite.findInvitedBy(
|
||||
this.user,
|
||||
this.filter,
|
||||
this.searchTerm
|
||||
).then((invites) => this.set("model", invites));
|
||||
}, INPUT_DELAY),
|
||||
_searchTermChanged() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
Invite.findInvitedBy(
|
||||
this.user,
|
||||
this.filter,
|
||||
this.searchTerm
|
||||
).then((invites) => this.set("model", invites));
|
||||
},
|
||||
INPUT_DELAY
|
||||
);
|
||||
},
|
||||
|
||||
inviteRedeemed: equal("filter", "redeemed"),
|
||||
invitePending: equal("filter", "pending"),
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Controller, { inject as controller } from "@ember/controller";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { equal } from "@ember/object/computed";
|
||||
import { longDate } from "discourse/lib/formatter";
|
||||
import { observes } from "discourse-common/utils/decorators";
|
||||
|
@ -37,9 +37,15 @@ export default Controller.extend({
|
|||
},
|
||||
|
||||
@observes("nameInput")
|
||||
_setName: discourseDebounce(function () {
|
||||
this.set("name", this.nameInput);
|
||||
}, 500),
|
||||
_setName() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
this.set("name", this.nameInput);
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
@observes("model.canLoadMore")
|
||||
_showFooter: function () {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { cancel, debounce, later } from "@ember/runloop";
|
||||
import { cancel, later } from "@ember/runloop";
|
||||
import { caretPosition, setCaretPosition } from "discourse/lib/utilities";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import Site from "discourse/models/site";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||
|
||||
/**
|
||||
|
@ -422,7 +423,7 @@ export default function (options) {
|
|||
|
||||
$(this).on("keyup.autocomplete", function (e) {
|
||||
if (options.debounced) {
|
||||
debounce(this, performAutocomplete, e, INPUT_DELAY);
|
||||
discourseDebounce(this, performAutocomplete, e, INPUT_DELAY);
|
||||
} else {
|
||||
performAutocomplete(e);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import Category from "discourse/models/category";
|
|||
import { Promise } from "rsvp";
|
||||
import { SEPARATOR } from "discourse/lib/category-hashtags";
|
||||
import { TAG_HASHTAG_POSTFIX } from "discourse/lib/tag-hashtags";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
|
||||
|
@ -27,38 +27,47 @@ function searchTags(term, categories, limit) {
|
|||
isTesting() ? 50 : 5000
|
||||
);
|
||||
|
||||
const debouncedSearch = discourseDebounce((q, cats, resultFunc) => {
|
||||
oldSearch = $.ajax(getURL("/tags/filter/search"), {
|
||||
type: "GET",
|
||||
cache: true,
|
||||
data: { limit: limit, q },
|
||||
});
|
||||
|
||||
var returnVal = CANCELLED_STATUS;
|
||||
|
||||
oldSearch
|
||||
.then((r) => {
|
||||
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,
|
||||
};
|
||||
const debouncedSearch = (q, cats, resultFunc) => {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
oldSearch = $.ajax(getURL("/tags/filter/search"), {
|
||||
type: "GET",
|
||||
cache: true,
|
||||
data: { limit: limit, q },
|
||||
});
|
||||
|
||||
returnVal = cats.concat(tags);
|
||||
})
|
||||
.always(() => {
|
||||
oldSearch = null;
|
||||
resultFunc(returnVal);
|
||||
});
|
||||
}, 300);
|
||||
var returnVal = CANCELLED_STATUS;
|
||||
|
||||
oldSearch
|
||||
.then((r) => {
|
||||
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;
|
||||
resultFunc(returnVal);
|
||||
});
|
||||
},
|
||||
q,
|
||||
cats,
|
||||
resultFunc,
|
||||
300
|
||||
);
|
||||
};
|
||||
|
||||
debouncedSearch(term, categories, (result) => {
|
||||
cancel(clearPromise);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { ajax } from "discourse/lib/ajax";
|
||||
import { run } from "@ember/runloop";
|
||||
const { debounce } = run;
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
|
||||
let _queue = [];
|
||||
let _processing = 0;
|
||||
|
@ -33,7 +32,7 @@ export default {
|
|||
|
||||
_queue.push({ runnable: () => callback, type, params });
|
||||
|
||||
debounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
discourseDebounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
},
|
||||
|
||||
_processQueue() {
|
||||
|
@ -50,7 +49,7 @@ export default {
|
|||
|
||||
// if queue has still jobs after splice, we request a future processing
|
||||
if (_queue.length > 0) {
|
||||
debounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
discourseDebounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
}
|
||||
|
||||
let reports = {};
|
||||
|
@ -79,7 +78,7 @@ export default {
|
|||
.finally(() => {
|
||||
_processing--;
|
||||
|
||||
debounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
discourseDebounce(this, this._processQueue, DEBOUNCING_DELAY);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
safariHacksDisabled,
|
||||
} from "discourse/lib/utilities";
|
||||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { helperContext } from "discourse-common/lib/helpers";
|
||||
import { later } from "@ember/runloop";
|
||||
|
||||
|
@ -145,7 +145,9 @@ function positioningWorkaround($fixedElement) {
|
|||
positioningWorkaround.blur(evt);
|
||||
};
|
||||
|
||||
var blurred = discourseDebounce(blurredNow, INPUT_DELAY);
|
||||
var blurred = function (evt) {
|
||||
discourseDebounce(this, blurredNow, evt, INPUT_DELAY);
|
||||
};
|
||||
|
||||
var positioningHack = function (evt) {
|
||||
let _this = this;
|
||||
|
@ -214,13 +216,19 @@ function positioningWorkaround($fixedElement) {
|
|||
}
|
||||
}
|
||||
|
||||
const checkForInputs = discourseDebounce(function () {
|
||||
attachTouchStart(fixedElement, lastTouched);
|
||||
const checkForInputs = function () {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
attachTouchStart(fixedElement, lastTouched);
|
||||
|
||||
$fixedElement.find("input[type=text],textarea").each(function () {
|
||||
attachTouchStart(this, positioningHack);
|
||||
});
|
||||
}, 100);
|
||||
$fixedElement.find("input[type=text],textarea").each(function () {
|
||||
attachTouchStart(this, positioningHack);
|
||||
});
|
||||
},
|
||||
100
|
||||
);
|
||||
};
|
||||
|
||||
positioningWorkaround.touchstartEvent = function (element) {
|
||||
var triggerHack = positioningHack.bind(element);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { cancel, later } from "@ember/runloop";
|
||||
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
|
||||
import { Promise } from "rsvp";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { emailValid } from "discourse/lib/utilities";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import { userPath } from "discourse/lib/url";
|
||||
|
@ -81,7 +81,32 @@ function performSearch(
|
|||
});
|
||||
}
|
||||
|
||||
var debouncedSearch = discourseDebounce(performSearch, 300);
|
||||
var debouncedSearch = function (
|
||||
term,
|
||||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
groupMembersOf,
|
||||
resultsFn
|
||||
) {
|
||||
discourseDebounce(
|
||||
this,
|
||||
performSearch,
|
||||
term,
|
||||
topicId,
|
||||
categoryId,
|
||||
includeGroups,
|
||||
includeMentionableGroups,
|
||||
includeMessageableGroups,
|
||||
allowedUsers,
|
||||
groupMembersOf,
|
||||
resultsFn,
|
||||
300
|
||||
);
|
||||
};
|
||||
|
||||
function organizeResults(r, options) {
|
||||
if (r === CANCELLED_STATUS) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { debounce, later } from "@ember/runloop";
|
||||
import Mixin from "@ember/object/mixin";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { later } from "@ember/runloop";
|
||||
|
||||
const helper = {
|
||||
offset() {
|
||||
|
@ -15,7 +16,7 @@ export default Mixin.create({
|
|||
init() {
|
||||
this._super(...arguments);
|
||||
this.queueDockCheck = () => {
|
||||
debounce(this, this.safeDockCheck, 5);
|
||||
discourseDebounce(this, this.safeDockCheck, 5);
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Mixin from "@ember/object/mixin";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
// Small buffer so that very tiny scrolls don't trigger mobile header switch
|
||||
const MOBILE_SCROLL_TOLERANCE = 5;
|
||||
|
||||
|
@ -47,9 +47,13 @@ export default Mixin.create({
|
|||
// If the user reaches the very bottom of the topic, we only want to reset
|
||||
// this scroll direction after a second scrolldown. This is a nicer event
|
||||
// similar to what Safari and Chrome do.
|
||||
debounce(() => {
|
||||
this._bottomHit = 1;
|
||||
}, 1000);
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
this._bottomHit = 1;
|
||||
},
|
||||
1000
|
||||
);
|
||||
|
||||
if (this._bottomHit === 1) {
|
||||
this.set("mobileScrollDirection", null);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Mixin from "@ember/object/mixin";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { scheduleOnce } from "@ember/runloop";
|
||||
import { inject as service } from "@ember/service";
|
||||
|
||||
|
@ -45,7 +45,9 @@ const Scrolling = Mixin.create({
|
|||
};
|
||||
|
||||
if (opts.debounce) {
|
||||
onScrollMethod = discourseDebounce(onScrollMethod, opts.debounce);
|
||||
onScrollMethod = () => {
|
||||
discourseDebounce(this, onScrollMethod, opts.debounce);
|
||||
};
|
||||
}
|
||||
|
||||
ScrollingDOMMethods.bindOnScroll(onScrollMethod, opts.name);
|
||||
|
|
|
@ -3,7 +3,7 @@ import I18n from "I18n";
|
|||
import Mixin from "@ember/object/mixin";
|
||||
import User from "discourse/models/user";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import { setting } from "discourse/lib/computed";
|
||||
|
||||
|
@ -14,20 +14,26 @@ export default Mixin.create({
|
|||
|
||||
minUsernameLength: setting("min_username_length"),
|
||||
|
||||
fetchExistingUsername: discourseDebounce(function () {
|
||||
User.checkUsername(null, this.accountEmail).then((result) => {
|
||||
if (
|
||||
result.suggestion &&
|
||||
(isEmpty(this.accountUsername) ||
|
||||
this.accountUsername === this.get("authOptions.username"))
|
||||
) {
|
||||
this.setProperties({
|
||||
accountUsername: result.suggestion,
|
||||
prefilledUsername: result.suggestion,
|
||||
fetchExistingUsername() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
User.checkUsername(null, this.accountEmail).then((result) => {
|
||||
if (
|
||||
result.suggestion &&
|
||||
(isEmpty(this.accountUsername) ||
|
||||
this.accountUsername === this.get("authOptions.username"))
|
||||
) {
|
||||
this.setProperties({
|
||||
accountUsername: result.suggestion,
|
||||
prefilledUsername: result.suggestion,
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 500),
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("accountUsername")
|
||||
basicUsernameValidation(accountUsername) {
|
||||
|
@ -87,54 +93,61 @@ export default Mixin.create({
|
|||
);
|
||||
},
|
||||
|
||||
checkUsernameAvailability: discourseDebounce(function () {
|
||||
if (this.shouldCheckUsernameAvailability()) {
|
||||
return User.checkUsername(this.accountUsername, this.accountEmail).then(
|
||||
(result) => {
|
||||
this.set("isDeveloper", false);
|
||||
if (result.available) {
|
||||
if (result.is_developer) {
|
||||
this.set("isDeveloper", true);
|
||||
}
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create({
|
||||
ok: true,
|
||||
reason: I18n.t("user.username.available"),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-username"),
|
||||
};
|
||||
|
||||
if (result.suggestion) {
|
||||
checkUsernameAvailability() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
if (this.shouldCheckUsernameAvailability()) {
|
||||
return User.checkUsername(
|
||||
this.accountUsername,
|
||||
this.accountEmail
|
||||
).then((result) => {
|
||||
this.set("isDeveloper", false);
|
||||
if (result.available) {
|
||||
if (result.is_developer) {
|
||||
this.set("isDeveloper", true);
|
||||
}
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.not_available", result),
|
||||
})
|
||||
)
|
||||
EmberObject.create({
|
||||
ok: true,
|
||||
reason: I18n.t("user.username.available"),
|
||||
})
|
||||
);
|
||||
} else {
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: result.errors
|
||||
? result.errors.join(" ")
|
||||
: I18n.t("user.username.not_available_no_suggestion"),
|
||||
})
|
||||
)
|
||||
);
|
||||
const failedAttrs = {
|
||||
failed: true,
|
||||
element: document.querySelector("#new-account-username"),
|
||||
};
|
||||
|
||||
if (result.suggestion) {
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: I18n.t("user.username.not_available", result),
|
||||
})
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return this.set(
|
||||
"uniqueUsernameValidation",
|
||||
EmberObject.create(
|
||||
Object.assign(failedAttrs, {
|
||||
reason: result.errors
|
||||
? result.errors.join(" ")
|
||||
: I18n.t("user.username.not_available_no_suggestion"),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
}, 500),
|
||||
},
|
||||
500
|
||||
);
|
||||
},
|
||||
|
||||
// Actually wait for the async name check before we're 100% sure we're good to go
|
||||
@discourseComputed("uniqueUsernameValidation", "basicUsernameValidation")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Placeholder } from "discourse/lib/posts-with-placeholders";
|
||||
import { addWidgetCleanCallback } from "discourse/components/mount-widget";
|
||||
import { createWidget } from "discourse/widgets/widget";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isTesting } from "discourse-common/config/environment";
|
||||
import transformPost from "discourse/lib/transform-post";
|
||||
|
||||
|
@ -41,7 +41,7 @@ export function cloak(post, component) {
|
|||
_heights[post.id] = $post.outerHeight();
|
||||
|
||||
component.dirtyKeys.keyDirty(`post-${post.id}`);
|
||||
debounce(component, "queueRerender", 1000);
|
||||
discourseDebounce(component, "queueRerender", 1000);
|
||||
}
|
||||
|
||||
export function uncloak(post, component) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { isValidSearchTerm, searchForTerm } from "discourse/lib/search";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import { createWidget } from "discourse/widgets/widget";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { get } from "@ember/object";
|
||||
import getURL from "discourse-common/lib/get-url";
|
||||
import { h } from "virtual-dom";
|
||||
|
@ -284,7 +284,7 @@ export default createWidget("search-menu", {
|
|||
searchData.noResults = false;
|
||||
this.searchService().set("highlightTerm", searchData.term);
|
||||
searchData.loading = true;
|
||||
debounce(SearchHelper, SearchHelper.perform, this, 400);
|
||||
discourseDebounce(SearchHelper, SearchHelper.perform, this, 400);
|
||||
},
|
||||
|
||||
moreOfType(type) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import I18n from "I18n";
|
||||
import { debounce } from "@ember/runloop";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
|
||||
let _cache = {};
|
||||
|
||||
|
@ -184,7 +184,7 @@ export function resolveAllShortUrls(ajax, siteSettings, scope, opts) {
|
|||
shortUploadElements = scope.querySelectorAll(attributes);
|
||||
if (shortUploadElements.length > 0) {
|
||||
// this is carefully batched so we can do a leading debounce (trigger right away)
|
||||
return debounce(
|
||||
return discourseDebounce(
|
||||
null,
|
||||
_loadShortUrls,
|
||||
shortUploadElements,
|
||||
|
|
|
@ -3,14 +3,7 @@ import PluginApiMixin, {
|
|||
applyContentPluginApiCallbacks,
|
||||
applyOnChangePluginApiCallbacks,
|
||||
} from "select-kit/mixins/plugin-api";
|
||||
import {
|
||||
bind,
|
||||
cancel,
|
||||
debounce,
|
||||
next,
|
||||
schedule,
|
||||
throttle,
|
||||
} from "@ember/runloop";
|
||||
import { bind, cancel, next, schedule, throttle } from "@ember/runloop";
|
||||
import { isEmpty, isNone, isPresent } from "@ember/utils";
|
||||
import Component from "@ember/component";
|
||||
import I18n from "I18n";
|
||||
|
@ -19,6 +12,7 @@ import { Promise } from "rsvp";
|
|||
import UtilsMixin from "select-kit/mixins/utils";
|
||||
import { createPopper } from "@popperjs/core";
|
||||
import deprecated from "discourse-common/lib/deprecated";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { guidFor } from "@ember/object/internals";
|
||||
import { makeArray } from "discourse-common/lib/helpers";
|
||||
|
||||
|
@ -386,7 +380,7 @@ export default Component.extend(
|
|||
cancel(this._searchPromise);
|
||||
}
|
||||
|
||||
debounce(this, this._debouncedInput, event.target.value, 200);
|
||||
discourseDebounce(this, this._debouncedInput, event.target.value, 200);
|
||||
},
|
||||
|
||||
_debouncedInput(filter) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import I18n from "I18n";
|
|||
import { INPUT_DELAY } from "discourse-common/config/environment";
|
||||
import { Promise } from "rsvp";
|
||||
import { cookAsync } from "discourse/lib/text";
|
||||
import discourseDebounce from "discourse/lib/debounce";
|
||||
import discourseDebounce from "discourse-common/lib/debounce";
|
||||
import { isEmpty } from "@ember/utils";
|
||||
import loadScript from "discourse/lib/load-script";
|
||||
import { notEmpty } from "@ember/object/computed";
|
||||
|
@ -56,18 +56,24 @@ export default Component.extend({
|
|||
},
|
||||
|
||||
@observes("markup")
|
||||
_renderPreview: discourseDebounce(function () {
|
||||
const markup = this.markup;
|
||||
_renderPreview() {
|
||||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
const markup = this.markup;
|
||||
|
||||
if (markup) {
|
||||
cookAsync(markup).then((result) => {
|
||||
this.set("currentPreview", result);
|
||||
schedule("afterRender", () =>
|
||||
this.$(".preview .discourse-local-date").applyLocalDates()
|
||||
);
|
||||
});
|
||||
}
|
||||
}, INPUT_DELAY),
|
||||
if (markup) {
|
||||
cookAsync(markup).then((result) => {
|
||||
this.set("currentPreview", result);
|
||||
schedule("afterRender", () =>
|
||||
this.$(".preview .discourse-local-date").applyLocalDates()
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
INPUT_DELAY
|
||||
);
|
||||
},
|
||||
|
||||
@computed("date", "toDate", "toTime")
|
||||
isRange(date, toDate, toTime) {
|
||||
|
|
Loading…
Reference in New Issue