Skip to content

Commit

Permalink
Make virtual children
Browse files Browse the repository at this point in the history
  • Loading branch information
pomber committed Feb 24, 2019
1 parent 7bd2a0f commit 032859f
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 18 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"netlify-auth-providers": "^1.0.0-alpha5",
"prismjs": "^1.15.0",
"react": "^16.8.1",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^16.8.1",
"react-scripts": "2.1.3",
"react-swipeable": "^4.3.2",
Expand Down
6 changes: 5 additions & 1 deletion src/history.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,11 @@ function Slides({ commits, slideLines, loadMore }) {
currentIndex={current}
selectCommit={index => setClampedTarget(index)}
/>
<Swipeable onSwipedLeft={nextSlide} onSwipedRight={prevSlide}>
<Swipeable
onSwipedLeft={nextSlide}
onSwipedRight={prevSlide}
style={{ height: "100%" }}
>
<Slide time={index - current} lines={slideLines[index]} />
</Swipeable>
</React.Fragment>
Expand Down
103 changes: 87 additions & 16 deletions src/slide.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from "react";
import animation from "./animation";
import theme from "./nightOwl";
import useChildren from "./useVirtualChildren";
import { Scrollbars } from "react-custom-scrollbars";

const themeStylesByType = Object.create(null);
theme.styles.forEach(({ types, style }) => {
Expand All @@ -27,32 +29,101 @@ function Line({ line, style }) {
);
}

export default function Slide({ time, lines }) {
const styles = animation((time + 1) / 2, lines);
function getLineHeight(line, i, { styles }) {
return styles[i].height != null ? styles[i].height : 15;
}

function getLine(line, i, { styles }) {
return <Line line={line} style={styles[i]} key={line.key} />;
}

function Lines({ height, top, lines, styles }) {
const children = useChildren({
height,
top,
items: lines,
getRow: getLine,
getRowHeight: getLineHeight,
data: { styles }
});
return children;
}

function useHeight(ref) {
let [height, setHeight] = React.useState(null);

function handleResize() {
setHeight(ref.current.offsetHeight);
}

React.useEffect(() => {
handleResize();
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, [ref.current]);

return height;
}

function Slide({ lines, styles }) {
const [top, setTop] = React.useState(0);

let ref = React.useRef(null);
let height = useHeight(ref);
return (
<pre
<div
style={{
backgroundColor: theme.plain.backgroundColor,
color: theme.plain.color,
width: "100%",
overflow: "hidden",
paddingTop: "100px",
margin: 0
margin: 0,
height: "100%",
boxSizing: "border-box"
}}
>
<code
<pre
style={{
display: "block",
width: "calc(100% - 20px)",
maxWidth: "900px",
margin: "auto",
padding: "10px"
width: "100%",
overflowY: "auto",
overflowX: "hidden",
margin: 0,
height: "100%"
}}
>
{lines.map((line, i) => (
<Line line={line} style={styles[i]} key={line.key} />
))}
</code>
</pre>
<Scrollbars
autoHide
onScroll={e => setTop(e.target.scrollTop)}
renderThumbVertical={({ style, ...props }) => (
<div
style={{ ...style, backgroundColor: "rgb(173, 219, 103, 0.3)" }}
{...props}
/>
)}
>
<code
style={{
display: "block",
width: "calc(100% - 20px)",
maxWidth: "900px",
margin: "auto",
padding: "10px",
height: "100%",
boxSizing: "border-box"
}}
ref={ref}
>
<Lines height={height} top={top} lines={lines} styles={styles} />
</code>
</Scrollbars>
</pre>
</div>
);
}

export default function SlideWrapper({ time, lines }) {
const styles = animation((time + 1) / 2, lines);
return <Slide styles={styles} lines={lines} />;
}
2 changes: 2 additions & 0 deletions src/todo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- move diffing to web worker
- make diffing incremental
43 changes: 43 additions & 0 deletions src/useVirtualChildren.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from "react";

export default function useChildren({
items,
getRow,
getRowHeight,
height,
top,
data
}) {
const children = [];

const extraRender = 200;

const topT = top - extraRender;
const bottomT = top + height + extraRender;
let h = 0;

let topPlaceHolderH = 0;
let bottomPlaceholderH = 0;

// This is the bottleneck
items.forEach((item, i) => {
const itemH = getRowHeight(item, i, data);
const nextH = h + itemH;
const isOverTop = nextH < topT;
const isUnderBottom = h > bottomT;

if (isOverTop) {
topPlaceHolderH += itemH;
} else if (isUnderBottom) {
bottomPlaceholderH += itemH;
} else {
children.push(getRow(item, i, data));
}

h = nextH;
});

children.unshift(<div style={{ height: topPlaceHolderH }} key="top-ph" />);
children.push(<div style={{ height: bottomPlaceholderH }} key="bottom-ph" />);
return children;
}
70 changes: 69 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,11 @@ acorn@^6.0.1, acorn@^6.0.2, acorn@^6.0.4:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.5.tgz#81730c0815f3f3b34d8efa95cb7430965f4d887a"
integrity sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==

add-px-to-style@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/add-px-to-style/-/add-px-to-style-1.0.0.tgz#d0c135441fa8014a8137904531096f67f28f263a"
integrity sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo=

address@1.0.3, address@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
Expand Down Expand Up @@ -3090,6 +3095,15 @@ dom-converter@~0.2:
dependencies:
utila "~0.4"

dom-css@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/dom-css/-/dom-css-2.1.0.tgz#fdbc2d5a015d0a3e1872e11472bbd0e7b9e6a202"
integrity sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI=
dependencies:
add-px-to-style "1.0.0"
prefix-style "2.0.1"
to-camel-case "1.0.0"

dom-serializer@0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
Expand Down Expand Up @@ -6026,7 +6040,7 @@ loglevel@^1.4.1:
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.1.tgz#e0fc95133b6ef276cdc8887cdaf24aa6f156f8fa"
integrity sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=

loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
Expand Down Expand Up @@ -7783,6 +7797,11 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.2, postcss@^7.0.5, postcss@^7.0.7:
source-map "^0.6.1"
supports-color "^5.5.0"

prefix-style@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/prefix-style/-/prefix-style-2.0.1.tgz#66bba9a870cfda308a5dc20e85e9120932c95a06"
integrity sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY=

prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
Expand Down Expand Up @@ -7871,6 +7890,15 @@ prompts@^0.1.9:
kleur "^2.0.1"
sisteransi "^0.1.1"

prop-types@^15.5.10:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
dependencies:
loose-envify "^1.4.0"
object-assign "^4.1.1"
react-is "^16.8.1"

prop-types@^15.5.8, prop-types@^15.6.2:
version "15.6.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
Expand Down Expand Up @@ -7986,6 +8014,13 @@ raf@3.4.0:
dependencies:
performance-now "^2.1.0"

raf@^3.1.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"

randomatic@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed"
Expand Down Expand Up @@ -8046,6 +8081,15 @@ react-app-polyfill@^0.2.0:
raf "3.4.0"
whatwg-fetch "3.0.0"

react-custom-scrollbars@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/react-custom-scrollbars/-/react-custom-scrollbars-4.2.1.tgz#830fd9502927e97e8a78c2086813899b2a8b66db"
integrity sha1-gw/ZUCkn6X6KeMIIaBOJmyqLZts=
dependencies:
dom-css "^2.0.0"
prop-types "^15.5.10"
raf "^3.1.0"

react-dev-utils@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-7.0.1.tgz#c53e759a22668ee2c0d146c24ce4bdec2b41e3c8"
Expand Down Expand Up @@ -8091,6 +8135,11 @@ react-error-overlay@^5.1.2:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-5.1.2.tgz#888957b884d4b25b083a82ad550f7aad96585394"
integrity sha512-7kEBKwU9R8fKnZJBRa5RSIfay4KJwnYvKB6gODGicUmDSAhQJ7Tdnll5S0RLtYrzRfMVXlqYw61rzrSpP4ThLQ==

react-is@^16.8.1:
version "16.8.3"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.3.tgz#4ad8b029c2a718fc0cfc746c8d4e1b7221e5387d"
integrity sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA==

react-scripts@2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-2.1.3.tgz#6e49be279f4039fb9f330d2b3529b933b8e90945"
Expand Down Expand Up @@ -9490,6 +9539,13 @@ to-arraybuffer@^1.0.0:
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=

to-camel-case@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46"
integrity sha1-GlYFSy+daWKYzmamCJcyK29CPkY=
dependencies:
to-space-case "^1.0.0"

to-fast-properties@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
Expand All @@ -9500,6 +9556,11 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=

to-no-case@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a"
integrity sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=

to-object-path@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
Expand All @@ -9525,6 +9586,13 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"

to-space-case@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17"
integrity sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=
dependencies:
to-no-case "^1.0.0"

topo@2.x.x:
version "2.0.2"
resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182"
Expand Down

0 comments on commit 032859f

Please sign in to comment.