add timeline header
This commit is contained in:
@@ -9,14 +9,15 @@
|
||||
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||
|
||||
import { Route as rootRouteImport } from './routes/__root'
|
||||
import { Route as TimelinesRouteImport } from './routes/timelines'
|
||||
import { Route as TimelineRouteImport } from './routes/timeline'
|
||||
import { Route as LoginRouteImport } from './routes/login'
|
||||
import { Route as DemoRouteImport } from './routes/demo'
|
||||
import { Route as DashboardRouteImport } from './routes/dashboard'
|
||||
import { Route as ConsentRouteImport } from './routes/consent'
|
||||
import { Route as IndexRouteImport } from './routes/index'
|
||||
import { Route as DefaultRouteImport } from './routes/_default'
|
||||
import { Route as DefaultIndexRouteImport } from './routes/_default.index'
|
||||
import { Route as TimelineTimelineIdRouteImport } from './routes/timeline.$timelineId'
|
||||
import { Route as DefaultTimelinesRouteImport } from './routes/_default.timelines'
|
||||
import { Route as DefaultLoginRouteImport } from './routes/_default.login'
|
||||
import { Route as DotwellKnownOpenidConfigurationRouteImport } from './routes/[.well-known]/openid-configuration'
|
||||
import { Route as DotwellKnownOauthProtectedResourceRouteImport } from './routes/[.well-known]/oauth-protected-resource'
|
||||
import { Route as DotwellKnownOauthAuthorizationServerRouteImport } from './routes/[.well-known]/oauth-authorization-server'
|
||||
@@ -24,21 +25,11 @@ import { Route as ApiMcpSplatRouteImport } from './routes/api/mcp/$'
|
||||
import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
|
||||
import { Route as DotwellKnownOauthAuthorizationServerApiAuthRouteImport } from './routes/[.well-known]/oauth-authorization-server.api.auth'
|
||||
|
||||
const TimelinesRoute = TimelinesRouteImport.update({
|
||||
id: '/timelines',
|
||||
path: '/timelines',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const TimelineRoute = TimelineRouteImport.update({
|
||||
id: '/timeline',
|
||||
path: '/timeline',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const LoginRoute = LoginRouteImport.update({
|
||||
id: '/login',
|
||||
path: '/login',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const DemoRoute = DemoRouteImport.update({
|
||||
id: '/demo',
|
||||
path: '/demo',
|
||||
@@ -54,16 +45,30 @@ const ConsentRoute = ConsentRouteImport.update({
|
||||
path: '/consent',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const IndexRoute = IndexRouteImport.update({
|
||||
const DefaultRoute = DefaultRouteImport.update({
|
||||
id: '/_default',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
} as any)
|
||||
const DefaultIndexRoute = DefaultIndexRouteImport.update({
|
||||
id: '/',
|
||||
path: '/',
|
||||
getParentRoute: () => rootRouteImport,
|
||||
getParentRoute: () => DefaultRoute,
|
||||
} as any)
|
||||
const TimelineTimelineIdRoute = TimelineTimelineIdRouteImport.update({
|
||||
id: '/$timelineId',
|
||||
path: '/$timelineId',
|
||||
getParentRoute: () => TimelineRoute,
|
||||
} as any)
|
||||
const DefaultTimelinesRoute = DefaultTimelinesRouteImport.update({
|
||||
id: '/timelines',
|
||||
path: '/timelines',
|
||||
getParentRoute: () => DefaultRoute,
|
||||
} as any)
|
||||
const DefaultLoginRoute = DefaultLoginRouteImport.update({
|
||||
id: '/login',
|
||||
path: '/login',
|
||||
getParentRoute: () => DefaultRoute,
|
||||
} as any)
|
||||
const DotwellKnownOpenidConfigurationRoute =
|
||||
DotwellKnownOpenidConfigurationRouteImport.update({
|
||||
id: '/.well-known/openid-configuration',
|
||||
@@ -100,50 +105,51 @@ const DotwellKnownOauthAuthorizationServerApiAuthRoute =
|
||||
} as any)
|
||||
|
||||
export interface FileRoutesByFullPath {
|
||||
'/': typeof IndexRoute
|
||||
'/': typeof DefaultIndexRoute
|
||||
'/consent': typeof ConsentRoute
|
||||
'/dashboard': typeof DashboardRoute
|
||||
'/demo': typeof DemoRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/timeline': typeof TimelineRouteWithChildren
|
||||
'/timelines': typeof TimelinesRoute
|
||||
'/.well-known/oauth-authorization-server': typeof DotwellKnownOauthAuthorizationServerRouteWithChildren
|
||||
'/.well-known/oauth-protected-resource': typeof DotwellKnownOauthProtectedResourceRoute
|
||||
'/.well-known/openid-configuration': typeof DotwellKnownOpenidConfigurationRoute
|
||||
'/login': typeof DefaultLoginRoute
|
||||
'/timelines': typeof DefaultTimelinesRoute
|
||||
'/timeline/$timelineId': typeof TimelineTimelineIdRoute
|
||||
'/api/auth/$': typeof ApiAuthSplatRoute
|
||||
'/api/mcp/$': typeof ApiMcpSplatRoute
|
||||
'/.well-known/oauth-authorization-server/api/auth': typeof DotwellKnownOauthAuthorizationServerApiAuthRoute
|
||||
}
|
||||
export interface FileRoutesByTo {
|
||||
'/': typeof IndexRoute
|
||||
'/consent': typeof ConsentRoute
|
||||
'/dashboard': typeof DashboardRoute
|
||||
'/demo': typeof DemoRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/timeline': typeof TimelineRouteWithChildren
|
||||
'/timelines': typeof TimelinesRoute
|
||||
'/.well-known/oauth-authorization-server': typeof DotwellKnownOauthAuthorizationServerRouteWithChildren
|
||||
'/.well-known/oauth-protected-resource': typeof DotwellKnownOauthProtectedResourceRoute
|
||||
'/.well-known/openid-configuration': typeof DotwellKnownOpenidConfigurationRoute
|
||||
'/login': typeof DefaultLoginRoute
|
||||
'/timelines': typeof DefaultTimelinesRoute
|
||||
'/timeline/$timelineId': typeof TimelineTimelineIdRoute
|
||||
'/': typeof DefaultIndexRoute
|
||||
'/api/auth/$': typeof ApiAuthSplatRoute
|
||||
'/api/mcp/$': typeof ApiMcpSplatRoute
|
||||
'/.well-known/oauth-authorization-server/api/auth': typeof DotwellKnownOauthAuthorizationServerApiAuthRoute
|
||||
}
|
||||
export interface FileRoutesById {
|
||||
__root__: typeof rootRouteImport
|
||||
'/': typeof IndexRoute
|
||||
'/_default': typeof DefaultRouteWithChildren
|
||||
'/consent': typeof ConsentRoute
|
||||
'/dashboard': typeof DashboardRoute
|
||||
'/demo': typeof DemoRoute
|
||||
'/login': typeof LoginRoute
|
||||
'/timeline': typeof TimelineRouteWithChildren
|
||||
'/timelines': typeof TimelinesRoute
|
||||
'/.well-known/oauth-authorization-server': typeof DotwellKnownOauthAuthorizationServerRouteWithChildren
|
||||
'/.well-known/oauth-protected-resource': typeof DotwellKnownOauthProtectedResourceRoute
|
||||
'/.well-known/openid-configuration': typeof DotwellKnownOpenidConfigurationRoute
|
||||
'/_default/login': typeof DefaultLoginRoute
|
||||
'/_default/timelines': typeof DefaultTimelinesRoute
|
||||
'/timeline/$timelineId': typeof TimelineTimelineIdRoute
|
||||
'/_default/': typeof DefaultIndexRoute
|
||||
'/api/auth/$': typeof ApiAuthSplatRoute
|
||||
'/api/mcp/$': typeof ApiMcpSplatRoute
|
||||
'/.well-known/oauth-authorization-server/api/auth': typeof DotwellKnownOauthAuthorizationServerApiAuthRoute
|
||||
@@ -155,58 +161,57 @@ export interface FileRouteTypes {
|
||||
| '/consent'
|
||||
| '/dashboard'
|
||||
| '/demo'
|
||||
| '/login'
|
||||
| '/timeline'
|
||||
| '/timelines'
|
||||
| '/.well-known/oauth-authorization-server'
|
||||
| '/.well-known/oauth-protected-resource'
|
||||
| '/.well-known/openid-configuration'
|
||||
| '/login'
|
||||
| '/timelines'
|
||||
| '/timeline/$timelineId'
|
||||
| '/api/auth/$'
|
||||
| '/api/mcp/$'
|
||||
| '/.well-known/oauth-authorization-server/api/auth'
|
||||
fileRoutesByTo: FileRoutesByTo
|
||||
to:
|
||||
| '/'
|
||||
| '/consent'
|
||||
| '/dashboard'
|
||||
| '/demo'
|
||||
| '/login'
|
||||
| '/timeline'
|
||||
| '/timelines'
|
||||
| '/.well-known/oauth-authorization-server'
|
||||
| '/.well-known/oauth-protected-resource'
|
||||
| '/.well-known/openid-configuration'
|
||||
| '/login'
|
||||
| '/timelines'
|
||||
| '/timeline/$timelineId'
|
||||
| '/'
|
||||
| '/api/auth/$'
|
||||
| '/api/mcp/$'
|
||||
| '/.well-known/oauth-authorization-server/api/auth'
|
||||
id:
|
||||
| '__root__'
|
||||
| '/'
|
||||
| '/_default'
|
||||
| '/consent'
|
||||
| '/dashboard'
|
||||
| '/demo'
|
||||
| '/login'
|
||||
| '/timeline'
|
||||
| '/timelines'
|
||||
| '/.well-known/oauth-authorization-server'
|
||||
| '/.well-known/oauth-protected-resource'
|
||||
| '/.well-known/openid-configuration'
|
||||
| '/_default/login'
|
||||
| '/_default/timelines'
|
||||
| '/timeline/$timelineId'
|
||||
| '/_default/'
|
||||
| '/api/auth/$'
|
||||
| '/api/mcp/$'
|
||||
| '/.well-known/oauth-authorization-server/api/auth'
|
||||
fileRoutesById: FileRoutesById
|
||||
}
|
||||
export interface RootRouteChildren {
|
||||
IndexRoute: typeof IndexRoute
|
||||
DefaultRoute: typeof DefaultRouteWithChildren
|
||||
ConsentRoute: typeof ConsentRoute
|
||||
DashboardRoute: typeof DashboardRoute
|
||||
DemoRoute: typeof DemoRoute
|
||||
LoginRoute: typeof LoginRoute
|
||||
TimelineRoute: typeof TimelineRouteWithChildren
|
||||
TimelinesRoute: typeof TimelinesRoute
|
||||
DotwellKnownOauthAuthorizationServerRoute: typeof DotwellKnownOauthAuthorizationServerRouteWithChildren
|
||||
DotwellKnownOauthProtectedResourceRoute: typeof DotwellKnownOauthProtectedResourceRoute
|
||||
DotwellKnownOpenidConfigurationRoute: typeof DotwellKnownOpenidConfigurationRoute
|
||||
@@ -216,13 +221,6 @@ export interface RootRouteChildren {
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface FileRoutesByPath {
|
||||
'/timelines': {
|
||||
id: '/timelines'
|
||||
path: '/timelines'
|
||||
fullPath: '/timelines'
|
||||
preLoaderRoute: typeof TimelinesRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/timeline': {
|
||||
id: '/timeline'
|
||||
path: '/timeline'
|
||||
@@ -230,13 +228,6 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof TimelineRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/login': {
|
||||
id: '/login'
|
||||
path: '/login'
|
||||
fullPath: '/login'
|
||||
preLoaderRoute: typeof LoginRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/demo': {
|
||||
id: '/demo'
|
||||
path: '/demo'
|
||||
@@ -258,12 +249,19 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof ConsentRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/': {
|
||||
id: '/'
|
||||
'/_default': {
|
||||
id: '/_default'
|
||||
path: ''
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof DefaultRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
}
|
||||
'/_default/': {
|
||||
id: '/_default/'
|
||||
path: '/'
|
||||
fullPath: '/'
|
||||
preLoaderRoute: typeof IndexRouteImport
|
||||
parentRoute: typeof rootRouteImport
|
||||
preLoaderRoute: typeof DefaultIndexRouteImport
|
||||
parentRoute: typeof DefaultRoute
|
||||
}
|
||||
'/timeline/$timelineId': {
|
||||
id: '/timeline/$timelineId'
|
||||
@@ -272,6 +270,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof TimelineTimelineIdRouteImport
|
||||
parentRoute: typeof TimelineRoute
|
||||
}
|
||||
'/_default/timelines': {
|
||||
id: '/_default/timelines'
|
||||
path: '/timelines'
|
||||
fullPath: '/timelines'
|
||||
preLoaderRoute: typeof DefaultTimelinesRouteImport
|
||||
parentRoute: typeof DefaultRoute
|
||||
}
|
||||
'/_default/login': {
|
||||
id: '/_default/login'
|
||||
path: '/login'
|
||||
fullPath: '/login'
|
||||
preLoaderRoute: typeof DefaultLoginRouteImport
|
||||
parentRoute: typeof DefaultRoute
|
||||
}
|
||||
'/.well-known/openid-configuration': {
|
||||
id: '/.well-known/openid-configuration'
|
||||
path: '/.well-known/openid-configuration'
|
||||
@@ -317,6 +329,21 @@ declare module '@tanstack/react-router' {
|
||||
}
|
||||
}
|
||||
|
||||
interface DefaultRouteChildren {
|
||||
DefaultLoginRoute: typeof DefaultLoginRoute
|
||||
DefaultTimelinesRoute: typeof DefaultTimelinesRoute
|
||||
DefaultIndexRoute: typeof DefaultIndexRoute
|
||||
}
|
||||
|
||||
const DefaultRouteChildren: DefaultRouteChildren = {
|
||||
DefaultLoginRoute: DefaultLoginRoute,
|
||||
DefaultTimelinesRoute: DefaultTimelinesRoute,
|
||||
DefaultIndexRoute: DefaultIndexRoute,
|
||||
}
|
||||
|
||||
const DefaultRouteWithChildren =
|
||||
DefaultRoute._addFileChildren(DefaultRouteChildren)
|
||||
|
||||
interface TimelineRouteChildren {
|
||||
TimelineTimelineIdRoute: typeof TimelineTimelineIdRoute
|
||||
}
|
||||
@@ -345,13 +372,11 @@ const DotwellKnownOauthAuthorizationServerRouteWithChildren =
|
||||
)
|
||||
|
||||
const rootRouteChildren: RootRouteChildren = {
|
||||
IndexRoute: IndexRoute,
|
||||
DefaultRoute: DefaultRouteWithChildren,
|
||||
ConsentRoute: ConsentRoute,
|
||||
DashboardRoute: DashboardRoute,
|
||||
DemoRoute: DemoRoute,
|
||||
LoginRoute: LoginRoute,
|
||||
TimelineRoute: TimelineRouteWithChildren,
|
||||
TimelinesRoute: TimelinesRoute,
|
||||
DotwellKnownOauthAuthorizationServerRoute:
|
||||
DotwellKnownOauthAuthorizationServerRouteWithChildren,
|
||||
DotwellKnownOauthProtectedResourceRoute:
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
createRootRouteWithContext,
|
||||
} from "@tanstack/react-router";
|
||||
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
||||
|
||||
import Header from "../components/header";
|
||||
import appCss from "../index.css?url";
|
||||
import type { QueryClient } from "@tanstack/react-query";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
@@ -47,7 +45,7 @@ export const Route = createRootRouteWithContext<RouterAppContext>()({
|
||||
|
||||
function RootDocument() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<head>
|
||||
<HeadContent />
|
||||
<script dangerouslySetInnerHTML={{ __html: themeScript }} />
|
||||
@@ -55,7 +53,6 @@ function RootDocument() {
|
||||
<body>
|
||||
<ThemeProvider>
|
||||
<div className="grid min-h-svh grid-rows-[auto_1fr]">
|
||||
<Header />
|
||||
<Outlet />
|
||||
</div>
|
||||
<Toaster richColors />
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
FieldRoot,
|
||||
} from "@/components/ui/field";
|
||||
|
||||
export const Route = createFileRoute("/")({
|
||||
export const Route = createFileRoute("/_default/")({
|
||||
component: HomeComponent,
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createFileRoute } from "@tanstack/react-router";
|
||||
import { useSuspenseQuery } from "@tanstack/react-query";
|
||||
import { timelinesQueryOptions } from "@/functions/get-timelines";
|
||||
|
||||
export const Route = createFileRoute("/timelines")({
|
||||
export const Route = createFileRoute("/_default/timelines")({
|
||||
loader: async ({ context }) => {
|
||||
await context.queryClient.ensureQueryData(timelinesQueryOptions());
|
||||
},
|
||||
15
apps/web/src/routes/_default.tsx
Normal file
15
apps/web/src/routes/_default.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Outlet, createFileRoute } from "@tanstack/react-router";
|
||||
import Header from "@/components/header";
|
||||
|
||||
export const Route = createFileRoute("/_default")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<Outlet />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
|
||||
import SignInForm from "@/components/sign-in-form";
|
||||
import SignUpForm from "@/components/sign-up-form";
|
||||
|
||||
export const Route = createFileRoute("/login")({
|
||||
component: RouteComponent,
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
const [showSignIn, setShowSignIn] = useState(false);
|
||||
|
||||
return showSignIn ? (
|
||||
<SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />
|
||||
) : (
|
||||
<SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { Link, createFileRoute } from "@tanstack/react-router";
|
||||
import { useSuspenseQuery } from "@tanstack/react-query";
|
||||
import { ArrowLeft, Moon, Plus, Sun } from "lucide-react";
|
||||
import type { FlutterEvent, FlutterTimelineState } from "@/lib/flutter-bridge";
|
||||
import { timelineQueryOptions } from "@/functions/get-timeline";
|
||||
import { FlutterView } from "@/components/flutter-view";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import UserMenu from "@/components/user-menu";
|
||||
import { useEntryMovedMutation } from "@/hooks/use-entry-moved-mutation";
|
||||
import { useEntryResizedMutation } from "@/hooks/use-entry-resized-mutation";
|
||||
import { useTheme } from "@/lib/theme";
|
||||
@@ -24,7 +27,7 @@ function RouteComponent() {
|
||||
const [flutterHeight, setFlutterHeight] = useState<number | undefined>();
|
||||
const entryMoved = useEntryMovedMutation(timelineId);
|
||||
const entryResized = useEntryResizedMutation(timelineId);
|
||||
const { theme } = useTheme();
|
||||
const { theme, toggleTheme } = useTheme();
|
||||
|
||||
const flutterState: FlutterTimelineState = useMemo(
|
||||
() => ({
|
||||
@@ -76,9 +79,40 @@ function RouteComponent() {
|
||||
|
||||
return (
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-3xl font-serif font-bold mb-6 mx-4">
|
||||
{timeline.title}
|
||||
</h1>
|
||||
<div className="flex flex-row items-center justify-between px-2 py-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<Link
|
||||
to="/timelines"
|
||||
className="text-muted-foreground hover:text-foreground inline-flex size-8 items-center justify-center rounded-md transition-colors"
|
||||
aria-label="Back to timelines"
|
||||
>
|
||||
<ArrowLeft className="size-4" />
|
||||
</Link>
|
||||
<h1 className="text-lg font-serif font-bold">{timeline.title}</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button variant="outline" size="sm">
|
||||
<Plus className="size-4" />
|
||||
Add Item
|
||||
</Button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={toggleTheme}
|
||||
className="text-muted-foreground hover:text-foreground inline-flex size-8 items-center justify-center rounded-md transition-colors"
|
||||
aria-label={
|
||||
theme === "dark" ? "Switch to light mode" : "Switch to dark mode"
|
||||
}
|
||||
>
|
||||
{theme === "dark" ? (
|
||||
<Sun className="size-4" />
|
||||
) : (
|
||||
<Moon className="size-4" />
|
||||
)}
|
||||
</button>
|
||||
<UserMenu />
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<FlutterView
|
||||
state={flutterState}
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "flutter build web --release --wasm --base-href /flutter/ && node scripts/copy-build.mjs"
|
||||
"build": "flutter build web --release --wasm --base-href /flutter/ --source-maps && node scripts/copy-build.mjs"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { cpSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import {
|
||||
copyFileSync,
|
||||
cpSync,
|
||||
existsSync,
|
||||
readFileSync,
|
||||
realpathSync,
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { execFileSync } from "node:child_process";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const src = resolve(__dirname, "../build/web");
|
||||
@@ -9,6 +17,22 @@ const dest = resolve(__dirname, "../../../apps/web/public/flutter");
|
||||
cpSync(src, dest, { recursive: true });
|
||||
console.log(`Copied Flutter build: ${src} → ${dest}`);
|
||||
|
||||
// Copy flutter.js.map from the Flutter SDK (not included in build output)
|
||||
const flutterBin = execFileSync("which", ["flutter"], {
|
||||
encoding: "utf-8",
|
||||
}).trim();
|
||||
const sdkBinDir = dirname(realpathSync(flutterBin));
|
||||
const flutterJsMap = resolve(
|
||||
sdkBinDir,
|
||||
"cache/flutter_web_sdk/flutter_js/flutter.js.map",
|
||||
);
|
||||
if (existsSync(flutterJsMap)) {
|
||||
copyFileSync(flutterJsMap, resolve(dest, "flutter.js.map"));
|
||||
console.log("Copied flutter.js.map from SDK");
|
||||
} else {
|
||||
console.warn(`flutter.js.map not found at ${flutterJsMap}`);
|
||||
}
|
||||
|
||||
// Extract buildConfig from flutter_bootstrap.js so the React app can fetch it
|
||||
const bootstrap = readFileSync(resolve(dest, "flutter_bootstrap.js"), "utf-8");
|
||||
const match = bootstrap.match(/_flutter\.buildConfig\s*=\s*({.*?});/);
|
||||
|
||||
Reference in New Issue
Block a user