UNPKG

mirador

Version:

An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.

251 lines (222 loc) 8.05 kB
import { createSelector } from 'reselect'; import flatten from 'lodash/flatten'; import CanvasGroupings from '../../lib/CanvasGroupings'; import { getIiifResourceImageService } from '../../lib/iiif'; import { getMiradorCanvasWrapper } from './wrappers'; import { miradorSlice, EMPTY_ARRAY } from './utils'; import { getWindow } from './getters'; import { getSequence } from './sequences'; import { getWindowViewType } from './windows'; import { getManifestLocale } from './manifests'; /** * Returns the info response. * @param {object} state * @returns {object} */ export const selectInfoResponses = (state) => miradorSlice(state).infoResponses; export const getCanvases = createSelector([getSequence], (sequence) => (sequence && sequence.getCanvases()) || EMPTY_ARRAY); /** * Return the canvas selected by an id * @param {object} state * @param {object} props * @param {string} props.canvasId * @returns {object} */ export const getCanvas = createSelector([getSequence, (state, { canvasId }) => canvasId], (sequence, canvasId) => { if (!sequence || !canvasId) return undefined; return sequence.getCanvasById(canvasId); }); /** * Returns the current canvas. * @param {object} state * @param {object} props * @param {string} props.windowId * @returns {object|undefined} */ export const getCurrentCanvas = createSelector([getSequence, getWindow], (sequence, window) => { if (!sequence || !window) return undefined; if (!window.canvasId) return sequence.getCanvasByIndex(0); return sequence.getCanvasById(window.canvasId); }); /** * Returns the visible canvas ids. * @param {object} state * @param {object} props * @param {string} props.windowId * @returns {Array} */ export const getVisibleCanvasIds = createSelector( [getWindow], (window) => (window && (window.visibleCanvases || (window.canvasId && [window.canvasId]))) || EMPTY_ARRAY, ); /** * Returns the visible canvses. * @param {object} state * @param {object} props * @param {string} props.windowId * @returns {Array} */ export const getVisibleCanvases = createSelector([getVisibleCanvasIds, getCanvases], (canvasIds, canvases) => (canvases || []).filter((c) => canvasIds.includes(c.id)), ); /** * Return the current canvases grouped by how they'll appear in the viewer. * For book view returns groups of 2, for single returns 1. * @param {object} state * @param {object} props * @param {string} props.manifestId * @param {string} props.windowId * @returns {Array} */ export const getCanvasGroupings = createSelector( [getCanvases, getWindowViewType], (canvases, view) => canvases && new CanvasGroupings(canvases, view).groupings(), ); /** * Return the current canvases selected in a window. * For book view returns 2, for single returns 1. * @param {object} state * @param {object} props * @param {string} props.manifestId * @param {string} props.windowId * @param {string} props.canvasId * @returns {Array} */ export const getCanvasGrouping = createSelector( [getCanvasGroupings, (state, { canvasId }) => canvasId], (groupings, canvasId) => (groupings && groupings.find((group) => group.some((c) => c.id === canvasId))) || EMPTY_ARRAY, ); /** * Return the next canvas(es) for a window. * For book view returns 2, for single returns 1. * @param {object} state * @param {object} props * @param {string} props.manifestId * @param {string} props.windowId * @returns {Array} */ export const getNextCanvasGrouping = createSelector([getCanvasGroupings, getCurrentCanvas], (groupings, canvas, view) => { if (!groupings || !canvas) return undefined; const currentGroupIndex = groupings.findIndex((group) => group.some((c) => c.id === canvas.id)); if (currentGroupIndex < 0 || currentGroupIndex + 1 >= groupings.length) return undefined; const newGroup = groupings[currentGroupIndex + 1]; return newGroup; }); /** * Return the previous canvas(es) for a window. * For book view returns 2, for single returns 1. * @param {object} state * @param {object} props * @param {string} props.manifestId * @param {string} props.windowId * @returns {Array} */ export const getPreviousCanvasGrouping = createSelector([getCanvasGroupings, getCurrentCanvas], (groupings, canvas, view) => { if (!groupings || !canvas) return undefined; const currentGroupIndex = groupings.findIndex((group) => group.some((c) => c.id === canvas.id)); if (currentGroupIndex < 1) return undefined; const newGroup = groupings[currentGroupIndex - 1]; return newGroup; }); /** * Return canvas label, or alternatively return the given index + 1 to be displayed. * @param {object} state * @param {object} props * @param {string} props.canvasId * @param {string} props.manifestId * @returns {string|number} */ export const getCanvasLabel = createSelector( [getCanvas, getManifestLocale], (canvas, locale) => canvas && (canvas.getLabel().length > 0 ? canvas.getLabel().getValue(locale) : String(canvas.index + 1)), ); /** * Return canvas description. * @param {object} canvas * @param {string} companionWindowId */ export const getCanvasDescription = createSelector([getCanvas], (canvas) => canvas && canvas.getProperty('description')); /** * Return visible non tiled canvas resources. * @param {object} * @param {string} windowId * @returns {Array} */ export const getVisibleCanvasNonTiledResources = createSelector( [getVisibleCanvases, getMiradorCanvasWrapper], (canvases, getMiradorCanvas) => flatten(canvases.map((canvas) => getMiradorCanvas(canvas).imageResources)).filter( (resource) => !getIiifResourceImageService(resource), ), ); /** * Returns visible canvas text resources. * @param {object} state * @param {string} windowId * @return {Array} */ export const getVisibleCanvasTextResources = createSelector( [getVisibleCanvases, getMiradorCanvasWrapper], (canvases, getMiradorCanvas) => flatten(canvases.map((canvas) => getMiradorCanvas(canvas).textResources)), ); /** * Returns visible canvas video resources. * @param {object} state * @param {string} windowId * @return {Array} */ export const getVisibleCanvasVideoResources = createSelector( [getVisibleCanvases, getMiradorCanvasWrapper], (canvases, getMiradorCanvas) => flatten(canvases.map((canvas) => getMiradorCanvas(canvas).videoResources)), ); /** * Returns visible canvas captions. * @param {object} state * @param {string} windowId * @return {Array} */ export const getVisibleCanvasCaptions = createSelector( [getVisibleCanvases, getMiradorCanvasWrapper], (canvases, getMiradorCanvas) => flatten( canvases.map((canvas) => { const miradorCanvas = getMiradorCanvas(canvas); // prefer v3, fallback to v2, which can also be an empty array if no captions exist. if (miradorCanvas.v3VttContent.length) return miradorCanvas.v3VttContent; return miradorCanvas.v2VttContent; }), ), ); /** * Returns visible canvas audio resources. * @param {object} state * @param {string} windowId * @return {Array} */ export const getVisibleCanvasAudioResources = createSelector( [getVisibleCanvases, getMiradorCanvasWrapper], (canvases, getMiradorCanvas) => flatten(canvases.map((canvas) => getMiradorCanvas(canvas).audioResources)), ); /** * Returns info response. * @param {object} state * @param {object} props * @param {string} props.windowId * @param {string} props.canvasId * @param {string} props.infoId * @returns {object|undefined} */ export const selectInfoResponse = createSelector( [(state, { infoId }) => infoId, getCanvas, getMiradorCanvasWrapper, selectInfoResponses], (infoId, canvas, getMiradorCanvas, infoResponses) => { let iiifServiceId = infoId; if (!infoId) { if (!canvas) return undefined; const image = getMiradorCanvas(canvas).iiifImageResources[0]; iiifServiceId = image && getIiifResourceImageService(image)?.id; } return ( iiifServiceId && infoResponses[iiifServiceId] && !infoResponses[iiifServiceId].isFetching && infoResponses[iiifServiceId] ); }, );