Skip to content

Commit

Permalink
chore: Remove index hack, move canvas layout outside for readability (#…
Browse files Browse the repository at this point in the history
…4006)

## Description

iframe now points to `/canvas` route
$ (splat) route has no UI, and now does only technical part.
_index route will be builder route on builder urls i.e.
`{ProjectId}.apps.webstudio.is` (next PR)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
  • Loading branch information
istarkov authored Aug 24, 2024
1 parent 8460cef commit 45e748f
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 107 deletions.
4 changes: 2 additions & 2 deletions apps/builder/app/builder/builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
$textEditingInstanceSelector,
} from "~/shared/nano-states";
import { $settings, type Settings } from "./shared/client-settings";
import { getBuildUrl } from "~/shared/router-utils";
import { getCanvasUrl } from "~/shared/router-utils";
import { useCopyPaste } from "~/shared/copy-paste";
import { BlockingAlerts } from "./features/blocking-alerts";
import { useSyncPageUrl } from "~/shared/pages";
Expand Down Expand Up @@ -311,7 +311,7 @@ export const Builder = ({
return unsubscribe;
}, []);

const canvasUrl = getBuildUrl({
const canvasUrl = getCanvasUrl({
project,
});

Expand Down
86 changes: 4 additions & 82 deletions apps/builder/app/routes/$.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,10 @@
import { lazy } from "react";
import {
type HeadersFunction,
type LoaderFunctionArgs,
redirect,
type HeadersFunction,
} from "@remix-run/server-runtime";
import {
isRouteErrorResponse,
Links,
Meta,
useLoaderData,
useRouteError,
} from "@remix-run/react";
import type { Params } from "@webstudio-is/react-sdk";
import { Body } from "@webstudio-is/sdk-components-react-remix";
import { createImageLoader } from "@webstudio-is/image";
import env from "~/env/env.server";
import { ErrorMessage } from "~/shared/error";
import { dashboardPath, isCanvas } from "~/shared/router-utils";
import { ClientOnly } from "~/shared/client-only";

import { dashboardPath } from "~/shared/router-utils";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const url = new URL(request.url);
Expand All @@ -38,29 +25,7 @@ export const loader = async ({ request }: LoaderFunctionArgs) => {
});
}

if (isCanvas(request) === false) {
throw redirect(dashboardPath());
}

const params: Params = {
imageBaseUrl: env.IMAGE_BASE_URL,
assetBaseUrl: env.ASSET_BASE_URL,
};

return { params };
};

export const ErrorBoundary = () => {
const error = useRouteError();

console.error({ error });
const message = isRouteErrorResponse(error)
? (error.data.message ?? error.data)
: error instanceof Error
? error.message
: String(error);

return <ErrorMessage message={message} />;
return redirect(dashboardPath());
};

export const headers: HeadersFunction = ({ errorHeaders, loaderHeaders }) => {
Expand All @@ -78,46 +43,3 @@ export const headers: HeadersFunction = ({ errorHeaders, loaderHeaders }) => {
}
return loaderHeaders;
};

const Canvas = lazy(async () => {
const { Canvas } = await import("~/canvas/index.client");
return { default: Canvas };
});

const Outlet = () => {
const { params } = useLoaderData<typeof loader>();
const imageLoader = createImageLoader({
imageBaseUrl: params.imageBaseUrl,
});
return (
<ClientOnly fallback={<Body />}>
<Canvas params={params} imageLoader={imageLoader} />
</ClientOnly>
);
};

/**
* @todo add support for published project on localhost
* consider switching current route to something like /canvas
*/

const Content = () => {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<Outlet />
</html>
);
};

export default Content;

// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
export const config = {
maxDuration: 30,
};
64 changes: 64 additions & 0 deletions apps/builder/app/routes/_canvas.canvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { lazy } from "react";
import { type LoaderFunctionArgs, redirect } from "@remix-run/server-runtime";
import {
isRouteErrorResponse,
useLoaderData,
useRouteError,
} from "@remix-run/react";
import type { Params } from "@webstudio-is/react-sdk";
import { Body } from "@webstudio-is/sdk-components-react-remix";
import { createImageLoader } from "@webstudio-is/image";
import env from "~/env/env.server";
import { ErrorMessage } from "~/shared/error";
import { dashboardPath, isCanvas } from "~/shared/router-utils";
import { ClientOnly } from "~/shared/client-only";

export const loader = async ({ request }: LoaderFunctionArgs) => {
if (isCanvas(request) === false) {
throw redirect(dashboardPath());
}

const params: Params = {
imageBaseUrl: env.IMAGE_BASE_URL,
assetBaseUrl: env.ASSET_BASE_URL,
};

return { params };
};

export const ErrorBoundary = () => {
const error = useRouteError();

console.error({ error });
const message = isRouteErrorResponse(error)
? (error.data.message ?? error.data)
: error instanceof Error
? error.message
: String(error);

return <ErrorMessage message={message} />;
};

const Canvas = lazy(async () => {
const { Canvas } = await import("~/canvas/index.client");
return { default: Canvas };
});

const CanvasRoute = () => {
const { params } = useLoaderData<typeof loader>();
const imageLoader = createImageLoader({
imageBaseUrl: params.imageBaseUrl,
});
return (
<ClientOnly fallback={<Body />}>
<Canvas params={params} imageLoader={imageLoader} />
</ClientOnly>
);
};

export default CanvasRoute;

// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
export const config = {
maxDuration: 30,
};
15 changes: 15 additions & 0 deletions apps/builder/app/routes/_canvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Links, Meta, Outlet } from "@remix-run/react";

export default function CanvasLayout() {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>
<Outlet />
</html>
);
}
26 changes: 5 additions & 21 deletions apps/builder/app/routes/_index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
// We want our catch-all route to also handle `/`.
// Unfortunately, Remix doesn't do this by default,
// see https://github.com/remix-run/remix/issues/2098#issuecomment-1049262218 .
// To solve this, we're re-exporting the $.tsx route API in index.tsx
import { redirect } from "@remix-run/server-runtime";
import { dashboardPath } from "~/shared/router-utils";

import type { LoaderFunctionArgs } from "@remix-run/server-runtime";
import CatchAllContnet, {
loader as catchAllloader,
ErrorBoundary as CatchAllErrorBoundary,
} from "./$";

// We're wrapping functions in order for them to be distinct from the ones in $.tsx.
// If they are the same, Remix may get confused, and don't load data on page transitions.

export const loader = (args: LoaderFunctionArgs) => catchAllloader(args);
export const ErrorBoundary = () => <CatchAllErrorBoundary />;
const Content = () => <CatchAllContnet />;
export default Content;

// Reduces Vercel function size from 29MB to 9MB for unknown reasons; effective when used in limited files.
export const config = {
maxDuration: 30,
// This is the builder path in the next PR
export const loader = async () => {
throw redirect(dashboardPath());
};
4 changes: 2 additions & 2 deletions apps/builder/app/shared/router-utils/path-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,12 +182,12 @@ export const restPatchPath = (props: { authToken?: string }) => {
}`;
};

export const getBuildUrl = ({ project }: { project: Project }) => {
export const getCanvasUrl = ({ project }: { project: Project }) => {
// const url = new URL(buildOrigin);
const searchParams = new URLSearchParams();
searchParams.set("projectId", project.id);

return `/?${searchParams.toString()}`;
return `/canvas?${searchParams.toString()}`;
};

export const restAi = (subEndpoint?: "detect" | "audio/transcriptions") =>
Expand Down

0 comments on commit 45e748f

Please sign in to comment.