Restore fixes

This commit is contained in:
Steve Ruiz 2022-07-10 22:05:43 +01:00
parent a4d980c290
commit b0755d8def
11 changed files with 83 additions and 102 deletions

View file

@ -1,9 +1,6 @@
import { RoomProvider } from '../utils/liveblocks' import { RoomProvider } from '../utils/liveblocks'
import { Tldraw, useFileSystem } from '@tldraw/tldraw' import { Tldraw, useFileSystem } from '@tldraw/tldraw'
import { useAccountHandlers } from 'hooks/useAccountHandlers' 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 React, { FC } from 'react'
import { styled } from 'styles' import { styled } from 'styles'
import { useReadOnlyMultiplayerState } from 'hooks/useReadOnlyMultiplayerState' import { useReadOnlyMultiplayerState } from 'hooks/useReadOnlyMultiplayerState'

View file

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

View file

@ -158,7 +158,9 @@ export const StyledToolButton = styled('button', {
}, },
}, },
circle: { circle: {
padding: '$2', padding: 0,
height: 32,
width: 32,
[`& ${StyledToolButtonInner}`]: { [`& ${StyledToolButtonInner}`]: {
border: '1px solid $panelContrast', border: '1px solid $panelContrast',
borderRadius: '100%', borderRadius: '100%',

View file

@ -101,7 +101,7 @@ const StyledToolsPanelContainer = styled('div', {
side: 'bottom', side: 'bottom',
debug: true, debug: true,
css: { css: {
bottom: 40, bottom: '40px',
}, },
}, },
], ],
@ -119,9 +119,9 @@ const StyledCenterWrap = styled('div', {
const StyledStatusWrap = styled('div', { const StyledStatusWrap = styled('div', {
position: 'absolute', position: 'absolute',
bottom: 0, bottom: '0px',
left: 0, left: '0px',
right: 0, right: '0px',
height: '40px', height: '40px',
width: '100%', width: '100%',
maxWidth: '100%', maxWidth: '100%',

View file

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

View file

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

View file

@ -1,19 +0,0 @@
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

View file

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

View file

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

View file

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

View file

@ -93,5 +93,6 @@
"bottom": "Bottom", "bottom": "Bottom",
"left": "Left", "left": "Left",
"right": "Right", "right": "Right",
"top": "Top" "top": "Top",
"page": "Page"
} }