diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 6ee8d11e..3a73b147 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,11 +1,12 @@ import { Elysia, t } from "elysia"; import { cors } from "@elysiajs/cors"; -import { swagger, onAfterHandle } from "./swagger"; +import { swagger } from "@elysiajs/swagger"; import { addTranscodeJob, addPackageJob } from "@mixwave/artisan/producer"; import { LangCodeSchema, VideoCodecSchema, AudioCodecSchema, + scalarCustomCss, } from "@mixwave/shared"; import { env } from "./env"; import { getJob, getJobs, getJobLogs } from "./jobs"; @@ -16,7 +17,23 @@ export type App = typeof app; const app = new Elysia() .use(cors()) - .use(swagger) + .use( + swagger({ + documentation: { + info: { + title: "Mixwave API", + description: + "The Mixwave API is organized around REST, returns JSON-encoded responses " + + "and uses standard HTTP response codes and verbs.", + version: "1.0.0", + }, + }, + scalarConfig: { + hideDownloadButton: true, + customCss: scalarCustomCss, + }, + }), + ) .model({ LangCode: LangCodeSchema, VideoCodec: VideoCodecSchema, @@ -260,8 +277,6 @@ const app = new Elysia() }, ); -app.onAfterHandle(onAfterHandle); - app.on("stop", () => { process.exit(0); }); diff --git a/packages/api/src/swagger.ts b/packages/api/src/swagger.ts deleted file mode 100644 index 505fc303..00000000 --- a/packages/api/src/swagger.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { swagger as elysiaSwagger } from "@elysiajs/swagger"; - -const CUSTOM_SCALAR_CSS = ` - .scalar-container.z-overlay { - padding-left: 16px; - padding-right: 16px; - } - - .scalar-api-client__send-request-button, .show-api-client-button { - background: var(--scalar-button-1); - } -`; - -export const swagger = elysiaSwagger({ - documentation: { - info: { - title: "Mixwave API", - description: - "The Mixwave API is organized around REST, returns JSON-encoded responses " + - "and uses standard HTTP response codes and verbs.", - version: "1.0.0", - }, - }, - scalarConfig: { - hideDownloadButton: true, - customCss: CUSTOM_SCALAR_CSS, - }, -}); - -const scalarScript = ` - -`; - -export async function onAfterHandle({ - request, - response, -}: { - request: Request; - response: Response; -}) { - const url = new URL(request.url); - - if (url.pathname.endsWith("/swagger")) { - const text = await response.text(); - const lines = text.split("\n"); - lines.splice( - lines.findIndex((line) => line.trim() === ""), - 0, - scalarScript, - ); - return new Response(lines.join(""), { - headers: { - "content-type": "text/html; charset=utf8", - }, - }); - } - - return response; -} diff --git a/packages/dashboard/src/App.tsx b/packages/dashboard/src/App.tsx index 3d25029a..a4b3a4c0 100644 --- a/packages/dashboard/src/App.tsx +++ b/packages/dashboard/src/App.tsx @@ -12,7 +12,6 @@ import { Suspense } from "react"; import { Toaster } from "@/components/ui/toaster"; import { PlayerPage } from "./pages/PlayerPage"; import { StoragePage } from "./pages/StoragePage"; -import { ThemeProvider } from "@/components/ui/theme-provider"; const queryClient = new QueryClient(); @@ -51,13 +50,11 @@ const router = createBrowserRouter([ export function App() { return ( - - - - - - - - + + + + + + ); } diff --git a/packages/dashboard/src/components/Editor.tsx b/packages/dashboard/src/components/Editor.tsx index 44ab1a47..82950b92 100644 --- a/packages/dashboard/src/components/Editor.tsx +++ b/packages/dashboard/src/components/Editor.tsx @@ -1,6 +1,5 @@ import MonacoEditor from "@monaco-editor/react"; import { useEffect, useState } from "react"; -import { useTheme } from "@/components/ui/theme-provider"; import type { BeforeMount, OnChange, OnMount } from "@monaco-editor/react"; type EditorProps = { @@ -16,9 +15,6 @@ export function Editor({ onSave, localStorageKey, }: EditorProps) { - const { theme } = useTheme(); - const style = useMonacoStyle(); - const [defaultValue] = useState(() => { const localStorageValue = localStorageKey ? localStorage.getItem(localStorageKey) @@ -58,14 +54,8 @@ export function Editor({ return (
-
-
{title}
-
-
- {style} +
{title}
+
); } - -function useMonacoStyle() { - const { theme } = useTheme(); - - if (theme === "dark") { - return ( - - ); - } - - return null; -} diff --git a/packages/dashboard/src/components/JobState.tsx b/packages/dashboard/src/components/JobState.tsx index df6cb065..2e82b1fa 100644 --- a/packages/dashboard/src/components/JobState.tsx +++ b/packages/dashboard/src/components/JobState.tsx @@ -8,31 +8,18 @@ import type { Job } from "@/api"; export function JobState({ state }: { state: Job["state"] }) { if (state === "completed") { - return createCircle( - "bg-emerald-200 text-emerald-800 dark:bg-emerald-400", - Check, - ); + return createCircle("bg-emerald-200 text-emerald-800", Check); } if (state === "failed") { - return createCircle("bg-red-200 text-red-800 dark:bg-red-400", X); + return createCircle("bg-red-200 text-red-800", X); } if (state === "running") { - return createCircle( - "bg-blue-200 text-blue-800 dark:bg-blue-400", - Loader, - "animate-spin", - ); + return createCircle("bg-blue-200 text-blue-800", Loader, "animate-spin"); } if (state === "skipped") { - return createCircle( - "bg-gray-200 text-gray-800 dark:bg-gray-400", - CircleOff, - ); + return createCircle("bg-gray-200 text-gray-800", CircleOff); } - return createCircle( - "bg-violet-200 text-violet-800 dark:bg-gray-400", - CircleDotDashed, - ); + return createCircle("bg-violet-200 text-violet-800", CircleDotDashed); } function createCircle( diff --git a/packages/dashboard/src/components/JsonHighlight.tsx b/packages/dashboard/src/components/JsonHighlight.tsx index 544efe8c..20468198 100644 --- a/packages/dashboard/src/components/JsonHighlight.tsx +++ b/packages/dashboard/src/components/JsonHighlight.tsx @@ -1,8 +1,10 @@ import { useMemo } from "react"; import { Light as SyntaxHighlighter } from "react-syntax-highlighter"; import json from "react-syntax-highlighter/dist/esm/languages/hljs/json"; -import { useTheme } from "@/components/ui/theme-provider"; -import { styleLight, styleDark } from "@/lib/syntax-styles"; +import style from "react-syntax-highlighter/dist/esm/styles/hljs/stackoverflow-light"; + +style["hljs"].padding = "1rem"; +delete style["hljs"].background; SyntaxHighlighter.registerLanguage("json", json); @@ -11,8 +13,6 @@ type SyntaxHighlightProps = { }; export function JsonHighlight({ json }: SyntaxHighlightProps) { - const { theme } = useTheme(); - const data = useMemo(() => { const parsed = JSON.parse(json); return JSON.stringify(parsed, null, 2); @@ -21,7 +21,7 @@ export function JsonHighlight({ json }: SyntaxHighlightProps) { return ( {data} diff --git a/packages/dashboard/src/components/Sidebar.tsx b/packages/dashboard/src/components/Sidebar.tsx index 92255e8f..5d68d800 100644 --- a/packages/dashboard/src/components/Sidebar.tsx +++ b/packages/dashboard/src/components/Sidebar.tsx @@ -5,7 +5,6 @@ import Rows3 from "lucide-react/icons/rows-3"; import Sailboat from "lucide-react/icons/sailboat"; import Play from "lucide-react/icons/play"; import Box from "lucide-react/icons/box"; -import { ModeToggle } from "@/components/ui/mode-toggle"; import { SidebarNavLink } from "./SidebarNavLink"; export function Sidebar() { @@ -41,9 +40,6 @@ export function Sidebar() {
-
- -
); } diff --git a/packages/dashboard/src/components/ui/mode-toggle.tsx b/packages/dashboard/src/components/ui/mode-toggle.tsx deleted file mode 100644 index c791b095..00000000 --- a/packages/dashboard/src/components/ui/mode-toggle.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Moon, Sun } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; -import { useTheme } from "@/components/ui/theme-provider"; - -export function ModeToggle() { - const { setTheme } = useTheme(); - - return ( - - - - - - setTheme("light")}> - Light - - setTheme("dark")}> - Dark - - setTheme("system")}> - System - - - - ); -} diff --git a/packages/dashboard/src/components/ui/theme-provider.tsx b/packages/dashboard/src/components/ui/theme-provider.tsx deleted file mode 100644 index e18440d7..00000000 --- a/packages/dashboard/src/components/ui/theme-provider.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { createContext, useContext, useEffect, useState } from "react"; - -type Theme = "dark" | "light" | "system"; - -type ThemeProviderProps = { - children: React.ReactNode; - defaultTheme?: Theme; - storageKey?: string; -}; - -type ThemeProviderState = { - theme: Theme; - setTheme: (theme: Theme) => void; -}; - -const initialState: ThemeProviderState = { - theme: "system", - setTheme: () => null, -}; - -const ThemeProviderContext = createContext(initialState); - -export function ThemeProvider({ - children, - defaultTheme = "system", - storageKey = "vite-ui-theme", - ...props -}: ThemeProviderProps) { - const [theme, setTheme] = useState( - () => (localStorage.getItem(storageKey) as Theme) || defaultTheme, - ); - - useEffect(() => { - const root = window.document.documentElement; - - root.classList.remove("light", "dark"); - - if (theme === "system") { - const systemTheme = window.matchMedia("(prefers-color-scheme: dark)") - .matches - ? "dark" - : "light"; - - root.classList.add(systemTheme); - return; - } - - root.classList.add(theme); - }, [theme]); - - const value = { - theme, - setTheme: (theme: Theme) => { - localStorage.setItem(storageKey, theme); - setTheme(theme); - }, - }; - - return ( - - {children} - - ); -} - -export const useTheme = () => { - const context = useContext(ThemeProviderContext); - - if (context === undefined) - throw new Error("useTheme must be used within a ThemeProvider"); - - return context; -}; diff --git a/packages/dashboard/src/lib/syntax-styles.ts b/packages/dashboard/src/lib/syntax-styles.ts deleted file mode 100644 index 74bef64c..00000000 --- a/packages/dashboard/src/lib/syntax-styles.ts +++ /dev/null @@ -1,11 +0,0 @@ -import styleDark from "react-syntax-highlighter/dist/esm/styles/hljs/stackoverflow-dark"; - -styleDark["hljs"].padding = "1rem"; -delete styleDark["hljs"].background; - -import styleLight from "react-syntax-highlighter/dist/esm/styles/hljs/stackoverflow-light"; - -styleLight["hljs"].padding = "1rem"; -delete styleLight["hljs"].background; - -export { styleLight, styleDark }; diff --git a/packages/dashboard/src/pages/ApiPage.tsx b/packages/dashboard/src/pages/ApiPage.tsx index 6a9a2a7a..32f673cb 100644 --- a/packages/dashboard/src/pages/ApiPage.tsx +++ b/packages/dashboard/src/pages/ApiPage.tsx @@ -1,10 +1,8 @@ import { SelectObject } from "@/components/SelectObject"; -import { useTheme } from "@/components/ui/theme-provider"; import { useNavigate, useParams } from "react-router-dom"; export function ApiPage() { const navigate = useNavigate(); - const { theme } = useTheme(); const { service = "api" } = useParams() as { service?: string; }; @@ -14,8 +12,6 @@ export function ApiPage() { stitcher: window.__ENV__.PUBLIC_STITCHER_ENDPOINT, }[service]; - const query = `?theme=${theme}`; - return ( <>
@@ -39,7 +35,7 @@ export function ApiPage() { />
-