From 64846d587dc8803122a30ceabb9922f2e717ee30 Mon Sep 17 00:00:00 2001 From: Jarek Radosz Date: Wed, 23 Aug 2023 15:04:40 +0200 Subject: [PATCH] FIX: Topic timeline/progress switching edge-cases (#23202) `Window`'s `resize` event was unreliable. You could shrink down the browser window so that the timeline would disappear but the progress element would not render to replace it. This commit makes it rely on a media query listener instead so it 1. matches the css 2. fires only when that query result changes (perf win) --- .../app/components/topic-navigation.js | 60 ++++++++----------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/topic-navigation.js b/app/assets/javascripts/discourse/app/components/topic-navigation.js index 6edc1b87c1d..fc05a911db2 100644 --- a/app/assets/javascripts/discourse/app/components/topic-navigation.js +++ b/app/assets/javascripts/discourse/app/components/topic-navigation.js @@ -9,11 +9,11 @@ import discourseDebounce from "discourse-common/lib/debounce"; import { headerOffset } from "discourse/lib/offset-calculator"; import { next } from "@ember/runloop"; import discourseLater from "discourse-common/lib/later"; -import { observes } from "discourse-common/utils/decorators"; +import { bind, observes } from "discourse-common/utils/decorators"; import JumpToPost from "./modal/jump-to-post"; -const MIN_WIDTH_TIMELINE = 924, - MIN_HEIGHT_TIMELINE = 325; +const MIN_WIDTH_TIMELINE = 925; +const MIN_HEIGHT_TIMELINE = 325; export default Component.extend(PanEvents, { modal: service(), @@ -47,35 +47,26 @@ export default Component.extend(PanEvents, { return; } - let info = this.info; - - // Safari's window.innerWidth doesn't match CSS media queries - let windowWidth = this.capabilities.isSafari - ? document.documentElement.clientWidth - : window.innerWidth; - - if (info.get("topicProgressExpanded")) { - info.set("renderTimeline", true); + if (this.info.topicProgressExpanded) { + this.info.set("renderTimeline", true); + } else if (this.site.mobileView) { + this.info.set("renderTimeline", false); } else { - let renderTimeline = !this.site.mobileView; + const composerHeight = + document.querySelector("#reply-control")?.offsetHeight || 0; + const verticalSpace = + window.innerHeight - composerHeight - headerOffset(); - if (renderTimeline) { - const composer = document.getElementById("reply-control"); - - if (composer) { - renderTimeline = - windowWidth > MIN_WIDTH_TIMELINE && - window.innerHeight - composer.offsetHeight - headerOffset() > - MIN_HEIGHT_TIMELINE; - } - } - - info.set("renderTimeline", renderTimeline); + this.info.set( + "renderTimeline", + this.mediaQuery.matches && verticalSpace > MIN_HEIGHT_TIMELINE + ); } }, + @bind _checkSize() { - discourseDebounce(this, this._performCheckSize, 300, true); + discourseDebounce(this, this._performCheckSize, 200, true); }, // we need to store this so topic progress has something to init with @@ -218,16 +209,13 @@ export default Component.extend(PanEvents, { .on("topic:jump-to-post", this, this._collapseFullscreen) .on("topic:keyboard-trigger", this, this.keyboardTrigger); - if (!this.site.mobileView) { - $(window).on("resize.discourse-topic-navigation", () => - this._checkSize() - ); + if (this.site.desktopView) { + this.mediaQuery = matchMedia(`(min-width: ${MIN_WIDTH_TIMELINE}px)`); + this.mediaQuery.addEventListener("change", this._checkSize); this.appEvents.on("composer:opened", this, this.composerOpened); this.appEvents.on("composer:resize-ended", this, this.composerOpened); this.appEvents.on("composer:closed", this, this.composerClosed); - $("#reply-control").on("div-resized.discourse-topic-navigation", () => - this._checkSize() - ); + $("#reply-control").on("div-resized", this._checkSize); } this._checkSize(); @@ -243,12 +231,12 @@ export default Component.extend(PanEvents, { $(window).off("click.hide-fullscreen"); - if (!this.site.mobileView) { - $(window).off("resize.discourse-topic-navigation"); + if (this.site.desktopView) { + this.mediaQuery.removeEventListener("change", this._checkSize); this.appEvents.off("composer:opened", this, this.composerOpened); this.appEvents.off("composer:resize-ended", this, this.composerOpened); this.appEvents.off("composer:closed", this, this.composerClosed); - $("#reply-control").off("div-resized.discourse-topic-navigation"); + $("#reply-control").off("div-resized", this._checkSize); } }, });