FIX: Use CSS transition to make room for composer (#16750)
The composer is displayed over the bottom part of the page. To make sure that no content is covered by the composer, a bottom padding is added equal to the height of the composer. When the composer is opened or closed that padding is added after around 300ms because of a debounce. This commit makes sure that the padding is added as soon as the composer state changes by using a CSS custom property (variable) and transition property for a smooth user interface.
This commit is contained in:
parent
6e53f4d913
commit
9ea8a4a9af
|
@ -1,4 +1,4 @@
|
||||||
import { cancel, later, run, schedule, throttle } from "@ember/runloop";
|
import { cancel, later, schedule, throttle } from "@ember/runloop";
|
||||||
import discourseComputed, {
|
import discourseComputed, {
|
||||||
bind,
|
bind,
|
||||||
observes,
|
observes,
|
||||||
|
@ -53,34 +53,6 @@ export default Component.extend(KeyEnterEscape, {
|
||||||
return composeState || Composer.CLOSED;
|
return composeState || Composer.CLOSED;
|
||||||
},
|
},
|
||||||
|
|
||||||
movePanels(size) {
|
|
||||||
document.querySelector("#main-outlet").style.paddingBottom = size
|
|
||||||
? `${size}px`
|
|
||||||
: "";
|
|
||||||
|
|
||||||
// signal the progress bar it should move!
|
|
||||||
this.appEvents.trigger("composer:resized");
|
|
||||||
},
|
|
||||||
|
|
||||||
@observes("composeState", "composer.{action,canEditTopicFeaturedLink}")
|
|
||||||
resize() {
|
|
||||||
schedule("afterRender", () => {
|
|
||||||
if (!this.element || this.isDestroying || this.isDestroyed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
discourseDebounce(this, this.debounceMove, 300);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
debounceMove() {
|
|
||||||
let height = 0;
|
|
||||||
if (!this.element.classList.contains("saving")) {
|
|
||||||
height = this.element.offsetHeight;
|
|
||||||
}
|
|
||||||
this.movePanels(height);
|
|
||||||
},
|
|
||||||
|
|
||||||
keyUp() {
|
keyUp() {
|
||||||
this.typed();
|
this.typed();
|
||||||
|
|
||||||
|
@ -128,11 +100,31 @@ export default Component.extend(KeyEnterEscape, {
|
||||||
this.appEvents.trigger("composer:div-resizing");
|
this.appEvents.trigger("composer:div-resizing");
|
||||||
this.element.classList.add("clear-transitions");
|
this.element.classList.add("clear-transitions");
|
||||||
const currentMousePos = mouseYPos(event);
|
const currentMousePos = mouseYPos(event);
|
||||||
let size = this.origComposerSize + (this.lastMousePos - currentMousePos);
|
|
||||||
|
|
||||||
|
let size = this.origComposerSize + (this.lastMousePos - currentMousePos);
|
||||||
size = Math.min(size, window.innerHeight - headerOffset());
|
size = Math.min(size, window.innerHeight - headerOffset());
|
||||||
this.movePanels(size);
|
const minHeight = parseInt(getComputedStyle(this.element).minHeight, 10);
|
||||||
this.element.style.height = size ? `${size}px` : "";
|
size = Math.max(minHeight, size);
|
||||||
|
|
||||||
|
["--reply-composer-height", "--new-topic-composer-height"].forEach((prop) =>
|
||||||
|
document.documentElement.style.setProperty(prop, size ? `${size}px` : "")
|
||||||
|
);
|
||||||
|
|
||||||
|
this._triggerComposerResized();
|
||||||
|
},
|
||||||
|
|
||||||
|
@observes("composeState", "composer.{action,canEditTopicFeaturedLink}")
|
||||||
|
_triggerComposerResized() {
|
||||||
|
schedule("afterRender", () => {
|
||||||
|
if (!this.element || this.isDestroying || this.isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
discourseDebounce(this, this.composerResized, 300);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
composerResized() {
|
||||||
|
this.appEvents.trigger("composer:resized");
|
||||||
},
|
},
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
|
@ -213,7 +205,6 @@ export default Component.extend(KeyEnterEscape, {
|
||||||
|
|
||||||
this.setupComposerResizeEvents();
|
this.setupComposerResizeEvents();
|
||||||
|
|
||||||
const resize = () => run(() => this.resize());
|
|
||||||
const triggerOpen = () => {
|
const triggerOpen = () => {
|
||||||
if (this.get("composer.composeState") === Composer.OPEN) {
|
if (this.get("composer.composeState") === Composer.OPEN) {
|
||||||
this.appEvents.trigger("composer:opened");
|
this.appEvents.trigger("composer:opened");
|
||||||
|
@ -222,7 +213,6 @@ export default Component.extend(KeyEnterEscape, {
|
||||||
triggerOpen();
|
triggerOpen();
|
||||||
|
|
||||||
afterTransition($(this.element), () => {
|
afterTransition($(this.element), () => {
|
||||||
resize();
|
|
||||||
triggerOpen();
|
triggerOpen();
|
||||||
});
|
});
|
||||||
positioningWorkaround($(this.element));
|
positioningWorkaround($(this.element));
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
:root {
|
||||||
|
--reply-composer-height: 300px;
|
||||||
|
--new-topic-composer-height: 400px;
|
||||||
|
}
|
||||||
|
html.composer-open {
|
||||||
|
#main-outlet {
|
||||||
|
padding-bottom: var(--reply-composer-height);
|
||||||
|
transition: padding-bottom 250ms ease;
|
||||||
|
}
|
||||||
|
}
|
||||||
#reply-control {
|
#reply-control {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -43,9 +53,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
&.open {
|
&.open {
|
||||||
height: 300px;
|
height: var(--reply-composer-height);
|
||||||
&.edit-title {
|
&.edit-title {
|
||||||
height: 400px; // more room when editing the title
|
// more room when editing the title
|
||||||
|
height: var(--new-topic-composer-height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue