From 1bf5fdeaca8c7c45854ef9934e863b9af7e69e1e Mon Sep 17 00:00:00 2001
From: Xc165543337 <90028194+Xc165543337@users.noreply.github.com>
Date: Wed, 22 May 2024 19:05:01 +0200
Subject: [PATCH] perf: implementation of Fuse.js for fuzzy searching icons

---
 package-lock.json                                 |  9 +++++++++
 package.json                                      |  1 +
 .../components/HabitForm/IconSelectorModal.tsx    | 15 ++++++++++++---
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/package-lock.json b/package-lock.json
index ddbdb4f..6f1eb66 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,7 @@
         "expo-status-bar": "1.12.1",
         "expo-system-ui": "3.0.4",
         "expo-web-browser": "13.0.3",
+        "fuse.js": "7.0.0",
         "immer": "10.1.1",
         "lottie-react-native": "6.7.0",
         "react": "18.2.0",
@@ -14240,6 +14241,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/fuse.js": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+      "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
diff --git a/package.json b/package.json
index 4a68399..fcfd25c 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "expo-status-bar": "1.12.1",
     "expo-system-ui": "3.0.4",
     "expo-web-browser": "13.0.3",
+    "fuse.js": "7.0.0",
     "immer": "10.1.1",
     "lottie-react-native": "6.7.0",
     "react": "18.2.0",
diff --git a/presentation/react-native/components/HabitForm/IconSelectorModal.tsx b/presentation/react-native/components/HabitForm/IconSelectorModal.tsx
index d130c8b..938a4c7 100644
--- a/presentation/react-native/components/HabitForm/IconSelectorModal.tsx
+++ b/presentation/react-native/components/HabitForm/IconSelectorModal.tsx
@@ -4,6 +4,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome"
 import { memo, useCallback, useEffect, useState, useTransition } from "react"
 import { Modal, ScrollView, View } from "react-native"
 import { Button, List, Text, TextInput } from "react-native-paper"
+import Fuse from "fuse.js"
 
 import { IconsList } from "./IconsList"
 
@@ -30,10 +31,18 @@ const iconNames = Object.keys(fas).map((key) => {
   return fas[key]?.iconName ?? key
 })
 
+const fuseOptions = {
+  keys: ["iconName"],
+  threshold: 0.4,
+}
+
+const fuse = new Fuse(iconNames, fuseOptions)
+
 const findIconsInLibrary = (icon: string): string[] => {
-  return iconNames
-    .filter((name, index, self) => {
-      return name.includes(icon) && self.indexOf(name) === index
+  return fuse
+    .search(icon)
+    .map((result) => {
+      return result.item
     })
     .slice(0, 50)
 }
-- 
GitLab