feat: added autocompletion for MediaDetails component

This commit is contained in:
overflowerror 2021-10-10 17:13:03 +02:00
parent 55df389ae9
commit 984da2c2bc
3 changed files with 71 additions and 6 deletions

View file

@ -0,0 +1,59 @@
import React, {FunctionComponent, useState} from "react";
export type AutocompleteProps = {
value: string,
options: string[],
onChange: (value: string) => void
}
const Autocomplete: FunctionComponent<AutocompleteProps> = ({value, options, onChange}) => {
const matchingOptions = options.filter(o => o.toLowerCase().indexOf(value.toLowerCase()) >= 0)
const [showSuggestion, setShowSuggestion] = useState<boolean>(false)
const [selectedIndex, setSelectedIndex] = useState<number|null>(null)
const onSelect = (value: string) => {
setShowSuggestion(false)
setSelectedIndex(null)
onChange(value)
}
return (
<>
<input
value={value}
onKeyDown={event => {
if (event.key == "ArrowDown") {
setSelectedIndex(Math.min(selectedIndex + 1, matchingOptions.length - 1))
} else if (event.key == "ArrowUp") {
setSelectedIndex(Math.max(0, selectedIndex - 1))
}
if (event.key == "Enter" && selectedIndex !== null) {
onSelect(matchingOptions[selectedIndex])
}
}}
onChange={event => {
setShowSuggestion(true)
setSelectedIndex(null)
onChange(event.target.value)
}}
/>
{ showSuggestion && matchingOptions.length > 0 && matchingOptions[0] != value &&
<ul>
{ matchingOptions.map((o, i) => (
<li
key={o}
onClick={() => {
onSelect(matchingOptions[i])
}}
>
{i === selectedIndex && "#"} {o}
</li>
))}
</ul>
}
</>
)
}
export default Autocomplete

View file

@ -1,14 +1,16 @@
import React, {FunctionComponent, useEffect, useState} from "react";
import {MediaFile} from "../../database/file";
import MediaPreview from "../MediaPreview";
import Autocomplete from "../Autocomplete";
export type MediaDetailsProps = {
basePath: string,
file: MediaFile,
onUpdate: (file: MediaFile) => void
onUpdate: (file: MediaFile) => void,
allTags: string[]
}
const MediaDetails: FunctionComponent<MediaDetailsProps> = ({basePath, file, onUpdate}) => {
const MediaDetails: FunctionComponent<MediaDetailsProps> = ({basePath, file, onUpdate, allTags}) => {
const [currentFile, setCurrentFile] = useState<MediaFile>(file)
const [hasChanges, setHasChanges] = useState<boolean>(false)
@ -49,9 +51,13 @@ const MediaDetails: FunctionComponent<MediaDetailsProps> = ({basePath, file, onU
))
}
<li>
<input type="text" value={newTagInput} onChange={(event) => {
setNewTagInput(event.target.value)
}} />
<Autocomplete
value={newTagInput}
options={allTags}
onChange={(value) => {
setNewTagInput(value)
}}
/>
<button onClick={() => {
addTag(newTagInput)
setNewTagInput("")

View file

@ -116,7 +116,7 @@ const Home: FunctionComponent<HomeProps> = () => {
{ selected &&
<>
<button onClick={() => setSelected(null)}>Back</button>
<MediaDetails basePath={basePath} file={selected} onUpdate={mediaUpdate} />
<MediaDetails basePath={basePath} file={selected} onUpdate={mediaUpdate} allTags={allTags} />
</>
}
{ !selected && showUntagged &&