encodes local storage data, hides off-screen shapes

This commit is contained in:
Steve Ruiz 2021-06-13 14:04:20 +01:00
parent c8070857b1
commit c88206fd47
3 changed files with 107 additions and 35 deletions

View file

@ -1,7 +1,7 @@
import { getShapeUtils } from 'lib/shape-utils' import { getShapeUtils } from 'lib/shape-utils'
import state, { useSelector } from 'state' import state, { useSelector } from 'state'
import { Bounds, GroupShape, PageState } from 'types' import { Bounds, GroupShape, PageState } from 'types'
import { boundsContain } from 'utils/bounds' import { boundsCollide, boundsContain } from 'utils/bounds'
import { deepCompareArrays, getPage, screenToWorld } from 'utils/utils' import { deepCompareArrays, getPage, screenToWorld } from 'utils/utils'
import Shape from './shape' import Shape from './shape'
@ -20,36 +20,39 @@ export default function Page() {
const page = getPage(s.data) const page = getPage(s.data)
const pageState = s.data.pageStates[page.id] const pageState = s.data.pageStates[page.id]
// if (!viewportCache.has(pageState)) { if (!viewportCache.has(pageState)) {
// const [minX, minY] = screenToWorld([0, 0], s.data) const [minX, minY] = screenToWorld([0, 0], s.data)
// const [maxX, maxY] = screenToWorld( const [maxX, maxY] = screenToWorld(
// [window.innerWidth, window.innerHeight], [window.innerWidth, window.innerHeight],
// s.data s.data
// ) )
// viewportCache.set(pageState, { viewportCache.set(pageState, {
// minX, minX,
// minY, minY,
// maxX, maxX,
// maxY, maxY,
// height: maxX - minX, height: maxX - minX,
// width: maxY - minY, width: maxY - minY,
// }) })
// } }
// const viewport = viewportCache.get(pageState) const viewport = viewportCache.get(pageState)
return ( return Object.values(page.shapes)
Object.values(page.shapes) .filter((shape) => shape.parentId === page.id)
.filter((shape) => shape.parentId === page.id) .filter((shape) => {
// .filter((shape) => { const shapeBounds = getShapeUtils(shape).getBounds(shape)
// const shapeBounds = getShapeUtils(shape).getBounds(shape) return (
// return boundsContain(viewport, shapeBounds) boundsContain(viewport, shapeBounds) ||
// }) boundsCollide(viewport, shapeBounds)
.sort((a, b) => a.childIndex - b.childIndex) )
.map((shape) => shape.id) })
) .sort((a, b) => a.childIndex - b.childIndex)
.map((shape) => shape.id)
}, deepCompareArrays) }, deepCompareArrays)
console.log(currentPageShapeIds.length)
const isSelecting = useSelector((s) => s.isIn('selecting')) const isSelecting = useSelector((s) => s.isIn('selecting'))
return ( return (

View file

@ -1,12 +1,12 @@
import * as fa from 'browser-fs-access' import * as fa from 'browser-fs-access'
import { Data, Page, PageState, TLDocument } from 'types' import { Data, Page, PageState, TLDocument } from 'types'
import { setToArray } from 'utils/utils' import { lzw_decode, lzw_encode, setToArray } from 'utils/utils'
import state from './state' import state from './state'
import { current } from 'immer' import { current } from 'immer'
import { v4 as uuid } from 'uuid' import { v4 as uuid } from 'uuid'
import * as idb from 'idb-keyval' import * as idb from 'idb-keyval'
const CURRENT_VERSION = 'code_slate_0.0.5' const CURRENT_VERSION = 'code_slate_0.0.6'
const DOCUMENT_ID = '0001' const DOCUMENT_ID = '0001'
function storageId(fileId: string, label: string, id?: string) { function storageId(fileId: string, label: string, id?: string) {
@ -69,7 +69,7 @@ class Storage {
return false return false
} }
const restoredData: any = JSON.parse(savedData) const restoredData: any = JSON.parse(lzw_decode(savedData))
for (let pageId in restoredData.document.pages) { for (let pageId in restoredData.document.pages) {
const selectedIds = restoredData.pageStates[pageId].selectedIds const selectedIds = restoredData.pageStates[pageId].selectedIds
@ -88,7 +88,7 @@ class Storage {
) )
if (savedPage !== null) { if (savedPage !== null) {
const restored: Page = JSON.parse(savedPage) const restored: Page = JSON.parse(lzw_decode(savedPage))
dataToSave.document.pages[pageId] = restored dataToSave.document.pages[pageId] = restored
} }
@ -106,7 +106,10 @@ class Storage {
const dataToSave = this.getDataToSave(data) const dataToSave = this.getDataToSave(data)
// Save current data to local storage // Save current data to local storage
localStorage.setItem(storageId(fileId, 'document', fileId), dataToSave) localStorage.setItem(
storageId(fileId, 'document', fileId),
lzw_encode(dataToSave)
)
} }
loadDocumentFromJson(data: Data, restoredData: any) { loadDocumentFromJson(data: Data, restoredData: any) {
@ -134,7 +137,7 @@ class Storage {
const page = data.document.pages[pageId] const page = data.document.pages[pageId]
const json = JSON.stringify(page) const json = JSON.stringify(page)
localStorage.setItem(storageId(fileId, 'page', pageId), json) localStorage.setItem(storageId(fileId, 'page', pageId), lzw_encode(json))
// Save page state // Save page state
@ -167,7 +170,7 @@ class Storage {
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId)) const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
if (savedPage !== null) { if (savedPage !== null) {
data.document.pages[pageId] = JSON.parse(savedPage) data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage))
} else { } else {
data.document.pages[pageId] = { data.document.pages[pageId] = {
id: pageId, id: pageId,
@ -186,7 +189,6 @@ class Storage {
if (savedPageState !== null) { if (savedPageState !== null) {
const restored: PageState = JSON.parse(savedPageState) const restored: PageState = JSON.parse(savedPageState)
restored.selectedIds = new Set(restored.selectedIds)
data.pageStates[pageId] = restored data.pageStates[pageId] = restored
} else { } else {
data.pageStates[pageId] = { data.pageStates[pageId] = {
@ -198,6 +200,10 @@ class Storage {
} }
} }
data.pageStates[pageId].selectedIds = new Set(
data.pageStates[pageId].selectedIds
)
// Empty shapes in state for other pages // Empty shapes in state for other pages
for (let key in data.document.pages) { for (let key in data.document.pages) {

View file

@ -1768,3 +1768,66 @@ export function getPoint(
'pressure' in e ? e.pressure || 0.5 : 0.5, 'pressure' in e ? e.pressure || 0.5 : 0.5,
] ]
} }
export function lzw_encode(s: string) {
const dict = {}
const data = (s + '').split('')
let currChar: string
let phrase = data[0]
let code = 256
const out = []
for (var i = 1; i < data.length; i++) {
currChar = data[i]
if (dict[phrase + currChar] != null) {
phrase += currChar
} else {
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
dict[phrase + currChar] = code
code++
phrase = currChar
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0))
for (var i = 0; i < out.length; i++) {
out[i] = String.fromCharCode(out[i])
}
return out.join('')
}
// Decompress an LZW-encoded string
export function lzw_decode(s: string) {
const dict = {}
const data = (s + '').split('')
let currChar = data[0]
let oldPhrase = currChar
let code = 256
let phrase: string
const out = [currChar]
for (var i = 1; i < data.length; i++) {
let currCode = data[i].charCodeAt(0)
if (currCode < 256) {
phrase = data[i]
} else {
phrase = dict[currCode] ? dict[currCode] : oldPhrase + currChar
}
out.push(phrase)
currChar = phrase.charAt(0)
dict[code] = oldPhrase + currChar
code++
oldPhrase = phrase
}
return out.join('')
}