diff --git a/__tests__/src/components/WindowSideBarCanvasPanel.test.js b/__tests__/src/components/WindowSideBarCanvasPanel.test.js index e01de7a023d63ddbb5747e67434e9a7e6450650e..d38027ec1e54b53c2acbb8c7a96f094368f8adaa 100644 --- a/__tests__/src/components/WindowSideBarCanvasPanel.test.js +++ b/__tests__/src/components/WindowSideBarCanvasPanel.test.js @@ -7,7 +7,6 @@ import manifesto from 'manifesto.js'; import { WindowSideBarCanvasPanel } from '../../../src/components/WindowSideBarCanvasPanel'; import { CanvasThumbnail } from '../../../src/components/CanvasThumbnail'; import manifestJson from '../../fixtures/version-2/019.json'; -import { getIdAndLabelOfCanvases } from '../../../src/state/selectors'; /** * Helper function to create a shallow wrapper around WindowSideBarCanvasPanel @@ -68,21 +67,20 @@ describe('WindowSideBarCanvasPanel', () => { it('should set the correct labels', () => { const wrapper = createWrapper(); - const canvases = manifesto.create(manifestJson).getSequences()[0].getCanvases(); - const idsAndLabels = getIdAndLabelOfCanvases(canvases); + expect(wrapper .find(List) .find(Typography) .at(0) .render() - .text()).toBe(idsAndLabels[0].label); + .text()).toBe('Test 19 Canvas: 1'); expect(wrapper .find(List) .find(Typography) .at(1) .render() - .text()).toBe(idsAndLabels[1].label); + .text()).toBe('Image 1'); }); it('should call the onClick handler of a list item', () => { @@ -90,4 +88,36 @@ describe('WindowSideBarCanvasPanel', () => { wrapper.find(ListItem).at(1).simulate('click'); expect(setCanvas).toHaveBeenCalledTimes(1); }); + + describe('getIdAndLabelOfCanvases', () => { + it('should return id and label of each canvas in manifest', () => { + const canvases = manifesto + .create(manifestJson) + .getSequences()[0] + .getCanvases(); + const wrapper = createWrapper({ canvases }); + const received = wrapper.instance().getIdAndLabelOfCanvases(canvases); + const expected = [ + { + id: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', + label: 'Test 19 Canvas: 1', + }, + { + id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', + label: 'Image 1', + }, + { + id: 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', + label: 'Image 2', + }, + ]; + expect(received).toEqual(expected); + }); + + it('should return empty array if canvas if empty', () => { + const wrapper = createWrapper({ canvases: [] }); + const received = wrapper.instance().getIdAndLabelOfCanvases([]); + expect(received).toEqual([]); + }); + }); }); diff --git a/__tests__/src/selectors/index.test.js b/__tests__/src/selectors/index.test.js index fdd9ae417dffce6bafbda95487853d8e2d2dde61..c2391dfede742134be0bb4c5b15ff55c9540a2b9 100644 --- a/__tests__/src/selectors/index.test.js +++ b/__tests__/src/selectors/index.test.js @@ -1,25 +1,17 @@ -import manifesto from 'manifesto.js'; import manifestFixture001 from '../../fixtures/version-2/001.json'; -import manifestFixture002 from '../../fixtures/version-2/002.json'; -import manifestFixture019 from '../../fixtures/version-2/019.json'; -import manifestFixtureWithAProvider from '../../fixtures/version-3/with_a_provider.json'; import { getCanvasLabel, getCompanionWindowForPosition, getAnnotationResourcesByMotivation, getIdAndContentOfResources, getLanguagesFromConfigWithCurrent, - getSelectedCanvas, - getSelectedCanvases, getThumbnailNavigationPosition, getSelectedAnnotationIds, getSelectedTargetAnnotations, getSelectedTargetsAnnotations, getSelectedTargetAnnotationResources, getWindowViewType, - getIdAndLabelOfCanvases, getCompanionWindowsOfWindow, - getWindowTitles, } from '../../../src/state/selectors'; import Annotation from '../../../src/lib/Annotation'; import AnnotationResource from '../../../src/lib/AnnotationResource'; @@ -36,17 +28,17 @@ describe('getThumbnailNavigationPosition', () => { }; it('should return thumbnail navigation position if window exists', () => { - const received = getThumbnailNavigationPosition(state, 'a'); + const received = getThumbnailNavigationPosition(state, { windowId: 'a' }); expect(received).toBe('bottom'); }); it('should return undefined if position does not exist in window', () => { - const received = getThumbnailNavigationPosition(state, 'b'); + const received = getThumbnailNavigationPosition(state, { windowId: 'b' }); expect(received).toBeUndefined(); }); it('should return undefined if window does not exists', () => { - const received = getThumbnailNavigationPosition(state, 'c'); + const received = getThumbnailNavigationPosition(state, { windowId: 'c' }); expect(received).toBeUndefined(); }); }); @@ -60,40 +52,53 @@ describe('getWindowViewType', () => { }; it('should return view type if window exists', () => { - const received = getWindowViewType(state, 'a'); + const received = getWindowViewType(state, { windowId: 'a' }); expect(received).toBe('single'); }); it('should return undefined if view type does not exist in window', () => { - const received = getWindowViewType(state, 'b'); + const received = getWindowViewType(state, { windowId: 'b' }); expect(received).toBeUndefined(); }); it('should return undefined if window does not exists', () => { - const received = getWindowViewType(state, 'c'); + const received = getWindowViewType(state, { windowId: 'c' }); expect(received).toBeUndefined(); }); }); describe('getCanvasLabel', () => { it('should return label of the canvas', () => { - const canvas = manifesto - .create(manifestFixture001) - .getSequences()[0] - .getCanvases()[0]; - - const received = getCanvasLabel(canvas); + const state = { manifests: { a: { json: manifestFixture001 } } }; + const received = getCanvasLabel(state, { manifestId: 'a', canvasIndex: 0 }); expect(received).toBe('Whole Page'); }); it('should return undefined if the canvas is undefined', () => { - expect(getCanvasLabel(undefined)).toBeUndefined(); + const state = { manifests: { } }; + expect(getCanvasLabel(state, { manifestId: 'b', canvasIndex: 0 })).toBeUndefined(); }); it('should return the canvas index as (+1) as string if no label given', () => { - const canvas = { getLabel: () => [] }; - const received = getCanvasLabel(canvas, 42); - expect(received).toBe('43'); + const manifest = { + '@context': 'http://iiif.io/api/presentation/2/context.json', + '@id': + 'http://iiif.io/api/presentation/2.1/example/fixtures/19/manifest.json', + '@type': 'sc:Manifest', + sequences: [ + { + canvases: [ + { + '@id': 'some-canvas-without-a-label', + }, + ], + }, + ], + }; + + const state = { manifests: { a: { json: manifest } } }; + const received = getCanvasLabel(state, { manifestId: 'a', canvasIndex: 0 }); + expect(received).toBe('1'); }); }); @@ -202,36 +207,6 @@ describe('getIdAndContentOfResources', () => { }); }); -describe('getIdAndLabelOfCanvases', () => { - it('should return id and label of each canvas in manifest', () => { - const canvases = manifesto - .create(manifestFixture019) - .getSequences()[0] - .getCanvases(); - const received = getIdAndLabelOfCanvases(canvases); - const expected = [ - { - id: 'http://iiif.io/api/presentation/2.0/example/fixtures/canvas/24/c1.json', - label: 'Test 19 Canvas: 1', - }, - { - id: 'https://purl.stanford.edu/fr426cg9537/iiif/canvas/fr426cg9537_1', - label: 'Image 1', - }, - { - id: 'https://purl.stanford.edu/rz176rt6531/iiif/canvas/rz176rt6531_1', - label: 'Image 2', - }, - ]; - expect(received).toEqual(expected); - }); - - it('should return empty array if canvas if empty', () => { - const received = getIdAndLabelOfCanvases([]); - expect(received).toEqual([]); - }); -}); - describe('getCompanionWindowForPosition', () => { const state = { windows: { a: { companionWindowIds: ['abc'] } }, @@ -242,19 +217,19 @@ describe('getCompanionWindowForPosition', () => { }; it('the companion window type based on the given position', () => { - const received = getCompanionWindowForPosition(state, 'a', 'right'); + const received = getCompanionWindowForPosition(state, { windowId: 'a', position: 'right' }); expect(received.id).toEqual('abc'); }); it('returns undefined if the given window does not exist', () => { - const received = getCompanionWindowForPosition(state, 'c', 'right'); + const received = getCompanionWindowForPosition(state, { windowId: 'c', position: 'right' }); expect(received).toBeUndefined(); }); it('returns undefined if a companion window at the given position does not exist', () => { - const received = getCompanionWindowForPosition(state, 'a', 'bottom'); + const received = getCompanionWindowForPosition(state, { windowId: 'a', position: 'bottom' }); expect(received).toBeUndefined(); }); @@ -295,7 +270,7 @@ describe('getCompanionWindowsOfWindow', () => { }; it('should return companion windows for a given window id', () => { - const received = getCompanionWindowsOfWindow(state, 'abc123'); + const received = getCompanionWindowsOfWindow(state, { windowId: 'abc123' }); expect(received).toEqual([ { id: 'foo', content: 'info' }, diff --git a/src/components/GalleryView.js b/src/components/GalleryView.js index 9c9e66b4a09bf1fdefa69af35dbbbd90ffdb9313..5b348e60b074ae4a087279a39e34bf9becdeb404 100644 --- a/src/components/GalleryView.js +++ b/src/components/GalleryView.js @@ -2,7 +2,6 @@ import React, { Component } from 'react'; import PropTypes from 'prop-types'; import Typography from '@material-ui/core/Typography'; import ManifestoCanvas from '../lib/ManifestoCanvas'; -import { getCanvasLabel } from '../state/selectors'; import { CanvasThumbnail } from './CanvasThumbnail'; import ns from '../config/css-ns'; @@ -52,7 +51,7 @@ export class GalleryView extends Component { aspectRatio={manifestoCanvas.aspectRatio} /> <Typography variant="caption"> - {getCanvasLabel(canvas, canvas.index)} + {manifestoCanvas.getLabel()} </Typography> </div> ); diff --git a/src/components/ThumbnailNavigation.js b/src/components/ThumbnailNavigation.js index 2b185d1c1225ab9c2951a7ca47f1c21c41834715..2626aaadbb367d23dfe07edb4e5afab6c22dae20 100644 --- a/src/components/ThumbnailNavigation.js +++ b/src/components/ThumbnailNavigation.js @@ -5,7 +5,6 @@ import Grid from 'react-virtualized/dist/commonjs/Grid'; import GridListTile from '@material-ui/core/GridListTile'; import GridListTileBar from '@material-ui/core/GridListTileBar'; import Typography from '@material-ui/core/Typography'; -import { getCanvasLabel } from '../state/selectors'; import { CanvasThumbnail } from './CanvasThumbnail'; import ManifestoCanvas from '../lib/ManifestoCanvas'; import ns from '../config/css-ns'; @@ -97,7 +96,7 @@ export class ThumbnailNavigation extends Component { classes={{ root: classes.root }} title={( <Typography classes={{ root: classes.title }} variant="caption"> - {getCanvasLabel(canvas, canvas.index)} + {manifestoCanvas.getLabel()} </Typography> )} /> diff --git a/src/components/WindowSideBarCanvasPanel.js b/src/components/WindowSideBarCanvasPanel.js index 80eae9a8e822f1344acb91fe46a7d5685923bbe1..f8f641fa7e2713a75ee135d4e3308d8f140cfb57 100644 --- a/src/components/WindowSideBarCanvasPanel.js +++ b/src/components/WindowSideBarCanvasPanel.js @@ -10,7 +10,6 @@ import Select from '@material-ui/core/Select'; import { CanvasThumbnail } from './CanvasThumbnail'; import ManifestoCanvas from '../lib/ManifestoCanvas'; import CompanionWindow from '../containers/CompanionWindow'; -import { getIdAndLabelOfCanvases } from '../state/selectors'; /** * a panel showing the canvases for a given manifest @@ -24,6 +23,16 @@ export class WindowSideBarCanvasPanel extends Component { this.handleVariantChange = this.handleVariantChange.bind(this); } + /** @private */ + getIdAndLabelOfCanvases() { + const { canvases } = this.props; + + return canvases.map((canvas, index) => ({ + id: canvas.id, + label: new ManifestoCanvas(canvas).getLabel(), + })); + } + /** */ handleVariantChange(event) { this.setState({ variant: event.target.value }); @@ -88,7 +97,7 @@ export class WindowSideBarCanvasPanel extends Component { const { variant } = this.state; - const canvasesIdAndLabel = getIdAndLabelOfCanvases(canvases); + const canvasesIdAndLabel = this.getIdAndLabelOfCanvases(canvases); return ( <CompanionWindow title={t('canvasIndex')} diff --git a/src/containers/CompanionArea.js b/src/containers/CompanionArea.js index f8b29c6825ac731664f881c0093551852e0b6477..f9d577e2489addb37b578fb708a282a7271a7269 100644 --- a/src/containers/CompanionArea.js +++ b/src/containers/CompanionArea.js @@ -10,7 +10,7 @@ import { CompanionArea } from '../components/CompanionArea'; /** */ const mapStateToProps = (state, { windowId, position }) => ({ sideBarOpen: state.windows[windowId].sideBarOpen, - companionWindows: getCompanionWindowsOfWindow(state, windowId) + companionWindows: getCompanionWindowsOfWindow(state, { windowId }) .filter(cw => cw.position === position), companionAreaOpen: position !== 'left' || state.windows[windowId].companionAreaOpen, }); diff --git a/src/containers/OpenSeadragonViewer.js b/src/containers/OpenSeadragonViewer.js index cbc4861798567df5b782a9ba6e18c51364c1dc9e..d0aecea6e5f6abe235e13986d836459018a5d520 100644 --- a/src/containers/OpenSeadragonViewer.js +++ b/src/containers/OpenSeadragonViewer.js @@ -9,7 +9,6 @@ import * as actions from '../state/actions'; import { getCanvasLabel, getSelectedAnnotationIds, - getSelectedCanvas, getSelectedTargetAnnotationResources, } from '../state/selectors'; @@ -22,10 +21,7 @@ const mapStateToProps = ({ viewers, windows, manifests, annotations, }, { windowId, currentCanvases }) => ({ viewer: viewers[windowId], - label: getCanvasLabel( - getSelectedCanvas({ windows, manifests }, { windowId }), - windows[windowId].canvasIndex, - ), + label: getCanvasLabel({ windows, manifests }, { windowId, canvasIndex: 'selected' }), annotations: getSelectedTargetAnnotationResources( { annotations }, currentCanvases.map(c => c.id), diff --git a/src/containers/ViewerInfo.js b/src/containers/ViewerInfo.js index 9581824ccab9a2b41fb6bd6b5c79ace79cae1d14..ad0fcfd101cae2559d82297fba95bb783c78825b 100644 --- a/src/containers/ViewerInfo.js +++ b/src/containers/ViewerInfo.js @@ -18,7 +18,7 @@ const mapStateToProps = (state, props) => { return { canvasCount: canvases.length, canvasIndex, - canvasLabel: getCanvasLabel(canvases[canvasIndex], canvasIndex), + canvasLabel: getCanvasLabel(state, { windowId, canvasIndex }), }; }; diff --git a/src/containers/Window.js b/src/containers/Window.js index 318daa9b52ad7530f2deaf5c4de2e0d4b31efc34..2bdfa90e2efd6bec46fd4ec38207ad7db1f1a82e 100644 --- a/src/containers/Window.js +++ b/src/containers/Window.js @@ -18,7 +18,7 @@ const mapStateToProps = (state, props) => ({ window: state.windows[props.window.id], workspaceType: state.config.workspace.type, label: getManifestTitle(state, { windowId: props.window.id }), - thumbnailNavigationPosition: getThumbnailNavigationPosition(state, props.window.id), + thumbnailNavigationPosition: getThumbnailNavigationPosition(state, { windowId: props.window.id }), }); /** diff --git a/src/containers/WindowCanvasNavigationControls.js b/src/containers/WindowCanvasNavigationControls.js index b76793a10ee93704145d1466876ce19d1d31bca8..a8b8384879ab07c538f816113fa62e11a48b292b 100644 --- a/src/containers/WindowCanvasNavigationControls.js +++ b/src/containers/WindowCanvasNavigationControls.js @@ -3,17 +3,13 @@ import { compose } from 'redux'; import { withPlugins } from '../extend'; import { getCanvasLabel, - getSelectedCanvas, } from '../state/selectors'; import { WindowCanvasNavigationControls } from '../components/WindowCanvasNavigationControls'; /** */ const mapStateToProps = (state, { windowId }) => ({ window: state.windows[windowId], - canvasLabel: getCanvasLabel( - getSelectedCanvas(state, { windowId }), - state.windows[windowId].canvasIndex, - ), + canvasLabel: getCanvasLabel(state, { windowId, canvasIndex: 'selected' }), visible: state.workspace.focusedWindowId === windowId, }); diff --git a/src/containers/WindowSideBarButtons.js b/src/containers/WindowSideBarButtons.js index 2cec11da4ce48d811b600db0899b272341063da8..17dbfd7bc913e57fc69f5e10cb1a938417098c63 100644 --- a/src/containers/WindowSideBarButtons.js +++ b/src/containers/WindowSideBarButtons.js @@ -36,7 +36,7 @@ const mapStateToProps = (state, { windowId }) => ({ getSelectedTargetAnnotations(state, (getSelectedCanvas(state, { windowId }) || {}).id), ['oa:commenting', 'sc:painting'], ).length > 0, - sideBarPanel: (getCompanionWindowForPosition(state, windowId, 'left') || {}).content, + sideBarPanel: (getCompanionWindowForPosition(state, { windowId, position: 'left' }) || {}).content, }); /** */ diff --git a/src/containers/WindowSideBarInfoPanel.js b/src/containers/WindowSideBarInfoPanel.js index dd10cbe92196623d7b6b013a4f96c2178e484509..e55cc7a520ad0537a6f9c6330c49e50adc32ffc5 100644 --- a/src/containers/WindowSideBarInfoPanel.js +++ b/src/containers/WindowSideBarInfoPanel.js @@ -20,11 +20,8 @@ import { WindowSideBarInfoPanel } from '../components/WindowSideBarInfoPanel'; * @private */ const mapStateToProps = (state, { windowId }) => ({ - canvasLabel: getCanvasLabel( - getSelectedCanvas(state, { windowId }), - state.windows[windowId].canvasIndex, - ), - canvasDescription: getCanvasDescription(getSelectedCanvas(state, { windowId })), + canvasLabel: getCanvasLabel(state, { windowId, canvasIndex: 'selected' }), + canvasDescription: getCanvasDescription(state, { windowId, canvasIndex: 'selected' }), canvasMetadata: getDestructuredMetadata(getSelectedCanvas(state, { windowId })), manifestLabel: getManifestTitle(state, { windowId }), manifestDescription: getManifestDescription(state, { windowId }), diff --git a/src/containers/WindowThumbnailSettings.js b/src/containers/WindowThumbnailSettings.js index 0fa87898f2c0b6877f70e50b777f4d3bbb6ee5e5..86ece45e61d629e6425997f314c2816905220ea2 100644 --- a/src/containers/WindowThumbnailSettings.js +++ b/src/containers/WindowThumbnailSettings.js @@ -19,9 +19,9 @@ const mapDispatchToProps = { setWindowThumbnailPosition: actions.setWindowThumbn * @memberof WindowViewer * @private */ -const mapStateToProps = (state, props) => ( +const mapStateToProps = (state, { windowId }) => ( { - thumbnailNavigationPosition: getThumbnailNavigationPosition(state, props.windowId), + thumbnailNavigationPosition: getThumbnailNavigationPosition(state, { windowId }), } ); diff --git a/src/containers/WindowViewSettings.js b/src/containers/WindowViewSettings.js index 1a7d8c44ed4911d6f23f24e6fe71115508d973ea..dcd29e9ea9ed3cf4ceb058c31ac2512b1359d054 100644 --- a/src/containers/WindowViewSettings.js +++ b/src/containers/WindowViewSettings.js @@ -19,9 +19,9 @@ const mapDispatchToProps = { setWindowViewType: actions.setWindowViewType }; * @memberof WindowViewer * @private */ -const mapStateToProps = (state, props) => ( +const mapStateToProps = (state, { windowId }) => ( { - windowViewType: getWindowViewType(state, props.windowId), + windowViewType: getWindowViewType(state, { windowId }), } ); diff --git a/src/lib/ManifestoCanvas.js b/src/lib/ManifestoCanvas.js index 684ae96ee85cbe8157c1d9e67f5efe1957ccb5eb..221691aa9e04e20e87d003aacb7938435d7bcfb2 100644 --- a/src/lib/ManifestoCanvas.js +++ b/src/lib/ManifestoCanvas.js @@ -79,6 +79,15 @@ export default class ManifestoCanvas { ); } + /** + * Get the canvas label + */ + getLabel() { + return this.canvas.getLabel().length > 0 + ? this.canvas.getLabel().map(label => label.value)[0] + : String(this.canvas.index + 1); + } + /** * Creates a canonical image request for a thumb * @param {Number} height diff --git a/src/state/selectors/canvases.js b/src/state/selectors/canvases.js index 26d74e5dac2ca23be28bc48141b0a56c37e0f73e..8051a0d019dd4bcf1270989d0e457888b978834d 100644 --- a/src/state/selectors/canvases.js +++ b/src/state/selectors/canvases.js @@ -2,18 +2,27 @@ import { createSelector } from 'reselect'; import CanvasGroupings from '../../lib/CanvasGroupings'; import { getManifestoInstance } from './manifests'; +export const getCanvases = createSelector( + [getManifestoInstance], + manifest => manifest && manifest.getSequences()[0].getCanvases(), +); + /** -* Return the current canvas selected in a window +* Return the canvas selected by an index * @param {object} state * @param {object} props * @param {string} props.manifestId * @param {string} props.windowId * @return {Object} */ -export const getSelectedCanvas = createSelector( +export const getCanvas = createSelector( [ getManifestoInstance, - (state, { windowId }) => state.windows[windowId].canvasIndex, + (state, { windowId, canvasIndex }) => ( + canvasIndex === 'selected' + ? state.windows[windowId].canvasIndex + : canvasIndex + ), ], (manifest, canvasIndex) => manifest && manifest @@ -21,6 +30,18 @@ export const getSelectedCanvas = createSelector( .getCanvasByIndex(canvasIndex), ); +/** +* Return the current canvas selected in a window +* @param {object} state +* @param {object} props +* @param {string} props.manifestId +* @param {string} props.windowId +* @return {Object} +*/ +export function getSelectedCanvas(state, props) { + return getCanvas(state, { ...props, canvasIndex: 'selected' }); +} + /** * Return the current canvases selected in a window * For book view returns 2, for single returns 1 @@ -32,12 +53,12 @@ export const getSelectedCanvas = createSelector( */ export const getSelectedCanvases = createSelector( [ - getManifestoInstance, + getCanvases, (state, { windowId }) => state.windows[windowId], ], - (manifest, { canvasIndex, view }) => manifest + (canvases, { canvasIndex, view }) => canvases && new CanvasGroupings( - manifest.getSequences()[0].getCanvases(), + canvases, view, ).getCanvases(canvasIndex), ); diff --git a/src/state/selectors/index.js b/src/state/selectors/index.js index c51fdf2df3a9c7a298bffb59357da71d29a90c83..fb5f2f433329dc23d8e9840b12e19654a5acb8c9 100644 --- a/src/state/selectors/index.js +++ b/src/state/selectors/index.js @@ -1,23 +1,13 @@ +import { createSelector } from 'reselect'; import filter from 'lodash/filter'; import flatten from 'lodash/flatten'; import Annotation from '../../lib/Annotation'; +import { getCanvas } from './canvases'; export * from './canvases'; export * from './manifests'; export * from './windows'; -/** -* Return ids and labels of canvases -* @ param {Array} canvases -* @return {Array} - [ {id: 'id', label: 'label' }, ... ] -*/ -export function getIdAndLabelOfCanvases(canvases) { - return canvases.map((canvas, index) => ({ - id: canvas.id, - label: getCanvasLabel(canvas, index), - })); -} - /** * Return annotations for an array of targets * @param {object} state @@ -76,18 +66,25 @@ export function getIdAndContentOfResources(resources) { })); } +/** */ +function getWindow(state, { windowId }) { + return state.windows && state.windows[windowId]; +} + /** Return position of thumbnail navigation in a certain window. * @param {object} state * @param {String} windowId * @param {String} */ -export function getThumbnailNavigationPosition(state, windowId) { - return state.windows[windowId] - && state.windows[windowId].thumbnailNavigationId - && state.companionWindows[state.windows[windowId].thumbnailNavigationId] - && state.companionWindows[state.windows[windowId].thumbnailNavigationId].position; -} - +export const getThumbnailNavigationPosition = createSelector( + [ + getWindow, + state => state.companionWindows, + ], + (window, companionWindows) => window + && companionWindows[window.thumbnailNavigationId] + && companionWindows[window.thumbnailNavigationId].position, +); /** Return type of view in a certain window. * @param {object} state @@ -96,68 +93,66 @@ export function getThumbnailNavigationPosition(state, windowId) { * @param {string} props.windowId * @param {String} */ -export function getWindowViewType(state, windowId) { - return state.windows[windowId] && state.windows[windowId].view; -} +export const getWindowViewType = createSelector( + [getWindow], + window => window && window.view, +); /** * Return canvas label, or alternatively return the given index + 1 to be displayed * @param {object} canvas * @return {String|Integer} */ -export function getCanvasLabel(canvas, canvasIndex) { - if (!canvas) { - return undefined; - } - if (canvas.getLabel().length > 0) { - return canvas.getLabel().map(label => label.value)[0]; - } - return String(canvasIndex + 1); -} +export const getCanvasLabel = createSelector( + [getCanvas], + canvas => (canvas && ( + canvas.getLabel().length > 0 + ? canvas.getLabel().map(label => label.value)[0] + : String(canvas.index + 1) + )), +); /** * Return canvas description * @param {object} canvas * @param {String} */ -export function getCanvasDescription(canvas) { - return canvas - && canvas.getProperty('description'); -} - -/** -* Return the companion window string from state in a given windowId and position -* @param {object} state -* @param {String} windowId -* @param {String} position -* @return {String} -*/ -export function getCompanionWindowForPosition(state, windowId, position) { - return ((state.windows[windowId] || {}).companionWindowIds || []).map(key => ( - state.companionWindows[key] - )).find(cw => ( - cw.position === position - )); -} +export const getCanvasDescription = createSelector( + [getCanvas], + canvas => canvas && canvas.getProperty('description'), +); /** * Return compantion window ids from a window * @param {String} windowId * @return {Array} */ -export function getCompanionWindowIds(state, windowId) { - return state.windows[windowId].companionWindowIds; -} +export const getCompanionWindowIds = createSelector( + [getWindow], + window => (window && window.companionWindowIds) || [], +); /** * Return companion windows of a window * @param {String} windowId * @return {Array} */ -export function getCompanionWindowsOfWindow(state, windowId) { - return getCompanionWindowIds(state, windowId) - .map(id => state.companionWindows[id]); -} +export const getCompanionWindowsOfWindow = createSelector( + [getCompanionWindowIds, state => state.companionWindows], + (companionWindowIds, companionWindows) => companionWindowIds.map(id => companionWindows[id]), +); + +/** +* Return the companion window string from state in a given windowId and position +* @param {object} state +* @param {String} windowId +* @param {String} position +* @return {String} +*/ +export const getCompanionWindowForPosition = createSelector( + [getCompanionWindowsOfWindow, (state, { position }) => position], + (companionWindows, position) => companionWindows.find(cw => cw.position === position), +); /** * Return languages from config (in state) and indicate which is currently set diff --git a/src/state/selectors/manifests.js b/src/state/selectors/manifests.js index 2d57c9607f1d696b19c279bf7c3b31b877cec9e9..3a25e301d38531bd4d49b4dca0e5d7243841a28c 100644 --- a/src/state/selectors/manifests.js +++ b/src/state/selectors/manifests.js @@ -6,7 +6,7 @@ import ManifestoCanvas from '../../lib/ManifestoCanvas'; export function getManifest(state, { manifestId, windowId }) { return state.manifests[ manifestId - || (windowId && state.windows[windowId] && state.windows[windowId].manifestId) + || (windowId && state.windows && state.windows[windowId] && state.windows[windowId].manifestId) ]; }