~ashkeel/strimertul

270ee2e9a6f1fb86c8125c5635143714ba3d85ad — Ash Keel a month ago 97c9117
refactor: import sorting with biome
45 files changed, 143 insertions(+), 143 deletions(-)

M frontend/src/AppWrapper.tsx
M frontend/src/index.tsx
M frontend/src/lib/extensions/extension.ts
M frontend/src/lib/extensions/workers/extensionHost.ts
M frontend/src/lib/react.ts
M frontend/src/store/api/reducer.ts
M frontend/src/store/extensions/reducer.ts
M frontend/src/store/index.ts
M frontend/src/store/logging/reducer.ts
M frontend/src/store/server/reducer.ts
M frontend/src/ui/App.tsx
M frontend/src/ui/ErrorWindow.tsx
M frontend/src/ui/components/AlertContent.tsx
M frontend/src/ui/components/BrowserLink.tsx
M frontend/src/ui/components/DialogContent.tsx
M frontend/src/ui/components/InteractiveAuthDialog.tsx
M frontend/src/ui/components/Loading.tsx
M frontend/src/ui/components/LogViewer.tsx
M frontend/src/ui/components/PageList.tsx
M frontend/src/ui/components/Sidebar.tsx
M frontend/src/ui/components/TwitchUserBlock.tsx
M frontend/src/ui/components/forms/ControlledInput.tsx
M frontend/src/ui/components/forms/Interval.tsx
M frontend/src/ui/components/forms/RadioGroup.tsx
M frontend/src/ui/components/utils/Channels.tsx
M frontend/src/ui/components/utils/Scrollbar.tsx
M frontend/src/ui/pages/Dashboard.tsx
M frontend/src/ui/pages/Onboarding.tsx
M frontend/src/ui/pages/loyalty/LoyaltyConfig.tsx
M frontend/src/ui/pages/loyalty/Rewards/GoalsTab.tsx
M frontend/src/ui/pages/loyalty/Rewards/RewardsTab.tsx
M frontend/src/ui/pages/system/Debug.tsx
M frontend/src/ui/pages/system/Extensions.tsx
M frontend/src/ui/pages/system/ServerSettings.tsx
M frontend/src/ui/pages/system/Strimertul.tsx
M frontend/src/ui/pages/twitch/ChatAlerts.tsx
M frontend/src/ui/pages/twitch/ChatCommands.tsx
M frontend/src/ui/pages/twitch/ChatTimers.tsx
M frontend/src/ui/pages/twitch/TwitchSettings/Page.tsx
M frontend/src/ui/pages/twitch/TwitchSettings/TwitchAPISettings.tsx
M frontend/src/ui/pages/twitch/TwitchSettings/TwitchChatSettings.tsx
M frontend/src/ui/pages/twitch/TwitchSettings/TwitchEventSubSettings.tsx
M frontend/src/ui/theme/forms.ts
M frontend/tsconfig.json
M frontend/vite.config.ts
M frontend/src/AppWrapper.tsx => frontend/src/AppWrapper.tsx +2 -2
@@ 1,6 1,6 @@
import { IsFatalError } from "@wailsapp/go/main/App";
import { EventsOn, EventsOff } from "@wailsapp/runtime/runtime";
import { useState, useEffect } from "react";
import { EventsOff, EventsOn } from "@wailsapp/runtime/runtime";
import { useEffect, useState } from "react";
import App from "./ui/App";
import ErrorWindow from "./ui/ErrorWindow";


M frontend/src/index.tsx => frontend/src/index.tsx +2 -2
@@ 1,7 1,7 @@
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { HashRouter } from "react-router-dom";
import { StrictMode } from "react";

import "inter-ui/inter.css";
import "inter-ui/inter-variable.css";


@@ 9,9 9,9 @@ import "@fontsource/space-mono/index.css";
import "normalize.css/normalize.css";
import "./locale/setup";

import AppWrapper from "./AppWrapper";
import store from "./store";
import { globalStyles } from "./ui/theme";
import AppWrapper from "./AppWrapper";

globalStyles();


M frontend/src/lib/extensions/extension.ts => frontend/src/lib/extensions/extension.ts +2 -2
@@ 1,10 1,10 @@
import type { ExtensionEntry } from "~/store/extensions/reducer";
import {
	ExtensionStatus,
	type ExtensionDependencies,
	type ExtensionHostMessage,
	type ExtensionHostCommand,
	type ExtensionHostMessage,
	type ExtensionRunOptions,
	ExtensionStatus,
} from "./types";

export const blankTemplate = (slug: string) => `// ==Extension==

M frontend/src/lib/extensions/workers/extensionHost.ts => frontend/src/lib/extensions/workers/extensionHost.ts +1 -1
@@ 1,7 1,7 @@
import Kilovolt from "@strimertul/kilovolt-client";
import ts from "typescript";
import { type ExtensionHostCommand, type ExtensionHostMessage, ExtensionStatus } from "../types";
import { type SourceMapMappings, parseSourceMap } from "../sourceMap";
import { type ExtensionHostCommand, type ExtensionHostMessage, ExtensionStatus } from "../types";

const sendMessage = (message: ExtensionHostMessage, transfer?: Transferable[]) =>
	postMessage(message, transfer);

M frontend/src/lib/react.ts => frontend/src/lib/react.ts +1 -1
@@ 1,6 1,6 @@
import type { ActionCreatorWithOptionalPayload, AsyncThunk, Draft } from "@reduxjs/toolkit";
import { useEffect, useState } from "react";
import type { KilovoltMessage, SubscriptionHandler } from "@strimertul/kilovolt-client";
import { useEffect, useState } from "react";
import { useAppDispatch, useAppSelector } from "~/store";
import apiReducer, { getUserPoints } from "~/store/api/reducer";
import type {

M frontend/src/store/api/reducer.ts => frontend/src/store/api/reducer.ts +9 -9
@@ 1,35 1,35 @@
import {
	type AsyncThunk,
	type CaseReducer,
	createAction,
	createAsyncThunk,
	createSlice,
	type Dispatch,
	type PayloadAction,
	type UnknownAction,
	createAction,
	createAsyncThunk,
	createSlice,
} from "@reduxjs/toolkit";
import KilovoltWS, { type KilovoltMessage } from "@strimertul/kilovolt-client";
import type { kvError } from "@strimertul/kilovolt-client/types/messages";
import { AuthenticateKVClient, IsServerReady } from "@wailsapp/go/main/App";
import { delay } from "~/lib/time";
import type { ThunkConfig } from "..";
import {
	type APIState,
	ConnectionStatus,
	type HTTPConfig,
	type LoyaltyConfig,
	type LoyaltyGoal,
	type LoyaltyPointsEntry,
	type LoyaltyRedeem,
	type LoyaltyReward,
	type LoyaltyStorage,
	type TwitchChatAlertsConfig,
	type TwitchChatConfig,
	type TwitchConfig,
	type TwitchChatCustomCommands,
	type TwitchChatTimersConfig,
	type TwitchChatAlertsConfig,
	type LoyaltyConfig,
	type LoyaltyReward,
	type LoyaltyGoal,
	type TwitchConfig,
	type UISettings,
} from "./types";
import type { ThunkConfig } from "..";

type ThunkAPIState = { api: APIState };


M frontend/src/store/extensions/reducer.ts => frontend/src/store/extensions/reducer.ts +1 -1
@@ 1,4 1,4 @@
import { createAsyncThunk, createSlice, type PayloadAction } from "@reduxjs/toolkit";
import { type PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { Extension } from "~/lib/extensions/extension";
import {
	type ExtensionDependencies,

M frontend/src/store/index.ts => frontend/src/store/index.ts +1 -1
@@ 3,8 3,8 @@ import { type EqualityFn, useDispatch, useSelector } from "react-redux";
import { thunk } from "redux-thunk";

import apiReducer from "./api/reducer";
import loggingReducer from "./logging/reducer";
import extensionsReducer from "./extensions/reducer";
import loggingReducer from "./logging/reducer";
import serverReducer from "./server/reducer";

const store = configureStore({

M frontend/src/store/logging/reducer.ts => frontend/src/store/logging/reducer.ts +1 -1
@@ 1,4 1,4 @@
import { createSlice, type PayloadAction } from "@reduxjs/toolkit";
import { type PayloadAction, createSlice } from "@reduxjs/toolkit";
import type { log } from "@wailsapp/go/models";

export interface ProcessedLogEntry {

M frontend/src/store/server/reducer.ts => frontend/src/store/server/reducer.ts +1 -1
@@ 1,5 1,5 @@
/* eslint-disable no-param-reassign */
import { createAsyncThunk, createSlice, type PayloadAction } from "@reduxjs/toolkit";
import { type PayloadAction, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { GetAppVersion } from "@wailsapp/go/main/App";
import type { main } from "@wailsapp/go/models";


M frontend/src/ui/App.tsx => frontend/src/ui/App.tsx +13 -13
@@ 3,15 3,15 @@ import {
	CodeIcon,
	DashboardIcon,
	FrameIcon,
	MixerHorizontalIcon,
	MixIcon,
	MixerHorizontalIcon,
	StarIcon,
	TableIcon,
	TimerIcon,
} from "@radix-ui/react-icons";
import { EventsOff, EventsOn } from "@wailsapp/runtime/runtime";
import { useTranslation } from "react-i18next";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Route, Routes, useLocation, useNavigate } from "react-router-dom";

import { GetKilovoltBind, GetLastLogs, IsServerReady } from "@wailsapp/go/main/App";


@@ 20,31 20,31 @@ import type { log, main } from "@wailsapp/go/models";
import { useAppDispatch, useAppSelector } from "~/store";
import { createWSClient, useAuthBypass } from "~/store/api/reducer";
import { ConnectionStatus } from "~/store/api/types";
import loggingReducer from "~/store/logging/reducer";
import { initializeExtensions } from "~/store/extensions/reducer";
import loggingReducer from "~/store/logging/reducer";
import { initializeServerInfo } from "~/store/server/reducer";

import { useKilovoltClient } from "~/lib/react";
import InteractiveAuthDialog from "./components/InteractiveAuthDialog";
import Loading from "./components/Loading";
import LogViewer from "./components/LogViewer";
import Sidebar, { type RouteSection } from "./components/Sidebar";
import Scrollbar from "./components/utils/Scrollbar";
import TwitchChatCommandsPage from "./pages/twitch/ChatCommands";
import TwitchChatTimersPage from "./pages/twitch/ChatTimers";
import ChatAlertsPage from "./pages/twitch/ChatAlerts";
import Dashboard from "./pages/Dashboard";
import DebugPage from "./pages/system/Debug";
import OnboardingPage from "./pages/Onboarding";
import LoyaltyConfigPage from "./pages/loyalty/LoyaltyConfig";
import LoyaltyQueuePage from "./pages/loyalty/LoyaltyQueue";
import LoyaltyRewardsPage from "./pages/loyalty/Rewards/Page";
import OnboardingPage from "./pages/Onboarding";
import DebugPage from "./pages/system/Debug";
import ExtensionsPage from "./pages/system/Extensions";
import ServerSettingsPage from "./pages/system/ServerSettings";
import StrimertulPage from "./pages/system/Strimertul";
import TwitchSettingsPage from "./pages/twitch/TwitchSettings/Page";
import UISettingsPage from "./pages/system/UISettingsPage";
import ExtensionsPage from "./pages/system/Extensions";
import ChatAlertsPage from "./pages/twitch/ChatAlerts";
import TwitchChatCommandsPage from "./pages/twitch/ChatCommands";
import TwitchChatTimersPage from "./pages/twitch/ChatTimers";
import TwitchSettingsPage from "./pages/twitch/TwitchSettings/Page";
import { getTheme, styled } from "./theme";
import Loading from "./components/Loading";
import InteractiveAuthDialog from "./components/InteractiveAuthDialog";
import { useKilovoltClient } from "~/lib/react";

const sections: RouteSection[] = [
	{

M frontend/src/ui/ErrorWindow.tsx => frontend/src/ui/ErrorWindow.tsx +3 -3
@@ 17,7 17,6 @@ import {
	DialogActions,
	Field,
	FlexRow,
	getTheme,
	InputBox,
	Label,
	MultiToggle,


@@ 25,9 24,10 @@ import {
	PageContainer,
	PageHeader,
	SectionHeader,
	styled,
	Textarea,
	TextBlock,
	Textarea,
	getTheme,
	styled,
} from "~/ui/theme";
import AlertContent from "./components/AlertContent";
import { Alert, AlertDescription, AlertTrigger } from "./theme/alert";

M frontend/src/ui/components/AlertContent.tsx => frontend/src/ui/components/AlertContent.tsx +7 -7
@@ 1,17 1,17 @@
import React from "react";
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
import type { VariantProps } from "@stitches/react";
import React from "react";
import { useTranslation } from "react-i18next";
import { Button } from "../theme";
import {
	AlertOverlay,
	AlertContainer,
	AlertTitle,
	AlertDescription,
	AlertActions,
	AlertAction,
	AlertActions,
	AlertCancel,
	AlertContainer,
	AlertDescription,
	AlertOverlay,
	AlertTitle,
} from "../theme/alert";
import { Button } from "../theme";

export interface DialogProps {
	title?: string;

M frontend/src/ui/components/BrowserLink.tsx => frontend/src/ui/components/BrowserLink.tsx +1 -1
@@ 1,5 1,5 @@
import React from "react";
import { BrowserOpenURL } from "@wailsapp/runtime";
import React from "react";

function BrowserLink(props: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
	if (!props.href) {

M frontend/src/ui/components/DialogContent.tsx => frontend/src/ui/components/DialogContent.tsx +4 -4
@@ 1,12 1,12 @@
import React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { Cross2Icon } from "@radix-ui/react-icons";
import React from "react";
import {
	DialogOverlay,
	DialogContainer,
	IconButton,
	DialogTitle,
	DialogDescription,
	DialogOverlay,
	DialogTitle,
	IconButton,
} from "../theme";

export interface DialogProps {

M frontend/src/ui/components/InteractiveAuthDialog.tsx => frontend/src/ui/components/InteractiveAuthDialog.tsx +3 -3
@@ 1,10 1,10 @@
import { useEffect, useState } from "react";
import { EventsEmit, EventsOff, EventsOn } from "@wailsapp/runtime";
import { CheckCircledIcon, CrossCircledIcon } from "@radix-ui/react-icons";
import { EventsEmit, EventsOff, EventsOn } from "@wailsapp/runtime";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import DialogContent from "./DialogContent";
import { Button, Dialog, DialogActions, DialogDescription, TextBlock, styled } from "../theme";
import BrowserLink from "./BrowserLink";
import DialogContent from "./DialogContent";

interface AuthRequest {
	uid: number;

M frontend/src/ui/components/Loading.tsx => frontend/src/ui/components/Loading.tsx +1 -1
@@ 3,7 3,7 @@ import type React from "react";
// @ts-expect-error Asset import
import spinner from "~/assets/icon-loading.svg";

import { lightMode, styled, TextBlock } from "../theme";
import { TextBlock, lightMode, styled } from "../theme";

const variants = {
	size: {

M frontend/src/ui/components/LogViewer.tsx => frontend/src/ui/components/LogViewer.tsx +1 -1
@@ 1,8 1,8 @@
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { ClipboardCopyIcon, Cross2Icon, SizeIcon } from "@radix-ui/react-icons";
import React, { useState } from "react";
import { useTranslation } from "react-i18next";
import { useAppSelector } from "src/store";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { delay } from "~/lib/time";
import type { ProcessedLogEntry } from "~/store/logging/reducer";
import {

M frontend/src/ui/components/PageList.tsx => frontend/src/ui/components/PageList.tsx +1 -1
@@ 1,6 1,6 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { styled, Toolbar, ToolbarButton, ToolbarComboBox } from "../theme";
import { Toolbar, ToolbarButton, ToolbarComboBox, styled } from "../theme";

export interface PageListProps {
	current: number;

M frontend/src/ui/components/Sidebar.tsx => frontend/src/ui/components/Sidebar.tsx +1 -1
@@ 6,8 6,8 @@ import { Link, useMatch, useResolvedPath } from "react-router-dom";
// @ts-expect-error Asset import
import logo from "~/assets/icon-logo.svg";

import { useAppSelector } from "~/store";
import { ExternalLinkIcon } from "@radix-ui/react-icons";
import { useAppSelector } from "~/store";
import { APPNAME, lightMode, styled } from "../theme";
import BrowserLink from "./BrowserLink";
import Scrollbar from "./utils/Scrollbar";

M frontend/src/ui/components/TwitchUserBlock.tsx => frontend/src/ui/components/TwitchUserBlock.tsx +1 -1
@@ 2,9 2,9 @@ import { GetTwitchLoggedUser } from "@wailsapp/go/main/App";
import type { helix } from "@wailsapp/go/models";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useKilovoltClient } from "~/lib/react";
import { useAppSelector } from "~/store";
import { TextBlock, styled } from "../theme";
import { useKilovoltClient } from "~/lib/react";

interface SyncError {
	ok: false;

M frontend/src/ui/components/forms/ControlledInput.tsx => frontend/src/ui/components/forms/ControlledInput.tsx +1 -1
@@ 3,7 3,7 @@
// messing with the cursor

import type React from "react";
import { useState, useRef, useEffect } from "react";
import { useEffect, useRef, useState } from "react";

const ControlledInput = (
	props: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>,

M frontend/src/ui/components/forms/Interval.tsx => frontend/src/ui/components/forms/Interval.tsx +1 -1
@@ 1,7 1,7 @@
import { useTranslation } from "react-i18next";
import { getInterval } from "~/lib/time";
import { ComboBox, FlexRow, InputBox } from "../../theme";
import { seconds, minutes, hours } from "./units";
import { hours, minutes, seconds } from "./units";

export interface TimeUnit {
	multiplier: number;

M frontend/src/ui/components/forms/RadioGroup.tsx => frontend/src/ui/components/forms/RadioGroup.tsx +3 -3
@@ 1,10 1,10 @@
import React, { type ReactElement } from "react";
import {
	Root,
	Item,
	Indicator,
	Item,
	Root,
	type RadioGroupProps as RootProps,
} from "@radix-ui/react-radio-group";
import React, { type ReactElement } from "react";
import { lightMode, styled } from "~/ui/theme";

export interface RadioGroupProps {

M frontend/src/ui/components/utils/Channels.tsx => frontend/src/ui/components/utils/Channels.tsx +1 -1
@@ 1,5 1,5 @@
import { ChatBubbleIcon, DiscordLogoIcon, EnvelopeClosedIcon } from "@radix-ui/react-icons";
import { ChannelList, Channel, ChannelLink } from "~/ui/pages/system/Strimertul";
import { Channel, ChannelLink, ChannelList } from "~/ui/pages/system/Strimertul";

export const Channels = (
	<ChannelList>

M frontend/src/ui/components/utils/Scrollbar.tsx => frontend/src/ui/components/utils/Scrollbar.tsx +1 -1
@@ 1,5 1,5 @@
import React from "react";
import * as ScrollArea from "@radix-ui/react-scroll-area";
import React from "react";
import { styled } from "../../theme";

export interface ScrollbarProps {

M frontend/src/ui/pages/Dashboard.tsx => frontend/src/ui/pages/Dashboard.tsx +7 -7
@@ 1,23 1,23 @@
import * as HoverCard from "@radix-ui/react-hover-card";
import {
	CircleIcon,
	ExclamationTriangleIcon,
	InfoCircledIcon,
	UpdateIcon,
} from "@radix-ui/react-icons";
import { GetLastLogs, GetProblems, GetTwitchAuthURL } from "@wailsapp/go/main/App";
import type { main } from "@wailsapp/go/models";
import { BrowserOpenURL } from "@wailsapp/runtime/runtime";
import { useEffect, useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { type EventSubNotification, EventSubNotificationType, unwrapEvent } from "~/lib/eventSub";
import { useKilovoltClient, useLiveKey, useModule } from "~/lib/react";
import { useAppDispatch, useAppSelector } from "~/store";
import { modules } from "~/store/api/reducer";
import * as HoverCard from "@radix-ui/react-hover-card";
import { useEffect, useState } from "react";
import type { main } from "@wailsapp/go/models";
import { GetLastLogs, GetProblems, GetTwitchAuthURL } from "@wailsapp/go/main/App";
import { BrowserOpenURL } from "@wailsapp/runtime/runtime";
import { PageContainer, SectionHeader, styled, TextBlock, theme, TooltipContent } from "../theme";
import BrowserLink from "../components/BrowserLink";
import Scrollbar from "../components/utils/Scrollbar";
import RevealLink from "../components/utils/RevealLink";
import Scrollbar from "../components/utils/Scrollbar";
import { PageContainer, SectionHeader, TextBlock, TooltipContent, styled, theme } from "../theme";

interface StreamInfo {
	id: string;

M frontend/src/ui/pages/Onboarding.tsx => frontend/src/ui/pages/Onboarding.tsx +4 -4
@@ 15,27 15,27 @@ import spinner from "~/assets/icon-logo.svg";
import AlertContent from "../components/AlertContent";
import BrowserLink from "../components/BrowserLink";
import DefinitionTable from "../components/DefinitionTable";
import RevealLink from "../components/utils/RevealLink";
import Channels from "../components/utils/Channels";
import RevealLink from "../components/utils/RevealLink";

import TwitchUserBlock from "../components/TwitchUserBlock";
import {
	Button,
	ButtonGroup,
	Field,
	InputBox,
	Label,
	lightMode,
	MultiToggle,
	MultiToggleItem,
	PageContainer,
	PasswordInputBox,
	SectionHeader,
	styled,
	TextBlock,
	lightMode,
	styled,
	themes,
} from "../theme";
import { Alert } from "../theme/alert";
import TwitchUserBlock from "../components/TwitchUserBlock";

const Container = styled("div", {
	display: "flex",

M frontend/src/ui/pages/loyalty/LoyaltyConfig.tsx => frontend/src/ui/pages/loyalty/LoyaltyConfig.tsx +11 -11
@@ 1,24 1,24 @@
import type React from "react";
import { CheckIcon } from "@radix-ui/react-icons";
import type React from "react";
import { useTranslation } from "react-i18next";
import { useModule, useTimedStatus } from "~/lib/react";
import apiReducer, { modules } from "~/store/api/reducer";
import { useAppDispatch } from "~/store";
import apiReducer, { modules } from "~/store/api/reducer";
import Interval from "../../components/forms/Interval";
import SaveButton from "../../components/forms/SaveButton";
import {
	Checkbox,
	CheckboxIndicator,
	Field,
	FieldNote,
	FlexRow,
	InputBox,
	Label,
	PageContainer,
	PageHeader,
	PageTitle,
	TextBlock,
	Field,
	FlexRow,
	Label,
	Checkbox,
	CheckboxIndicator,
	InputBox,
	FieldNote,
} from "../../theme";
import SaveButton from "../../components/forms/SaveButton";
import Interval from "../../components/forms/Interval";

export default function LoyaltySettingsPage(): React.ReactElement {
	const { t } = useTranslation();

M frontend/src/ui/pages/loyalty/Rewards/GoalsTab.tsx => frontend/src/ui/pages/loyalty/Rewards/GoalsTab.tsx +1 -1
@@ 19,8 19,8 @@ import {
	Label,
	MultiButton,
	NoneText,
	styled,
	Textarea,
	styled,
} from "../../../theme";
import { Alert, AlertTrigger } from "../../../theme/alert";
import {

M frontend/src/ui/pages/loyalty/Rewards/RewardsTab.tsx => frontend/src/ui/pages/loyalty/Rewards/RewardsTab.tsx +6 -6
@@ 23,19 23,19 @@ import {
	Label,
	MultiButton,
	NoneText,
	styled,
	Textarea,
	styled,
} from "../../../theme";
import { Alert, AlertTrigger } from "../../../theme/alert";
import {
	RewardItemContainer,
	RewardActions,
	RewardCost,
	RewardDescription,
	RewardHeader,
	RewardID,
	RewardIcon,
	RewardItemContainer,
	RewardName,
	RewardID,
	RewardCost,
	RewardActions,
	RewardDescription,
} from "./theme";

const RewardList = styled("div", { marginTop: "1rem" });

M frontend/src/ui/pages/system/Debug.tsx => frontend/src/ui/pages/system/Debug.tsx +1 -1
@@ 12,8 12,8 @@ import {
	PageContainer,
	PageHeader,
	PageTitle,
	styled,
	Textarea,
	styled,
} from "../../theme";

const Disclaimer = styled("div", {

M frontend/src/ui/pages/system/Extensions.tsx => frontend/src/ui/pages/system/Extensions.tsx +5 -5
@@ 1,4 1,5 @@
import Editor, { type Monaco, useMonaco } from "@monaco-editor/react";
import * as HoverCard from "@radix-ui/react-hover-card";
import {
	ExclamationTriangleIcon,
	InfoCircledIcon,


@@ 13,9 14,10 @@ import { blankTemplate } from "~/lib/extensions/extension";
import { kilovoltDefinition } from "~/lib/extensions/helpers";
import { parseExtensionMetadata } from "~/lib/extensions/metadata";
import { ExtensionStatus } from "~/lib/extensions/types";
import { useModule } from "~/lib/react";
import slug from "~/lib/slug";
import * as HoverCard from "@radix-ui/react-hover-card";
import { useAppDispatch, useAppSelector } from "~/store";
import { modules } from "~/store/api/reducer";
import extensionsReducer, {
	currentFile,
	type ExtensionEntry,


@@ 27,8 29,6 @@ import extensionsReducer, {
	startExtension,
	stopExtension,
} from "~/store/extensions/reducer";
import { useModule } from "~/lib/react";
import { modules } from "~/store/api/reducer";
import AlertContent from "../../components/AlertContent";
import DialogContent from "../../components/DialogContent";
import Loading from "../../components/Loading";


@@ 40,18 40,18 @@ import {
	DialogActions,
	Field,
	FlexRow,
	getTheme,
	InputBox,
	Label,
	MultiButton,
	PageContainer,
	PageHeader,
	PageTitle,
	styled,
	TabButton,
	TabContainer,
	TabContent,
	TabList,
	getTheme,
	styled,
} from "../../theme";
import { Alert, AlertTrigger } from "../../theme/alert";


M frontend/src/ui/pages/system/ServerSettings.tsx => frontend/src/ui/pages/system/ServerSettings.tsx +1 -1
@@ 5,8 5,8 @@ import { useModule, useTimedStatus } from "~/lib/react";
import { useAppDispatch } from "~/store";
import apiReducer, { modules } from "~/store/api/reducer";
import AlertContent from "../../components/AlertContent";
import RevealLink from "../../components/utils/RevealLink";
import SaveButton from "../../components/forms/SaveButton";
import RevealLink from "../../components/utils/RevealLink";
import {
	Field,
	FieldNote,

M frontend/src/ui/pages/system/Strimertul.tsx => frontend/src/ui/pages/system/Strimertul.tsx +2 -2
@@ 1,15 1,15 @@
import { keyframes } from "@stitches/react";
import type React from "react";
import { useState } from "react";
import { keyframes } from "@stitches/react";
import { Trans, useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";

// @ts-expect-error Asset import
import logo from "~/assets/icon-logo.svg";

import { APPNAME, PageContainer, PageHeader, styled } from "../../theme";
import BrowserLink from "../../components/BrowserLink";
import Channels from "../../components/utils/Channels";
import { APPNAME, PageContainer, PageHeader, styled } from "../../theme";

const gradientAnimation = keyframes({
	"0%": {

M frontend/src/ui/pages/twitch/ChatAlerts.tsx => frontend/src/ui/pages/twitch/ChatAlerts.tsx +3 -3
@@ 1,10 1,11 @@
import { CheckIcon } from "@radix-ui/react-icons";
import type React from "react";
import { useTranslation } from "react-i18next";
import { CheckIcon } from "@radix-ui/react-icons";
import { useModule, useTimedStatus } from "~/lib/react";
import apiReducer, { modules } from "~/store/api/reducer";
import { useAppDispatch } from "~/store";
import apiReducer, { modules } from "~/store/api/reducer";
import MultiInput from "../../components/forms/MultiInput";
import SaveButton from "../../components/forms/SaveButton";
import {
	Checkbox,
	CheckboxIndicator,


@@ 20,7 21,6 @@ import {
	TabList,
	TextBlock,
} from "../../theme";
import SaveButton from "../../components/forms/SaveButton";

export default function ChatAlertsPage(): React.ReactElement {
	const { t } = useTranslation();

M frontend/src/ui/pages/twitch/ChatCommands.tsx => frontend/src/ui/pages/twitch/ChatCommands.tsx +4 -4
@@ 1,4 1,5 @@
import { PlusIcon } from "@radix-ui/react-icons";
import { TestCommandTemplate } from "@wailsapp/go/main/App";
import type React from "react";
import { useRef, useState } from "react";
import { useTranslation } from "react-i18next";


@@ 6,12 7,11 @@ import { useModule } from "~/lib/react";
import { useAppDispatch } from "~/store";
import { modules } from "~/store/api/reducer";
import {
	accessLevels,
	type AccessLevelType,
	type ReplyType,
	type TwitchChatCustomCommand,
	accessLevels,
} from "~/store/api/types";
import { TestCommandTemplate } from "@wailsapp/go/main/App";
import AlertContent from "../../components/AlertContent";
import DialogContent from "../../components/DialogContent";
import {


@@ 32,9 32,9 @@ import {
	PageContainer,
	PageHeader,
	PageTitle,
	styled,
	Textarea,
	TextBlock,
	Textarea,
	styled,
} from "../../theme";
import { Alert, AlertTrigger } from "../../theme/alert";


M frontend/src/ui/pages/twitch/ChatTimers.tsx => frontend/src/ui/pages/twitch/ChatTimers.tsx +2 -2
@@ 10,8 10,8 @@ import type { TwitchChatTimer } from "~/store/api/types";
import AlertContent from "../../components/AlertContent";
import DialogContent from "../../components/DialogContent";
import Interval from "../../components/forms/Interval";
import { hours, minutes } from "../../components/forms/units";
import MultiInput from "../../components/forms/MultiInput";
import { hours, minutes } from "../../components/forms/units";
import {
	Button,
	Dialog,


@@ 26,8 26,8 @@ import {
	PageContainer,
	PageHeader,
	PageTitle,
	styled,
	TextBlock,
	styled,
} from "../../theme";
import { Alert, AlertTrigger } from "../../theme/alert";


M frontend/src/ui/pages/twitch/TwitchSettings/Page.tsx => frontend/src/ui/pages/twitch/TwitchSettings/Page.tsx +1 -1
@@ 20,8 20,8 @@ import {
	TextBlock,
} from "../../../theme";
import TwitchAPISettings from "./TwitchAPISettings";
import TwitchEventSubSettings from "./TwitchEventSubSettings";
import TwitchChatSettings from "./TwitchChatSettings";
import TwitchEventSubSettings from "./TwitchEventSubSettings";

export default function TwitchSettingsPage(): React.ReactElement {
	const { t } = useTranslation();

M frontend/src/ui/pages/twitch/TwitchSettings/TwitchAPISettings.tsx => frontend/src/ui/pages/twitch/TwitchSettings/TwitchAPISettings.tsx +4 -4
@@ 1,13 1,14 @@
import { useState } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useModule, useTimedStatus } from "~/lib/react";
import { checkTwitchKeys } from "~/lib/twitch";
import { useAppDispatch } from "~/store";
import apiReducer, { modules } from "~/store/api/reducer";
import { checkTwitchKeys } from "~/lib/twitch";
import AlertContent from "../../../components/AlertContent";
import BrowserLink from "../../../components/BrowserLink";
import DefinitionTable from "../../../components/DefinitionTable";
import RevealLink from "../../../components/utils/RevealLink";
import SaveButton from "../../../components/forms/SaveButton";
import RevealLink from "../../../components/utils/RevealLink";
import {
	Button,
	ButtonGroup,


@@ 16,10 17,9 @@ import {
	Label,
	PasswordInputBox,
	SectionHeader,
	styled,
	TextBlock,
	styled,
} from "../../../theme";
import AlertContent from "../../../components/AlertContent";
import { Alert } from "../../../theme/alert";

const StepList = styled("ul", {

M frontend/src/ui/pages/twitch/TwitchSettings/TwitchChatSettings.tsx => frontend/src/ui/pages/twitch/TwitchSettings/TwitchChatSettings.tsx +2 -2
@@ 1,10 1,10 @@
import { ExternalLinkIcon } from "@radix-ui/react-icons";
import { useTranslation } from "react-i18next";
import { useLiveKeyString, useModule, useTimedStatus } from "~/lib/react";
import { startAuthFlow } from "~/lib/twitch";
import { useAppDispatch, useAppSelector } from "~/store";
import apiReducer, { modules } from "~/store/api/reducer";
import { startAuthFlow } from "~/lib/twitch";
import TwitchUserBlock from "~/ui/components/TwitchUserBlock";
import { ExternalLinkIcon } from "@radix-ui/react-icons";
import SaveButton from "../../../components/forms/SaveButton";
import { Button, Field, FlexRow, InputBox, Label, SectionHeader, TextBlock } from "../../../theme";


M frontend/src/ui/pages/twitch/TwitchSettings/TwitchEventSubSettings.tsx => frontend/src/ui/pages/twitch/TwitchSettings/TwitchEventSubSettings.tsx +2 -2
@@ 1,10 1,10 @@
import { ExternalLinkIcon } from "@radix-ui/react-icons";
import { useTranslation } from "react-i18next";
import eventsubTests from "~/data/eventsub-tests";
import { useAppSelector } from "~/store";
import { startAuthFlow } from "~/lib/twitch";
import { Button, ButtonGroup, SectionHeader, TextBlock } from "../../../theme";
import { useAppSelector } from "~/store";
import TwitchUserBlock from "../../../components/TwitchUserBlock";
import { Button, ButtonGroup, SectionHeader, TextBlock } from "../../../theme";

export default function TwitchEventSubSettings() {
	const { t } = useTranslation();

M frontend/src/ui/theme/forms.ts => frontend/src/ui/theme/forms.ts +2 -2
@@ 1,9 1,9 @@
import * as UnstyledLabel from "@radix-ui/react-label";
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import * as UnstyledLabel from "@radix-ui/react-label";
import * as ToggleGroup from "@radix-ui/react-toggle-group";
import { lightMode, styled, theme } from "./theme";
import ControlledInput from "../components/forms/ControlledInput";
import PasswordField from "../components/forms/PasswordField";
import { lightMode, styled, theme } from "./theme";

export const Field = styled("fieldset", {
	all: "unset",

M frontend/tsconfig.json => frontend/tsconfig.json +14 -14
@@ 1,16 1,16 @@
{
  "compilerOptions": {
    "target": "esnext",
    "module": "es2022",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "jsx": "react-jsx",
    "lib": ["es2019", "dom"],
    "resolveJsonModule": true,
    "baseUrl": ".",
    "paths": {
      "@wailsapp/*": ["./wailsjs/*"],
      "~/*": ["./src/*"],
    }
  }
	"compilerOptions": {
		"target": "esnext",
		"module": "es2022",
		"moduleResolution": "node",
		"allowSyntheticDefaultImports": true,
		"jsx": "react-jsx",
		"lib": ["es2019", "dom"],
		"resolveJsonModule": true,
		"baseUrl": ".",
		"paths": {
			"@wailsapp/*": ["./wailsjs/*"],
			"~/*": ["./src/*"]
		}
	}
}

M frontend/vite.config.ts => frontend/vite.config.ts +7 -7
@@ 1,10 1,10 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import tsconfigPaths from "vite-tsconfig-paths";

export default defineConfig({
  plugins: [tsconfigPaths(), react()],
  build: {
    emptyOutDir: false,
  },
	plugins: [tsconfigPaths(), react()],
	build: {
		emptyOutDir: false,
	},
});