Fix Picker not providing the correct sticker after searching

Picking a sticker after using the search bar returns the index of that
sticker inside the filtered list and not the original list which results
in unexpected behaviors.

Instead of filtering the sticker list according to the search prompt,
hide the unwanted stickers by not rendering them. By doing so, all stickers
will retain their original index from the master sticker list.
This commit is contained in:
Suuringo
2022-10-13 22:30:20 +02:00
parent 2580c87e64
commit 61fda881b6

View File

@@ -5,26 +5,12 @@ import {
Button,
TextField,
} from "@mui/material";
import { useState, useEffect } from "react";
import default_characters from "../characters.json";
import { useState, useMemo } from "react";
import characters from "../characters.json";
export default function Picker({ setCharacter }) {
const [anchorEl, setAnchorEl] = useState(null);
const [search, setSearch] = useState("");
const [characters, setCharacters] = useState(default_characters);
useEffect(() => {
setCharacters(
default_characters.filter((char) => {
const s = search.toLowerCase();
return (
s === char.id ||
char.name.toLowerCase().includes(s) ||
char.character.toLowerCase().includes(s)
);
})
);
}, [search]);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
@@ -37,6 +23,44 @@ export default function Picker({ setCharacter }) {
const open = Boolean(anchorEl);
const id = open ? "picker" : undefined;
// Memoize the filtered image list items to avoid recomputing them
// at every render
const memoizedImageListItems = useMemo(() => {
const s = search.toLowerCase();
return characters.map((c, index) => {
if (s === c.id ||
c.name.toLowerCase().includes(s) ||
c.character.toLowerCase().includes(s)) {
return (
<ImageListItem
key={index}
onClick={() => {
handleClose();
setCharacter(index);
}}
sx={{
cursor: "pointer",
"&:hover": {
opacity: 0.5,
},
"&:active": {
opacity: 0.8,
},
}}
>
<img
src={`/img/${c.img}`}
srcSet={`/img/${c.img}`}
alt={c.name}
loading="lazy"
/>
</ImageListItem>
)
}
return null;
})
}, [search, setCharacter])
return (
<div>
<Button
@@ -80,31 +104,7 @@ export default function Picker({ setCharacter }) {
rowHeight={140}
className="image-grid"
>
{characters.map((c, index) => (
<ImageListItem
key={index}
onClick={() => {
handleClose();
setCharacter(index);
}}
sx={{
cursor: "pointer",
"&:hover": {
opacity: 0.5,
},
"&:active": {
opacity: 0.8,
},
}}
>
<img
src={`/img/${c.img}`}
srcSet={`/img/${c.img}`}
alt={c.name}
loading="lazy"
/>
</ImageListItem>
))}
{memoizedImageListItems}
</ImageList>
</div>
</Popover>