Skip to content

Commit 2bfd6a1

Browse files
authored
Merge pull request #3605 from ProjectMirador/react-full-screen
Update react-full-screen
2 parents 704aee6 + 5d2fda7 commit 2bfd6a1

10 files changed

Lines changed: 66 additions & 104 deletions

File tree

__tests__/src/actions/workspace.test.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,6 @@ describe('workspace actions', () => {
1313
expect(actions.updateWorkspace(options)).toEqual(expectedAction);
1414
});
1515
});
16-
describe('setWorkspaceFullscreen', () => {
17-
it('should return correct action type if set to true', () => {
18-
const receivedAction = actions.setWorkspaceFullscreen(true);
19-
const expectedAction = {
20-
isFullscreenEnabled: true,
21-
type: ActionTypes.SET_WORKSPACE_FULLSCREEN,
22-
};
23-
expect(receivedAction).toEqual(expectedAction);
24-
});
25-
it('should return correct action type if set to false', () => {
26-
const receivedAction = actions.setWorkspaceFullscreen(false);
27-
const expectedAction = {
28-
isFullscreenEnabled: false,
29-
type: ActionTypes.SET_WORKSPACE_FULLSCREEN,
30-
};
31-
expect(receivedAction).toEqual(expectedAction);
32-
});
33-
});
3416
describe('updateWorkspaceMosaicLayout', () => {
3517
it('should updates mosaic layout', () => {
3618
const options = { foo: 'bar' };

__tests__/src/components/AppProviders.test.js

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React from 'react';
22
import { shallow } from 'enzyme';
33
import { ThemeProvider, StylesProvider } from '@material-ui/core/styles';
4-
import Fullscreen from 'react-full-screen';
54
import { DndContext, DndProvider } from 'react-dnd';
65
import { AppProviders } from '../../../src/components/AppProviders';
76
import settings from '../../../src/config/settings';
@@ -14,7 +13,6 @@ function createWrapper(props) {
1413
<AppProviders
1514
language="en"
1615
isFullscreenEnabled={false}
17-
setWorkspaceFullscreen={() => {}}
1816
theme={settings.theme}
1917
translations={{}}
2018
t={k => k}
@@ -28,7 +26,6 @@ describe('AppProviders', () => {
2826
const wrapper = createWrapper();
2927
expect(wrapper.find(ThemeProvider).length).toBe(1);
3028
expect(wrapper.find(StylesProvider).length).toBe(1);
31-
expect(wrapper.find(Fullscreen).length).toBe(1);
3229
});
3330

3431
it('sets up a theme based on the config passed in merged w/ MaterialUI', () => {
@@ -44,23 +41,6 @@ describe('AppProviders', () => {
4441
expect(wrapper.instance().i18n.t('off')).toEqual('on');
4542
});
4643

47-
it('should pass setWorkspaceFullscreen to Fullscreen.onChange', () => {
48-
const mockFn = jest.fn();
49-
const wrapper = createWrapper({ setWorkspaceFullscreen: mockFn });
50-
expect(wrapper.find(Fullscreen).first().prop('onChange'))
51-
.toBe(mockFn);
52-
});
53-
54-
it('should pass isFullscreenEnabled to Fullscreen.enabled', () => {
55-
let wrapper = createWrapper({ isFullscreenEnabled: false });
56-
expect(wrapper.find(Fullscreen).first().prop('enabled'))
57-
.toEqual(false);
58-
59-
wrapper = createWrapper({ isFullscreenEnabled: true });
60-
expect(wrapper.find(Fullscreen).first().prop('enabled'))
61-
.toEqual(true);
62-
});
63-
6444
describe('componentDidUpdate()', () => {
6545
it('changes the i18n language if the language prop has been updated', () => {
6646
const wrapper = createWrapper();

__tests__/src/components/FullScreenButton.test.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@ import FullscreenIcon from '@material-ui/icons/FullscreenSharp';
44
import FullscreenExitIcon from '@material-ui/icons/FullscreenExitSharp';
55
import MiradorMenuButton from '../../../src/containers/MiradorMenuButton';
66
import { FullScreenButton } from '../../../src/components/FullScreenButton';
7+
import FullScreenContext from '../../../src/contexts/FullScreenContext';
78

89
/** */
9-
function createWrapper(props) {
10+
function createWrapper(props, contextProps = { active: false }) {
1011
return shallow(
1112
<FullScreenButton
1213
classes={{}}
1314
className="xyz"
14-
setWorkspaceFullscreen={() => {}}
15-
isFullscreenEnabled={false}
1615
{...props}
1716
/>,
18-
);
17+
{
18+
wrappingComponent: FullScreenContext.Provider,
19+
wrappingComponentProps: { value: { enter: () => { }, exit: () => { }, ...contextProps } },
20+
},
21+
).dive();
1922
}
2023

2124
describe('FullScreenButton', () => {
@@ -30,10 +33,10 @@ describe('FullScreenButton', () => {
3033
});
3134

3235
describe('when not in fullscreen', () => {
33-
let setWorkspaceFullscreen;
36+
let enter;
3437
beforeAll(() => {
35-
setWorkspaceFullscreen = jest.fn();
36-
wrapper = createWrapper({ setWorkspaceFullscreen });
38+
enter = jest.fn();
39+
wrapper = createWrapper({}, { enter });
3740
menuButton = wrapper.find(MiradorMenuButton);
3841
});
3942

@@ -45,17 +48,17 @@ describe('FullScreenButton', () => {
4548
expect(menuButton.props()['aria-label']).toEqual('workspaceFullScreen');
4649
});
4750

48-
it('triggers the setWorkspaceFullscreen prop with the appropriate boolean', () => {
51+
it('triggers the handle enter with the appropriate boolean', () => {
4952
menuButton.props().onClick(); // Trigger the onClick prop
50-
expect(setWorkspaceFullscreen).toHaveBeenCalledWith(true);
53+
expect(enter).toHaveBeenCalled();
5154
});
5255
});
5356

5457
describe('when in fullscreen', () => {
55-
let setWorkspaceFullscreen;
58+
let exit;
5659
beforeAll(() => {
57-
setWorkspaceFullscreen = jest.fn();
58-
wrapper = createWrapper({ isFullscreenEnabled: true, setWorkspaceFullscreen });
60+
exit = jest.fn();
61+
wrapper = createWrapper({}, { active: true, exit });
5962
menuButton = wrapper.find(MiradorMenuButton);
6063
});
6164

@@ -67,9 +70,9 @@ describe('FullScreenButton', () => {
6770
expect(menuButton.props()['aria-label']).toEqual('exitFullScreen');
6871
});
6972

70-
it('triggers the setWorkspaceFullscreen prop with the appropriate boolean', () => {
73+
it('triggers the handle exit with the appropriate boolean', () => {
7174
menuButton.props().onClick(); // Trigger the onClick prop
72-
expect(setWorkspaceFullscreen).toHaveBeenCalledWith(false);
75+
expect(exit).toHaveBeenCalled();
7376
});
7477
});
7578
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
"react-dnd-html5-backend": "^10.0.2",
6161
"react-dnd-multi-backend": "^5.0.0",
6262
"react-dnd-touch-backend": "^10.0.2",
63-
"react-full-screen": "^0.2.4",
63+
"react-full-screen": "^1.1.1",
6464
"react-i18next": "^11.7.0",
6565
"react-image": "^4.0.1",
6666
"react-mosaic-component": "^4.0.1",

src/components/AppProviders.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { Component } from 'react';
22
import PropTypes from 'prop-types';
3-
import Fullscreen from 'react-full-screen';
3+
import { FullScreen, useFullScreenHandle } from 'react-full-screen';
44
import { I18nextProvider } from 'react-i18next';
55
import { LiveAnnouncer } from 'react-aria-live';
66
import {
@@ -12,6 +12,7 @@ import HTML5toTouch from 'react-dnd-multi-backend/dist/cjs/HTML5toTouch';
1212
import { create } from 'jss';
1313
import rtl from 'jss-rtl';
1414
import createI18nInstance from '../i18n';
15+
import FullScreenContext from '../contexts/FullScreenContext';
1516

1617
/**
1718
* Allow applications to opt-out of (or provide their own) drag and drop context
@@ -46,6 +47,25 @@ MaybeDndProvider.propTypes = {
4647
]).isRequired,
4748
};
4849

50+
/**
51+
* Shim to inject the full screen handle into a context
52+
*/
53+
const FullScreenShim = ({ children }) => {
54+
const handle = useFullScreenHandle();
55+
56+
return (
57+
<FullScreen handle={handle}>
58+
<FullScreenContext.Provider value={handle}>
59+
{children}
60+
</FullScreenContext.Provider>
61+
</FullScreen>
62+
);
63+
};
64+
65+
FullScreenShim.propTypes = {
66+
children: PropTypes.node.isRequired,
67+
};
68+
4969
/**
5070
* This component adds viewer-specific providers.
5171
* @prop {Object} manifests
@@ -81,8 +101,8 @@ export class AppProviders extends Component {
81101
/** */
82102
render() {
83103
const {
84-
children, createGenerateClassNameOptions, isFullscreenEnabled,
85-
setWorkspaceFullscreen, theme, translations,
104+
children, createGenerateClassNameOptions,
105+
theme, translations,
86106
dndManager,
87107
} = this.props;
88108

@@ -93,10 +113,7 @@ export class AppProviders extends Component {
93113
});
94114

95115
return (
96-
<Fullscreen
97-
enabled={isFullscreenEnabled}
98-
onChange={setWorkspaceFullscreen}
99-
>
116+
<FullScreenShim>
100117
<I18nextProvider i18n={this.i18n}>
101118
<LiveAnnouncer>
102119
<ThemeProvider
@@ -113,7 +130,7 @@ export class AppProviders extends Component {
113130
</ThemeProvider>
114131
</LiveAnnouncer>
115132
</I18nextProvider>
116-
</Fullscreen>
133+
</FullScreenShim>
117134
);
118135
}
119136
}
@@ -122,9 +139,7 @@ AppProviders.propTypes = {
122139
children: PropTypes.node,
123140
createGenerateClassNameOptions: PropTypes.object, // eslint-disable-line react/forbid-prop-types
124141
dndManager: PropTypes.object, // eslint-disable-line react/forbid-prop-types
125-
isFullscreenEnabled: PropTypes.bool,
126142
language: PropTypes.string.isRequired,
127-
setWorkspaceFullscreen: PropTypes.func.isRequired,
128143
theme: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
129144
translations: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
130145
};
@@ -133,5 +148,4 @@ AppProviders.defaultProps = {
133148
children: null,
134149
createGenerateClassNameOptions: {},
135150
dndManager: undefined,
136-
isFullscreenEnabled: false,
137151
};

src/components/FullScreenButton.js

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import FullscreenIcon from '@material-ui/icons/FullscreenSharp';
33
import FullscreenExitIcon from '@material-ui/icons/FullscreenExitSharp';
44
import PropTypes from 'prop-types';
55
import MiradorMenuButton from '../containers/MiradorMenuButton';
6+
import FullScreenContext from '../contexts/FullScreenContext';
7+
68
/**
79
*/
810
export class FullScreenButton extends Component {
@@ -12,29 +14,30 @@ export class FullScreenButton extends Component {
1214
*/
1315
render() {
1416
const {
15-
className, isFullscreenEnabled, setWorkspaceFullscreen, t,
17+
className, t,
1618
} = this.props;
1719
return (
18-
<MiradorMenuButton
19-
className={className}
20-
aria-label={isFullscreenEnabled ? t('exitFullScreen') : t('workspaceFullScreen')}
21-
onClick={() => setWorkspaceFullscreen(!isFullscreenEnabled)}
22-
>
23-
{isFullscreenEnabled ? <FullscreenExitIcon /> : <FullscreenIcon />}
24-
</MiradorMenuButton>
20+
<FullScreenContext.Consumer>
21+
{ handle => (
22+
<MiradorMenuButton
23+
className={className}
24+
aria-label={handle.active ? t('exitFullScreen') : t('workspaceFullScreen')}
25+
onClick={handle.active ? handle.exit : handle.enter}
26+
>
27+
{handle.active ? <FullscreenExitIcon /> : <FullscreenIcon />}
28+
</MiradorMenuButton>
29+
)}
30+
</FullScreenContext.Consumer>
2531
);
2632
}
2733
}
2834

2935
FullScreenButton.propTypes = {
3036
className: PropTypes.string,
31-
isFullscreenEnabled: PropTypes.bool,
32-
setWorkspaceFullscreen: PropTypes.func.isRequired,
3337
t: PropTypes.func,
3438
};
3539

3640
FullScreenButton.defaultProps = {
3741
className: undefined,
38-
isFullscreenEnabled: false,
3942
t: key => key,
4043
};

src/containers/AppProviders.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { compose } from 'redux';
22
import { connect } from 'react-redux';
33
import { withPlugins } from '../extend/withPlugins';
4-
import * as actions from '../state/actions';
5-
import { getConfig, getTheme, getFullScreenEnabled } from '../state/selectors';
4+
import { getConfig, getTheme } from '../state/selectors';
65
import { AppProviders } from '../components/AppProviders';
76

87
/**
@@ -13,24 +12,14 @@ import { AppProviders } from '../components/AppProviders';
1312
const mapStateToProps = state => (
1413
{
1514
createGenerateClassNameOptions: getConfig(state).createGenerateClassNameOptions,
16-
isFullscreenEnabled: getFullScreenEnabled(state),
1715
language: getConfig(state).language,
1816
theme: getTheme(state),
1917
translations: getConfig(state).translations,
2018
}
2119
);
2220

23-
/**
24-
* mapDispatchToProps - used to hook up connect to action creators
25-
* @memberof App
26-
* @private
27-
*/
28-
const mapDispatchToProps = {
29-
setWorkspaceFullscreen: actions.setWorkspaceFullscreen,
30-
};
31-
3221
const enhance = compose(
33-
connect(mapStateToProps, mapDispatchToProps),
22+
connect(mapStateToProps),
3423
withPlugins('AppProviders'),
3524
);
3625

src/containers/FullScreenButton.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,21 @@ import { connect } from 'react-redux';
22
import { compose } from 'redux';
33
import { withTranslation } from 'react-i18next';
44
import { withPlugins } from '../extend/withPlugins';
5-
import * as actions from '../state/actions';
6-
import { getFullScreenEnabled } from '../state/selectors';
75
import { FullScreenButton } from '../components/FullScreenButton';
86

97
/**
108
* mapStateToProps - to hook up connect
119
* @memberof FullScreenButton
1210
* @private
1311
*/
14-
const mapStateToProps = state => ({
15-
isFullscreenEnabled: getFullScreenEnabled(state),
16-
});
12+
const mapStateToProps = _state => ({});
1713

1814
/**
1915
* mapDispatchToProps - used to hook up connect to action creators
2016
* @memberof ManifestListItem
2117
* @private
2218
*/
23-
const mapDispatchToProps = { setWorkspaceFullscreen: actions.setWorkspaceFullscreen };
19+
const mapDispatchToProps = {};
2420

2521
const enhance = compose(
2622
withTranslation(),

src/contexts/FullScreenContext.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { createContext } from 'react';
2+
3+
const FullScreenContext = createContext();
4+
5+
export default FullScreenContext;

src/state/actions/workspace.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,6 @@ export function updateWorkspace(config) {
99
return { config, type: ActionTypes.UPDATE_WORKSPACE };
1010
}
1111

12-
/**
13-
* setWorkspaceFullscreen - action creator
14-
*
15-
* @param {Boolean} isFullscreenEnabled
16-
* @memberof ActionCreators
17-
*/
18-
export function setWorkspaceFullscreen(isFullscreenEnabled) {
19-
return { isFullscreenEnabled, type: ActionTypes.SET_WORKSPACE_FULLSCREEN };
20-
}
21-
2212
/**
2313
* toggleZoomControls - action creator
2414
* @param {Boolean} showZoomControls

0 commit comments

Comments
 (0)