This commit is contained in:
Orion Reed 2024-07-20 03:21:16 +02:00
parent 344bd352ad
commit 754e7afd5b
5 changed files with 136 additions and 65 deletions

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ggraph</title> <title>Palace</title>
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>

View File

@ -1,5 +1,5 @@
{ {
"name": "ggraph", "name": "palace",
"main": "src/server.ts", "main": "src/server.ts",
"serve": { "serve": {
"path": "dist" "path": "dist"

View File

@ -1,14 +1,13 @@
import "tldraw/tldraw.css"; import "tldraw/tldraw.css";
import { Tldraw } from "tldraw"; import { Tldraw, track, useEditor } from "tldraw";
import { useYjsStore } from "./useYjsStore"; import { useYjsStore } from "./useYjsStore";
import { AgentButton } from "./components/AgentButton";
import { SocialShapeUtil } from "./SocialShapeUtil"; import { SocialShapeUtil } from "./SocialShapeUtil";
import { SocialShapeTool } from "./SocialShapeTool"; import { SocialShapeTool } from "./SocialShapeTool";
import { CustomToolbar, overrides } from "./ui"; import { CustomToolbar, overrides } from "./ui";
// import { getDocumentMeta, getUserId, getUsersInRoom, setDocumentMeta } from "./storeUtils";
import { registerDefaultPropagators } from "./propagators/ScopedPropagators"; import { registerDefaultPropagators } from "./propagators/ScopedPropagators";
import { PromptShape } from "./PromptShape"; import { PromptShape } from "./PromptShape";
import { PromptShapeTool } from "./PromptTool"; import { PromptShapeTool } from "./PromptTool";
import { CustomMainMenu } from "./CustomMainMenu";
const shapeUtils = [SocialShapeUtil, PromptShape]; const shapeUtils = [SocialShapeUtil, PromptShape];
const tools = [SocialShapeTool, PromptShapeTool]; const tools = [SocialShapeTool, PromptShapeTool];
@ -41,74 +40,87 @@ export default function Canvas() {
registerDefaultPropagators(editor) registerDefaultPropagators(editor)
// const userId = getUserId(editor)
// setDocumentMeta(editor, {
// [userId]: 123
// })
// // console.log(getDocumentMeta(editor))
// // removeDocumentMeta(editor, 'test')
// setTimeout(() => {
// console.log(getDocumentMeta(editor))
// console.log(getUsersInRoom(editor))
// }, 2000);
}} }}
components={{ components={{
SharePanel: AgentButton, SharePanel: NameEditor,
Toolbar: CustomToolbar, Toolbar: CustomToolbar,
MainMenu: CustomMainMenu,
}} }}
/> />
</div> </div>
); );
} }
// const NameEditor = track(() => { const NameEditor = track(() => {
// const editor = useEditor(); const editor = useEditor();
const { color, name } = editor.user.getUserPreferences();
function randomName(): string {
const firstNames = ['Boba', 'Zap', 'Fizz', 'Glorp', 'Squish', 'Blip', 'Floof', 'Ziggy', 'Quark', 'Noodle', 'AI'];
const lastNames = ['Bubbles', 'Zoomers', 'Wiggles', 'Snazzle', 'Boop', 'Fizzle', 'Wobble', 'Giggle', 'Squeak', 'Noodle', 'Palace'];
return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${lastNames[Math.floor(Math.random() * lastNames.length)]}`
}
// const { color, name } = editor.user.getUserPreferences(); function randomHexColor(): string {
return `#${Math.floor(Math.random() * 16777215).toString(16)}`
}
// return ( const userPrefs = editor.user.getUserPreferences()
// <div
// style={{ if (userPrefs.name === "New User") {
// // TODO: style this properly and consistently with tldraw editor.user.updateUserPreferences({
// pointerEvents: "all", name: randomName(),
// display: "flex", color: randomHexColor()
// width: "148px", })
// margin: "4px 8px", }
// border: "none",
// }} return (
// > <div
// <input style={{
// style={{ // TODO: style this properly and consistently with tldraw
// borderRadius: "9px 0px 0px 9px", pointerEvents: "all",
// border: "none", display: "flex",
// backgroundColor: "white", width: "160px",
// boxShadow: "0px 0px 4px rgba(0, 0, 0, 0.25)", margin: "4px 8px",
// }} border: "none",
// type="color" }}
// value={color} >
// onChange={(e) => { <input
// editor.user.updateUserPreferences({ style={{
// color: e.currentTarget.value, borderRadius: "9px 0px 0px 9px",
// }); width: '30px',
// }} height: '30px',
// /> border: "none",
// <input backgroundColor: "white",
// style={{ boxShadow: "0px 0px 4px rgba(0, 0, 0, 0.25)",
// width: "100%", appearance: "none",
// borderRadius: "0px 9px 9px 0px", WebkitAppearance: "none",
// border: "none", cursor: "pointer",
// backgroundColor: "white", overflow: "hidden",
// boxShadow: "0px 0px 4px rgba(0, 0, 0, 0.25)", }}
// }} type="color"
// value={name} value={color}
// onChange={(e) => { onChange={(e) => {
// editor.user.updateUserPreferences({ editor.user.updateUserPreferences({
// name: e.currentTarget.value, color: e.currentTarget.value,
// }); });
// }} }}
// /> />
// </div> <input
// ); style={{
// }); width: "100%",
borderRadius: "0px 9px 9px 0px",
border: "none",
backgroundColor: "white",
boxShadow: "0px 0px 4px rgba(0, 0, 0, 0.25)",
}}
value={name}
onChange={(e) => {
editor.user.updateUserPreferences({
name: e.currentTarget.value,
});
}}
/>
</div>
);
});

57
src/CustomMainMenu.tsx Normal file
View File

@ -0,0 +1,57 @@
import {
DefaultMainMenu,
TldrawUiMenuItem,
Editor,
TLContent,
DefaultMainMenuContent,
useEditor,
useExportAs,
} from "tldraw";
export function CustomMainMenu() {
const editor = useEditor()
const exportAs = useExportAs()
const importJSON = (editor: Editor) => {
const input = document.createElement("input");
input.type = "file";
input.accept = ".json";
input.onchange = (event) => {
const file = (event.target as HTMLInputElement).files?.[0];
const reader = new FileReader();
reader.onload = (event) => {
if (typeof event.target?.result !== 'string') {
return
}
const jsonData = JSON.parse(event.target.result) as TLContent
editor.putContentOntoCurrentPage(jsonData, { select: true })
};
reader.readAsText(file as Blob);
};
input.click();
};
const exportJSON = (editor: Editor) => {
const exportName = `palace-${Math.round(+new Date() / 1000).toString().slice(5)}`
exportAs(Array.from(editor.getCurrentPageShapeIds()), 'json', exportName)
};
return (
<DefaultMainMenu>
<DefaultMainMenuContent />
<TldrawUiMenuItem
id="export"
label="Export JSON"
icon="external-link"
readonlyOk
onSelect={() => exportJSON(editor)}
/>
<TldrawUiMenuItem
id="import"
label="Import JSON"
icon="external-link"
readonlyOk
onSelect={() => importJSON(editor)}
/>
</DefaultMainMenu>
)
}

View File

@ -25,7 +25,7 @@ export const overrides: TLUiOverrides = {
prompt: { prompt: {
id: "prompt", id: "prompt",
name: "Prompt", name: "Prompt",
icon: "code", icon: "fill-solid",
kbd: "p", kbd: "p",
label: "Prompt", label: "Prompt",
onSelect: () => { onSelect: () => {
@ -39,9 +39,11 @@ export const overrides: TLUiOverrides = {
export const CustomToolbar = (props: DefaultToolbarProps) => { export const CustomToolbar = (props: DefaultToolbarProps) => {
const tools = useTools() const tools = useTools()
const isSocialSelected = useIsToolSelected(tools.social) const isSocialSelected = useIsToolSelected(tools.social)
const isPromptSelected = useIsToolSelected(tools.prompt)
return ( return (
<DefaultToolbar {...props}> <DefaultToolbar {...props}>
<TldrawUiMenuItem {...tools.social} isSelected={isSocialSelected} /> <TldrawUiMenuItem {...tools.social} isSelected={isSocialSelected} />
<TldrawUiMenuItem {...tools.prompt} isSelected={isPromptSelected} />
<DefaultToolbarContent /> <DefaultToolbarContent />
</DefaultToolbar> </DefaultToolbar>
) )