[feature] Iframe warning (#800)

pull/802/head
Steve Ruiz 2022-07-08 21:25:08 +01:00 zatwierdzone przez GitHub
rodzic 1e80d1ac21
commit 2352985e94
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
31 zmienionych plików z 325 dodań i 205 usunięć

1
.gitignore vendored
Wyświetl plik

@ -18,3 +18,4 @@ apps/www/public/sw.js.map
.env
firebase.config.*.turbo
.turbo
apps/new-tab-extension/tsconfig.tsbuildinfo

Wyświetl plik

@ -1,12 +1,5 @@
# @tldraw/new-tab-extension
## 0.1.1
### Patch Changes
- Updated dependencies
- @tldraw/tldraw@1.19.1
## 0.1.0
### Minor Changes

Wyświetl plik

@ -1,7 +1,7 @@
{
"name": "@tldraw/new-tab-extension",
"private": true,
"version": "0.1.1",
"version": "0.1.0",
"description": "A tiny little new tab extension for tldraw.",
"author": "@steveruizok",
"repository": {

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1,11 +1,5 @@
# @tldraw/vscode-editor
## 1.11.1
### Patch Changes
- Fix toolbar placement.
## 1.11.0
### Minor Changes

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "@tldraw/vscode-editor",
"version": "1.11.1",
"version": "1.11.0",
"private": true,
"description": "An an editor for the tldraw vscode extension.",
"author": "@steveruizok",

Wyświetl plik

@ -1,13 +1,5 @@
# @tldraw/www
## 1.7.9
### Patch Changes
- Updated dependencies
- @tldraw/core@1.14.2
- @tldraw/tldraw@1.19.1
## 1.7.8
### Patch Changes

Wyświetl plik

@ -0,0 +1,127 @@
import React from 'react'
import { styled } from 'styles'
export function IFrameWarning({ url = 'https://tldraw.com' }: { url?: string }) {
const [copied, setCopied] = React.useState(false)
const rTimeout = React.useRef<any>(0)
const handleCopy = React.useCallback(() => {
setCopied(true)
clearTimeout(rTimeout.current)
rTimeout.current = setTimeout(() => {
setCopied(false)
}, 1200)
const textarea = document.createElement('textarea')
textarea.setAttribute('position', 'fixed')
textarea.setAttribute('top', '0')
textarea.setAttribute('readonly', 'true')
textarea.setAttribute('contenteditable', 'true')
textarea.style.position = 'fixed'
textarea.value = url
document.body.appendChild(textarea)
textarea.focus()
textarea.select()
//tldraw.com/r/hasdasdsad sad sadaasdasdasdsdasdadssdadadsd as ello
https: try {
const range = document.createRange()
range.selectNodeContents(textarea)
const sel = window.getSelection()
if (sel) {
sel.removeAllRanges()
sel.addRange(range)
textarea.setSelectionRange(0, textarea.value.length)
}
document.execCommand('copy')
} catch (err) {
console.log('nope')
null // Could not copy to clipboard
} finally {
document.body.removeChild(textarea)
}
}, [])
return (
<StyledContainer>
<StyledUrlLink href={url} target="_parent">
Visit this page on tldraw.com{' '}
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3 2C2.44772 2 2 2.44772 2 3V12C2 12.5523 2.44772 13 3 13H12C12.5523 13 13 12.5523 13 12V8.5C13 8.22386 12.7761 8 12.5 8C12.2239 8 12 8.22386 12 8.5V12H3V3L6.5 3C6.77614 3 7 2.77614 7 2.5C7 2.22386 6.77614 2 6.5 2H3ZM12.8536 2.14645C12.9015 2.19439 12.9377 2.24964 12.9621 2.30861C12.9861 2.36669 12.9996 2.4303 13 2.497L13 2.5V2.50049V5.5C13 5.77614 12.7761 6 12.5 6C12.2239 6 12 5.77614 12 5.5V3.70711L6.85355 8.85355C6.65829 9.04882 6.34171 9.04882 6.14645 8.85355C5.95118 8.65829 5.95118 8.34171 6.14645 8.14645L11.2929 3H9.5C9.22386 3 9 2.77614 9 2.5C9 2.22386 9.22386 2 9.5 2H12.4999H12.5C12.5678 2 12.6324 2.01349 12.6914 2.03794C12.7504 2.06234 12.8056 2.09851 12.8536 2.14645Z"
fill="currentColor"
stroke="black"
strokeWidth=".5"
></path>
</svg>
</StyledUrlLink>
<StyledUrlContainer onClick={handleCopy}>
<span>{url}</span>
<svg
width="18"
height="18"
viewBox="0 0 15 15"
fill="currentColor"
xmlns="http://www.w3.org/2000/svg"
>
{copied ? (
<path d="M11.4669 3.72684C11.7558 3.91574 11.8369 4.30308 11.648 4.59198L7.39799 11.092C7.29783 11.2452 7.13556 11.3467 6.95402 11.3699C6.77247 11.3931 6.58989 11.3355 6.45446 11.2124L3.70446 8.71241C3.44905 8.48022 3.43023 8.08494 3.66242 7.82953C3.89461 7.57412 4.28989 7.55529 4.5453 7.78749L6.75292 9.79441L10.6018 3.90792C10.7907 3.61902 11.178 3.53795 11.4669 3.72684Z" />
) : (
<path d="M5 2V1H10V2H5ZM4.75 0C4.33579 0 4 0.335786 4 0.75V1H3.5C2.67157 1 2 1.67157 2 2.5V12.5C2 13.3284 2.67157 14 3.5 14H7V13H3.5C3.22386 13 3 12.7761 3 12.5V2.5C3 2.22386 3.22386 2 3.5 2H4V2.25C4 2.66421 4.33579 3 4.75 3H10.25C10.6642 3 11 2.66421 11 2.25V2H11.5C11.7761 2 12 2.22386 12 2.5V7H13V2.5C13 1.67157 12.3284 1 11.5 1H11V0.75C11 0.335786 10.6642 0 10.25 0H4.75ZM9 8.5C9 8.77614 8.77614 9 8.5 9C8.22386 9 8 8.77614 8 8.5C8 8.22386 8.22386 8 8.5 8C8.77614 8 9 8.22386 9 8.5ZM10.5 9C10.7761 9 11 8.77614 11 8.5C11 8.22386 10.7761 8 10.5 8C10.2239 8 10 8.22386 10 8.5C10 8.77614 10.2239 9 10.5 9ZM13 8.5C13 8.77614 12.7761 9 12.5 9C12.2239 9 12 8.77614 12 8.5C12 8.22386 12.2239 8 12.5 8C12.7761 8 13 8.22386 13 8.5ZM14.5 9C14.7761 9 15 8.77614 15 8.5C15 8.22386 14.7761 8 14.5 8C14.2239 8 14 8.22386 14 8.5C14 8.77614 14.2239 9 14.5 9ZM15 10.5C15 10.7761 14.7761 11 14.5 11C14.2239 11 14 10.7761 14 10.5C14 10.2239 14.2239 10 14.5 10C14.7761 10 15 10.2239 15 10.5ZM14.5 13C14.7761 13 15 12.7761 15 12.5C15 12.2239 14.7761 12 14.5 12C14.2239 12 14 12.2239 14 12.5C14 12.7761 14.2239 13 14.5 13ZM14.5 15C14.7761 15 15 14.7761 15 14.5C15 14.2239 14.7761 14 14.5 14C14.2239 14 14 14.2239 14 14.5C14 14.7761 14.2239 15 14.5 15ZM8.5 11C8.77614 11 9 10.7761 9 10.5C9 10.2239 8.77614 10 8.5 10C8.22386 10 8 10.2239 8 10.5C8 10.7761 8.22386 11 8.5 11ZM9 12.5C9 12.7761 8.77614 13 8.5 13C8.22386 13 8 12.7761 8 12.5C8 12.2239 8.22386 12 8.5 12C8.77614 12 9 12.2239 9 12.5ZM8.5 15C8.77614 15 9 14.7761 9 14.5C9 14.2239 8.77614 14 8.5 14C8.22386 14 8 14.2239 8 14.5C8 14.7761 8.22386 15 8.5 15ZM11 14.5C11 14.7761 10.7761 15 10.5 15C10.2239 15 10 14.7761 10 14.5C10 14.2239 10.2239 14 10.5 14C10.7761 14 11 14.2239 11 14.5ZM12.5 15C12.7761 15 13 14.7761 13 14.5C13 14.2239 12.7761 14 12.5 14C12.2239 14 12 14.2239 12 14.5C12 14.7761 12.2239 15 12.5 15Z" />
)}
</svg>
</StyledUrlContainer>
</StyledContainer>
)
}
const StyledContainer = styled('div', {
position: 'absolute',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontFamily: '$body',
fontWeight: 'normal',
fontSize: '$3',
gap: '$5',
flexDirection: 'column',
})
const StyledUrlLink = styled('a', {
display: 'flex',
alignItems: 'center',
gap: '$2',
padding: '$5',
})
const StyledUrlContainer = styled('a', {
backgroundColor: '$hover',
borderRadius: '$2',
maxWidth: '62%',
minWidth: 320,
gap: '$4',
padding: '$4 $5',
fontSize: '$2',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
'& span': {
flexGrow: 2,
overflow: 'auto',
whiteSpace: 'nowrap',
'-ms-overflow-style': 'none' /* for Internet Explorer, Edge */,
scrollbarWidth: 'none',
'&::webkit-scrollbar': {
display: 'none',
},
},
})

Wyświetl plik

@ -1,6 +1,9 @@
import { RoomProvider } from '../utils/liveblocks'
import { Tldraw, useFileSystem } from '@tldraw/tldraw'
import { useAccountHandlers } from 'hooks/useAccountHandlers'
import { useMultiplayerAssets } from 'hooks/useMultiplayerAssets'
import { useMultiplayerState } from 'hooks/useMultiplayerState'
import { useUploadAssets } from 'hooks/useUploadAssets'
import React, { FC } from 'react'
import { styled } from 'styles'
import { useReadOnlyMultiplayerState } from 'hooks/useReadOnlyMultiplayerState'

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "@tldraw/www",
"version": "1.7.9",
"version": "1.7.8",
"private": true,
"description": "A tiny little drawing app (site).",
"repository": {

Wyświetl plik

@ -2,6 +2,7 @@ import * as React from 'react'
import type { GetServerSideProps } from 'next'
import { getSession } from 'next-auth/react'
import dynamic from 'next/dynamic'
import { IFrameWarning } from 'components/IFrameWarning'
const MultiplayerEditor = dynamic(() => import('components/MultiplayerEditor'), {
ssr: false,
}) as any
@ -13,6 +14,10 @@ interface RoomProps {
}
export default function Room({ id, isUser, isSponsor }: RoomProps) {
if (typeof window !== 'undefined') {
return <IFrameWarning url={`https://tldraw.com/r/${id}`} />
}
return <MultiplayerEditor isUser={isUser} isSponsor={isSponsor} roomId={id} />
}

Wyświetl plik

@ -3,6 +3,7 @@ import type { GetServerSideProps } from 'next'
import { getSession } from 'next-auth/react'
import dynamic from 'next/dynamic'
import { Utils } from '@tldraw/core'
import { IFrameWarning } from 'components/IFrameWarning'
const ReadOnlyMultiplayerEditor = dynamic(() => import('components/ReadOnlyMultiplayerEditor'), {
ssr: false,
}) as any
@ -14,6 +15,10 @@ interface RoomProps {
}
export default function Room({ id, isUser, isSponsor }: RoomProps) {
if (typeof window !== 'undefined') {
return <IFrameWarning url={`https://tldraw.com/v/${id}`} />
}
return <ReadOnlyMultiplayerEditor isUser={isUser} isSponsor={isSponsor} roomId={id} />
}

Wyświetl plik

@ -18,6 +18,7 @@ import UIOptions from './ui-options'
import { Multiplayer } from './multiplayer'
import './styles.css'
import Export from '~export'
import IFrame from '~iframe'
const pages: ({ path: string; component: any; title: string } | '---')[] = [
{ path: '/develop', component: Develop, title: 'Develop' },
@ -42,6 +43,7 @@ const pages: ({ path: string; component: any; title: string } | '---')[] = [
{ path: '/export', component: Export, title: 'Export' },
{ path: '/scroll', component: Scroll, title: 'In a scrolling container' },
{ path: '/multiplayer', component: Multiplayer, title: 'Multiplayer' },
{ path: '/iframe', component: IFrame, title: 'IFrame' },
]
export default function App() {

Wyświetl plik

@ -0,0 +1,9 @@
import * as React from 'react'
export default function IFrame() {
return (
<div className="tldraw">
<iframe src="http://localhost:3000/r/hello" style={{ width: '100%', height: '50%' }} />
</div>
)
}

Wyświetl plik

@ -17,7 +17,7 @@
],
"scripts": {
"build": "turbo run build",
"build:www": "turbo run build:www",
"build:www": "turbo run build:www --force",
"build:core": "turbo run build:core",
"build:packages": "turbo run build:packages --stream",
"build:apps": "turbo run build:apps",

Wyświetl plik

@ -1,11 +1,5 @@
# Changelog
## 1.14.2
### Patch Changes
- Fix toolbar placement.
## 1.14.1
### Patch Changes

Wyświetl plik

@ -1,5 +1,5 @@
{
"version": "1.14.2",
"version": "1.14.1",
"name": "@tldraw/core",
"description": "The tldraw core renderer and utilities.",
"author": "@steveruizok",

Wyświetl plik

@ -1491,15 +1491,14 @@ left past the initial left edge) then swap points on that axis.
* @param str string
*/
static lns(str: string) {
const result = str.split('')
const result = str
.split('')
.map((n) => (Number.isNaN(+n) ? n : +n < 5 ? 5 + +n : +n > 5 ? +n - 5 : +n))
result.push(...result.splice(0, Math.round(result.length / 5)))
result.push(...result.splice(0, Math.round(result.length / 4)))
result.push(...result.splice(0, Math.round(result.length / 3)))
result.push(...result.splice(0, Math.round(result.length / 2)))
return result
.reverse()
.map((n) => (+n ? (+n < 5 ? 5 + +n : +n > 5 ? +n - 5 : n) : n))
.join('')
return result.reverse().join('')
}
}

Wyświetl plik

@ -1,13 +1,5 @@
# Changelog
## 1.19.1
### Patch Changes
- Fix toolbar placement.
- Updated dependencies
- @tldraw/core@1.14.2
## 1.19.0
### Minor Changes

Wyświetl plik

@ -1,6 +1,6 @@
{
"name": "@tldraw/tldraw",
"version": "1.19.1",
"version": "1.19.0",
"description": "A tiny little drawing app (editor)",
"author": "@steveruizok",
"repository": {
@ -47,7 +47,7 @@
"@radix-ui/react-icons": "^1.1.1",
"@radix-ui/react-tooltip": "^0.1.7",
"@stitches/react": "^1.2.8",
"@tldraw/core": "^1.14.2",
"@tldraw/core": "^1.14.1",
"@tldraw/intersect": "^1.7.1",
"@tldraw/vec": "^1.7.1",
"idb-keyval": "^6.1.0",

Wyświetl plik

@ -618,7 +618,7 @@ const StyledUI = styled('div', {
left: 0,
height: '100%',
width: '100%',
padding: '0',
padding: '8px 8px 0 8px',
display: 'flex',
alignItems: 'flex-start',
justifyContent: 'flex-start',

Wyświetl plik

@ -119,7 +119,7 @@ export const StyledToolButton = styled('button', {
color: '$text',
fontSize: '$0',
background: 'none',
margin: 0,
margin: '0',
padding: '$2',
display: 'flex',
alignItems: 'center',
@ -158,9 +158,7 @@ export const StyledToolButton = styled('button', {
},
},
circle: {
padding: '0',
height: 32,
width: 32,
padding: '$2',
[`& ${StyledToolButtonInner}`]: {
border: '1px solid $panelContrast',
borderRadius: '100%',

Wyświetl plik

@ -1,13 +1,12 @@
import * as React from 'react'
import { styled } from '~styles'
import type { TDSnapshot } from '~types'
import { useTldrawApp } from '~hooks'
import { useMediaQuery, useTldrawApp } from '~hooks'
import { StatusBar } from './StatusBar'
import { BackToContent } from './BackToContent'
import { PrimaryTools } from './PrimaryTools'
import { ActionButton } from './ActionButton'
import { DeleteButton } from './DeleteButton'
import { breakpoints } from '~components/breakpoints'
const isDebugModeSelector = (s: TDSnapshot) => s.settings.isDebugMode
const dockPositionState = (s: TDSnapshot) => s.settings.dockPosition
@ -18,29 +17,74 @@ interface ToolsPanelProps {
export const ToolsPanel = React.memo(function ToolsPanel({ onBlur }: ToolsPanelProps) {
const app = useTldrawApp()
const side = app.useStore(dockPositionState)
const isDebugMode = app.useStore(isDebugModeSelector)
const dockPosition = app.useStore(dockPositionState)
const isMobile = useMediaQuery('(max-width: 900px)')
const bottomStyle = {
width: '100%',
height: 'min-content',
left: 0,
right: 0,
bottom: isDebugMode ? 40 : 0,
}
const topStyle = {
width: '100%',
height: 'min-content',
left: 0,
right: 0,
top: isMobile ? 60 : 10,
}
const rightStyle = { width: 'min-content', height: '100%', right: 0 }
const leftStyle = { width: 'min-content', height: '100%', left: 10 }
const toolStyle = () => {
switch (dockPosition) {
case 'bottom':
return bottomStyle
case 'left':
return leftStyle
case 'right':
return rightStyle
case 'top':
return topStyle
default:
return bottomStyle
}
}
const style = toolStyle()
const centerWrapStyle =
dockPosition === 'bottom' || dockPosition === 'top'
? { gridRow: 1, gridColumn: 2 }
: { gridRow: 2, gridColumn: 1 }
const primaryToolStyle = dockPosition === 'bottom' || dockPosition === 'top' ? 'row' : 'column'
return (
<>
<StyledToolsPanelContainer side={side} onBlur={onBlur} bp={breakpoints} debug={isDebugMode}>
<StyledCenterWrap id="TD-Tools">
<BackToContent />
<StyledPrimaryTools
orientation={side === 'bottom' || side === 'top' ? 'horizontal' : 'vertical'}
>
<ActionButton />
<PrimaryTools />
<DeleteButton />
</StyledPrimaryTools>
</StyledCenterWrap>
</StyledToolsPanelContainer>
<StyledToolsPanelContainer
style={{
...style,
}}
onBlur={onBlur}
>
<StyledCenterWrap
id="TD-Tools"
style={{
...centerWrapStyle,
}}
>
<BackToContent />
<StyledPrimaryTools style={{ flexDirection: primaryToolStyle }}>
<ActionButton />
<PrimaryTools />
<DeleteButton />
</StyledPrimaryTools>
</StyledCenterWrap>
{isDebugMode && (
<StyledStatusWrap>
<StatusBar />
</StyledStatusWrap>
)}
</>
</StyledToolsPanelContainer>
)
})
@ -49,68 +93,24 @@ const StyledToolsPanelContainer = styled('div', {
width: '100%',
minWidth: 0,
maxWidth: '100%',
height: '64px',
display: 'grid',
gridTemplateColumns: 'auto auto auto',
gridTemplateRows: 'auto auto',
justifyContent: 'space-between',
padding: '0',
gap: '$4',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: 200,
overflow: 'hidden',
pointerEvents: 'none',
'& > div > *': {
pointerEvents: 'all',
},
variants: {
debug: {
true: {},
false: {},
},
bp: {
mobile: {},
small: {},
medium: {},
large: {},
},
side: {
top: {
width: '100%',
height: 64,
left: 0,
right: 0,
top: 45,
},
right: { width: 64, height: '100%', top: 0, right: 0 },
bottom: {
width: '100%',
left: 0,
right: 0,
bottom: 0,
},
left: { width: 64, height: '100%', left: 0 },
},
},
compoundVariants: [
{
side: 'top',
bp: 'large',
css: {
top: '10px',
},
},
{
side: 'bottom',
debug: true,
css: {
bottom: 40,
},
},
],
})
const StyledCenterWrap = styled('div', {
gridRow: 1,
gridColumn: 2,
display: 'flex',
width: 'fit-content',
height: 'fit-content',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
@ -118,11 +118,10 @@ const StyledCenterWrap = styled('div', {
})
const StyledStatusWrap = styled('div', {
position: 'absolute',
position: 'fixed',
bottom: 0,
left: 0,
right: 0,
height: '40px',
width: '100%',
maxWidth: '100%',
})
@ -131,16 +130,5 @@ const StyledPrimaryTools = styled('div', {
position: 'relative',
display: 'flex',
alignItems: 'center',
height: 'fit-content',
gap: '$3',
variants: {
orientation: {
horizontal: {
flexDirection: 'row',
},
vertical: {
flexDirection: 'column',
},
},
},
gap: '$2',
})

Wyświetl plik

@ -119,7 +119,7 @@ export const MultiplayerMenu = React.memo(function MultiplayerMenu() {
<DMItem
id="TD-Multiplayer-CopyReadOnlyLink"
onClick={handleCopyReadOnlySelect}
disabled={!room}
disabled={false}
>
<FormattedMessage id="copy.readonly.link" />
<SmallIcon>{copied ? <CheckIcon /> : <ClipboardIcon />}</SmallIcon>

Wyświetl plik

@ -5,3 +5,4 @@ export * from './useStylesheet'
export * from './useFileSystemHandlers'
export * from './useFileSystem'
export * from './useTranslation'
export * from './useMediaQuery'

Wyświetl plik

@ -0,0 +1,19 @@
import * as React from 'react'
export function useMediaQuery(query: string) {
const [matches, setMatches] = React.useState(false)
React.useEffect(() => {
const media = window.matchMedia(query)
if (media.matches !== matches) {
setMatches(media.matches)
}
const listener = () => setMatches(media.matches)
window.addEventListener('resize', listener)
return () => window.removeEventListener('resize', listener)
}, [matches, query])
return matches
}
export default useMediaQuery

Wyświetl plik

@ -1015,6 +1015,7 @@ export class TLDR {
sel.addRange(range)
textarea.setSelectionRange(0, textarea.value.length)
}
document.execCommand('copy')
} catch (err) {
null // Could not copy to clipboard
} finally {

Wyświetl plik

@ -267,13 +267,13 @@ export class TldrawApp extends StateManager<TDSnapshot> {
constructor(id?: string, callbacks = {} as TDCallbacks) {
super(TldrawApp.defaultState, id, TldrawApp.version, (prev, next, prevVersion) => {
return migrate(
{
...next,
document: { ...next.document, ...prev.document, version: prevVersion },
},
TldrawApp.version
)
return {
...next,
document: migrate(
{ ...next.document, ...prev.document, version: prevVersion },
TldrawApp.version
),
}
})
this.callbacks = callbacks
@ -282,7 +282,10 @@ export class TldrawApp extends StateManager<TDSnapshot> {
/* -------------------- Internal -------------------- */
protected migrate = (state: TDSnapshot): TDSnapshot => {
return migrate(state, TldrawApp.version)
return {
...state,
document: migrate(state.document, TldrawApp.version),
}
}
protected onReady = () => {
@ -294,10 +297,10 @@ export class TldrawApp extends StateManager<TDSnapshot> {
try {
this.patchState({
...migrate(this.state, TldrawApp.version),
appState: {
status: TDStatus.Idle,
},
document: migrate(this.document, TldrawApp.version),
})
} catch (e) {
console.error('The data appears to be corrupted. Resetting!', e)
@ -1229,7 +1232,10 @@ export class TldrawApp extends StateManager<TDSnapshot> {
// Set the default page name to the localized version of "Page"
doc.pages['page'].name = 'Page 1'
this.resetHistory().clearSelectHistory().loadDocument(TldrawApp.defaultDocument).persist({})
this.resetHistory()
.clearSelectHistory()
.loadDocument(migrate(doc, TldrawApp.version))
.persist({})
return this
}
@ -1267,17 +1273,12 @@ export class TldrawApp extends StateManager<TDSnapshot> {
// If it's a new document, do a full change.
if (this.document.id !== document.id) {
this.replaceState({
...migrate(
{
...this.state,
document,
},
TldrawApp.version
),
...this.state,
appState: {
...this.appState,
currentPageId: Object.keys(document.pages)[0],
},
document: migrate(document, TldrawApp.version),
})
return this
}
@ -1339,11 +1340,12 @@ export class TldrawApp extends StateManager<TDSnapshot> {
return this.replaceState(
{
...migrate(
{ ...this.state, document: { ...document, pageStates: currentPageStates } },
TldrawApp.version
),
...this.state,
appState: nextAppState,
document: {
...migrate(document, TldrawApp.version),
pageStates: currentPageStates,
},
},
'merge'
)
@ -1356,7 +1358,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
updateDocument = (document: TDDocument, reason = 'updated_document'): this => {
const prevState = this.state
let nextState = { ...prevState, document: { ...prevState.document } }
const nextState = { ...prevState, document: { ...prevState.document } }
if (!document.pages[this.currentPageId]) {
nextState.appState = {
@ -1397,10 +1399,9 @@ export class TldrawApp extends StateManager<TDSnapshot> {
}
}
return this.replaceState(
migrate(nextState, nextState.document.version || 0),
`${reason}:${document.id}`
)
nextState.document = migrate(nextState.document, nextState.document.version || 0)
return this.replaceState(nextState, `${reason}:${document.id}`)
}
/**
@ -1436,21 +1437,22 @@ export class TldrawApp extends StateManager<TDSnapshot> {
this.clearSelectHistory()
this.session = undefined
const state = {
...TldrawApp.defaultState,
settings: {
...this.state.settings,
this.replaceState(
{
...TldrawApp.defaultState,
settings: {
...this.state.settings,
},
document: migrate(document, TldrawApp.version),
appState: {
...TldrawApp.defaultState.appState,
...this.state.appState,
currentPageId: Object.keys(document.pages)[0],
disableAssets: this.disableAssets,
},
},
document,
appState: {
...TldrawApp.defaultState.appState,
...this.state.appState,
currentPageId: Object.keys(document.pages)[0],
disableAssets: this.disableAssets,
},
}
this.replaceState(migrate(state, TldrawApp.version), 'loaded_document')
'loaded_document'
)
const { point, zoom } = this.camera
this.updateViewport(point, zoom)
return this
@ -1474,7 +1476,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
if (this.readOnly) return
try {
const fileHandle = await saveToFileSystem(
migrate(this.state, TldrawApp.version).document,
migrate(this.document, TldrawApp.version),
this.fileSystemHandle
)
this.fileSystemHandle = fileHandle
@ -4119,7 +4121,7 @@ export class TldrawApp extends StateManager<TDSnapshot> {
getShapeUtil = TLDR.getShapeUtil
static version = 15.4
static version = 15.3
static defaultDocument: TDDocument = {
id: 'doc',

Wyświetl plik

@ -50,7 +50,7 @@ TldrawTestApp {
"shapes": Object {},
},
},
"version": 15.4,
"version": 15.3,
},
"settings": Object {
"dockPosition": "bottom",
@ -201,7 +201,7 @@ TldrawTestApp {
},
},
},
"version": 15.4,
"version": 15.3,
},
"settings": Object {
"dockPosition": "bottom",
@ -373,7 +373,7 @@ TldrawTestApp {
"shapes": Object {},
},
},
"version": 15.4,
"version": 15.3,
},
"settings": Object {
"dockPosition": "bottom",

Wyświetl plik

@ -1,8 +1,7 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import { Decoration, FontStyle, TDDocument, TDShapeType, TDSnapshot, TextShape } from '~types'
import { Decoration, FontStyle, TDDocument, TDShapeType, TextShape } from '~types'
export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
const { document, settings } = state
export function migrate(document: TDDocument, newVersion: number): TDDocument {
const { version = 0 } = document
if (!('assets' in document)) {
@ -12,8 +11,8 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
// Remove unused assets when loading a document
const assetIdsInUse = new Set<string>()
Object.values(document.pages).forEach((page) =>
Object.values(page.shapes).forEach((shape) => {
Object.values(document.pages).forEach(page =>
Object.values(page.shapes).forEach(shape => {
const { parentId, children, assetId } = shape
if (assetId) {
@ -27,7 +26,7 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
}
if (shape.type === TDShapeType.Group && children) {
children.forEach((childId) => {
children.forEach(childId => {
if (!page.shapes[childId]) {
console.warn('Encountered a parent with a missing child!', shape.id, childId)
children?.splice(children.indexOf(childId), 1)
@ -39,31 +38,31 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
})
)
Object.keys(document.assets).forEach((assetId) => {
Object.keys(document.assets).forEach(assetId => {
if (!assetIdsInUse.has(assetId)) {
delete document.assets[assetId]
}
})
if (version === newVersion) return state
if (version === newVersion) return document
if (version < 14) {
Object.values(document.pages).forEach((page) => {
Object.values(document.pages).forEach(page => {
Object.values(page.shapes)
.filter((shape) => shape.type === TDShapeType.Text)
.forEach((shape) => (shape as TextShape).style.font === FontStyle.Script)
.filter(shape => shape.type === TDShapeType.Text)
.forEach(shape => (shape as TextShape).style.font === FontStyle.Script)
})
}
// Lowercase styles, move binding meta to binding
if (version <= 13) {
Object.values(document.pages).forEach((page) => {
Object.values(page.bindings).forEach((binding) => {
Object.values(document.pages).forEach(page => {
Object.values(page.bindings).forEach(binding => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Object.assign(binding, (binding as any).meta)
})
Object.values(page.shapes).forEach((shape) => {
Object.values(page.shapes).forEach(shape => {
Object.entries(shape.style).forEach(([id, style]) => {
if (typeof style === 'string') {
// @ts-ignore
@ -96,8 +95,8 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
document.assets = {}
}
Object.values(document.pages).forEach((page) => {
Object.values(page.shapes).forEach((shape) => {
Object.values(document.pages).forEach(page => {
Object.values(page.shapes).forEach(shape => {
if (version < 15.2) {
if (shape.type === TDShapeType.Image || shape.type === TDShapeType.Video) {
shape.style.isFilled = true
@ -118,13 +117,9 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
})
})
if (version < 15.4) {
settings.dockPosition = 'bottom'
}
// Cleanup
Object.values(document.pageStates).forEach((pageState) => {
pageState.selectedIds = pageState.selectedIds.filter((id) => {
Object.values(document.pageStates).forEach(pageState => {
pageState.selectedIds = pageState.selectedIds.filter(id => {
return document.pages[pageState.id].shapes[id] !== undefined
})
pageState.bindingId = undefined
@ -135,5 +130,5 @@ export function migrate(state: TDSnapshot, newVersion: number): TDSnapshot {
document.version = newVersion
return state
return document
}

Wyświetl plik

@ -54,7 +54,7 @@
"duplicate": "Duplicate",
"cancel": "Cancel",
"copy.invite.link": "Copy Invite Link",
"copy.readonly.link": "Copy Read-only Link",
"copy.readonly.link": "Copy ReadOnly Link",
"create.multiplayer.project": "Create a Multiplayer Project",
"copy.multiplayer.project": "Copy to Multiplayer Project",
"select": "Select",