diff --git a/app/assets/javascripts/discourse/app/components/d-button.gjs b/app/assets/javascripts/discourse/app/components/d-button.gjs index d0b0147010a..3c541f2b617 100644 --- a/app/assets/javascripts/discourse/app/components/d-button.gjs +++ b/app/assets/javascripts/discourse/app/components/d-button.gjs @@ -6,6 +6,7 @@ import { htmlSafe } from "@ember/template"; import { or } from "truth-helpers"; import GlimmerComponentWithDeprecatedParentView from "discourse/components/glimmer-component-with-deprecated-parent-view"; import concatClass from "discourse/helpers/concat-class"; +import runAfterFramePaint from "discourse/lib/after-frame-paint"; import icon from "discourse-common/helpers/d-icon"; import deprecated from "discourse-common/lib/deprecated"; import I18n from "discourse-i18n"; @@ -118,17 +119,17 @@ export default class DButton extends GlimmerComponentWithDeprecatedParentView { ); } } else if (typeof actionVal === "object" && actionVal.value) { - if (forwardEvent) { - actionVal.value(actionParam, event); - } else { - actionVal.value(actionParam); - } + runAfterFramePaint(() => + forwardEvent + ? actionVal.value(actionParam, event) + : actionVal.value(actionParam) + ); } else if (typeof actionVal === "function") { - if (forwardEvent) { - actionVal(actionParam, event); - } else { - actionVal(actionParam); - } + runAfterFramePaint(() => + forwardEvent + ? actionVal(actionParam, event) + : actionVal(actionParam) + ); } } else if (route) { this.router.transitionTo(route); diff --git a/app/assets/javascripts/discourse/app/lib/after-frame-paint.js b/app/assets/javascripts/discourse/app/lib/after-frame-paint.js index aa1cdb4eba2..d5d4b5e5cd3 100644 --- a/app/assets/javascripts/discourse/app/lib/after-frame-paint.js +++ b/app/assets/javascripts/discourse/app/lib/after-frame-paint.js @@ -1,4 +1,4 @@ -import DEBUG from "@glimmer/env"; +import { DEBUG } from "@glimmer/env"; import { registerWaiter } from "@ember/test"; import { isTesting } from "discourse-common/config/environment"; diff --git a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js index 652605151a3..f2bcce3cd8c 100644 --- a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js +++ b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js @@ -2,6 +2,7 @@ import { alias, match } from "@ember/object/computed"; import Mixin from "@ember/object/mixin"; import { schedule, throttle } from "@ember/runloop"; import { service } from "@ember/service"; +import runAfterFramePaint from "discourse/lib/after-frame-paint"; import { wantsNewWindow } from "discourse/lib/intercept-click"; import { headerOffset } from "discourse/lib/offset-calculator"; import DiscourseURL from "discourse/lib/url"; @@ -86,9 +87,11 @@ export default Mixin.create({ document.querySelector(".card-cloak")?.classList.remove("hidden"); this.appEvents.trigger("user-card:show", { username }); - this._positionCard(target, event); - this._showCallback(username).then((user) => { - this.appEvents.trigger("user-card:after-show", { user }); + runAfterFramePaint(() => { + this._positionCard(target, event); + this._showCallback(username).then((user) => { + this.appEvents.trigger("user-card:after-show", { user }); + }); }); // We bind scrolling on mobile after cards are shown to hide them if user scrolls diff --git a/spec/system/homepage_spec.rb b/spec/system/homepage_spec.rb index 29546fdda78..6ff5acc6ef9 100644 --- a/spec/system/homepage_spec.rb +++ b/spec/system/homepage_spec.rb @@ -34,6 +34,10 @@ describe "Homepage", type: :system do # Wait for the save to complete find(".btn-primary.save-changes:not([disabled])", wait: 5) + try_until_success do + visit "/u/#{user.username}/preferences/interface" + homepage_picker.has_selected_name?("Top") + end visit "/" @@ -89,9 +93,12 @@ describe "Homepage", type: :system do homepage_picker.select_row_by_name("Top") page.find(".btn-primary.save-changes").click - # Wait for the save to complete + # Make sure save is complete find(".btn-primary.save-changes:not([disabled])", wait: 5) - expect(user.user_option.homepage_id).to eq(UserOption::HOMEPAGES.key("top")) + try_until_success do + visit "/u/#{user.username}/preferences/interface" + homepage_picker.has_selected_name?("Top") + end find("#site-logo").click expect(page).to have_css(".navigation-container .top.active", text: "Top") @@ -107,7 +114,10 @@ describe "Homepage", type: :system do # Wait for the save to complete find(".btn-primary.save-changes:not([disabled])", wait: 5) - expect(user.reload.user_option.homepage_id).to_not eq(UserOption::HOMEPAGES.key("top")) + try_until_success do + visit "/u/#{user.username}/preferences/interface" + homepage_picker.has_selected_name?("(default)") + end find("#site-logo").click