mirror of
https://github.com/uetchy/namae.git
synced 2025-08-20 18:08:11 +09:00
feat: persistent search result
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
import React, {useState, useRef, useEffect} from 'react';
|
||||
import styled from 'styled-components';
|
||||
import {useTranslation} from 'react-i18next';
|
||||
import {Link, useHistory} from 'react-router-dom';
|
||||
|
||||
import {sendQueryStatistics} from '../util/analytics';
|
||||
import {useDeferredState} from '../util/hooks';
|
||||
import {mobile} from '../util/css';
|
||||
|
||||
import Suggestion from './Suggestion';
|
||||
|
||||
const Form: React.FC<{onQuery: (query: string) => void}> = ({onQuery}) => {
|
||||
const Form: React.FC<{
|
||||
initialValue?: string;
|
||||
}> = ({initialValue = ''}) => {
|
||||
const history = useHistory();
|
||||
const [query, setQuery] = useDeferredState(800, '');
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const [inputValue, setInputValue] = useState(initialValue);
|
||||
const [suggested, setSuggested] = useState(false);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const {t} = useTranslation();
|
||||
@@ -23,7 +27,8 @@ const Form: React.FC<{onQuery: (query: string) => void}> = ({onQuery}) => {
|
||||
// clear input form and focus on it
|
||||
function onLogoClick(): void {
|
||||
setInputValue('');
|
||||
inputRef.current?.focus();
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
inputRef.current!.focus();
|
||||
}
|
||||
|
||||
// invoke when user clicked one of the suggested items
|
||||
@@ -35,11 +40,20 @@ const Form: React.FC<{onQuery: (query: string) => void}> = ({onQuery}) => {
|
||||
const queryGiven = query && query.length > 0;
|
||||
|
||||
useEffect(() => {
|
||||
function onQuery(query: string) {
|
||||
if (!query || query === '') {
|
||||
return;
|
||||
}
|
||||
sendQueryStatistics(query.length);
|
||||
history.push(`/s/${query}`);
|
||||
}
|
||||
|
||||
if (query.length === 0) {
|
||||
setSuggested(false);
|
||||
} else {
|
||||
onQuery(query);
|
||||
}
|
||||
onQuery(query);
|
||||
}, [query, onQuery]);
|
||||
}, [query, history]);
|
||||
|
||||
useEffect(() => {
|
||||
const modifiedValue = inputValue.replace(/[\s@+!#$%^&*()[\]]/g, '');
|
||||
@@ -48,7 +62,9 @@ const Form: React.FC<{onQuery: (query: string) => void}> = ({onQuery}) => {
|
||||
|
||||
return (
|
||||
<InputContainer>
|
||||
<Logo onClick={onLogoClick}>namæ</Logo>
|
||||
<Logo onClick={onLogoClick}>
|
||||
<Link to="/">namæ</Link>
|
||||
</Logo>
|
||||
<InputView
|
||||
onChange={onInputChange}
|
||||
value={inputValue}
|
||||
@@ -89,6 +105,14 @@ const Logo = styled.div`
|
||||
${mobile} {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:hover,
|
||||
a:active,
|
||||
a:visited {
|
||||
text-decoration: none;
|
||||
color: #4a90e2;
|
||||
}
|
||||
`;
|
||||
|
||||
const InputView = styled.input.attrs({
|
||||
|
@@ -121,9 +121,13 @@ const Suggestion: React.FC<{
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
let isEffective = true;
|
||||
const fn = async (): Promise<void> => {
|
||||
if (query && query.length > 0) {
|
||||
const synonyms = await findSynonyms(query);
|
||||
if (!isEffective) {
|
||||
return;
|
||||
}
|
||||
synonymRef.current = synonyms;
|
||||
const best = fillArray(
|
||||
sampleFromArray(synonyms, maximumCount),
|
||||
@@ -134,6 +138,9 @@ const Suggestion: React.FC<{
|
||||
}
|
||||
};
|
||||
fn();
|
||||
return () => {
|
||||
isEffective = false;
|
||||
};
|
||||
}, [query]);
|
||||
|
||||
return (
|
||||
@@ -141,15 +148,15 @@ const Suggestion: React.FC<{
|
||||
<Title>{t('try')}</Title>
|
||||
<Items>
|
||||
{bestWords &&
|
||||
bestWords.map((name) => (
|
||||
<Item key={name} onClick={(): void => applyQuery(name)}>
|
||||
bestWords.map((name, i) => (
|
||||
<Item key={name + i} onClick={(): void => applyQuery(name)}>
|
||||
{name}
|
||||
</Item>
|
||||
))}
|
||||
<Icon>
|
||||
<TiArrowSync onClick={shuffle} />
|
||||
</Icon>
|
||||
</Items>
|
||||
<Icon>
|
||||
<TiArrowSync onClick={shuffle} />
|
||||
</Icon>
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user