Add GdprBanner component, remove useGdpr hook
This commit is contained in:
parent
af6cb3a4c2
commit
d422bdf3d3
|
@ -0,0 +1,60 @@
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Banner, Button, HStack, Stack, Text } from 'soapbox/components/ui';
|
||||||
|
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||||
|
|
||||||
|
const acceptedGdpr = !!localStorage.getItem('soapbox:gdpr');
|
||||||
|
|
||||||
|
/** Displays a cookie consent banner. */
|
||||||
|
const GdprBanner: React.FC = () => {
|
||||||
|
/** Track whether the banner has already been displayed once. */
|
||||||
|
const [shown, setShown] = useState<boolean>(acceptedGdpr);
|
||||||
|
|
||||||
|
const soapbox = useSoapboxConfig();
|
||||||
|
const isLoggedIn = useAppSelector(state => !!state.me);
|
||||||
|
const siteTitle = useAppSelector(state => state.instance.title);
|
||||||
|
|
||||||
|
const handleAccept = () => {
|
||||||
|
localStorage.setItem('soapbox:gdpr', 'true');
|
||||||
|
setShown(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const showBanner = soapbox.gdpr && !isLoggedIn && !shown;
|
||||||
|
|
||||||
|
if (!showBanner) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Banner theme='opaque'>
|
||||||
|
<Stack space={2}>
|
||||||
|
<Stack>
|
||||||
|
<Text size='xl' weight='bold'>
|
||||||
|
<FormattedMessage id='gdpr.title' defaultMessage='{siteTitle} uses cookies' values={{ siteTitle }} />
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<Text weight='medium' className='opacity-90'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='gdpr.message'
|
||||||
|
defaultMessage="{siteTitle} uses session cookies, which are essential to the website's functioning."
|
||||||
|
values={{ siteTitle }}
|
||||||
|
/>
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<HStack space={2} justifyContent='end'>
|
||||||
|
<Button theme='secondary' to='/login'>
|
||||||
|
<FormattedMessage id='gdpr.learn_more' defaultMessage='Learn more' />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button theme='accent' onClick={handleAccept}>
|
||||||
|
<FormattedMessage id='gdpr.accept' defaultMessage='Accept' />
|
||||||
|
</Button>
|
||||||
|
</HStack>
|
||||||
|
</Stack>
|
||||||
|
</Banner>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GdprBanner;
|
|
@ -13,6 +13,7 @@ import { fetchMe } from 'soapbox/actions/me';
|
||||||
import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox';
|
import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||||
import { fetchVerificationConfig } from 'soapbox/actions/verification';
|
import { fetchVerificationConfig } from 'soapbox/actions/verification';
|
||||||
import * as BuildConfig from 'soapbox/build_config';
|
import * as BuildConfig from 'soapbox/build_config';
|
||||||
|
import GdprBanner from 'soapbox/components/gdpr-banner';
|
||||||
import Helmet from 'soapbox/components/helmet';
|
import Helmet from 'soapbox/components/helmet';
|
||||||
import LoadingScreen from 'soapbox/components/loading-screen';
|
import LoadingScreen from 'soapbox/components/loading-screen';
|
||||||
import AuthLayout from 'soapbox/features/auth_layout';
|
import AuthLayout from 'soapbox/features/auth_layout';
|
||||||
|
@ -34,7 +35,6 @@ import {
|
||||||
useSettings,
|
useSettings,
|
||||||
useTheme,
|
useTheme,
|
||||||
useLocale,
|
useLocale,
|
||||||
useGdpr,
|
|
||||||
} from 'soapbox/hooks';
|
} from 'soapbox/hooks';
|
||||||
import MESSAGES from 'soapbox/locales/messages';
|
import MESSAGES from 'soapbox/locales/messages';
|
||||||
import { useCachedLocationHandler } from 'soapbox/utils/redirect';
|
import { useCachedLocationHandler } from 'soapbox/utils/redirect';
|
||||||
|
@ -78,7 +78,6 @@ const loadInitial = () => {
|
||||||
|
|
||||||
/** Highest level node with the Redux store. */
|
/** Highest level node with the Redux store. */
|
||||||
const SoapboxMount = () => {
|
const SoapboxMount = () => {
|
||||||
useGdpr();
|
|
||||||
useCachedLocationHandler();
|
useCachedLocationHandler();
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const instance = useAppSelector(state => state.instance);
|
const instance = useAppSelector(state => state.instance);
|
||||||
|
@ -178,6 +177,8 @@ const SoapboxMount = () => {
|
||||||
<BundleContainer fetchComponent={ModalContainer}>
|
<BundleContainer fetchComponent={ModalContainer}>
|
||||||
{Component => <Component />}
|
{Component => <Component />}
|
||||||
</BundleContainer>
|
</BundleContainer>
|
||||||
|
|
||||||
|
<GdprBanner />
|
||||||
</>
|
</>
|
||||||
</ScrollContext>
|
</ScrollContext>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
|
|
|
@ -3,7 +3,6 @@ export { useAppDispatch } from './useAppDispatch';
|
||||||
export { useAppSelector } from './useAppSelector';
|
export { useAppSelector } from './useAppSelector';
|
||||||
export { useDimensions } from './useDimensions';
|
export { useDimensions } from './useDimensions';
|
||||||
export { useFeatures } from './useFeatures';
|
export { useFeatures } from './useFeatures';
|
||||||
export { useGdpr } from './useGdpr';
|
|
||||||
export { useLocale } from './useLocale';
|
export { useLocale } from './useLocale';
|
||||||
export { useOnScreen } from './useOnScreen';
|
export { useOnScreen } from './useOnScreen';
|
||||||
export { useOwnAccount } from './useOwnAccount';
|
export { useOwnAccount } from './useOwnAccount';
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
|
||||||
|
|
||||||
import snackbar from 'soapbox/actions/snackbar';
|
|
||||||
|
|
||||||
import { useAppDispatch } from './useAppDispatch';
|
|
||||||
import { useAppSelector } from './useAppSelector';
|
|
||||||
import { useSoapboxConfig } from './useSoapboxConfig';
|
|
||||||
|
|
||||||
const hasGdpr = !!localStorage.getItem('soapbox:gdpr');
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
|
||||||
accept: { id: 'gdpr.accept', defaultMessage: 'Accept' },
|
|
||||||
learnMore: { id: 'gdpr.learn_more', defaultMessage: 'Learn more' },
|
|
||||||
body: { id: 'gdpr.message', defaultMessage: '{siteTitle} uses session cookies, which are essential to the website\'s functioning.' },
|
|
||||||
});
|
|
||||||
|
|
||||||
/** Displays a GDPR popup unless it has already been accepted. */
|
|
||||||
const useGdpr = () => {
|
|
||||||
const intl = useIntl();
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
/** Track whether the snackbar has already been displayed once. */
|
|
||||||
const triggered = useRef<boolean>(hasGdpr);
|
|
||||||
|
|
||||||
const soapbox = useSoapboxConfig();
|
|
||||||
const isLoggedIn = useAppSelector(state => !!state.me);
|
|
||||||
const siteTitle = useAppSelector(state => state.instance.title);
|
|
||||||
|
|
||||||
const handleAccept = () => {
|
|
||||||
localStorage.setItem('soapbox:gdpr', 'true');
|
|
||||||
triggered.current = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (soapbox.gdpr && !isLoggedIn && !triggered.current) {
|
|
||||||
const message = intl.formatMessage(messages.body, { siteTitle });
|
|
||||||
|
|
||||||
dispatch(snackbar.show('info', message, {
|
|
||||||
action: handleAccept,
|
|
||||||
actionLabel: intl.formatMessage(messages.accept),
|
|
||||||
dismissAfter: false,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}, [soapbox.gdpr, isLoggedIn]);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { useGdpr };
|
|
Loading…
Reference in New Issue