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

View file

@ -1,12 +1,12 @@
import * as fa from 'browser-fs-access'
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 { current } from 'immer'
import { v4 as uuid } from 'uuid'
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'
function storageId(fileId: string, label: string, id?: string) {
@ -69,7 +69,7 @@ class Storage {
return false
}
const restoredData: any = JSON.parse(savedData)
const restoredData: any = JSON.parse(lzw_decode(savedData))
for (let pageId in restoredData.document.pages) {
const selectedIds = restoredData.pageStates[pageId].selectedIds
@ -88,7 +88,7 @@ class Storage {
)
if (savedPage !== null) {
const restored: Page = JSON.parse(savedPage)
const restored: Page = JSON.parse(lzw_decode(savedPage))
dataToSave.document.pages[pageId] = restored
}
@ -106,7 +106,10 @@ class Storage {
const dataToSave = this.getDataToSave(data)
// 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) {
@ -134,7 +137,7 @@ class Storage {
const page = data.document.pages[pageId]
const json = JSON.stringify(page)
localStorage.setItem(storageId(fileId, 'page', pageId), json)
localStorage.setItem(storageId(fileId, 'page', pageId), lzw_encode(json))
// Save page state
@ -167,7 +170,7 @@ class Storage {
const savedPage = localStorage.getItem(storageId(fileId, 'page', pageId))
if (savedPage !== null) {
data.document.pages[pageId] = JSON.parse(savedPage)
data.document.pages[pageId] = JSON.parse(lzw_decode(savedPage))
} else {
data.document.pages[pageId] = {
id: pageId,
@ -186,7 +189,6 @@ class Storage {
if (savedPageState !== null) {
const restored: PageState = JSON.parse(savedPageState)
restored.selectedIds = new Set(restored.selectedIds)
data.pageStates[pageId] = restored
} else {
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
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,
]
}
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('')
}