palace
This commit is contained in:
parent
344bd352ad
commit
754e7afd5b
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "ggraph",
|
"name": "palace",
|
||||||
"main": "src/server.ts",
|
"main": "src/server.ts",
|
||||||
"serve": {
|
"serve": {
|
||||||
"path": "dist"
|
"path": "dist"
|
||||||
|
|
|
||||||
136
src/App.tsx
136
src/App.tsx
|
|
@ -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>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue