@recogito/metaphor-annotation-plugin 0.0.11-beta.4 → 0.0.11-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pages/_components/ImageMetaphorView/ImageMetaphorView.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/ImageMetaphorView.js +9 -8
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/ListTab/ImageListCard.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/ListTab/ImageListCard.js +6 -2
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedArrowAnnotation.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedArrowAnnotation.js +6 -2
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedImageAnnotation.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedImageAnnotation.js +26 -3
- package/dist/pages/_components/ImageMetaphorView/components/ArrowToolbar/ArrowToolbar.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/ArrowToolbar/ArrowToolbar.js +6 -2
- package/dist/pages/_components/ImageMetaphorView/components/HoverTooltip/HoverTooltip.js +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/MetadataPanel/Contents.js +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/ShapeToolbar/ShapeToolbar.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/ShapeToolbar/ShapeToolbar.js +18 -3
- package/dist/pages/_components/ImageMetaphorView/components/image-panel.css +47 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/CurrentImage.d.ts +12 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/CurrentImage.d.ts.map +1 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/CurrentImage.js +7 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/RelationPreview.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/shared/RelationPreview.js +8 -6
- package/dist/pages/_components/ImageMetaphorView/components/shared/ShapeSnippet.d.ts +14 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/ShapeSnippet.d.ts.map +1 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/ShapeSnippet.js +55 -0
- package/dist/pages/_components/ImageMetaphorView/components/shared/index.d.ts +2 -1
- package/dist/pages/_components/ImageMetaphorView/components/shared/index.d.ts.map +1 -1
- package/dist/pages/_components/ImageMetaphorView/components/shared/index.js +2 -1
- package/dist/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.d.ts.map +1 -1
- package/dist/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.js +4 -2
- package/dist/pages/_components/shared/categoryColors.d.ts +9 -0
- package/dist/pages/_components/shared/categoryColors.d.ts.map +1 -0
- package/dist/pages/_components/shared/categoryColors.js +32 -0
- package/dist/pages/_components/shared/components/Conversation/Conversation.d.ts.map +1 -1
- package/dist/pages/_components/shared/components/Conversation/Conversation.js +2 -1
- package/dist/pages/_components/shared/i18n.js +1 -1
- package/locales/de/annotate-metaphor.json +142 -0
- package/locales/en/annotate-metaphor.json +142 -0
- package/package.json +5 -4
- package/dist/pages/_components/ImageMetaphorView/components/shared/colors.d.ts +0 -2
- package/dist/pages/_components/ImageMetaphorView/components/shared/colors.d.ts.map +0 -1
- package/dist/pages/_components/ImageMetaphorView/components/shared/colors.js +0 -17
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageMetaphorView.d.ts","sourceRoot":"","sources":["../../../../src/pages/_components/ImageMetaphorView/ImageMetaphorView.tsx"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,OAAO,EACb,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"ImageMetaphorView.d.ts","sourceRoot":"","sources":["../../../../src/pages/_components/ImageMetaphorView/ImageMetaphorView.tsx"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,OAAO,EACb,MAAM,sBAAsB,CAAC;AAoC9B,UAAU,sBAAsB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAElB,OAAO,EAAE,OAAO,CAAC;IAEjB,QAAQ,EAAE,QAAQ,CAAC;IAEnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAsCD,eAAO,MAAM,iBAAiB,GAAI,OAAO,sBAAsB,gCAgR9D,CAAC"}
|
|
@@ -20,6 +20,7 @@ import { AnnotationPanel, } from './components/AnnotationPanel';
|
|
|
20
20
|
import { ShapeToolbar } from './components/ShapeToolbar';
|
|
21
21
|
import { ImageArrows } from './components/ImageArrows';
|
|
22
22
|
import { HoverTooltip } from './components/HoverTooltip';
|
|
23
|
+
import { CurrentImageProvider } from './components/shared';
|
|
23
24
|
import { useMultiPagePresence } from './hooks';
|
|
24
25
|
import { ImageUndoStack } from './components/ImageUndoStack';
|
|
25
26
|
import { MetadataPanel } from './components/MetadataPanel';
|
|
@@ -87,11 +88,11 @@ export const ImageMetaphorView = (props) => {
|
|
|
87
88
|
cantaloupePath: CANTALOUPE_PATH,
|
|
88
89
|
getAccessToken,
|
|
89
90
|
});
|
|
90
|
-
// OSD tile source: the info.json URL for a IIIF image service, or
|
|
91
|
-
// image
|
|
91
|
+
// OSD tile source: the info.json URL for a IIIF image service, or an
|
|
92
|
+
// 'image' tile source for a static image.
|
|
92
93
|
const tilesource = useMemo(() => currentImage
|
|
93
94
|
? currentImage.type === 'static'
|
|
94
|
-
? currentImage.url
|
|
95
|
+
? { type: 'image', url: currentImage.url }
|
|
95
96
|
: currentImage.serviceUrl
|
|
96
97
|
: undefined, [currentImage]);
|
|
97
98
|
const [present, setPresent] = useState([]);
|
|
@@ -128,9 +129,9 @@ export const ImageMetaphorView = (props) => {
|
|
|
128
129
|
ajaxWithCredentials: authToken ? true : undefined,
|
|
129
130
|
};
|
|
130
131
|
}, [tilesource, authToken]);
|
|
131
|
-
return (_jsx(I18nextProvider, { i18n: clientI18next, children: !isIIIF ? (_jsx("div", { className: 'view-unsupported', children: clientI18next.t('This document type is not supported in this view.') })) : error ? (_jsx("div", { className: 'view-unsupported', children: error })) : activeLayer && tilesource ? (_jsx(AuthorColorProvider, { children: _jsx(Annotorious, { children: _jsx(FilterState, { children: _jsx(HideAllState, { children: _jsxs("div", { id: 'metaphor-image-root', children: [_jsx(MetadataPanel, { document: document, open: metadataOpen, onOpenChange: onMetadataOpenChange, canvases: canvases, currentCanvas: currentCanvas, image: image, manifest: manifest, authToken: authToken, onSelectCanvas: setCurrentCanvas, activeUsers: activeUsers }), _jsx("div", { id: 'main', children: _jsxs(OpenSeadragonAnnotator, { ref: annoRef, autoSave: true, disableUndoRedoKeys: true, tool: tool, drawingMode: 'drag', drawingEnabled: drawingEnabled && !isLocked, userSelectAction: selectAction, style: style, onInitError: (error) => console.error('[metaphor] OSD annotator init failed', error), children: [_jsx(EditorToolbar, { annotationsOpen: !!annotationTab, context: context, document: document, metadataOpen: metadataOpen, metadataOpenButtonRef: metadataOpenButtonRef, onMetadataOpenChange: onMetadataOpenChange, present: present, project: project, privacy: privacy, onChangePrivacy: setPrivacy, onAnnotationsOpenChange: (open) => setAnnotationTab(open ? 'list' : undefined), tools:
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
132
|
+
return (_jsx(I18nextProvider, { i18n: clientI18next, children: !isIIIF ? (_jsx("div", { className: 'view-unsupported', children: clientI18next.t('This document type is not supported in this view.') })) : error ? (_jsx("div", { className: 'view-unsupported', children: error })) : activeLayer && tilesource ? (_jsx(AuthorColorProvider, { children: _jsx(CurrentImageProvider, { image: currentImage, authToken: authToken, children: _jsx(Annotorious, { children: _jsx(FilterState, { children: _jsx(HideAllState, { children: _jsxs("div", { id: 'metaphor-image-root', children: [_jsx(MetadataPanel, { document: document, open: metadataOpen, onOpenChange: onMetadataOpenChange, canvases: canvases, currentCanvas: currentCanvas, image: image, manifest: manifest, authToken: authToken, onSelectCanvas: setCurrentCanvas, activeUsers: activeUsers }), _jsx("div", { id: 'main', children: _jsxs(OpenSeadragonAnnotator, { ref: annoRef, autoSave: true, disableUndoRedoKeys: true, tool: tool, drawingMode: 'drag', drawingEnabled: drawingEnabled && !isLocked, userSelectAction: selectAction, style: style, onInitError: (error) => console.error('[metaphor] OSD annotator init failed', error), children: [_jsx(EditorToolbar, { annotationsOpen: !!annotationTab, context: context, document: document, metadataOpen: metadataOpen, metadataOpenButtonRef: metadataOpenButtonRef, onMetadataOpenChange: onMetadataOpenChange, present: present, project: project, privacy: privacy, onChangePrivacy: setPrivacy, onAnnotationsOpenChange: (open) => setAnnotationTab(open ? 'list' : undefined), tools:
|
|
133
|
+
// no drawing tools in locked projects
|
|
134
|
+
!isLocked && (_jsx(Toolbar, { tool: tool, drawingEnabled: drawingEnabled, arrowsMode: arrowsMode, onChangeTool: setTool, onSetDrawingEnabled: setDrawingEnabled, onSetArrowsMode: setArrowsMode })), moreMenu: _jsx(ImageMoreTools, { privacy: privacy, arrowsVisibility: arrowsVisibility, onChangePrivacy: setPrivacy, onSetArrowsVisibility: setArrowsVisibility }) }), _jsx(OpenSeadragonViewer, { className: 'ia-osd-container', options: options }, currentCanvas?.id), _jsx(ImageUndoStack, {}), _jsx(SelectionURLState, { backButton: true }), _jsx(FilterAdapter, {}), layers.length > 0 && (_jsx(StorageAdapter, { activeLayer: activeLayer, channelId: channelId, layers: layers, onPresence: setPresent, onOffPageActivity: isMultiCanvas ? onPageActivity : undefined, onSelectionChange: isMultiCanvas && currentCanvas
|
|
135
|
+
? (user) => onPageActivity({ source: currentCanvas.id, user })
|
|
136
|
+
: undefined, privacyMode: privacy === 'private', source: isPresentationManifest ? currentCanvas?.id : undefined })), _jsx(OpenSeadragonHoverTooltip, { tooltip: (tooltipProps) => (_jsx(HoverTooltip, { annotation: tooltipProps.annotation })) }), _jsx(OpenSeadragonAnnotationPopup, { popup: (popupProps) => (_jsx(ShapeToolbar, { annotation: popupProps.annotation, editable: Boolean(popupProps.editable), onClickAdvanced: () => setAnnotationTab('selected') })) }), _jsx(AnnotoriousPlugin, { plugin: ToolsPlugin }), _jsx(AnnotoriousPlugin, { plugin: MagneticOutlinePlugin }), _jsx(ImageArrows, { mode: arrowsMode, visibility: arrowsVisibility })] }) }), _jsx(AnnotationPanel, { isLocked: isLocked, tab: annotationTab, onStateChange: setAnnotationTab })] }) }) }) }) }) })) : (_jsx("div", { className: 'spinner-container', children: _jsx(Spinner, { className: 'spinner', size: 32 }) })) }));
|
|
136
137
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageListCard.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/ListTab/ImageListCard.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ImageListCard.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/ListTab/ImageListCard.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,gCAAgC,CAAC;AAexC,UAAU,kBAAkB;IAC1B,UAAU,EAAE,kBAAkB,CAAC;IAE/B,QAAQ,EAAE,OAAO,CAAC;IAElB,SAAS,EAAE,OAAO,CAAC;IAEnB,WAAW,EAAE,OAAO,CAAC;IAErB,cAAc,IAAI,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,aAAa,GAAI,OAAO,kBAAkB,gCAgItD,CAAC"}
|
package/dist/pages/_components/ImageMetaphorView/components/AnnotationPanel/ListTab/ImageListCard.js
CHANGED
|
@@ -4,7 +4,8 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import { Visibility, } from '@recogito/annotorious-supabase';
|
|
5
5
|
import { ChatTeardropTextIcon, LockIcon } from '@phosphor-icons/react';
|
|
6
6
|
import { Avatar } from '@recogito/studio-sdk/components';
|
|
7
|
-
import {
|
|
7
|
+
import { RelationPreview, ShapeSnippet, useRelations } from '../../shared';
|
|
8
|
+
import { getCategoryColor, getCategoryTextColor } from '../../../../shared/categoryColors';
|
|
8
9
|
const timeAgo = (date, locale) => {
|
|
9
10
|
const rtf = new Intl.RelativeTimeFormat(locale || 'en', { numeric: 'auto' });
|
|
10
11
|
const mins = Math.round((date.getTime() - Date.now()) / 60000);
|
|
@@ -33,5 +34,8 @@ export const ImageListCard = (props) => {
|
|
|
33
34
|
]
|
|
34
35
|
.filter(Boolean)
|
|
35
36
|
.join(' ');
|
|
36
|
-
return (_jsxs("div", { className: cardClass, children: [_jsx("button", { type: 'button', className: 'unstyled list-card-select', "aria-pressed": props.selected, "aria-label": t('Select Annotation'), onClick: props.onToggleSelect }), _jsxs("div", { className: 'list-card-content', children: [
|
|
37
|
+
return (_jsxs("div", { className: cardClass, children: [_jsx("button", { type: 'button', className: 'unstyled list-card-select', "aria-pressed": props.selected, "aria-label": t('Select Annotation'), onClick: props.onToggleSelect }), _jsxs("div", { className: 'list-card-content', children: [_jsxs("div", { className: 'ia-list-card-header', children: [_jsx(ShapeSnippet, { annotation: annotation, size: 28 }), category ? (_jsx("div", { className: 'ia-list-card-category', style: {
|
|
38
|
+
backgroundColor: getCategoryColor(category),
|
|
39
|
+
color: getCategoryTextColor(category),
|
|
40
|
+
}, children: category })) : (_jsx("div", { className: 'ia-list-card-untitled', children: t('Untitled annotation') }))] }), properties.length > 0 && (_jsx("div", { className: 'list-card-tags', children: properties.map((body, idx) => (_jsxs("div", { className: 'list-card-tag', children: [_jsx("div", { className: 'list-card-tag-dot' }), _jsx("span", { children: body.value })] }, body.id || idx))) })), arrows.length > 0 && (_jsx("div", { className: 'ia-relation-list', children: arrows.map((arrow) => (_jsx(RelationPreview, { arrow: arrow, referenceAnnotationId: annotation.id }, arrow.id))) })), _jsxs("div", { className: 'list-card-footer', children: [_jsxs("div", { className: 'list-card-meta', children: [_jsx(Avatar, { id: creator?.id || 'unknown', name: creatorName, avatar: creator?.avatar, size: 'sm' }), _jsx("span", { className: 'list-card-author', children: creatorName }), _jsxs("span", { className: 'list-card-date', children: ["\u00B7 ", timeAgo(created, i18n.language)] })] }), _jsxs("div", { className: 'list-card-footer-actions', children: [commentCount > 0 && (_jsxs("span", { className: 'list-card-comments', children: [_jsx(ChatTeardropTextIcon, { size: 14, weight: 'bold', "aria-hidden": 'true' }), _jsx("span", { children: commentCount })] })), isPrivate && (_jsx("span", { className: 'list-card-private', title: t('Private'), children: _jsx(LockIcon, { size: 14, weight: 'bold' }) }))] })] })] })] }));
|
|
37
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectedArrowAnnotation.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedArrowAnnotation.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"SelectedArrowAnnotation.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedArrowAnnotation.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAIxE,UAAU,4BAA4B;IACpC,UAAU,EAAE,eAAe,CAAC;IAE5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,uBAAuB,GAAI,OAAO,4BAA4B,gCAwE1E,CAAC"}
|
|
@@ -3,7 +3,8 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { ShapesIcon, TrashIcon, XIcon } from '@phosphor-icons/react';
|
|
5
5
|
import { createBody, useAnnotationStore } from '@annotorious/react';
|
|
6
|
-
import {
|
|
6
|
+
import { RelationPreview, SetCategory } from '../../shared';
|
|
7
|
+
import { getCategoryColor, getCategoryTextColor } from '../../../../shared/categoryColors';
|
|
7
8
|
export const SelectedArrowAnnotation = (props) => {
|
|
8
9
|
const { t } = useTranslation();
|
|
9
10
|
const store = useAnnotationStore();
|
|
@@ -16,5 +17,8 @@ export const SelectedArrowAnnotation = (props) => {
|
|
|
16
17
|
store?.deleteBody(body);
|
|
17
18
|
};
|
|
18
19
|
const onDelete = () => store?.deleteAnnotation(props.annotation.id);
|
|
19
|
-
return (_jsxs("div", { className: 'ia-selected', children: [_jsx("div", { className: 'ia-selected-section', children: category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
20
|
+
return (_jsxs("div", { className: 'ia-selected', children: [_jsx("div", { className: 'ia-selected-section', children: category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
21
|
+
backgroundColor: getCategoryColor(category),
|
|
22
|
+
color: getCategoryTextColor(category),
|
|
23
|
+
}, children: [_jsx("span", { children: category }), props.editable && (_jsx("button", { className: 'unstyled icon-only', "aria-label": t('Clear class'), onClick: onClearCategory, children: _jsx(XIcon, {}) }))] })) : props.editable && (_jsx(SetCategory, { onSetCategory: onSetCategory, children: _jsxs("button", { className: 'ia-add-class', children: [_jsx(ShapesIcon, { size: 20 }), " ", t('Add class')] }) })) }), _jsx("div", { className: 'ia-selected-section', children: _jsx(RelationPreview, { arrow: props.annotation }) }), props.editable && (_jsx("div", { className: 'ia-selected-footer', children: _jsxs("button", { className: 'danger', onClick: onDelete, children: [_jsx(TrashIcon, {}), " ", t('Delete relation')] }) }))] }));
|
|
20
24
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectedImageAnnotation.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedImageAnnotation.tsx"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,oBAAoB,CAAC;AAgB5B,UAAU,4BAA4B;IACpC,UAAU,EAAE,eAAe,CAAC;IAE5B,QAAQ,EAAE,OAAO,CAAC;IAElB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,uBAAuB,GAAI,OAAO,4BAA4B,
|
|
1
|
+
{"version":3,"file":"SelectedImageAnnotation.d.ts","sourceRoot":"","sources":["../../../../../../../src/pages/_components/ImageMetaphorView/components/AnnotationPanel/SelectedTab/SelectedImageAnnotation.tsx"],"names":[],"mappings":"AASA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,oBAAoB,CAAC;AAgB5B,UAAU,4BAA4B;IACpC,UAAU,EAAE,eAAe,CAAC;IAE5B,QAAQ,EAAE,OAAO,CAAC;IAElB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,uBAAuB,GAAI,OAAO,4BAA4B,gCAyL1E,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useMemo } from 'react';
|
|
2
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { ArrowsLeftRightIcon, ChatsIcon, XIcon, ShapesIcon, TrashIcon, } from '@phosphor-icons/react';
|
|
5
5
|
import { createBody, useAnnotationStore, } from '@annotorious/react';
|
|
6
6
|
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Conversation, } from '../../../../shared/components';
|
|
7
|
-
import {
|
|
7
|
+
import { SetCategory, AddProperty, RelationPreview, useRelations, } from '../../shared';
|
|
8
|
+
import { getCategoryColor, getCategoryTextColor } from '../../../../shared/categoryColors';
|
|
8
9
|
export const SelectedImageAnnotation = (props) => {
|
|
9
10
|
const { t } = useTranslation();
|
|
10
11
|
const store = useAnnotationStore();
|
|
@@ -20,6 +21,28 @@ export const SelectedImageAnnotation = (props) => {
|
|
|
20
21
|
const onDeleteProperty = (body) => store?.deleteBody(body);
|
|
21
22
|
const onDelete = () => store?.deleteAnnotation(props.annotation.id);
|
|
22
23
|
const arrows = useRelations(props.annotation.id);
|
|
24
|
+
const [openAccordions, setOpenAccordions] = useState([]);
|
|
25
|
+
// Comment button: open the conversation and focus the reply input
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const onFocusConversation = (evt) => {
|
|
28
|
+
if (evt.detail !== props.annotation.id)
|
|
29
|
+
return;
|
|
30
|
+
setOpenAccordions((open) => open.includes('conversation') ? open : [...open, 'conversation']);
|
|
31
|
+
// wait for the accordion animation
|
|
32
|
+
setTimeout(() => {
|
|
33
|
+
const reply = document.getElementById('conversation-reply');
|
|
34
|
+
if (reply) {
|
|
35
|
+
reply.focus({ preventScroll: true });
|
|
36
|
+
reply.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
37
|
+
}
|
|
38
|
+
}, 350);
|
|
39
|
+
};
|
|
40
|
+
window.addEventListener('request-focus-conversation', onFocusConversation);
|
|
41
|
+
return () => window.removeEventListener('request-focus-conversation', onFocusConversation);
|
|
42
|
+
}, [props.annotation.id]);
|
|
23
43
|
const commentCount = useMemo(() => props.annotation.bodies.filter((b) => b.purpose === 'commenting' || b.purpose === 'replying').length, [props.annotation]);
|
|
24
|
-
return (_jsxs("div", { className: 'ia-selected', children: [_jsx("div", { className: 'ia-selected-section', children: category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
44
|
+
return (_jsxs("div", { className: 'ia-selected', children: [_jsx("div", { className: 'ia-selected-section', children: category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
45
|
+
backgroundColor: getCategoryColor(category),
|
|
46
|
+
color: getCategoryTextColor(category),
|
|
47
|
+
}, children: [_jsx("span", { children: category }), props.editable && (_jsx("button", { className: 'unstyled icon-only', "aria-label": t('Clear class'), onClick: onClearCategory, children: _jsx(XIcon, {}) }))] })) : props.editable && (_jsx(SetCategory, { onSetCategory: onSetCategory, children: _jsxs("button", { className: 'ia-add-class', children: [_jsx(ShapesIcon, { size: 20 }), " ", t('Add class')] }) })) }), _jsxs("div", { className: 'ia-selected-section', children: [_jsxs("div", { className: 'ia-section-header', children: [_jsx("span", { children: t('Properties') }), props.editable && _jsx(AddProperty, { onAddProperty: onAddProperty })] }), properties.length > 0 && (_jsx("ul", { className: 'ia-property-list', children: properties.map((body) => (_jsxs("li", { className: 'ia-property-pill', children: [body.value, props.editable && (_jsx("button", { className: 'unstyled icon-only', "aria-label": t('Remove property'), onClick: () => onDeleteProperty(body), children: _jsx(XIcon, {}) }))] }, body.id))) }))] }), _jsx("div", { className: 'ia-selected-section', children: _jsxs(Accordion, { type: 'multiple', value: openAccordions, onValueChange: setOpenAccordions, children: [_jsxs(AccordionItem, { value: 'relations', children: [_jsx(AccordionTrigger, { children: _jsxs("div", { className: 'accordion-trigger-layout', children: [_jsx(ArrowsLeftRightIcon, { weight: 'bold', size: 16, "aria-hidden": 'true' }), t('Relations'), arrows.length > 0 && (_jsx("span", { className: 'accordion-badge', children: arrows.length }))] }) }), _jsx(AccordionContent, { children: arrows.length > 0 ? (_jsx("div", { className: 'ia-relation-list', children: arrows.map((arrow) => (_jsx(RelationPreview, { arrow: arrow, referenceAnnotationId: props.annotation.id }, arrow.id))) })) : (_jsx("p", { className: 'ia-relations-empty', children: t('No relations') })) })] }), _jsxs(AccordionItem, { value: 'conversation', children: [_jsx(AccordionTrigger, { children: _jsxs("div", { className: 'accordion-trigger-layout', children: [_jsx(ChatsIcon, { weight: 'bold', size: 16, "aria-hidden": 'true' }), t('Conversation'), commentCount > 0 && (_jsx("span", { className: 'accordion-badge', children: commentCount }))] }) }), _jsx(AccordionContent, { children: _jsx(Conversation, { annotation: props.annotation, isLocked: props.isLocked }) })] })] }) }), props.editable && (_jsx("div", { className: 'ia-selected-footer', children: _jsxs("button", { className: 'danger', onClick: onDelete, children: [_jsx(TrashIcon, {}), " ", t('Delete annotation')] }) }))] }));
|
|
25
48
|
};
|
package/dist/pages/_components/ImageMetaphorView/components/ArrowToolbar/ArrowToolbar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ArrowToolbar.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/ArrowToolbar/ArrowToolbar.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"ArrowToolbar.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/ArrowToolbar/ArrowToolbar.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAKxE,eAAO,MAAM,YAAY,GAAI,OAAO,eAAe,uCAsGlD,CAAC"}
|
|
@@ -4,7 +4,8 @@ import { useTranslation } from 'react-i18next';
|
|
|
4
4
|
import * as Tooltip from '@radix-ui/react-tooltip';
|
|
5
5
|
import { TagIcon, TrashIcon, XIcon } from '@phosphor-icons/react';
|
|
6
6
|
import { createBody, useAnnotationStore, useSelection, } from '@annotorious/react';
|
|
7
|
-
import {
|
|
7
|
+
import { SetCategory } from '../shared';
|
|
8
|
+
import { getCategoryColor, getCategoryTextColor } from '../../../shared/categoryColors';
|
|
8
9
|
// Popup for a selected arrow (relation)
|
|
9
10
|
export const ArrowToolbar = (props) => {
|
|
10
11
|
const { t } = useTranslation();
|
|
@@ -23,5 +24,8 @@ export const ArrowToolbar = (props) => {
|
|
|
23
24
|
// Nothing to show or do for a read-only relation without a category
|
|
24
25
|
if (!editable && !category)
|
|
25
26
|
return null;
|
|
26
|
-
return (_jsx(Tooltip.Provider, { delayDuration: 300, children: _jsxs("div", { className: 'ia-shape-toolbar', children: [category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
27
|
+
return (_jsx(Tooltip.Provider, { delayDuration: 300, children: _jsxs("div", { className: 'ia-shape-toolbar', children: [category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
28
|
+
backgroundColor: getCategoryColor(category),
|
|
29
|
+
color: getCategoryTextColor(category),
|
|
30
|
+
}, children: [_jsx("span", { children: category }), editable && (_jsx("button", { className: 'unstyled icon-only', "aria-label": t('Clear class'), onClick: onClearCategory, children: _jsx(XIcon, {}) }))] })) : (_jsxs(Tooltip.Root, { children: [_jsx(SetCategory, { onSetCategory: onSetCategory, children: _jsx(Tooltip.Trigger, { asChild: true, children: _jsx("button", { className: 'compact', "aria-label": t('Add relationship tag'), children: _jsx(TagIcon, { size: 16 }) }) }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('Add relationship tag'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] })), editable && (_jsxs(_Fragment, { children: [_jsx("span", { className: 'ia-shape-toolbar-sep' }), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: _jsx("button", { className: 'compact', "aria-label": t('Delete relation'), onClick: onDelete, children: _jsx(TrashIcon, { size: 16 }) }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('Delete relation'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] })] }))] }) }));
|
|
27
31
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { isArrowAnnotation } from '@annotorious/plugin-arrows-react';
|
|
3
|
-
import { getCategoryColor } from '
|
|
3
|
+
import { getCategoryColor } from '../../../shared/categoryColors';
|
|
4
4
|
/**
|
|
5
5
|
* Tooltip for the hovered annotation on the image: shows the category (if
|
|
6
6
|
* any), tinted with the category color (except for arrow annotations).
|
|
@@ -32,5 +32,5 @@ export const Contents = (props) => {
|
|
|
32
32
|
}
|
|
33
33
|
return [];
|
|
34
34
|
}, [props.canvases, props.currentCanvas, props.image, props.documentName, props.activeUsers, i18n.language]);
|
|
35
|
-
return (_jsx("ul", { className: 'ia-canvas-list', children: items.map((item) => (_jsx("li", { children: _jsxs("button", { type: 'button', className: `unstyled ia-canvas-item${item.current ? ' is-current' : ''}`, "aria-current": item.current ? 'true' : undefined, onClick: item.onSelect, children: [_jsxs("span", { className: 'ia-canvas-thumb', children: [_jsx(IIIFThumbnail, { url: item.url, authToken: props.authToken, fallback: _jsx(ImageIcon, { size: 28, weight: 'thin', "aria-hidden": 'true' }) }), item.activeUsers.length > 0 && (_jsx("ul", { className: 'ia-canvas-activity', "aria-label": t('Users active on this page'), children: item.activeUsers.slice(0, 10).map((user) => (_jsx("li", { title: user.name || t('Anonymous'), style: { backgroundColor: user.appearance.color }, children: _jsx("span", { children: user.name || t('Anonymous') }) }, user.presenceKey))) }))] }), _jsx("span", { className: 'ia-canvas-label', children: item.label })] }) }, item.key))) }));
|
|
35
|
+
return (_jsx("ul", { className: 'ia-canvas-list', children: items.map((item) => (_jsx("li", { children: _jsxs("button", { type: 'button', className: `unstyled ia-canvas-item${item.current ? ' is-current' : ''}`, "aria-current": item.current ? 'true' : undefined, onClick: item.onSelect, children: [_jsxs("span", { className: 'ia-canvas-thumb', children: [_jsx(IIIFThumbnail, { url: item.url, authToken: props.authToken, fallback: _jsx(ImageIcon, { size: 28, weight: 'thin', "aria-hidden": 'true' }) }), item.activeUsers.length > 0 && (_jsx("ul", { className: 'ia-canvas-activity', "aria-label": t('Users active on this page'), children: item.activeUsers.slice(0, 10).map((user) => (_jsx("li", { title: user.name || t('Anonymous', { ns: 'annotation-common' }), style: { backgroundColor: user.appearance.color }, children: _jsx("span", { children: user.name || t('Anonymous', { ns: 'annotation-common' }) }) }, user.presenceKey))) }))] }), _jsx("span", { className: 'ia-canvas-label', children: item.label })] }) }, item.key))) }));
|
|
36
36
|
};
|
package/dist/pages/_components/ImageMetaphorView/components/ShapeToolbar/ShapeToolbar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ShapeToolbar.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/ShapeToolbar/ShapeToolbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ShapeToolbar.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/ShapeToolbar/ShapeToolbar.tsx"],"names":[],"mappings":"AAUA,OAAO,EAGL,KAAK,eAAe,EAErB,MAAM,oBAAoB,CAAC;AAI5B,UAAU,iBAAiB;IACzB,UAAU,EAAE,eAAe,CAAC;IAG5B,QAAQ,EAAE,OAAO,CAAC;IAElB,eAAe,IAAI,IAAI,CAAC;CACzB;AAED,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,gCAuJpD,CAAC"}
|
|
@@ -2,9 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import * as Tooltip from '@radix-ui/react-tooltip';
|
|
5
|
-
import { TagIcon, TrashIcon,
|
|
5
|
+
import { ChatTeardropTextIcon, DotsThreeIcon, TagIcon, TrashIcon, XIcon, } from '@phosphor-icons/react';
|
|
6
6
|
import { createBody, useAnnotationStore, } from '@annotorious/react';
|
|
7
|
-
import {
|
|
7
|
+
import { SetCategory } from '../shared';
|
|
8
|
+
import { getCategoryColor, getCategoryTextColor } from '../../../shared/categoryColors';
|
|
8
9
|
export const ShapeToolbar = (props) => {
|
|
9
10
|
const { t } = useTranslation();
|
|
10
11
|
const store = useAnnotationStore();
|
|
@@ -16,5 +17,19 @@ export const ShapeToolbar = (props) => {
|
|
|
16
17
|
store?.deleteBody(body);
|
|
17
18
|
};
|
|
18
19
|
const onDelete = () => store?.deleteAnnotation(props.annotation.id);
|
|
19
|
-
|
|
20
|
+
const commentCount = useMemo(() => props.annotation.bodies.filter((b) => b.purpose === 'commenting' || b.purpose === 'replying').length, [props.annotation]);
|
|
21
|
+
// Open the Selected tab, then ask it to open + focus the conversation
|
|
22
|
+
const onComment = () => {
|
|
23
|
+
props.onClickAdvanced();
|
|
24
|
+
// small delay, so the Selected tab is mounted
|
|
25
|
+
setTimeout(() => {
|
|
26
|
+
window.dispatchEvent(new CustomEvent('request-focus-conversation', {
|
|
27
|
+
detail: props.annotation.id,
|
|
28
|
+
}));
|
|
29
|
+
}, 100);
|
|
30
|
+
};
|
|
31
|
+
return (_jsx(Tooltip.Provider, { delayDuration: 300, children: _jsxs("div", { className: 'ia-shape-toolbar', children: [category ? (_jsxs("div", { className: 'ia-category-chip', style: {
|
|
32
|
+
backgroundColor: getCategoryColor(category),
|
|
33
|
+
color: getCategoryTextColor(category),
|
|
34
|
+
}, children: [_jsx("span", { children: category }), props.editable && (_jsx("button", { className: 'unstyled icon-only', "aria-label": t('Clear class'), onClick: onClearCategory, children: _jsx(XIcon, {}) }))] })) : props.editable && (_jsxs(Tooltip.Root, { children: [_jsx(SetCategory, { onSetCategory: onSetCategory, children: _jsx(Tooltip.Trigger, { asChild: true, children: _jsx("button", { className: 'compact', "aria-label": t('Add concept tag'), children: _jsx(TagIcon, { size: 16 }) }) }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('Add concept tag'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] })), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: _jsxs("div", { className: 'toolbar-btn-wrapper', children: [_jsx("button", { className: 'compact', "aria-label": t('Comment'), onClick: onComment, children: _jsx(ChatTeardropTextIcon, { size: 16 }) }), commentCount > 0 && (_jsx("span", { className: 'toolbar-badge text-body-tiny', children: commentCount }))] }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('Comment'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] }), props.editable && (_jsxs(_Fragment, { children: [_jsx("span", { className: 'ia-shape-toolbar-sep' }), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: _jsx("button", { className: 'compact', "aria-label": t('Delete annotation'), onClick: onDelete, children: _jsx(TrashIcon, { size: 16 }) }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('Delete annotation'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] })] })), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: _jsx("button", { className: 'compact', "aria-label": t('More'), onClick: props.onClickAdvanced, children: _jsx(DotsThreeIcon, { size: 16 }) }) }), _jsx(Tooltip.Portal, { children: _jsxs(Tooltip.Content, { className: 'tooltip-content', sideOffset: 6, children: [t('More'), _jsx(Tooltip.Arrow, { className: 'tooltip-arrow' })] }) })] })] }) }));
|
|
20
35
|
};
|
|
@@ -211,6 +211,8 @@
|
|
|
211
211
|
.ia-set-category-form input {
|
|
212
212
|
flex: 1 1 auto;
|
|
213
213
|
min-width: 0;
|
|
214
|
+
font-family: inherit;
|
|
215
|
+
font-size: var(--font-tiny);
|
|
214
216
|
}
|
|
215
217
|
|
|
216
218
|
/* RelationPreview */
|
|
@@ -345,3 +347,48 @@
|
|
|
345
347
|
.ia-hover-tooltip span {
|
|
346
348
|
position: relative;
|
|
347
349
|
}
|
|
350
|
+
|
|
351
|
+
/* Annotation region thumbnail */
|
|
352
|
+
.ia-shape-snippet {
|
|
353
|
+
display: inline-block;
|
|
354
|
+
flex-shrink: 0;
|
|
355
|
+
overflow: hidden;
|
|
356
|
+
border-radius: 4px;
|
|
357
|
+
background-color: var(--gray-100);
|
|
358
|
+
background-repeat: no-repeat;
|
|
359
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.ia-shape-snippet img {
|
|
363
|
+
display: block;
|
|
364
|
+
width: 100%;
|
|
365
|
+
height: 100%;
|
|
366
|
+
object-fit: cover;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.ia-list-card-header {
|
|
370
|
+
display: flex;
|
|
371
|
+
align-items: stretch;
|
|
372
|
+
gap: 6px;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
.ia-list-card-header .ia-list-card-untitled {
|
|
376
|
+
align-self: center;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
.ia-relation-end {
|
|
380
|
+
position: relative;
|
|
381
|
+
z-index: 2;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
.ia-snippet-tooltip {
|
|
385
|
+
padding: 4px;
|
|
386
|
+
border-radius: 8px;
|
|
387
|
+
background-color: #fff;
|
|
388
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
389
|
+
z-index: 1000;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.ia-snippet-tooltip .ia-shape-snippet {
|
|
393
|
+
display: block;
|
|
394
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { CozyImageResource } from 'cozy-iiif';
|
|
3
|
+
interface CurrentImageContextValue {
|
|
4
|
+
image?: CozyImageResource;
|
|
5
|
+
authToken?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const CurrentImageProvider: (props: CurrentImageContextValue & {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}) => import("react").JSX.Element;
|
|
10
|
+
export declare const useCurrentImage: () => CurrentImageContextValue;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=CurrentImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CurrentImage.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/CurrentImage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnD,UAAU,wBAAwB;IAChC,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAMD,eAAO,MAAM,oBAAoB,GAC/B,OAAO,wBAAwB,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,gCAO1D,CAAC;AAEF,eAAO,MAAM,eAAe,gCAAwC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from 'react';
|
|
3
|
+
const CurrentImageContext = createContext({});
|
|
4
|
+
// The image shown in the viewer (and its auth token, for uploaded images), so
|
|
5
|
+
// that components can crop annotation snippets out of it
|
|
6
|
+
export const CurrentImageProvider = (props) => (_jsx(CurrentImageContext.Provider, { value: { image: props.image, authToken: props.authToken }, children: props.children }));
|
|
7
|
+
export const useCurrentImage = () => useContext(CurrentImageContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RelationPreview.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/RelationPreview.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RelationPreview.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/RelationPreview.tsx"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,kCAAkC,CAAC;AAS1C,UAAU,oBAAoB;IAC5B,KAAK,EAAE,eAAe,CAAC;IAIvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,OAAO,oBAAoB,gCAyE1D,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
|
-
import
|
|
4
|
+
import * as Tooltip from '@radix-ui/react-tooltip';
|
|
5
|
+
import { useAnnotation, } from '@annotorious/react';
|
|
5
6
|
import { isArrowAnchor, } from '@annotorious/plugin-arrows-react';
|
|
6
|
-
import { getCategoryColor } from '
|
|
7
|
+
import { getCategoryColor } from '../../../shared/categoryColors';
|
|
8
|
+
import { ShapeSnippet } from './ShapeSnippet';
|
|
7
9
|
const getCategory = (annotation) => annotation?.bodies.find((b) => b.purpose === 'classifying')?.value;
|
|
8
10
|
/**
|
|
9
11
|
* Compact "A ⇢ B" pill for a relation (arrow) between annotations, after
|
|
@@ -23,12 +25,12 @@ export const RelationPreview = (props) => {
|
|
|
23
25
|
if (!annotation)
|
|
24
26
|
return _jsx("span", { className: 'ia-relation-end ia-relation-end-point' });
|
|
25
27
|
const endCategory = getCategory(annotation);
|
|
26
|
-
return (_jsxs("span", { className: 'ia-relation-end', children: [_jsx("span", { className: 'ia-relation-dot', style: endCategory
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
return (_jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { asChild: true, children: _jsxs("span", { className: 'ia-relation-end', children: [_jsx("span", { className: 'ia-relation-dot', style: endCategory
|
|
29
|
+
? { backgroundColor: getCategoryColor(endCategory) }
|
|
30
|
+
: undefined }), _jsx("span", { className: endCategory ? undefined : 'ia-relation-untitled', children: endCategory || t('Untitled') })] }) }), _jsx(Tooltip.Portal, { children: _jsx(Tooltip.Content, { className: 'ia-snippet-tooltip', side: 'top', sideOffset: 6, children: _jsx(ShapeSnippet, { annotation: annotation, size: 96 }) }) })] }));
|
|
29
31
|
};
|
|
30
32
|
const [left, right] = isOutgoing
|
|
31
33
|
? [startAnnotation, endAnnotation]
|
|
32
34
|
: [endAnnotation, startAnnotation];
|
|
33
|
-
return (_jsxs("div", { className: 'ia-relation-preview', children: [renderEnd(left), _jsx("span", { className: `ia-relation-line ${isOutgoing ? 'outgoing' : 'incoming'}`, "aria-label": isOutgoing ? t('links to') : t('linked from'), children: category && _jsx("span", { className: 'ia-relation-category', children: category }) }), renderEnd(right)] }));
|
|
35
|
+
return (_jsx(Tooltip.Provider, { delayDuration: 100, children: _jsxs("div", { className: 'ia-relation-preview', children: [renderEnd(left), _jsx("span", { className: `ia-relation-line ${isOutgoing ? 'outgoing' : 'incoming'}`, "aria-label": isOutgoing ? t('links to') : t('linked from'), children: category && _jsx("span", { className: 'ia-relation-category', children: category }) }), renderEnd(right)] }) }));
|
|
34
36
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ImageAnnotation } from '@annotorious/react';
|
|
2
|
+
interface ShapeSnippetProps {
|
|
3
|
+
annotation: ImageAnnotation;
|
|
4
|
+
size: number;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Thumbnail of an annotation's region (its bounding box), cropped out of the
|
|
9
|
+
* current image. IIIF images use an Image API region request, static images
|
|
10
|
+
* are cropped via CSS.
|
|
11
|
+
*/
|
|
12
|
+
export declare const ShapeSnippet: (props: ShapeSnippetProps) => import("react").JSX.Element | null;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=ShapeSnippet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShapeSnippet.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/ShapeSnippet.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA6B1D,UAAU,iBAAiB;IACzB,UAAU,EAAE,eAAe,CAAC;IAE5B,IAAI,EAAE,MAAM,CAAC;IAEb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,uCAkDpD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { IIIFThumbnail, useAuthImageSrc } from '@recogito/studio-sdk/components';
|
|
4
|
+
import { useCurrentImage } from './CurrentImage';
|
|
5
|
+
// Requested pixel width of the cropped region (enough for 2x displays)
|
|
6
|
+
const REQUEST_WIDTH = 200;
|
|
7
|
+
const getRegion = (annotation, width, height) => {
|
|
8
|
+
const bounds = annotation.target?.selector?.geometry?.bounds;
|
|
9
|
+
if (!bounds)
|
|
10
|
+
return;
|
|
11
|
+
// Clamp to the image, so the image server doesn't reject the region
|
|
12
|
+
const x = Math.max(0, Math.floor(bounds.minX));
|
|
13
|
+
const y = Math.max(0, Math.floor(bounds.minY));
|
|
14
|
+
const maxX = width ? Math.min(width, Math.ceil(bounds.maxX)) : Math.ceil(bounds.maxX);
|
|
15
|
+
const maxY = height ? Math.min(height, Math.ceil(bounds.maxY)) : Math.ceil(bounds.maxY);
|
|
16
|
+
const w = maxX - x;
|
|
17
|
+
const h = maxY - y;
|
|
18
|
+
return w > 0 && h > 0 ? { x, y, w, h } : undefined;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Thumbnail of an annotation's region (its bounding box), cropped out of the
|
|
22
|
+
* current image. IIIF images use an Image API region request, static images
|
|
23
|
+
* are cropped via CSS.
|
|
24
|
+
*/
|
|
25
|
+
export const ShapeSnippet = (props) => {
|
|
26
|
+
const { image, authToken } = useCurrentImage();
|
|
27
|
+
const region = useMemo(() => image && getRegion(props.annotation, image.width, image.height), [image, props.annotation]);
|
|
28
|
+
// Level-1 compatible: region by pixels + size by width
|
|
29
|
+
const regionUrl = useMemo(() => {
|
|
30
|
+
if (!image || image.type !== 'dynamic' || !region)
|
|
31
|
+
return;
|
|
32
|
+
const width = Math.min(REQUEST_WIDTH, region.w);
|
|
33
|
+
const service = image.serviceUrl.replace(/\/info\.json$/, '').replace(/\/$/, '');
|
|
34
|
+
return `${service}/${region.x},${region.y},${region.w},${region.h}/${width},/0/default.jpg`;
|
|
35
|
+
}, [image, region]);
|
|
36
|
+
const staticUrl = image?.type === 'static' ? image.url : undefined;
|
|
37
|
+
const { src: staticSrc } = useAuthImageSrc(staticUrl, authToken);
|
|
38
|
+
const style = { width: props.size, height: props.size };
|
|
39
|
+
const className = ['ia-shape-snippet', props.className].filter(Boolean).join(' ');
|
|
40
|
+
if (regionUrl)
|
|
41
|
+
return (_jsx("span", { className: className, style: style, children: _jsx(IIIFThumbnail, { url: regionUrl, authToken: authToken }) }));
|
|
42
|
+
// Static image: show the full image, scaled and offset so the region covers the box
|
|
43
|
+
if (staticSrc && region && image?.width && image?.height) {
|
|
44
|
+
const scale = props.size / Math.min(region.w, region.h);
|
|
45
|
+
const offsetX = (props.size - region.w * scale) / 2 - region.x * scale;
|
|
46
|
+
const offsetY = (props.size - region.h * scale) / 2 - region.y * scale;
|
|
47
|
+
return (_jsx("span", { className: className, style: {
|
|
48
|
+
...style,
|
|
49
|
+
backgroundImage: `url(${staticSrc})`,
|
|
50
|
+
backgroundSize: `${image.width * scale}px ${image.height * scale}px`,
|
|
51
|
+
backgroundPosition: `${offsetX}px ${offsetY}px`,
|
|
52
|
+
} }));
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from './colors';
|
|
2
1
|
export * from './SetCategory';
|
|
3
2
|
export * from './AddProperty';
|
|
4
3
|
export * from './RelationPreview';
|
|
5
4
|
export * from './useRelations';
|
|
5
|
+
export * from './CurrentImage';
|
|
6
|
+
export * from './ShapeSnippet';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC"}
|
package/dist/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorCodingState.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAkB,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ColorCodingState.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,EAAkB,KAAK,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAKhE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAIpE,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAC;IAE1B,0BAA0B,EAAE,MAAM,CAAC;IAEnC,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAGD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAWlD,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;CAC9B;AAKD,UAAU,uBAAuB;IAC/B,MAAM,EAAE,WAAW,CAAC;IAEpB,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAErC,KAAK,EAAE,UAAU,CAAC;IAElB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAElC,QAAQ,CAAC,UAAU,EAAE,aAAa,GAAG,KAAK,CAAC;IAE3C,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAKD,UAAU,qBAAqB;IAC7B,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,gCA+D5D,CAAC;AAEF,eAAO,MAAM,cAAc,+BAAuC,CAAC"}
|
package/dist/pages/_components/TeiMetaphorView/components/ColorCodingState/ColorCodingState.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useContext, useMemo, useState, } from 'react';
|
|
3
3
|
import { useAnnotations } from '@annotorious/react';
|
|
4
|
-
import {
|
|
4
|
+
import { enumerateTags, getTags, } from '@recogito/studio-sdk';
|
|
5
5
|
import { getAnnotationType } from '../../utils';
|
|
6
|
+
import { getCategoryColor } from '../../../shared/categoryColors';
|
|
6
7
|
// themes for 'by-type' color coding
|
|
7
8
|
export const THEMES = {
|
|
8
9
|
ORANGE: {
|
|
@@ -29,7 +30,8 @@ export const ColorCodingState = (props) => {
|
|
|
29
30
|
const { getColor, legend } = useMemo(() => {
|
|
30
31
|
// 'by-tag': mapped from palette by first tag
|
|
31
32
|
if (coding === 'by-tag') {
|
|
32
|
-
|
|
33
|
+
// Stable per-tag colors
|
|
34
|
+
const palette = { getColor: (label) => getCategoryColor(label) };
|
|
33
35
|
const legend = tags.map((tag) => ({
|
|
34
36
|
label: tag.label,
|
|
35
37
|
color: palette.getColor(tag.label),
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color for a category (or tag) label. Derived from the label itself, so the
|
|
3
|
+
* same category gets the same color for everyone, on every load, in both
|
|
4
|
+
* views - unlike assigning palette colors in first-seen order.
|
|
5
|
+
*/
|
|
6
|
+
export declare const getCategoryColor: (label: string) => string;
|
|
7
|
+
/** Text color (white or near-black) with the better contrast on the category color */
|
|
8
|
+
export declare const getCategoryTextColor: (label: string) => string;
|
|
9
|
+
//# sourceMappingURL=categoryColors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"categoryColors.d.ts","sourceRoot":"","sources":["../../../../src/pages/_components/shared/categoryColors.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,MAAM,KAAG,MACV,CAAC;AAYxC,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,GAAI,OAAO,MAAM,KAAG,MAKpD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AdobeCategorical12 } from '@recogito/studio-sdk';
|
|
2
|
+
const PALETTE = AdobeCategorical12;
|
|
3
|
+
// FNV-1a: small, fast, stable string hash
|
|
4
|
+
const hash = (str) => {
|
|
5
|
+
let h = 0x811c9dc5;
|
|
6
|
+
for (let i = 0; i < str.length; i++) {
|
|
7
|
+
h ^= str.charCodeAt(i);
|
|
8
|
+
h = Math.imul(h, 0x01000193);
|
|
9
|
+
}
|
|
10
|
+
return h >>> 0;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Color for a category (or tag) label. Derived from the label itself, so the
|
|
14
|
+
* same category gets the same color for everyone, on every load, in both
|
|
15
|
+
* views - unlike assigning palette colors in first-seen order.
|
|
16
|
+
*/
|
|
17
|
+
export const getCategoryColor = (label) => PALETTE[hash(label) % PALETTE.length];
|
|
18
|
+
const luminance = (hex) => {
|
|
19
|
+
const [r, g, b] = [1, 3, 5].map((i) => {
|
|
20
|
+
const c = parseInt(hex.slice(i, i + 2), 16) / 255;
|
|
21
|
+
return c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
|
|
22
|
+
});
|
|
23
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
24
|
+
};
|
|
25
|
+
const DARK_TEXT = '#1a1a1a';
|
|
26
|
+
/** Text color (white or near-black) with the better contrast on the category color */
|
|
27
|
+
export const getCategoryTextColor = (label) => {
|
|
28
|
+
const bg = luminance(getCategoryColor(label));
|
|
29
|
+
const onWhite = 1.05 / (bg + 0.05);
|
|
30
|
+
const onDark = (bg + 0.05) / (luminance(DARK_TEXT) + 0.05);
|
|
31
|
+
return onWhite >= onDark ? '#ffffff' : DARK_TEXT;
|
|
32
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/shared/components/Conversation/Conversation.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAO5B,UAAU,iBAAiB;IACzB,UAAU,EAAE,UAAU,CAAC;IAGvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,
|
|
1
|
+
{"version":3,"file":"Conversation.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/shared/components/Conversation/Conversation.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,oBAAoB,CAAC;AAO5B,UAAU,iBAAiB;IACzB,UAAU,EAAE,UAAU,CAAC;IAGvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,YAAY,GAAI,OAAO,iBAAiB,gCAyGpD,CAAC"}
|
|
@@ -36,6 +36,7 @@ export const Conversation = (props) => {
|
|
|
36
36
|
store.updateAnnotation(updated);
|
|
37
37
|
setReplyText('');
|
|
38
38
|
};
|
|
39
|
+
const replyPlaceholder = comments.length === 0 ? t('Add a comment...') : t('Add a reply...');
|
|
39
40
|
const onKeyDown = (e) => {
|
|
40
41
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
41
42
|
e.preventDefault();
|
|
@@ -51,5 +52,5 @@ export const Conversation = (props) => {
|
|
|
51
52
|
}).format(comment.created)
|
|
52
53
|
: t('Unknown date');
|
|
53
54
|
return (_jsxs("div", { className: 'annotation-section conversation-section', children: [_jsx("div", { className: 'annotation-header', children: _jsx("div", { className: 'annotation-header-left', children: _jsxs("div", { className: 'conversation-meta', children: [_jsx(Avatar, { id: comment.creator?.id || 'default', name: authorName, avatar: comment.creator?.avatar, size: 'sm' }), _jsx("span", { className: 'author', children: authorName }), _jsxs("span", { className: 'date', children: ["\u00B7 ", dateStr] })] }) }) }), _jsx(Comment, { children: comment.value })] }, comment.id));
|
|
54
|
-
}), !props.isLocked && (_jsx("div", { className: 'conversation-reply-area', children: _jsxs("div", { className: 'conversation-reply-wrapper', children: [_jsx("textarea", { id: 'conversation-reply', className: 'conversation-reply-input', placeholder:
|
|
55
|
+
}), !props.isLocked && (_jsx("div", { className: 'conversation-reply-area', children: _jsxs("div", { className: 'conversation-reply-wrapper', children: [_jsx("textarea", { id: 'conversation-reply', className: 'conversation-reply-input', placeholder: replyPlaceholder, "aria-label": replyPlaceholder, value: replyText, onChange: (e) => setReplyText(e.target.value), onKeyDown: onKeyDown }), _jsx(Button, { className: 'unstyled conversation-reply-submit', onClick: onReplySubmit, disabled: !replyText.trim(), "aria-label": t('Save reply'), children: _jsx(ArrowRightIcon, { size: 18, "aria-hidden": 'true' }) })] }) }))] }));
|
|
55
56
|
};
|
|
@@ -14,7 +14,7 @@ clientI18next
|
|
|
14
14
|
.init({
|
|
15
15
|
fallbackLng: i18n?.defaultLocale || 'en',
|
|
16
16
|
supportedLngs: i18n?.locales || ['en'],
|
|
17
|
-
ns: ['common', 'project-assignments', 'annotate-metaphor'],
|
|
17
|
+
ns: ['common', 'annotation-common', 'project-assignments', 'annotate-metaphor'],
|
|
18
18
|
defaultNS: 'annotate-metaphor',
|
|
19
19
|
backend: {
|
|
20
20
|
loadPath: '/locales/{{lng}}/{{ns}}.json',
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Account": "Konto",
|
|
3
|
+
"Add": "Hinzufügen",
|
|
4
|
+
"Add a comment...": "Kommentar schreiben...",
|
|
5
|
+
"Add class": "Klasse hinzufügen",
|
|
6
|
+
"Add concept tag": "Konzept-Tag hinzufügen",
|
|
7
|
+
"Add property": "Eigenschaft hinzufügen",
|
|
8
|
+
"Add relationship tag": "Beziehungs-Tag hinzufügen",
|
|
9
|
+
"All": "Alle",
|
|
10
|
+
"All annotations": "Alle Annotationen",
|
|
11
|
+
"Add a reply...": "Antwort hinzufügen...",
|
|
12
|
+
"Add or extend span": "Markierung erweitern oder hinzufügen",
|
|
13
|
+
"Analysis": "Analyse",
|
|
14
|
+
"Annotation visibility": "Sichtbarkeit der Annotationen",
|
|
15
|
+
"Annotations": "Annotationen",
|
|
16
|
+
"Annotations you create in Private mode will be visible to no-one except you.": "Annotationen die Du im privaten Modus erstellst sind nur für Dich sichtbar.",
|
|
17
|
+
"Author": "Autor",
|
|
18
|
+
"Box": "Box",
|
|
19
|
+
"By annotation type": "Nach Annotationstyp",
|
|
20
|
+
"By first tag": "Nach erstem Tag",
|
|
21
|
+
"annotationsCount_one": "{{count}} Annotation",
|
|
22
|
+
"annotationsCount_other": "{{count}} Annotationen",
|
|
23
|
+
"Clear class": "Klasse entfernen",
|
|
24
|
+
"Close annotation panel": "Annotations-Panel schließen",
|
|
25
|
+
"Close navigation/metadata panel": "Navigations-/Metadaten-Panel schließen",
|
|
26
|
+
"Close sidebar": "Seitenleiste schließen",
|
|
27
|
+
"Collections": "Sammlungen",
|
|
28
|
+
"Color theme": "Farbschema",
|
|
29
|
+
"Comment": "Kommentar",
|
|
30
|
+
"Comments": "Kommentare",
|
|
31
|
+
"Contents": "Inhalt",
|
|
32
|
+
"Conversation": "Unterhaltung",
|
|
33
|
+
"Created": "Erstellt",
|
|
34
|
+
"Current viewport": "Im sichtbaren Bereich",
|
|
35
|
+
"Cyan": "Cyan",
|
|
36
|
+
"Delete annotation": "Annotation löschen",
|
|
37
|
+
"Delete relation": "Beziehung löschen",
|
|
38
|
+
"Delete tag": "Tag löschen",
|
|
39
|
+
"Direct": "Direkt",
|
|
40
|
+
"Document": "Dokument",
|
|
41
|
+
"Document navigation and metadata": "Dokumentnavigation und Metadaten",
|
|
42
|
+
"Draw arrows": "Pfeile zeichnen",
|
|
43
|
+
"Edit word": "Wort bearbeiten",
|
|
44
|
+
"Ellipse": "Ellipse",
|
|
45
|
+
"Enter concept": "Konzept eingeben",
|
|
46
|
+
"Filter": "Filter",
|
|
47
|
+
"Help": "Hilfe",
|
|
48
|
+
"Hide all annotations": "Alle Annotationen ausblenden",
|
|
49
|
+
"Hide relations": "Beziehungen ausblenden",
|
|
50
|
+
"Highlight Style": "Markierungsstil",
|
|
51
|
+
"Indirect": "Indirekt",
|
|
52
|
+
"Info": "Info",
|
|
53
|
+
"Jobs": "Jobs",
|
|
54
|
+
"Link all intersecting words to this metaphor": "Alle überschneidenden Wörter mit dieser Metapher verknüpfen",
|
|
55
|
+
"Language": "Sprache",
|
|
56
|
+
"linked from": "verknüpft von",
|
|
57
|
+
"Linked Words": "Verknüpfte Wörter",
|
|
58
|
+
"links to": "verknüpft mit",
|
|
59
|
+
"List": "Liste",
|
|
60
|
+
"Manifest": "Manifest",
|
|
61
|
+
"Mark as Metaphor": "Als Metapher markieren",
|
|
62
|
+
"Mark as Metaphor-Related Word": "Als Metaphor-Related Word markieren",
|
|
63
|
+
"Metadata": "Metadaten",
|
|
64
|
+
"Metaphor": "Metapher",
|
|
65
|
+
"Metaphor Annotation View": "Metaphor Annotation View",
|
|
66
|
+
"Metaphor-Related Word": "Metaphor-Related Word",
|
|
67
|
+
"More": "Mehr",
|
|
68
|
+
"More tools": "Weitere Werkzeuge",
|
|
69
|
+
"Move & select": "Bewegen & auswählen",
|
|
70
|
+
"MRW Type": "MRW-Typ",
|
|
71
|
+
"Name": "Name",
|
|
72
|
+
"No annotations in the current view": "Keine Annotationen im sichtbaren Bereich",
|
|
73
|
+
"No annotations yet": "Noch keine Annotationen",
|
|
74
|
+
"No document metadata available.": "Keine Dokumentmetadaten verfügbar.",
|
|
75
|
+
"No intersecting annotations": "Keine überschneidenden Annotationen",
|
|
76
|
+
"No relations": "Keine Beziehungen",
|
|
77
|
+
"No tags yet": "Noch keine Tags",
|
|
78
|
+
"No users yet": "Noch keine Benutzer",
|
|
79
|
+
"Open in Metaphor Annotation View": "In Metaphor Annotation View öffnen",
|
|
80
|
+
"Open or close annotation panel": "Annotations-Panel öffnen oder schließen",
|
|
81
|
+
"Open or close metadata panel": "Metadaten-Panel öffnen oder schließen",
|
|
82
|
+
"Orange": "Orange",
|
|
83
|
+
"Organization Admin": "Organisationsadmin",
|
|
84
|
+
"Page {{n}}": "Seite {{n}}",
|
|
85
|
+
"Path": "Pfad",
|
|
86
|
+
"Polygon": "Polygon",
|
|
87
|
+
"Private": "Privat",
|
|
88
|
+
"Private annotations only": "Nur private Annotationen",
|
|
89
|
+
"Profile Settings": "Profileinstellungen",
|
|
90
|
+
"Properties": "Eigenschaften",
|
|
91
|
+
"Property": "Eigenschaft",
|
|
92
|
+
"Public": "Öffentlich",
|
|
93
|
+
"Public annotations are visible to anyone with access to this document. This may include invited users or the general public.": "Öffentliche Annotationen sind für alle Benutzer sichtbar, die Zugriff auf dieses Dokument haben.",
|
|
94
|
+
"Public annotations only": "Nur öffentliche Annotationen",
|
|
95
|
+
"Re-select & replace span": "Markierung neu auswählen und ersetzen",
|
|
96
|
+
"Read less": "Weniger anzeigen",
|
|
97
|
+
"Read more": "Mehr anzeigen",
|
|
98
|
+
"Redo": "Wiederherstellen",
|
|
99
|
+
"Relations": "Beziehungen",
|
|
100
|
+
"Remove property": "Eigenschaft entfernen",
|
|
101
|
+
"Rotate clockwise": "Im Uhrzeigersinn drehen",
|
|
102
|
+
"Rotate counter-clockwise": "Gegen den Uhrzeigersinn drehen",
|
|
103
|
+
"Save reply": "Antwort speichern",
|
|
104
|
+
"Scissors": "Kontur-Schere",
|
|
105
|
+
"Search tags...": "Tags suchen...",
|
|
106
|
+
"Select all intersecting words": "Alle überschneidenden Wörter auswählen",
|
|
107
|
+
"Select an annotation": "Annotation auswählen",
|
|
108
|
+
"Select Annotation": "Annotation auswählen",
|
|
109
|
+
"Select annotation type": "Annotationstyp auswählen",
|
|
110
|
+
"Select highlight style": "Markierungsstil auswählen",
|
|
111
|
+
"Select MRW type": "MRW-Typ auswählen",
|
|
112
|
+
"Select MRW type...": "MRW-Typ auswählen...",
|
|
113
|
+
"Select shape": "Form auswählen",
|
|
114
|
+
"Selected": "Auswahl",
|
|
115
|
+
"Settings": "Einstellungen",
|
|
116
|
+
"Shift": "Umschalt",
|
|
117
|
+
"Show all": "Alle anzeigen",
|
|
118
|
+
"Sign out": "Abmelden",
|
|
119
|
+
"Site Administration": "Administration",
|
|
120
|
+
"Source": "Quelle",
|
|
121
|
+
"Sort ascending": "Aufsteigend sortieren",
|
|
122
|
+
"Sort descending": "Absteigend sortieren",
|
|
123
|
+
"Text": "Text",
|
|
124
|
+
"Text order": "Textreihenfolge",
|
|
125
|
+
"This document type is not supported in this view.": "Dieser Dokumenttyp wird in dieser Ansicht nicht unterstützt.",
|
|
126
|
+
"Title": "Titel",
|
|
127
|
+
"Toggle sort direction": "Sortierrichtung umschalten",
|
|
128
|
+
"Type": "Typ",
|
|
129
|
+
"Undo": "Rückgängig",
|
|
130
|
+
"Unknown": "Unbekannt",
|
|
131
|
+
"Unknown date": "Unbekanntes Datum",
|
|
132
|
+
"Unknown User": "Unbekannter Benutzer",
|
|
133
|
+
"Untitled": "Ohne Titel",
|
|
134
|
+
"Untitled annotation": "Annotation ohne Titel",
|
|
135
|
+
"Updated": "Aktualisiert",
|
|
136
|
+
"Users": "Benutzer",
|
|
137
|
+
"Users active on this page": "Aktive Benutzer auf dieser Seite",
|
|
138
|
+
"Visibility": "Sichtbarkeit",
|
|
139
|
+
"Word": "Wort",
|
|
140
|
+
"Zoom in": "Vergrößern",
|
|
141
|
+
"Zoom out": "Verkleinern"
|
|
142
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
{
|
|
2
|
+
"Account": "Account",
|
|
3
|
+
"Add": "Add",
|
|
4
|
+
"Add a comment...": "Add a comment...",
|
|
5
|
+
"Add class": "Add class",
|
|
6
|
+
"Add concept tag": "Add concept tag",
|
|
7
|
+
"Add property": "Add property",
|
|
8
|
+
"Add relationship tag": "Add relationship tag",
|
|
9
|
+
"All": "All",
|
|
10
|
+
"All annotations": "All annotations",
|
|
11
|
+
"Add a reply...": "Add a reply...",
|
|
12
|
+
"Add or extend span": "Add or extend span",
|
|
13
|
+
"Analysis": "Analysis",
|
|
14
|
+
"Annotation visibility": "Annotation visibility",
|
|
15
|
+
"Annotations": "Annotations",
|
|
16
|
+
"Annotations you create in Private mode will be visible to no-one except you.": "Annotations you create in Private mode will be visible to no-one except you.",
|
|
17
|
+
"Author": "Author",
|
|
18
|
+
"Box": "Box",
|
|
19
|
+
"By annotation type": "By annotation type",
|
|
20
|
+
"By first tag": "By first tag",
|
|
21
|
+
"annotationsCount_one": "{{count}} Annotation",
|
|
22
|
+
"annotationsCount_other": "{{count}} Annotations",
|
|
23
|
+
"Clear class": "Clear class",
|
|
24
|
+
"Close annotation panel": "Close annotation panel",
|
|
25
|
+
"Close navigation/metadata panel": "Close navigation/metadata panel",
|
|
26
|
+
"Close sidebar": "Close sidebar",
|
|
27
|
+
"Collections": "Collections",
|
|
28
|
+
"Color theme": "Color theme",
|
|
29
|
+
"Comment": "Comment",
|
|
30
|
+
"Comments": "Comments",
|
|
31
|
+
"Contents": "Contents",
|
|
32
|
+
"Conversation": "Conversation",
|
|
33
|
+
"Created": "Created",
|
|
34
|
+
"Current viewport": "Current viewport",
|
|
35
|
+
"Cyan": "Cyan",
|
|
36
|
+
"Delete annotation": "Delete annotation",
|
|
37
|
+
"Delete relation": "Delete relation",
|
|
38
|
+
"Delete tag": "Delete tag",
|
|
39
|
+
"Direct": "Direct",
|
|
40
|
+
"Document": "Document",
|
|
41
|
+
"Document navigation and metadata": "Document navigation and metadata",
|
|
42
|
+
"Draw arrows": "Draw arrows",
|
|
43
|
+
"Edit word": "Edit word",
|
|
44
|
+
"Ellipse": "Ellipse",
|
|
45
|
+
"Enter concept": "Enter concept",
|
|
46
|
+
"Filter": "Filter",
|
|
47
|
+
"Help": "Help",
|
|
48
|
+
"Hide all annotations": "Hide all annotations",
|
|
49
|
+
"Hide relations": "Hide relations",
|
|
50
|
+
"Highlight Style": "Highlight Style",
|
|
51
|
+
"Indirect": "Indirect",
|
|
52
|
+
"Info": "Info",
|
|
53
|
+
"Jobs": "Jobs",
|
|
54
|
+
"Link all intersecting words to this metaphor": "Link all intersecting words to this metaphor",
|
|
55
|
+
"Language": "Language",
|
|
56
|
+
"linked from": "linked from",
|
|
57
|
+
"Linked Words": "Linked Words",
|
|
58
|
+
"links to": "links to",
|
|
59
|
+
"List": "List",
|
|
60
|
+
"Manifest": "Manifest",
|
|
61
|
+
"Mark as Metaphor": "Mark as Metaphor",
|
|
62
|
+
"Mark as Metaphor-Related Word": "Mark as Metaphor-Related Word",
|
|
63
|
+
"Metadata": "Metadata",
|
|
64
|
+
"Metaphor": "Metaphor",
|
|
65
|
+
"Metaphor Annotation View": "Metaphor Annotation View",
|
|
66
|
+
"Metaphor-Related Word": "Metaphor-Related Word",
|
|
67
|
+
"More": "More",
|
|
68
|
+
"More tools": "More tools",
|
|
69
|
+
"Move & select": "Move & select",
|
|
70
|
+
"MRW Type": "MRW Type",
|
|
71
|
+
"Name": "Name",
|
|
72
|
+
"No annotations in the current view": "No annotations in the current view",
|
|
73
|
+
"No annotations yet": "No annotations yet",
|
|
74
|
+
"No document metadata available.": "No document metadata available.",
|
|
75
|
+
"No intersecting annotations": "No intersecting annotations",
|
|
76
|
+
"No relations": "No relations",
|
|
77
|
+
"No tags yet": "No tags yet",
|
|
78
|
+
"No users yet": "No users yet",
|
|
79
|
+
"Open in Metaphor Annotation View": "Open in Metaphor Annotation View",
|
|
80
|
+
"Open or close annotation panel": "Open or close annotation panel",
|
|
81
|
+
"Open or close metadata panel": "Open or close metadata panel",
|
|
82
|
+
"Orange": "Orange",
|
|
83
|
+
"Organization Admin": "Organization Admin",
|
|
84
|
+
"Page {{n}}": "Page {{n}}",
|
|
85
|
+
"Path": "Path",
|
|
86
|
+
"Polygon": "Polygon",
|
|
87
|
+
"Private": "Private",
|
|
88
|
+
"Private annotations only": "Private annotations only",
|
|
89
|
+
"Profile Settings": "Profile Settings",
|
|
90
|
+
"Properties": "Properties",
|
|
91
|
+
"Property": "Property",
|
|
92
|
+
"Public": "Public",
|
|
93
|
+
"Public annotations are visible to anyone with access to this document. This may include invited users or the general public.": "Public annotations are visible to anyone with access to this document. This may include invited users or the general public.",
|
|
94
|
+
"Public annotations only": "Public annotations only",
|
|
95
|
+
"Re-select & replace span": "Re-select & replace span",
|
|
96
|
+
"Read less": "Read less",
|
|
97
|
+
"Read more": "Read more",
|
|
98
|
+
"Redo": "Redo",
|
|
99
|
+
"Relations": "Relations",
|
|
100
|
+
"Remove property": "Remove property",
|
|
101
|
+
"Rotate clockwise": "Rotate clockwise",
|
|
102
|
+
"Rotate counter-clockwise": "Rotate counter-clockwise",
|
|
103
|
+
"Save reply": "Save reply",
|
|
104
|
+
"Scissors": "Scissors",
|
|
105
|
+
"Search tags...": "Search tags...",
|
|
106
|
+
"Select all intersecting words": "Select all intersecting words",
|
|
107
|
+
"Select an annotation": "Select an annotation",
|
|
108
|
+
"Select Annotation": "Select Annotation",
|
|
109
|
+
"Select annotation type": "Select annotation type",
|
|
110
|
+
"Select highlight style": "Select highlight style",
|
|
111
|
+
"Select MRW type": "Select MRW type",
|
|
112
|
+
"Select MRW type...": "Select MRW type...",
|
|
113
|
+
"Select shape": "Select shape",
|
|
114
|
+
"Selected": "Selected",
|
|
115
|
+
"Settings": "Settings",
|
|
116
|
+
"Shift": "Shift",
|
|
117
|
+
"Show all": "Show all",
|
|
118
|
+
"Sign out": "Sign out",
|
|
119
|
+
"Site Administration": "Site Administration",
|
|
120
|
+
"Source": "Source",
|
|
121
|
+
"Sort ascending": "Sort ascending",
|
|
122
|
+
"Sort descending": "Sort descending",
|
|
123
|
+
"Text": "Text",
|
|
124
|
+
"Text order": "Text order",
|
|
125
|
+
"This document type is not supported in this view.": "This document type is not supported in this view.",
|
|
126
|
+
"Title": "Title",
|
|
127
|
+
"Toggle sort direction": "Toggle sort direction",
|
|
128
|
+
"Type": "Type",
|
|
129
|
+
"Undo": "Undo",
|
|
130
|
+
"Unknown": "Unknown",
|
|
131
|
+
"Unknown date": "Unknown date",
|
|
132
|
+
"Unknown User": "Unknown User",
|
|
133
|
+
"Untitled": "Untitled",
|
|
134
|
+
"Untitled annotation": "Untitled annotation",
|
|
135
|
+
"Updated": "Updated",
|
|
136
|
+
"Users": "Users",
|
|
137
|
+
"Users active on this page": "Users active on this page",
|
|
138
|
+
"Visibility": "Visibility",
|
|
139
|
+
"Word": "Word",
|
|
140
|
+
"Zoom in": "Zoom in",
|
|
141
|
+
"Zoom out": "Zoom out"
|
|
142
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@recogito/metaphor-annotation-plugin",
|
|
3
|
-
"version": "0.0.11-beta.
|
|
3
|
+
"version": "0.0.11-beta.7",
|
|
4
4
|
"description": "A plugin that adds the Metaphor Annotation View, a custom annotation view route for TEI documents",
|
|
5
5
|
"homepage": "https://github.com/recogito/metaphor-annotation-plugin#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"type": "module",
|
|
14
14
|
"files": [
|
|
15
|
-
"dist"
|
|
15
|
+
"dist",
|
|
16
|
+
"locales"
|
|
16
17
|
],
|
|
17
18
|
"main": "./dist/index.js",
|
|
18
19
|
"module": "./dist/index.js",
|
|
@@ -40,10 +41,10 @@
|
|
|
40
41
|
"typescript": "^5.9.3"
|
|
41
42
|
},
|
|
42
43
|
"peerDependencies": {
|
|
43
|
-
"@annotorious/react": "^3.9.
|
|
44
|
+
"@annotorious/react": "^3.9.5",
|
|
44
45
|
"@recogito/annotorious-supabase": "^1.6.0",
|
|
45
46
|
"@recogito/react-text-annotator": "^4.3.4",
|
|
46
|
-
"@recogito/studio-sdk": "^0.
|
|
47
|
+
"@recogito/studio-sdk": "^0.13.0",
|
|
47
48
|
"react": ">=19.x",
|
|
48
49
|
"react-dom": ">=19.x"
|
|
49
50
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../../../../src/pages/_components/ImageMetaphorView/components/shared/colors.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,gBAAgB,GAAI,UAAU,MAAM,WAOhD,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
const PALETTE = [
|
|
2
|
-
'#c026d3',
|
|
3
|
-
'#fb923c',
|
|
4
|
-
'#a16207',
|
|
5
|
-
'#65a30d',
|
|
6
|
-
'#0891b2',
|
|
7
|
-
'#7c3aed',
|
|
8
|
-
];
|
|
9
|
-
const assigned = new Map();
|
|
10
|
-
export const getCategoryColor = (category) => {
|
|
11
|
-
const existing = assigned.get(category);
|
|
12
|
-
if (existing)
|
|
13
|
-
return existing;
|
|
14
|
-
const next = PALETTE[assigned.size % PALETTE.length];
|
|
15
|
-
assigned.set(category, next);
|
|
16
|
-
return next;
|
|
17
|
-
};
|