Skip to content

Commit

Permalink
Convert some class components to functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeer committed Nov 19, 2024
1 parent 19998cd commit 29e75cc
Show file tree
Hide file tree
Showing 31 changed files with 1,019 additions and 1,510 deletions.
49 changes: 16 additions & 33 deletions src/components/AccessTokenSender.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,31 @@
import { Component } from 'react';
import { useCallback } from 'react';
import PropTypes from 'prop-types';
import { IIIFIFrameCommunication } from './IIIFIFrameCommunication';

/**
* Opens a new window for click
*/
export class AccessTokenSender extends Component {
/** */
constructor(props) {
super(props);

this.onReceiveAccessTokenMessage = this.onReceiveAccessTokenMessage.bind(this);
}

/** @private */
onReceiveAccessTokenMessage(e) {
const { handleAccessTokenMessage, url } = this.props;
export function AccessTokenSender({ handleAccessTokenMessage, url = undefined }) {
const onReceiveAccessTokenMessage = useCallback((e) => {
if (e.data && e.data.messageId && e.data.messageId === url) handleAccessTokenMessage(e.data);
}
}, [handleAccessTokenMessage, url]);

/** */
render() {
const { url } = this.props;
if (!url) return null;
if (!url) return null;

/**
login, clickthrough/kiosk open @id, wait for close
external, no-op
*/
return (
<IIIFIFrameCommunication
src={`${url}?origin=${window.origin}&messageId=${url}`}
title="AccessTokenSender"
handleReceiveMessage={this.onReceiveAccessTokenMessage}
/>
);
}
/**
login, clickthrough/kiosk open @id, wait for close
external, no-op
*/
return (
<IIIFIFrameCommunication
src={`${url}?origin=${window.origin}&messageId=${url}`}
title="AccessTokenSender"
handleReceiveMessage={onReceiveAccessTokenMessage}
/>
);
}

AccessTokenSender.propTypes = {
handleAccessTokenMessage: PropTypes.func.isRequired,
url: PropTypes.string,
};

AccessTokenSender.defaultProps = {
url: undefined,
};
34 changes: 13 additions & 21 deletions src/components/AnnotationSettings.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Component } from 'react';
import PropTypes from 'prop-types';
import VisibilityIcon from '@mui/icons-material/VisibilitySharp';
import VisibilityOffIcon from '@mui/icons-material/VisibilityOffSharp';
Expand All @@ -8,26 +7,19 @@ import MiradorMenuButton from '../containers/MiradorMenuButton';
* AnnotationSettings is a component to handle various annotation
* display settings in the Annotation companion window
*/
export class AnnotationSettings extends Component {
/**
* Returns the rendered component
*/
render() {
const {
displayAll, displayAllDisabled, t, toggleAnnotationDisplay,
} = this.props;

return (
<MiradorMenuButton
aria-label={t(displayAll ? 'displayNoAnnotations' : 'highlightAllAnnotations')}
onClick={toggleAnnotationDisplay}
disabled={displayAllDisabled}
size="small"
>
{ displayAll ? <VisibilityIcon /> : <VisibilityOffIcon /> }
</MiradorMenuButton>
);
}
export function AnnotationSettings({
displayAll, displayAllDisabled, t, toggleAnnotationDisplay,
}) {
return (
<MiradorMenuButton
aria-label={t(displayAll ? 'displayNoAnnotations' : 'highlightAllAnnotations')}
onClick={toggleAnnotationDisplay}
disabled={displayAllDisabled}
size="small"
>
{ displayAll ? <VisibilityIcon /> : <VisibilityOffIcon /> }
</MiradorMenuButton>
);
}

AnnotationSettings.propTypes = {
Expand Down
52 changes: 17 additions & 35 deletions src/components/App.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
createRef, Component, lazy, Suspense,
createRef, lazy, Suspense,
} from 'react';
import PropTypes from 'prop-types';
import PluginProvider from '../extend/PluginProvider';
Expand All @@ -12,45 +12,27 @@ const WorkspaceArea = lazy(() => import('../containers/WorkspaceArea'));
* This is the top level Mirador component.
* @prop {Object} manifests
*/
export class App extends Component {
/** */
constructor(props) {
super(props);

this.areaRef = createRef();
}

/**
* render
* @return {String} - HTML markup for the component
*/
render() {
const { dndManager, plugins } = this.props;

return (
<PluginProvider plugins={plugins}>
<AppProviders dndManager={dndManager}>
<WorkspaceContext.Provider value={this.areaRef}>
<Suspense
fallback={<div />}
>
<WorkspaceArea areaRef={this.areaRef} />
</Suspense>
</WorkspaceContext.Provider>
</AppProviders>
</PluginProvider>
);
}
export function App({ dndManager = undefined, plugins = [] }) {
const areaRef = createRef();

return (
<PluginProvider plugins={plugins}>
<AppProviders dndManager={dndManager}>
<WorkspaceContext.Provider value={areaRef}>
<Suspense
fallback={<div />}
>
<WorkspaceArea areaRef={areaRef} />
</Suspense>
</WorkspaceContext.Provider>
</AppProviders>
</PluginProvider>
);
}

App.propTypes = {
dndManager: PropTypes.object, // eslint-disable-line react/forbid-prop-types
plugins: PropTypes.array, // eslint-disable-line react/forbid-prop-types
};

App.defaultProps = {
dndManager: undefined,
plugins: [],
};

export default App;
123 changes: 58 additions & 65 deletions src/components/AppProviders.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component } from 'react';
import { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { FullScreen, useFullScreenHandle } from 'react-full-screen';
import { I18nextProvider } from 'react-i18next';
Expand Down Expand Up @@ -68,72 +68,70 @@ FullScreenShim.propTypes = {
};

/**
* This component adds viewer-specific providers.
* @prop {Object} manifests
* Hook up the I18next provider to the configuration in redux to allow
* plugins + config to inject additional translations.
*/
export class AppProviders extends Component {
/** */
constructor(props) {
super(props);

this.i18n = createI18nInstance();
// Set i18n language
this.i18n.changeLanguage(props.language);
}
const StoreAwareI18nextProvider = ({ children, language, translations }) => {
const [i18n] = useState(createI18nInstance());
useEffect(() => {
i18n.changeLanguage(language);
}, [i18n, language]);

/**
* Update the i18n language if it is changed
*/
componentDidUpdate(prevProps) {
const { language } = this.props;
if (prevProps.language !== language) {
this.i18n.changeLanguage(language);
}
}
useEffect(() => {
Object.keys(translations).forEach((lng) => {
i18n.addResourceBundle(lng, 'translation', translations[lng], true, true);
});
}, [i18n, translations]);

/** */
render() {
const {
children,
theme, translations,
dndManager,
} = this.props;
return (<I18nextProvider i18n={i18n}>{children}</I18nextProvider>);
};

/**
* Create rtl emotion cache
*/
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});
StoreAwareI18nextProvider.propTypes = {
children: PropTypes.node.isRequired,
language: PropTypes.string.isRequired,
translations: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

/**
* Create default emotion cache
*/
const cacheDefault = createCache({
key: 'mui',
});
/**
* Create rtl emotion cache
*/
const cacheRtl = createCache({
key: 'muirtl',
stylisPlugins: [prefixer, rtlPlugin],
});

Object.keys(translations).forEach((lng) => {
this.i18n.addResourceBundle(lng, 'translation', translations[lng], true, true);
});
/**
* Create default emotion cache
*/
const cacheDefault = createCache({
key: 'mui',
});

return (
<FullScreenShim>
<I18nextProvider i18n={this.i18n}>
<StyledEngineProvider injectFirst>
<CacheProvider value={theme.direction === 'rtl' ? cacheRtl : cacheDefault}>
<ThemeProvider theme={createTheme((theme))}>
<MaybeDndProvider dndManager={dndManager}>
{children}
</MaybeDndProvider>
</ThemeProvider>
</CacheProvider>
</StyledEngineProvider>
</I18nextProvider>
</FullScreenShim>
);
}
/**
* This component adds viewer-specific providers.
* @prop {Object} manifests
*/
export function AppProviders({
children = null,
language,
theme, translations,
dndManager = undefined,
}) {
return (
<FullScreenShim>
<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>
</FullScreenShim>
);
}

AppProviders.propTypes = {
Expand All @@ -143,8 +141,3 @@ AppProviders.propTypes = {
theme: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
translations: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
};

AppProviders.defaultProps = {
children: null,
dndManager: undefined,
};
Loading

0 comments on commit 29e75cc

Please sign in to comment.