-
Notifications
You must be signed in to change notification settings - Fork 264
Expand file tree
/
Copy pathAppProviders.js
More file actions
148 lines (132 loc) · 4.22 KB
/
AppProviders.js
File metadata and controls
148 lines (132 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import { FullScreen, useFullScreenHandle } from 'react-full-screen';
import { I18nextProvider } from 'react-i18next';
import {
ThemeProvider, StyledEngineProvider, createTheme,
} from '@mui/material/styles';
import { DndContext, DndProvider } from 'react-dnd';
import { MultiBackend } from 'react-dnd-multi-backend';
import { HTML5toTouch } from 'rdndmb-html5-to-touch';
import rtlPlugin from 'stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import createI18nInstance from '../i18n';
import FullScreenContext from '../contexts/FullScreenContext';
import OpenSeadragonWorkspaceReferencesContext from '../contexts/OpenSeadragonWorkspaceReferencesContext';
/**
* Allow applications to opt-out of (or provide their own) drag and drop context
*/
const MaybeDndProvider = (props) => {
const { dndManager, children } = props;
if (dndManager === false) {
return children;
}
if (dndManager === undefined) {
return (
<DndProvider backend={MultiBackend} options={HTML5toTouch}>
{children}
</DndProvider>
);
}
return (
<DndContext.Provider value={dndManager}>
{children}
</DndContext.Provider>
);
};
MaybeDndProvider.propTypes = {
children: PropTypes.node.isRequired,
dndManager: PropTypes.oneOf([
undefined,
false,
PropTypes.object, // eslint-disable-line react/forbid-prop-types
]).isRequired,
};
/**
* Shim to inject the full screen handle into a context
*/
const FullScreenShim = ({ children }) => {
const handle = useFullScreenHandle();
return (
<FullScreen handle={handle}>
<FullScreenContext.Provider value={handle}>
{children}
</FullScreenContext.Provider>
</FullScreen>
);
};
FullScreenShim.propTypes = {
children: PropTypes.node.isRequired,
};
/**
* Hook up the I18next provider to the configuration in redux to allow
* plugins + config to inject additional translations.
*/
const StoreAwareI18nextProvider = ({ children, language, translations }) => {
const [i18n] = useState(createI18nInstance());
useEffect(() => {
i18n.changeLanguage(language);
}, [i18n, language]);
useEffect(() => {
Object.keys(translations).forEach((lng) => {
i18n.addResourceBundle(lng, 'translation', translations[lng], true, true);
});
}, [i18n, translations]);
return (<I18nextProvider i18n={i18n}>{children}</I18nextProvider>);
};
StoreAwareI18nextProvider.propTypes = {
children: PropTypes.node.isRequired,
language: PropTypes.string.isRequired,
translations: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};
/**
* Create rtl emotion cache
*/
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
/**
* Create default emotion cache
*/
const cacheDefault = createCache({
key: 'mui',
});
/**
* This component adds viewer-specific providers.
* @prop {Object} manifests
*/
export function AppProviders({
children = null,
language,
theme, translations,
dndManager = undefined,
}) {
const osdReferences = useRef({});
return (
<FullScreenShim>
<OpenSeadragonWorkspaceReferencesContext.Provider value={osdReferences}>
<StoreAwareI18nextProvider language={language} translations={translations}>
<StyledEngineProvider injectFirst>
<CacheProvider value={theme.direction === 'rtl' ? cacheRtl : cacheDefault}>
<ThemeProvider theme={createTheme((theme))}>
<MaybeDndProvider dndManager={dndManager}>
{children}
</MaybeDndProvider>
</ThemeProvider>
</CacheProvider>
</StyledEngineProvider>
</StoreAwareI18nextProvider>
</OpenSeadragonWorkspaceReferencesContext.Provider>
</FullScreenShim>
);
}
AppProviders.propTypes = {
children: PropTypes.node,
dndManager: PropTypes.object, // eslint-disable-line react/forbid-prop-types
language: PropTypes.string.isRequired,
theme: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
translations: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};