2021-12-15 09:28:17 +00:00
|
|
|
import {
|
|
|
|
ChatBubbleIcon,
|
|
|
|
DashboardIcon,
|
|
|
|
FrameIcon,
|
|
|
|
GearIcon,
|
|
|
|
MixerHorizontalIcon,
|
|
|
|
StarIcon,
|
|
|
|
TableIcon,
|
|
|
|
TimerIcon,
|
|
|
|
} from '@radix-ui/react-icons';
|
2022-11-24 00:54:56 +00:00
|
|
|
import { EventsOff, EventsOn } from '@wailsapp/runtime/runtime';
|
|
|
|
import { t } from 'i18next';
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
import { useSelector } from 'react-redux';
|
2021-12-15 09:28:17 +00:00
|
|
|
import { Route, Routes } from 'react-router-dom';
|
2021-12-15 11:12:19 +00:00
|
|
|
|
2022-11-24 00:54:56 +00:00
|
|
|
import {
|
|
|
|
GetKilovoltBind,
|
|
|
|
GetLastLogs,
|
|
|
|
IsServerReady,
|
|
|
|
} from '@wailsapp/go/main/App';
|
|
|
|
import { main } from '@wailsapp/go/models';
|
|
|
|
|
2022-11-18 14:46:50 +00:00
|
|
|
import { RootState, useAppDispatch } from '../store';
|
2022-11-18 19:28:13 +00:00
|
|
|
import { createWSClient, useAuthBypass } from '../store/api/reducer';
|
2021-12-15 09:28:17 +00:00
|
|
|
import { ConnectionStatus } from '../store/api/types';
|
2022-11-24 00:54:56 +00:00
|
|
|
import loggingReducer from '../store/logging/reducer';
|
|
|
|
import Sidebar, { RouteSection } from './components/Sidebar';
|
|
|
|
import AuthDialog from './pages/AuthDialog';
|
2022-01-02 10:46:07 +00:00
|
|
|
import TwitchBotCommandsPage from './pages/BotCommands';
|
2022-01-10 10:19:54 +00:00
|
|
|
import TwitchBotTimersPage from './pages/BotTimers';
|
2022-01-10 16:57:32 +00:00
|
|
|
import ChatAlertsPage from './pages/ChatAlerts';
|
2022-11-24 00:54:56 +00:00
|
|
|
import Dashboard from './pages/Dashboard';
|
|
|
|
import DebugPage from './pages/Debug';
|
2022-01-11 10:59:48 +00:00
|
|
|
import LoyaltyConfigPage from './pages/LoyaltyConfig';
|
2022-01-12 12:20:30 +00:00
|
|
|
import LoyaltyQueuePage from './pages/LoyaltyQueue';
|
2022-01-14 19:16:54 +00:00
|
|
|
import LoyaltyRewardsPage from './pages/LoyaltyRewards';
|
2022-11-24 00:54:56 +00:00
|
|
|
import ServerSettingsPage from './pages/ServerSettings';
|
|
|
|
import StrimertulPage from './pages/Strimertul';
|
|
|
|
import TwitchSettingsPage from './pages/TwitchSettings';
|
|
|
|
import { APPNAME, styled } from './theme';
|
|
|
|
|
|
|
|
// @ts-expect-error Asset import
|
|
|
|
import spinner from '../assets/icon-loading.svg';
|
2022-11-24 18:49:25 +00:00
|
|
|
import Scrollbar from './components/utils/Scrollbar';
|
|
|
|
import LogViewer from './components/LogViewer';
|
2021-12-15 09:28:17 +00:00
|
|
|
|
2021-12-16 16:01:24 +00:00
|
|
|
const LoadingDiv = styled('div', {
|
|
|
|
display: 'flex',
|
2022-11-24 00:54:56 +00:00
|
|
|
flexDirection: 'column',
|
2021-12-16 16:01:24 +00:00
|
|
|
justifyContent: 'center',
|
|
|
|
alignItems: 'center',
|
|
|
|
minHeight: '100vh',
|
|
|
|
});
|
2021-12-15 09:28:17 +00:00
|
|
|
|
2021-12-16 16:01:24 +00:00
|
|
|
const Spinner = styled('img', {
|
|
|
|
maxWidth: '100px',
|
|
|
|
});
|
2021-12-15 09:28:17 +00:00
|
|
|
|
2022-11-24 00:54:56 +00:00
|
|
|
interface LoadingProps {
|
|
|
|
message: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
function Loading({ message }: React.PropsWithChildren<LoadingProps>) {
|
2021-12-15 09:28:17 +00:00
|
|
|
return (
|
|
|
|
<LoadingDiv>
|
2022-11-18 14:46:50 +00:00
|
|
|
<Spinner src={spinner as string} alt="Loading..." />
|
2022-11-24 00:54:56 +00:00
|
|
|
<p>{message}</p>
|
2021-12-15 09:28:17 +00:00
|
|
|
</LoadingDiv>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
const sections: RouteSection[] = [
|
|
|
|
{
|
|
|
|
title: 'menu.sections.monitor',
|
|
|
|
links: [
|
|
|
|
{
|
|
|
|
title: 'menu.pages.monitor.dashboard',
|
|
|
|
url: '/',
|
|
|
|
icon: <DashboardIcon />,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.sections.strimertul',
|
|
|
|
links: [
|
|
|
|
{
|
|
|
|
title: 'menu.pages.strimertul.settings',
|
|
|
|
url: '/http',
|
|
|
|
icon: <GearIcon />,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.sections.twitch',
|
|
|
|
links: [
|
|
|
|
{
|
|
|
|
title: 'menu.pages.twitch.configuration',
|
|
|
|
url: '/twitch/settings',
|
|
|
|
icon: <MixerHorizontalIcon />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.pages.twitch.bot-commands',
|
|
|
|
url: '/twitch/bot/commands',
|
|
|
|
icon: <ChatBubbleIcon />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.pages.twitch.bot-timers',
|
|
|
|
url: '/twitch/bot/timers',
|
|
|
|
icon: <TimerIcon />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.pages.twitch.bot-alerts',
|
|
|
|
url: '/twitch/bot/alerts',
|
|
|
|
icon: <FrameIcon />,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.sections.loyalty',
|
|
|
|
links: [
|
|
|
|
{
|
|
|
|
title: 'menu.pages.loyalty.configuration',
|
|
|
|
url: '/loyalty/settings',
|
|
|
|
icon: <MixerHorizontalIcon />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.pages.loyalty.points',
|
|
|
|
url: '/loyalty/users',
|
|
|
|
icon: <TableIcon />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: 'menu.pages.loyalty.rewards',
|
|
|
|
url: '/loyalty/rewards',
|
|
|
|
icon: <StarIcon />,
|
|
|
|
},
|
|
|
|
],
|
|
|
|
},
|
|
|
|
];
|
2021-09-17 09:55:15 +00:00
|
|
|
|
2021-12-16 16:01:24 +00:00
|
|
|
const Container = styled('div', {
|
2021-12-18 02:25:00 +00:00
|
|
|
position: 'relative',
|
2021-12-16 16:01:24 +00:00
|
|
|
display: 'flex',
|
|
|
|
flexDirection: 'row',
|
2021-12-18 02:25:00 +00:00
|
|
|
overflow: 'hidden',
|
|
|
|
height: '100vh',
|
2021-12-16 16:01:24 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
const PageContent = styled('main', {
|
2021-12-18 02:25:00 +00:00
|
|
|
flex: 1,
|
|
|
|
overflow: 'auto',
|
|
|
|
});
|
|
|
|
|
|
|
|
const PageWrapper = styled('div', {
|
2021-12-16 16:01:24 +00:00
|
|
|
display: 'flex',
|
|
|
|
flexDirection: 'row',
|
|
|
|
flex: 1,
|
2021-12-18 02:25:00 +00:00
|
|
|
overflow: 'hidden',
|
2021-12-16 16:01:24 +00:00
|
|
|
});
|
|
|
|
|
2021-12-09 09:45:38 +00:00
|
|
|
export default function App(): JSX.Element {
|
2022-11-24 00:54:56 +00:00
|
|
|
const [ready, setReady] = useState(false);
|
2021-12-15 09:28:17 +00:00
|
|
|
const client = useSelector((state: RootState) => state.api.client);
|
|
|
|
const connected = useSelector(
|
|
|
|
(state: RootState) => state.api.connectionStatus,
|
|
|
|
);
|
2022-11-18 14:46:50 +00:00
|
|
|
const dispatch = useAppDispatch();
|
2021-12-15 09:28:17 +00:00
|
|
|
|
2022-11-18 19:28:13 +00:00
|
|
|
const connectToKV = async () => {
|
2022-11-24 00:54:56 +00:00
|
|
|
const address = await GetKilovoltBind();
|
2022-11-18 19:28:13 +00:00
|
|
|
await dispatch(
|
|
|
|
createWSClient({
|
|
|
|
address: `ws://${address}/ws`,
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2022-11-24 00:54:56 +00:00
|
|
|
// Get application logs
|
|
|
|
useEffect(() => {
|
|
|
|
void GetLastLogs().then((logs) => {
|
|
|
|
dispatch(loggingReducer.actions.loadedLogData(logs));
|
|
|
|
});
|
|
|
|
EventsOn('log-event', (event: main.LogEntry) => {
|
|
|
|
dispatch(loggingReducer.actions.receivedEvent(event));
|
|
|
|
});
|
|
|
|
return () => {
|
|
|
|
EventsOff('log-event');
|
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
void IsServerReady().then(setReady);
|
|
|
|
EventsOn('ready', (newValue: boolean) => {
|
|
|
|
setReady(newValue);
|
|
|
|
});
|
|
|
|
return () => {
|
|
|
|
EventsOff('ready');
|
|
|
|
};
|
|
|
|
}, []);
|
|
|
|
|
2021-12-15 09:28:17 +00:00
|
|
|
useEffect(() => {
|
2022-11-24 00:54:56 +00:00
|
|
|
if (!ready) {
|
|
|
|
return;
|
|
|
|
}
|
2021-12-15 09:28:17 +00:00
|
|
|
if (!client) {
|
2022-11-18 19:28:13 +00:00
|
|
|
void connectToKV();
|
|
|
|
}
|
|
|
|
if (connected === ConnectionStatus.AuthenticationNeeded) {
|
|
|
|
void dispatch(useAuthBypass());
|
2021-12-15 09:28:17 +00:00
|
|
|
}
|
2022-11-24 00:54:56 +00:00
|
|
|
}, [ready, connected]);
|
2021-12-15 09:28:17 +00:00
|
|
|
|
|
|
|
if (connected === ConnectionStatus.NotConnected) {
|
2022-11-24 00:54:56 +00:00
|
|
|
return <Loading message={t('special.loading', { APPNAME })} />;
|
2021-12-15 09:28:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (connected === ConnectionStatus.AuthenticationNeeded) {
|
|
|
|
return <AuthDialog />;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Container>
|
2022-11-24 18:49:25 +00:00
|
|
|
<LogViewer />
|
2021-12-15 09:28:17 +00:00
|
|
|
<Sidebar sections={sections} />
|
2022-11-24 18:49:25 +00:00
|
|
|
<Scrollbar
|
|
|
|
vertical={true}
|
|
|
|
root={{ flex: 1 }}
|
|
|
|
viewport={{ height: '100vh', flex: '1' }}
|
|
|
|
>
|
|
|
|
<PageContent>
|
|
|
|
<PageWrapper role="main">
|
|
|
|
<Routes>
|
|
|
|
<Route path="/" element={<Dashboard />} />
|
|
|
|
<Route path="/about" element={<StrimertulPage />} />
|
|
|
|
<Route path="/debug" element={<DebugPage />} />
|
|
|
|
<Route path="/http" element={<ServerSettingsPage />} />
|
|
|
|
<Route path="/twitch/settings" element={<TwitchSettingsPage />} />
|
|
|
|
<Route
|
|
|
|
path="/twitch/bot/commands"
|
|
|
|
element={<TwitchBotCommandsPage />}
|
|
|
|
/>
|
|
|
|
<Route
|
|
|
|
path="/twitch/bot/timers"
|
|
|
|
element={<TwitchBotTimersPage />}
|
|
|
|
/>
|
|
|
|
<Route path="/twitch/bot/alerts" element={<ChatAlertsPage />} />
|
|
|
|
<Route path="/loyalty/settings" element={<LoyaltyConfigPage />} />
|
|
|
|
<Route path="/loyalty/users" element={<LoyaltyQueuePage />} />
|
|
|
|
<Route path="/loyalty/rewards" element={<LoyaltyRewardsPage />} />
|
|
|
|
</Routes>
|
|
|
|
</PageWrapper>
|
|
|
|
</PageContent>
|
|
|
|
</Scrollbar>
|
2021-12-15 09:28:17 +00:00
|
|
|
</Container>
|
|
|
|
);
|
2021-05-02 12:29:43 +00:00
|
|
|
}
|