DEV: Introduce `discourseLater` (#17532)

A wrapper for `later()` from `@ember/runloop`, similar to `discourseDebounce`. It automatically reduces the delay in testing environment.
This commit is contained in:
Jarek Radosz 2022-07-17 00:50:49 +02:00 committed by GitHub
parent 5707431981
commit 5538b8442e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
45 changed files with 151 additions and 118 deletions

View File

@ -3,7 +3,8 @@ import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
import { emojiUrlFor } from "discourse/lib/text";
import { action, set, setProperties } from "@ember/object";
import { later, schedule } from "@ember/runloop";
import { schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export default Component.extend({
classNameBindings: [":value-list", ":emoji-list"],
@ -104,7 +105,7 @@ export default Component.extend({
}
this.set("isEditorFocused", true);
later(() => {
discourseLater(() => {
if (this.element && !this.isDestroying && !this.isDestroyed) {
this.set("emojiPickerIsActive", true);
}

View File

@ -6,7 +6,7 @@ import { ajax } from "discourse/lib/ajax";
import bootbox from "bootbox";
import copyText from "discourse/lib/copy-text";
import discourseComputed from "discourse-common/utils/decorators";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export default Component.extend({
classNames: ["ip-lookup"],
@ -83,7 +83,7 @@ export default Component.extend({
$(document.body).append($copyRange);
if (copyText(text, $copyRange[0])) {
this.set("copied", true);
later(() => this.set("copied", false), 2000);
discourseLater(() => this.set("copied", false), 2000);
}
$copyRange.remove();
},

View File

@ -1,7 +1,7 @@
import Controller from "@ember/controller";
import I18n from "I18n";
import bootbox from "bootbox";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { action, computed } from "@ember/object";
import { clipboardCopy } from "discourse/lib/utilities";
@ -41,7 +41,7 @@ export default class AdminCustomizeColorsShowController extends Controller {
);
}
later(() => {
discourseLater(() => {
this.set("model.savingStatus", null);
}, 2000);
}

View File

@ -0,0 +1,14 @@
import { later } from "@ember/runloop";
import { isTesting } from "discourse-common/config/environment";
export default function () {
if (isTesting() && typeof [...arguments].at(-1) === "number") {
// Replace the `wait` argument with 10ms
let args = [].slice.call(arguments, 0, -1);
args.push(10);
return later.apply(undefined, args);
} else {
return later(...arguments);
}
}

View File

@ -16,7 +16,7 @@ import discourseComputed, { bind } from "discourse-common/utils/decorators";
import { formattedReminderTime } from "discourse/lib/bookmark";
import { and, notEmpty } from "@ember/object/computed";
import { popupAjaxError } from "discourse/lib/ajax-error";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
const BOOKMARK_BINDINGS = {
enter: { handler: "saveAndClose" },
@ -75,7 +75,7 @@ export default Component.extend({
didInsertElement() {
this._super(...arguments);
later(() => {
discourseLater(() => {
if (this.site.isMobileDevice) {
document.getElementById("bookmark-name").blur();
}

View File

@ -1,4 +1,5 @@
import { cancel, later, schedule, throttle } from "@ember/runloop";
import { cancel, schedule, throttle } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import discourseComputed, {
bind,
observes,
@ -10,7 +11,6 @@ import afterTransition from "discourse/lib/after-transition";
import discourseDebounce from "discourse-common/lib/debounce";
import { headerOffset } from "discourse/lib/offset-calculator";
import positioningWorkaround from "discourse/lib/safari-hacks";
import { isTesting } from "discourse-common/config/environment";
const START_DRAG_EVENTS = ["touchstart", "mousedown"];
const DRAG_EVENTS = ["touchmove", "mousemove"];
@ -63,15 +63,12 @@ export default Component.extend(KeyEnterEscape, {
// One second from now, check to see if the last key was hit when
// we recorded it. If it was, the user paused typing.
cancel(this._lastKeyTimeout);
this._lastKeyTimeout = later(
() => {
if (lastKeyUp !== this._lastKeyUp) {
return;
}
this.appEvents.trigger("composer:find-similar");
},
isTesting() ? 50 : 1000
);
this._lastKeyTimeout = discourseLater(() => {
if (lastKeyUp !== this._lastKeyUp) {
return;
}
this.appEvents.trigger("composer:find-similar");
}, 1000);
},
@observes("composeState")

View File

@ -22,7 +22,8 @@ import {
fetchUnseenMentions,
linkSeenMentions,
} from "discourse/lib/link-mentions";
import { later, next, schedule, throttle } from "@ember/runloop";
import { next, schedule, throttle } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Component from "@ember/component";
import Composer from "discourse/models/composer";
import ComposerUploadUppy from "discourse/mixins/composer-upload-uppy";
@ -519,7 +520,7 @@ export default Component.extend(ComposerUploadUppy, {
if (found.indexOf(name) === -1) {
// add a delay to allow for typing, so you don't open the warning right away
// previously we would warn after @bob even if you were about to mention @bob2
later(
discourseLater(
this,
() => {
if (
@ -545,7 +546,7 @@ export default Component.extend(ComposerUploadUppy, {
return;
}
later(
discourseLater(
this,
() => {
this.hereMention(hereCount);
@ -699,7 +700,7 @@ export default Component.extend(ComposerUploadUppy, {
this.appEvents.trigger("composer:will-close");
next(() => {
// need to wait a bit for the "slide down" transition of the composer
later(
discourseLater(
() => this.appEvents.trigger("composer:closed"),
isTesting() ? 0 : 400
);

View File

@ -1,5 +1,6 @@
import { isBlank } from "@ember/utils";
import { later, schedule, scheduleOnce, throttle } from "@ember/runloop";
import { schedule, scheduleOnce, throttle } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import AddArchetypeClass from "discourse/mixins/add-archetype-class";
import ClickTrack from "discourse/lib/click-track";
import Component from "@ember/component";
@ -76,7 +77,7 @@ export default Component.extend(
this.pauseHeaderTopicUpdate = true;
this._lastShowTopic = true;
later(() => {
discourseLater(() => {
this._lastShowTopic = false;
this.pauseHeaderTopicUpdate = false;
}, debounceDuration);

View File

@ -1,4 +1,4 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import Category from "discourse/models/category";
import { action } from "@ember/object";
import { buildCategoryPanel } from "discourse/components/edit-category-panel";
@ -7,6 +7,7 @@ import discourseComputed from "discourse-common/utils/decorators";
import getURL from "discourse-common/lib/get-url";
import { isEmpty } from "@ember/utils";
import { not } from "@ember/object/computed";
import discourseLater from "discourse-common/lib/later";
export default buildCategoryPanel("general", {
init() {
@ -122,7 +123,7 @@ export default buildCategoryPanel("general", {
},
_focusCategoryName() {
this._laterFocus = later(() => {
this._laterFocus = discourseLater(() => {
const categoryName = this.element.querySelector(".category-name");
categoryName && categoryName.focus();
}, 25);

View File

@ -10,7 +10,8 @@ import {
} from "pretty-text/emoji";
import { emojiUnescape, emojiUrlFor } from "discourse/lib/text";
import { escapeExpression } from "discourse/lib/utilities";
import { later, schedule } from "@ember/runloop";
import { schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Component from "@ember/component";
import { createPopper } from "@popperjs/core";
import { htmlSafe } from "@ember/template";
@ -140,7 +141,7 @@ export default Component.extend({
// this is a low-tech trick to prevent appending hundreds of emojis
// of blocking the rendering of the picker
later(() => {
discourseLater(() => {
schedule("afterRender", () => {
if (!this.site.isMobileDevice || this.isEditorFocused) {
const filter = emojiPicker.querySelector("input.filter");

View File

@ -5,7 +5,7 @@ import { alias } from "@ember/object/computed";
import discourseComputed from "discourse-common/utils/decorators";
import { escapeExpression } from "discourse/lib/utilities";
import { isEmpty } from "@ember/utils";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export default Component.extend({
tagName: null,
@ -48,7 +48,7 @@ export default Component.extend({
didInsertElement() {
this._super(...arguments);
later(() => {
discourseLater(() => {
if (this.element) {
const textArea = this.element.querySelector(".topic-share-url");
textArea.style.height = textArea.scrollHeight + "px";

View File

@ -1,5 +1,5 @@
import Component from "@ember/component";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { on } from "@ember/object/evented";
export default Component.extend({
@ -13,7 +13,7 @@ export default Component.extend({
hideForSession() {
this.session.set("hideSignupCta", true);
this.keyValueStore.setItem("anon-cta-hidden", Date.now());
later(() => this.session.set("showSignupCta", false), 20 * 1000);
discourseLater(() => this.session.set("showSignupCta", false), 20 * 1000);
},
},

View File

@ -2,7 +2,8 @@ import PanEvents, {
SWIPE_DISTANCE_THRESHOLD,
SWIPE_VELOCITY_THRESHOLD,
} from "discourse/mixins/pan-events";
import { cancel, later, schedule } from "@ember/runloop";
import { cancel, schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Docking from "discourse/mixins/docking";
import MountWidget from "discourse/components/mount-widget";
import ItsATrap from "@discourse/itsatrap";
@ -42,7 +43,7 @@ const SiteHeaderComponent = MountWidget.extend(
const headerCloak = document.querySelector(".header-cloak");
panel.classList.add("animate");
headerCloak.classList.add("animate");
this._scheduledRemoveAnimate = later(() => {
this._scheduledRemoveAnimate = discourseLater(() => {
panel.classList.remove("animate");
headerCloak.classList.remove("animate");
}, 200);
@ -60,7 +61,7 @@ const SiteHeaderComponent = MountWidget.extend(
const offsetDirection = menuOrigin === "left" ? -1 : 1;
panel.style.setProperty("--offset", `${offsetDirection * windowWidth}px`);
headerCloak.style.setProperty("--opacity", 0);
this._scheduledRemoveAnimate = later(() => {
this._scheduledRemoveAnimate = discourseLater(() => {
panel.classList.remove("animate");
headerCloak.classList.remove("animate");
schedule("afterRender", () => {

View File

@ -1,5 +1,6 @@
import getURL from "discourse-common/lib/get-url";
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import { action } from "@ember/object";
@ -34,7 +35,7 @@ export default Component.extend({
} else {
// Since we can do this transparently for people browsing the forum
// hold back the message 24 hours.
this._timeoutHandler = later(() => {
this._timeoutHandler = discourseLater(() => {
this.updatePromptState(true);
}, 1000 * 60 * 24 * 60);
}
@ -52,7 +53,7 @@ export default Component.extend({
if (isTesting()) {
this.set(secondProp, value);
} else {
later(() => {
discourseLater(() => {
this.set(secondProp, value);
}, 500);
}

View File

@ -1,6 +1,6 @@
import { action } from "@ember/object";
import showModal from "discourse/lib/show-modal";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import isElementInViewport from "discourse/lib/is-element-in-viewport";
import discourseComputed, { on } from "discourse-common/utils/decorators";
import I18n from "I18n";
@ -73,7 +73,7 @@ export default Component.extend({
// viewport, or if too many topics fill the page
@on("didInsertElement")
_determineOtherDismissVisibility() {
later(() => {
discourseLater(() => {
if (this.position === "top") {
this.set(
"isOtherDismissUnreadButtonVisible",

View File

@ -6,7 +6,8 @@ import Component from "@ember/component";
import EmberObject from "@ember/object";
import discourseDebounce from "discourse-common/lib/debounce";
import { headerOffset } from "discourse/lib/offset-calculator";
import { later, next } from "@ember/runloop";
import { next } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { observes } from "discourse-common/utils/decorators";
import showModal from "discourse/lib/show-modal";
@ -116,7 +117,7 @@ export default Component.extend(PanEvents, {
_collapseFullscreen() {
if (this.get("info.topicProgressExpanded")) {
$(".timeline-fullscreen").removeClass("show");
later(() => {
discourseLater(() => {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
@ -147,13 +148,13 @@ export default Component.extend(PanEvents, {
$timelineContainer.addClass("animate");
if (this._shouldPanClose(event)) {
$timelineContainer.css("--offset", `${maxOffset}px`);
later(() => {
discourseLater(() => {
this._collapseFullscreen();
$timelineContainer.removeClass("animate");
}, 200);
} else {
$timelineContainer.css("--offset", 0);
later(() => {
discourseLater(() => {
$timelineContainer.removeClass("animate");
}, 200);
}

View File

@ -1,7 +1,8 @@
import discourseComputed, { bind } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import { alias } from "@ember/object/computed";
import { later, scheduleOnce } from "@ember/runloop";
import { scheduleOnce } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { action } from "@ember/object";
import { isTesting } from "discourse-common/config/environment";
@ -77,7 +78,7 @@ export default Component.extend({
// start CSS transitions a tiny bit later
// to avoid jumpiness on initial topic load
later(this._addCssTransitions, CSS_TRANSITION_DELAY);
discourseLater(this._addCssTransitions, CSS_TRANSITION_DELAY);
},
willDestroyElement() {

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Category from "discourse/models/category";
import Component from "@ember/component";
import { DELETE_REPLIES_TYPE } from "discourse/controllers/edit-topic-timer";
@ -112,7 +113,7 @@ export default Component.extend({
// TODO Sam: concerned this can cause a heavy rerender loop
if (!isTesting()) {
this._delayedRerender = later(() => {
this._delayedRerender = discourseLater(() => {
this.renderTopicTimer();
}, this.rerenderDelay(minutesLeft));
}

View File

@ -3,7 +3,7 @@ import I18n from "I18n";
import ModalFunctionality from "discourse/mixins/modal-functionality";
import { SECOND_FACTOR_METHODS } from "discourse/models/user";
import { alias } from "@ember/object/computed";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export default Controller.extend(ModalFunctionality, {
loading: false,
@ -95,7 +95,7 @@ export default Controller.extend(ModalFunctionality, {
},
_hideCopyMessage() {
later(
discourseLater(
() => this.setProperties({ successMessage: null, errorMessage: null }),
2000
);

View File

@ -4,7 +4,8 @@ import DiscourseURL, { userPath } from "discourse/lib/url";
import { alias, and, not, or } from "@ember/object/computed";
import discourseComputed, { observes } from "discourse-common/utils/decorators";
import { isEmpty, isPresent } from "@ember/utils";
import { later, next, schedule } from "@ember/runloop";
import { next, schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Bookmark, { AUTO_DELETE_PREFERENCES } from "discourse/models/bookmark";
import Composer from "discourse/models/composer";
import EmberObject, { action } from "@ember/object";
@ -1545,7 +1546,7 @@ export default Controller.extend(bufferedProperty("model"), {
}
if (this._retryInProgress) {
later(() => {
discourseLater(() => {
this.retryOnRateLimit(times, promise, topicId);
}, 100);
return;
@ -1570,7 +1571,7 @@ export default Controller.extend(bufferedProperty("model"), {
this._retryRateLimited = true;
later(() => {
discourseLater(() => {
this._retryRateLimited = false;
this.retryOnRateLimit(times - 1, promise, topicId);
}, waitSeconds * 1000);

View File

@ -1,6 +1,6 @@
import DiscourseURL from "discourse/lib/url";
import { isDevelopment } from "discourse-common/config/environment";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
// Use the message bus for live reloading of components for faster development.
export default {
@ -73,6 +73,6 @@ export default {
const reloaded = node.cloneNode(true);
reloaded.href = newHref;
node.insertAdjacentElement("afterend", reloaded);
later(() => node?.parentNode?.removeChild(node), 500);
discourseLater(() => node?.parentNode?.removeChild(node), 500);
},
};

View File

@ -1,4 +1,5 @@
import { later, schedule } from "@ember/runloop";
import { schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import I18n from "I18n";
import highlightSyntax from "discourse/lib/highlight-syntax";
import lightbox from "discourse/lib/lightbox";
@ -116,7 +117,7 @@ export default {
.forEach((videoContainer) => {
const video = videoContainer.getElementsByTagName("video")[0];
video.addEventListener("loadeddata", () => {
later(() => {
discourseLater(() => {
if (video.videoWidth === 0 || video.videoHeight === 0) {
const notice = document.createElement("div");
notice.className = "notice";

View File

@ -1,5 +1,5 @@
import { postRNWebviewMessage } from "discourse/lib/utilities";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
// Send bg color to webview so iOS status bar matches site theme
export default {
@ -16,7 +16,7 @@ export default {
}
},
updateAppBackground() {
later(() => {
discourseLater(() => {
const header = document.querySelector(".d-header-wrap .d-header");
if (header) {
const styles = window.getComputedStyle(header);

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { caretPosition, setCaretPosition } from "discourse/lib/utilities";
import { INPUT_DELAY } from "discourse-common/config/environment";
import Site from "discourse/models/site";
@ -113,7 +114,7 @@ export default function (options) {
let inputSelectedItems = [];
function handlePaste() {
later(() => me.trigger("keydown"), 50);
discourseLater(() => me.trigger("keydown"), 50);
}
function closeAutocomplete() {
@ -531,7 +532,7 @@ export default function (options) {
// saves us wiring up a change event as well
cancel(inputTimeout);
inputTimeout = later(function () {
inputTimeout = discourseLater(function () {
if (inputSelectedItems.length === 0) {
inputSelectedItems.push("");
}

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
import Category from "discourse/models/category";
import { Promise } from "rsvp";
@ -22,7 +23,7 @@ function searchTags(term, categories, limit) {
return new Promise((resolve) => {
let clearPromise = isTesting()
? null
: later(() => {
: discourseLater(() => {
resolve(CANCELLED_STATUS);
}, 5000);

View File

@ -6,7 +6,7 @@ import { ajax } from "discourse/lib/ajax";
import bootbox from "bootbox";
import getURL, { samePrefix } from "discourse-common/lib/get-url";
import { isTesting } from "discourse-common/config/environment";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { selectedText } from "discourse/lib/utilities";
import { wantsNewWindow } from "discourse/lib/intercept-click";
@ -59,7 +59,7 @@ export function openLinkInNewTab(link) {
link.dataset.autoRoute = true;
link.removeAttribute("href");
later(() => {
discourseLater(() => {
if (link) {
link.classList.remove("no-href");
link.setAttribute("href", link.dataset.href);

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Mobile from "discourse/lib/mobile";
import { bind } from "discourse-common/utils/decorators";
import showModal from "discourse/lib/show-modal";
@ -188,7 +189,7 @@ export default class CodeblockButtons {
delete this._fadeCopyCodeblocksRunners[commandId];
}
this._fadeCopyCodeblocksRunners[commandId] = later(() => {
this._fadeCopyCodeblocksRunners[commandId] = discourseLater(() => {
button.classList.remove("action-complete");
button.innerHTML = state;
delete this._fadeCopyCodeblocksRunners[commandId];

View File

@ -2,7 +2,7 @@ import cookie, { removeCookie } from "discourse/lib/cookie";
import I18n from "I18n";
import Session from "discourse/models/session";
import { ajax } from "discourse/lib/ajax";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export function listColorSchemes(site, options = {}) {
let schemes = site.get("user_color_schemes");
@ -73,7 +73,7 @@ export function loadColorSchemeStylesheet(
document.body.appendChild(link);
}
if (!darkMode) {
later(() => {
discourseLater(() => {
const schemeType = getComputedStyle(document.body).getPropertyValue(
"--scheme-type"
);

View File

@ -5,7 +5,7 @@ import { Promise } from "rsvp";
import Site from "discourse/models/site";
import User from "discourse/models/user";
import { formatUsername } from "discourse/lib/utilities";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
let primaryTab = false;
let liveEnabled = false;
@ -94,7 +94,7 @@ function confirmNotification(siteSettings) {
const clickEventHandler = () => notification.close();
notification.addEventListener("click", clickEventHandler);
later(() => {
discourseLater(() => {
notification.close();
notification.removeEventListener("click", clickEventHandler);
}, 10 * 1000);

View File

@ -1,6 +1,7 @@
import { bind } from "discourse-common/utils/decorators";
import discourseDebounce from "discourse-common/lib/debounce";
import { later, run, throttle } from "@ember/runloop";
import { run, throttle } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import {
nextTopicUrl,
previousTopicUrl,
@ -308,7 +309,7 @@ export default {
this.sendToSelectedPost("replyToPost");
// lazy but should work for now
later(() => $(".d-editor .quote").click(), 500);
discourseLater(() => $(".d-editor .quote").click(), 500);
return false;
},

View File

@ -1,7 +1,7 @@
import { INPUT_DELAY } from "discourse-common/config/environment";
import discourseDebounce from "discourse-common/lib/debounce";
import { helperContext } from "discourse-common/lib/helpers";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
let workaroundActive = false;
@ -93,7 +93,7 @@ function positioningWorkaround(fixedElement) {
let delay = caps.isIpadOS ? 350 : 150;
later(() => {
discourseLater(() => {
if (caps.isIpadOS) {
// disable hacks when using a hardware keyboard
// by default, a hardware keyboard will show the keyboard accessory bar

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { CANCELLED_STATUS } from "discourse/lib/autocomplete";
import { Promise } from "rsvp";
import discourseDebounce from "discourse-common/lib/debounce";
@ -253,7 +254,7 @@ export default function userSearch(options) {
let clearPromise;
if (!isTesting()) {
clearPromise = later(() => resolve(CANCELLED_STATUS), 5000);
clearPromise = discourseLater(() => resolve(CANCELLED_STATUS), 5000);
}
if (skipSearch(term, options.allowEmails, options.lastSeenUsers)) {

View File

@ -1,6 +1,7 @@
import Mixin from "@ember/object/mixin";
import discourseDebounce from "discourse-common/lib/debounce";
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { isTesting } from "discourse-common/config/environment";
const INITIAL_DELAY_MS = isTesting() ? 0 : 50;
@ -38,7 +39,11 @@ export default Mixin.create({
});
// dockCheck might happen too early on full page refresh
this._initialTimer = later(this, this.safeDockCheck, INITIAL_DELAY_MS);
this._initialTimer = discourseLater(
this,
this.safeDockCheck,
INITIAL_DELAY_MS
);
},
willDestroyElement() {

View File

@ -1,4 +1,5 @@
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Mixin from "@ember/object/mixin";
import { isTesting } from "discourse-common/config/environment";
@ -10,7 +11,7 @@ export default Mixin.create({
this.queueRerender();
} else {
cancel(this._listenToDoNotDisturbLoop);
this._listenToDoNotDisturbLoop = later(
this._listenToDoNotDisturbLoop = discourseLater(
this,
() => {
this.listenForDoNotDisturbChanges();

View File

@ -32,7 +32,8 @@ import { url } from "discourse/lib/computed";
import { userPath } from "discourse/lib/url";
import { htmlSafe } from "@ember/template";
import Evented from "@ember/object/evented";
import { cancel, later } from "@ember/runloop";
import { cancel } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { isTesting } from "discourse-common/config/environment";
export const SECOND_FACTOR_METHODS = {
@ -1220,7 +1221,11 @@ User.reopen(Evented, {
const utcNow = moment.utc();
const remaining = moment.utc(endsAt).diff(utcNow, "milliseconds");
this._clearStatusTimerId = later(this, "_autoClearStatus", remaining);
this._clearStatusTimerId = discourseLater(
this,
"_autoClearStatus",
remaining
);
},
_unscheduleStatusClearing() {

View File

@ -1,4 +1,5 @@
import { cancel, later, schedule } from "@ember/runloop";
import { cancel, schedule } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import DiscourseRoute from "discourse/routes/discourse";
import DiscourseURL from "discourse/lib/url";
import { ID_CONSTRAINT } from "discourse/models/topic";
@ -7,9 +8,8 @@ import { isEmpty } from "@ember/utils";
import { inject as service } from "@ember/service";
import { setTopicId } from "discourse/lib/topic-list-tracker";
import showModal from "discourse/lib/show-modal";
import { isTesting } from "discourse-common/config/environment";
const SCROLL_DELAY = isTesting() ? 0 : 500;
const SCROLL_DELAY = 500;
const TopicRoute = DiscourseRoute.extend({
screenTrack: service(),
@ -231,7 +231,7 @@ const TopicRoute = DiscourseRoute.extend({
this.setProperties({
lastScrollPos: parseInt($(document).scrollTop(), 10),
scheduledReplace: later(
scheduledReplace: discourseLater(
this,
"_replaceUnlessScrolling",
postUrl,
@ -270,7 +270,7 @@ const TopicRoute = DiscourseRoute.extend({
this.setProperties({
lastScrollPos: currentPos,
scheduledReplace: later(
scheduledReplace: discourseLater(
this,
"_replaceUnlessScrolling",
url,

View File

@ -1,15 +1,8 @@
import Service from "@ember/service";
import EmberObject, { computed } from "@ember/object";
import { ajax } from "discourse/lib/ajax";
import {
cancel,
debounce,
later,
next,
once,
run,
throttle,
} from "@ember/runloop";
import { cancel, debounce, next, once, run, throttle } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import Session from "discourse/models/session";
import { Promise } from "rsvp";
import User from "discourse/models/user";
@ -324,7 +317,7 @@ export default class PresenceService extends Service {
try {
result = await this._initialDataAjax;
} catch (e) {
later(this, this._makeInitialDataRequest, PRESENCE_GET_RETRY_MS);
discourseLater(this, this._makeInitialDataRequest, PRESENCE_GET_RETRY_MS);
throw e;
} finally {
this._initialDataAjax = null;
@ -595,7 +588,7 @@ export default class PresenceService extends Service {
this._presentChannels.length > 0 &&
!isTesting()
) {
this._nextUpdateTimer = later(
this._nextUpdateTimer = discourseLater(
this,
this._throttledUpdateServer,
PRESENCE_INTERVAL_S * 1000

View File

@ -5,7 +5,7 @@ import { NotificationLevels } from "discourse/lib/notification-levels";
import { ajax } from "discourse/lib/ajax";
import getURL from "discourse-common/lib/get-url";
import { h } from "virtual-dom";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { wantsNewWindow } from "discourse/lib/intercept-click";
const flatten = (array) => [].concat.apply([], array);
@ -385,7 +385,7 @@ export default createWidget("hamburger-menu", {
const headerCloak = document.querySelector(".header-cloak");
headerCloak.classList.add("animate");
headerCloak.style.setProperty("--opacity", 0);
later(() => this.sendWidgetAction("toggleHamburger"), 200);
discourseLater(() => this.sendWidgetAction("toggleHamburger"), 200);
}
},

View File

@ -1,5 +1,6 @@
import { applyDecorators, createWidget } from "discourse/widgets/widget";
import { later, next } from "@ember/runloop";
import { next } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { Promise } from "rsvp";
import { formattedReminderTime } from "discourse/lib/bookmark";
import { h } from "virtual-dom";
@ -737,7 +738,7 @@ export default createWidget("post-menu", {
heart.classList.add("heart-animation");
return new Promise((resolve) => {
later(() => {
discourseLater(() => {
this.sendWidgetAction("toggleLike").then(() => resolve());
}, 400);
});

View File

@ -5,7 +5,7 @@ import { createWidget } from "discourse/widgets/widget";
import { actionDescriptionHtml } from "discourse/widgets/post-small-action";
import { h } from "virtual-dom";
import { iconNode } from "discourse-common/lib/icon-library";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { relativeAge } from "discourse/lib/formatter";
import renderTags from "discourse/lib/render-tags";
import renderTopicFeaturedLink from "discourse/lib/render-topic-featured-link";
@ -444,7 +444,7 @@ export default createWidget("topic-timeline", {
const stream = this.attrs.topic.get("postStream");
// a little debounce to avoid flashing
later(() => {
discourseLater(() => {
if (!this.state.position === scrollPosition) {
return;
}

View File

@ -1,4 +1,4 @@
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import { createWidget } from "discourse/widgets/widget";
import { h } from "virtual-dom";
import showModal from "discourse/lib/show-modal";
@ -295,7 +295,7 @@ export default createWidget("user-menu", {
const headerCloak = document.querySelector(".header-cloak");
headerCloak.classList.add("animate");
headerCloak.style.setProperty("--opacity", 0);
later(() => this.sendWidgetAction("toggleUserMenu"), 200);
discourseLater(() => this.sendWidgetAction("toggleUserMenu"), 200);
}
},

View File

@ -7,7 +7,7 @@ import {
publishToMessageBus,
} from "discourse/tests/helpers/qunit-helpers";
import { hbs } from "ember-cli-htmlbars";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
module("Integration | Component | software-update-prompt", function (hooks) {
setupRenderingTest(hooks);
@ -23,7 +23,7 @@ module("Integration | Component | software-update-prompt", function (hooks) {
publishToMessageBus("/global/asset-version", "somenewversion");
const done = assert.async();
later(() => {
discourseLater(() => {
assert.strictEqual(
count("div.software-update-prompt.require-software-refresh"),
1,

View File

@ -3,7 +3,7 @@ import { module, skip, test } from "qunit";
import ClickTrack from "discourse/lib/click-track";
import DiscourseURL from "discourse/lib/url";
import User from "discourse/models/user";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
import pretender from "discourse/tests/helpers/create-pretender";
import sinon from "sinon";
import { setPrefix } from "discourse-common/lib/get-url";
@ -203,7 +203,7 @@ module("Unit | Utility | click-track", function (hooks) {
assert.timeout(75);
const done = assert.async();
later(() => {
discourseLater(() => {
assert.strictEqual(
fixture("a").getAttribute("href"),
"http://www.google.com"

View File

@ -8,7 +8,7 @@ import {
setFailedCache,
setLocalCache,
} from "pretty-text/oneboxer-cache";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
let timeout;
const loadingQueue = [];
@ -92,7 +92,7 @@ function loadNext(ajax) {
}
)
.finally(() => {
timeout = later(() => loadNext(ajax), timeoutMs);
timeout = discourseLater(() => loadNext(ajax), timeoutMs);
if (removeLoading) {
elem.classList.remove(LOADING_ONEBOX_CSS_CLASS);
elem.dataset.oneboxLoaded = "";
@ -152,6 +152,6 @@ export function load({
if (synchronous) {
return loadNext(ajax);
} else {
timeout = timeout || later(() => loadNext(ajax), 150);
timeout = timeout || discourseLater(() => loadNext(ajax), 150);
}
}

View File

@ -1,6 +1,6 @@
import Component from "@ember/component";
import { afterRender } from "discourse-common/utils/decorators";
import { later } from "@ember/runloop";
import discourseLater from "discourse-common/lib/later";
export default Component.extend({
tagName: "section",
@ -20,7 +20,7 @@ export default Component.extend({
this.set("iconIds", ids.sort());
} else {
// Let's try again a short time later if there are no svgs loaded yet
later(this, this.setIconIds, 1500);
discourseLater(this, this.setIconIds, 1500);
}
},
});