Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dont merge] changes from demo #47

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
44 changes: 32 additions & 12 deletions app/PreviewShape/PreviewShape.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint-disable react-hooks/rules-of-hooks */
import { ReactElement, useEffect } from 'react'
import {
BaseBoxShapeUtil,
DefaultSpinner,
Expand All @@ -12,9 +13,9 @@ import {
useToasts,
useValue,
} from 'tldraw'
import { useEffect } from 'react'
import { Dropdown } from '../components/Dropdown'
import { LINK_HOST, PROTOCOL } from '../lib/hosts'
import { getSandboxPermissions } from '../lib/iframe'
import { uploadLink } from '../lib/uploadLink'

export type PreviewShape = TLBaseShape<
Expand Down Expand Up @@ -47,7 +48,6 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
override isAspectRatioLocked = (_shape: PreviewShape) => false
override canResize = (_shape: PreviewShape) => true
override canBind = (_shape: PreviewShape) => false
override canUnmount = () => false

override component(shape: PreviewShape) {
const isEditing = useIsEditing(shape.id)
Expand Down Expand Up @@ -124,6 +124,23 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
border: '1px solid var(--color-panel-contrast)',
borderRadius: 'var(--radius-2)',
}}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
sandbox={getSandboxPermissions({
'allow-downloads-without-user-activation': false,
'allow-downloads': true,
'allow-modals': true,
'allow-orientation-lock': false,
'allow-pointer-lock': true,
'allow-popups': true,
'allow-popups-to-escape-sandbox': true,
'allow-presentation': true,
'allow-storage-access-by-user-activation': true,
'allow-top-navigation': true,
'allow-top-navigation-by-user-activation': true,
'allow-scripts': true,
'allow-same-origin': true,
'allow-forms': true,
})}
/>
<div
style={{
Expand Down Expand Up @@ -179,25 +196,28 @@ export class PreviewShapeUtil extends BaseBoxShapeUtil<PreviewShape> {
)
}

override toSvg(shape: PreviewShape, _ctx: SvgExportContext): SVGElement | Promise<SVGElement> {
override toSvg(shape: PreviewShape, _ctx: SvgExportContext): Promise<ReactElement> {
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g')
// while screenshot is the same as the old one, keep waiting for a new one
return new Promise((resolve, _) => {
if (window === undefined) return resolve(g)
if (window === undefined) return resolve(<g></g>)
const windowListener = (event: MessageEvent) => {
if (event.data.screenshot && event.data?.shapeid === shape.id) {
const image = document.createElementNS('http://www.w3.org/2000/svg', 'image')
image.setAttributeNS('http://www.w3.org/1999/xlink', 'href', event.data.screenshot)
image.setAttribute('width', shape.props.w.toString())
image.setAttribute('height', shape.props.h.toString())
g.appendChild(image)
window.removeEventListener('message', windowListener)
clearTimeout(timeOut)
resolve(g)
resolve(
<g>
<image
href={event.data.screenshot}
width={shape.props.w}
height={shape.props.h}
></image>
</g>
)
}
}
const timeOut = setTimeout(() => {
resolve(g)
resolve(<g></g>)
window.removeEventListener('message', windowListener)
}, 2000)
window.addEventListener('message', windowListener)
Expand Down Expand Up @@ -238,7 +258,7 @@ const ROTATING_BOX_SHADOWS = [
},
]

function getRotatedBoxShadow(rotation: number) {
export function getRotatedBoxShadow(rotation: number) {
const cssStrings = ROTATING_BOX_SHADOWS.map((shadow) => {
const { offsetX, offsetY, blur, spread, color } = shadow
const vec = new Vec(offsetX, offsetY)
Expand Down
65 changes: 57 additions & 8 deletions app/components/ExportButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,66 @@
import { useMakeHappen } from '../hooks/useMakeHappen'
import { useMakeReal } from '../hooks/useMakeReal'
import { useMakeRealAnthropic } from '../hooks/useMakeRealAnthropic'

export function ExportButton() {
const makeReal = useMakeReal()
const makeRealAnthropicHaiku = useMakeRealAnthropic('claude-3-haiku-20240307')
const makeRealAntrhopicSonnet = useMakeRealAnthropic('claude-3-sonnet-20240229')
const makeRealAnthropicOpus = useMakeRealAnthropic('claude-3-opus-20240229')
const makeHappen = useMakeHappen()

return (
<button
onClick={makeReal}
className="p-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
<div
style={{
display: 'flex',
gap: '0px',
}}
>
<div className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Make Real
</div>
</button>
<button
onClick={makeHappen}
// className="p-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
>
<div className="bg-gray-900 hover:bg-gray-700 text-white font-bold py-2 px-4 rounded">
Make Happen
</div>
</button>
{/* <button
onClick={makeRealAnthropicHaiku}
className="pl-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
>
<div className="bg-yellow-400 hover:bg-yellow-500 text-black font-bold py-2 px-4 rounded">
Make Real
</div>
</button>
<button
onClick={makeRealAntrhopicSonnet}
className="pl-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
>
<div className="bg-amber-500 hover:bg-amber-600 text-black font-bold py-2 px-4 rounded">
Make Real
</div>
</button>
<button
onClick={makeRealAnthropicOpus}
className="pl-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
>
<div className="bg-orange-500 hover:bg-orange-700 text-white font-bold py-2 px-4 rounded">
Make Real
</div>
</button> */}
<button
onClick={makeReal}
className="p-2"
style={{ cursor: 'pointer', zIndex: 100000, pointerEvents: 'all' }}
>
<div className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Make Real
</div>
</button>
</div>
)
}
42 changes: 42 additions & 0 deletions app/hooks/useMakeHappen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { track } from '@vercel/analytics/react'
import { useCallback } from 'react'
import { useEditor, useToasts } from 'tldraw'
import { makeHappen } from '../lib/makeHappen'

export function useMakeHappen() {
const editor = useEditor()
const toast = useToasts()

return useCallback(async () => {
const input = document.getElementById('openai_key_risky_but_cool') as HTMLInputElement
const apiKey = input?.value ?? null

track('make_real', { timestamp: Date.now() })

try {
await makeHappen(editor, apiKey)
} catch (e: any) {
track('no_luck', { timestamp: Date.now() })

console.error(e)

toast.addToast({
title: 'Something went wrong',
description: `${e.message.slice(0, 200)}`,
actions: [
{
type: 'primary',
label: 'Read the guide',
onClick: () => {
// open a new tab with the url...
window.open(
'https://tldraw.notion.site/Make-Real-FAQs-93be8b5273d14f7386e14eb142575e6e',
'_blank'
)
},
},
],
})
}
}, [editor, toast])
}
42 changes: 42 additions & 0 deletions app/hooks/useMakeRealAnthropic.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { track } from '@vercel/analytics/react'
import { useCallback } from 'react'
import { useEditor, useToasts } from 'tldraw'
import { makeRealAnthropic } from '../lib/makeRealAnthropic'

export function useMakeRealAnthropic(model: string) {
const editor = useEditor()
const toast = useToasts()

return useCallback(async () => {
const input = document.getElementById('openai_key_risky_but_cool') as HTMLInputElement
const apiKey = input?.value ?? null

track('make_real', { timestamp: Date.now() })

try {
await makeRealAnthropic(editor, apiKey, model)
} catch (e: any) {
track('no_luck', { timestamp: Date.now() })

console.error(e)

toast.addToast({
title: 'Something went wrong',
description: `${e.message.slice(0, 200)}`,
actions: [
{
type: 'primary',
label: 'Read the guide',
onClick: () => {
// open a new tab with the url...
window.open(
'https://tldraw.notion.site/Make-Real-FAQs-93be8b5273d14f7386e14eb142575e6e',
'_blank'
)
},
},
],
})
}
}, [editor, toast, model])
}
Loading