Skip to content

Commit

Permalink
Altas #4 - Refactoring RelatedMedia to work with IIIF Collection mani…
Browse files Browse the repository at this point in the history
…fest
  • Loading branch information
dleadbetter committed Apr 2, 2024
1 parent 7bc064a commit efdc4b2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 41 deletions.
33 changes: 10 additions & 23 deletions packages/core-data/src/components/MediaGallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,28 @@

import * as Dialog from '@radix-ui/react-dialog';
import Viewer from '@samvera/clover-iiif/viewer';
import { Image, X } from 'lucide-react';
import { X } from 'lucide-react';
import React from 'react';
import type { MediaContent } from '../types/MediaContent';

type Props = {
/**
* The MediaContent record contain the IIIF manifest URL.
* URL of the IIIF manifest to render.
*/
defaultItem: MediaContent,
manifestUrl: string,

/**
* Callback fired when the dialog is closed.
*/
onClose: () => void,

/**
* Title text to display at the top of the dialog.
*/
title?: string
onClose: () => void
};

/**
* This component renders a IIIF Viewer for the passed MediaContent record.
*/
const MediaGallery = (props: Props) => (
<Dialog.Root
className='media-gallery'
open={props.manifestUrl}
onOpenChange={props.onClose}
open={Boolean(props.defaultItem)}
>
<Dialog.Portal>
<Dialog.Overlay
Expand All @@ -39,23 +32,16 @@ const MediaGallery = (props: Props) => (
<Dialog.Content
className='dialog-content'
>
<Dialog.Title
className='dialog-title flex items-center'
>
<Image
className='h-4 w-4 mr-1.5'
/>
{ props.title }
</Dialog.Title>
<div
className='pt-6 pb-2 text-sm w-full text-muted min-h-20'
>
{ Boolean(props.defaultItem) && (
{ props.manifestUrl && (
<Viewer
iiifContent={props.defaultItem.manifest_url}
iiifContent={props.manifestUrl}
options={{
informationPanel: {
open: false
open: false,
renderToggle: false
}
}}
/>
Expand All @@ -65,6 +51,7 @@ const MediaGallery = (props: Props) => (
asChild
>
<button
aria-label='Close'
className='dialog-close rounded-full'
type='button'
>
Expand Down
63 changes: 46 additions & 17 deletions packages/core-data/src/components/RelatedMedia.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
import { Thumbnail } from '@samvera/clover-iiif/primitives';
import React, { useState } from 'react';
import _ from 'underscore';
import type { MediaContent } from '../types/MediaContent';
import LoadAnimation from './LoadAnimation';
import MediaGallery from './MediaGallery';
import { useLoader } from '../hooks/CoreData';

type Props = {
/**
* A message to display when no records are returned from the API.
*/
emptyMessage?: string,

/**
* Callback fired when the component is mounted to fetch the data.
*/
Expand All @@ -31,30 +36,54 @@ const DEFAULT_THUMBNAIL_WIDTH = 80;
* This component renders the related Core Data media records as well as a gallery viewer.
*/
const RelatedMedia = (props: Props) => {
const [showGallery, setShowGallery] = useState<MediaContent>();
const [manifestUrl, setManifestUrl] = useState<string>();

const { data, loading } = useLoader(props.onLoad);

if (loading) {
return (
<LoadAnimation />
);
}

const { data } = useLoader(props.onLoad);
if (_.isEmpty(data?.items) && props.emptyMessage) {
return (
<div
className='pt-6 pl-3 pr-6 pb-8 flex items-center justify-center text-muted/50 italic'
>
{ props.emptyMessage }
</div>
);
}

return (
<div
className='p-3 pb-4 grid grid-cols-3 gap-1'
>
{ _.map(data?.items, (item) => (
<Thumbnail
key={item.body.id}
className='rounded shadow cursor-pointer'
onClick={() => setShowGallery(item.body)}
thumbnail={[{
id: item.body.content_thumbnail_url,
type: 'Image',
width: props.thumbnailWidth,
height: props.thumbnailHeight
}]}
/>
{ _.map(data?.items, ({ id, label: { en: label }, thumbnail }) => (
<div
className='flex flex-col gap-2'
key={id}
>
<Thumbnail
className='rounded shadow cursor-pointer'
onClick={() => setManifestUrl(id)}
thumbnail={_.map(thumbnail, (t) => ({
...t,
width: props.thumbnailWidth,
height: props.thumbnailHeight
}))}
/>
<div
className='text-sm whitespace-nowrap'
>
{ label }
</div>
</div>
))}
<MediaGallery
defaultItem={showGallery}
onClose={() => setShowGallery(undefined)}
manifestUrl={manifestUrl}
onClose={() => setManifestUrl(null)}
/>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/core-data/src/services/Places.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const fetchOne = (baseUrl, id, projectIds, params = {}) => {
* @returns {Promise<any>}
*/
const fetchRelatedMedia = (baseUrl, id, projectIds, params = {}) => {
const url = Api.buildNestedUrl(baseUrl, 'places', id, 'media_contents', projectIds, params);
const url = Api.buildNestedUrl(baseUrl, 'places', id, 'manifests', projectIds, params);
return fetch(url).then((response) => response.json());
};

Expand Down

0 comments on commit efdc4b2

Please sign in to comment.