forked from CringeStudios/gamja
Save and restore buffer scroll position
This commit is contained in:
parent
96f33019f8
commit
544303923c
@ -4,6 +4,7 @@ import Buffer from "/components/buffer.js";
|
|||||||
import BufferList from "/components/buffer-list.js";
|
import BufferList from "/components/buffer-list.js";
|
||||||
import Connect from "/components/connect.js";
|
import Connect from "/components/connect.js";
|
||||||
import Composer from "/components/composer.js";
|
import Composer from "/components/composer.js";
|
||||||
|
import ScrollManager from "/components/scroll-manager.js";
|
||||||
import { html, Component, createRef } from "/lib/index.js";
|
import { html, Component, createRef } from "/lib/index.js";
|
||||||
import { SERVER_BUFFER, Status, Unread } from "/state.js";
|
import { SERVER_BUFFER, Status, Unread } from "/state.js";
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ export default class App extends Component {
|
|||||||
buffers: new Map(),
|
buffers: new Map(),
|
||||||
activeBuffer: null,
|
activeBuffer: null,
|
||||||
};
|
};
|
||||||
|
buffer = createRef();
|
||||||
composer = createRef();
|
composer = createRef();
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -414,9 +416,11 @@ export default class App extends Component {
|
|||||||
<section id="sidebar">
|
<section id="sidebar">
|
||||||
<${BufferList} buffers=${this.state.buffers} activeBuffer=${this.state.activeBuffer} onBufferClick=${this.handleBufferListClick}/>
|
<${BufferList} buffers=${this.state.buffers} activeBuffer=${this.state.activeBuffer} onBufferClick=${this.handleBufferListClick}/>
|
||||||
</section>
|
</section>
|
||||||
<section id="buffer">
|
<${ScrollManager} target=${this.buffer} scrollKey=${this.state.activeBuffer}>
|
||||||
|
<section id="buffer" ref=${this.buffer}>
|
||||||
<${Buffer} buffer=${activeBuffer}/>
|
<${Buffer} buffer=${activeBuffer}/>
|
||||||
</section>
|
</section>
|
||||||
|
</>
|
||||||
<${Composer} ref=${this.composer} readOnly=${this.state.activeBuffer == SERVER_BUFFER} onSubmit=${this.handleComposerSubmit}/>
|
<${Composer} ref=${this.composer} readOnly=${this.state.activeBuffer == SERVER_BUFFER} onSubmit=${this.handleComposerSubmit}/>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
76
components/scroll-manager.js
Normal file
76
components/scroll-manager.js
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
import { html, Component } from "/lib/index.js";
|
||||||
|
|
||||||
|
var store = new Map();
|
||||||
|
|
||||||
|
export default class ScrollManager extends Component {
|
||||||
|
stickToBottom = false;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.handleScroll = this.handleScroll.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
isAtBottom() {
|
||||||
|
var target = this.props.target.current;
|
||||||
|
return target.scrollTop >= target.scrollHeight - target.offsetHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll(pos) {
|
||||||
|
var target = this.props.target.current;
|
||||||
|
if (pos.bottom) {
|
||||||
|
pos.y = target.scrollHeight - target.offsetHeight;
|
||||||
|
}
|
||||||
|
target.scrollTop = pos.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveScrollPosition() {
|
||||||
|
var target = this.props.target.current;
|
||||||
|
store.set(this.props.scrollKey, {
|
||||||
|
y: target.scrollTop,
|
||||||
|
bottom: this.isAtBottom(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
restoreScrollPosition() {
|
||||||
|
var target = this.props.target.current;
|
||||||
|
var pos = store.get(this.props.scrollKey);
|
||||||
|
if (!pos) {
|
||||||
|
pos = { bottom: true };
|
||||||
|
}
|
||||||
|
this.scroll(pos);
|
||||||
|
this.stickToBottom = pos.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleScroll() {
|
||||||
|
this.stickToBottom = this.isAtBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.restoreScrollPosition();
|
||||||
|
this.props.target.current.addEventListener("scroll", this.handleScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
if (this.props.scrollKey !== nextProps.scrollKey) {
|
||||||
|
this.saveScrollPosition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (this.props.scrollKey !== prevProps.scrollKey) {
|
||||||
|
this.restoreScrollPosition();
|
||||||
|
} else if (this.stickToBottom) {
|
||||||
|
this.scroll({ bottom: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.props.target.current.removeEventListener("scroll", this.handleScroll);
|
||||||
|
this.saveScrollPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user