feat: main Fixed responsiveness and added Safe and safe functions and added globalThis usage for recursion safety on SSR
This commit is contained in:
parent
56da3991a5
commit
9793237357
@ -1,9 +1,18 @@
|
|||||||
import { Flex } from '@chakra-ui/react'
|
import { Flex } from '@chakra-ui/react'
|
||||||
import { Nav } from '../Nav/Nav'
|
import { Nav } from '../Nav/Nav'
|
||||||
|
import { ProfileDrawer } from '../Nav/ProfileDrawer'
|
||||||
|
|
||||||
export const Main = props => {
|
export const Main = props => {
|
||||||
return (
|
return (
|
||||||
<Flex alignItems='center' justifyContent='center' flexDir={'column'}>
|
<Flex
|
||||||
|
position={'relative'}
|
||||||
|
alignItems='center'
|
||||||
|
justifyContent='center'
|
||||||
|
flexDir={'column'}
|
||||||
|
overflow='hidden'
|
||||||
|
maxW='100vw'
|
||||||
|
>
|
||||||
|
{/* <ProfileDrawer></ProfileDrawer> */}
|
||||||
<Nav />
|
<Nav />
|
||||||
{props.children}
|
{props.children}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -1,8 +1,15 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Flex } from '@chakra-ui/react'
|
import { Flex } from '@chakra-ui/react'
|
||||||
import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton'
|
import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton'
|
||||||
|
import { ProfileDrawer } from './ProfileDrawer'
|
||||||
|
|
||||||
export const Nav = props => {
|
export const Nav = props => {
|
||||||
|
const [profileDrawerOpen, setProfileDrawerOpen] = React.useState(false)
|
||||||
|
|
||||||
|
const toggleProfileDrawer = React.useCallback(() => {
|
||||||
|
setProfileDrawerOpen(!profileDrawerOpen)
|
||||||
|
}, [profileDrawerOpen])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex
|
<Flex
|
||||||
@ -15,12 +22,24 @@ export const Nav = props => {
|
|||||||
top={0}
|
top={0}
|
||||||
left={0}
|
left={0}
|
||||||
right={0}
|
right={0}
|
||||||
py={4}
|
py={6}
|
||||||
px={4}
|
px={6}
|
||||||
|
bg='white'
|
||||||
|
zIndex={999}
|
||||||
|
boxShadow={'0px 0px 10px rgba(0,0,0,0.1)'}
|
||||||
>
|
>
|
||||||
|
<RainbowSkeleton
|
||||||
|
ml={'auto'}
|
||||||
|
w='25px'
|
||||||
|
h='25px'
|
||||||
|
onClick={toggleProfileDrawer}
|
||||||
|
sx={{}}
|
||||||
|
borderRadius='999px'
|
||||||
|
></RainbowSkeleton>
|
||||||
{/* <RainbowSkeleton w='40px' ml='auto' mr={"4px"}></RainbowSkeleton>
|
{/* <RainbowSkeleton w='40px' ml='auto' mr={"4px"}></RainbowSkeleton>
|
||||||
<RainbowSkeleton></RainbowSkeleton> */}
|
<RainbowSkeleton></RainbowSkeleton> */}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
{/* <ProfileDrawer isOpen={profileDrawerOpen}></ProfileDrawer> */}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
27
remix/app/components/Nav/ProfileDrawer.tsx
Normal file
27
remix/app/components/Nav/ProfileDrawer.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { Drawer, DrawerBody, DrawerContent, Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
|
export const ProfileDrawer = props => {
|
||||||
|
const navItems = ['settings']
|
||||||
|
|
||||||
|
const onClose = React.useCallback(() => {
|
||||||
|
// nothing
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Drawer
|
||||||
|
placement='right'
|
||||||
|
size='md'
|
||||||
|
isOpen={props?.isOpen}
|
||||||
|
onClose={onClose}
|
||||||
|
>
|
||||||
|
<DrawerContent maxW={'90%'} mt={'35px'} className='ProfileDrawer'>
|
||||||
|
<DrawerBody>
|
||||||
|
{navItems.map((item, idx) => {
|
||||||
|
return <Flex key={idx}>{item}</Flex>
|
||||||
|
})}
|
||||||
|
</DrawerBody>
|
||||||
|
</DrawerContent>
|
||||||
|
</Drawer>
|
||||||
|
)
|
||||||
|
}
|
7
remix/app/components/Safety/Safe.tsx
Normal file
7
remix/app/components/Safety/Safe.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { safe } from '~/functions/safe'
|
||||||
|
|
||||||
|
export const Safe = props => {
|
||||||
|
// do not render more than the limit of things to prevent infinite loops
|
||||||
|
|
||||||
|
return safe(props)
|
||||||
|
}
|
@ -2,46 +2,46 @@ import React from 'react'
|
|||||||
import { Flex } from '@chakra-ui/react'
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
|
||||||
export const RainbowSkeleton = props => {
|
export const RainbowSkeleton = props => {
|
||||||
|
const [rainbowColours] = React.useState([
|
||||||
const [rainbowColours] = React.useState(["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"])
|
'#f34a4a',
|
||||||
|
'#ffbc48',
|
||||||
|
'#58ca70',
|
||||||
|
'#47b5e6',
|
||||||
|
'#a555e8'
|
||||||
|
])
|
||||||
|
|
||||||
const keyframes = React.useMemo(() => {
|
const keyframes = React.useMemo(() => {
|
||||||
let keyframes = {}
|
let keyframes = {}
|
||||||
rainbowColours.forEach((colour, idx) => {
|
rainbowColours.forEach((colour, idx) => {
|
||||||
keyframes[Math.round(idx * 100 / rainbowColours.length) + "%"] = { backgroundColor: colour }
|
keyframes[Math.round((idx * 100) / rainbowColours.length) + '%'] = {
|
||||||
|
backgroundColor: colour
|
||||||
|
}
|
||||||
})
|
})
|
||||||
keyframes["100%"] = { backgroundColor: rainbowColours[0] }
|
keyframes['100%'] = { backgroundColor: rainbowColours[0] }
|
||||||
return keyframes
|
return keyframes
|
||||||
}, [rainbowColours])
|
}, [rainbowColours])
|
||||||
|
|
||||||
if (props?.loaded) {
|
if (props?.loaded) {
|
||||||
return props?.children
|
return props?.children
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
cursor='pointer'
|
||||||
|
w='10px'
|
||||||
|
h='8px'
|
||||||
|
borderRadius={'2px'}
|
||||||
|
bg={'rgba(0,0,0,0.1)'}
|
||||||
|
sx={{
|
||||||
|
'@keyframes placeholder-rainbow': keyframes,
|
||||||
|
'@keyframes placeholder-opacity': {
|
||||||
|
'0%': { opacity: 0.2 },
|
||||||
|
'100%': { opacity: 1 }
|
||||||
|
},
|
||||||
|
// add delay
|
||||||
|
animation: `placeholder-rainbow 3s infinite linear, placeholder-opacity 1.3s linear 0s infinite alternate none running}`
|
||||||
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
flexDirection={'column'}
|
></Flex>
|
||||||
justifyContent={'center'}
|
|
||||||
alignItems={'center'}
|
|
||||||
cursor={'pointer'}
|
|
||||||
>
|
|
||||||
<Flex
|
|
||||||
w='10px'
|
|
||||||
h='8px'
|
|
||||||
borderRadius={'2px'}
|
|
||||||
mb='10px'
|
|
||||||
sx={{
|
|
||||||
'@keyframes placeholder-rainbow': keyframes,
|
|
||||||
'@keyframes placeholder-opacity': {
|
|
||||||
'0%': { opacity: 0.2 },
|
|
||||||
'100%': { opacity: 1 }
|
|
||||||
},
|
|
||||||
// add delay
|
|
||||||
animation: `placeholder-rainbow 3s infinite linear, placeholder-opacity 1.3s linear 0s infinite alternate none running}`
|
|
||||||
}}
|
|
||||||
{...props}
|
|
||||||
></Flex>
|
|
||||||
</Flex>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { Box, Flex } from '@chakra-ui/react'
|
import { Box, Flex } from '@chakra-ui/react'
|
||||||
import { safe } from '~/functions/safe'
|
import { Safe } from '../Safety/Safe'
|
||||||
|
|
||||||
export const Thingtime = props => {
|
export const Thingtime = props => {
|
||||||
// const cuid = React.useMemo(() => {
|
// const uuid = React.useMemo(() => {
|
||||||
// return Math.random().toString(36).substring(7)
|
// return Math.random().toString(36).substring(7)
|
||||||
// }, [])
|
// }, [])
|
||||||
const cuid = React.useRef(Math.random().toString(36).substring(7))
|
const uuid = React.useRef(Math.random().toString(36).substring(7))
|
||||||
|
|
||||||
|
const depth = React.useMemo(() => {
|
||||||
|
return props?.depth || 1
|
||||||
|
}, [props?.depth])
|
||||||
|
|
||||||
const thing = React.useMemo(() => {
|
const thing = React.useMemo(() => {
|
||||||
return props.thing
|
return props.thing
|
||||||
@ -28,13 +32,6 @@ export const Thingtime = props => {
|
|||||||
}
|
}
|
||||||
}, [thing, validKeyTypes])
|
}, [thing, validKeyTypes])
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
if (window?.thingtime?.things) {
|
|
||||||
window.thingtime.things.count =
|
|
||||||
(window?.thingtime?.things?.count || 1) + 1
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const type = React.useMemo(() => {
|
const type = React.useMemo(() => {
|
||||||
return typeof thing
|
return typeof thing
|
||||||
}, [thing])
|
}, [thing])
|
||||||
@ -84,15 +81,11 @@ export const Thingtime = props => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('nik ret 1', thing)
|
|
||||||
|
|
||||||
recurse(thing, '')
|
recurse(thing, '')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.error('Error in Thingtime.tsx creating flattenedKeys', err)
|
// console.error('Error in Thingtime.tsx creating flattenedKeys', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('nik ret 2', ret)
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}, [thing])
|
}, [thing])
|
||||||
|
|
||||||
@ -105,37 +98,42 @@ export const Thingtime = props => {
|
|||||||
const template1Modes = ['view', 'edit']
|
const template1Modes = ['view', 'edit']
|
||||||
|
|
||||||
if (template1Modes?.includes(mode)) {
|
if (template1Modes?.includes(mode)) {
|
||||||
console.log('nik keys', keys)
|
|
||||||
if (keys?.length) {
|
if (keys?.length) {
|
||||||
value = (
|
value = (
|
||||||
<Flex
|
<Safe {...props}>
|
||||||
position='relative'
|
<Flex
|
||||||
flexDir='column'
|
position='relative'
|
||||||
minW='500px'
|
flexDir='column'
|
||||||
maxW='100%'
|
// w={'500px'}
|
||||||
pl={6}
|
// w={['200px', '500px']}
|
||||||
>
|
maxW='100%'
|
||||||
{keysToUse?.length &&
|
pl={[4, 6]}
|
||||||
keysToUse.map((key, idx) => {
|
pr={[4, 6]}
|
||||||
if (!key?.human) {
|
>
|
||||||
key = {
|
{keysToUse?.length &&
|
||||||
human: key,
|
keysToUse.map((key, idx) => {
|
||||||
key: key
|
if (!key?.human) {
|
||||||
|
key = {
|
||||||
|
human: key,
|
||||||
|
key: key
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const nextThing = thing[key?.key]
|
const nextThing = thing[key?.key]
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Thingtime
|
<Thingtime
|
||||||
key={idx}
|
key={idx}
|
||||||
parent={thing}
|
depth={depth + 1}
|
||||||
path={key}
|
parent={thing}
|
||||||
thing={nextThing}
|
path={key}
|
||||||
></Thingtime>
|
thing={nextThing}
|
||||||
)
|
// thing={{ infinite: { yes: true } }}
|
||||||
})}
|
></Thingtime>
|
||||||
</Flex>
|
)
|
||||||
|
})}
|
||||||
|
</Flex>
|
||||||
|
</Safe>
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
editableValue = (
|
editableValue = (
|
||||||
@ -161,39 +159,45 @@ export const Thingtime = props => {
|
|||||||
const [showContextMenu, setShowContextMenu] = React.useState(false)
|
const [showContextMenu, setShowContextMenu] = React.useState(false)
|
||||||
|
|
||||||
const path = React.useMemo(() => {
|
const path = React.useMemo(() => {
|
||||||
return <Flex fontSize='12px'>{props?.path?.human}</Flex>
|
return (
|
||||||
|
<Flex maxW='100%' wordBreak={'break-all'} fontSize='12px'>
|
||||||
|
{props?.path?.human}
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
}, [props?.path])
|
}, [props?.path])
|
||||||
|
|
||||||
const handleMouseEvent = React.useCallback(
|
const handleMouseEvent = React.useCallback(
|
||||||
e => {
|
e => {
|
||||||
const target = e?.target
|
const target = e?.target
|
||||||
// extract cuid from className
|
// extract uuid from className
|
||||||
console.log('nik eh', target?.className, cuid)
|
|
||||||
const className = target?.className
|
const className = target?.className
|
||||||
if (className?.includes(cuid?.current)) {
|
if (className?.includes(uuid?.current)) {
|
||||||
setShowContextMenu(e?.type === 'mouseenter')
|
setShowContextMenu(e?.type === 'mouseenter')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[cuid]
|
[uuid]
|
||||||
)
|
)
|
||||||
|
|
||||||
console.log('nik cuid', cuid)
|
return (
|
||||||
|
<Safe {...props} depth={depth} uuid={uuid?.current}>
|
||||||
return safe(
|
<Flex
|
||||||
<Flex
|
onMouseEnter={handleMouseEvent}
|
||||||
onMouseEnter={handleMouseEvent}
|
onMouseLeave={handleMouseEvent}
|
||||||
onMouseLeave={handleMouseEvent}
|
position='relative'
|
||||||
position='relative'
|
flexDir='column'
|
||||||
flexDir='column'
|
py={3}
|
||||||
py={3}
|
w='500px'
|
||||||
{...props}
|
// minW={depth === 1 ? '120px' : null}
|
||||||
className={`thing-${cuid?.current}`}
|
maxW='100%'
|
||||||
>
|
{...props}
|
||||||
{/* {cuid?.current} */}
|
className={`thing-${uuid?.current}`}
|
||||||
{path}
|
>
|
||||||
{showContextMenu && contextMenu}
|
{/* {uuid?.current} */}
|
||||||
{editableValue}
|
{path}
|
||||||
{value}
|
{showContextMenu && contextMenu}
|
||||||
</Flex>
|
{editableValue}
|
||||||
|
{value}
|
||||||
|
</Flex>
|
||||||
|
</Safe>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ export const ThingtimeDemo = props => {
|
|||||||
// return null
|
// return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex pb={40}>
|
<Flex maxW='100%' pb={40}>
|
||||||
<Thingtime thing={demoThing}></Thingtime>
|
<Thingtime thing={demoThing}></Thingtime>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
|
@ -1,16 +1,56 @@
|
|||||||
export const safe = response => {
|
export const safe = props => {
|
||||||
// do not render more than the limit of things to prevent infinite loops
|
// do not render more than the limit of things to prevent infinite loops
|
||||||
|
const thingtime = getThingtime()
|
||||||
|
|
||||||
|
const uuid = props?.uuid
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (
|
if (
|
||||||
typeof window?.thingtime?.things?.count === 'number' &&
|
typeof thingtime?.things?.count === 'number' &&
|
||||||
window?.thingtime?.things?.count > window?.thingtime?.things?.limit
|
thingtime?.things?.count >= thingtime?.things?.limit
|
||||||
) {
|
) {
|
||||||
console.error('Maximum things reached')
|
console.error(
|
||||||
|
'[codex] Maximum things reached',
|
||||||
|
thingtime?.things?.count,
|
||||||
|
thingtime?.things?.limit
|
||||||
|
)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// console.error('Error in Thingtime.tsx checking maximum things', err)
|
console.error('[codex] Error in Thingtime.tsx checking maximum things', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return response
|
try {
|
||||||
|
if (!thingtime?.things?.db?.[uuid]) {
|
||||||
|
thingtime.things.db[uuid] = {
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
thingtime.things.count++
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (props?.depth >= thingtime?.things?.maxDepth) {
|
||||||
|
console.error(
|
||||||
|
'[codex] Reached max depth',
|
||||||
|
props?.depth,
|
||||||
|
thingtime?.things?.maxDepth
|
||||||
|
)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
return props?.children
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getThingtime = () => {
|
||||||
|
try {
|
||||||
|
return window?.thingtime || globalThis?.thingtime
|
||||||
|
} catch {
|
||||||
|
return globalThis?.thingtime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,16 +48,26 @@ export default function App () {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// limiter
|
// limiter
|
||||||
try {
|
|
||||||
window.thingtime = {
|
const setThingtime = glob => {
|
||||||
tmp: {},
|
try {
|
||||||
things: {
|
glob.thingtime = {
|
||||||
limit: 999,
|
tmp: {},
|
||||||
count: 0,
|
things: {
|
||||||
|
db: {},
|
||||||
|
limit: 9999,
|
||||||
|
maxDepth: 10,
|
||||||
|
count: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// will error on server
|
||||||
}
|
}
|
||||||
} catch (err) {
|
}
|
||||||
// will error on server
|
|
||||||
}
|
try {
|
||||||
|
setThingtime(window)
|
||||||
|
} catch {
|
||||||
|
setThingtime(globalThis)
|
||||||
|
}
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
import { Flex } from '@chakra-ui/react'
|
import { Flex } from '@chakra-ui/react'
|
||||||
|
import { ProfileDrawer } from '~/components/Nav/ProfileDrawer'
|
||||||
import { Splash } from '~/components/Splash/Splash'
|
import { Splash } from '~/components/Splash/Splash'
|
||||||
import { ThingtimeDemo } from '~/components/Thingtime/ThingtimeDemo'
|
import { ThingtimeDemo } from '~/components/Thingtime/ThingtimeDemo'
|
||||||
|
|
||||||
export default function Index () {
|
export default function Index () {
|
||||||
return (
|
return (
|
||||||
<Flex flexDir='column' alignItems='center' justifyContent='center'>
|
<Flex
|
||||||
|
maxW='100%'
|
||||||
|
flexDir='column'
|
||||||
|
alignItems='center'
|
||||||
|
justifyContent='center'
|
||||||
|
>
|
||||||
<Splash></Splash>
|
<Splash></Splash>
|
||||||
<ThingtimeDemo></ThingtimeDemo>
|
<ThingtimeDemo></ThingtimeDemo>
|
||||||
|
<ProfileDrawer></ProfileDrawer>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user