diff --git a/frontend/src/AppWrapper.tsx b/frontend/src/AppWrapper.tsx new file mode 100644 index 0000000..597bb12 --- /dev/null +++ b/frontend/src/AppWrapper.tsx @@ -0,0 +1,23 @@ +import { IsFatalError } from '@wailsapp/go/main/App'; +import { EventsOn, EventsOff } from '@wailsapp/runtime/runtime'; +import { useState, useEffect } from 'react'; +import App from './ui/App'; +import ErrorWindow from './ui/ErrorWindow'; + +export default function AppWrapper() { + const [fatalErrorEncountered, setFatalErrorStatus] = useState(false); + useEffect(() => { + void IsFatalError().then(setFatalErrorStatus); + EventsOn('fatalError', () => { + setFatalErrorStatus(true); + }); + return () => { + EventsOff('fatalError'); + }; + }, []); + + if (fatalErrorEncountered) { + return ; + } + return ; +} diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 75becb8..6d4586c 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -1,9 +1,7 @@ import { createRoot } from 'react-dom/client'; import { Provider } from 'react-redux'; import { HashRouter } from 'react-router-dom'; -import { StrictMode, useEffect, useState } from 'react'; -import { EventsOff, EventsOn } from '@wailsapp/runtime'; -import { IsFatalError } from '@wailsapp/go/main/App'; +import { StrictMode } from 'react'; import 'inter-ui/inter.css'; import '@fontsource/space-mono/index.css'; @@ -11,30 +9,11 @@ import 'normalize.css/normalize.css'; import './locale/setup'; import store from './store'; -import App from './ui/App'; -import ErrorWindow from './ui/ErrorWindow'; import { globalStyles } from './ui/theme'; +import AppWrapper from './AppWrapper'; globalStyles(); -function AppWrapper() { - const [fatalErrorEncountered, setFatalErrorStatus] = useState(false); - useEffect(() => { - void IsFatalError().then(setFatalErrorStatus); - EventsOn('fatalError', () => { - setFatalErrorStatus(true); - }); - return () => { - EventsOff('fatalError'); - }; - }, []); - - if (fatalErrorEncountered) { - return ; - } - return ; -} - const main = document.getElementById('main'); const root = createRoot(main); root.render( diff --git a/frontend/src/ui/components/AlertContent.tsx b/frontend/src/ui/components/AlertContent.tsx index 79b4d01..2f6f6af 100644 --- a/frontend/src/ui/components/AlertContent.tsx +++ b/frontend/src/ui/components/AlertContent.tsx @@ -71,4 +71,5 @@ function AlertContent({ ); } -export default React.memo(AlertContent); +const PureAlertContent = React.memo(AlertContent); +export default PureAlertContent; diff --git a/frontend/src/ui/components/BrowserLink.tsx b/frontend/src/ui/components/BrowserLink.tsx index 31b5e33..49f6fa9 100644 --- a/frontend/src/ui/components/BrowserLink.tsx +++ b/frontend/src/ui/components/BrowserLink.tsx @@ -19,4 +19,5 @@ function BrowserLink(props: React.AnchorHTMLAttributes) { ); } -export default React.memo(BrowserLink); +const PureBrowserLink = React.memo(BrowserLink); +export default PureBrowserLink; diff --git a/frontend/src/ui/components/DefinitionTable.tsx b/frontend/src/ui/components/DefinitionTable.tsx index 14df73e..d28c8bd 100644 --- a/frontend/src/ui/components/DefinitionTable.tsx +++ b/frontend/src/ui/components/DefinitionTable.tsx @@ -37,4 +37,5 @@ function DefinitionTable({ entries }: DefinitionTableProps) { ); } -export default React.memo(DefinitionTable); +const PureDefinitionTable = React.memo(DefinitionTable); +export default PureDefinitionTable; diff --git a/frontend/src/ui/components/DialogContent.tsx b/frontend/src/ui/components/DialogContent.tsx index cb640a6..9d23e76 100644 --- a/frontend/src/ui/components/DialogContent.tsx +++ b/frontend/src/ui/components/DialogContent.tsx @@ -45,4 +45,5 @@ function DialogContent({ ); } -export default React.memo(DialogContent); +const PureDialogContent = React.memo(DialogContent); +export default PureDialogContent; diff --git a/frontend/src/ui/components/LogViewer.tsx b/frontend/src/ui/components/LogViewer.tsx index 045a5fa..461d61d 100644 --- a/frontend/src/ui/components/LogViewer.tsx +++ b/frontend/src/ui/components/LogViewer.tsx @@ -429,4 +429,5 @@ function LogViewer() { ); } -export default React.memo(LogViewer); +const PureLogViewer = React.memo(LogViewer); +export default PureLogViewer; diff --git a/frontend/src/ui/components/PageList.tsx b/frontend/src/ui/components/PageList.tsx index 5d37972..9e0cdec 100644 --- a/frontend/src/ui/components/PageList.tsx +++ b/frontend/src/ui/components/PageList.tsx @@ -156,4 +156,5 @@ function PageList({ ); } -export default React.memo(PageList); +const PurePageList = React.memo(PageList); +export default PurePageList; diff --git a/frontend/src/ui/components/forms/Interval.tsx b/frontend/src/ui/components/forms/Interval.tsx index 2aaa4cf..3a41b34 100644 --- a/frontend/src/ui/components/forms/Interval.tsx +++ b/frontend/src/ui/components/forms/Interval.tsx @@ -1,17 +1,13 @@ -import React from 'react'; import { useTranslation } from 'react-i18next'; import { getInterval } from '~/lib/time'; import { ComboBox, FlexRow, InputBox } from '../../theme'; +import { seconds, minutes, hours } from './units'; export interface TimeUnit { multiplier: number; unit: string; } -export const seconds = { multiplier: 1, unit: 'time.seconds' }; -export const minutes = { multiplier: 60, unit: 'time.minutes' }; -export const hours = { multiplier: 3600, unit: 'time.hours' }; - export interface IntervalProps { active: boolean; value: number; @@ -22,7 +18,7 @@ export interface IntervalProps { onChange?: (value: number) => void; } -function Interval({ +export default function Interval({ id, active, value, @@ -87,5 +83,3 @@ function Interval({ ); } - -export default React.memo(Interval); diff --git a/frontend/src/ui/components/forms/MultiInput.tsx b/frontend/src/ui/components/forms/MultiInput.tsx index 0727cec..a641315 100644 --- a/frontend/src/ui/components/forms/MultiInput.tsx +++ b/frontend/src/ui/components/forms/MultiInput.tsx @@ -91,4 +91,5 @@ function MultiInput({ ); } -export default React.memo(MultiInput); +const PureMultiInput = React.memo(MultiInput); +export default PureMultiInput; diff --git a/frontend/src/ui/components/forms/PasswordField.tsx b/frontend/src/ui/components/forms/PasswordField.tsx index e94cc46..6af22c9 100644 --- a/frontend/src/ui/components/forms/PasswordField.tsx +++ b/frontend/src/ui/components/forms/PasswordField.tsx @@ -22,4 +22,5 @@ function PasswordField( ); } -export default React.memo(PasswordField); +const PurePasswordField = React.memo(PasswordField); +export default PurePasswordField; diff --git a/frontend/src/ui/components/forms/RadioGroup.tsx b/frontend/src/ui/components/forms/RadioGroup.tsx index b46a0bd..e28ce0b 100644 --- a/frontend/src/ui/components/forms/RadioGroup.tsx +++ b/frontend/src/ui/components/forms/RadioGroup.tsx @@ -60,7 +60,7 @@ const RadioIndicator = styled(Indicator, { }, }); -export default function RadioGroup(props: RadioGroupProps & RootProps) { +function RadioGroup(props: RadioGroupProps & RootProps) { return ( {props.values.map(({ id, label }) => ( @@ -74,3 +74,6 @@ export default function RadioGroup(props: RadioGroupProps & RootProps) { ); } + +const PureRadioGroup = React.memo(RadioGroup); +export default PureRadioGroup; diff --git a/frontend/src/ui/components/forms/SaveButton.tsx b/frontend/src/ui/components/forms/SaveButton.tsx index 65c5ab9..f8641e0 100644 --- a/frontend/src/ui/components/forms/SaveButton.tsx +++ b/frontend/src/ui/components/forms/SaveButton.tsx @@ -31,4 +31,5 @@ function SaveButton( } } -export default React.memo(SaveButton); +const PureSaveButton = React.memo(SaveButton); +export default PureSaveButton; diff --git a/frontend/src/ui/components/forms/units.tsx b/frontend/src/ui/components/forms/units.tsx new file mode 100644 index 0000000..ef663be --- /dev/null +++ b/frontend/src/ui/components/forms/units.tsx @@ -0,0 +1,3 @@ +export const seconds = { multiplier: 1, unit: 'time.seconds' }; +export const minutes = { multiplier: 60, unit: 'time.minutes' }; +export const hours = { multiplier: 3600, unit: 'time.hours' }; diff --git a/frontend/src/ui/components/utils/RevealLink.tsx b/frontend/src/ui/components/utils/RevealLink.tsx index 61064e4..793d6c0 100644 --- a/frontend/src/ui/components/utils/RevealLink.tsx +++ b/frontend/src/ui/components/utils/RevealLink.tsx @@ -28,4 +28,5 @@ function RevealLink({ value, setter }: RevealLinkProps) { ); } -export default React.memo(RevealLink); +const PureRevealLink = React.memo(RevealLink); +export default PureRevealLink; diff --git a/frontend/src/ui/components/utils/Scrollbar.tsx b/frontend/src/ui/components/utils/Scrollbar.tsx index 4635643..ffd8fd1 100644 --- a/frontend/src/ui/components/utils/Scrollbar.tsx +++ b/frontend/src/ui/components/utils/Scrollbar.tsx @@ -61,4 +61,5 @@ function Scrollbar({ ); } -export default React.memo(Scrollbar); +const PureScrollbar = React.memo(Scrollbar); +export default PureScrollbar; diff --git a/frontend/src/ui/components/utils/WIPNotice.tsx b/frontend/src/ui/components/utils/WIPNotice.tsx index 0270baf..29c4505 100644 --- a/frontend/src/ui/components/utils/WIPNotice.tsx +++ b/frontend/src/ui/components/utils/WIPNotice.tsx @@ -33,4 +33,5 @@ function WIP(): React.ReactElement { ); } -export default React.memo(WIP); +const PureWIP = React.memo(WIP); +export default PureWIP; diff --git a/frontend/src/ui/pages/BotTimers.tsx b/frontend/src/ui/pages/BotTimers.tsx index 86321ca..a872c4b 100644 --- a/frontend/src/ui/pages/BotTimers.tsx +++ b/frontend/src/ui/pages/BotTimers.tsx @@ -8,7 +8,8 @@ import { modules } from '~/store/api/reducer'; import { TwitchBotTimer } from '~/store/api/types'; import AlertContent from '../components/AlertContent'; import DialogContent from '../components/DialogContent'; -import Interval, { hours, minutes } from '../components/forms/Interval'; +import Interval from '../components/forms/Interval'; +import { hours, minutes } from '../components/forms/units'; import MultiInput from '../components/forms/MultiInput'; import { Button,