mirror of
https://github.com/uetchy/namae.git
synced 2025-03-17 04:30:31 +09:00
fix: improved godfather
This commit is contained in:
parent
618512b4f8
commit
a30ee9a411
@ -1,10 +1,13 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
import React, { useEffect, useState, useRef } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import fetch from 'isomorphic-unfetch'
|
import fetch from 'isomorphic-unfetch'
|
||||||
|
import { TiArrowSync } from 'react-icons/ti'
|
||||||
|
|
||||||
import { capitalize } from '../util/text'
|
import { capitalize } from '../util/text'
|
||||||
|
import { mobile } from '../util/css'
|
||||||
|
|
||||||
|
const maximumCount = 3
|
||||||
const modifiers = [
|
const modifiers = [
|
||||||
(word) => `${capitalize(word)}ify`,
|
(word) => `${capitalize(word)}ify`,
|
||||||
(word) => `lib${lower(word)}`,
|
(word) => `lib${lower(word)}`,
|
||||||
@ -40,6 +43,10 @@ const modifiers = [
|
|||||||
(word) => `${capitalize(word)}`,
|
(word) => `${capitalize(word)}`,
|
||||||
]
|
]
|
||||||
|
|
||||||
|
function lower(word) {
|
||||||
|
return word.toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
function shuffleArray(array) {
|
function shuffleArray(array) {
|
||||||
for (let i = array.length - 1; i > 0; i--) {
|
for (let i = array.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1))
|
const j = Math.floor(Math.random() * (i + 1))
|
||||||
@ -50,15 +57,23 @@ function shuffleArray(array) {
|
|||||||
return array
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sampleFromArray(array, maximum) {
|
||||||
|
return shuffleArray(array).slice(0, maximum)
|
||||||
|
}
|
||||||
|
|
||||||
function modifyWord(word) {
|
function modifyWord(word) {
|
||||||
return modifiers[Math.floor(Math.random() * modifiers.length)](word)
|
return modifiers[Math.floor(Math.random() * modifiers.length)](word)
|
||||||
}
|
}
|
||||||
|
|
||||||
function lower(word) {
|
function fillArray(array, filler, maximum) {
|
||||||
return word.toLowerCase()
|
const deficit = maximum - array.length
|
||||||
|
if (deficit > 0) {
|
||||||
|
array = [...array, ...Array(deficit).fill(filler)]
|
||||||
|
}
|
||||||
|
return array
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findSynonyms(word, maximum = 10) {
|
async function findSynonyms(word) {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&dt=ss&ie=UTF-8&oe=UTF-8&dj=1&q=${encodeURIComponent(
|
`https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&dt=ss&ie=UTF-8&oe=UTF-8&dj=1&q=${encodeURIComponent(
|
||||||
@ -66,59 +81,68 @@ async function findSynonyms(word, maximum = 10) {
|
|||||||
)}`
|
)}`
|
||||||
)
|
)
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
const synonyms = json.synsets.reduce(
|
const synonyms = [
|
||||||
(sum, synset) =>
|
|
||||||
(sum = [...sum, ...synset.entry.map((e) => e.synonym[0])]),
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
let bestWords = [
|
|
||||||
...new Set(
|
...new Set(
|
||||||
shuffleArray(synonyms.filter((word) => !word.match(/[\s-]/))).slice(
|
json.synsets.reduce(
|
||||||
0,
|
(sum, synset) =>
|
||||||
maximum
|
(sum = [...sum, ...synset.entry.map((e) => e.synonym[0])]),
|
||||||
|
[]
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
]
|
].filter((word) => !word.match(/[\s-]/))
|
||||||
const deficit = maximum - bestWords.length
|
return synonyms
|
||||||
if (deficit > 0) {
|
|
||||||
bestWords = [...bestWords, ...Array(deficit).fill(word)]
|
|
||||||
}
|
|
||||||
return bestWords
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return Array(maximum).fill(word)
|
return []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Suggestion({ query, onSubmit }) {
|
export default function Suggestion({ query, onSubmit }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [synonyms, setSynonyms] = useState([])
|
const synonymRef = useRef([])
|
||||||
|
const [bestWords, setBestWords] = useState([])
|
||||||
|
|
||||||
useEffect(() => {
|
function shuffle() {
|
||||||
const fn = async () => {
|
const best = fillArray(
|
||||||
if (query && query.length > 0) {
|
sampleFromArray(synonymRef.current, maximumCount),
|
||||||
const synonyms = (await findSynonyms(query, 3)).map((synonym) =>
|
query,
|
||||||
modifyWord(synonym)
|
maximumCount
|
||||||
)
|
).map((word) => modifyWord(word))
|
||||||
setSynonyms(synonyms)
|
setBestWords(best)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fn()
|
|
||||||
}, [query])
|
|
||||||
|
|
||||||
function applyQuery(name) {
|
function applyQuery(name) {
|
||||||
onSubmit(name)
|
onSubmit(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const fn = async () => {
|
||||||
|
if (query && query.length > 0) {
|
||||||
|
const synonyms = await findSynonyms(query)
|
||||||
|
synonymRef.current = synonyms
|
||||||
|
const best = fillArray(
|
||||||
|
sampleFromArray(synonyms, maximumCount),
|
||||||
|
query,
|
||||||
|
maximumCount
|
||||||
|
).map((word) => modifyWord(word))
|
||||||
|
setBestWords(best)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn()
|
||||||
|
}, [query])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<Title>{t('try')}</Title>
|
<Title>{t('try')}</Title>
|
||||||
<Items>
|
<Items>
|
||||||
{synonyms &&
|
{bestWords &&
|
||||||
synonyms.map((name) => (
|
bestWords.map((name) => (
|
||||||
<Item key={name} onClick={() => applyQuery(name)}>
|
<Item key={name} onClick={() => applyQuery(name)}>
|
||||||
{name}
|
{name}
|
||||||
</Item>
|
</Item>
|
||||||
))}
|
))}
|
||||||
|
<Icon>
|
||||||
|
<TiArrowSync onClick={shuffle} />
|
||||||
|
</Icon>
|
||||||
</Items>
|
</Items>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
@ -127,31 +151,49 @@ export default function Suggestion({ query, onSubmit }) {
|
|||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: baseline;
|
|
||||||
line-height: 1em;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const Title = styled.div`
|
const Title = styled.div`
|
||||||
margin-top: 15px;
|
margin-top: 15px;
|
||||||
font-size: 0.6em;
|
padding: 5px 12px;
|
||||||
|
color: gray;
|
||||||
|
border: 1px solid gray;
|
||||||
|
border-radius: 2em;
|
||||||
`
|
`
|
||||||
|
|
||||||
const Items = styled.div`
|
const Items = styled.div`
|
||||||
margin-top: 15px;
|
margin-top: 2px;
|
||||||
margin-left: 8px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
|
${mobile} {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const Item = styled.div`
|
const Item = styled.div`
|
||||||
margin-right: 10px;
|
margin-top: 8px;
|
||||||
|
margin-right: 14px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
border-bottom: 1px dashed black;
|
border-bottom: 1px dashed black;
|
||||||
|
color: black;
|
||||||
|
|
||||||
|
${mobile} {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const Icon = styled(Item)`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: none;
|
||||||
`
|
`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user