Fixes save and load states, fix group bg
This commit is contained in:
parent
ee48a7afb8
commit
ad0ce1ba3a
8 changed files with 154 additions and 98 deletions
|
@ -10,10 +10,10 @@ export default function useLoadOnMount(roomId?: string) {
|
||||||
fonts.load('12px Verveine Regular', 'Fonts are loaded!').then(() => {
|
fonts.load('12px Verveine Regular', 'Fonts are loaded!').then(() => {
|
||||||
state.send('MOUNTED', { roomId })
|
state.send('MOUNTED', { roomId })
|
||||||
|
|
||||||
if (roomId !== undefined) {
|
// if (roomId !== undefined) {
|
||||||
state.send('RT_LOADED_ROOM', { id: roomId })
|
// state.send('RT_LOADED_ROOM', { id: roomId })
|
||||||
coopState.send('JOINED_ROOM', { id: roomId })
|
// coopState.send('JOINED_ROOM', { id: roomId })
|
||||||
}
|
// }
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => state.send('MOUNTED'), 1000)
|
setTimeout(() => state.send('MOUNTED'), 1000)
|
||||||
|
|
|
@ -3,8 +3,11 @@ import Head from 'next/head'
|
||||||
import { AppProps } from 'next/app'
|
import { AppProps } from 'next/app'
|
||||||
import { globalStyles } from 'styles'
|
import { globalStyles } from 'styles'
|
||||||
import { Provider } from 'next-auth/client'
|
import { Provider } from 'next-auth/client'
|
||||||
|
import { init } from 'utils/sentry'
|
||||||
import 'styles/globals.css'
|
import 'styles/globals.css'
|
||||||
|
|
||||||
|
init()
|
||||||
|
|
||||||
function MyApp({ Component, pageProps }: AppProps): JSX.Element {
|
function MyApp({ Component, pageProps }: AppProps): JSX.Element {
|
||||||
globalStyles()
|
globalStyles()
|
||||||
|
|
||||||
|
|
|
@ -17,15 +17,14 @@ export default function createPage(data: Data, goToPage = true): void {
|
||||||
data.document.pages[page.id] = page
|
data.document.pages[page.id] = page
|
||||||
data.pageStates[page.id] = pageState
|
data.pageStates[page.id] = pageState
|
||||||
|
|
||||||
data.currentPageId = page.id
|
|
||||||
storage.savePage(data, data.document.id, page.id)
|
|
||||||
storage.saveDocumentToLocalStorage(data)
|
|
||||||
|
|
||||||
if (goToPage) {
|
if (goToPage) {
|
||||||
data.currentPageId = page.id
|
data.currentPageId = page.id
|
||||||
} else {
|
} else {
|
||||||
data.currentPageId = currentPageId
|
data.currentPageId = currentPageId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
storage.savePage(data, data.document.id, page.id)
|
||||||
|
storage.saveDocumentToLocalStorage(data)
|
||||||
},
|
},
|
||||||
undo(data) {
|
undo(data) {
|
||||||
const { page, currentPageId } = snapshot
|
const { page, currentPageId } = snapshot
|
||||||
|
|
|
@ -70,6 +70,8 @@ class CoopClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnect(): CoopClient {
|
disconnect(): CoopClient {
|
||||||
|
if (!this.room) return
|
||||||
|
|
||||||
this.room.unsubscribe('connection', this.handleConnectionEvent)
|
this.room.unsubscribe('connection', this.handleConnectionEvent)
|
||||||
this.room.unsubscribe('my-presence', this.handleMyPresenceEvent)
|
this.room.unsubscribe('my-presence', this.handleMyPresenceEvent)
|
||||||
this.room.unsubscribe('others', this.handleOthersEvent)
|
this.room.unsubscribe('others', this.handleOthersEvent)
|
||||||
|
@ -79,6 +81,8 @@ class CoopClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
reconnect(): CoopClient {
|
reconnect(): CoopClient {
|
||||||
|
if (!this.room) return
|
||||||
|
|
||||||
this.connect(this.roomId)
|
this.connect(this.roomId)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
@ -128,6 +132,8 @@ class CoopClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCursor(): CoopClient {
|
clearCursor(): CoopClient {
|
||||||
|
if (!this.room) return
|
||||||
|
|
||||||
this.room.updatePresence({ cursor: null })
|
this.room.updatePresence({ cursor: null })
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ const group = registerShapeUtils<GroupShape>({
|
||||||
width={size[0]}
|
width={size[0]}
|
||||||
height={size[1]}
|
height={size[1]}
|
||||||
data-shy={true}
|
data-shy={true}
|
||||||
|
fill="none"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
@ -169,6 +170,7 @@ const group = registerShapeUtils<GroupShape>({
|
||||||
const StyledGroupShape = styled('rect', {
|
const StyledGroupShape = styled('rect', {
|
||||||
zDash: 5,
|
zDash: 5,
|
||||||
zStrokeWidth: 1,
|
zStrokeWidth: 1,
|
||||||
|
stroke: '$text',
|
||||||
})
|
})
|
||||||
|
|
||||||
export default group
|
export default group
|
||||||
|
|
|
@ -160,7 +160,8 @@ const state = createState({
|
||||||
on: {
|
on: {
|
||||||
MOUNTED: [
|
MOUNTED: [
|
||||||
'resetHistory',
|
'resetHistory',
|
||||||
{ unless: 'hasRoomId', do: 'restoredPreviousDocument' },
|
'resetStorage',
|
||||||
|
'restoredPreviousDocument',
|
||||||
{ to: 'ready' },
|
{ to: 'ready' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -174,26 +175,9 @@ const state = createState({
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
UNMOUNTED: {
|
UNMOUNTED: {
|
||||||
do: [
|
do: ['saveDocumentState', 'resetDocumentState'],
|
||||||
'saveAppState',
|
|
||||||
'saveDocumentState',
|
|
||||||
'resetDocumentState',
|
|
||||||
'resetHistory',
|
|
||||||
],
|
|
||||||
to: 'loading',
|
to: 'loading',
|
||||||
},
|
},
|
||||||
// Network-Related
|
|
||||||
RT_LOADED_ROOM: [
|
|
||||||
'clearRoom',
|
|
||||||
{ if: 'hasRoom', do: ['resetDocumentState', 'resetHistory'] },
|
|
||||||
],
|
|
||||||
// RT_UNLOADED_ROOM: ['clearRoom', 'resetDocumentState'],
|
|
||||||
// RT_DISCONNECTED_ROOM: ['clearRoom', 'resetDocumentState'],
|
|
||||||
// RT_CREATED_SHAPE: 'addRtShape',
|
|
||||||
// RT_CHANGED_STATUS: 'setRtStatus',
|
|
||||||
// RT_DELETED_SHAPE: 'deleteRtShape',
|
|
||||||
// RT_EDITED_SHAPE: 'editRtShape',
|
|
||||||
// Client
|
|
||||||
RESIZED_WINDOW: 'resetPageState',
|
RESIZED_WINDOW: 'resetPageState',
|
||||||
RESET_DOCUMENT_STATE: [
|
RESET_DOCUMENT_STATE: [
|
||||||
'resetHistory',
|
'resetHistory',
|
||||||
|
@ -306,7 +290,7 @@ const state = createState({
|
||||||
},
|
},
|
||||||
SAVED: {
|
SAVED: {
|
||||||
unlessAny: ['isInSession', 'isReadOnly'],
|
unlessAny: ['isInSession', 'isReadOnly'],
|
||||||
do: 'forceSave',
|
do: ['saveDocumentState', 'saveToFileSystem'],
|
||||||
},
|
},
|
||||||
LOADED_FROM_FILE: {
|
LOADED_FROM_FILE: {
|
||||||
unless: 'isInSession',
|
unless: 'isInSession',
|
||||||
|
@ -346,8 +330,10 @@ const state = createState({
|
||||||
RESET_CAMERA: 'resetCamera',
|
RESET_CAMERA: 'resetCamera',
|
||||||
COPIED_TO_SVG: 'copyToSvg',
|
COPIED_TO_SVG: 'copyToSvg',
|
||||||
LOADED_FROM_FILE_STSTEM: 'loadFromFileSystem',
|
LOADED_FROM_FILE_STSTEM: 'loadFromFileSystem',
|
||||||
SAVED_AS_TO_FILESYSTEM: 'saveAsToFileSystem',
|
SAVED_AS_TO_FILESYSTEM: ['saveDocumentState', 'saveAsToFileSystem'],
|
||||||
SAVED_TO_FILESYSTEM: {
|
SAVED_TO_FILESYSTEM: [
|
||||||
|
'saveDocumentState',
|
||||||
|
{
|
||||||
unless: 'isReadOnly',
|
unless: 'isReadOnly',
|
||||||
then: {
|
then: {
|
||||||
if: 'isReadOnly',
|
if: 'isReadOnly',
|
||||||
|
@ -355,6 +341,7 @@ const state = createState({
|
||||||
else: 'saveToFileSystem',
|
else: 'saveToFileSystem',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
initial: 'selecting',
|
initial: 'selecting',
|
||||||
states: {
|
states: {
|
||||||
|
@ -1281,30 +1268,38 @@ const state = createState({
|
||||||
clearRoom(data) {
|
clearRoom(data) {
|
||||||
data.room = undefined
|
data.room = undefined
|
||||||
},
|
},
|
||||||
resetDocumentState(data) {
|
resetStorage() {
|
||||||
data.document.id = uniqueId()
|
storage.reset()
|
||||||
|
},
|
||||||
|
resetDocumentState(data, payload: { roomId?: string }) {
|
||||||
|
// Save the current document and app state.
|
||||||
|
storage.savePage(data)
|
||||||
|
storage.savePageState(data)
|
||||||
|
storage.saveAppStateToLocalStorage(data)
|
||||||
|
storage.saveDocumentToLocalStorage(data)
|
||||||
|
|
||||||
|
// Cancel all current sessions, reset history, etc..
|
||||||
session.cancel(data)
|
session.cancel(data)
|
||||||
|
|
||||||
inputs.reset()
|
inputs.reset()
|
||||||
|
|
||||||
history.reset()
|
history.reset()
|
||||||
|
storage.reset()
|
||||||
|
|
||||||
const newId = 'page1'
|
// Populate a new app state.
|
||||||
|
const newDocumentId = payload?.roomId ? payload.roomId : uniqueId()
|
||||||
data.currentPageId = newId
|
const newPageId = 'page1'
|
||||||
|
|
||||||
|
data.document.id = newDocumentId
|
||||||
data.pointedId = null
|
data.pointedId = null
|
||||||
data.hoveredId = null
|
data.hoveredId = null
|
||||||
data.editingId = null
|
data.editingId = null
|
||||||
data.currentPageId = 'page1'
|
data.currentPageId = newPageId
|
||||||
data.currentParentId = 'page1'
|
data.currentParentId = newPageId
|
||||||
data.currentCodeFileId = 'file0'
|
data.currentCodeFileId = 'file0'
|
||||||
data.codeControls = {}
|
data.codeControls = {}
|
||||||
|
|
||||||
data.document.pages = {
|
data.document.pages = {
|
||||||
[newId]: {
|
[newPageId]: {
|
||||||
id: newId,
|
id: newPageId,
|
||||||
name: 'Page 1',
|
name: 'Page 1',
|
||||||
type: 'page',
|
type: 'page',
|
||||||
shapes: {},
|
shapes: {},
|
||||||
|
@ -1313,8 +1308,8 @@ const state = createState({
|
||||||
}
|
}
|
||||||
|
|
||||||
data.pageStates = {
|
data.pageStates = {
|
||||||
[newId]: {
|
[newPageId]: {
|
||||||
id: newId,
|
id: newPageId,
|
||||||
selectedIds: new Set(),
|
selectedIds: new Set(),
|
||||||
camera: {
|
camera: {
|
||||||
point: [0, 0],
|
point: [0, 0],
|
||||||
|
@ -1322,6 +1317,12 @@ const state = createState({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the new app state.
|
||||||
|
storage.savePage(data)
|
||||||
|
storage.savePageState(data)
|
||||||
|
storage.saveAppStateToLocalStorage(data)
|
||||||
|
storage.saveDocumentToLocalStorage(data)
|
||||||
},
|
},
|
||||||
resetPageState(data) {
|
resetPageState(data) {
|
||||||
const pageState = data.pageStates[data.currentPageId]
|
const pageState = data.pageStates[data.currentPageId]
|
||||||
|
@ -1344,6 +1345,7 @@ const state = createState({
|
||||||
/* --------------------- Shapes --------------------- */
|
/* --------------------- Shapes --------------------- */
|
||||||
resetShapes(data) {
|
resetShapes(data) {
|
||||||
const page = tld.getPage(data)
|
const page = tld.getPage(data)
|
||||||
|
|
||||||
Object.values(page.shapes).forEach((shape) => {
|
Object.values(page.shapes).forEach((shape) => {
|
||||||
page.shapes[shape.id] = { ...shape }
|
page.shapes[shape.id] = { ...shape }
|
||||||
})
|
})
|
||||||
|
@ -2052,8 +2054,8 @@ const state = createState({
|
||||||
|
|
||||||
/* ---------------------- Data ---------------------- */
|
/* ---------------------- Data ---------------------- */
|
||||||
|
|
||||||
restoredPreviousDocument(data) {
|
restoredPreviousDocument(data, payload: { roomId?: string }) {
|
||||||
storage.firstLoad(data)
|
storage.firstLoad(data, payload?.roomId)
|
||||||
},
|
},
|
||||||
|
|
||||||
saveToFileSystem(data) {
|
saveToFileSystem(data) {
|
||||||
|
@ -2077,6 +2079,9 @@ const state = createState({
|
||||||
},
|
},
|
||||||
|
|
||||||
saveDocumentState(data) {
|
saveDocumentState(data) {
|
||||||
|
storage.savePage(data)
|
||||||
|
storage.savePageState(data)
|
||||||
|
storage.saveAppStateToLocalStorage(data)
|
||||||
storage.saveDocumentToLocalStorage(data)
|
storage.saveDocumentToLocalStorage(data)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -2084,14 +2089,6 @@ const state = createState({
|
||||||
storage.saveToFileSystem(data)
|
storage.saveToFileSystem(data)
|
||||||
},
|
},
|
||||||
|
|
||||||
savePage(data) {
|
|
||||||
storage.savePage(data)
|
|
||||||
},
|
|
||||||
|
|
||||||
loadPage(data) {
|
|
||||||
storage.loadPage(data)
|
|
||||||
},
|
|
||||||
|
|
||||||
saveCode(data, payload: { code: string }) {
|
saveCode(data, payload: { code: string }) {
|
||||||
data.document.code[data.currentCodeFileId].code = payload.code
|
data.document.code[data.currentCodeFileId].code = payload.code
|
||||||
storage.saveDocumentToLocalStorage(data)
|
storage.saveDocumentToLocalStorage(data)
|
||||||
|
|
|
@ -13,14 +13,9 @@ function storageId(fileId: string, label: string, id?: string) {
|
||||||
class Storage {
|
class Storage {
|
||||||
previousSaveHandle?: any // FileSystemHandle
|
previousSaveHandle?: any // FileSystemHandle
|
||||||
|
|
||||||
constructor() {
|
firstLoad(data: Data, roomId?: string) {
|
||||||
// this.loadPreviousHandle() // Still needs debugging
|
const lastOpenedFileId =
|
||||||
}
|
roomId || localStorage.getItem(`${CURRENT_VERSION}_lastOpened`)
|
||||||
|
|
||||||
firstLoad(data: Data) {
|
|
||||||
const lastOpenedFileId = localStorage.getItem(
|
|
||||||
`${CURRENT_VERSION}_lastOpened`
|
|
||||||
)
|
|
||||||
|
|
||||||
// 1. Load Document from Local Storage
|
// 1. Load Document from Local Storage
|
||||||
// Using the "last opened file id" in local storage.
|
// Using the "last opened file id" in local storage.
|
||||||
|
@ -30,9 +25,9 @@ class Storage {
|
||||||
storageId(lastOpenedFileId, 'document-state', lastOpenedFileId)
|
storageId(lastOpenedFileId, 'document-state', lastOpenedFileId)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (savedState === null) {
|
if (!savedState) {
|
||||||
// If no state with that document was found, create a fresh random id.
|
// If no state with that document was found, create a fresh random id.
|
||||||
data.document.id = uniqueId()
|
data.document.id = roomId ? roomId : uniqueId()
|
||||||
} else {
|
} else {
|
||||||
// If we did find a state and document, load it into state.
|
// If we did find a state and document, load it into state.
|
||||||
const restoredDocument: Data = JSON.parse(decompress(savedState))
|
const restoredDocument: Data = JSON.parse(decompress(savedState))
|
||||||
|
@ -42,11 +37,7 @@ class Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
this.load(data)
|
this.load(data)
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveAppStateToLocalStorage = (data: Data) => {
|
saveAppStateToLocalStorage = (data: Data) => {
|
||||||
|
@ -63,6 +54,8 @@ class Storage {
|
||||||
storageId(data.document.id, 'document', data.document.id),
|
storageId(data.document.id, 'document', data.document.id),
|
||||||
compress(JSON.stringify(document))
|
compress(JSON.stringify(document))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
localStorage.setItem(`${CURRENT_VERSION}_lastOpened`, data.document.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
getCompleteDocument = (data: Data) => {
|
getCompleteDocument = (data: Data) => {
|
||||||
|
@ -138,7 +131,9 @@ class Storage {
|
||||||
if (savedPageState !== null) {
|
if (savedPageState !== null) {
|
||||||
// If we've found a page state in local storage, set it into state.
|
// If we've found a page state in local storage, set it into state.
|
||||||
data.pageStates[pageId] = JSON.parse(decompress(savedPageState))
|
data.pageStates[pageId] = JSON.parse(decompress(savedPageState))
|
||||||
data.pageStates[pageId].selectedIds = new Set([])
|
data.pageStates[pageId].selectedIds = new Set(
|
||||||
|
data.pageStates[pageId].selectedIds
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
// Or else create a new one.
|
// Or else create a new one.
|
||||||
data.pageStates[pageId] = {
|
data.pageStates[pageId] = {
|
||||||
|
@ -154,15 +149,31 @@ class Storage {
|
||||||
|
|
||||||
// 3. Restore the last page state
|
// 3. Restore the last page state
|
||||||
// Using the "last page state" in local storage.
|
// Using the "last page state" in local storage.
|
||||||
|
|
||||||
|
try {
|
||||||
const savedPageState = localStorage.getItem(
|
const savedPageState = localStorage.getItem(
|
||||||
storageId(data.document.id, 'lastPageState', data.document.id)
|
storageId(data.document.id, 'lastPageState', data.document.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (savedPageState !== null) {
|
|
||||||
const pageState = JSON.parse(decompress(savedPageState))
|
const pageState = JSON.parse(decompress(savedPageState))
|
||||||
|
|
||||||
|
if (!data.document.pages[pageState.id]) {
|
||||||
|
throw new Error('Page state id not in document')
|
||||||
|
}
|
||||||
|
|
||||||
pageState.selectedIds = new Set([])
|
pageState.selectedIds = new Set([])
|
||||||
data.pageStates[pageState.id] = pageState
|
data.pageStates[pageState.id] = pageState
|
||||||
data.currentPageId = pageState.id
|
data.currentPageId = pageState.id
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Could not restore page state:', e.message)
|
||||||
|
|
||||||
|
data.pageStates[data.currentPageId] = {
|
||||||
|
id: data.currentPageId,
|
||||||
|
selectedIds: new Set([]),
|
||||||
|
camera: {
|
||||||
|
point: [0, 0],
|
||||||
|
zoom: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Save the current app state / document
|
// 4. Save the current app state / document
|
||||||
|
@ -203,6 +214,9 @@ class Storage {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Load the current page
|
||||||
|
this.loadPage(data, data.document.id, data.currentPageId)
|
||||||
|
|
||||||
// Update camera for the new page state
|
// Update camera for the new page state
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(
|
||||||
'--camera-zoom',
|
'--camera-zoom',
|
||||||
|
@ -247,13 +261,13 @@ class Storage {
|
||||||
|
|
||||||
data.currentPageId = pageId
|
data.currentPageId = pageId
|
||||||
|
|
||||||
// Get saved page from local storage
|
try {
|
||||||
|
// If we have a page in local storage, move it into state
|
||||||
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
|
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
|
||||||
|
|
||||||
if (savedPage !== null) {
|
|
||||||
// If we have a page, move it into state
|
|
||||||
data.document.pages[pageId] = JSON.parse(decompress(savedPage))
|
data.document.pages[pageId] = JSON.parse(decompress(savedPage))
|
||||||
} else {
|
} catch (e) {
|
||||||
|
console.warn('Could not load a page with the id', pageId)
|
||||||
|
|
||||||
// If we don't have a page, create a new page
|
// If we don't have a page, create a new page
|
||||||
data.document.pages[pageId] = {
|
data.document.pages[pageId] = {
|
||||||
id: pageId,
|
id: pageId,
|
||||||
|
@ -309,23 +323,20 @@ class Storage {
|
||||||
|
|
||||||
/* ------------------- File System ------------------ */
|
/* ------------------- File System ------------------ */
|
||||||
|
|
||||||
|
reset = () => {
|
||||||
|
this.previousSaveHandle = undefined
|
||||||
|
}
|
||||||
|
|
||||||
saveToFileSystem = (data: Data) => {
|
saveToFileSystem = (data: Data) => {
|
||||||
this.saveAppStateToLocalStorage(data)
|
this.saveDataToFileSystem(data, false)
|
||||||
this.saveDocumentToLocalStorage(data)
|
|
||||||
this.saveDataToFileSystem(data, data.document.id, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveAsToFileSystem = (data: Data) => {
|
saveAsToFileSystem = (data: Data) => {
|
||||||
this.saveAppStateToLocalStorage(data)
|
this.saveDataToFileSystem(data, true)
|
||||||
this.saveDocumentToLocalStorage(data)
|
|
||||||
this.saveDataToFileSystem(data, uniqueId(), true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saveDataToFileSystem = async (
|
saveDataToFileSystem = async (data: Data, saveAs: boolean) => {
|
||||||
data: Data,
|
const isSavingAs = saveAs || !this.previousSaveHandle
|
||||||
fileId: string,
|
|
||||||
saveAs: boolean
|
|
||||||
) => {
|
|
||||||
const document = this.getCompleteDocument(data)
|
const document = this.getCompleteDocument(data)
|
||||||
|
|
||||||
// Then save to file system
|
// Then save to file system
|
||||||
|
@ -351,12 +362,14 @@ class Storage {
|
||||||
blob,
|
blob,
|
||||||
{
|
{
|
||||||
fileName: `${
|
fileName: `${
|
||||||
saveAs ? documentName : this.previousSaveHandle?.name || 'My Document'
|
isSavingAs
|
||||||
|
? documentName
|
||||||
|
: this.previousSaveHandle?.name || 'My Document'
|
||||||
}.tldr`,
|
}.tldr`,
|
||||||
description: 'tldraw file',
|
description: 'tldraw file',
|
||||||
extensions: ['.tldr'],
|
extensions: ['.tldr'],
|
||||||
},
|
},
|
||||||
saveAs ? undefined : this.previousSaveHandle,
|
isSavingAs ? undefined : this.previousSaveHandle,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
.then((handle) => {
|
.then((handle) => {
|
||||||
|
|
36
utils/sentry.ts
Normal file
36
utils/sentry.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import * as Sentry from '@sentry/node'
|
||||||
|
import { RewriteFrames } from '@sentry/integrations'
|
||||||
|
|
||||||
|
export function init(): void {
|
||||||
|
if (!process.env.NEXT_PUBLIC_SENTRY_DSN) return
|
||||||
|
|
||||||
|
const integrations = []
|
||||||
|
|
||||||
|
if (
|
||||||
|
process.env.NEXT_IS_SERVER === 'true' &&
|
||||||
|
process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR
|
||||||
|
) {
|
||||||
|
// For Node.js, rewrite Error.stack to use relative paths, so that source
|
||||||
|
// maps starting with ~/_next map to files in Error.stack with path
|
||||||
|
// app:///_next
|
||||||
|
integrations.push(
|
||||||
|
new RewriteFrames({
|
||||||
|
iteratee: (frame) => {
|
||||||
|
frame.filename = frame.filename.replace(
|
||||||
|
process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR,
|
||||||
|
'app:///'
|
||||||
|
)
|
||||||
|
frame.filename = frame.filename.replace('.next', '_next')
|
||||||
|
return frame
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Sentry.init({
|
||||||
|
enabled: process.env.NODE_ENV === 'production',
|
||||||
|
integrations,
|
||||||
|
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||||
|
release: process.env.NEXT_PUBLIC_COMMIT_SHA,
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue