about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2024-04-19 22:55:53 +0100
committerGitHub <noreply@github.com>2024-04-19 22:55:53 +0100
commitedbb18afa44bcfee4560ac19880a0c32563b6a0e (patch)
treec8b9223c7751d9c8a587477f3087ed764be640a3
parent8b33ffdfb5ca606708c8104ecad4fa5430268483 (diff)
downloadvoidsky-edbb18afa44bcfee4560ac19880a0c32563b6a0e.tar.zst
Throttle gif search by 500ms (#3622)
* debounce gif search by 300ms

* Throttle it instead

---------

Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
-rw-r--r--src/components/dialogs/GifSelect.tsx11
-rw-r--r--src/components/hooks/useThrottledValue.ts27
2 files changed, 30 insertions, 8 deletions
diff --git a/src/components/dialogs/GifSelect.tsx b/src/components/dialogs/GifSelect.tsx
index 92e21af47..c8897da36 100644
--- a/src/components/dialogs/GifSelect.tsx
+++ b/src/components/dialogs/GifSelect.tsx
@@ -1,10 +1,4 @@
-import React, {
-  useCallback,
-  useDeferredValue,
-  useMemo,
-  useRef,
-  useState,
-} from 'react'
+import React, {useCallback, useMemo, useRef, useState} from 'react'
 import {TextInput, View} from 'react-native'
 import {Image} from 'expo-image'
 import {msg, Trans} from '@lingui/macro'
@@ -22,6 +16,7 @@ import {Gif, useGifphySearch, useGiphyTrending} from '#/state/queries/giphy'
 import {atoms as a, useBreakpoints, useTheme} from '#/alf'
 import * as Dialog from '#/components/Dialog'
 import * as TextField from '#/components/forms/TextField'
+import {useThrottledValue} from '#/components/hooks/useThrottledValue'
 import {ArrowLeft_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow'
 import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
 import {InlineLinkText} from '#/components/Link'
@@ -82,7 +77,7 @@ function GifList({
   const {gtMobile} = useBreakpoints()
   const ref = useRef<TextInput>(null)
   const [undeferredSearch, setSearch] = useState('')
-  const search = useDeferredValue(undeferredSearch)
+  const search = useThrottledValue(undeferredSearch, 500)
 
   const isSearching = search.length > 0
 
diff --git a/src/components/hooks/useThrottledValue.ts b/src/components/hooks/useThrottledValue.ts
new file mode 100644
index 000000000..5764c547e
--- /dev/null
+++ b/src/components/hooks/useThrottledValue.ts
@@ -0,0 +1,27 @@
+import {useEffect, useRef, useState} from 'react'
+
+import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
+
+export function useThrottledValue<T>(value: T, time?: number) {
+  const pendingValueRef = useRef(value)
+  const [throttledValue, setThrottledValue] = useState(value)
+
+  useEffect(() => {
+    pendingValueRef.current = value
+  }, [value])
+
+  const handleTick = useNonReactiveCallback(() => {
+    if (pendingValueRef.current !== throttledValue) {
+      setThrottledValue(pendingValueRef.current)
+    }
+  })
+
+  useEffect(() => {
+    const id = setInterval(handleTick, time)
+    return () => {
+      clearInterval(id)
+    }
+  }, [handleTick, time])
+
+  return throttledValue
+}