Add GdprBanner component, remove useGdpr hook

This commit is contained in:
Alex Gleason 2022-07-26 10:58:17 -05:00
parent af6cb3a4c2
commit d422bdf3d3
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
4 changed files with 63 additions and 51 deletions

View File

@ -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;

View File

@ -13,6 +13,7 @@ import { fetchMe } from 'soapbox/actions/me';
import { loadSoapboxConfig, getSoapboxConfig } from 'soapbox/actions/soapbox';
import { fetchVerificationConfig } from 'soapbox/actions/verification';
import * as BuildConfig from 'soapbox/build_config';
import GdprBanner from 'soapbox/components/gdpr-banner';
import Helmet from 'soapbox/components/helmet';
import LoadingScreen from 'soapbox/components/loading-screen';
import AuthLayout from 'soapbox/features/auth_layout';
@ -34,7 +35,6 @@ import {
useSettings,
useTheme,
useLocale,
useGdpr,
} from 'soapbox/hooks';
import MESSAGES from 'soapbox/locales/messages';
import { useCachedLocationHandler } from 'soapbox/utils/redirect';
@ -78,7 +78,6 @@ const loadInitial = () => {
/** Highest level node with the Redux store. */
const SoapboxMount = () => {
useGdpr();
useCachedLocationHandler();
const me = useAppSelector(state => state.me);
const instance = useAppSelector(state => state.instance);
@ -178,6 +177,8 @@ const SoapboxMount = () => {
<BundleContainer fetchComponent={ModalContainer}>
{Component => <Component />}
</BundleContainer>
<GdprBanner />
</>
</ScrollContext>
</BrowserRouter>

View File

@ -3,7 +3,6 @@ export { useAppDispatch } from './useAppDispatch';
export { useAppSelector } from './useAppSelector';
export { useDimensions } from './useDimensions';
export { useFeatures } from './useFeatures';
export { useGdpr } from './useGdpr';
export { useLocale } from './useLocale';
export { useOnScreen } from './useOnScreen';
export { useOwnAccount } from './useOwnAccount';

View File

@ -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 };