From c291dd491da8967d0bbc12eef93311174fdc634f Mon Sep 17 00:00:00 2001 From: Pavel Mineev Date: Sun, 12 Apr 2020 21:47:09 +0300 Subject: [PATCH] update preact --- .../app/components/root/in-view/in-view.tsx | 83 ++++++------------- frontend/app/components/thread/thread.tsx | 2 +- frontend/package-lock.json | 6 +- frontend/package.json | 2 +- 4 files changed, 32 insertions(+), 61 deletions(-) diff --git a/frontend/app/components/root/in-view/in-view.tsx b/frontend/app/components/root/in-view/in-view.tsx index ac4af11e..5faec57b 100644 --- a/frontend/app/components/root/in-view/in-view.tsx +++ b/frontend/app/components/root/in-view/in-view.tsx @@ -1,31 +1,25 @@ -import { Component, JSX } from 'preact'; -import { sleep } from '@app/utils/sleep'; +/** @jsx createElement */ +import { JSX } from 'preact'; +import { useState, useEffect, useRef, PropRef } from 'preact/hooks'; interface Props { - children: (props: { inView: boolean; ref: (ref: Component) => unknown }) => JSX.Element; + children: (props: { inView: boolean; ref: PropRef }) => JSX.Element; } -interface State { - inView: boolean; - ref: Element | undefined; -} - -let instanceMap: WeakMap>; +let instanceMap: WeakMap void>; let observer: IntersectionObserver; -function getObserver(): { observer: IntersectionObserver; instanceMap: WeakMap> } { +function getObserver(): { observer: IntersectionObserver; instanceMap: WeakMap void> } { if (observer && instanceMap) { return { observer, instanceMap }; } - instanceMap = new WeakMap>(); + instanceMap = new WeakMap void>(); observer = new window.IntersectionObserver( entries => { entries.forEach(e => { - const instance = instanceMap.get(e.target); - if (!instance) return; - instance.setState({ - inView: e.isIntersecting, - }); + const setInView = instanceMap.get(e.target); + if (!setInView) return; + setInView(e.isIntersecting); }); }, { @@ -35,47 +29,24 @@ function getObserver(): { observer: IntersectionObserver; instanceMap: WeakMap { - state: State = { - inView: false, - ref: undefined, - }; +export function InView({ children }: Props) { + const [inView, setInView] = useState(false); + const ref = useRef(); // eslint-disable-line - componentWillUpdate(_nextProps: Props, nextState: State) { - if (this.state.ref === nextState.ref) return; - - if (this.state.ref instanceof Element) { - const { observer, instanceMap } = getObserver(); - observer.unobserve(this.state.ref); - instanceMap.delete(this.state.ref); - } - - if (nextState.ref instanceof Element) { - const { observer, instanceMap } = getObserver(); - observer.observe(nextState.ref); - instanceMap.set(nextState.ref, this); - } - } - - refSetter = async (ref: Component | null) => { - await sleep(1); - const el = ref ? ref.base : undefined; - if (el === this.state.ref) return; - this.setState({ - ref: ref ? (ref.base as Element) : undefined, - }); - }; - - componentWillUnmount() { - if (!(this.state.ref instanceof Element)) return; + useEffect(() => { const { observer, instanceMap } = getObserver(); - observer.unobserve(this.state.ref); - instanceMap.delete(this.state.ref); - } + if (ref.current) { + observer.observe(ref.current.base); + instanceMap.set(ref.current.base, setInView); + } - render() { - const props = { inView: this.state.inView, ref: this.refSetter }; - const r = this.props.children(props); - return r; - } + return () => { + if (ref.current) { + observer.unobserve(ref.current.base); + instanceMap.delete(ref.current.base); + } + }; + }); + + return children({ inView, ref }); } diff --git a/frontend/app/components/thread/thread.tsx b/frontend/app/components/thread/thread.tsx index 16bab18e..d4a36ddd 100644 --- a/frontend/app/components/thread/thread.tsx +++ b/frontend/app/components/thread/thread.tsx @@ -56,7 +56,7 @@ export const Thread: FunctionComponent = ({ id, level, mix, getPreview }) {inviewProps => ( inviewProps.ref(ref)} + ref={inviewProps.ref} key={`comment-${id}`} view="main" intl={intl} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4ec6cc2c..e6db45d4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18244,9 +18244,9 @@ } }, "preact": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.0.1.tgz", - "integrity": "sha512-lq7jo1rwwCd1YkiBcuOxRc3I0y1FZACa6O7tgNXt47QZJtSlLEE53f/FDNsLtiB2IVQTHbaey20TjSPmejhDyQ==" + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.4.0.tgz", + "integrity": "sha512-34iqY2qPWKAmsi+tNNwYCstta93P+zF1f4DLtsOUPh32uYImNzJY7h7EymCva+6RoJL01v3W3phSRD8jE0sFLg==" }, "preact-render-to-string": { "version": "4.1.0", diff --git a/frontend/package.json b/frontend/package.json index 35142ff8..e25f814e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -115,7 +115,7 @@ "intersection-observer": "^0.7.0", "lodash-es": "^4.17.15", "node-emoji": "^1.10.0", - "preact": "^10.0.1", + "preact": "^10.4.0", "react-intl": "^3.12.0", "react-redux": "^7.1.1", "redux": "^4.0.5",