Skip to content

Commit

Permalink
Demo Content State (Images)
Browse files Browse the repository at this point in the history
  • Loading branch information
mathewjordan committed Jan 2, 2025
1 parent 7162dd6 commit 99976ac
Show file tree
Hide file tree
Showing 8 changed files with 4,800 additions and 5,926 deletions.
38 changes: 33 additions & 5 deletions components/Clover/ViewerWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import Container from "../Shared/Container";
import { IconInfo } from "@/components/Shared/SVG/Icons";
import React from "react";
import { UserContext } from "@/context/user-context";
import type { Work } from "@nulib/dcapi-types";
import dynamic from "next/dynamic";

export const CloverViewer = dynamic(
Expand All @@ -23,14 +22,18 @@ export const CloverViewer = dynamic(
);

interface WrapperProps {
manifestId: Work["iiif_manifest"];
contentStateCallback?: (contentState: any) => void;
iiifContent?: string;
isWorkRestricted?: boolean;
manifestId: string | null;
viewerOptions?: ViewerConfigOptions;
}

const WorkViewerWrapper: React.FC<WrapperProps> = ({
manifestId,
contentStateCallback,
iiifContent,
isWorkRestricted,
manifestId,
viewerOptions = {},
}) => {
const userAuth = React.useContext(UserContext);
Expand Down Expand Up @@ -76,14 +79,39 @@ const WorkViewerWrapper: React.FC<WrapperProps> = ({
...viewerOptions,
};

function handleCanvasIdCallback(activeCanvas: string) {
if (activeCanvas && contentStateCallback) {
const contentStateAnnotationId = `${manifestId}/content-state}`;
const contentState = {
"@context": "http://iiif.io/api/presentation/3/context.json",
id: contentStateAnnotationId,
type: "Annotation",
motivation: ["contentState"],
target: {
id: activeCanvas,
type: "Canvas",
partOf: [
{
id: manifestId,
type: "Manifest",
},
],
},
};

contentStateCallback(JSON.stringify(contentState));
}
}

return (
<Container containerType="wide">
<ViewerWrapperStyled data-testid="work-viewer-wrapper">
{manifestId && (
<CloverViewer
// @ts-ignore
canvasIdCallback={handleCanvasIdCallback}
customTheme={customTheme}
iiifContent={manifestId}
iiifContent={iiifContent || manifestId}
options={options}
/>
)}
Expand All @@ -100,4 +128,4 @@ const WorkViewerWrapper: React.FC<WrapperProps> = ({
);
};

export default WorkViewerWrapper;
export default React.memo(WorkViewerWrapper);
1 change: 1 addition & 0 deletions components/Shared/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const SharedDialog: React.FC<SharedDialogProps> = ({
<DialogOverlay />
<DialogContent
onInteractOutside={handleCloseClick}
onEscapeKeyDown={handleCloseClick}
{...(size ? { size } : {})}
>
<DialogHeader>
Expand Down
47 changes: 47 additions & 0 deletions components/Shared/IIIF/ContentState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import CopyText from "@/components/Shared/CopyText";
import SharedDialog from "@/components/Shared/Dialog";
import { encodeContentState } from "@iiif/helpers";
import { useState } from "react";

interface IIIFContentStateProps {
contentState: any;
}

const IIIFContentState: React.FC<IIIFContentStateProps> = ({
contentState,
}) => {
const [isOpen, setIsOpen] = useState(false);

const title = "Demo Content State";

function handleClick() {
setIsOpen(true);
}

function close() {
setIsOpen(false);
}

const uri = new URL(window.location.href);
uri.searchParams.set("iiif-content", encodeContentState(contentState));
const shareUrl = uri.toString();

return (
<div>
<button onClick={handleClick}>{title}</button>
<SharedDialog
title={title}
handleCloseClick={close}
isOpen={isOpen}
size="small"
>
<>
<textarea style={{ width: "100%" }}>{contentState}</textarea>
<CopyText textPrompt="Share Current State" textToCopy={shareUrl} />
</>
</SharedDialog>
</div>
);
};

export default IIIFContentState;
8 changes: 7 additions & 1 deletion components/Work/TopInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { Button } from "@nulib/design-system";
import Card from "@/components/Shared/Card";
import { DefinitionListWrapper } from "@/components/Shared/DefinitionList.styled";
import Expand from "@/components/Shared/Expand/Expand";
import IIIFContentState from "../Shared/IIIF/ContentState";
import IIIFShare from "../Shared/IIIF/Share";
import { Manifest } from "@iiif/presentation-3";
import type { Work } from "@nulib/dcapi-types";
Expand All @@ -26,6 +27,7 @@ import type { WorkTypeCountMap } from "@/lib/collection-helpers";

interface TopInfoProps {
collectionWorkTypeCounts?: WorkTypeCountMap | null;
contentState?: any;
manifest?: Manifest;
work: Work;
}
Expand All @@ -36,6 +38,7 @@ export interface ActionsDialog {

const WorkTopInfo: React.FC<TopInfoProps> = ({
collectionWorkTypeCounts,
contentState,
manifest,
work,
}) => {
Expand Down Expand Up @@ -84,7 +87,10 @@ const WorkTopInfo: React.FC<TopInfoProps> = ({
/>
)}
</div>
<IIIFShare uri={manifest.id} />
<div>
{contentState && <IIIFContentState contentState={contentState} />}
<IIIFShare uri={manifest.id} />
</div>
</TopInfoHeaderContent>

<ActionButtons>
Expand Down
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
Loading

0 comments on commit 99976ac

Please sign in to comment.