From f6e6b90d8d7bb94b258ba5b4245de9ec46a711e1 Mon Sep 17 00:00:00 2001 From: Kevin Belisle Date: Thu, 8 Jul 2021 23:10:04 -0400 Subject: [PATCH] Optimize Search results rendering, replace favicon --- spa/package-lock.json | 32 ++++++++++ spa/package.json | 3 +- spa/public/favicon.ico | Bin 3870 -> 15406 bytes spa/public/index.html | 6 +- spa/src/App.js | 2 +- spa/src/Player.js | 16 ++--- spa/src/Search.js | 129 ++++++++++++++++++++++++++--------------- spa/src/Statistic.js | 13 +---- spa/src/index.js | 1 + 9 files changed, 128 insertions(+), 74 deletions(-) diff --git a/spa/package-lock.json b/spa/package-lock.json index 57d145d..c75d241 100644 --- a/spa/package-lock.json +++ b/spa/package-lock.json @@ -4777,6 +4777,11 @@ "wrap-ansi": "^6.2.0" } }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -5789,6 +5794,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", @@ -13008,6 +13022,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "react-query": { "version": "3.18.1", "resolved": "https://registry.npmjs.org/react-query/-/react-query-3.18.1.tgz", @@ -13166,6 +13185,19 @@ "tslib": "^1.0.0" } }, + "react-virtualized": { + "version": "9.22.3", + "resolved": "https://registry.npmjs.org/react-virtualized/-/react-virtualized-9.22.3.tgz", + "integrity": "sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==", + "requires": { + "@babel/runtime": "^7.7.2", + "clsx": "^1.0.4", + "dom-helpers": "^5.1.3", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + } + }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", diff --git a/spa/package.json b/spa/package.json index ab465ff..c1a06ac 100644 --- a/spa/package.json +++ b/spa/package.json @@ -18,7 +18,8 @@ "react-icons": "^4.2.0", "react-query": "^3.18.1", "react-router-dom": "^5.2.0", - "react-scripts": "4.0.3" + "react-scripts": "4.0.3", + "react-virtualized": "^9.22.3" }, "scripts": { "start": "react-scripts start", diff --git a/spa/public/favicon.ico b/spa/public/favicon.ico index a11777cc471a4344702741ab1c8a588998b1311a..c6493367ee724adad6cfa8e237f1bcc85b4b37eb 100644 GIT binary patch literal 15406 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 MP5B!Rj0Ok(2T_PvW&i*H literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ diff --git a/spa/public/index.html b/spa/public/index.html index 6bd9b20..f671f3e 100644 --- a/spa/public/index.html +++ b/spa/public/index.html @@ -4,12 +4,14 @@ - + + - React App + Stonks! diff --git a/spa/src/App.js b/spa/src/App.js index bda9272..eaed35b 100644 --- a/spa/src/App.js +++ b/spa/src/App.js @@ -1,7 +1,7 @@ import React from "react"; import { useQuery } from "react-query"; import axios from "axios"; -import { BrowserRouter, Switch, Redirect, Route } from "react-router-dom"; +import { BrowserRouter, Switch, Route } from "react-router-dom"; import { Container } from "@chakra-ui/react"; import Search from "./Search"; diff --git a/spa/src/Player.js b/spa/src/Player.js index 0b7323f..c973f42 100644 --- a/spa/src/Player.js +++ b/spa/src/Player.js @@ -1,23 +1,17 @@ -import React, { useMemo, useState } from "react"; +import React from "react"; import { useQuery } from "react-query"; import axios from "axios"; import { - Button, Center, - Flex, Heading, - Icon, Image, Table, Thead, Tbody, - Tfoot, Tr, Th, Td, - TableCaption, } from "@chakra-ui/react"; -import { FaUserCircle, FaArrowAltCircleRight } from "react-icons/fa"; import { Link } from "react-router-dom"; const Player = ({ playerId, players }) => { @@ -33,9 +27,7 @@ const Player = ({ playerId, players }) => { } ); - const playerDict = useMemo(() => { - return Object.assign({}, ...players.data.map((x) => ({ [x.id]: x.name }))); - }, players); + const playerName = players.data.find((x) => x.id === playerId).name; return ( <> @@ -55,9 +47,9 @@ const Player = ({ playerId, players }) => { src={`https://minotar.net/avatar/${playerId.replaceAll("-", "")}/48`} mr="4" /> - {playerDict[playerId]} + {playerName} - +
diff --git a/spa/src/Search.js b/spa/src/Search.js index 45efb5a..984e162 100644 --- a/spa/src/Search.js +++ b/spa/src/Search.js @@ -1,9 +1,10 @@ import React, { useMemo, useState } from "react"; import Fuse from "fuse.js"; -import { Button, Center, Flex, Heading, Icon, Input } from "@chakra-ui/react"; +import { Button, Center, Heading, Icon, Input } from "@chakra-ui/react"; import { FaUserCircle, FaArrowAltCircleRight } from "react-icons/fa"; import { Link } from "react-router-dom"; +import { AutoSizer, WindowScroller, List } from "react-virtualized"; const Search = ({ statistics, players }) => { const [searchTerm, setSearchTerm] = useState(""); @@ -39,54 +40,86 @@ const Search = ({ statistics, players }) => { return searchEngine.search(`'"${searchTerm}"'`); }, [searchEngine, searchTerm]); + const renderRow = ({ + index, // Index of row + isScrolling, // The List is currently being scrolled + isVisible, // This row is visible within the List (eg it is not an overscanned row) + key, // Unique key within array of rendered rows + parent, // Reference to the parent List (instance) + style, // Style object to be applied to row (to position it); + // This must be passed through to the rendered row element. + }) => { + const x = searchResults[index]; + + return ( + + + + ); + }; + return ( - <> - -
📈
-
- setSearchTerm(event.target.value)} - /> - - {searchResults.map((x, i) => { - return ( - - - - ); - })} - - + + {({ height, isScrolling, onChildScroll, scrollTop, registerChild }) => ( + <> + +
📈
+
+ setSearchTerm(event.target.value)} + /> +
+ + {({ width }) => ( + + )} + +
+ + )} +
); }; diff --git a/spa/src/Statistic.js b/spa/src/Statistic.js index edab8f4..df0cedb 100644 --- a/spa/src/Statistic.js +++ b/spa/src/Statistic.js @@ -1,23 +1,16 @@ -import React, { useMemo, useState } from "react"; +import React, { useMemo } from "react"; import { useQuery } from "react-query"; import axios from "axios"; import { - Button, Center, - Flex, Heading, - Icon, - Input, Table, Thead, Tbody, - Tfoot, Tr, Th, Td, - TableCaption, } from "@chakra-ui/react"; -import { FaUserCircle, FaArrowAltCircleRight } from "react-icons/fa"; import { Link } from "react-router-dom"; const Statistic = ({ type, name, players }) => { @@ -34,7 +27,7 @@ const Statistic = ({ type, name, players }) => { const playerDict = useMemo(() => { return Object.assign({}, ...players.data.map((x) => ({ [x.id]: x.name }))); - }, players); + }, [players]); return ( <> @@ -49,7 +42,7 @@ const Statistic = ({ type, name, players }) => { {type} {name} -
Statistic
+
diff --git a/spa/src/index.js b/spa/src/index.js index 433993c..167328f 100644 --- a/spa/src/index.js +++ b/spa/src/index.js @@ -6,6 +6,7 @@ import { QueryClient, QueryClientProvider } from "react-query"; import App from "./App.js"; import "./index.css"; +import "react-virtualized/styles.css"; const queryClient = new QueryClient();
Player