Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,15 @@ convertBibleQuote/bible
/electron
/android
/.circleci
/node_modules
/.git
/.env
/.env.*
/.auto-claude
/ZITADEL_AUTH_CONFIG.md
/www/built
/www/index.html
/www/service-worker.*
/www/version
/test-results
/playwright-report
44 changes: 29 additions & 15 deletions app/Routes.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
import React, { Suspense, useEffect, useRef } from 'react';
import { Navigate, Route, Routes as RouterRoutes, useLocation, useParams } from 'react-router-dom';
import Main from 'containers/Main/Main';
import NotFound from 'components/NotFound/NotFound';
import Readings from 'containers/Readings/Readings';
import dateFormat from 'dateformat';
import Sermon from 'containers/Sermon/Sermon';
import Saint from 'containers/Saint/Saint';
import ThisDay from 'containers/ThisDay/ThisDay';
import Service from 'containers/Service/Service';
import { Global, ThemeProvider, css as rcss } from '@emotion/react';
import { css } from '@emotion/css';
import { useRecoilValue, useSetRecoilState } from 'recoil';

import { loadServiceRoute } from './routeLoaders';
import checkVersion from './checkVersion';

import Main from 'containers/Main/Main';
import NotFound from 'components/NotFound/NotFound';
import useDay from 'hooks/useDay';
import getTheme from 'styles/getTheme';
import langState from 'state/langState';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { LangContext } from 'containers/Service/LangContext';
import pendingUpdateState from 'state/pendingUpdateState';
import UpdatePrompt from 'components/UpdatePrompt/UpdatePrompt';
import isParallelState from 'state/isParallel';
import { Promo } from 'components/Promo/Promo';
import Loader from 'components/Loader/Loader';
import themeState from 'state/themeState';
import SettingsMenu from 'containers/Main/SettingsMenu';

import checkVersion from './checkVersion';
import menuShownState from 'state/menuShownState';

const Hymns = React.lazy(async () => {
const module = await import(/* webpackChunkName: "route-hymns" */ 'containers/Hymns/Hymns');
Expand All @@ -33,6 +30,20 @@ const Hymn = React.lazy(async () => {
const module = await import(/* webpackChunkName: "route-hymns" */ 'containers/Hymns/Hymn');
return { default: module.Hymn };
});
const Readings = React.lazy(
async () => await import(/* webpackChunkName: "route-readings" */ 'containers/Readings/Readings')
);
const Sermon = React.lazy(
async () => await import(/* webpackChunkName: "route-date-sermon" */ 'containers/Sermon/Sermon')
);
const Saint = React.lazy(async () => await import(/* webpackChunkName: "route-date-saint" */ 'containers/Saint/Saint'));
const ThisDay = React.lazy(
async () => await import(/* webpackChunkName: "route-this-day" */ 'containers/ThisDay/ThisDay')
);
const Service = React.lazy(loadServiceRoute);
const SettingsMenu = React.lazy(
async () => await import(/* webpackChunkName: "settings-menu" */ 'containers/Main/SettingsMenu')
);
const Profile = React.lazy(
async () => await import(/* webpackChunkName: "route-profile" */ 'containers/Profile/Profile')
);
Expand Down Expand Up @@ -110,6 +121,7 @@ const Routes = () => {
};
}, [location.key, setPendingUpdate]);
const isParallel = useRecoilValue(isParallelState);
const menuShown = useRecoilValue(menuShownState);
const themeStateValue = useRecoilValue(themeState);
const theme = getTheme(undefined, themeStateValue);

Expand Down Expand Up @@ -138,14 +150,16 @@ const Routes = () => {
margin: 0 auto;
`}
>
<SettingsMenu />
{menuShown && (
<Suspense fallback={null}>
<SettingsMenu />
</Suspense>
)}
<Suspense fallback={<Loader />}>
<RouterRoutes>
<Route
path="/"
element={
<Navigate replace to={`/date/${dateFormat(new Date(), 'yyyy-mm-dd')}`} />
}
element={<Navigate replace to={`/date/${dateFormat(new Date(), 'yyyy-mm-dd')}`} />}
/>
<Route path="/hymns/:hymnId" element={<Hymn />} />
<Route path="/hymns" element={<Hymns />} />
Expand Down
2 changes: 2 additions & 0 deletions app/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Worker from './precache.worker.js';
import './redirectToHome';
import { isCapacitor } from 'utils/deviceInfo';
import precache from 'precache.ts';
import { startPerformanceTelemetry } from 'utils/performanceTelemetry';

window.APP_LOADED = true;
const isProd = process.env.NODE_ENV === 'production';
Expand All @@ -36,6 +37,7 @@ if (isProd) {
namesSubmit: 'Names Submit',
},
});
startPerformanceTelemetry();
}

const rootElement = document.getElementById('react-root');
Expand Down
45 changes: 24 additions & 21 deletions app/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
import React, { forwardRef } from 'react';
import { css } from '@emotion/css';

const Button = forwardRef((props, ref) => (
<button
{...props}
ref={ref}
aria-label={props.title || undefined}
type="button"
className={`${css`
cursor: pointer;
padding: 12px;
user-select: none;
&:hover {
opacity: 0.8;
}
&:active {
opacity: 0.5;
}
`} ${props.className}`}
>
{props.children}
</button>
));
const Button = forwardRef<HTMLButtonElement, React.ButtonHTMLAttributes<HTMLButtonElement>>(
({ children, className = '', title, ...props }, ref) => (
<button
{...props}
ref={ref}
title={title}
aria-label={title || undefined}
type="button"
className={`${css`
cursor: pointer;
padding: 12px;
user-select: none;
&:hover {
opacity: 0.8;
}
&:active {
opacity: 0.5;
}
`} ${className}`}
>
{children}
</button>
)
);

export default Button;
20 changes: 17 additions & 3 deletions app/components/HeightUpdate/HeightUpdater.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import React, { useContext, useEffect } from 'react';
import { SwipeableViewsContext } from 'react-swipeable-views';

interface SwipeableViewsContextValue {
slideUpdateHeight?: () => void;
}

export const HeightUpdater = ({ children }: { children: React.ReactNode }): JSX.Element => {
const context = useContext(SwipeableViewsContext);
const context = useContext(
SwipeableViewsContext as unknown as React.Context<SwipeableViewsContextValue | undefined>
);
useEffect(() => {
setTimeout(() => {
context?.slideUpdateHeight?.();
const updateHeight = context?.slideUpdateHeight;
if (!updateHeight) {
return undefined;
}

const timer = window.setTimeout(() => {
updateHeight();
}, 30);
return () => {
window.clearTimeout(timer);
};
});
return <>{children}</>;
};
Loading