diff --git a/app/assets/javascripts/discourse/app/components/topic-timeline.js b/app/assets/javascripts/discourse/app/components/topic-timeline.js index c8702ebcfe4..e10377c30e0 100644 --- a/app/assets/javascripts/discourse/app/components/topic-timeline.js +++ b/app/assets/javascripts/discourse/app/components/topic-timeline.js @@ -3,6 +3,7 @@ import MountWidget from "discourse/components/mount-widget"; import Docking from "discourse/mixins/docking"; import { observes } from "discourse-common/utils/decorators"; import optionalService from "discourse/lib/optional-service"; +import outletHeights from "discourse/lib/header-outlet-height"; const headerPadding = () => { let topPadding = parseInt($("#main-outlet").css("padding-top"), 10) + 3; @@ -67,13 +68,16 @@ export default MountWidget.extend(Docking, { const prev = this.dockAt; const posTop = headerPadding() + info.offset(); - const pos = posTop + timelineHeight; + const pos = posTop + timelineHeight - outletHeights(); this.dockBottom = false; if (posTop < topicTop) { this.dockAt = parseInt(topicTop, 10); } else if (pos > topicBottom + footerHeight) { - this.dockAt = parseInt(topicBottom - timelineHeight + footerHeight, 10); + this.dockAt = parseInt( + topicBottom - timelineHeight + footerHeight + outletHeights(), + 10 + ); this.dockBottom = true; if (this.dockAt < 0) { this.dockAt = 0; diff --git a/app/assets/javascripts/discourse/app/lib/header-outlet-height.js b/app/assets/javascripts/discourse/app/lib/header-outlet-height.js new file mode 100644 index 00000000000..049d7b16da7 --- /dev/null +++ b/app/assets/javascripts/discourse/app/lib/header-outlet-height.js @@ -0,0 +1,22 @@ +export default function() { + const outletSelector = [ + ".above-site-header-outlet", + ".below-site-header-outlet" + ]; + // If these outlets have height they impact timeline and usercard positioning + + let outletHeights = 0; + + outletSelector.forEach(function(outletClass) { + if (document.querySelector(outletClass)) { + let outlets = document.querySelectorAll(outletClass); + outlets.forEach(outlet => { + if (outlet.offsetHeight) { + outletHeights += parseInt(outlet.offsetHeight, 10); + } + }); + } + }); + + return outletHeights; +} 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 cccf26db7e3..d72fb5b4573 100644 --- a/app/assets/javascripts/discourse/app/mixins/card-contents-base.js +++ b/app/assets/javascripts/discourse/app/mixins/card-contents-base.js @@ -5,6 +5,7 @@ import afterTransition from "discourse/lib/after-transition"; import DiscourseURL from "discourse/lib/url"; import Mixin from "@ember/object/mixin"; import { escapeExpression } from "discourse/lib/utilities"; +import outletHeights from "discourse/lib/header-outlet-height"; import { inject as service } from "@ember/service"; export default Mixin.create({ @@ -211,7 +212,7 @@ export default Mixin.create({ } } - position.top -= $("#main-outlet").offset().top; + position.top -= $("#main-outlet").offset().top - outletHeights(); if (isFixed) { position.top -= $("html").scrollTop(); //if content is fixed and will be cut off on the bottom, display it above...