Skip to content

Commit

Permalink
search fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mruwnik committed May 3, 2024
1 parent e7219c0 commit 0cc1782
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 71 deletions.
2 changes: 1 addition & 1 deletion app/components/SearchInput/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const SearchInput = ({onChange, expandable, placeholderText}: SearchInput
}}
value={search}
/>
{search !== '' && <XIcon className="x-icon" onClick={clear} />}
{search !== '' && <XIcon className="x-icon pointer" onClick={clear} />}
</div>
</div>
)
Expand Down
88 changes: 31 additions & 57 deletions app/components/search.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,54 @@
import {useState, useEffect, useRef} from 'react'
import {useState} from 'react'
import debounce from 'lodash/debounce'
import {useSearch} from '~/hooks/useSearch'
import {SearchInput} from './SearchInput/Input'
import {SearchResults} from './SearchResults/Dropdown'
import {questionUrl} from '~/routesMapper'
import useOutsideOnClick from '~/hooks/useOnOutsideClick'

type Props = {
queryFromUrl?: string
limitFromUrl?: number
removeQueryFromUrl?: () => void
}

export default function Search({queryFromUrl, limitFromUrl, removeQueryFromUrl}: Props) {
const [showResults, setShowResults] = useState(!!queryFromUrl)
const searchInputRef = useRef('')
export default function Search({limitFromUrl}: Props) {
const [showResults, setShowResults] = useState(false)
const [searchPhrase, setSearchPhrase] = useState('')

const {search, isPendingSearch, results} = useSearch(limitFromUrl)
const {search, isPendingSearch, results, clear} = useSearch(limitFromUrl)
const clickDetectorRef = useOutsideOnClick(() => setShowResults(false))

const searchFn = (rawValue: string) => {
const value = rawValue.trim()
if (value === searchInputRef.current) return
if (value === searchPhrase) return
setSearchPhrase(value)

searchInputRef.current = value

search(value)
logSearch(value)
}

// run search if queryFromUrl is provided initially or if it pops from browser history after it was removed,
// update url if searchInput changes,
// and use current version of functions without affecting deps
const searchInput = searchInputRef.current
const searchFnRef = useRef(searchFn)
searchFnRef.current = searchFn
const removeQueryFromUrlRef = useRef(removeQueryFromUrl)
removeQueryFromUrlRef.current = removeQueryFromUrl
const queryFromUrlWasRemoved = useRef(false)
useEffect(() => {
if (queryFromUrl) {
if (!searchInput || queryFromUrlWasRemoved.current) {
searchFnRef.current(queryFromUrl)
queryFromUrlWasRemoved.current = false
const inputEl = document.querySelector('input[name="searchbar"]') as HTMLInputElement
inputEl.value = queryFromUrl
} else if (queryFromUrl !== searchInput) {
removeQueryFromUrlRef.current?.()
queryFromUrlWasRemoved.current = true
}
if (value) {
search(value)
logSearch(value)
} else {
clear()
}
}, [queryFromUrl, searchInput])
}

const handleChange = debounce(searchFn, 100)

const handleBlur = () => {
setTimeout(() => setShowResults(false), 500)
}

return (
<>
<div onFocus={() => setShowResults(true)} onBlur={handleBlur}>
<SearchInput expandable onChange={handleChange} />
<div className={`search-loader ${isPendingSearch ? 'loader' : ''}`}> </div>
{isPendingSearch && results.length == 0 && (
<div className="result-item-box no-questions">Searching for questions...</div>
)}
{searchInput && showResults && (
<SearchResults
results={results.map((r) => ({
title: r.title,
url: questionUrl(r),
description: '', // TODO: fetch descriptions 🤔
}))}
/>
)}
</div>
</>
<div onFocus={() => setShowResults(true)} ref={clickDetectorRef}>
<SearchInput expandable onChange={handleChange} />
<div className={`search-loader ${isPendingSearch ? 'loader' : ''}`}> </div>
{isPendingSearch && results.length == 0 && (
<div className="result-item-box no-questions">Searching for questions...</div>
)}
{searchPhrase && showResults && (
<SearchResults
results={results.map((r) => ({
title: r.title,
url: questionUrl(r),
description: '', // TODO: fetch descriptions 🤔
}))}
/>
)}
</div>
)
}
/**
Expand Down
19 changes: 6 additions & 13 deletions app/routes/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import Page from '~/components/Page'
import Chatbot from '~/components/Chatbot'
import {ChatSettings, Mode} from '~/hooks/useChat'
import Button from '~/components/Button'
import useOutsideOnClick from '~/hooks/useOnOutsideClick'

export const shouldRevalidate: ShouldRevalidateFunction = () => false

export default function App() {
const [params] = useSearchParams()
const [showSettings, setShowSettings] = useState(false)
const clickDetectorRef = useOutsideOnClick(() => setShowSettings(false))
const [chatSettings, setChatSettings] = useState({
mode: 'default',
completions: 'gpt-3.5-turbo',
Expand All @@ -26,15 +28,9 @@ export default function App() {
</Button>
)

const stopBubbling = (e: any) => {
e.preventDefault()
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
}

return (
<Page noFooter>
<div className="page-body full-height padding-top-32" onClick={() => setShowSettings(false)}>
<div className="page-body full-height padding-top-32">
<Chatbot
question={question}
questions={[
Expand All @@ -44,9 +40,9 @@ export default function App() {
]}
settings={chatSettings}
/>
<div className="settings-container">
<div className="settings-container" ref={clickDetectorRef}>
{showSettings && (
<div className="settings bordered flex-container" onClick={stopBubbling}>
<div className="settings bordered flex-container">
<div>Answer detail</div>
<ModeButton mode="default" name="Default" />
<ModeButton mode="rookie" name="Detailed" />
Expand All @@ -57,10 +53,7 @@ export default function App() {
width="24"
height="24"
className="pointer"
onClick={(e) => {
stopBubbling(e)
setShowSettings((current) => !current)
}}
onClick={() => setShowSettings((current) => !current)}
/>
</div>
</div>
Expand Down

0 comments on commit 0cc1782

Please sign in to comment.