DEV: Small refactor to header offset (#15421)

Centralizes calculations in a helper under the site header component.

This also reverts a small CSS change to the composer: since ac79c5ef,
the composer height was not including the grippie, which means that the
composer height was off by 11 pixels, and the topic progress widget was
sometimes being displayed cut off by 11 pixels.
This commit is contained in:
Penar Musaraj 2021-12-29 11:03:21 -05:00 committed by GitHub
parent 108c8302fb
commit 879e35195a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 40 deletions

View File

@ -8,7 +8,7 @@ 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 { headerOffset } from "discourse/components/site-header";
import positioningWorkaround from "discourse/lib/safari-hacks";
const START_DRAG_EVENTS = ["touchstart", "mousedown"];
@ -130,7 +130,7 @@ export default Component.extend(KeyEnterEscape, {
const currentMousePos = mouseYPos(event);
let size = this.origComposerSize + (this.lastMousePos - currentMousePos);
size = Math.min(size, window.innerHeight - headerHeight());
size = Math.min(size, window.innerHeight - headerOffset());
this.movePanels(size);
this.element.style.height = size ? `${size}px` : "";
},

View File

@ -183,13 +183,13 @@ const SiteHeaderComponent = MountWidget.extend(
}
const headerRect = header.getBoundingClientRect();
let headerOffset = headerRect.top + headerRect.height;
let headerOffsetCalc = headerRect.top + headerRect.height;
if (window.scrollY < 0) {
headerOffset += window.scrollY;
headerOffsetCalc += window.scrollY;
}
const newValue = `${headerOffset}px`;
const newValue = `${headerOffsetCalc}px`;
if (newValue !== this.currentHeaderOffsetValue) {
this.currentHeaderOffsetValue = newValue;
document.documentElement.style.setProperty("--header-offset", newValue);
@ -389,7 +389,7 @@ const SiteHeaderComponent = MountWidget.extend(
headerCloak.style.display = "block";
}
const menuTop = this.site.mobileView ? headerTop() : headerHeight();
const menuTop = this.site.mobileView ? headerTop() : headerOffset();
const winHeightOffset = 16;
let initialWinHeight = window.innerHeight;
@ -438,16 +438,13 @@ export default SiteHeaderComponent.extend({
classNames: ["d-header-wrap"],
});
export function headerHeight() {
const header = document.querySelector("header.d-header");
// Header may not exist in tests (e.g. in the user menu component test).
if (!header) {
return 0;
}
const headerOffsetTop = header.offsetTop ? header.offsetTop : 0;
return header.offsetHeight + headerOffsetTop - document.body.scrollTop;
export function headerOffset() {
return (
parseInt(
document.documentElement.style.getPropertyValue("--header-offset"),
10
) || 0
);
}
export function headerTop() {

View File

@ -1,5 +1,6 @@
import Docking from "discourse/mixins/docking";
import MountWidget from "discourse/components/mount-widget";
import { headerOffset } from "discourse/components/site-header";
import { next } from "@ember/runloop";
import { observes } from "discourse-common/utils/decorators";
import optionalService from "discourse/lib/optional-service";
@ -50,7 +51,7 @@ export default MountWidget.extend(Docking, {
const timelineHeight = (timeline && timeline.offsetHeight) || 400;
const prev = this.dockAt;
const posTop = this.headerOffset() + window.pageYOffset;
const posTop = headerOffset() + window.pageYOffset;
const pos = posTop + timelineHeight;
this.dockBottom = false;
@ -72,12 +73,6 @@ export default MountWidget.extend(Docking, {
}
},
headerOffset() {
return (
parseInt(document.body.style.getPropertyValue("--header-offset"), 10) || 0
);
},
didInsertElement() {
this._super(...arguments);

View File

@ -1,6 +1,7 @@
import { addWidgetCleanCallback } from "discourse/components/mount-widget";
import Site from "discourse/models/site";
import { bind } from "discourse-common/utils/decorators";
import { headerOffset } from "discourse/components/site-header";
import { schedule } from "@ember/runloop";
export default class StickyAvatars {
@ -78,11 +79,6 @@ export default class StickyAvatars {
@bind
_initIntersectionObserver() {
schedule("afterRender", () => {
const headerOffset =
parseInt(document.body.style.getPropertyValue("--header-offset"), 10) ||
0;
const headerHeight = Math.max(headerOffset, 0);
this.intersectionObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
@ -95,13 +91,16 @@ export default class StickyAvatars {
?.clientHeight;
if (
this.direction === "⬆️" ||
postContentHeight > window.innerHeight - headerHeight
postContentHeight > window.innerHeight - headerOffset()
) {
entry.target.classList.add(this.stickyClass);
}
});
},
{ threshold: [0.0, 1.0], rootMargin: `-${headerHeight}px 0px 0px 0px` }
{
threshold: [0.0, 1.0],
rootMargin: `-${headerOffset()}px 0px 0px 0px`,
}
);
});
}

View File

@ -3,7 +3,7 @@
margin: 0 auto;
padding: 8px;
box-sizing: border-box;
height: 100%;
height: calc(100% - 11px);
width: 100%;
.submit-panel {
@ -60,7 +60,6 @@
cursor: row-resize;
padding: 4px 0;
background: var(--tertiary);
margin-top: -11px;
&:before {
content: "";

View File

@ -1,5 +1,6 @@
import { ajax } from "discourse/lib/ajax";
import discourseDebounce from "discourse-common/lib/debounce";
import { headerOffset } from "discourse/components/site-header";
import isElementInViewport from "discourse/lib/is-element-in-viewport";
import { withPluginApi } from "discourse/lib/plugin-api";
@ -85,17 +86,10 @@ function initialize(api) {
return;
}
const headerOffset =
parseInt(
getComputedStyle(document.body).getPropertyValue(
"--header-offset"
),
10
) || 0;
const viewportOffset = post.getBoundingClientRect();
window.scrollTo({
top: window.scrollY + viewportOffset.top - headerOffset,
top: window.scrollY + viewportOffset.top - headerOffset(),
behavior: "smooth",
});
},