Skip to content

Commit

Permalink
Add directives to change how sites generate
Browse files Browse the repository at this point in the history
  • Loading branch information
SawyerHood committed Jun 4, 2024
1 parent 5a705e8 commit 50e7fe0
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 5 deletions.
17 changes: 15 additions & 2 deletions app/api/html/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ export async function POST(req: NextRequest) {
const url = formData.get("url")! as string;
const rawDeps = (formData.get("deps") as string) || "[]";
const deps = JSON.parse(rawDeps);
const prompts = JSON.parse((formData.get("prompts")! as string) || "[]");
const settings: Settings = JSON.parse(formData.get("settings")! as string);
const programStream = await createProgramStream({
url,
prompts,
// Keep only the last 3 deps
deps: deps
.filter(
Expand All @@ -57,11 +59,22 @@ async function createProgramStream({
url,
deps,
settings,
prompts,
}: {
url: string;
deps: { url: string; html: string }[];
settings: Settings;
prompts: string[];
}) {
const makeMessage = (url: string) => {
if (!prompts.length) {
return `<url>${url}</url>`;
}

return `${prompts
.map((prompt) => `<directive>${prompt}</directive>`)
.join("\n")}\n<url>${url}</url>`;
};
const params: ChatCompletionCreateParamsStreaming = {
messages: [
{
Expand All @@ -71,7 +84,7 @@ async function createProgramStream({
...deps.flatMap((dep): ChatCompletionMessageParam[] => [
{
role: "user",
content: dep.url,
content: makeMessage(dep.url),
},
{
role: "assistant",
Expand All @@ -83,7 +96,7 @@ async function createProgramStream({
]),
{
role: "user",
content: url,
content: makeMessage(url),
},
],

Expand Down
5 changes: 4 additions & 1 deletion components/BottomBar.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Hand, MousePointer2, PanelTop } from "lucide-react";
import { Hand, MousePointer2, PanelTop, ScrollText } from "lucide-react";
import { Card } from "./ui/card";
import { ToggleGroupItem, ToggleGroup } from "./ui/toggle-group";
import { useEditor, useValue } from "tldraw";
Expand Down Expand Up @@ -29,6 +29,9 @@ export function BottomBar() {
<ToggleGroupItem value="browser" aria-label="browser">
<PanelTop className="h-4 w-4" />
</ToggleGroupItem>
<ToggleGroupItem value="prompt" aria-label="prompt">
<ScrollText className="h-4 w-4" />
</ToggleGroupItem>
</ToggleGroup>
</Card>
);
Expand Down
21 changes: 20 additions & 1 deletion components/BrowserShape.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
TLBaseShape,
TLShape,
TLShapeId,
TLTextShape,
Vec,
toDomPrecision,
useIsEditing,
Expand Down Expand Up @@ -245,6 +246,21 @@ export class BrowserShapeUtil extends BaseBoxShapeUtil<BrowserShape> {
[this.editor]
);

const promptsParam = useValue(
"prompts",
() => {
return JSON.stringify(
this.editor
.getCurrentPageShapes()
.filter((s): s is TLTextShape =>
Boolean(s.type === "text" && s.meta.prompt)
)
.map((t) => t.props.text)
);
},
[this.editor]
);

// The deps are in top to bottom order
const depsParams = useValue(
"deps",
Expand Down Expand Up @@ -346,6 +362,7 @@ export class BrowserShapeUtil extends BaseBoxShapeUtil<BrowserShape> {
/>
<input type="hidden" name="deps" value={depsParams} />
<input type="hidden" name="settings" value={settings} />
<input type="hidden" name="prompts" value={promptsParam} />
<Button
type="submit"
variant="ghost"
Expand Down Expand Up @@ -451,7 +468,9 @@ function getRotatedBoxShadow(rotation: number) {
}

function LoadingBar() {
return <div className="w-full h-2 bg-blue-600 animate-pulse" />;
return (
<div className="w-full h-1 bg-blue-600 animate-pulse absolute top-0 left-0" />
);
}

class RegisterOnce {
Expand Down
23 changes: 22 additions & 1 deletion components/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Button } from "./ui/button";
import { snapshot } from "@/lib/snapshot";
import { shouldUseAuth } from "@/lib/shouldUseAuth";
import { Settings } from "@/components/Settings";
import { PromptShapeTool } from "@/tools/PromptShapeTool";

const Tldraw = dynamic(async () => (await import("tldraw")).Tldraw, {
ssr: false,
Expand All @@ -25,7 +26,7 @@ export function Canvas() {
persistenceKey="tlweb"
shapeUtils={shapeUtils}
hideUi={false}
tools={[BrowserTool]}
tools={[BrowserTool, PromptShapeTool]}
components={{
Toolbar: null,
PageMenu: null,
Expand All @@ -48,6 +49,26 @@ function UI() {
}
}, [editor]);

// useEffect(() => {
// const unlisten = editor.store.listen(
// (update) => {
// for (const record of Object.values(update.changes.added)) {
// if (record.typeName === "shape" && record.type === "text") {
// editor.updateShape({
// id: record.id,
// type: record.type,
// meta: {
// prompt: true,
// },
// });
// }
// }
// },
// { scope: "document", source: "user" }
// );
// return unlisten;
// }, [editor]);

return (
<>
<div
Expand Down
20 changes: 20 additions & 0 deletions tools/PromptShapeTool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TLCompleteEventInfo, TLTextShape, TextShapeTool } from "tldraw";

export class PromptShapeTool extends TextShapeTool {
static override id = "prompt";
onExit = (info: TLCompleteEventInfo) => {
const shape = this.editor.getEditingShape();
console.log("onDragExit", shape);
if (!shape) return;
this.editor.updateShape<TLTextShape>({
id: shape.id,
type: "text",
meta: {
prompt: true,
},
props: {
color: "light-violet",
},
});
};
}

0 comments on commit 50e7fe0

Please sign in to comment.