Skip to content

Commit

Permalink
Merge pull request #147 from recogito/develop
Browse files Browse the repository at this point in the history
Merge develop into main for new release
  • Loading branch information
lwjameson authored Mar 11, 2024
2 parents 366a897 + f52b4d8 commit 9c86fcc
Show file tree
Hide file tree
Showing 201 changed files with 6,317 additions and 2,254 deletions.
1,283 changes: 752 additions & 531 deletions package-lock.json

Large diffs are not rendered by default.

20 changes: 14 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev --host",
"start": "astro dev",
"build": "astro build",
"build-node": "astro build --config astro.config.node.mjs",
"preview-node": "node ./dist/server/entry.mjs",
"astro": "astro"
},
"dependencies": {
"@annotorious/react": "^3.0.0-rc.18",
"@allmaps/iiif-parser": "^1.0.0-beta.33",
"@annotorious/react": "^3.0.0-rc.19",
"@astrojs/netlify": "^2.2.3",
"@astrojs/node": "^5.3.3",
"@astrojs/react": "^2.2.0",
Expand All @@ -22,17 +23,19 @@
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.4",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.6",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^1.2.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.3",
"@radix-ui/react-tooltip": "^1.0.7",
"@react-spring/web": "^9.7.3",
"@recogito/annotorious-supabase": "^3.0.0-rc.7",
"@recogito/react-pdf-annotator": "1.0.0-rc.7",
"@recogito/react-text-annotator": "^3.0.0-rc.10",
"@recogito/annotorious-supabase": "^1.0.0-rc.10",
"@recogito/react-pdf-annotator": "^1.0.0-rc.12",
"@recogito/react-text-annotator": "^3.0.0-rc.18",
"@supabase/auth-helpers-shared": "^0.3.4",
"@supabase/supabase-js": "^2.32.0",
"@table-library/react-table-library": "^4.1.7",
Expand All @@ -48,6 +51,7 @@
"eslint-plugin-react": "^7.33.2",
"formik": "^2.4.1",
"linkedom": "^0.15.6",
"manifesto.js": "^4.2.17",
"moment": "^2.29.4",
"openseadragon": "^3.1.0",
"papaparse": "^5.4.1",
Expand All @@ -59,6 +63,8 @@
"react-moment": "^1.1.3",
"react-quill": "^2.0.0",
"react-textarea-autosize": "^8.4.1",
"react-virtualized-auto-sizer": "^1.0.22",
"react-window": "^1.8.10",
"timeago-react": "^3.0.6",
"uuid": "^9.0.0"
},
Expand All @@ -70,10 +76,12 @@
"@types/papaparse": "^5.3.9",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
"@types/react-window": "^1.8.8",
"@types/uuid": "^9.0.1",
"@typescript-eslint/eslint-plugin": "^6.9.0",
"@typescript-eslint/parser": "^6.9.0",
"eslint": "^8.52.0",
"eslint-plugin-react": "^7.33.2"
"eslint-plugin-react": "^7.33.2",
"typescript": "^5.3.3"
}
}
File renamed without changes.
19 changes: 18 additions & 1 deletion src/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ export interface UserProfile {
avatar_url?: string;
}

export interface ExtendedUserProfile extends UserProfile {
email_address: string;
last_sign_in_at: string;
org_group_id: string;
org_group_name: string;
}

export type MyProfile = UserProfile & {
created_at: string;

Expand All @@ -32,6 +39,10 @@ export interface Project {
name: string;

description?: string;

is_open_join: boolean;

is_open_edit: boolean;
}

/**
Expand All @@ -53,6 +64,10 @@ export interface ExtendedProjectData {

description?: string;

is_open_join?: boolean;

is_open_edit?: boolean;

contexts: Context[];

layers: [
Expand Down Expand Up @@ -160,7 +175,7 @@ export const ContentTypes = [

export type ContentType = (typeof ContentTypes)[number];

export const Protocols = ['IIIF_IMAGE'] as const;
export const Protocols = ['IIIF_IMAGE', 'IIIF_PRESENTATION'] as const;

export type Protocol = (typeof Protocols)[number];

Expand All @@ -172,6 +187,8 @@ export interface Context {
description?: string;

project_id: string;

is_project_default: boolean;
}

export interface TaggedContext extends Context {
Expand Down
161 changes: 161 additions & 0 deletions src/apps/annotation-image/AnnotatedImage/AnnotatedImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { forwardRef, useMemo, useState } from 'react';
import type OpenSeadragon from 'openseadragon';
import { Annotation } from '@components/Annotation';
import { UndoStack } from '@components/AnnotationDesktop';
import { createAppearenceProvider } from '@components/Presence';
import type { PrivacyMode } from '@components/PrivacySelector';
import { SupabasePlugin } from '@components/SupabasePlugin';
import type { DocumentInTaggedContext, Layer, Policies, Translations } from 'src/Types';
import { Toolpanel } from '../Toolpanel';
import {
AnnotoriousOpenSeadragonAnnotator,
DrawingStyle,
ImageAnnotation,
OpenSeadragonAnnotator,
OpenSeadragonPopup,
OpenSeadragonViewer,
PointerSelectAction,
PresentUser,
useAnnotator
} from '@annotorious/react';

const SUPABASE: string = import.meta.env.PUBLIC_SUPABASE;

const SUPABASE_API_KEY: string = import.meta.env.PUBLIC_SUPABASE_API_KEY;

interface AnnotatedImageProps {

channelId: string;

defaultLayer?: Layer;

imageManifestURL: string;

isPresentationManifest?: boolean;

filter?: (a: ImageAnnotation) => boolean;

i18n: Translations;

layers?: Layer[];

policies: Policies;

present: PresentUser[];

style?: (a: ImageAnnotation) => DrawingStyle;

tagVocabulary: string[];

usePopup: boolean;

onChangePresent(present: PresentUser[]): void;

onConnectionError(): void;

onSaveError(): void;

onLoad(): void;

}

export const AnnotatedImage = forwardRef<OpenSeadragon.Viewer, AnnotatedImageProps>((props, ref) => {

const { i18n, policies, present, tagVocabulary } = props;

const anno = useAnnotator<AnnotoriousOpenSeadragonAnnotator>();

const [drawingEnabled, setDrawingEnabled] = useState(false);

const [tool, setTool] = useState<string>('rectangle');

const [privacy, setPrivacy] = useState<PrivacyMode>('PUBLIC');

const appearance = useMemo(() => createAppearenceProvider(), []);

const options: OpenSeadragon.Options = useMemo(() => ({
tileSources: props.imageManifestURL,
gestureSettingsMouse: {
clickToZoom: false
},
showNavigationControl: false,
crossOriginPolicy: 'Anonymous',
minZoomLevel: 0.4,
visibilityRatio: 0.2,
preserveImageSizeOnResize: true
}), [props.imageManifestURL]);

const selectAction = (annotation: ImageAnnotation) => {
// Annotation targets are editable for creators and admins
const me = anno?.getUser()?.id;

const canEdit = annotation.target.creator?.id === me ||
policies.get('layers').has('INSERT');

return canEdit ? PointerSelectAction.EDIT : PointerSelectAction.SELECT;
}

const onChangeTool = (tool: string | null) => {
if (tool) {
if (!drawingEnabled) setDrawingEnabled(true);
setTool(tool);
} else {
setDrawingEnabled(false);
}
}

return (
<OpenSeadragonAnnotator
autoSave
drawingEnabled={drawingEnabled}
pointerSelectAction={selectAction}
tool={tool}
filter={props.filter}
style={props.style}>

<UndoStack
undoEmpty={true} />

{props.layers &&
<SupabasePlugin
supabaseUrl={SUPABASE}
apiKey={SUPABASE_API_KEY}
channel={props.channelId}
defaultLayer={props.defaultLayer?.id}
layerIds={props.layers.map(layer => layer.id)}
appearanceProvider={appearance}
privacyMode={privacy === 'PRIVATE'}
source={props.isPresentationManifest ? props.imageManifestURL : undefined}
onInitialLoad={props.onLoad}
onPresence={props.onChangePresent}
onConnectError={props.onConnectionError}
onInitialLoadError={props.onConnectionError}
onSaveError={props.onSaveError} />
}

<OpenSeadragonViewer
ref={ref}
className="ia-osd-container"
options={options} />

{props.usePopup && (
<OpenSeadragonPopup
popup ={props => (
<Annotation.Popup
{...props}
i18n={i18n}
policies={policies}
present={present}
tagVocabulary={tagVocabulary} /> )} />
)}

<Toolpanel
i18n={i18n}
isAdmin={policies.get('layers').has('INSERT')}
privacy={privacy}
onChangeTool={onChangeTool}
onChangePrivacy={setPrivacy} />
</OpenSeadragonAnnotator>
)

});
1 change: 1 addition & 0 deletions src/apps/annotation-image/AnnotatedImage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AnnotatedImage';
21 changes: 21 additions & 0 deletions src/apps/annotation-image/IIIF/IIIFThumbnail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Resource } from 'manifesto.js';

interface IIIFThumnailProps {

image: Resource;

}

export const IIIFThumbnail = (props: IIIFThumnailProps) => {

const src = `${props.image.getServices()[0].id}/full/120,/0/default.jpg`;

return (
<div className="thumbnail-wrapper">
<div className="thumbnail">
<img src={src} />
</div>
</div>
)

}
43 changes: 43 additions & 0 deletions src/apps/annotation-image/IIIF/IIIFThumbnailStrip.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.ia-thumbnail-strip .thumbnail-strip-item {
align-items: center;
display: flex;
flex-direction: column;
font-size: var(--font-tiny);
}

.ia-thumbnail-strip .thumbnail-wrapper {
box-sizing: border-box;
cursor: pointer;
display: flex;
justify-content: center;
padding: 10px 10px 0px 10px;
width: 100%;
}

.ia-thumbnail-strip .thumbnail-strip-item .label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.ia-thumbnail-strip .thumbnail {
padding: 3px;
border-radius: calc(var(--border-radius) + 5px);
}

.ia-thumbnail-strip .thumbnail-strip-item.selected .thumbnail {
background-color: var(--brighter-blue);
}

.ia-thumbnail-strip .thumbnail:hover {
background-color: var(--gray-300);
}

.ia-thumbnail-strip .thumbnail img {
border: 2px solid #fff;
border-radius: calc(var(--border-radius) + 3px);
display: block;
height: 120px;
object-fit: cover;
width: 120px;
}
Loading

0 comments on commit 9c86fcc

Please sign in to comment.