feat: adding and removing of file tags works

This commit is contained in:
overflowerror 2021-10-09 22:02:45 +02:00
parent 380a0ece0b
commit 7437e027e7
5 changed files with 87 additions and 9 deletions

View file

@ -1,27 +1,72 @@
import React, {FunctionComponent} from "react";
import React, {FunctionComponent, useEffect, useState} from "react";
import {MediaFile} from "../../database/file";
import MediaPreview from "../MediaPreview";
export type MediaDetailsProps = {
basePath: string,
file: MediaFile
file: MediaFile,
onUpdate: (file: MediaFile) => void
}
const MediaDetails: FunctionComponent<MediaDetailsProps> = ({basePath, file}) => {
const MediaDetails: FunctionComponent<MediaDetailsProps> = ({basePath, file, onUpdate}) => {
const [currentFile, setCurrentFile] = useState<MediaFile>(file)
const [hasChanges, setHasChanges] = useState<boolean>(false)
const [newTagInput, setNewTagInput] = useState<string>("")
useEffect(() => {
if (currentFile.getPath() != file.getPath()) {
setCurrentFile(file)
setHasChanges(false)
setNewTagInput("")
}
}, [file])
const removeTag = (tag: string) => {
const clone = currentFile.clone()
clone.removeTag(tag)
setCurrentFile(clone)
setHasChanges(true)
}
const addTag = (tag: string) => {
const clone = currentFile.clone()
clone.addTag(tag)
setCurrentFile(clone)
setHasChanges(true)
}
return (
<div>
<MediaPreview basePath={basePath} file={file} />
<MediaPreview basePath={basePath} file={currentFile} />
<div>
Path: {file.getPath()} <br />
Path: {currentFile.getPath()} <br />
Tags:
<ul>
{
file.getTags().map(t => (
<li key={t}>{t}</li>
currentFile.getTags().map(t => (
<li key={t}>{t} <a onClick={() => removeTag(t)}>-</a> </li>
))
}
<li>
<input type="text" value={newTagInput} onChange={(event) => {
setNewTagInput(event.target.value)
}} />
<button onClick={() => {
addTag(newTagInput)
setNewTagInput("")
}}>
Add
</button>
</li>
</ul>
</div>
{ hasChanges &&
<button onClick={() => {
onUpdate(currentFile)
setHasChanges(false)
}}>Save</button>
}
</div>
)
}

View file

@ -75,4 +75,13 @@ export class Database {
return obj
}
public clone(): Database {
const clone = new Database()
clone.directories = [...this.directories]
// not a deep copy; files are references
clone.files = [...this.files]
return clone
}
}

View file

@ -32,7 +32,7 @@ export class MediaFile {
public removeTag(tag: string) {
const i = this.tags.indexOf(tag)
if (i >= 0) {
this.tags.slice(i, 1)
this.tags.splice(i, 1)
}
}
@ -71,4 +71,10 @@ export class MediaFile {
return obj
}
public clone(): MediaFile {
const clone = new MediaFile(this.path)
clone.tags = [...this.tags]
return clone
}
}

View file

@ -63,6 +63,10 @@ class Repository {
return untagged.filter((v, i, s) => s.indexOf(v) == i)
}
public update(db: Database) {
this.cached = db
}
}
export default Repository

View file

@ -45,6 +45,20 @@ const Home: FunctionComponent<HomeProps> = () => {
}, [repository])
const query = database ? queryFilter(database.query(), tags) : emptyQuery
const allTags = database ? database.query().tags() : []
const mediaUpdate = (updatedFile: MediaFile) => {
const clone = database.clone() // not a deep copy
clone.updateFile(updatedFile)
repository.update(clone)
setError("Saving...")
repository.write().then(() => {
setSelected(updatedFile)
setDatabase(clone)
setError(null)
})
}
return (
<div>
@ -59,7 +73,7 @@ const Home: FunctionComponent<HomeProps> = () => {
{ selected &&
<>
<button onClick={() => setSelected(null)}>Back</button>
<MediaDetails basePath={repository.getPath()} file={selected} />
<MediaDetails basePath={repository.getPath()} file={selected} onUpdate={mediaUpdate} />
</>
}
{ !selected &&