diff --git a/remix/app/components/Thingtime/Thingtime.tsx b/remix/app/components/Thingtime/Thingtime.tsx index 0ee38d0..b2801b4 100644 --- a/remix/app/components/Thingtime/Thingtime.tsx +++ b/remix/app/components/Thingtime/Thingtime.tsx @@ -1,16 +1,183 @@ -import React from "react" -import { Box, Flex } from "@chakra-ui/react" +import React from 'react' +import { Box, Flex } from '@chakra-ui/react' export const Thingtime = props => { - const thing = React.useMemo(() => { return props.thing }, [props.thing]) - return -
-      {JSON.stringify(thing, null, 2)}
-    
-
- -} \ No newline at end of file + const mode = React.useMemo(() => { + return 'view' + }, []) + + const validKeyTypes = React.useMemo(() => { + return ['object', 'array'] + }, []) + + const keys = React.useMemo(() => { + if (validKeyTypes?.includes(typeof thing)) { + return Object.keys(thing) + } else { + return [] + } + }, [thing, validKeyTypes]) + + React.useEffect(() => { + if (window?.thingtime?.things) { + window.thingtime.things.count = + (window?.thingtime?.things?.count || 1) + 1 + } + }, []) + + const type = React.useMemo(() => { + return typeof thing + }, [thing]) + + const renderableValue = React.useMemo(() => { + if (type === 'string') { + return thing + } else if (type === 'number') { + return thing + } else if (type === 'boolean') { + return thing ? 'true' : 'false' + } else if (type === 'object') { + return JSON.stringify(thing, null, 2) + } else { + return null + } + }, [thing, type]) + + const flattenedKeys = React.useMemo(() => { + // create an array of all keys on object so that if object is + // { my: { child: {} } } + // the array looks like + // ['my', 'my.child'] + + const ret = [] + + try { + const randId = Math.random().toString(36).substring(7) + + window.thingtime.tmp[randId] = 0 + + const recurse = (obj, prefix) => { + Object.keys(obj).forEach(key => { + if (typeof obj[key] === 'object') { + if (window?.thingtime?.tmp[randId] < 1000) { + window.thingtime.tmp[randId]++ + recurse(obj[key], `${prefix}${prefix && '.'}${key}`) + } else { + console.error('Recursion limit reached in Thingtime.tsx') + } + } else { + ret.push({ + key: `${prefix}${prefix && '.'}${key}`, + human: `${prefix}${prefix && ' '}${key}` + }) + } + }) + } + + console.log('nik ret 1', thing) + + recurse(thing, '') + } catch (err) { + // console.error('Error in Thingtime.tsx creating flattenedKeys', err) + } + + console.log('nik ret 2', ret) + + return ret + }, [thing]) + + // do not render more than the limit of things to prevent infinite loops + try { + if ( + typeof window?.thingtime?.things?.count === 'number' && + window?.thingtime?.things?.count > window?.thingtime?.things?.limit + ) { + console.error('Maximum things reached') + return null + } + } catch (err) { + // console.error('Error in Thingtime.tsx checking maximum things', err) + } + + let ret = null + + const keysToUse = keys + // const keysToUse = flattenedKeys + + const template1Modes = ['view', 'edit'] + + if (template1Modes?.includes(mode)) { + console.log('nik keys', keys) + if (keys?.length) { + ret = ( + + {keysToUse?.length && + keysToUse.map((key, idx) => { + if (!key?.human) { + key = { + human: key, + key: key + } + } + + const nextThing = thing[key?.key] + + return ( + + ) + })} + + ) + } else { + ret = ( + + {props?.key?.human} + + {renderableValue} + + + ) + } + } + + const contextMenu = ( + + Settings + + ) + + const [showContextMenu, setShowContextMenu] = React.useState(false) + + return ( + setShowContextMenu(true)} + onMouseLeave={() => setShowContextMenu(false)} + position='relative' + {...props} + > + {showContextMenu && contextMenu} + {ret} + + ) +} diff --git a/remix/app/components/Thingtime/ThingtimeDemo.tsx b/remix/app/components/Thingtime/ThingtimeDemo.tsx index 48af325..6da1060 100644 --- a/remix/app/components/Thingtime/ThingtimeDemo.tsx +++ b/remix/app/components/Thingtime/ThingtimeDemo.tsx @@ -9,7 +9,14 @@ export const ThingtimeDemo = props => { image: 'thing image', price: 100, quantity: 1, - id: 1 + id: 1, + nested: { + data: { + is: { + fun: "Isn't it?" + } + } + } } const [demoThing, setDemoThing] = React.useState(thing) diff --git a/remix/app/components/rainbowText.tsx b/remix/app/components/rainbowText.tsx index 0e1fc23..5cc12f1 100644 --- a/remix/app/components/rainbowText.tsx +++ b/remix/app/components/rainbowText.tsx @@ -5,6 +5,7 @@ export const RainbowText = props => { return ( ) } + + +// limiter +try { + window.thingtime = { + tmp: {}, + things: { + limit: 999, + count: 0, + } + } +} catch (err) { + // will error on server +} \ No newline at end of file diff --git a/remix/app/routes/index.tsx b/remix/app/routes/index.tsx index f27bdb9..a7291e0 100644 --- a/remix/app/routes/index.tsx +++ b/remix/app/routes/index.tsx @@ -4,9 +4,9 @@ import { ThingtimeDemo } from '~/components/Thingtime/ThingtimeDemo' export default function Index () { return ( - + - {/* */} + ) }