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 { Nav } from '../Nav/Nav'
|
||||
import { ProfileDrawer } from '../Nav/ProfileDrawer'
|
||||
|
||||
export const Main = props => {
|
||||
return (
|
||||
<Flex alignItems='center' justifyContent='center' flexDir={'column'}>
|
||||
<Flex
|
||||
position={'relative'}
|
||||
alignItems='center'
|
||||
justifyContent='center'
|
||||
flexDir={'column'}
|
||||
overflow='hidden'
|
||||
maxW='100vw'
|
||||
>
|
||||
{/* <ProfileDrawer></ProfileDrawer> */}
|
||||
<Nav />
|
||||
{props.children}
|
||||
</Flex>
|
||||
|
@ -1,8 +1,15 @@
|
||||
import React from 'react'
|
||||
import { Flex } from '@chakra-ui/react'
|
||||
import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton'
|
||||
import { ProfileDrawer } from './ProfileDrawer'
|
||||
|
||||
export const Nav = props => {
|
||||
const [profileDrawerOpen, setProfileDrawerOpen] = React.useState(false)
|
||||
|
||||
const toggleProfileDrawer = React.useCallback(() => {
|
||||
setProfileDrawerOpen(!profileDrawerOpen)
|
||||
}, [profileDrawerOpen])
|
||||
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
@ -15,12 +22,24 @@ export const Nav = props => {
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
py={4}
|
||||
px={4}
|
||||
py={6}
|
||||
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></RainbowSkeleton> */}
|
||||
</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'
|
||||
|
||||
export const RainbowSkeleton = props => {
|
||||
|
||||
const [rainbowColours] = React.useState(["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"])
|
||||
const [rainbowColours] = React.useState([
|
||||
'#f34a4a',
|
||||
'#ffbc48',
|
||||
'#58ca70',
|
||||
'#47b5e6',
|
||||
'#a555e8'
|
||||
])
|
||||
|
||||
const keyframes = React.useMemo(() => {
|
||||
let keyframes = {}
|
||||
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
|
||||
}, [rainbowColours])
|
||||
|
||||
if (props?.loaded) {
|
||||
return props?.children
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<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}
|
||||
flexDirection={'column'}
|
||||
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>
|
||||
></Flex>
|
||||
)
|
||||
}
|
||||
|
@ -1,12 +1,16 @@
|
||||
import React from 'react'
|
||||
import { Box, Flex } from '@chakra-ui/react'
|
||||
import { safe } from '~/functions/safe'
|
||||
import { Safe } from '../Safety/Safe'
|
||||
|
||||
export const Thingtime = props => {
|
||||
// const cuid = React.useMemo(() => {
|
||||
// const uuid = React.useMemo(() => {
|
||||
// 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(() => {
|
||||
return props.thing
|
||||
@ -28,13 +32,6 @@ export const Thingtime = props => {
|
||||
}
|
||||
}, [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])
|
||||
@ -84,15 +81,11 @@ export const Thingtime = props => {
|
||||
})
|
||||
}
|
||||
|
||||
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])
|
||||
|
||||
@ -105,37 +98,42 @@ export const Thingtime = props => {
|
||||
const template1Modes = ['view', 'edit']
|
||||
|
||||
if (template1Modes?.includes(mode)) {
|
||||
console.log('nik keys', keys)
|
||||
if (keys?.length) {
|
||||
value = (
|
||||
<Flex
|
||||
position='relative'
|
||||
flexDir='column'
|
||||
minW='500px'
|
||||
maxW='100%'
|
||||
pl={6}
|
||||
>
|
||||
{keysToUse?.length &&
|
||||
keysToUse.map((key, idx) => {
|
||||
if (!key?.human) {
|
||||
key = {
|
||||
human: key,
|
||||
key: key
|
||||
<Safe {...props}>
|
||||
<Flex
|
||||
position='relative'
|
||||
flexDir='column'
|
||||
// w={'500px'}
|
||||
// w={['200px', '500px']}
|
||||
maxW='100%'
|
||||
pl={[4, 6]}
|
||||
pr={[4, 6]}
|
||||
>
|
||||
{keysToUse?.length &&
|
||||
keysToUse.map((key, idx) => {
|
||||
if (!key?.human) {
|
||||
key = {
|
||||
human: key,
|
||||
key: key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const nextThing = thing[key?.key]
|
||||
const nextThing = thing[key?.key]
|
||||
|
||||
return (
|
||||
<Thingtime
|
||||
key={idx}
|
||||
parent={thing}
|
||||
path={key}
|
||||
thing={nextThing}
|
||||
></Thingtime>
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
return (
|
||||
<Thingtime
|
||||
key={idx}
|
||||
depth={depth + 1}
|
||||
parent={thing}
|
||||
path={key}
|
||||
thing={nextThing}
|
||||
// thing={{ infinite: { yes: true } }}
|
||||
></Thingtime>
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
</Safe>
|
||||
)
|
||||
} else {
|
||||
editableValue = (
|
||||
@ -161,39 +159,45 @@ export const Thingtime = props => {
|
||||
const [showContextMenu, setShowContextMenu] = React.useState(false)
|
||||
|
||||
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])
|
||||
|
||||
const handleMouseEvent = React.useCallback(
|
||||
e => {
|
||||
const target = e?.target
|
||||
// extract cuid from className
|
||||
console.log('nik eh', target?.className, cuid)
|
||||
// extract uuid from className
|
||||
const className = target?.className
|
||||
if (className?.includes(cuid?.current)) {
|
||||
if (className?.includes(uuid?.current)) {
|
||||
setShowContextMenu(e?.type === 'mouseenter')
|
||||
}
|
||||
},
|
||||
[cuid]
|
||||
[uuid]
|
||||
)
|
||||
|
||||
console.log('nik cuid', cuid)
|
||||
|
||||
return safe(
|
||||
<Flex
|
||||
onMouseEnter={handleMouseEvent}
|
||||
onMouseLeave={handleMouseEvent}
|
||||
position='relative'
|
||||
flexDir='column'
|
||||
py={3}
|
||||
{...props}
|
||||
className={`thing-${cuid?.current}`}
|
||||
>
|
||||
{/* {cuid?.current} */}
|
||||
{path}
|
||||
{showContextMenu && contextMenu}
|
||||
{editableValue}
|
||||
{value}
|
||||
</Flex>
|
||||
return (
|
||||
<Safe {...props} depth={depth} uuid={uuid?.current}>
|
||||
<Flex
|
||||
onMouseEnter={handleMouseEvent}
|
||||
onMouseLeave={handleMouseEvent}
|
||||
position='relative'
|
||||
flexDir='column'
|
||||
py={3}
|
||||
w='500px'
|
||||
// minW={depth === 1 ? '120px' : null}
|
||||
maxW='100%'
|
||||
{...props}
|
||||
className={`thing-${uuid?.current}`}
|
||||
>
|
||||
{/* {uuid?.current} */}
|
||||
{path}
|
||||
{showContextMenu && contextMenu}
|
||||
{editableValue}
|
||||
{value}
|
||||
</Flex>
|
||||
</Safe>
|
||||
)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ export const ThingtimeDemo = props => {
|
||||
// return null
|
||||
|
||||
return (
|
||||
<Flex pb={40}>
|
||||
<Flex maxW='100%' pb={40}>
|
||||
<Thingtime thing={demoThing}></Thingtime>
|
||||
</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
|
||||
const thingtime = getThingtime()
|
||||
|
||||
const uuid = props?.uuid
|
||||
|
||||
try {
|
||||
if (
|
||||
typeof window?.thingtime?.things?.count === 'number' &&
|
||||
window?.thingtime?.things?.count > window?.thingtime?.things?.limit
|
||||
typeof thingtime?.things?.count === 'number' &&
|
||||
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
|
||||
}
|
||||
} 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
|
||||
try {
|
||||
window.thingtime = {
|
||||
tmp: {},
|
||||
things: {
|
||||
limit: 999,
|
||||
count: 0,
|
||||
|
||||
const setThingtime = glob => {
|
||||
try {
|
||||
glob.thingtime = {
|
||||
tmp: {},
|
||||
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 { ProfileDrawer } from '~/components/Nav/ProfileDrawer'
|
||||
import { Splash } from '~/components/Splash/Splash'
|
||||
import { ThingtimeDemo } from '~/components/Thingtime/ThingtimeDemo'
|
||||
|
||||
export default function Index () {
|
||||
return (
|
||||
<Flex flexDir='column' alignItems='center' justifyContent='center'>
|
||||
<Flex
|
||||
maxW='100%'
|
||||
flexDir='column'
|
||||
alignItems='center'
|
||||
justifyContent='center'
|
||||
>
|
||||
<Splash></Splash>
|
||||
<ThingtimeDemo></ThingtimeDemo>
|
||||
<ProfileDrawer></ProfileDrawer>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user