From bf663064dc1ad389ea3a69e09976a1d8963c0aec Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Tue, 17 Dec 2024 07:14:35 -0800 Subject: [PATCH 1/4] Add the current locale to a context for the workspace and companion windows --- src/components/AppProviders.js | 21 ++-- src/components/CompanionWindow.js | 157 ++++++++++++++++-------------- src/contexts/LocaleContext.js | 5 + 3 files changed, 99 insertions(+), 84 deletions(-) create mode 100644 src/contexts/LocaleContext.js diff --git a/src/components/AppProviders.js b/src/components/AppProviders.js index 541b7480e9..514fc41af9 100644 --- a/src/components/AppProviders.js +++ b/src/components/AppProviders.js @@ -14,6 +14,7 @@ import { CacheProvider } from '@emotion/react'; import createCache from '@emotion/cache'; import createI18nInstance from '../i18n'; import FullScreenContext from '../contexts/FullScreenContext'; +import LocaleContext from '../contexts/LocaleContext'; /** * Allow applications to opt-out of (or provide their own) drag and drop context @@ -119,15 +120,17 @@ export function AppProviders({ return ( - - - - - {children} - - - - + + + + + + {children} + + + + + ); diff --git a/src/components/CompanionWindow.js b/src/components/CompanionWindow.js index cf03de3af3..b558f1d7ac 100644 --- a/src/components/CompanionWindow.js +++ b/src/components/CompanionWindow.js @@ -1,5 +1,6 @@ /* eslint-disable react/require-default-props */ import { Children, cloneElement, forwardRef } from 'react'; +import { useSelector } from 'react-redux'; import PropTypes from 'prop-types'; import { styled } from '@mui/material/styles'; import CloseIcon from '@mui/icons-material/CloseSharp'; @@ -14,6 +15,8 @@ import { useElementSize } from '@custom-react-hooks/use-element-size'; import mergeRefs from 'merge-refs'; import MiradorMenuButton from '../containers/MiradorMenuButton'; import ns from '../config/css-ns'; +import LocaleContext from '../contexts/LocaleContext'; +import { getCompanionWindowLocale } from '../state/selectors/companionWindows'; const Root = styled(Paper, { name: 'CompanionWindow', slot: 'root' })({}); const StyledToolbar = styled(Toolbar, { name: 'CompanionWindow', slot: 'toolbar' })({}); @@ -29,12 +32,13 @@ const StyledCloseButton = styled(MiradorMenuButton, { name: 'CompanionWindow', s */ export const CompanionWindow = forwardRef((props, innerRef) => { const { - ariaLabel = undefined, classes = {}, direction, paperClassName = '', onCloseClick = () => {}, updateCompanionWindow = undefined, isDisplayed = false, + ariaLabel = undefined, classes = {}, direction, id, paperClassName = '', onCloseClick = () => {}, updateCompanionWindow = undefined, isDisplayed = false, position = null, title = null, children = undefined, titleControls = null, defaultSidebarPanelWidth = 235, defaultSidebarPanelHeight = 201, } = props; const [sizeRef, size] = useElementSize(); const { t } = useTranslation(); + const locale = useSelector(state => getCompanionWindowLocale(state, { companionWindowId: id }), [id]); /** */ const openInNewStyle = direction === 'rtl' ? { transform: 'scale(-1, 1)' } : {}; @@ -105,83 +109,85 @@ export const CompanionWindow = forwardRef((props, innerRef) => { component="aside" aria-label={ariaLabel || title} > - - - + - {title} - { - position === 'left' - ? updateCompanionWindow - && ( - { updateCompanionWindow({ position: 'right' }); }} - > - - - ) - : ( - <> - { - updateCompanionWindow && ( - { updateCompanionWindow({ position: position === 'bottom' ? 'right' : 'bottom' }); }} - > - - - ) - } - + {title} + { + position === 'left' + ? updateCompanionWindow + && ( + { updateCompanionWindow({ position: 'right' }); }} > - - - + + + ) + : ( + <> + { + updateCompanionWindow && ( + { updateCompanionWindow({ position: position === 'bottom' ? 'right' : 'bottom' }); }} + > + + + ) + } + + + + + ) + } + { + titleControls && ( + + {titleControls} + ) - } - { - titleControls && ( - - {titleControls} - - ) - } - - - {childrenWithAdditionalProps} - - + } + + + {childrenWithAdditionalProps} + + + ); }); @@ -193,6 +199,7 @@ CompanionWindow.propTypes = { defaultSidebarPanelHeight: PropTypes.number, defaultSidebarPanelWidth: PropTypes.number, direction: PropTypes.string.isRequired, + id: PropTypes.string.isRequired, isDisplayed: PropTypes.bool, onCloseClick: PropTypes.func, paperClassName: PropTypes.string, diff --git a/src/contexts/LocaleContext.js b/src/contexts/LocaleContext.js new file mode 100644 index 0000000000..dfa092bab3 --- /dev/null +++ b/src/contexts/LocaleContext.js @@ -0,0 +1,5 @@ +import { createContext } from 'react'; + +const LocaleContext = createContext(); + +export default LocaleContext; From efc99f3b556bb2fdd1292ab9b299a7113ca9ce3d Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Tue, 17 Dec 2024 07:15:44 -0800 Subject: [PATCH 2/4] Extract IIIFResourceLabel component for rendering the contextually appropriate label for a IIIF resource. --- .../components/GalleryViewThumbnail.test.js | 1 + .../WindowSideBarCanvasPanel.test.js | 4 +-- src/components/CanvasLayers.js | 12 ++------ src/components/CollectionDialog.js | 18 ++++-------- src/components/IIIFResourceLabel.js | 28 +++++++++++++++++++ src/components/IIIFThumbnail.js | 11 ++------ src/components/WindowSideBarCanvasPanel.js | 14 ++-------- .../WindowSideBarCollectionPanel.js | 16 +++-------- src/lib/MiradorCanvas.js | 4 +-- src/state/selectors/manifests.js | 2 +- 10 files changed, 50 insertions(+), 60 deletions(-) create mode 100644 src/components/IIIFResourceLabel.js diff --git a/__tests__/src/components/GalleryViewThumbnail.test.js b/__tests__/src/components/GalleryViewThumbnail.test.js index 4a21a67547..53c4b06a6f 100644 --- a/__tests__/src/components/GalleryViewThumbnail.test.js +++ b/__tests__/src/components/GalleryViewThumbnail.test.js @@ -73,6 +73,7 @@ describe('GalleryView', () => { describe('on-demand annotation fetching', () => { const canvas = { getHeight: () => 50, + getLabel: () => ({ getValue: () => 'label' }), getServices: vi.fn(), getThumbnail: vi.fn(), getType: vi.fn(), diff --git a/__tests__/src/components/WindowSideBarCanvasPanel.test.js b/__tests__/src/components/WindowSideBarCanvasPanel.test.js index 0a7549a55d..d0fcdb79f2 100644 --- a/__tests__/src/components/WindowSideBarCanvasPanel.test.js +++ b/__tests__/src/components/WindowSideBarCanvasPanel.test.js @@ -13,8 +13,8 @@ function createWrapper(props) { let sequences; if (props.multipleSequences) { - sequences = [{ id: 'a', label: 'seq1' }, - { id: 'b', label: 'seq2' }]; + sequences = [{ getLabel: () => ({ getValue: () => undefined }), id: 'a', label: 'seq1' }, + { getLabel: () => ({ getValue: () => undefined }), id: 'b', label: 'seq2' }]; } else { sequences = Utils.parseManifest(manifestJson).getSequences(); } diff --git a/src/components/CanvasLayers.js b/src/components/CanvasLayers.js index ed1abd71e2..b58266431d 100644 --- a/src/components/CanvasLayers.js +++ b/src/components/CanvasLayers.js @@ -17,6 +17,7 @@ import { useTranslation } from 'react-i18next'; import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'; import MiradorMenuButton from '../containers/MiradorMenuButton'; import IIIFThumbnail from '../containers/IIIFThumbnail'; +import { IIIFResourceLabel } from './IIIFResourceLabel'; const StyledDragHandle = styled('div')(({ theme }) => ({ alignItems: 'center', @@ -40,15 +41,6 @@ const reorder = (list, startIndex, endIndex) => { return result; }; -/** */ -function getUseableLabel(resource, index) { - return (resource - && resource.getLabel - && resource.getLabel().length > 0) - ? resource.getLabel().getValue() - : String(index + 1); -} - /** @private */ function Layer({ resource, layerMetadata = {}, index, handleOpacityChange, setLayerVisibility, moveToTop, @@ -78,7 +70,7 @@ function Layer({ component="div" variant="body1" > - {getUseableLabel(resource, index)} +
{ setLayerVisibility(resource.id, !layer.visibility); }}> { layer.visibility ? : } diff --git a/src/components/CollectionDialog.js b/src/components/CollectionDialog.js index f44bde133b..56067e263d 100644 --- a/src/components/CollectionDialog.js +++ b/src/components/CollectionDialog.js @@ -21,6 +21,7 @@ import CollapsibleSection from '../containers/CollapsibleSection'; import ScrollIndicatedDialogContent from '../containers/ScrollIndicatedDialogContent'; import ManifestInfo from '../containers/ManifestInfo'; import WorkspaceContext from '../contexts/WorkspaceContext'; +import { IIIFResourceLabel } from './IIIFResourceLabel'; const StyledScrollIndicatedDialogContent = styled(ScrollIndicatedDialogContent)(() => ({ padding: (theme) => theme.spacing(1), @@ -38,15 +39,6 @@ const StyledCollectionFilter = styled('div')(() => ({ paddingTop: 0, })); -/** */ -function getUseableLabel(resource, index) { - return (resource - && resource.getLabel - && resource.getLabel().length > 0) - ? resource.getLabel().getValue() - : String(index + 1); -} - /** */ const Placeholder = ({ onClose, container }) => ( - {getUseableLabel(manifest)} + @@ -158,7 +150,7 @@ export function CollectionDialog({ startIcon={} onClick={() => goToPreviousCollection()} > - {getUseableLabel(collection)} + )} @@ -204,7 +196,7 @@ export function CollectionDialog({ onClick={() => { selectCollection(c); }} variant="multiline" > - {getUseableLabel(c)} + )) } @@ -219,7 +211,7 @@ export function CollectionDialog({ onClick={() => { selectManifest(m); }} variant="multiline" > - {getUseableLabel(m)} + )) } diff --git a/src/components/IIIFResourceLabel.js b/src/components/IIIFResourceLabel.js new file mode 100644 index 0000000000..4784458298 --- /dev/null +++ b/src/components/IIIFResourceLabel.js @@ -0,0 +1,28 @@ +import { useContext } from 'react'; +import { useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { + getLocale, +} from '../state/selectors'; +import LocaleContext from '../contexts/LocaleContext'; + +/** + * Render the contextually appropriate label for the resource + */ +export function IIIFResourceLabel({ fallback, resource }) { + const contextLocale = useContext(LocaleContext); + const fallbackLocale = useSelector(state => getLocale(state, {})); + + if (!resource) return fallback; + + const label = resource.getLabel(); + + if (!label) return fallback; + + return label.getValue(contextLocale || fallbackLocale || '') ?? (fallback || resource.id); +} + +IIIFResourceLabel.propTypes = { + fallback: PropTypes.string, + resource: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types +}; diff --git a/src/components/IIIFThumbnail.js b/src/components/IIIFThumbnail.js index 2feea6651a..301cc68b0f 100644 --- a/src/components/IIIFThumbnail.js +++ b/src/components/IIIFThumbnail.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import { styled } from '@mui/material/styles'; import { useInView } from 'react-intersection-observer'; import getThumbnail from '../lib/ThumbnailFactory'; +import { IIIFResourceLabel } from './IIIFResourceLabel'; const Root = styled('div', { name: 'IIIFThumbnail', slot: 'root' })({}); @@ -129,14 +130,6 @@ LazyLoadedImage.propTypes = { }), thumbnailsConfig: PropTypes.object, // eslint-disable-line react/forbid-prop-types }; -/** */ -function getUseableLabel(resource, index) { - return (resource - && resource.getLabel - && resource.getLabel().length > 0) - ? resource.getLabel().getValue() - : String(index + 1); -} const defaultPlaceholder = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mMMDQmtBwADgwF/Op8FmAAAAABJRU5ErkJggg=='; @@ -173,7 +166,7 @@ export function IIIFThumbnail({ { labelled && ( )} {children} diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js index 2b30297c4b..a407a7877c 100644 --- a/src/components/WindowSideBarCanvasPanel.js +++ b/src/components/WindowSideBarCanvasPanel.js @@ -17,21 +17,13 @@ import { useTranslation } from 'react-i18next'; import CompanionWindow from '../containers/CompanionWindow'; import SidebarIndexList from '../containers/SidebarIndexList'; import SidebarIndexTableOfContents from '../containers/SidebarIndexTableOfContents'; +import { IIIFResourceLabel } from './IIIFResourceLabel'; const StyledBreak = styled('div')(() => ({ flexBasis: '100%', height: 0, })); -/** */ -function getUseableLabel(resource, index) { - return (resource - && resource.getLabel - && resource.getLabel().length > 0) - ? resource.getLabel().getValue() - : resource.id; -} - /** * a panel showing the canvases for a given manifest */ @@ -113,7 +105,7 @@ export function WindowSideBarCanvasPanel({ }} data-testid="sequence-select" > - { sequences.map((s, i) => { getUseableLabel(s, i) }) } + { sequences.map((s, i) => ) } ) @@ -143,7 +135,7 @@ export function WindowSideBarCanvasPanel({ endIcon={} > - {getUseableLabel(collection)} + )} diff --git a/src/components/WindowSideBarCollectionPanel.js b/src/components/WindowSideBarCollectionPanel.js index 6f71e38ab5..2661538170 100644 --- a/src/components/WindowSideBarCollectionPanel.js +++ b/src/components/WindowSideBarCollectionPanel.js @@ -11,15 +11,7 @@ import ArrowUpwardIcon from '@mui/icons-material/ArrowUpwardSharp'; import { useTranslation } from 'react-i18next'; import CompanionWindow from '../containers/CompanionWindow'; import IIIFThumbnail from '../containers/IIIFThumbnail'; - -/** */ -function getUseableLabel(resource, index) { - return (resource - && resource.getLabel - && resource.getLabel().length > 0) - ? resource.getLabel().getValue() - : resource.id; -} +import { IIIFResourceLabel } from './IIIFResourceLabel'; /** */ function Item({ @@ -46,7 +38,7 @@ function Item({ /> )} - {getUseableLabel(manifest)} + ); } @@ -105,13 +97,13 @@ export function WindowSideBarCollectionPanel({ - {getUseableLabel(parentCollection)} + )} - { collection && getUseableLabel(collection)} + { collection && } { isFetching && } diff --git a/src/lib/MiradorCanvas.js b/src/lib/MiradorCanvas.js index 6e17fad668..6d09450e21 100644 --- a/src/lib/MiradorCanvas.js +++ b/src/lib/MiradorCanvas.js @@ -177,9 +177,9 @@ export default class MiradorCanvas { /** * Get the canvas label */ - getLabel() { + getLabel(locale = undefined) { return this.canvas.getLabel().length > 0 - ? this.canvas.getLabel().getValue() + ? this.canvas.getLabel().getValue(locale) : String(this.canvas.index + 1); } } diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js index d7a9c7c1ef..1faeb5643c 100644 --- a/src/state/selectors/manifests.js +++ b/src/state/selectors/manifests.js @@ -20,7 +20,7 @@ function createManifestoInstance(json, locale) { } /** */ -const getLocale = createSelector( +export const getLocale = createSelector( [ getCompanionWindow, getConfig, From 6af39a417c9479a260dde7acd74a54acddc20215 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Tue, 17 Dec 2024 07:34:35 -0800 Subject: [PATCH 3/4] Extract getCompanionWindowLocale selector. --- src/state/selectors/companionWindows.js | 12 ++++++++++++ src/state/selectors/manifests.js | 8 ++++---- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/state/selectors/companionWindows.js b/src/state/selectors/companionWindows.js index 392240ee35..5a0218dd24 100644 --- a/src/state/selectors/companionWindows.js +++ b/src/state/selectors/companionWindows.js @@ -29,6 +29,18 @@ export const getCompanionWindow = createSelector( (companionWindows, companionWindowId) => companionWindowId && companionWindows[companionWindowId], ); +/** + * Returns the companion window locale. + * @param {object} state + * @param {object} props + * @param {string} props.companionWindowId + * @returns {string|undefined} + */ +export const getCompanionWindowLocale = createSelector( + [getCompanionWindow], + companionWindow => companionWindow && companionWindow.locale, +); + /** * Return position of thumbnail navigation in a certain window. * @param {object} state diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js index 1faeb5643c..df47daec81 100644 --- a/src/state/selectors/manifests.js +++ b/src/state/selectors/manifests.js @@ -3,7 +3,7 @@ import { createCachedSelector } from 're-reselect'; import { PropertyValue, Utils, Resource } from 'manifesto.js'; import getThumbnail from '../../lib/ThumbnailFactory'; import asArray from '../../lib/asArray'; -import { getCompanionWindow } from './companionWindows'; +import { getCompanionWindowLocale } from './companionWindows'; import { getManifest } from './getters'; import { getConfig } from './config'; @@ -22,11 +22,11 @@ function createManifestoInstance(json, locale) { /** */ export const getLocale = createSelector( [ - getCompanionWindow, + getCompanionWindowLocale, getConfig, ], - (companionWindow = {}, config = {}) => ( - companionWindow.locale || config.language + (companionWindowLocale, config = {}) => ( + companionWindowLocale || config.language ), ); From d947941386700a8dae958085341a0472b402b6e5 Mon Sep 17 00:00:00 2001 From: Chris Beer Date: Tue, 17 Dec 2024 07:46:59 -0800 Subject: [PATCH 4/4] Push property localization down to getValues instead of part of parsing the property values. --- __tests__/src/selectors/manifests.test.js | 6 -- src/state/selectors/canvases.js | 7 ++- src/state/selectors/manifests.js | 73 ++++++++++------------- src/state/selectors/searches.js | 2 +- 4 files changed, 37 insertions(+), 51 deletions(-) diff --git a/__tests__/src/selectors/manifests.test.js b/__tests__/src/selectors/manifests.test.js index 1cf9bf50a3..3c10199d2a 100644 --- a/__tests__/src/selectors/manifests.test.js +++ b/__tests__/src/selectors/manifests.test.js @@ -59,12 +59,6 @@ describe('getManifestoInstance', () => { const received = getManifestoInstance(state, { manifestId: 'x' }); expect(received.id).toEqual('http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json'); }); - it('is cached based off of input props', () => { - const state = { manifests: { x: { json: manifestFixture019 } } }; - const received = getManifestoInstance(state, { manifestId: 'x' }); - expect(getManifestoInstance(state, { manifestId: 'x' })).toBe(received); - expect(getManifestoInstance(state, { manifestId: 'x', windowId: 'y' })).not.toBe(received); - }); }); describe('getManifestLogo()', () => { diff --git a/src/state/selectors/canvases.js b/src/state/selectors/canvases.js index f93daa8411..164c7408df 100644 --- a/src/state/selectors/canvases.js +++ b/src/state/selectors/canvases.js @@ -6,6 +6,7 @@ import { miradorSlice } from './utils'; import { getWindow } from './getters'; import { getSequence } from './sequences'; import { getWindowViewType } from './windows'; +import { getManifestLocale } from './manifests'; /** * Returns the info response. @@ -183,10 +184,10 @@ export const getPreviousCanvasGrouping = createSelector( * @returns {string|number} */ export const getCanvasLabel = createSelector( - [getCanvas], - canvas => (canvas && ( + [getCanvas, getManifestLocale], + (canvas, locale) => (canvas && ( canvas.getLabel().length > 0 - ? canvas.getLabel().getValue() + ? canvas.getLabel().getValue(locale) : String(canvas.index + 1) )), ); diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js index df47daec81..04e3661e68 100644 --- a/src/state/selectors/manifests.js +++ b/src/state/selectors/manifests.js @@ -1,5 +1,4 @@ import { createSelector } from 'reselect'; -import { createCachedSelector } from 're-reselect'; import { PropertyValue, Utils, Resource } from 'manifesto.js'; import getThumbnail from '../../lib/ThumbnailFactory'; import asArray from '../../lib/asArray'; @@ -24,9 +23,10 @@ export const getLocale = createSelector( [ getCompanionWindowLocale, getConfig, + (state, { locale }) => locale, ], - (companionWindowLocale, config = {}) => ( - companionWindowLocale || config.language + (companionWindowLocale, config = {}, locale) => ( + locale || companionWindowLocale || config.language || config.fallbackLanguages ), ); @@ -57,17 +57,9 @@ export const getManifestError = createSelector( ); /** Instantiate a manifesto instance */ -const getContextualManifestoInstance = createCachedSelector( +const getContextualManifestoInstance = createSelector( getManifest, - getLocale, - (manifest, locale) => manifest - && createManifestoInstance(manifest.json, locale), -)( - (state, { companionWindowId, manifestId, windowId }) => [ - manifestId, - windowId, - getLocale(state, { companionWindowId }), - ].join(' - '), // Cache key consisting of manifestId, windowId, and locale + manifest => manifest && createManifestoInstance(manifest.json), ); /** @@ -80,15 +72,14 @@ const getContextualManifestoInstance = createCachedSelector( export const getManifestoInstance = createSelector( getContextualManifestoInstance, (state, { json }) => json, - getLocale, - (manifesto, manifestJson, locale) => ( + (manifesto, manifestJson) => ( manifestJson && createManifestoInstance(manifestJson, locale) ) || manifesto, ); export const getManifestLocale = createSelector( - [getManifestoInstance], - manifest => manifest && manifest.options && manifest.options.locale && manifest.options.locale.replace(/-.*$/, ''), + [getManifestoInstance, getLocale], + (manifest, locale) => locale ?? (manifest && manifest.options && manifest.options.locale && manifest.options.locale.replace(/-.*$/, '')), ); /** */ @@ -114,7 +105,7 @@ export const getManifestProviderName = createSelector( ], (provider, locale) => provider && provider[0].label - && PropertyValue.parse(provider[0].label, locale).getValue(), + && PropertyValue.parse(provider[0].label).getValue(locale), ); /** @@ -159,8 +150,8 @@ export const getManifestHomepage = createSelector( (homepages, locale) => homepages && asArray(homepages).map(homepage => ( { - label: PropertyValue.parse(homepage.label, locale) - .getValue(), + label: PropertyValue.parse(homepage.label) + .getValue(locale), value: homepage.id || homepage['@id'], } )), @@ -175,11 +166,11 @@ export const getManifestHomepage = createSelector( * @returns {string|null} */ export const getManifestRenderings = createSelector( - [getManifestoInstance], - manifest => manifest + [getManifestoInstance, getManifestLocale], + (manifest, locale) => manifest && manifest.getRenderings().map(rendering => ( { - label: rendering.getLabel().getValue(), + label: rendering.getLabel().getValue(locale), value: rendering.id, } )), @@ -202,8 +193,8 @@ export const getManifestSeeAlso = createSelector( && asArray(seeAlso).map(related => ( { format: related.format, - label: PropertyValue.parse(related.label, locale) - .getValue(), + label: PropertyValue.parse(related.label) + .getValue(locale), value: related.id || related['@id'], } )), @@ -243,8 +234,8 @@ export const getManifestRelated = createSelector( } : { format: related.format, - label: PropertyValue.parse(related.label, locale) - .getValue(), + label: PropertyValue.parse(related.label) + .getValue(locale), value: related.id || related['@id'], } )), @@ -259,13 +250,13 @@ export const getManifestRelated = createSelector( * @returns {string|null} */ export const getRequiredStatement = createSelector( - [getManifestoInstance], - manifest => manifest + [getManifestoInstance, getManifestLocale], + (manifest, locale) => manifest && asArray(manifest.getRequiredStatement()) .filter(l => l && l.getValues().some(v => v)) .map(labelValuePair => ({ - label: (labelValuePair.label && labelValuePair.label.getValue()) || null, - values: labelValuePair.getValues(), + label: (labelValuePair.label && labelValuePair.label.getValue(locale)) || null, + values: labelValuePair.getValues(locale), })), ); @@ -285,7 +276,7 @@ export const getRights = createSelector( ], (rights, license, locale) => { const data = rights || license; - return asArray(PropertyValue.parse(data, locale).getValues()); + return asArray(PropertyValue.parse(data).getValues(locale)); }, ); @@ -319,9 +310,9 @@ export function getManifestThumbnail(state, props) { * @returns {string} */ export const getManifestTitle = createSelector( - [getManifestoInstance], - manifest => manifest - && manifest.getLabel().getValue(), + [getManifestoInstance, getManifestLocale], + (manifest, locale) => manifest + && manifest.getLabel().getValue(locale), ); /** @@ -352,7 +343,7 @@ export const getManifestSummary = createSelector( getManifestLocale, ], (summary, locale) => summary - && PropertyValue.parse(summary, locale).getValue(locale), + && PropertyValue.parse(summary).getValue(locale), ); /** @@ -377,11 +368,11 @@ export const getManifestUrl = createSelector( * @param iiifResource * @returns {Array[Object]} */ -export function getDestructuredMetadata(iiifResource) { +export function getDestructuredMetadata(iiifResource, locale = undefined) { return (iiifResource && iiifResource.getMetadata().map(labelValuePair => ({ - label: labelValuePair.getLabel(), - values: labelValuePair.getValues(), + label: labelValuePair.getLabel(locale), + values: labelValuePair.getValues(locale), })) ); } @@ -395,8 +386,8 @@ export function getDestructuredMetadata(iiifResource) { * @returns {Array[Object]} */ export const getManifestMetadata = createSelector( - [getManifestoInstance], - manifest => manifest && getDestructuredMetadata(manifest), + [getManifestoInstance, getManifestLocale], + (manifest, locale) => manifest && getDestructuredMetadata(manifest, locale), ); /** */ diff --git a/src/state/selectors/searches.js b/src/state/selectors/searches.js index f402d1e8c8..f1cb5eedf4 100644 --- a/src/state/selectors/searches.js +++ b/src/state/selectors/searches.js @@ -294,7 +294,7 @@ export const getResourceAnnotationLabel = createSelector( !(resourceAnnotation && resourceAnnotation.resource && resourceAnnotation.resource.label) ) return []; - return PropertyValue.parse(resourceAnnotation.resource.label, locale).getValues(); + return PropertyValue.parse(resourceAnnotation.resource.label).getValues(locale); }, );