feat: main Added some very cool functionality, mainly the ctrl/cmd+p to modify thingtime state, also added new demo data and demo UGC block section so users can essentially edit the website locally for themselves.
This commit is contained in:
parent
cfa05adc94
commit
34cd118437
@ -4,6 +4,49 @@ import { colors } from './colors'
|
||||
export const theme = extendTheme({
|
||||
colors,
|
||||
// edit Input defaultProps
|
||||
styles: {
|
||||
global: {
|
||||
// make all elements padding and margin animate
|
||||
'*': {
|
||||
transition: 'padding 0.2s ease, margin 0.2s ease'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'input:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'textarea:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'select:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'button:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'div:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'a:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
},
|
||||
// make all elements have a transparent focus border
|
||||
'span:focus': {
|
||||
boxShadow: 'none !important',
|
||||
borderColor: 'transparent !important'
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Input: {
|
||||
defaultProps: {
|
||||
|
@ -19,15 +19,63 @@ try {
|
||||
|
||||
const initialThingtime = {
|
||||
nav: {},
|
||||
version: 4
|
||||
}
|
||||
|
||||
const userData = {
|
||||
settings: {
|
||||
showCommander: true,
|
||||
clearCommanderOnToggle: true,
|
||||
clearCommanderContextOnToggle: true
|
||||
},
|
||||
'Bottom Content': {
|
||||
Content: "Edit this to your heart's desire"
|
||||
}
|
||||
}
|
||||
|
||||
export const ThingtimeProvider = (props: any): JSX.Element => {
|
||||
const [thingtime, set] = React.useState(initialThingtime)
|
||||
const [thingtime, set] = React.useState({
|
||||
...initialThingtime,
|
||||
...userData
|
||||
})
|
||||
|
||||
const thingtimeRef = React.useRef(thingtime)
|
||||
|
||||
// get thingtime from localstorage
|
||||
React.useEffect(() => {
|
||||
try {
|
||||
const thingtimeFromLocalStorage = window.localStorage.getItem('thingtime')
|
||||
|
||||
if (thingtimeFromLocalStorage) {
|
||||
const parsed = JSON.parse(thingtimeFromLocalStorage)
|
||||
if (parsed) {
|
||||
const invalidLocalStorage =
|
||||
!parsed.version || parsed.version < initialThingtime.version
|
||||
if (!invalidLocalStorage) {
|
||||
set(parsed)
|
||||
} else {
|
||||
const newThingtime = {
|
||||
...parsed,
|
||||
...initialThingtime
|
||||
}
|
||||
set(newThingtime)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('There was an error getting thingtime from localStorage')
|
||||
}
|
||||
}, [])
|
||||
|
||||
React.useEffect(() => {
|
||||
thingtimeRef.current = thingtime
|
||||
|
||||
try {
|
||||
window.localStorage.setItem('thingtime', JSON.stringify(thingtime))
|
||||
} catch (err) {
|
||||
console.error('There was an error saving thingtime to localStorage')
|
||||
}
|
||||
}, [thingtime])
|
||||
|
||||
const setThingtime = React.useCallback(
|
||||
(path, value) => {
|
||||
@ -41,12 +89,22 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
||||
|
||||
path = sanitise(path)
|
||||
|
||||
// log the path and value
|
||||
console.log('nik ThingtimeProvider setThingtime path', path)
|
||||
console.log('nik ThingtimeProvider setThingtime value', value)
|
||||
|
||||
smarts.setsmart(newThingtime, path, value)
|
||||
|
||||
// subtract last path part from dot delimitted path
|
||||
// prop1.prop2.prop3 => prop1.prop2
|
||||
const pathParts = path.split('.')
|
||||
pathParts.pop()
|
||||
const parentPath = pathParts.join('.')
|
||||
|
||||
if (parentPath?.length) {
|
||||
const parent = smarts.getsmart(newThingtime, parentPath)
|
||||
|
||||
const newParent = Array.isArray(parent) ? [...parent] : { ...parent }
|
||||
|
||||
smarts.setsmart(newThingtime, parentPath, newParent)
|
||||
}
|
||||
|
||||
set(newThingtime)
|
||||
},
|
||||
[thingtime]
|
||||
@ -55,7 +113,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
||||
const getThingtime = React.useCallback(
|
||||
(...args) => {
|
||||
const path = args[0]
|
||||
if (path === 'thingtime' || path === 'tt' || !path) {
|
||||
if (path === 'thingtime' || path === 'tt' || path === '.' || !path) {
|
||||
return thingtime
|
||||
}
|
||||
return smarts.getsmart(thingtime, path)
|
||||
@ -83,7 +141,8 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
||||
const value = {
|
||||
thingtime,
|
||||
setThingtime,
|
||||
getThingtime
|
||||
getThingtime,
|
||||
thingtimeRef
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -5,97 +5,202 @@ import { Thingtime } from '../Thingtime/Thingtime'
|
||||
import { sanitise } from '~/functions/path'
|
||||
|
||||
export const Commander = props => {
|
||||
const { thingtime, setThingtime, getThingtime } = useThingtime()
|
||||
|
||||
const [contextPath, setContextPath] = React.useState()
|
||||
|
||||
const [showContext, setShowContext] = React.useState(false)
|
||||
|
||||
const contextValue = React.useMemo(() => {
|
||||
console.log('thingtime updated!')
|
||||
const ret = getThingtime(contextPath)
|
||||
console.log('nik ret', ret)
|
||||
return ret
|
||||
}, [contextPath, getThingtime])
|
||||
|
||||
const showCommander = React.useMemo(() => {
|
||||
console.log(
|
||||
'nik thingtime?.settings?.showCommander',
|
||||
thingtime?.settings?.showCommander
|
||||
)
|
||||
return thingtime?.settings?.showCommander
|
||||
}, [thingtime?.settings?.showCommander])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (thingtime?.settings?.clearCommanderOnToggle) {
|
||||
setValue('')
|
||||
}
|
||||
if (showCommander) {
|
||||
inputRef?.current?.focus?.()
|
||||
}
|
||||
}, [showCommander, thingtime])
|
||||
const { thingtime, setThingtime, getThingtime, thingtimeRef } = useThingtime()
|
||||
|
||||
const inputRef = React.useRef()
|
||||
|
||||
const [value, setValue] = React.useState('')
|
||||
|
||||
const [contextPath, setContextPath] = React.useState()
|
||||
|
||||
const [showContext, setShowContextState] = React.useState(false)
|
||||
|
||||
const setShowContext = React.useCallback(
|
||||
(value, from) => {
|
||||
setShowContextState(value)
|
||||
},
|
||||
[setShowContextState]
|
||||
)
|
||||
const [suggestions, setSuggestions] = React.useState([])
|
||||
|
||||
const contextValue = React.useMemo(() => {
|
||||
console.log('thingtime updated!')
|
||||
const ret = getThingtime(contextPath)
|
||||
return ret
|
||||
}, [contextPath, getThingtime])
|
||||
|
||||
const showCommander = React.useMemo(() => {
|
||||
return thingtime?.settings?.showCommander
|
||||
}, [thingtime?.settings?.showCommander])
|
||||
|
||||
// watch value
|
||||
React.useEffect(() => {
|
||||
if (!value?.length) {
|
||||
setSuggestions([])
|
||||
}
|
||||
}, [value])
|
||||
|
||||
// showCommander useEffect
|
||||
React.useEffect(() => {
|
||||
if (showCommander) {
|
||||
inputRef?.current?.focus?.()
|
||||
} else {
|
||||
if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) {
|
||||
setValue('')
|
||||
}
|
||||
if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) {
|
||||
setShowContext(false, 'showCommander useEffect')
|
||||
}
|
||||
}
|
||||
}, [showCommander, thingtimeRef, setShowContext])
|
||||
|
||||
const onChange = React.useCallback(e => {
|
||||
setValue(e.target.value)
|
||||
}, [])
|
||||
|
||||
const validSetters = React.useMemo(() => {
|
||||
return ['=', ' is ']
|
||||
}, [])
|
||||
|
||||
const command = React.useMemo(() => {
|
||||
const sanitizedCommand = sanitise(value)
|
||||
|
||||
if (sanitizedCommand?.includes(validSetters[0])) {
|
||||
const indexOfSplitter = sanitizedCommand?.indexOf(validSetters[0])
|
||||
const [pathRaw, valRaw] = [
|
||||
sanitizedCommand?.slice(0, indexOfSplitter),
|
||||
sanitizedCommand?.slice(indexOfSplitter + validSetters[0]?.length)
|
||||
]
|
||||
return [pathRaw?.trim(), valRaw?.trim()]
|
||||
} else if (sanitizedCommand?.includes(validSetters[1])) {
|
||||
const indexOfSplitter = sanitizedCommand?.indexOf(validSetters[1])
|
||||
const [pathRaw, valRaw] = [
|
||||
sanitizedCommand?.slice(0, indexOfSplitter),
|
||||
sanitizedCommand?.slice(indexOfSplitter + validSetters[1]?.length)
|
||||
]
|
||||
return [pathRaw?.trim(), valRaw?.trim()]
|
||||
}
|
||||
return [sanitizedCommand]
|
||||
}, [value, validSetters])
|
||||
|
||||
const commandContainsPath = React.useMemo(() => {
|
||||
const suggestionsIncludesSubstring = suggestions?.find(suggestion => {
|
||||
return command?.includes(suggestion)
|
||||
})
|
||||
return suggestionsIncludesSubstring
|
||||
}, [suggestions, command])
|
||||
|
||||
const commandPath = React.useMemo(() => {
|
||||
return command?.[0]
|
||||
}, [command])
|
||||
|
||||
const commandValue = React.useMemo(() => {
|
||||
return command?.[1]
|
||||
}, [command])
|
||||
|
||||
const validQuotations = React.useMemo(() => {
|
||||
return ['"', "'"]
|
||||
}, [])
|
||||
|
||||
const escapedCommandValue = React.useMemo(() => {
|
||||
// replace quotations with escaped quoations except for first and last quotation
|
||||
const startingQuotation = commandValue?.[0]
|
||||
const endingQuotation = commandValue?.[commandValue?.length - 1]
|
||||
const isQuoted =
|
||||
validQuotations?.includes(startingQuotation) &&
|
||||
validQuotations?.includes(endingQuotation)
|
||||
const restOfCommandValue = isQuoted
|
||||
? commandValue?.slice(1, commandValue?.length - 1)
|
||||
: commandValue
|
||||
const escaped = restOfCommandValue
|
||||
?.replace(/"/g, '\\"')
|
||||
?.replace(/'/g, "\\'")
|
||||
const ret = `"${escaped}"`
|
||||
return ret
|
||||
}, [commandValue, validQuotations])
|
||||
|
||||
const commandIsAction = React.useMemo(() => {
|
||||
return commandPath && commandValue
|
||||
}, [commandPath, commandValue])
|
||||
|
||||
// thingtime changes update suggestions
|
||||
React.useEffect(() => {
|
||||
// when thingtime changes, update suggestions
|
||||
// with all flattened key path values recursively
|
||||
|
||||
if (value?.length) {
|
||||
const suggestions = ['tt', 'thingtime', '.']
|
||||
const recurse = (obj, path) => {
|
||||
Object.keys(obj).forEach(key => {
|
||||
const val = obj[key]
|
||||
const newPath = path ? `${path}.${key}` : key
|
||||
if (typeof val === 'object') {
|
||||
suggestions.push(key)
|
||||
recurse(val, newPath)
|
||||
} else {
|
||||
suggestions.push(newPath)
|
||||
}
|
||||
})
|
||||
}
|
||||
recurse(thingtime, '')
|
||||
|
||||
if (commandPath) {
|
||||
const filteredSuggestions = suggestions.filter((suggestion, i) => {
|
||||
return suggestion?.toLowerCase()?.includes(commandPath?.toLowerCase())
|
||||
})
|
||||
if (!filteredSuggestions?.includes(commandPath)) {
|
||||
const adjustedSuggestions = [commandPath, ...filteredSuggestions]
|
||||
setSuggestions(adjustedSuggestions)
|
||||
} else {
|
||||
setSuggestions(filteredSuggestions)
|
||||
}
|
||||
} else {
|
||||
setSuggestions(suggestions)
|
||||
}
|
||||
|
||||
// if (value) {
|
||||
// setShowContext(true, 'Thingtime changes update suggestions')
|
||||
// }
|
||||
}
|
||||
}, [thingtime, value, commandPath, setShowContext])
|
||||
|
||||
const onEnter = React.useCallback(
|
||||
props => {
|
||||
// if first characters of value equal tt. then run command
|
||||
// or if first character is a dot then run command
|
||||
try {
|
||||
const isTT = value?.slice(0, 3) === 'tt.'
|
||||
const isDot = value?.slice(0, 1) === '.'
|
||||
const executeCommand = isTT || isDot
|
||||
if (executeCommand) {
|
||||
const command = isTT ? value?.slice(3) : value?.slice(1)
|
||||
const sanitisedCommand = sanitise(command)
|
||||
console.log('nik command', command)
|
||||
|
||||
console.log('setting to thingtime', thingtime)
|
||||
|
||||
const commandIsSetter = command?.includes('=')
|
||||
|
||||
if (commandIsSetter) {
|
||||
// nothing
|
||||
const [pathRaw, valRaw] = sanitisedCommand?.split('=')
|
||||
const path = pathRaw.trim()
|
||||
const val = valRaw.trim()
|
||||
console.log('nik path', path)
|
||||
console.log('nik val', val)
|
||||
try {
|
||||
const realVal = eval(val)
|
||||
console.log('nik realVal', realVal)
|
||||
setThingtime(path, realVal)
|
||||
} catch (err) {
|
||||
console.log('setThingtime errored in Commander', err)
|
||||
}
|
||||
// setContextPath(path)
|
||||
} else {
|
||||
const val = getThingtime(sanitisedCommand)
|
||||
|
||||
console.log('setting to val', val)
|
||||
|
||||
setContextPath(sanitisedCommand)
|
||||
setShowContext(true)
|
||||
if (commandIsAction) {
|
||||
// nothing
|
||||
try {
|
||||
const fn = `() => { return ${escapedCommandValue} }`
|
||||
const evalFn = eval(fn)
|
||||
const realVal = evalFn()
|
||||
setThingtime(commandPath, realVal)
|
||||
} catch (err) {
|
||||
console.log('setThingtime errored in Commander', err)
|
||||
}
|
||||
} else if (commandContainsPath) {
|
||||
setContextPath(commandPath)
|
||||
setShowContext(true, 'commandContainsPath check')
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Caught error on commander onEnter', err)
|
||||
}
|
||||
},
|
||||
[value, thingtime, getThingtime, setThingtime]
|
||||
[
|
||||
setShowContext,
|
||||
escapedCommandValue,
|
||||
setThingtime,
|
||||
commandIsAction,
|
||||
commandPath,
|
||||
commandContainsPath
|
||||
]
|
||||
)
|
||||
|
||||
// trigger on enter
|
||||
const onKeyDown = React.useCallback(
|
||||
e => {
|
||||
if (e.key === 'Enter') {
|
||||
console.log('nik enter')
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
onEnter({ e })
|
||||
@ -105,7 +210,7 @@ export const Commander = props => {
|
||||
// )
|
||||
}
|
||||
},
|
||||
[thingtime?.settings?.showCommander, onEnter]
|
||||
[onEnter]
|
||||
)
|
||||
|
||||
const openCommander = React.useCallback(() => {
|
||||
@ -116,7 +221,7 @@ export const Commander = props => {
|
||||
setThingtime('settings.showCommander', false)
|
||||
setShowContext(false)
|
||||
setContextPath(undefined)
|
||||
}, [setThingtime])
|
||||
}, [setThingtime, setShowContext])
|
||||
|
||||
const toggleCommander = React.useCallback(() => {
|
||||
if (thingtime?.settings?.showCommander) {
|
||||
@ -129,7 +234,6 @@ export const Commander = props => {
|
||||
React.useEffect(() => {
|
||||
const keyListener = (e: any) => {
|
||||
if (e?.metaKey && e?.code === 'KeyP') {
|
||||
console.log('nik heard event')
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
toggleCommander()
|
||||
@ -145,44 +249,114 @@ export const Commander = props => {
|
||||
return () => {
|
||||
window.removeEventListener('keydown', keyListener)
|
||||
}
|
||||
}, [setThingtime, thingtime])
|
||||
}, [setThingtime, thingtime, toggleCommander, closeCommander])
|
||||
|
||||
const selectSuggestion = React.useCallback(
|
||||
suggestion => {
|
||||
setValue(suggestion)
|
||||
setContextPath(suggestion)
|
||||
setShowContext(true, 'Select suggestion')
|
||||
},
|
||||
[setValue, setContextPath, setShowContext]
|
||||
)
|
||||
|
||||
const excludedSuggestions = React.useMemo(() => {
|
||||
return ['.']
|
||||
}, [])
|
||||
|
||||
const renderedSuggestions = React.useMemo(() => {
|
||||
return suggestions?.filter(suggestion => {
|
||||
return !excludedSuggestions?.includes(suggestion)
|
||||
})
|
||||
}, [suggestions, excludedSuggestions])
|
||||
|
||||
const mobileVW = React.useMemo(() => {
|
||||
return 'calc(100vw - 45px)'
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Center
|
||||
<Flex
|
||||
id='commander'
|
||||
display={showCommander ? 'flex' : 'none'}
|
||||
display={['flex', showCommander ? 'flex' : 'none']}
|
||||
justifyContent={['flex-start', 'center']}
|
||||
// zIndex={99999}
|
||||
// position='fixed'
|
||||
// top='100px'
|
||||
pointerEvents={'none'}
|
||||
position='absolute'
|
||||
h='100%'
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
py={1}
|
||||
px={1}
|
||||
maxW='100%'
|
||||
>
|
||||
<Center
|
||||
display={showContext ? 'flex' : 'none'}
|
||||
<Flex
|
||||
alignItems={['flex-start', 'center']}
|
||||
position='absolute'
|
||||
top={'100%'}
|
||||
maxH='90vh'
|
||||
overflowY='scroll'
|
||||
left={0}
|
||||
right={0}
|
||||
h='auto'
|
||||
mt={2}
|
||||
mx={1}
|
||||
maxW='100%'
|
||||
borderRadius={'12px'}
|
||||
flexDir='column'
|
||||
>
|
||||
<Flex p={3} borderRadius={'12px'} bg='grey'>
|
||||
<Flex
|
||||
display={renderedSuggestions?.length ? 'flex' : 'none'}
|
||||
w={['100%', '400px']}
|
||||
maxW={'100%'}
|
||||
bg='grey'
|
||||
borderRadius={'12px'}
|
||||
flexDir='column'
|
||||
id='commander-suggestions'
|
||||
py={3}
|
||||
mb={3}
|
||||
pointerEvents={'all'}
|
||||
>
|
||||
{renderedSuggestions.map((suggestion, i) => {
|
||||
return (
|
||||
<Flex
|
||||
cursor='pointer'
|
||||
px={4}
|
||||
_hover={{
|
||||
bg: 'greys.medium'
|
||||
}}
|
||||
key={i}
|
||||
onClick={() => selectSuggestion(suggestion)}
|
||||
>
|
||||
{suggestion}
|
||||
</Flex>
|
||||
)
|
||||
})}
|
||||
</Flex>
|
||||
<Flex
|
||||
display={showContext ? 'flex' : 'none'}
|
||||
maxW='100%'
|
||||
py={3}
|
||||
borderRadius={'12px'}
|
||||
bg='grey'
|
||||
pointerEvents={'all'}
|
||||
>
|
||||
<Thingtime thing={contextValue}></Thingtime>
|
||||
</Flex>
|
||||
</Center>
|
||||
</Flex>
|
||||
<Center
|
||||
position='relative'
|
||||
bg='grey'
|
||||
w='400px'
|
||||
w={['100%', '400px']}
|
||||
maxW={[mobileVW, '100%']}
|
||||
h='100%'
|
||||
outline={'none'}
|
||||
overflow='hidden'
|
||||
p={'1px'}
|
||||
borderRadius={'6px'}
|
||||
pointerEvents={'all'}
|
||||
>
|
||||
<Box
|
||||
position='absolute'
|
||||
@ -218,6 +392,6 @@ export const Commander = props => {
|
||||
placeholder={"What's on your mind?"}
|
||||
></Input>
|
||||
</Center>
|
||||
</Center>
|
||||
</Flex>
|
||||
)
|
||||
}
|
||||
|
@ -13,10 +13,18 @@ export const Nav = props => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box position='fixed' top={0} left={0} right={0} zIndex={999}>
|
||||
<Box
|
||||
position='fixed'
|
||||
maxW='100vw'
|
||||
top={0}
|
||||
left={0}
|
||||
right={0}
|
||||
zIndex={999}
|
||||
>
|
||||
<Flex
|
||||
as='nav'
|
||||
w='100%'
|
||||
maxW='100%'
|
||||
alignItems={'center'}
|
||||
position='relative'
|
||||
justifyContent='center'
|
||||
@ -31,6 +39,7 @@ export const Nav = props => {
|
||||
ml={'auto'}
|
||||
w='25px'
|
||||
h='25px'
|
||||
cursor='pointer'
|
||||
onClick={toggleProfileDrawer}
|
||||
bg={'rgba(0,0,0,0.1)'}
|
||||
sx={{}}
|
||||
|
@ -10,6 +10,10 @@ export const Thingtime = props => {
|
||||
|
||||
const [uuid, setUuid] = React.useState()
|
||||
|
||||
const pl = React.useMemo(() => {
|
||||
return props?.pl || [4, 6]
|
||||
}, [props?.pl])
|
||||
|
||||
// will only run on the client
|
||||
React.useEffect(() => {
|
||||
setUuid(Math.random().toString(36).substring(7))
|
||||
@ -17,14 +21,6 @@ export const Thingtime = props => {
|
||||
|
||||
const { thingtime } = useThingtime()
|
||||
|
||||
React.useEffect(() => {
|
||||
// console.log('nik thingtime?.test changed', thingtime?.test)
|
||||
}, [thingtime?.test])
|
||||
|
||||
React.useEffect(() => {
|
||||
// console.log('nik thingtime changed', thingtime)
|
||||
}, [thingtime])
|
||||
|
||||
const depth = React.useMemo(() => {
|
||||
return props?.depth || 1
|
||||
}, [props?.depth])
|
||||
@ -44,7 +40,6 @@ export const Thingtime = props => {
|
||||
const keys = React.useMemo(() => {
|
||||
if (validKeyTypes?.includes(typeof thing)) {
|
||||
const keysRet = Object.keys(thing)
|
||||
console.log('nik keysRet', keysRet)
|
||||
return keysRet
|
||||
} else {
|
||||
return []
|
||||
@ -57,12 +52,18 @@ export const Thingtime = props => {
|
||||
|
||||
const renderableValue = React.useMemo(() => {
|
||||
if (type === 'string') {
|
||||
if (!thing) {
|
||||
return 'Empty string'
|
||||
}
|
||||
return thing
|
||||
} else if (type === 'number') {
|
||||
return thing
|
||||
} else if (type === 'boolean') {
|
||||
return thing ? 'true' : 'false'
|
||||
} else if (type === 'object') {
|
||||
if (thing === null) {
|
||||
return 'null'
|
||||
}
|
||||
if (!keys?.length) {
|
||||
return 'Empty object'
|
||||
}
|
||||
@ -78,7 +79,7 @@ export const Thingtime = props => {
|
||||
return 'Circular reference in object.'
|
||||
}
|
||||
} else {
|
||||
return null
|
||||
return 'Undefined'
|
||||
}
|
||||
}, [thing, type])
|
||||
|
||||
@ -140,8 +141,7 @@ export const Thingtime = props => {
|
||||
// w={['200px', '500px']}
|
||||
maxW='100%'
|
||||
py={props?.path ? 3 : 0}
|
||||
pl={[4, 6]}
|
||||
// pr={[4, 6]}
|
||||
pl={props?.valuePl}
|
||||
>
|
||||
{keysToUse?.length &&
|
||||
keysToUse.map((key, idx) => {
|
||||
@ -162,6 +162,7 @@ export const Thingtime = props => {
|
||||
path={key}
|
||||
thing={nextThing}
|
||||
// thing={{ infinite: { yes: true } }}
|
||||
valuePl={pl}
|
||||
></Thingtime>
|
||||
)
|
||||
})}
|
||||
@ -175,6 +176,7 @@ export const Thingtime = props => {
|
||||
border='none'
|
||||
outline={'none'}
|
||||
py={2}
|
||||
pl={pl}
|
||||
fontSize={'20px'}
|
||||
>
|
||||
{renderableValue}
|
||||
@ -184,7 +186,7 @@ export const Thingtime = props => {
|
||||
}
|
||||
|
||||
const contextMenu = (
|
||||
<Flex userSelect={'none'} position='absolute' top={0} right={0}>
|
||||
<Flex pr={4} userSelect={'none'} position='absolute' top={0} right={0}>
|
||||
Settings
|
||||
</Flex>
|
||||
)
|
||||
@ -193,7 +195,7 @@ export const Thingtime = props => {
|
||||
|
||||
const path = React.useMemo(() => {
|
||||
return (
|
||||
<Flex maxW='100%' wordBreak={'break-all'} fontSize='12px'>
|
||||
<Flex maxW='100%' pl={pl} wordBreak={'break-all'} fontSize='12px'>
|
||||
{props?.path?.human}
|
||||
</Flex>
|
||||
)
|
||||
@ -227,7 +229,7 @@ export const Thingtime = props => {
|
||||
>
|
||||
{/* {uuid?.current} */}
|
||||
{path}
|
||||
{showContextMenu && contextMenu}
|
||||
{/* {showContextMenu && contextMenu} */}
|
||||
{editableValue}
|
||||
{value}
|
||||
</Flex>
|
||||
|
@ -4,19 +4,34 @@ import { Flex } from '@chakra-ui/react'
|
||||
|
||||
export const ThingtimeDemo = props => {
|
||||
const thing = {
|
||||
name: 'thing',
|
||||
description: 'thing description',
|
||||
image: 'thing image',
|
||||
price: 100,
|
||||
quantity: 1,
|
||||
id: 1,
|
||||
nested: {
|
||||
Suggestion: 'Press ctrl/cmd + P',
|
||||
Name: 'thingtime',
|
||||
Description: `
|
||||
Thing Time is a versatile online platform that empowers users to organize, customize, and manage different types of data. By generalizing the concept of social media feeds, Thing Time allows users to switch between various data schemas, essentially providing them with personalized feeds and organizational tools. It's like a combination of Facebook, Twitter, and Evernote, but with the user in control of what kind of data they want to see and manage. Whether it's social posts, marketplace listings, or personal notes, Thing Time puts the power of data organization and customization in the user’s hands.
|
||||
`,
|
||||
'Image URL': 'https://google.com/images',
|
||||
Price: '$100',
|
||||
QTY: 1,
|
||||
ID: 123,
|
||||
Nested: {
|
||||
data: {
|
||||
is: {
|
||||
fun: "Isn't it?"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Array: ['one', 'two', 'three'],
|
||||
'Array of Objects': [
|
||||
{
|
||||
name: 'one'
|
||||
},
|
||||
{
|
||||
name: 'two'
|
||||
},
|
||||
{
|
||||
name: 'three'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
const [demoThing, setDemoThing] = React.useState(thing)
|
||||
|
@ -13,7 +13,7 @@ const getGlobal = () => {
|
||||
export const useThingtime = (props?: any) => {
|
||||
const value = useContext(ThingtimeContext)
|
||||
|
||||
const { thingtime, setThingtime, getThingtime } = value
|
||||
const { thingtime, setThingtime, getThingtime, thingtimeRef } = value
|
||||
|
||||
return value
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
export const sanitise = str => {
|
||||
const isTT = str?.slice(0, 3) === 'tt.'
|
||||
const isThingtime = str?.slice(0, 9) === 'thingtime.'
|
||||
const isDot = str?.slice(0, 1) === '.'
|
||||
|
||||
if (isTT) {
|
||||
str = str?.slice(3)
|
||||
@ -9,5 +10,9 @@ export const sanitise = str => {
|
||||
str = str?.slice(9)
|
||||
}
|
||||
|
||||
if (isDot) {
|
||||
str = str?.slice(1)
|
||||
}
|
||||
|
||||
return str
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
import { Flex } from '@chakra-ui/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'
|
||||
|
||||
export default function Index () {
|
||||
const { thingtime } = useThingtime()
|
||||
|
||||
return (
|
||||
<Flex
|
||||
maxW='100%'
|
||||
@ -13,6 +17,7 @@ export default function Index () {
|
||||
>
|
||||
<Splash></Splash>
|
||||
<ThingtimeDemo></ThingtimeDemo>
|
||||
<Thingtime mb={200} thing={thingtime['Bottom Content']}></Thingtime>
|
||||
<ProfileDrawer></ProfileDrawer>
|
||||
</Flex>
|
||||
)
|
||||
|
@ -11,13 +11,13 @@ try {
|
||||
// nothing
|
||||
}
|
||||
|
||||
const babel = require('@babel/standalone')
|
||||
// const babel = require('@babel/standalone')
|
||||
|
||||
babel.template = require('@babel/template').default
|
||||
babel.t = require('@babel/types')
|
||||
babel.generator = require('@babel/generator').default
|
||||
babel.babylon = require('@babel/parser')
|
||||
babel.prettier = require('prettier')
|
||||
// babel.template = require('@babel/template').default
|
||||
// babel.t = require('@babel/types')
|
||||
// babel.generator = require('@babel/generator').default
|
||||
// babel.babylon = require('@babel/parser')
|
||||
// babel.prettier = require('prettier')
|
||||
|
||||
const objList = []
|
||||
const stringList = []
|
||||
@ -38,8 +38,10 @@ const stringList = []
|
||||
// import prettier from 'prettier'
|
||||
// babel.prettier = prettier
|
||||
|
||||
export const babel = () => {}
|
||||
export const local = {}
|
||||
export const t = babel?.t
|
||||
export const t = () => {}
|
||||
// export const t = babel?.t
|
||||
|
||||
export const getBabel = () => {
|
||||
return babel
|
||||
|
Loading…
Reference in New Issue
Block a user