Initial commit from agent-native create
This commit is contained in:
+174
@@ -0,0 +1,174 @@
|
||||
import { configureTracking } from "@agent-native/core/client/analytics";
|
||||
import { appPath } from "@agent-native/core/client/api-path";
|
||||
import { useDbSync } from "@agent-native/core/client/hooks";
|
||||
import {
|
||||
AppProviders,
|
||||
createAgentNativeQueryClient,
|
||||
} from "@agent-native/core/client/hooks";
|
||||
import { getLocaleInitScript, useT } from "@agent-native/core/client/i18n";
|
||||
import {
|
||||
CommandMenu,
|
||||
useCommandMenuShortcut,
|
||||
} from "@agent-native/core/client/navigation";
|
||||
import { getThemeInitScript } from "@agent-native/core/client/ui";
|
||||
import { IconHierarchy2, IconSun, IconMoon } from "@tabler/icons-react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useTheme } from "next-themes";
|
||||
import { useCallback, useState } from "react";
|
||||
import {
|
||||
Links,
|
||||
Meta,
|
||||
Outlet,
|
||||
Scripts,
|
||||
ScrollRestoration,
|
||||
useNavigate,
|
||||
} from "react-router";
|
||||
import type { LinksFunction } from "react-router";
|
||||
|
||||
import { Layout as AppLayout } from "@/components/layout/Layout";
|
||||
import { AppToolkitProvider } from "@/components/ui/toolkit-provider";
|
||||
import { useNavigationState } from "@/hooks/use-navigation-state";
|
||||
import { APP_TITLE } from "@/lib/app-config";
|
||||
import { TAB_ID } from "@/lib/tab-id";
|
||||
|
||||
import changelog from "../CHANGELOG.md?raw";
|
||||
import { i18nCatalog } from "./i18n";
|
||||
|
||||
import stylesheet from "./global.css?url";
|
||||
|
||||
configureTracking({
|
||||
getDefaultProps: (_name, properties) => ({
|
||||
...properties,
|
||||
app: "app",
|
||||
template: "chat",
|
||||
}),
|
||||
});
|
||||
|
||||
export const links: LinksFunction = () => [
|
||||
{ rel: "stylesheet", href: stylesheet },
|
||||
];
|
||||
|
||||
const THEME_INIT_SCRIPT = getThemeInitScript();
|
||||
const LOCALE_INIT_SCRIPT = getLocaleInitScript();
|
||||
|
||||
export function Layout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
||||
/>
|
||||
<script
|
||||
suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }}
|
||||
/>
|
||||
<script
|
||||
data-agent-native-locale-init
|
||||
suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
||||
/>
|
||||
<link rel="manifest" href={appPath("/manifest.json")} />
|
||||
<meta name="theme-color" content="#18181B" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta
|
||||
name="apple-mobile-web-app-status-bar-style"
|
||||
content="black-translucent"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-title" content={APP_TITLE} />
|
||||
<link rel="icon" type="image/svg+xml" href={appPath("/favicon.svg")} />
|
||||
<link rel="apple-touch-icon" href={appPath("/icon-180.svg")} />
|
||||
<Meta />
|
||||
<Links />
|
||||
</head>
|
||||
<body>
|
||||
{children}
|
||||
<ScrollRestoration />
|
||||
<Scripts />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
function DbSyncSetup() {
|
||||
const qc = useQueryClient();
|
||||
useNavigationState();
|
||||
useDbSync({
|
||||
queryClient: qc,
|
||||
ignoreSource: TAB_ID,
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
function ThemeToggleItem() {
|
||||
const { resolvedTheme, setTheme } = useTheme();
|
||||
const t = useT();
|
||||
const isDark = resolvedTheme === "dark";
|
||||
return (
|
||||
<CommandMenu.Item
|
||||
onSelect={() => setTheme(isDark ? "light" : "dark")}
|
||||
keywords={["theme", "dark", "light", "mode"]}
|
||||
>
|
||||
{isDark ? <IconSun size={16} /> : <IconMoon size={16} />}
|
||||
{t("root.toggleTheme")}
|
||||
</CommandMenu.Item>
|
||||
);
|
||||
}
|
||||
|
||||
function AppContent() {
|
||||
const [cmdkOpen, setCmdkOpen] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
const t = useT();
|
||||
useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
|
||||
return (
|
||||
<>
|
||||
<CommandMenu
|
||||
open={cmdkOpen}
|
||||
onOpenChange={setCmdkOpen}
|
||||
changelog={changelog}
|
||||
changelogKey="chat"
|
||||
>
|
||||
<CommandMenu.Group heading={t("root.commandActions")}>
|
||||
<CommandMenu.Item onSelect={() => {}}>
|
||||
{t("root.commandSearch")}
|
||||
</CommandMenu.Item>
|
||||
<CommandMenu.Item
|
||||
onSelect={() => navigate("/agent")}
|
||||
keywords={[
|
||||
"agent",
|
||||
"context",
|
||||
"files",
|
||||
"connections",
|
||||
"jobs",
|
||||
"access",
|
||||
]}
|
||||
>
|
||||
<IconHierarchy2 size={16} />
|
||||
{t("settings.openAgentSettings")}
|
||||
</CommandMenu.Item>
|
||||
</CommandMenu.Group>
|
||||
<CommandMenu.Group heading={t("root.commandAppearance")}>
|
||||
<ThemeToggleItem />
|
||||
</CommandMenu.Group>
|
||||
</CommandMenu>
|
||||
<AppLayout>
|
||||
<Outlet />
|
||||
</AppLayout>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Root() {
|
||||
const [queryClient] = useState(() => createAgentNativeQueryClient());
|
||||
return (
|
||||
<AppToolkitProvider>
|
||||
<AppProviders queryClient={queryClient} i18n={{ catalog: i18nCatalog }}>
|
||||
<DbSyncSetup />
|
||||
<AppContent />
|
||||
</AppProviders>
|
||||
</AppToolkitProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export { ErrorBoundary } from "@agent-native/core/client/ui";
|
||||
Reference in New Issue
Block a user