From 29ce562d0111d15d9540b571d2ed0742a68d624a Mon Sep 17 00:00:00 2001 From: Mitchell McCaffrey Date: Wed, 30 Sep 2020 15:39:56 +1000 Subject: [PATCH] Added search filtering to map select --- package.json | 1 + src/components/map/MapTiles.js | 7 +++++-- src/modals/SelectMapModal.js | 35 +++++++++++++++++++++++++++++----- yarn.lock | 5 +++++ 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index e1084c1..bcb6f4b 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "case": "^1.6.3", "dexie": "^2.0.4", "fake-indexeddb": "^3.0.0", + "fuse.js": "^6.4.1", "interactjs": "^1.9.7", "konva": "^6.0.0", "lodash.get": "^4.4.2", diff --git a/src/components/map/MapTiles.js b/src/components/map/MapTiles.js index 7b2cfa9..0b18ee8 100644 --- a/src/components/map/MapTiles.js +++ b/src/components/map/MapTiles.js @@ -29,6 +29,8 @@ function MapTiles({ onDone, selectMode, onSelectModeChange, + search, + onSearchChange, }) { const { databaseStatus } = useContext(DatabaseContext); const isSmallScreen = useMedia({ query: "(max-width: 500px)" }); @@ -70,7 +72,7 @@ function MapTiles({ }} onFocus={() => onMapSelect()} > - + - + onMapSelect()} > diff --git a/src/modals/SelectMapModal.js b/src/modals/SelectMapModal.js index 86a89a3..d2510b8 100644 --- a/src/modals/SelectMapModal.js +++ b/src/modals/SelectMapModal.js @@ -1,6 +1,7 @@ -import React, { useRef, useState, useContext } from "react"; +import React, { useRef, useState, useContext, useEffect } from "react"; import { Button, Flex, Label } from "theme-ui"; import shortid from "shortid"; +import Fuse from "fuse.js"; import EditMapModal from "./EditMapModal"; @@ -52,6 +53,26 @@ function SelectMapModal({ updateMap, } = useContext(MapDataContext); + const [filteredMaps, setFilteredMaps] = useState([]); + const [fuse, setFuse] = useState(); + const [search, setSearch] = useState(""); + + // Update search index when maps change + useEffect(() => { + setFuse(new Fuse(ownedMaps, { keys: ["name"] })); + }, [ownedMaps]); + + // Perform search when search changes + useEffect(() => { + if (search) { + setFilteredMaps(fuse.search(search).map((result) => result.item)); + } + }, [search, ownedMaps, fuse]); + + function handleSearchChange(event) { + setSearch(event.target.value); + } + const [imageLoading, setImageLoading] = useState(false); // The map selected in the modal @@ -207,10 +228,12 @@ function SelectMapModal({ }); break; case "range": + // Use filtered maps if we have searched + const maps = search ? filteredMaps : ownedMaps; // Add all items inbetween the previous selected map and the current selected if (selectedMapIds.length > 0) { - const mapIndex = ownedMaps.findIndex((m) => m.id === map.id); - const lastIndex = ownedMaps.findIndex( + const mapIndex = maps.findIndex((m) => m.id === map.id); + const lastIndex = maps.findIndex( (m) => m.id === selectedMapIds[selectedMapIds.length - 1] ); let idsToAdd = []; @@ -221,7 +244,7 @@ function SelectMapModal({ direction < 0 ? i >= mapIndex : i <= mapIndex; i += direction ) { - const mapId = ownedMaps[i].id; + const mapId = maps[i].id; if (selectedMapIds.includes(mapId)) { idsToRemove.push(mapId); } else { @@ -317,7 +340,7 @@ function SelectMapModal({ Select or import a map setIsEditModalOpen(true)} onMapsReset={handleMapsReset} @@ -328,6 +351,8 @@ function SelectMapModal({ onDone={handleDone} selectMode={selectMode} onSelectModeChange={setSelectMode} + search={search} + onSearchChange={handleSearchChange} />