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; if (this.props.target.current.scrollTop == 0) { this.props.onScrollTop(); } } handleScroll() { this.stickToBottom = this.isAtBottom(); if (this.props.target.current.scrollTop == 0) { this.props.onScrollTop(); } } 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; } }