Skip to content

Commit

Permalink
Merge pull request #4058 from ProjectMirador/manifest-locales-picker
Browse files Browse the repository at this point in the history
Update the LocalePicker to use labels for languages.
  • Loading branch information
cbeer authored Dec 18, 2024
2 parents 01ebfc1 + df014ca commit c6e4ecd
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 13 deletions.
18 changes: 18 additions & 0 deletions __tests__/integration/mirador/i18n.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<title>Mirador</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500">
</head>
<body>
<div id="mirador" style="position: absolute; top: 0; bottom: 0; left: 0; right: 0;"></div>
<script type="module">
import Mirador from '../../../src';
import config from './mirador-configs/i18n.js';
Mirador.viewer(config);
</script>
</body>
</html>
25 changes: 25 additions & 0 deletions __tests__/integration/mirador/mirador-configs/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export default {
catalog: [
{ manifestId: 'https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json' },
{ manifestId: 'https://iiif.harvardartmuseums.org/manifests/object/299843' },
{ manifestId: 'https://media.nga.gov/public/manifests/nga_highlights.json', provider: 'National Gallery of Art' },
{ manifestId: 'https://data.ucd.ie/api/img/manifests/ucdlib:33064', provider: 'Irish Architectural Archive' },
{ manifestId: 'https://wellcomelibrary.org/iiif/b18035723/manifest', provider: 'Wellcome Library' },
{ manifestId: 'https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json', provider: 'Biblissima' },
{ manifestId: 'https://www.e-codices.unifr.ch/metadata/iiif/gau-Fragment/manifest.json', provider: 'e-codices - Virtual Manuscript Library of Switzerland' },
{ manifestId: 'https://wellcomelibrary.org/iiif/collection/b18031511', provider: 'Wellcome Library' },
{ manifestId: 'https://gallica.bnf.fr/iiif/ark:/12148/btv1b10022508f/manifest.json', provider: 'Bibliothèque nationale de France' },
{ manifestId: 'https://manifests.britishart.yale.edu/Osbornfa1', provider: 'Beinecke Rare Book and Manuscript Library, Yale University' },
{ manifestId: 'https://iiif.biblissima.fr/chateauroux/B360446201_MS0005/manifest.json', provider: 'Biblissima' },
{ manifestId: 'https://iiif.durham.ac.uk/manifests/trifle/32150/t1/m4/q7/t1m4q77fr328/manifest', provider: 'Durham University Library' },
// { manifestId: "https://iiif.vam.ac.uk/collections/O1023003/manifest.json", provider: "Ocean liners"},
{ manifestId: 'https://zavicajna.digitalna.rs/iiif/iiif/api/presentation/2/4aa44ad1-0b74-4590-ab09-534a38cb7c53%252F00000001%252Fostalo01%252F00000012/manifest', provider: "Библиотека 'Милутин Бојић'" },
],
id: 'mirador',
language: 'fr',
windows: [{
manifestId: 'https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json',
showLocalePicker: true,
thumbnailNavigationPosition: 'far-bottom',
}],
};
8 changes: 4 additions & 4 deletions __tests__/src/components/LocalePicker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('LocalePicker', () => {
createWrapper({ availableLocales: ['en', 'de'], locale: 'de' });
// The option to expand the dropdown menu is rendered by a CompanionWindow titleControls prop in WindowSideBarInfoPanel, which is a combobox
const dropdownTitle = screen.getByRole('combobox');
expect(dropdownTitle).toHaveTextContent('de');
expect(dropdownTitle).toHaveTextContent('Deutsch');
});

it('renders a select with both options and sets the current value', async () => {
Expand All @@ -41,10 +41,10 @@ describe('LocalePicker', () => {
// Assert that the menu element has 2 children (2 options)
expect(menu.children).toHaveLength(2); // eslint-disable-line testing-library/no-node-access
// Verify that the select element has the correct value ('de')
const deOption = screen.getByRole('option', { name: 'de' });
const deOption = screen.getByRole('option', { name: 'Deutsch' });
expect(deOption).toHaveAttribute('aria-selected', 'true');
// Verify en is also an option
expect(screen.getByRole('option', { name: 'en' })).toBeInTheDocument();
expect(screen.getByRole('option', { name: 'English' })).toBeInTheDocument();
});

it('triggers setLocale prop when clicking a list item', async () => {
Expand All @@ -59,7 +59,7 @@ describe('LocalePicker', () => {
// Open the Select component
await user.click(dropdownTitle);
// Change the locale to 'de'
await user.click(screen.getByRole('option', { name: 'de' }));
await user.click(screen.getByRole('option', { name: 'Deutsch' }));
expect(setLocale).toHaveBeenCalledTimes(1);
expect(setLocale).toHaveBeenCalledWith('de');
});
Expand Down
55 changes: 54 additions & 1 deletion __tests__/src/selectors/manifests.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ describe('getManifestLocale', () => {
});

describe('getMetadataLocales', () => {
it('gets the locales preseent in the manifest metadata', () => {
it('gets the locales preseent in the IIIF v2 manifest metadata', () => {
const manifest = {
'@context': 'http://iiif.io/api/presentation/2/context.json',
'@id':
Expand Down Expand Up @@ -403,6 +403,59 @@ describe('getMetadataLocales', () => {
const received = getMetadataLocales(state, { manifestId: 'x' });
expect(received).toEqual(['de-label', 'en-label', 'en-value', 'de-value', 'one-value']);
});
it('gets the locales preseent in the IIIF v3 manifest metadata', () => {
const manifest = {
'@context': 'http://iiif.io/api/presentation/3/context.json',
id: 'https://iiif.io/api/cookbook/recipe/0006-text-language/manifest.json',
label: {
en: [
"Whistler's Mother",
],
fr: [
'La Mère de Whistler',
],
},
metadata: [
{
label: {
en: [
'Creator',
],
fr: [
'Auteur',
],
},
value: {
none: [
'Whistler, James Abbott McNeill',
],
},
},
{
label: {
en: [
'Subject',
],
fr: [
'Sujet',
],
},
value: {
en: [
'McNeill Anna Matilda, mother of Whistler (1804-1881)',
],
fr: [
'McNeill Anna Matilda, mère de Whistler (1804-1881)',
],
},
},
],
type: 'Manifest',
};
const state = { manifests: { x: { json: manifest } } };
const received = getMetadataLocales(state, { manifestId: 'x' });
expect(received).toEqual(['en', 'fr', 'none']);
});
});

describe('getRequiredStatement', () => {
Expand Down
19 changes: 16 additions & 3 deletions src/components/LocalePicker.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
import PropTypes from 'prop-types';
import keyBy from 'lodash/keyBy';
import MenuItem from '@mui/material/MenuItem';
import InputLabel from '@mui/material/InputLabel';
import FormControl from '@mui/material/FormControl';
import Select from '@mui/material/Select';
import Typography from '@mui/material/Typography';
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
import { getLanguagesFromConfigWithCurrent } from '../state/selectors/config';

/**
* Provide a locale picker
*/
export function LocalePicker({ availableLocales = [], locale = '', setLocale = undefined }) {
const languages = useSelector(state => getLanguagesFromConfigWithCurrent(state));
const { t } = useTranslation();

if (!setLocale || availableLocales.length < 2) return null;

const selectedLocale = availableLocales.indexOf(locale) >= 0 ? locale : availableLocales[0];
const labels = keyBy(languages, o => o.locale);

return (
<FormControl>
<FormControl variant="standard">
<InputLabel>{t('language')}</InputLabel>
<Select
MenuProps={{
anchorOrigin: {
horizontal: 'left',
vertical: 'bottom',
},
}}
autoWidth
displayEmpty
value={locale}
value={selectedLocale}
onChange={(e) => { setLocale(e.target.value); }}
name="locale"
>
{
availableLocales.map(l => (
<MenuItem key={l} value={l}><Typography variant="body2">{ l }</Typography></MenuItem>
<MenuItem key={l} value={l}><Typography variant="body2">{ labels[l]?.label || l }</Typography></MenuItem>
))
}
</Select>
Expand Down
27 changes: 22 additions & 5 deletions src/state/selectors/manifests.js
Original file line number Diff line number Diff line change
Expand Up @@ -415,14 +415,31 @@ export const getManifestMetadata = createSelector(

/** */
function getLocalesForStructure(item) {
const languages = [];
const languages = new Set([]);

/** Extract language indicators from IIIF v2 or v3 manifests */
const extractLanguage = (i) => {
if (!(i && typeof i === 'object')) return;

// IIIF v2 pattern
if (i['@language'] && i['@value']) {
languages.add(i['@language']);
return;
}

// IIIF v3 pattern
Object.keys(i).forEach((key) => {
languages.add(key);
});
};

if (Array.isArray(item)) {
languages.push(...item.filter(i => (typeof i === 'object' && i['@language'])).map(i => i['@language']));
} else if (item && typeof item === 'object') {
if (item['@language']) languages.push(item['@language']);
item.forEach(i => extractLanguage(i));
} else {
extractLanguage(item);
}
return languages;

return [...languages];
}

/** */
Expand Down

0 comments on commit c6e4ecd

Please sign in to comment.