Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iiif structures #6162

Closed
wants to merge 13 commits into from
15 changes: 8 additions & 7 deletions common/model/iiif.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ export type IIIFCanvas = {
otherContent: any[];
};

export type IIIFStructure = {
'@id': string;
'@type': string;
label: string;
canvases: string[];
};

export type IIIFRendering = {
'@id': string;
format: string;
Expand Down Expand Up @@ -87,12 +94,6 @@ export type IIIFSequence = {
canvases: IIIFCanvas[];
rendering: IIIFRendering[];
};
type IIIFStructure = {
'@id': string;
'@type': string;
label: string;
canvases: string[];
};

export type IIIFMetadata = {
label: string;
Expand All @@ -108,7 +109,7 @@ export type AuthService = {
service: {
'@context': string;
'@id': string;
profile: string
profile: string;
}[];
};

Expand Down
5 changes: 5 additions & 0 deletions common/utils/iiif.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
IIIFRendering,
IIIFMetadata,
IIIFCanvas,
IIIFStructure,
IIIFMediaElement,
Service,
AuthService,
Expand Down Expand Up @@ -124,6 +125,10 @@ export function getCanvases(iiifManifest: IIIFManifest): IIIFCanvas[] {
return sequence ? sequence.canvases : [];
}

export function getStructures(iiifManifest: IIIFManifest): IIIFStructure[] {
return iiifManifest?.structures || [];
}

export function getVideo(
iiifManifest: IIIFManifest
): IIIFMediaElement | undefined {
Expand Down
79 changes: 60 additions & 19 deletions common/views/components/IIIFViewer/IIIFViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import {
isUiEnabled,
} from '@weco/common/utils/iiif';
import styled from 'styled-components';
import { useState, useEffect, useRef, FunctionComponent } from 'react';
import {
useState,
useEffect,
useRef,
FunctionComponent,
useContext,
} from 'react';
import { classNames } from '@weco/common/utils/classnames';
import Router from 'next/router';
import { iiifImageTemplate } from '@weco/common/utils/convert-image-uri';
Expand All @@ -25,14 +31,16 @@ import NoScriptViewer from './parts/NoScriptViewer';
import MainViewer from './parts/MainViewer';
import ThumbsViewer from './parts/ThumbsViewer';
import GridViewer from './parts/GridViewer';
import ExplorePanel from './parts/ExplorePanel';
import Control from '../Buttons/Control/Control';
import Layout12 from '@weco/common/views/components/Layout12/Layout12';

import Download from '@weco/catalogue/components/Download/Download';
import dynamic from 'next/dynamic';
import { DigitalLocation, Work } from '../../../model/catalogue';
import { FixedSizeList } from 'react-window';
import useSkipInitialEffect from '@weco/common/hooks/useSkipInitialEffect';
import PrototypeTabs from './parts/PrototypeTabs';
import TogglesContext from '@weco/common/views/components/TogglesContext/TogglesContext';

const LoadingComponent = () => (
<div
Expand Down Expand Up @@ -211,7 +219,8 @@ const IIIFViewerComponent: FunctionComponent<IIIFViewerProps> = ({
manifestIndex,
handleImageError,
}: IIIFViewerProps) => {
const [gridVisible, setGridVisible] = useState(false);
const { structuresPrototype } = useContext(TogglesContext);
const [explorePanelVisible, setExplorePanelVisible] = useState(false);
const [enhanced, setEnhanced] = useState(false);
const [parentManifest, setParentManifest] = useState<
IIIFManifest | undefined
Expand Down Expand Up @@ -281,7 +290,7 @@ const IIIFViewerComponent: FunctionComponent<IIIFViewerProps> = ({
}

useEffect(() => {
setGridVisible(!!Router.query.isOverview);
setExplorePanelVisible(!!Router.query.isOverview);
}, []);

useEffect(() => {
Expand Down Expand Up @@ -396,15 +405,15 @@ const IIIFViewerComponent: FunctionComponent<IIIFViewerProps> = ({
});

useEffect(() => {
if (gridVisible) {
if (explorePanelVisible) {
const thumb = gridViewerRef.current?.getElementsByClassName(
'activeThumbnail'
)?.[0] as HTMLButtonElement | undefined;
thumb?.focus();
} else {
viewToggleRef.current?.focus();
}
}, [gridVisible]);
}, [explorePanelVisible]);

useEffect(() => {
function handleResize() {
Expand All @@ -428,8 +437,8 @@ const IIIFViewerComponent: FunctionComponent<IIIFViewerProps> = ({
<ViewerTopBar
canvases={canvases}
enhanced={enhanced}
gridVisible={gridVisible}
setGridVisible={setGridVisible}
explorePanelVisible={explorePanelVisible}
setExplorePanelVisible={setExplorePanelVisible}
workId={workId}
viewToggleRef={viewToggleRef}
currentManifestLabel={currentManifestLabel}
Expand Down Expand Up @@ -545,19 +554,51 @@ const IIIFViewerComponent: FunctionComponent<IIIFViewerProps> = ({
)}
{mainImageService['@id'] && currentCanvas && (
<ViewerLayout isFullscreen={isFullscreen}>
<GridViewer
gridHeight={pageHeight}
gridWidth={pageWidth}
mainViewerRef={mainViewerRef}
gridVisible={gridVisible}
setGridVisible={setGridVisible}
activeIndex={activeIndex}
setActiveIndex={setActiveIndex}
canvases={canvases}
gridViewerRef={gridViewerRef}
<ExplorePanel
explorePanelVisible={explorePanelVisible}
isFullscreen={isFullscreen}
viewerRef={viewerRef}
/>
>
{structuresPrototype ? (
<PrototypeTabs
manifest={manifest}
mainViewerRef={mainViewerRef}
gridViewerRef={gridViewerRef}
GridView={
<GridViewer
gridHeight={pageHeight}
gridWidth={pageWidth}
mainViewerRef={mainViewerRef}
explorePanelVisible={explorePanelVisible}
setExplorePanelVisible={setExplorePanelVisible}
activeIndex={activeIndex}
setActiveIndex={setActiveIndex}
canvases={canvases}
gridViewerRef={gridViewerRef}
isFullscreen={isFullscreen}
viewerRef={viewerRef}
/>
}
setExplorePanelVisible={setExplorePanelVisible}
setActiveIndex={setActiveIndex}
pageHeight={pageHeight}
/>
) : (
<GridViewer
gridHeight={pageHeight}
gridWidth={pageWidth}
mainViewerRef={mainViewerRef}
explorePanelVisible={explorePanelVisible}
setExplorePanelVisible={setExplorePanelVisible}
activeIndex={activeIndex}
setActiveIndex={setActiveIndex}
canvases={canvases}
gridViewerRef={gridViewerRef}
isFullscreen={isFullscreen}
viewerRef={viewerRef}
/>
)}
</ExplorePanel>
{pageWidth >= 600 && (
<ThumbsViewer
canvases={canvases}
Expand Down
68 changes: 68 additions & 0 deletions common/views/components/IIIFViewer/parts/ExplorePanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import styled from 'styled-components';
import { useContext, RefObject, FunctionComponent, ReactNode } from 'react';
import {
headerHeight,
topBarHeight,
} from '@weco/common/views/components/IIIFViewer/IIIFViewer';
import GlobalInfoBarContext from '@weco/common/views/components/GlobalInfoBarContext/GlobalInfoBarContext';

type ExploreContainerProps = {
isVisible?: boolean;
isFullscreen?: boolean;
infoBarIsVisible?: boolean;
viewerRef: RefObject<HTMLElement>;
};

const ExploreContainer = styled.div<ExploreContainerProps>`
outline: none;
position: fixed;
top: ${props => {
const viewerOffset = props?.viewerRef?.current?.offsetTop || 0;

if (props.isVisible && props.isFullscreen) {
return `${topBarHeight}px`;
} else if (props.isVisible && !props.isFullscreen) {
if (props.infoBarIsVisible) {
return `${viewerOffset + topBarHeight}px`;
} else {
return `${headerHeight}px`;
}
} else {
return `100vh`;
}
}};
left: 0;
bottom: 0;
width: 100vw;
z-index: 1;
background: ${props => props.theme.color('viewerBlack')};
transition: top 500ms ease;
`;

type Props = {
explorePanelVisible: boolean;
isFullscreen: boolean;
viewerRef: RefObject<HTMLElement>;
children: ReactNode;
};

const ExplorePanel: FunctionComponent<Props> = ({
explorePanelVisible,
isFullscreen,
viewerRef,
children,
}: Props) => {
const { isVisible } = useContext(GlobalInfoBarContext);
return (
<ExploreContainer
isVisible={explorePanelVisible}
isFullscreen={isFullscreen}
infoBarIsVisible={isVisible}
viewerRef={viewerRef}
>
{children}
</ExploreContainer>
);
};

export default ExplorePanel;
Loading