-
Notifications
You must be signed in to change notification settings - Fork 1
/
Annotate.tsx
113 lines (92 loc) · 3.41 KB
/
Annotate.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import { Annotorious, AnnotoriousPlugin, ImageAnnotator, W3CImageFormat } from '@annotorious/react';
import { mountExtension as SelectorPack } from '@annotorious/selector-pack';
import { ChevronLeft } from 'lucide-react';
import { useStore } from '@/store';
import { SaveStatus, SavingIndicator } from '@/components/SavingIndicator';
import { useToast } from '@/ui/Toaster';
import { EditorPanel } from './EditorPanel';
import { StoragePlugin } from './StoragePlugin';
import { Tool, Toolbar } from './Toolbar';
import './Annotate.css';
import '@annotorious/react/annotorious-react.css';
export const Annotate = () => {
const store = useStore({ redirect: true });
const params = useParams();
const image = store?.getImage(params.id!);
const [saveStatus, setSaveStatus] = useState<SaveStatus>('idle');
const [tool, setTool] = useState<Tool>('rectangle');
const { toast } = useToast();
const onSaving = () => setSaveStatus('saving');
const onSaved = () => setSaveStatus('success');
const onError = (error: Error) => {
setSaveStatus('failed');
toast({
title: 'Something went wrong',
description: `There was an error saving annotation. Message: ${error}`
});
}
return store && (
<div className="page-root page annotate">
<Annotorious>
<main className="bg-muted relative p-0 flex flex-col overflow-hidden">
<div>
<nav className="p-3 pr-4 bg-white inline-block border-r rounded-br-lg shadow-md relative z-10">
<ul className="flex text-sm">
<li className="inline-block">
<Link className="font-semibold" to="/images">
<ChevronLeft className="h-5 w-5 mr-1" />
</Link>
</li>
{image && (
<li className="inline-block font-medium">
{image.name}
</li>
)}
</ul>
</nav>
</div>
<SavingIndicator status={saveStatus} />
{image && (
<div className="flex justify-center items-center z-0 flex-grow pb-12">
<ImageAnnotator
// @ts-ignore
adapter={W3CImageFormat(image.path)}
autoSave={true}
tool={tool}>
<img
className="select-none"
src={URL.createObjectURL(image.data)}
alt={image.path} />
</ImageAnnotator>
{/* @ts-ignore */}
<AnnotoriousPlugin
// @ts-ignore
plugin={SelectorPack} />
<StoragePlugin
image={image}
onSaving={onSaving}
onSaved={onSaved}
onError={onError} />
</div>
)}
<div className="pointer-events-none">
<div className="absolute bottom-0 left-0 right-0 flex justify-center p-4">
<Toolbar
tool={tool}
onToolChange={setTool}/>
</div>
</div>
</main>
<aside className="border-l p-3 overflow-y-auto w-[340px]">
<EditorPanel
image={image}
onSaving={onSaving}
onSaved={onSaved}
onError={onError} />
</aside>
</Annotorious>
</div>
)
}