commit
f6729816f1
|
|
@ -13,7 +13,7 @@
|
||||||
name="description"
|
name="description"
|
||||||
content="Enter your availability to find a time that works for everyone!"
|
content="Enter your availability to find a time that works for everyone!"
|
||||||
>
|
>
|
||||||
<meta http-equiv="origin-trial" content="AhWOaJkK9UupntsXcPeoI5jB0QriKWpjKihquvBAZt2CXCXljDoV7BasrVwECNBngkQ/Bxehaq12s0kdC0U8vAwAAABOeyJvcmlnaW4iOiJodHRwczovL2NyYWIuZml0OjQ0MyIsImZlYXR1cmUiOiJEaWdpdGFsR29vZHMiLCJleHBpcnkiOjE2MjYyMjA3OTl9">
|
<meta http-equiv="origin-trial" content="Ar7tjGW2QiMeUPQCeRlYjb3ea5SyMxU5a7dEPxbmq7BSlOrSb+Twl7QiZ+z36B2KlPH9HXXCrTxfOBs2W1IbPQQAAABOeyJvcmlnaW4iOiJodHRwczovL2NyYWIuZml0OjQ0MyIsImZlYXR1cmUiOiJEaWdpdGFsR29vZHMiLCJleHBpcnkiOjE2MzE2NjM5OTl9">
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png">
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png">
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ import { BrowserRouter, Switch, Route } from 'react-router-dom';
|
||||||
import { ThemeProvider, Global } from '@emotion/react';
|
import { ThemeProvider, Global } from '@emotion/react';
|
||||||
import { Workbox } from 'workbox-window';
|
import { Workbox } from 'workbox-window';
|
||||||
|
|
||||||
import { Settings, Loading, Egg, UpdateDialog } from 'components';
|
import { Settings, Loading, Egg, UpdateDialog, TranslateDialog } from 'components';
|
||||||
|
|
||||||
import { useSettingsStore } from 'stores';
|
import { useSettingsStore, useTranslateStore } from 'stores';
|
||||||
import theme from 'theme';
|
import theme from 'theme';
|
||||||
|
|
||||||
const EGG_PATTERN = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
|
const EGG_PATTERN = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
|
||||||
|
|
@ -29,6 +29,8 @@ const App = () => {
|
||||||
const [eggKey, setEggKey] = useState(0);
|
const [eggKey, setEggKey] = useState(0);
|
||||||
|
|
||||||
const [updateAvailable, setUpdateAvailable] = useState(false);
|
const [updateAvailable, setUpdateAvailable] = useState(false);
|
||||||
|
const languageSupported = useTranslateStore(state => state.navigatorSupported);
|
||||||
|
const translateDialogDismissed = useTranslateStore(state => state.translateDialogDismissed);
|
||||||
|
|
||||||
const eggHandler = useCallback(
|
const eggHandler = useCallback(
|
||||||
event => {
|
event => {
|
||||||
|
|
@ -93,7 +95,7 @@ const App = () => {
|
||||||
styles={theme => ({
|
styles={theme => ({
|
||||||
html: {
|
html: {
|
||||||
scrollBehavior: 'smooth',
|
scrollBehavior: 'smooth',
|
||||||
'-webkit-print-color-adjust': 'exact',
|
WebkitPrintColorAdjust: 'exact',
|
||||||
},
|
},
|
||||||
body: {
|
body: {
|
||||||
backgroundColor: theme.background,
|
backgroundColor: theme.background,
|
||||||
|
|
@ -127,6 +129,8 @@ const App = () => {
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{!languageSupported && !translateDialogDismissed && <TranslateDialog />}
|
||||||
|
|
||||||
<Suspense fallback={<Loading />}>
|
<Suspense fallback={<Loading />}>
|
||||||
<Settings />
|
<Settings />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { Button } from 'components';
|
||||||
|
|
||||||
|
import { useTranslateStore } from 'stores';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Wrapper,
|
||||||
|
ButtonWrapper,
|
||||||
|
} from './translateDialogStyle';
|
||||||
|
|
||||||
|
const TranslateDialog = ({ onClose }) => {
|
||||||
|
const navigatorLang = useTranslateStore(state => state.navigatorLang);
|
||||||
|
const setDialogDismissed = useTranslateStore(state => state.setDialogDismissed);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<div>
|
||||||
|
<h2>Translate Crab Fit</h2>
|
||||||
|
<p>Crab Fit hasn't been translated to your language yet.</p>
|
||||||
|
</div>
|
||||||
|
<ButtonWrapper>
|
||||||
|
<Button
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
href={`https://docs.google.com/forms/d/e/1FAIpQLSd5bcs8LTP_8Ydrh2e4iMlZft5x81qSfAxekuuQET27A2mBhA/viewform?usp=pp_url&entry.1530835706=__other_option__&entry.1530835706.other_option_response=${encodeURIComponent(navigatorLang)}`}
|
||||||
|
>Help translate!</Button>
|
||||||
|
<Button secondary onClick={() => setDialogDismissed(true)}>Close</Button>
|
||||||
|
</ButtonWrapper>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TranslateDialog;
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
export const Wrapper = styled.div`
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
background-color: ${props => props.theme.background};
|
||||||
|
${props => props.theme.mode === 'dark' && `
|
||||||
|
border: 1px solid ${props.theme.primaryBackground};
|
||||||
|
`}
|
||||||
|
z-index: 900;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 500px;
|
||||||
|
max-width: calc(100% - 40px);
|
||||||
|
box-shadow: 0 3px 6px 0 rgba(0,0,0,.3);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
& h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
& p {
|
||||||
|
margin: 12px 0 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const ButtonWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-left: 20px;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
@media (max-width: 400px) {
|
||||||
|
margin: 20px 0 0;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
@ -19,6 +19,7 @@ export { default as Footer } from './Footer/Footer';
|
||||||
export { default as Recents } from './Recents/Recents';
|
export { default as Recents } from './Recents/Recents';
|
||||||
export { default as Logo } from './Logo/Logo';
|
export { default as Logo } from './Logo/Logo';
|
||||||
export { default as UpdateDialog } from './UpdateDialog/UpdateDialog';
|
export { default as UpdateDialog } from './UpdateDialog/UpdateDialog';
|
||||||
|
export { default as TranslateDialog } from './TranslateDialog/TranslateDialog';
|
||||||
|
|
||||||
export const _GoogleCalendar = () => import('./GoogleCalendar/GoogleCalendar');
|
export const _GoogleCalendar = () => import('./GoogleCalendar/GoogleCalendar');
|
||||||
export const _OutlookCalendar = () => import('./OutlookCalendar/OutlookCalendar');
|
export const _OutlookCalendar = () => import('./OutlookCalendar/OutlookCalendar');
|
||||||
|
|
|
||||||
|
|
@ -224,11 +224,11 @@ const Home = ({ offline }) => {
|
||||||
<h2>{t('home:about.name')}</h2>
|
<h2>{t('home:about.name')}</h2>
|
||||||
<Stats>
|
<Stats>
|
||||||
<Stat>
|
<Stat>
|
||||||
<StatNumber>{stats.eventCount ?? '350+'}</StatNumber>
|
<StatNumber>{stats.eventCount ?? '700+'}</StatNumber>
|
||||||
<StatLabel>{t('home:about.events')}</StatLabel>
|
<StatLabel>{t('home:about.events')}</StatLabel>
|
||||||
</Stat>
|
</Stat>
|
||||||
<Stat>
|
<Stat>
|
||||||
<StatNumber>{stats.personCount ?? '550+'}</StatNumber>
|
<StatNumber>{stats.personCount ?? '1600+'}</StatNumber>
|
||||||
<StatLabel>{t('home:about.availabilities')}</StatLabel>
|
<StatLabel>{t('home:about.availabilities')}</StatLabel>
|
||||||
</Stat>
|
</Stat>
|
||||||
</Stats>
|
</Stats>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import create from 'zustand';
|
import create from 'zustand';
|
||||||
import { persist } from 'zustand/middleware';
|
import { persist } from 'zustand/middleware';
|
||||||
|
import locales from 'res/dayjs_locales';
|
||||||
|
|
||||||
export const useSettingsStore = create(persist(
|
export const useSettingsStore = create(persist(
|
||||||
set => ({
|
set => ({
|
||||||
|
|
@ -44,3 +45,20 @@ export const useLocaleUpdateStore = create(set => ({
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
setLocale: locale => set({ locale }),
|
setLocale: locale => set({ locale }),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const useTranslateStore = create(persist(
|
||||||
|
set => ({
|
||||||
|
navigatorLang: navigator.language,
|
||||||
|
navigatorSupported: Object.keys(locales).includes(navigator.language.substring(0, 2)),
|
||||||
|
translateDialogDismissed: false,
|
||||||
|
|
||||||
|
setDialogDismissed: value => set({ translateDialogDismissed: value }),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'crabfit-translate',
|
||||||
|
blacklist: [
|
||||||
|
'navigatorLang',
|
||||||
|
'navigatorSupported',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@ clientsClaim();
|
||||||
// Injection point
|
// Injection point
|
||||||
precacheAndRoute(self.__WB_MANIFEST);
|
precacheAndRoute(self.__WB_MANIFEST);
|
||||||
|
|
||||||
// Set up App Shell-style routing, so that all navigation requests
|
|
||||||
// are fulfilled with your index.html shell. Learn more at
|
|
||||||
// https://developers.google.com/web/fundamentals/architecture/app-shell
|
|
||||||
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
|
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
|
||||||
registerRoute(
|
registerRoute(
|
||||||
// Return false to exempt requests from being fulfilled by index.html.
|
// Return false to exempt requests from being fulfilled by index.html.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue