diff --git a/__tests__/CanvasDownloadLinks.test.js b/__tests__/CanvasDownloadLinks.test.js index 8a14e5d..ef2ec2b 100644 --- a/__tests__/CanvasDownloadLinks.test.js +++ b/__tests__/CanvasDownloadLinks.test.js @@ -16,6 +16,7 @@ function createWrapper(props) { restrictDownloadOnSizeDefinition={false} viewType="single" windowId="wid123" + t={(k, v) => `${k} ${JSON.stringify(v)}`} {...props} />, ); @@ -62,7 +63,7 @@ describe('CanvasDownloadLinks', () => { it('includes a canvas-level rendering as a download link', () => { createWrapper({ canvas }); - const downloadLink = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i }); + const downloadLink = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":4000,"height":1000}/i }); expect(downloadLink).toBeInTheDocument(); }); }); @@ -79,7 +80,7 @@ describe('CanvasDownloadLinks', () => { createWrapper({ canvas, infoResponse, windowId: 'zoomedOutWindow' }); - const zoomedLink = screen.queryByText('Zoomed region (6000 x 1000px)'); + const zoomedLink = screen.queryByText('mirador-dl-plugin.zoomed_region {"width":6000,"height":1000}'); expect(zoomedLink).not.toBeInTheDocument(); }); @@ -90,7 +91,7 @@ describe('CanvasDownloadLinks', () => { createWrapper({ canvas, infoResponse, windowId: 'zoomedIntoNonImageSpaceWindow' }); - const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)'); + const zoomedLink = screen.queryByText('mirador-dl-plugin.zoomed_region {"width":2000,"height":500}'); expect(zoomedLink).not.toBeInTheDocument(); }); @@ -101,7 +102,7 @@ describe('CanvasDownloadLinks', () => { createWrapper({ canvas, infoResponse, windowId: 'zoomedInWindow' }); - const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)'); + const zoomedLink = screen.queryByText('mirador-dl-plugin.zoomed_region {"width":2000,"height":500}'); expect(zoomedLink).toBeInTheDocument(); }); @@ -113,13 +114,13 @@ describe('CanvasDownloadLinks', () => { createWrapper({ canvas, infoResponse, viewType: 'book', windowId: 'zoomedInWindow', }); - const zoomedLink = screen.queryByText('Zoomed region (2000 x 500px)'); + const zoomedLink = screen.queryByText('mirador-dl-plugin.zoomed_region {"width":2000,"height":500}'); expect(zoomedLink).not.toBeInTheDocument(); createWrapper({ canvas, infoResponse, viewType: 'gallery', windowId: 'zoomedInWindow', }); - const zoomedLinkGallery = screen.queryByText('Zoomed region (2000 x 500px)'); + const zoomedLinkGallery = screen.queryByText('mirador-dl-plugin.zoomed_region {"width":2000,"height":500}'); expect(zoomedLinkGallery).not.toBeInTheDocument(); }); @@ -138,7 +139,7 @@ describe('CanvasDownloadLinks', () => { windowId: 'zoomedInWindow', }); - const downloadLink = screen.getByRole('link', { name: /Whole image \(400 x 100px\)/i }); + const downloadLink = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":400,"height":100}/i }); expect(screen.getAllByRole('link')).toHaveLength(2); // Should only show small-size version and link to PDF. expect(downloadLink).toBeInTheDocument(); }); @@ -163,9 +164,9 @@ describe('CanvasDownloadLinks', () => { it('renders download links for all specified sizes in the dialog', () => { createWrapper({ canvas, infoResponse: { json: { sizes } } }); - const link1 = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i }); - const link2 = screen.getByRole('link', { name: /Whole image \(2000 x 500px\)/i }); - const link3 = screen.getByRole('link', { name: /Whole image \(1000 x 250px\)/i }); + const link1 = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":4000,"height":1000}/i }); + const link2 = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":2000,"height":500}/i }); + const link3 = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":1000,"height":250}/i }); expect(link1).toBeInTheDocument(); expect(link2).toBeInTheDocument(); @@ -177,7 +178,7 @@ describe('CanvasDownloadLinks', () => { it('renders a single link to the full-size image', () => { createWrapper({ canvas }); - const link = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i }); + const link = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":4000,"height":1000}/i }); expect(link).toBeInTheDocument(); expect(link).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/full/0/default.jpg?download=true'); }); @@ -186,10 +187,10 @@ describe('CanvasDownloadLinks', () => { it('renders links for both full-size and 1000px wide versions', () => { createWrapper({ canvas }); - const link1 = screen.getByRole('link', { name: /Whole image \(4000 x 1000px\)/i }); + const link1 = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":4000,"height":1000}/i }); expect(link1).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/full/0/default.jpg?download=true'); - const link2 = screen.getByRole('link', { name: /Whole image \(1000 x 250px\)/i }); + const link2 = screen.getByRole('link', { name: /mirador-dl-plugin\.whole_image {"width":1000,"height":250}/i }); expect(link2).toHaveAttribute('href', 'http://example.com/iiif/abc123/full/1000,/0/default.jpg?download=true'); }); }); diff --git a/__tests__/ManifestDownloadLinks.test.js b/__tests__/ManifestDownloadLinks.test.js index 4897ffd..c107d19 100644 --- a/__tests__/ManifestDownloadLinks.test.js +++ b/__tests__/ManifestDownloadLinks.test.js @@ -7,6 +7,7 @@ function createWrapper(props) { k} {...props} />, ); @@ -30,7 +31,7 @@ describe('ManifestDownloadLinks', () => { createWrapper({ renderings }); screen.getByRole('heading'); - const headingElement = screen.getByText('Other download options'); + const headingElement = screen.getByText('mirador-dl-plugin.other_download'); expect(headingElement).toBeInTheDocument(); expect(headingElement.tagName).toBe('H3'); }); diff --git a/__tests__/MiradorDownloadDialog.test.js b/__tests__/MiradorDownloadDialog.test.js index ccb7a30..85eb6ac 100644 --- a/__tests__/MiradorDownloadDialog.test.js +++ b/__tests__/MiradorDownloadDialog.test.js @@ -14,6 +14,7 @@ function createWrapper(props) { infoResponse={() => ({})} manifest={{ getSequences: () => [] }} open + t={(k) => k} viewType="single" windowId="wid123" {...props} @@ -50,7 +51,7 @@ describe('Dialog', () => { it('calls the closeDialog function when the close button is clicked', async () => { const closeDialog = jest.fn(); createWrapper({ closeDialog }); - const closeButton = await screen.findByText(/Close/); + const closeButton = await screen.findByText(/mirador-dl-plugin\.close/); fireEvent.click(closeButton); expect(closeDialog).toHaveBeenCalled(); }); diff --git a/__tests__/miradorDownloadPlugin.test.js b/__tests__/miradorDownloadPlugin.test.js index 6c6516b..b691986 100644 --- a/__tests__/miradorDownloadPlugin.test.js +++ b/__tests__/miradorDownloadPlugin.test.js @@ -7,6 +7,7 @@ function createWrapper(props) { {}} openDownloadDialog={() => {}} + t={(k) => k} {...props} />, ); @@ -19,7 +20,7 @@ describe('miradorDownloadPlugin', () => { describe('Component Rendering', () => { it('displays a "Download" element when rendered', () => { createWrapper(); - const downloadElement = screen.queryByText(/Download/i); + const downloadElement = screen.queryByText(/mirador-dl-plugin\.download/i); expect(downloadElement).toBeInTheDocument(); }); }); @@ -30,7 +31,7 @@ describe('MenuItem', () => { const handleClose = jest.fn(); const openDownloadDialog = jest.fn(); createWrapper({ handleClose, openDownloadDialog }); - const openDownloadDialogButton = await screen.findByText(/Download/); + const openDownloadDialogButton = await screen.findByText(/mirador-dl-plugin\.download/); fireEvent.click(openDownloadDialogButton); expect(handleClose).toHaveBeenCalled(); expect(openDownloadDialog).toHaveBeenCalled(); diff --git a/src/CanvasDownloadLinks.js b/src/CanvasDownloadLinks.js index 839bf87..12e503c 100644 --- a/src/CanvasDownloadLinks.js +++ b/src/CanvasDownloadLinks.js @@ -13,24 +13,24 @@ import RenderingDownloadLink from './RenderingDownloadLink'; */ export default class CanvasDownloadLinks extends Component { zoomedImageLabel() { + const { t } = this.props; const bounds = this.currentBounds(); - return `Zoomed region (${Math.floor(bounds.width)} x ${Math.floor( - bounds.height, - )}px)`; + return t('mirador-dl-plugin.zoomed_region', { + width: Math.floor(bounds.width), + height: Math.floor(bounds.height), + }); } fullImageLabel() { - const { canvas } = this.props; - - return `Whole image (${canvas.getWidth()} x ${canvas.getHeight()}px)`; + const { canvas, t } = this.props; + return t('mirador-dl-plugin.whole_image', { width: canvas.getWidth(), height: canvas.getHeight() }); } smallImageLabel() { - const { canvas } = this.props; + const { canvas, t } = this.props; + const height = Math.floor((1000 * canvas.getHeight()) / canvas.getWidth()); - return `Whole image (1000 x ${Math.floor( - (1000 * canvas.getHeight()) / canvas.getWidth(), - )}px)`; + return t('mirador-dl-plugin.whole_image', { width: 1000, height }); } zoomedImageUrl() { @@ -161,6 +161,7 @@ export default class CanvasDownloadLinks extends Component { } linksForDefinedSizes() { + const { t } = this.props; return this.definedSizes().map((size) => ( - {`Whole image (${size.width} x ${size.height}px)`} + {t('mirador-dl-plugin.whole_image', { width: size.width, height: size.height })} )); @@ -233,6 +234,7 @@ CanvasDownloadLinks.propTypes = { }), }).isRequired, restrictDownloadOnSizeDefinition: PropTypes.bool.isRequired, + t: PropTypes.func.isRequired, viewType: PropTypes.string.isRequired, windowId: PropTypes.string.isRequired, }; diff --git a/src/ManifestDownloadLinks.js b/src/ManifestDownloadLinks.js index e23e9b3..751e125 100644 --- a/src/ManifestDownloadLinks.js +++ b/src/ManifestDownloadLinks.js @@ -13,12 +13,12 @@ export default class ManifestDownloadLinks extends Component { * Returns the rendered component */ render() { - const { renderings } = this.props; + const { renderings, t } = this.props; return ( - Other download options + {t('mirador-dl-plugin.other_download')} {renderings.map((rendering) => ( @@ -32,4 +32,5 @@ export default class ManifestDownloadLinks extends Component { ManifestDownloadLinks.propTypes = { renderings: PropTypes.array.isRequired, // eslint-disable-line react/forbid-prop-types + t: PropTypes.func.isRequired, }; diff --git a/src/MiradorDownloadDialog.js b/src/MiradorDownloadDialog.js index c102790..f0a472e 100644 --- a/src/MiradorDownloadDialog.js +++ b/src/MiradorDownloadDialog.js @@ -15,6 +15,7 @@ import DialogTitle from '@mui/material/DialogTitle'; import DialogActions from '@mui/material/DialogActions'; import Button from '@mui/material/Button'; import ManifestDownloadLinks from './ManifestDownloadLinks'; +import translations from './translations'; import CanvasDownloadLinks from './CanvasDownloadLinks'; const mapDispatchToProps = (dispatch, { windowId }) => ({ @@ -66,6 +67,7 @@ export class MiradorDownloadDialog extends Component { infoResponse, open, restrictDownloadOnSizeDefinition, + t, viewType, windowId, } = this.props; @@ -84,7 +86,7 @@ export class MiradorDownloadDialog extends Component { maxWidth="xs" > - Download + {t('mirador-dl-plugin.download')} {canvases.map((canvas) => ( @@ -96,6 +98,7 @@ export class MiradorDownloadDialog extends Component { restrictDownloadOnSizeDefinition } key={canvas.id} + t={t} viewType={viewType} windowId={windowId} /> @@ -103,12 +106,13 @@ export class MiradorDownloadDialog extends Component { {this.renderings().length > 0 && ( )} @@ -129,6 +133,7 @@ MiradorDownloadDialog.propTypes = { }), open: PropTypes.bool, restrictDownloadOnSizeDefinition: PropTypes.bool, + t: PropTypes.func.isRequired, viewType: PropTypes.string.isRequired, windowId: PropTypes.string.isRequired, }; @@ -144,6 +149,9 @@ export default { mode: 'add', name: 'MiradorDownloadDialog', component: MiradorDownloadDialog, + config: { + translations, + }, mapDispatchToProps, mapStateToProps, }; diff --git a/src/miradorDownloadPlugin.js b/src/miradorDownloadPlugin.js index 81cdbf4..de73bca 100644 --- a/src/miradorDownloadPlugin.js +++ b/src/miradorDownloadPlugin.js @@ -4,6 +4,7 @@ import MenuItem from '@mui/material/MenuItem'; import ListItemIcon from '@mui/material/ListItemIcon'; import ListItemText from '@mui/material/ListItemText'; import VerticalAlignBottomIcon from '@mui/icons-material/VerticalAlignBottom'; +import translations from './translations'; // eslint-disable-next-line default-param-last const downloadDialogReducer = (state = {}, action) => { @@ -40,13 +41,15 @@ class MiradorDownload extends Component { } render() { + const { t } = this.props; + return ( this.openDialogAndCloseMenu()}> - Download + {t('mirador-dl-plugin.download')} ); @@ -56,6 +59,7 @@ class MiradorDownload extends Component { MiradorDownload.propTypes = { handleClose: PropTypes.func, openDownloadDialog: PropTypes.func, + t: PropTypes.func.isRequired, }; MiradorDownload.defaultProps = { @@ -68,6 +72,9 @@ export default { mode: 'add', name: 'MiradorDownloadPlugin', component: MiradorDownload, + config: { + translations, + }, mapDispatchToProps, reducers: { windowDialogs: downloadDialogReducer, diff --git a/src/translations.js b/src/translations.js new file mode 100644 index 0000000..af2cdae --- /dev/null +++ b/src/translations.js @@ -0,0 +1,31 @@ +const translations = { + de: { + 'mirador-dl-plugin': { + close: 'Schließen', + download: 'Download', + other_download: 'Andere Download-Optionen', + whole_image: 'Gesamtes Bild ({{width}} x {{height}}px)', + zoomed_region: 'Aktueller Bildausschnitt ({{width}} x {{height}}px)', + }, + }, + en: { + 'mirador-dl-plugin': { + close: 'Close', + download: 'Download', + other_download: 'Other download options', + whole_image: 'Whole image ({{width}} x {{height}}px)', + zoomed_region: 'Zoomed region ({{width}} x {{height}}px)', + }, + }, + fr: { + 'mirador-dl-plugin': { + close: 'Fermer', + download: 'Télécharger', + other_download: 'Autres options de téléchargement', + whole_image: 'Image entière ({{width}} x {{height}}px)', + zoomed_region: 'Région zoomée ({{width}} x {{height}}px)', + }, + }, +}; + +export default translations;