Preserve scroll position when adding/removing staged quote

This commit is contained in:
Scott Nonnenberg 2019-01-14 19:20:45 -08:00
parent cba47668cd
commit 7db7a3ad44
4 changed files with 59 additions and 24 deletions

View file

@ -1542,6 +1542,7 @@
this.quoteView = null;
}
if (!this.quotedMessage) {
this.view.restoreBottomOffset();
this.updateMessageFieldSize({});
return;
}
@ -1565,16 +1566,18 @@
this.quoteView = new Whisper.ReactWrapperView({
className: 'quote-wrapper',
Component: window.Signal.Components.Quote,
elCallback: el => this.$('.send').prepend(el),
props: Object.assign({}, props, {
withContentAbove: true,
onClose: () => {
this.setQuoteMessage(null);
},
}),
onInitialRender: () => {
this.view.restoreBottomOffset();
this.updateMessageFieldSize({});
},
});
this.$('.send').prepend(this.quoteView.el);
this.updateMessageFieldSize({});
},
async sendMessage(e) {

View file

@ -70,6 +70,15 @@
resetScrollPosition() {
this.$el.scrollTop(this.scrollPosition - this.$el.outerHeight());
},
restoreBottomOffset() {
if (_.isNumber(this.bottomOffset)) {
// + 10 is necessary to account for padding
const height = this.$el.height() + 10;
const topOfBottomScreen = this.el.scrollHeight - height;
this.$el.scrollTop(topOfBottomScreen - this.bottomOffset);
}
},
scrollToBottomIfNeeded() {
// This is counter-intuitive. Our current bottomOffset is reflective of what
// we last measured, not necessarily the current state. And this is called

View file

@ -12,20 +12,43 @@
window.Whisper.ReactWrapperView = Backbone.View.extend({
className: 'react-wrapper',
initialize(options) {
const { Component, props, onClose } = options;
const {
Component,
props,
onClose,
tagName,
className,
onInitialRender,
elCallback,
} = options;
this.render();
if (elCallback) {
elCallback(this.el);
}
this.tagName = options.tagName;
this.className = options.className;
this.tagName = tagName;
this.className = className;
this.Component = Component;
this.onClose = onClose;
this.onInitialRender = onInitialRender;
this.update(props);
this.hasRendered = false;
},
update(props) {
const updatedProps = this.augmentProps(props);
const reactElement = React.createElement(this.Component, updatedProps);
ReactDOM.render(reactElement, this.el);
ReactDOM.render(reactElement, this.el, () => {
if (this.hasRendered) {
return;
}
this.hasRendered = true;
if (this.onInitialRender) {
this.onInitialRender();
}
});
},
augmentProps(props) {
return Object.assign({}, props, {