feat: feature/mvp-sprint-1

This commit is contained in:
Nikolaj Frey 2023-07-21 11:13:02 +10:00
parent 71d9fade5e
commit e701e91e96
7 changed files with 225 additions and 100 deletions

View File

@ -84,7 +84,13 @@ const initialThingtime = smarts.merge(initialValues, force)
// }
export const ThingtimeProvider = (props: any): JSX.Element => {
const [thingtime, set] = React.useState(initialThingtime)
const [thingtime, rawSet] = React.useState(initialThingtime)
const set = React.useCallback((newThingtime) => {
newThingtime.tt = newThingtime
newThingtime.thingtime = newThingtime
rawSet(newThingtime)
}, [])
const thingtimeRef = React.useRef(thingtime)
const stateRef = React.useRef({

View File

@ -25,7 +25,7 @@ export const Commander = (props) => {
const [showContext, setShowContextState] = React.useState(false)
const mobileVW = React.useMemo(() => {
return "calc(100vw - 45px)"
return "calc(100vw - 55px)"
}, [])
const rainbowRepeats = 2
@ -349,6 +349,7 @@ export const Commander = (props) => {
// height="100%"
pointerEvents="none"
id="commander"
paddingX={1}
>
<Flex
position="absolute"

View File

@ -0,0 +1,22 @@
import React from "react"
import { Center } from "@chakra-ui/react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
export const Icon = (props) => {
const icon = React.useMemo(() => {
if (props?.name === "gear") {
return {
prefix: "fas",
iconName: props?.name,
}
}
return props?.name
}, [props?.name])
return (
<Center {...props?.chakras}>
<FontAwesomeIcon icon={icon}></FontAwesomeIcon>
</Center>
)
}

View File

@ -1,6 +1,7 @@
import React from "react"
import { Box, Flex } from "@chakra-ui/react"
import { Icon } from "../Icon/Icon"
import { Safe } from "../Safety/Safe"
import { useThingtime } from "./useThingtime"
@ -9,8 +10,12 @@ export const Thingtime = (props) => {
// and add button to expand circular reference
// up to 1 level deep
const { thingtime } = useThingtime()
const [uuid, setUuid] = React.useState()
const [circular, setCircular] = React.useState(props?.circular)
const depth = React.useMemo(() => {
return props?.depth || 1
}, [props?.depth])
@ -28,8 +33,6 @@ export const Thingtime = (props) => {
setUuid(Math.random().toString(36).substring(7))
}, [])
const { thingtime } = useThingtime()
const thing = React.useMemo(() => {
return props.thing
}, [props.thing])
@ -105,109 +108,89 @@ export const Thingtime = (props) => {
// err,
// thing
// )
return "Circular reference in object."
return <Box onClick={() => setCircular(false)}>Click to Expand</Box>
}
} else {
return "Something!"
}
}, [thing, type])
}, [thing, type, keys])
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}`,
})
}
})
}
recurse(thing, "")
} catch (err) {
// console.error('Error in Thingtime.tsx creating flattenedKeys', err)
}
return ret
}, [thing])
let value = null
let editableValue = null
const keysToUse = keys
const keysToUse = React.useMemo(() => {
return keys
}, [keys])
// const keysToUse = flattenedKeys
const template1Modes = ["view", "edit"]
const template1Modes = React.useMemo(() => {
return ["view", "edit"]
}, [])
if (template1Modes?.includes(mode)) {
if (keys?.length && !props?.circular) {
value = (
<Safe {...props}>
<Flex
position="relative"
flexDirection="column"
// w={'500px'}
// w={['200px', '500px']}
maxWidth="100%"
paddingLeft={valuePl}
paddingY={props?.path ? 3 : 0}
>
{keysToUse?.length &&
keysToUse.map((key, idx) => {
if (!key?.human) {
key = {
human: key,
key: key,
const value = React.useMemo(() => {
if (template1Modes?.includes(mode)) {
if (keys?.length && !circular) {
return (
<Safe {...props}>
<Flex
position="relative"
flexDirection="column"
// w={'500px'}
// w={['200px', '500px']}
maxWidth="100%"
paddingLeft={valuePl}
paddingY={props?.path ? 3 : 0}
>
{keysToUse?.length &&
keysToUse.map((key, idx) => {
if (!key?.human) {
key = {
human: key,
key: key,
}
}
}
const nextThing = thing[key?.key]
const nextThing = thing[key?.key]
const nextSeen = [...seen]
const nextSeen = [...seen]
if (typeof nextThing === "object") {
nextSeen.push(nextThing)
}
if (typeof nextThing === "object") {
nextSeen.push(nextThing)
}
return (
<Thingtime
key={idx}
seen={nextSeen}
circular={seen?.includes?.(nextThing)}
depth={depth + 1}
parent={thing}
path={key}
thing={nextThing}
// thing={{ infinite: { yes: true } }}
valuePl={pl}
></Thingtime>
)
})}
</Flex>
</Safe>
)
} else {
editableValue = (
return (
<Thingtime
key={idx}
seen={nextSeen}
circular={seen?.includes?.(nextThing)}
depth={depth + 1}
parent={thing}
path={key}
thing={nextThing}
// thing={{ infinite: { yes: true } }}
valuePl={pl}
></Thingtime>
)
})}
</Flex>
</Safe>
)
}
}
}, [
keysToUse,
mode,
circular,
seen,
depth,
thing,
props,
valuePl,
pl,
keys,
template1Modes,
])
const editableValue = React.useMemo(() => {
if (template1Modes?.includes(mode)) {
return (
<Box
paddingLeft={pl}
fontSize="20px"
@ -222,7 +205,7 @@ export const Thingtime = (props) => {
</Box>
)
}
}
}, [renderableValue, mode, template1Modes, pl])
const contextMenu = (
<Flex
@ -299,9 +282,14 @@ export const Thingtime = (props) => {
className={`thing-${uuid?.current}`}
>
{/* {uuid?.current} */}
{path}
<Flex position="relative" flexDirection="row">
{path}
<Flex position="absolute" top={0} right={0}>
<Icon name="gear"></Icon>
</Flex>
</Flex>
{/* {showContextMenu && contextMenu} */}
{editableValue}
{!value && editableValue}
{value}
</Flex>
</Safe>

View File

@ -0,0 +1,51 @@
import React from "react"
import { Box, Flex } from "@chakra-ui/react"
import { useMatches } from "@remix-run/react"
import { ProfileDrawer } from "~/components/Nav/ProfileDrawer"
import { Splash } from "~/components/Splash/Splash"
import { Thingtime } from "~/components/Thingtime/Thingtime"
import { ThingtimeDemo } from "~/components/Thingtime/ThingtimeDemo"
import { useThingtime } from "~/components/Thingtime/useThingtime"
import { GradientPath } from "~/gp/GradientPath"
export default function Index() {
const { getThingtime } = useThingtime()
const matches = useMatches()
const location = React.useMemo(() => {
return matches[matches.length - 1]
}, [matches])
const path = React.useMemo(() => {
const pathStepOne = location?.pathname?.replace("/things/", "")
const path = pathStepOne?.replace(/\//g, ".")
return path
}, [location?.pathname])
const thing = React.useMemo(() => {
// remove /things/ from path
const ret = getThingtime(path)
return ret
}, [path, getThingtime])
return (
<Flex
alignItems="center"
justifyContent="center"
flexDirection="column"
maxWidth="100%"
>
<Thingtime
path={path}
thing={thing}
chakras={{ marginY: 200 }}
width="600px"
></Thingtime>
<ProfileDrawer></ProfileDrawer>
</Flex>
)
}

View File

@ -9,6 +9,10 @@
},
"dependencies": {
"@chakra-ui/react": "^2.7.1",
"@fortawesome/fontawesome-svg-core": "^6.4.0",
"@fortawesome/free-regular-svg-icons": "^6.4.0",
"@fortawesome/free-solid-svg-icons": "^6.4.0",
"@fortawesome/react-fontawesome": "^0.2.0",
"@remix-run/node": "^1.15.0",
"@remix-run/react": "^1.15.0",
"@remix-run/serve": "^1.15.0",

View File

@ -8,6 +8,18 @@ dependencies:
'@chakra-ui/react':
specifier: ^2.7.1
version: 2.7.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.0.28)(framer-motion@10.12.17)(react-dom@18.2.0)(react@18.2.0)
'@fortawesome/fontawesome-svg-core':
specifier: ^6.4.0
version: 6.4.0
'@fortawesome/free-regular-svg-icons':
specifier: ^6.4.0
version: 6.4.0
'@fortawesome/free-solid-svg-icons':
specifier: ^6.4.0
version: 6.4.0
'@fortawesome/react-fontawesome':
specifier: ^0.2.0
version: 0.2.0(@fortawesome/fontawesome-svg-core@6.4.0)(react@18.2.0)
'@remix-run/node':
specifier: ^1.15.0
version: 1.15.0
@ -34,7 +46,7 @@ dependencies:
version: 2.3.0
isbot:
specifier: latest
version: 3.6.12
version: 3.6.13
lodash-es:
specifier: ^4.17.21
version: 4.17.21
@ -3055,6 +3067,47 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/@fortawesome/fontawesome-common-types@6.4.0:
resolution: {integrity: sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ==}
engines: {node: '>=6'}
requiresBuild: true
dev: false
/@fortawesome/fontawesome-svg-core@6.4.0:
resolution: {integrity: sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
'@fortawesome/fontawesome-common-types': 6.4.0
dev: false
/@fortawesome/free-regular-svg-icons@6.4.0:
resolution: {integrity: sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
'@fortawesome/fontawesome-common-types': 6.4.0
dev: false
/@fortawesome/free-solid-svg-icons@6.4.0:
resolution: {integrity: sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ==}
engines: {node: '>=6'}
requiresBuild: true
dependencies:
'@fortawesome/fontawesome-common-types': 6.4.0
dev: false
/@fortawesome/react-fontawesome@0.2.0(@fortawesome/fontawesome-svg-core@6.4.0)(react@18.2.0):
resolution: {integrity: sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==}
peerDependencies:
'@fortawesome/fontawesome-svg-core': ~1 || ~6
react: '>=16.3'
dependencies:
'@fortawesome/fontawesome-svg-core': 6.4.0
prop-types: 15.8.1
react: 18.2.0
dev: false
/@gar/promisify@1.1.3:
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
dev: true
@ -6921,8 +6974,8 @@ packages:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
dev: true
/isbot@3.6.12:
resolution: {integrity: sha512-dGc3jRIORywaaqs4G5wj+58i5/l1eoI75q7XNiyW9Sgfoyr3QkyDZUXw+cuB7AOFq/0aruCQrGLrnKJlQarP/g==}
/isbot@3.6.13:
resolution: {integrity: sha512-uoP4uK5Dc2CrabmK+Gue1jTL+scHiCc1c9rblRpJwG8CPxjLIv8jmGyyGRGkbPOweayhkskdZsEQXG6p+QCQrg==}
engines: {node: '>=12'}
dev: false