Adds provisional logger

This commit is contained in:
Steve Ruiz 2021-07-04 19:45:07 +01:00
parent 48c659a68a
commit 8180146eb3
14 changed files with 3583 additions and 204 deletions

View file

@ -120,16 +120,16 @@ Array [
"id": "bend",
"index": 2,
"point": Array [
0,
0,
50,
50,
],
},
"end": Object {
"id": "end",
"index": 1,
"point": Array [
0,
0,
100,
100,
],
},
"start": Object {

View file

@ -7,9 +7,14 @@ import { CodeError, CodeFile, CodeResult } from 'types'
import CodeDocs from './code-docs'
import { generateFromCode } from 'state/code/generate'
import * as Panel from '../panel'
import { IconButton } from '../shared'
import { Code, PlayCircle, ChevronUp, ChevronDown } from 'react-feather'
import { Cross2Icon } from '@radix-ui/react-icons'
import { breakpoints, IconButton } from '../shared'
import {
Cross2Icon,
CodeIcon,
PlayIcon,
ChevronUpIcon,
ChevronDownIcon,
} from '@radix-ui/react-icons'
import dynamic from 'next/dynamic'
import { ReaderIcon } from '@radix-ui/react-icons'
const CodeEditor = dynamic(() => import('./code-editor'))
@ -17,6 +22,7 @@ const CodeEditor = dynamic(() => import('./code-editor'))
const increaseCodeSize = () => state.send('INCREASED_CODE_FONT_SIZE')
const decreaseCodeSize = () => state.send('DECREASED_CODE_FONT_SIZE')
const toggleCodePanel = () => state.send('TOGGLED_CODE_PANEL_OPEN')
const handleWheel = (e: React.WheelEvent) => e.stopPropagation()
export default function CodePanel(): JSX.Element {
const rContainer = useRef<HTMLDivElement>(null)
@ -132,56 +138,48 @@ export default function CodePanel(): JSX.Element {
return (
<Panel.Root
dir="ltr"
bp={{ '@initial': 'mobile', '@sm': 'small' }}
bp={breakpoints}
data-bp-desktop
ref={rContainer}
isOpen={isOpen}
variant="code"
onWheel={(e) => e.stopPropagation()}
onWheel={handleWheel}
>
{isOpen ? (
<Panel.Layout>
<Panel.Header side="left">
<IconButton
bp={{ '@initial': 'mobile', '@sm': 'small' }}
size="small"
onClick={toggleCodePanel}
>
<IconButton bp={breakpoints} size="small" onClick={toggleCodePanel}>
<Cross2Icon />
</IconButton>
<h3>Code</h3>
<ButtonsGroup>
<FontSizeButtons>
<IconButton
bp={{ '@initial': 'mobile', '@sm': 'small' }}
bp={breakpoints}
size="small"
disabled={!local.isIn('editingCode')}
onClick={increaseCodeSize}
>
<ChevronUp />
<ChevronUpIcon />
</IconButton>
<IconButton
size="small"
disabled={!local.isIn('editingCode')}
onClick={decreaseCodeSize}
>
<ChevronDown />
<ChevronDownIcon />
</IconButton>
</FontSizeButtons>
<IconButton
bp={{ '@initial': 'mobile', '@sm': 'small' }}
size="small"
onClick={toggleDocs}
>
<IconButton bp={breakpoints} size="small" onClick={toggleDocs}>
<ReaderIcon />
</IconButton>
<IconButton
bp={{ '@initial': 'mobile', '@sm': 'small' }}
bp={breakpoints}
size="small"
disabled={!local.isIn('editingCode')}
onClick={handleSave}
>
<PlayCircle />
<PlayIcon />
</IconButton>
</ButtonsGroup>
</Panel.Header>
@ -201,12 +199,8 @@ export default function CodePanel(): JSX.Element {
{error && <Panel.Footer>{error.message}</Panel.Footer>}
</Panel.Layout>
) : (
<IconButton
bp={{ '@initial': 'mobile', '@sm': 'small' }}
size="small"
onClick={toggleCodePanel}
>
<Code />
<IconButton bp={breakpoints} size="small" onClick={toggleCodePanel}>
<CodeIcon />
</IconButton>
)}
</Panel.Root>

View file

@ -0,0 +1,200 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
import styled from 'styles'
import React, { useRef } from 'react'
import state, { useSelector } from 'state'
import * as Panel from '../panel'
import { breakpoints, IconButton, RowButton, IconWrapper } from '../shared'
import {
Cross2Icon,
PlayIcon,
CrumpledPaperIcon,
StopIcon,
ClipboardCopyIcon,
} from '@radix-ui/react-icons'
import logger from 'state/logger'
import { useStateDesigner } from '@state-designer/react'
const stopPropagation = (e: React.KeyboardEvent) => e.stopPropagation()
const toggleDebugPanel = () => state.send('TOGGLED_DEBUG_PANEL')
export default function CodePanel(): JSX.Element {
const rContainer = useRef<HTMLDivElement>(null)
const isDebugging = useSelector((s) => s.data.settings.isDebugMode)
const isOpen = useSelector((s) => s.data.settings.isDebugOpen)
const rTextArea = useRef<HTMLTextAreaElement>(null)
const local = useStateDesigner({
initial: 'stopped',
data: {
log: '',
},
states: {
stopped: {
on: {
CHANGED_LOG: 'setLog',
COPIED_LOG: { if: 'hasLog', do: 'copyLog' },
PLAYED_BACK_LOG: { if: 'hasLog', do: 'playbackLog' },
STARTED_LOGGING: { do: 'startLogger', to: 'logging' },
},
},
logging: {
on: {
STOPPED_LOGGING: { do: 'stopLogger', to: 'stopped' },
},
},
},
conditions: {
hasLog(data) {
return data.log !== ''
},
},
actions: {
setLog(data, payload: { value: string }) {
data.log = payload.value
},
startLogger(data) {
logger.start(state.data)
data.log = ''
},
stopLogger(data) {
logger.stop(state.data)
data.log = logger.copyToJson()
},
playbackLog(data) {
logger.playback(state.data, data.log)
},
copyLog() {
logger.copyToJson()
},
},
})
if (!isDebugging) return null
const handleLoggingStop = () => local.send('STOPPED_LOGGING')
const handlePlayback = () =>
local.send('PLAYED_BACK_LOG', { log: rTextArea.current?.value })
const handleLoggingStart = () => local.send('STARTED_LOGGING')
const handleLoggingCopy = () => local.send('COPIED_DEBUG_LOG')
return (
<StylePanelRoot
dir="ltr"
bp={breakpoints}
data-bp-desktop
ref={rContainer}
variant="code"
onWheel={(e) => e.stopPropagation()}
>
{isOpen ? (
<Panel.Layout onKeyDown={stopPropagation}>
<Panel.Header side="left">
<IconButton
bp={breakpoints}
size="small"
onClick={toggleDebugPanel}
>
<Cross2Icon />
</IconButton>
<span>Debugging</span>
<div />
</Panel.Header>
<Panel.Content>
<hr />
{local.isIn('stopped') ? (
<RowButton bp={breakpoints} onClick={handleLoggingStart}>
<span>Start Logger</span>
<IconWrapper size="small">
<PlayIcon />
</IconWrapper>
</RowButton>
) : (
<RowButton bp={breakpoints} onClick={handleLoggingStop}>
<span>Stop Logger</span>
<IconWrapper size="small">
<StopIcon />
</IconWrapper>
</RowButton>
)}
{
<RowButton
bp={breakpoints}
onClick={handleLoggingCopy}
disabled={!local.can('COPIED_LOG')}
>
<span>Copy Log</span>
<IconWrapper size="small">
<ClipboardCopyIcon />
</IconWrapper>
</RowButton>
}
<JSONTextAreaWrapper>
<JSONTextArea
ref={rTextArea}
value={local.data.log}
onChange={(e) =>
local.send('CHANGED_LOG', { value: e.currentTarget.value })
}
/>
</JSONTextAreaWrapper>
<RowButton
bp={breakpoints}
onClick={handlePlayback}
disabled={!local.can('PLAYED_BACK_LOG')}
>
<span>Play Back Log</span>
</RowButton>
</Panel.Content>
</Panel.Layout>
) : (
<IconButton bp={breakpoints} size="small" onClick={toggleDebugPanel}>
<CrumpledPaperIcon />
</IconButton>
)}
</StylePanelRoot>
)
}
const StylePanelRoot = styled(Panel.Root, {
marginRight: '8px',
width: 'fit-content',
maxWidth: 'fit-content',
overflow: 'hidden',
position: 'relative',
border: '1px solid $panel',
boxShadow: '0px 2px 4px rgba(0,0,0,.2)',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
pointerEvents: 'all',
padding: 2,
'& hr': {
marginTop: 2,
marginBottom: 2,
marginLeft: '-2px',
border: 'none',
height: 1,
backgroundColor: '$brushFill',
width: 'calc(100% + 4px)',
},
})
const JSONTextAreaWrapper = styled('div', {
padding: '4px',
})
const JSONTextArea = styled('textarea', {
minHeight: '100px',
width: '100%',
font: '$mono',
backgroundColor: '$panel',
border: '1px solid $border',
borderRadius: '4px',
padding: '4px',
outline: 'none',
})

View file

@ -7,6 +7,7 @@ import StylePanel from './style-panel/style-panel'
import styled from 'styles'
import PagePanel from './page-panel/page-panel'
import CodePanel from './code-panel/code-panel'
import DebugPanel from './debug-panel/debug-panel'
import ControlsPanel from './controls-panel/controls-panel'
export default function Editor({ roomId }: { roomId?: string }): JSX.Element {
@ -15,6 +16,7 @@ export default function Editor({ roomId }: { roomId?: string }): JSX.Element {
return (
<Layout>
<DebugPanel />
<CodePanel />
<PagePanel />
<ControlsPanel />

View file

@ -7,6 +7,7 @@ import {
IconWrapper,
ButtonsRow,
RowButton,
breakpoints,
} from 'components/shared'
import ShapesFunctions from './shapes-functions'
import AlignDistribute from './align-distribute'
@ -24,9 +25,12 @@ import {
Cross2Icon,
} from '@radix-ui/react-icons'
const breakpoints = { '@initial': 'mobile', '@sm': 'small' } as any
const handleStylePanelOpen = () => state.send('TOGGLED_STYLE_PANEL_OPEN')
const handleCopy = () => state.send('COPIED')
const handlePaste = () => state.send('PASTED')
const handleCopyToSvg = () => state.send('COPIED_TO_SVG')
const handleSave = () => state.send('SAVED')
const handleLoad = () => state.send('LOADED_FROM_FILE_STSTEM')
export default function StylePanel(): JSX.Element {
const rContainer = useRef<HTMLDivElement>(null)
@ -72,14 +76,14 @@ function SelectedShapeContent(): JSX.Element {
<RowButton
bp={breakpoints}
disabled={selectedShapesCount === 0}
onClick={() => state.send('COPIED')}
onClick={handleCopy}
>
<span>Copy</span>
<IconWrapper size="small">
<ClipboardCopyIcon />
</IconWrapper>
</RowButton>
<RowButton bp={breakpoints} onClick={() => state.send('PASTED')}>
<RowButton bp={breakpoints} onClick={handlePaste}>
<span>Paste</span>
<IconWrapper size="small">
<ClipboardIcon />
@ -88,7 +92,7 @@ function SelectedShapeContent(): JSX.Element {
<RowButton
bp={breakpoints}
disabled={selectedShapesCount === 0}
onClick={() => state.send('COPIED_TO_SVG')}
onClick={handleCopyToSvg}
>
<span>Copy to SVG</span>
<IconWrapper size="small">
@ -96,13 +100,10 @@ function SelectedShapeContent(): JSX.Element {
</IconWrapper>
</RowButton>
<hr />
<RowButton bp={breakpoints} onClick={() => state.send('SAVED')}>
<RowButton bp={breakpoints} onClick={handleSave}>
<span>Save</span>
</RowButton>
<RowButton
bp={breakpoints}
onClick={() => state.send('LOADED_FROM_FILE_STSTEM')}
>
<RowButton bp={breakpoints} onClick={handleLoad}>
<span>Load</span>
</RowButton>
</>

View file

@ -195,7 +195,11 @@ export default function useKeyboardEvents() {
}
case 'd': {
if (metaKey(e)) {
if (e.shiftKey) {
state.send('TOGGLED_DEBUG_MODE')
} else {
state.send('DUPLICATED', info)
}
} else {
state.send('SELECTED_DRAW_TOOL', info)
}
@ -228,6 +232,8 @@ export default function useKeyboardEvents() {
case 'l': {
if (metaKey(e)) {
if (e.shiftKey) {
state.send('TOGGLED_LOGGER')
} else {
state.send('LOADED_FROM_FILE_STSTEM', info)
}
} else {

View file

@ -5,8 +5,8 @@ import coopState from 'state/coop/coop-state'
export default function useLoadOnMount(roomId: string = undefined) {
useEffect(() => {
if ('fonts' in document) {
const fonts = (document as any).fonts
fonts.load('12px Verveine Regular', 'Fonts are loaded!').then(() => {
state.send('MOUNTED')
@ -15,6 +15,9 @@ export default function useLoadOnMount(roomId: string = undefined) {
coopState.send('JOINED_ROOM', { id: roomId })
}
})
} else {
setTimeout(() => state.send('MOUNTED'), 1000)
}
return () => {
state.send('UNMOUNTED').send('RT_UNLOADED_ROOM', { id: roomId })

View file

@ -47,7 +47,7 @@
"@sentry/react": "^6.7.2",
"@sentry/tracing": "^6.7.2",
"@sentry/webpack-plugin": "^1.15.1",
"@state-designer/react": "^1.7.32",
"@state-designer/react": "^1.7.4",
"@stitches/react": "^0.2.2",
"@types/uuid": "^8.3.0",
"browser-fs-access": "^0.17.3",

View file

@ -15,10 +15,36 @@ import * as Session from './sessions'
* directly to the state using `forceData`.
* @param info
*/
export function fastTranslate(info: PointerInfo): void {
const data = { ...state.data }
session.update<Session.TranslateSession>(
data,
tld.screenToWorld(info.point, data),
info.shiftKey,
info.altKey
)
state.forceData(freeze(data))
}
export function fastTransform(info: PointerInfo): void {
const data = { ...state.data }
session.update<Session.TransformSession | Session.TransformSingleSession>(
data,
tld.screenToWorld(info.point, data),
info.shiftKey
)
state.forceData(freeze(data))
}
export function fastDrawUpdate(info: PointerInfo): void {
const data = { ...state.data }
coopState.send('MOVED_CURSOSR', {
coopState.send('MOVED_CURSOR', {
pageId: data.currentPageId,
point: info.point,
})
@ -102,28 +128,3 @@ export function fastBrushSelect(point: number[]): void {
state.forceData(freeze(data))
}
export function fastTranslate(info: PointerInfo): void {
const data = { ...state.data }
session.update<Session.TranslateSession>(
data,
tld.screenToWorld(info.point, data),
info.shiftKey,
info.altKey
)
state.forceData(freeze(data))
}
export function fastTransform(info: PointerInfo): void {
const data = { ...state.data }
session.update<Session.TransformSession | Session.TransformSingleSession>(
data,
tld.screenToWorld(info.point, data),
info.shiftKey
)
state.forceData(freeze(data))
}

View file

@ -84,8 +84,8 @@ class Inputs {
this.points[e.pointerId] = info
this.activePointerId = e.pointerId
this.pointer = info
return info
}
@ -169,12 +169,17 @@ class Inputs {
return { point: getPoint(e), shiftKey, ctrlKey, metaKey, altKey }
}
canAccept = (pointerId: PointerEvent['pointerId']) => {
return (
this.activePointerId === undefined || this.activePointerId === pointerId
)
canAccept = (pointerId: PointerEvent['pointerId']): boolean => {
pointerId
return true
}
// canAccept = (pointerId: PointerEvent['pointerId']) => {
// return (
// this.activePointerId === undefined || this.activePointerId === pointerId
// )
// }
isDoubleClick() {
if (!this.pointer) return
@ -225,6 +230,17 @@ class Inputs {
altKey,
}
}
reset() {
this.activePointerId = undefined
this.pointerUpTime = 0
this.pointer = undefined
this.points = {}
this.keyboard = undefined
this.keys = {}
}
}
export default new Inputs()

272
state/logger.ts Normal file
View file

@ -0,0 +1,272 @@
import { Data } from 'types'
import clipboard from './clipboard'
import state from './state'
import { isDraft, current } from 'immer'
import { setToArray } from 'utils'
import tld from 'utils/tld'
import inputs from './inputs'
interface LogEntry {
eventName: string
payload: any
time: number
didCauseUpdate: boolean
}
class Logger {
filters = new Set([
// 'MOVED_OVER_SHAPE',
// 'RESIZED_WINDOW',
// 'HOVERED_SHAPE',
// 'UNHOVERED_SHAPE',
// 'PANNED_CAMERA',
'STARTED_LOGGING',
'STOPPED_LOGGING',
])
snapshotStart: Data
snapshotEnd: Data
log: LogEntry[] = []
isSimulating = false
isRunning = false
speed = 0
startTime = 0
/**
* Start the logger.
*
* ### Example
*
*```ts
* logger.start()
*```
*/
start = (data: Data): Logger => {
if (this.isRunning) return
this.isRunning = true
this.snapshotStart = isDraft(data) ? current(data) : data
this.log = []
this.startTime = Date.now()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.snapshotStart.pageStates[data.currentPageId].selectedIds = setToArray(
tld.getSelectedIds(data)
)
return this
}
/**
* Stop the logger.
*
* ### Example
*
*```ts
* logger.stop()
*```
*/
stop = (data: Data): Logger => {
if (!this.isRunning) return
this.isRunning = false
this.snapshotEnd = isDraft(data) ? current(data) : data
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
this.snapshotEnd.pageStates[data.currentPageId].selectedIds = setToArray(
tld.getSelectedIds(data)
)
// if (window.confirm('Stopped logging. Copy to clipboard?')) {
// this.copyToJson()
// }
return this
}
/**
* Add an event and payload to the log.
*
* ### Example
*
*```ts
* logger.addToLog(eventName, payload)
*```
*/
addToLog(event: string, payload: any, didCauseUpdate = false) {
if (!this.isRunning) return
if (this.filters.has(event)) return
didCauseUpdate
// if (!didCauseUpdate) return
this.log.push({
eventName: event,
payload: payload,
time: Date.now() - this.startTime,
didCauseUpdate: true,
})
}
/**
* Play back a log entry.
*
* ### Example
*
*```ts
* logger.playback(log)
*```
*/
playback = (data: Data, log: string): Logger => {
const parsed: { start: Data; end: Data; events: LogEntry[] } =
JSON.parse(log)
const { start, events } = parsed
this.isSimulating = true
try {
data.pageStates[data.currentPageId].selectedIds = new Set(
start.pageStates[start.currentPageId].selectedIds
)
state.send('RESET_DOCUMENT_STATE').forceData(start)
const pointerDowns = [
'POINTED_CANVAS',
'POINTED_SHAPE',
'POINTED_BOUNDS',
'DOUBLE_POINTED_SHAPE',
'POINTED_HANDLE',
'RIGHT_POINTED',
]
const pointerChanges = [
...pointerDowns,
'MOVED_POINTER',
'MOVED_OVER_SHAPE',
'STOPPED_POINTING',
'DOUBLE_POINTED_CANVAS',
]
const pointerUps = ['STOPPED_POINTING']
for (const event of events) {
if (pointerDowns.includes(event.eventName)) {
inputs.pointer.origin = event.payload.point
}
if (pointerChanges.includes(event.eventName)) {
inputs.activePointerId = event.payload.pointerId
inputs.pointer = { ...inputs.pointer, ...event.payload }
inputs.points[event.payload.pointerId] = inputs.pointer
}
if (pointerUps.includes(event.eventName)) {
delete inputs.points[event.payload.pointerId]
delete inputs.activePointerId
// TODO: Double pointing
}
state.send(event.eventName, event.payload)
}
setTimeout(
() => (this.isSimulating = false),
events[events.length - 1].time + 1
)
} catch (e) {
console.warn('Could not play back that state.')
}
return this
}
/**
* Export the log as JSON.
*
* ### Example
*
*```ts
* logger.toJson()
*```
*/
copyToJson = () => {
const logAsString = JSON.stringify({
start: this.snapshotStart,
end: this.snapshotEnd,
events: this.log,
})
clipboard.copyStringToClipboard(logAsString)
return logAsString
}
/**
* Add a new event filter. Filtered events will not be logged.
*
* ### Example
*
*```ts
* logger.addFilter("SOME_EVENT")
*```
*/
addFilter(eventName: string) {
this.filters.add(eventName)
}
/**
* Remove an event from the filters. Filtered events will not be logged.
*
* ### Example
*
*```ts
* logger.removeFilter("SOME_EVENT")
*```
*/
removeFilter(eventName: string) {
this.filters.delete(eventName)
}
/**
* Replace all of the filtered events.
*
* ### Example
*
*```ts
* logger.setFilters(["SOME_EVENT", "SOME_OTHER_EVENT"])
*```
*/
setFilters(eventNames: string[]) {
this.filters = new Set(eventNames)
}
/**
* Clear the current set of event filters.
*
* ### Example
*
*```ts
* logger.clear()
*```
*/
clearFilters() {
this.filters.clear()
}
}
export default new Logger()

View file

@ -37,6 +37,7 @@ import {
ColorStyle,
} from 'types'
import { getFontSize } from './shape-styles'
import logger from './logger'
const initialData: Data = {
isReadOnly: false,
@ -44,6 +45,8 @@ const initialData: Data = {
fontSize: 13,
isDarkMode: false,
isCodeOpen: false,
isDebugMode: false,
isDebugOpen: false,
isStyleOpen: false,
isToolLocked: false,
isPenLocked: false,
@ -141,12 +144,22 @@ for (let i = 0; i < count; i++) {
const state = createState({
data: initialData,
on: {
TOGGLED_DEBUG_PANEL: 'toggleDebugPanel',
TOGGLED_DEBUG_MODE: 'toggleDebugMode',
TOGGLED_LOGGER: 'toggleLogger',
COPIED_DEBUG_LOG: 'copyDebugLog',
LOADED_FROM_SNAPSHOT: {
unless: 'isInSession',
do: ['loadDocumentFromJson', 'resetHistory'],
},
},
initial: 'loading',
states: {
loading: {
on: {
MOUNTED: {
do: 'restoredPreviousDocument',
do: ['resetHistory', 'restoredPreviousDocument'],
to: 'ready',
},
},
@ -160,13 +173,18 @@ const state = createState({
},
on: {
UNMOUNTED: {
do: ['saveAppState', 'saveDocumentState', 'resetDocumentState'],
do: [
'saveAppState',
'saveDocumentState',
'resetDocumentState',
'resetHistory',
],
to: 'loading',
},
// Network-Related
RT_LOADED_ROOM: [
'clearRoom',
{ if: 'hasRoom', do: 'resetDocumentState' },
{ if: 'hasRoom', do: ['resetDocumentState', 'resetHistory'] },
],
// RT_UNLOADED_ROOM: ['clearRoom', 'resetDocumentState'],
// RT_DISCONNECTED_ROOM: ['clearRoom', 'resetDocumentState'],
@ -176,7 +194,11 @@ const state = createState({
// RT_EDITED_SHAPE: 'editRtShape',
// Client
RESIZED_WINDOW: 'resetPageState',
RESET_DOCUMENT_STATE: 'resetDocumentState',
RESET_DOCUMENT_STATE: [
'resetHistory',
'resetDocumentState',
{ to: 'selecting' },
],
TOGGLED_READ_ONLY: 'toggleReadOnly',
LOADED_FONTS: 'resetShapes',
USED_PEN_DEVICE: 'enablePenLock',
@ -729,6 +751,9 @@ const state = createState({
do: 'createShape',
to: 'draw.editing',
},
STOPPED_POINTING: {
to: 'draw.creating',
},
},
},
editing: {
@ -745,8 +770,11 @@ const state = createState({
},
PRESSED_SHIFT: 'keyUpdateDrawSession',
RELEASED_SHIFT: 'keyUpdateDrawSession',
// MOVED_POINTER: 'updateDrawSession',
PANNED_CAMERA: 'updateDrawSession',
MOVED_POINTER: {
if: 'isSimulating',
do: 'updateDrawSession',
},
},
},
},
@ -1041,7 +1069,7 @@ const state = createState({
to: 'selecting',
},
},
initial: 'drawingShapeBounds',
initial: 'bounds',
states: {
bounds: {
onEnter: 'startDrawTransformSession',
@ -1096,6 +1124,9 @@ const state = createState({
},
},
conditions: {
isSimulating() {
return logger.isSimulating
},
hasRoom(_, payload: { id?: string }) {
return payload.id !== undefined
},
@ -1203,6 +1234,30 @@ const state = createState({
},
},
actions: {
/* ---------------------- Debug --------------------- */
closeDebugPanel(data) {
data.settings.isDebugOpen = false
},
openDebugPanel(data) {
data.settings.isDebugOpen = true
},
toggleDebugMode(data) {
data.settings.isDebugMode = !data.settings.isDebugMode
},
toggleDebugPanel(data) {
data.settings.isDebugOpen = !data.settings.isDebugOpen
},
toggleLogger(data) {
if (logger.isRunning) {
logger.stop(data)
} else {
logger.start(data)
}
},
copyDebugLog() {
logger.copyToJson()
},
// Networked Room
addRtShape(data, payload: { pageId: string; shape: Shape }) {
const { pageId, shape } = payload
@ -1227,6 +1282,8 @@ const state = createState({
session.cancel(data)
inputs.reset()
const newId = 'page1'
data.currentPageId = newId
@ -1315,6 +1372,7 @@ const state = createState({
tld.setSelectedIds(data, [shape.id])
},
/* -------------------- Sessions -------------------- */
// Shared
@ -2091,6 +2149,11 @@ const state = createState({
return commonStyle
},
},
options: {
onSend(eventName, payload, didCauseUpdate) {
logger.addToLog(eventName, payload, didCauseUpdate)
},
},
})
export default state

View file

@ -8,6 +8,8 @@ export interface Data {
fontSize: number
isDarkMode: boolean
isCodeOpen: boolean
isDebugOpen: boolean
isDebugMode: boolean
isStyleOpen: boolean
nudgeDistanceSmall: number
nudgeDistanceLarge: number

3051
yarn.lock

File diff suppressed because it is too large Load diff