DEV: Improve header offset calculation (#24910)

This commit is contained in:
Penar Musaraj
2023-12-15 09:29:17 -05:00
committed by GitHub
parent 437c2c5552
commit 8a4ab79be2
3 changed files with 21 additions and 16 deletions

View File

@ -448,27 +448,37 @@ export default SiteHeaderComponent.extend({
@bind @bind
updateHeaderOffset() { updateHeaderOffset() {
let headerWrapTop = this.headerWrap.getBoundingClientRect().top; // Safari likes overscolling the page (on both iOS and macOS).
// This shows up as a negative value in window.scrollY.
// We can use this to offset the headerWrap's top offset to avoid
// jitteriness and bad positioning.
const windowOverscroll = Math.min(0, window.scrollY);
if (headerWrapTop !== 0) { // The headerWrap's top offset can also be a negative value on Safari,
headerWrapTop -= Math.max(0, document.body.getBoundingClientRect().top); // because of the changing height of the viewport (due to the URL bar).
} // For our use case, it's best to ensure this is clamped to 0.
const headerWrapTop = Math.max(
0,
Math.floor(this.headerWrap.getBoundingClientRect().top)
);
let offsetTop = headerWrapTop + windowOverscroll;
if (DEBUG && isTesting()) { if (DEBUG && isTesting()) {
headerWrapTop -= document offsetTop -= document
.getElementById("ember-testing-container") .getElementById("ember-testing-container")
.getBoundingClientRect().top; .getBoundingClientRect().top;
headerWrapTop -= 1; // For 1px border on testing container offsetTop -= 1; // For 1px border on testing container
} }
const documentStyle = document.documentElement.style; const documentStyle = document.documentElement.style;
const currentValue = documentStyle.getPropertyValue("--header-offset"); const currentValue =
const newValue = `${this.headerWrap.offsetHeight + headerWrapTop}px`; parseInt(documentStyle.getPropertyValue("--header-offset"), 10) || 0;
const newValue = this.headerWrap.offsetHeight + offsetTop;
if (currentValue !== newValue) { if (currentValue !== newValue) {
documentStyle.setProperty("--header-offset", newValue); documentStyle.setProperty("--header-offset", `${newValue}px`);
} }
}, },

View File

@ -1,18 +1,12 @@
import Component from "@glimmer/component"; import Component from "@glimmer/component";
import { action } from "@ember/object"; import { action } from "@ember/object";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import { htmlSafe } from "@ember/template";
import DButton from "discourse/components/d-button"; import DButton from "discourse/components/d-button";
import { headerOffset } from "discourse/lib/offset-calculator";
import DiscourseURL from "discourse/lib/url"; import DiscourseURL from "discourse/lib/url";
export default class ChatNavbar extends Component { export default class ChatNavbar extends Component {
@service chatStateManager; @service chatStateManager;
get topStyle() {
return htmlSafe(`top: ${headerOffset()}px`);
}
@action @action
async closeFullScreen() { async closeFullScreen() {
this.chatStateManager.prefersDrawer(); this.chatStateManager.prefersDrawer();
@ -26,7 +20,7 @@ export default class ChatNavbar extends Component {
} }
<template> <template>
<div class="chat-navbar-container" style={{this.topStyle}}> <div class="chat-navbar-container">
<nav class="chat-navbar"> <nav class="chat-navbar">
{{#if (has-block "current")}} {{#if (has-block "current")}}
<span class="chat-navbar__current"> <span class="chat-navbar__current">

View File

@ -9,6 +9,7 @@
position: sticky; position: sticky;
border-bottom: 1px solid var(--primary-low); border-bottom: 1px solid var(--primary-low);
background: var(--secondary); background: var(--secondary);
top: var(--header-offset);
height: 50px; height: 50px;
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;