feat: feature/mvp-sprint-1 Added type wrapping, custom types, new child types, commander address bar behaviour
This commit is contained in:
parent
168035201d
commit
a69c4067df
@ -30,7 +30,207 @@ try {
|
|||||||
|
|
||||||
const force = {
|
const force = {
|
||||||
settings: {
|
settings: {
|
||||||
undoLimit: 999,
|
types: {
|
||||||
|
javascript: {
|
||||||
|
any: {
|
||||||
|
type: "any",
|
||||||
|
value: () => {
|
||||||
|
return null
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: {
|
||||||
|
type: "object",
|
||||||
|
value: () => {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
type: "array",
|
||||||
|
value: () => {
|
||||||
|
return []
|
||||||
|
},
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
type: "string",
|
||||||
|
value: () => {
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
type: "number",
|
||||||
|
value: () => {
|
||||||
|
return 0
|
||||||
|
},
|
||||||
|
},
|
||||||
|
boolean: {
|
||||||
|
type: "boolean",
|
||||||
|
value: () => {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
function: {
|
||||||
|
type: "function",
|
||||||
|
value: () => {
|
||||||
|
return () => {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
custom: {
|
||||||
|
"Thingtime Logo": {
|
||||||
|
type: "chakra",
|
||||||
|
value: {
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Box",
|
||||||
|
props: {
|
||||||
|
fontSize: 12,
|
||||||
|
},
|
||||||
|
rawChildren: ["🌈 Thingtime"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Violet Container Centered": {
|
||||||
|
name: "Violet Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "💜",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Violet Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#AB47BC",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Indigo Container Centered": {
|
||||||
|
name: "Indigo Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "🩷",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Indigo Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#5C6BC0",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Blue Container Centered": {
|
||||||
|
name: "Blue Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "💙",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Blue Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#42A5F5",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Green Container Centered": {
|
||||||
|
name: "Green Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "💚",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Green Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#66BB6A",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Yellow Container Centered": {
|
||||||
|
name: "Yellow Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "💛",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Yellow Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#FFEE58",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Orange Container Centered": {
|
||||||
|
name: "Orange Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "🧡",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Orange Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#FF7043",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Red Container Centered": {
|
||||||
|
name: "Red Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
icon: "❤️",
|
||||||
|
wrap: "children",
|
||||||
|
value: {
|
||||||
|
name: "Red Container Centered",
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Center",
|
||||||
|
props: {
|
||||||
|
bg: "#C62828",
|
||||||
|
padding: 4,
|
||||||
|
borderRadius: 12,
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Left Aligned": {
|
||||||
|
type: "chakra",
|
||||||
|
value: {
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Flex",
|
||||||
|
props: {
|
||||||
|
mr: "auto",
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Right Aligned": {
|
||||||
|
type: "chakra",
|
||||||
|
value: {
|
||||||
|
type: "chakra",
|
||||||
|
chakra: "Flex",
|
||||||
|
props: {
|
||||||
|
ml: "auto",
|
||||||
|
},
|
||||||
|
children: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// undoLimit: 999,
|
||||||
// commander: {
|
// commander: {
|
||||||
// nav: {
|
// nav: {
|
||||||
// commanderActive: false,
|
// commanderActive: false,
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import ClickAwayListener from "react-click-away-listener"
|
import ClickAwayListener from "react-click-away-listener"
|
||||||
import { Center, Flex, Input } from "@chakra-ui/react"
|
import { Center, Flex, Input } from "@chakra-ui/react"
|
||||||
|
import { useLocation } from "@remix-run/react"
|
||||||
import Fuse from "fuse.js"
|
import Fuse from "fuse.js"
|
||||||
|
|
||||||
import { Rainbow } from "../Rainbow/Rainbow"
|
import { Rainbow } from "../Rainbow/Rainbow"
|
||||||
@ -8,12 +9,15 @@ import { Thingtime } from "../Thingtime/Thingtime"
|
|||||||
import { useThingtime } from "../Thingtime/useThingtime"
|
import { useThingtime } from "../Thingtime/useThingtime"
|
||||||
|
|
||||||
import { sanitise } from "~/functions/sanitise"
|
import { sanitise } from "~/functions/sanitise"
|
||||||
|
import { usePath } from "~/hooks/usePath"
|
||||||
import { getParentPath } from "~/smarts"
|
import { getParentPath } from "~/smarts"
|
||||||
|
|
||||||
export const CommanderV1 = (props) => {
|
export const CommanderV1 = (props) => {
|
||||||
const { thingtime, setThingtime, getThingtime, thingtimeRef, paths } =
|
const { thingtime, setThingtime, getThingtime, thingtimeRef, paths } =
|
||||||
useThingtime()
|
useThingtime()
|
||||||
|
|
||||||
|
const { mode, changePath } = usePath()
|
||||||
|
|
||||||
const commanderId = React.useMemo(() => {
|
const commanderId = React.useMemo(() => {
|
||||||
return props?.id || "global"
|
return props?.id || "global"
|
||||||
}, [props?.id])
|
}, [props?.id])
|
||||||
@ -36,7 +40,7 @@ export const CommanderV1 = (props) => {
|
|||||||
const [active, setActive] = React.useState(false)
|
const [active, setActive] = React.useState(false)
|
||||||
const [contextPath, setContextPath] = React.useState()
|
const [contextPath, setContextPath] = React.useState()
|
||||||
|
|
||||||
const mode = React.useMemo(() => {
|
const commanderMode = React.useMemo(() => {
|
||||||
return props?.mode || "value"
|
return props?.mode || "value"
|
||||||
}, [props?.mode])
|
}, [props?.mode])
|
||||||
|
|
||||||
@ -318,8 +322,13 @@ export const CommanderV1 = (props) => {
|
|||||||
// const newValue = setThingtime(commandPath, prevValue)
|
// const newValue = setThingtime(commandPath, prevValue)
|
||||||
|
|
||||||
console.log("Setting context path", commandPath)
|
console.log("Setting context path", commandPath)
|
||||||
setContextPath(commandPath)
|
// setContextPath(commandPath)
|
||||||
setShowContext(true, "commandContainsPath check")
|
|
||||||
|
changePath({
|
||||||
|
path: commandPath,
|
||||||
|
})
|
||||||
|
|
||||||
|
// setShowContext(true, "commandContainsPath check")
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Caught error on commander onEnter", err)
|
console.error("Caught error on commander onEnter", err)
|
||||||
@ -328,6 +337,8 @@ export const CommanderV1 = (props) => {
|
|||||||
}, [
|
}, [
|
||||||
hoveredSuggestion,
|
hoveredSuggestion,
|
||||||
selectSuggestion,
|
selectSuggestion,
|
||||||
|
mode,
|
||||||
|
changePath,
|
||||||
commanderActive,
|
commanderActive,
|
||||||
commandIsAction,
|
commandIsAction,
|
||||||
commandPath,
|
commandPath,
|
||||||
@ -421,9 +432,9 @@ export const CommanderV1 = (props) => {
|
|||||||
<ClickAwayListener onClickAway={closeCommander}>
|
<ClickAwayListener onClickAway={closeCommander}>
|
||||||
<Flex
|
<Flex
|
||||||
position="absolute"
|
position="absolute"
|
||||||
|
zIndex={9999}
|
||||||
top={0}
|
top={0}
|
||||||
right={0}
|
right={0}
|
||||||
// zIndex={99999}
|
|
||||||
// position='fixed'
|
// position='fixed'
|
||||||
// top='100px'
|
// top='100px'
|
||||||
left={0}
|
left={0}
|
||||||
@ -438,6 +449,7 @@ export const CommanderV1 = (props) => {
|
|||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
position="absolute"
|
position="absolute"
|
||||||
|
zIndex={9999}
|
||||||
top="100%"
|
top="100%"
|
||||||
right={0}
|
right={0}
|
||||||
left={0}
|
left={0}
|
||||||
@ -528,6 +540,7 @@ export const CommanderV1 = (props) => {
|
|||||||
>
|
>
|
||||||
<Center
|
<Center
|
||||||
position="relative"
|
position="relative"
|
||||||
|
zIndex={9999}
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
width={["100%", "400px"]}
|
width={["100%", "400px"]}
|
||||||
maxWidth={[mobileVW, "100%"]}
|
maxWidth={[mobileVW, "100%"]}
|
||||||
@ -553,6 +566,7 @@ export const CommanderV1 = (props) => {
|
|||||||
color: "greys.dark",
|
color: "greys.dark",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
zIndex={9999}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
background="grey"
|
background="grey"
|
||||||
@ -570,6 +584,7 @@ export const CommanderV1 = (props) => {
|
|||||||
{!props?.rainbow && (
|
{!props?.rainbow && (
|
||||||
<Center
|
<Center
|
||||||
position="relative"
|
position="relative"
|
||||||
|
zIndex={9999}
|
||||||
overflow="hidden"
|
overflow="hidden"
|
||||||
width={["100%", "400px"]}
|
width={["100%", "400px"]}
|
||||||
maxWidth={[mobileVW, "100%"]}
|
maxWidth={[mobileVW, "100%"]}
|
||||||
@ -588,6 +603,7 @@ export const CommanderV1 = (props) => {
|
|||||||
color: "greys.dark",
|
color: "greys.dark",
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
zIndex={9999}
|
||||||
width="100%"
|
width="100%"
|
||||||
height="100%"
|
height="100%"
|
||||||
background="grey"
|
background="grey"
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import { Center } from "@chakra-ui/react"
|
import { Center } from "@chakra-ui/react"
|
||||||
|
import emojis from "emojis-list"
|
||||||
|
|
||||||
export const Icon = (props) => {
|
export const Icon = (props) => {
|
||||||
const name = props?.name
|
const name = props?.name
|
||||||
@ -183,6 +184,28 @@ export const Icon = (props) => {
|
|||||||
}
|
}
|
||||||
return "🌀"
|
return "🌀"
|
||||||
}
|
}
|
||||||
|
if (["function", "lambda"]?.includes(name)) {
|
||||||
|
return "📐"
|
||||||
|
}
|
||||||
|
if (["pin", "pinned", "located"]?.includes(name)) {
|
||||||
|
return "📌"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (["wrap", "wrapped"]?.includes(name)) {
|
||||||
|
return "🎁"
|
||||||
|
// return "🎀"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emojis?.includes(name)) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
if (["random"]?.includes(name)) {
|
||||||
|
return emojis[Math.floor(Math.random() * emojis.length)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// question mark
|
||||||
|
return "❓"
|
||||||
}, [name])
|
}, [name])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -7,6 +7,11 @@ import { ProfileDrawer } from "../Nav/ProfileDrawer"
|
|||||||
export const Main = (props) => {
|
export const Main = (props) => {
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
|
sx={{
|
||||||
|
"*": {
|
||||||
|
whiteSpace: "pre-wrap",
|
||||||
|
},
|
||||||
|
}}
|
||||||
position="relative"
|
position="relative"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
justifyContent="center"
|
justifyContent="center"
|
||||||
|
@ -79,7 +79,7 @@ export const Nav = (props) => {
|
|||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
position="fixed"
|
position="fixed"
|
||||||
zIndex={999}
|
zIndex={9999}
|
||||||
top={0}
|
top={0}
|
||||||
right={0}
|
right={0}
|
||||||
left={0}
|
left={0}
|
||||||
|
@ -9,6 +9,15 @@ export const SettingsMenu = (props) => {
|
|||||||
const [show, setShow] = useState(false)
|
const [show, setShow] = useState(false)
|
||||||
const hideRef = React.useRef(null)
|
const hideRef = React.useRef(null)
|
||||||
const [opacity, setOpacity] = React.useState(props?.opacity === 0 ? 0 : 1)
|
const [opacity, setOpacity] = React.useState(props?.opacity === 0 ? 0 : 1)
|
||||||
|
const [pinStatus, setPinStatus] = React.useState(false)
|
||||||
|
|
||||||
|
const stateRef = React.useRef({
|
||||||
|
pinStatus,
|
||||||
|
})
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
stateRef.current.pinStatus = pinStatus
|
||||||
|
}, [pinStatus])
|
||||||
|
|
||||||
const { thingtime, events } = useThingtime()
|
const { thingtime, events } = useThingtime()
|
||||||
|
|
||||||
@ -25,7 +34,10 @@ export const SettingsMenu = (props) => {
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const subscription = events.subscribe((event) => {
|
const subscription = events.subscribe((event) => {
|
||||||
if (event?.type === "settings-menu-hide" && event?.uuid !== uuid) {
|
if (event?.type === "settings-menu-hide" && event?.uuid !== uuid) {
|
||||||
setShow(false)
|
if (!stateRef?.current?.pinStatus || event?.force) {
|
||||||
|
setShow(false)
|
||||||
|
setOpacity(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -40,8 +52,10 @@ export const SettingsMenu = (props) => {
|
|||||||
setOpacity(props?.opacity)
|
setOpacity(props?.opacity)
|
||||||
} else {
|
} else {
|
||||||
opacityRef.current = setInterval(() => {
|
opacityRef.current = setInterval(() => {
|
||||||
setOpacity(props?.opacity)
|
if (!stateRef?.current?.pinStatus) {
|
||||||
setShow(false)
|
setOpacity(props?.opacity)
|
||||||
|
setShow(false)
|
||||||
|
}
|
||||||
}, waitTime)
|
}, waitTime)
|
||||||
}
|
}
|
||||||
}, [props?.opacity])
|
}, [props?.opacity])
|
||||||
@ -53,17 +67,23 @@ export const SettingsMenu = (props) => {
|
|||||||
type: "settings-menu-hide",
|
type: "settings-menu-hide",
|
||||||
uuid,
|
uuid,
|
||||||
})
|
})
|
||||||
|
} else if (!show) {
|
||||||
|
setPinStatus(false)
|
||||||
}
|
}
|
||||||
}, [show, props?.opacity, events, uuid])
|
}, [show, props?.opacity, events, uuid])
|
||||||
|
|
||||||
const maybeHide = React.useCallback(() => {
|
const maybeHide = React.useCallback(() => {
|
||||||
clearInterval(hideRef?.current)
|
clearInterval(hideRef?.current)
|
||||||
hideRef.current = setTimeout(() => {
|
hideRef.current = setTimeout(() => {
|
||||||
setShow(false)
|
if (!stateRef?.current?.pinStatus) {
|
||||||
|
setShow(false)
|
||||||
|
setOpacity(0)
|
||||||
|
}
|
||||||
}, waitTime)
|
}, waitTime)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const showMenu = React.useCallback(() => {
|
const showMenu = React.useCallback(() => {
|
||||||
|
clearInterval(hideRef?.current)
|
||||||
setShow(true)
|
setShow(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@ -76,22 +96,41 @@ export const SettingsMenu = (props) => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const types = React.useMemo(() => {
|
const types = React.useMemo(() => {
|
||||||
const ret = [
|
const baseTypes = thingtime?.settings?.types?.javascript || {}
|
||||||
{ label: "any", icon: "any" },
|
const baseTypeKeys = Object.keys(baseTypes)
|
||||||
"object",
|
|
||||||
"array",
|
|
||||||
"string",
|
|
||||||
"number",
|
|
||||||
"boolean",
|
|
||||||
]
|
|
||||||
return ret
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const onChangeType = React.useCallback(
|
const customTypes = thingtime?.settings?.types?.custom || {}
|
||||||
(type) => {
|
const customTypeKeysRaw = Object.keys(customTypes)
|
||||||
props?.onChangeType?.(type)
|
const customTypeKeys = customTypeKeysRaw?.filter((key) => {
|
||||||
|
return !baseTypeKeys?.includes?.(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
const types = [
|
||||||
|
...(baseTypeKeys?.map?.((key) => {
|
||||||
|
return {
|
||||||
|
...baseTypes?.[key],
|
||||||
|
key,
|
||||||
|
}
|
||||||
|
}) || []),
|
||||||
|
...(customTypeKeys?.map?.((key) => {
|
||||||
|
return {
|
||||||
|
...customTypes?.[key],
|
||||||
|
key,
|
||||||
|
}
|
||||||
|
}) || []),
|
||||||
|
]
|
||||||
|
|
||||||
|
return types
|
||||||
|
}, [
|
||||||
|
thingtime?.settings?.types?.javascript,
|
||||||
|
thingtime?.settings?.types?.custom,
|
||||||
|
])
|
||||||
|
|
||||||
|
const onType = React.useCallback(
|
||||||
|
(args) => {
|
||||||
|
props?.onType?.(args)
|
||||||
},
|
},
|
||||||
[props?.onChangeType]
|
[props?.onType]
|
||||||
)
|
)
|
||||||
const onDelete = React.useCallback(
|
const onDelete = React.useCallback(
|
||||||
(type) => {
|
(type) => {
|
||||||
@ -100,7 +139,8 @@ export const SettingsMenu = (props) => {
|
|||||||
[props?.onDelete]
|
[props?.onDelete]
|
||||||
)
|
)
|
||||||
|
|
||||||
const iconSize = 10
|
const childIconSize = 10
|
||||||
|
const iconSize = props?.iconSize || 7
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClickAwayListener onClickAway={hideMenu}>
|
<ClickAwayListener onClickAway={hideMenu}>
|
||||||
@ -120,7 +160,7 @@ export const SettingsMenu = (props) => {
|
|||||||
// onClick={deleteValue}
|
// onClick={deleteValue}
|
||||||
transition="all 0.2s ease-in-out"
|
transition="all 0.2s ease-in-out"
|
||||||
>
|
>
|
||||||
<Icon name="wizard" size={7}></Icon>
|
<Icon name="wizard" size={iconSize}></Icon>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
position="absolute"
|
position="absolute"
|
||||||
@ -131,6 +171,20 @@ export const SettingsMenu = (props) => {
|
|||||||
opacity={show ? 1 : 0}
|
opacity={show ? 1 : 0}
|
||||||
pointerEvents={show ? "all" : "none"}
|
pointerEvents={show ? "all" : "none"}
|
||||||
>
|
>
|
||||||
|
<Flex
|
||||||
|
position="absolute"
|
||||||
|
top={0}
|
||||||
|
right={0}
|
||||||
|
padding="5px"
|
||||||
|
cursor="pointer"
|
||||||
|
onClick={() => setPinStatus((prev) => !prev)}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
opacity={pinStatus ? 1 : 0.5}
|
||||||
|
name={pinStatus ? "pinned" : "pin"}
|
||||||
|
size="8px"
|
||||||
|
></Icon>
|
||||||
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
// rowGap={basePadding / 3}
|
// rowGap={basePadding / 3}
|
||||||
@ -143,8 +197,8 @@ export const SettingsMenu = (props) => {
|
|||||||
<Flex
|
<Flex
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
paddingRight={basePadding * 2}
|
// paddingRight={basePadding}
|
||||||
paddingLeft={basePadding * 1}
|
paddingLeft={basePadding}
|
||||||
_hover={{
|
_hover={{
|
||||||
background: "greys.light",
|
background: "greys.light",
|
||||||
}}
|
}}
|
||||||
@ -152,7 +206,11 @@ export const SettingsMenu = (props) => {
|
|||||||
// paddingX={basePadding * 1}
|
// paddingX={basePadding * 1}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon marginBottom="-2px" name="cyclone" size={iconSize}></Icon>
|
<Icon
|
||||||
|
marginBottom="-2px"
|
||||||
|
name="cyclone"
|
||||||
|
size={childIconSize}
|
||||||
|
></Icon>
|
||||||
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
||||||
Types
|
Types
|
||||||
</Text>
|
</Text>
|
||||||
@ -161,6 +219,8 @@ export const SettingsMenu = (props) => {
|
|||||||
<Flex
|
<Flex
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
// rowGap={basePadding}
|
// rowGap={basePadding}
|
||||||
|
overflowY="scroll"
|
||||||
|
maxHeight="300px"
|
||||||
background="greys.lightt"
|
background="greys.lightt"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
>
|
>
|
||||||
@ -176,32 +236,53 @@ export const SettingsMenu = (props) => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => onChangeType(type?.key || type)}
|
onClick={() => onType({ type })}
|
||||||
paddingY={1}
|
paddingY={1}
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
width="100%"
|
width="100%"
|
||||||
paddingRight={basePadding * 4}
|
paddingRight={basePadding}
|
||||||
paddingLeft={basePadding * 2}
|
paddingLeft={basePadding * 2}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
marginBottom="-2px"
|
marginBottom="-2px"
|
||||||
name={type?.icon || type?.key || type?.label || type}
|
name={type?.icon || type?.key || type?.label || type}
|
||||||
size={iconSize}
|
size={childIconSize}
|
||||||
></Icon>
|
></Icon>
|
||||||
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
||||||
{type?.label || type?.key || type}
|
{type?.label || type?.key || type}
|
||||||
</Text>
|
</Text>
|
||||||
|
{type?.wrap && (
|
||||||
|
<Flex
|
||||||
|
marginLeft="auto"
|
||||||
|
_hover={{
|
||||||
|
transform: "scale(1.3)",
|
||||||
|
}}
|
||||||
|
transition="all 0.2s ease-out"
|
||||||
|
onClick={(e) => {
|
||||||
|
e?.preventDefault?.()
|
||||||
|
e?.stopPropagation?.()
|
||||||
|
// cancel bubble
|
||||||
|
e?.nativeEvent?.stopImmediatePropagation?.()
|
||||||
|
onType({
|
||||||
|
type,
|
||||||
|
wrap: true,
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon name="wrap" size={childIconSize}></Icon>
|
||||||
|
</Flex>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
return ret
|
return ret
|
||||||
})}
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
{!props?.readonly && (
|
{!props?.readonly && props?.onDelete && (
|
||||||
<Flex
|
<Flex
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
@ -213,7 +294,11 @@ export const SettingsMenu = (props) => {
|
|||||||
paddingX={basePadding * 1}
|
paddingX={basePadding * 1}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon marginBottom="-2px" name="bin" size={iconSize}></Icon>
|
<Icon
|
||||||
|
marginBottom="-2px"
|
||||||
|
name="bin"
|
||||||
|
size={childIconSize}
|
||||||
|
></Icon>
|
||||||
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
||||||
Recycle
|
Recycle
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -25,6 +25,7 @@ import { Safe } from "../Safety/Safe"
|
|||||||
import { SettingsMenu } from "./SettingsMenu"
|
import { SettingsMenu } from "./SettingsMenu"
|
||||||
import { useThingtime } from "./useThingtime"
|
import { useThingtime } from "./useThingtime"
|
||||||
|
|
||||||
|
import { useThings } from "~/hooks/useThings"
|
||||||
import { getThing } from "~/smarts"
|
import { getThing } from "~/smarts"
|
||||||
|
|
||||||
export const Thingtime = (props) => {
|
export const Thingtime = (props) => {
|
||||||
@ -32,7 +33,10 @@ export const Thingtime = (props) => {
|
|||||||
// and add button to expand circular reference
|
// and add button to expand circular reference
|
||||||
// up to 1 level deep
|
// up to 1 level deep
|
||||||
|
|
||||||
const { thingtime, setThingtime, getThingtime, loading } = useThingtime()
|
const { append } = useThings()
|
||||||
|
|
||||||
|
const { thingtime, setThingtime, getThingtime, loading, events } =
|
||||||
|
useThingtime()
|
||||||
|
|
||||||
const [uuid, setUuid] = React.useState(undefined)
|
const [uuid, setUuid] = React.useState(undefined)
|
||||||
|
|
||||||
@ -42,6 +46,8 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
const thingtimeRef = React.useRef()
|
const thingtimeRef = React.useRef()
|
||||||
|
|
||||||
|
const [showFullPathContext, setShowFullPathContext] = React.useState(false)
|
||||||
|
|
||||||
const editValueRef = React.useRef({})
|
const editValueRef = React.useRef({})
|
||||||
|
|
||||||
const depth = React.useMemo(() => {
|
const depth = React.useMemo(() => {
|
||||||
@ -65,20 +71,20 @@ export const Thingtime = (props) => {
|
|||||||
return "100%"
|
return "100%"
|
||||||
}, [props?.width, props?.w, render])
|
}, [props?.width, props?.w, render])
|
||||||
|
|
||||||
const chakras = React.useMemo(() => {
|
const chakraChild = React.useMemo(() => {
|
||||||
if (!props?.edit && props?.chakra) {
|
if (!props?.edit && props?.chakraChild) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}, [props?.edit, props?.chakra])
|
}, [props?.edit, props?.chakraChild])
|
||||||
|
|
||||||
const pl = React.useMemo(() => {
|
const pl = React.useMemo(() => {
|
||||||
if (!props.edit && chakras) {
|
if (!props.edit && chakraChild) {
|
||||||
return [0]
|
return [0]
|
||||||
}
|
}
|
||||||
|
|
||||||
return props?.pl || [4, 6]
|
return props?.pl || [4, 6]
|
||||||
}, [props?.pl, props?.edit, chakras])
|
}, [props?.pl, props?.edit, chakraChild])
|
||||||
|
|
||||||
const pr = React.useMemo(() => {
|
const pr = React.useMemo(() => {
|
||||||
return props?.pr || (depth === 0 ? [4, 6] : 0)
|
return props?.pr || (depth === 0 ? [4, 6] : 0)
|
||||||
@ -138,7 +144,7 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
const thing = React.useMemo(() => {
|
const thing = React.useMemo(() => {
|
||||||
return props.thing
|
return props.thing
|
||||||
}, [props.thing, childrenRef.current])
|
}, [props.thing, uuid, childrenRef.current])
|
||||||
|
|
||||||
const chakra = React.useMemo(() => {
|
const chakra = React.useMemo(() => {
|
||||||
return !props?.edit && typeof thing?.chakra === "string" && thing?.chakra
|
return !props?.edit && typeof thing?.chakra === "string" && thing?.chakra
|
||||||
@ -250,7 +256,7 @@ export const Thingtime = (props) => {
|
|||||||
}, [props?.valuePl, props?.path])
|
}, [props?.valuePl, props?.path])
|
||||||
|
|
||||||
const renderableValue = React.useMemo(() => {
|
const renderableValue = React.useMemo(() => {
|
||||||
if (chakras) {
|
if (chakraChild) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,11 +293,7 @@ export const Thingtime = (props) => {
|
|||||||
} else {
|
} else {
|
||||||
return "Something.."
|
return "Something.."
|
||||||
}
|
}
|
||||||
}, [thing, thingDep, type, chakras, keys])
|
}, [thing, thingDep, type, chakraChild, keys])
|
||||||
|
|
||||||
const hasChakraChildren = React.useMemo(() => {
|
|
||||||
return !props?.edit && chakra && render && thing?.children
|
|
||||||
}, [chakra, props?.edit, render, thing?.children])
|
|
||||||
|
|
||||||
const renderChakra = React.useMemo(() => {
|
const renderChakra = React.useMemo(() => {
|
||||||
if (!props?.edit && chakra && render) {
|
if (!props?.edit && chakra && render) {
|
||||||
@ -366,7 +368,7 @@ export const Thingtime = (props) => {
|
|||||||
notRoot
|
notRoot
|
||||||
fullPath={fullPath + "." + key?.key}
|
fullPath={fullPath + "." + key?.key}
|
||||||
path={key}
|
path={key}
|
||||||
chakraChildren={chakra}
|
chakraChild={chakra}
|
||||||
thing={nextThing}
|
thing={nextThing}
|
||||||
// thing={{ infinite: { yes: true } }}
|
// thing={{ infinite: { yes: true } }}
|
||||||
valuePl={pl}
|
valuePl={pl}
|
||||||
@ -382,6 +384,8 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
console.log("Thingtime is chakra", fullPath, chakra)
|
console.log("Thingtime is chakra", fullPath, chakra)
|
||||||
|
|
||||||
|
const rawChildren = thing?.rawChildren
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (ChakraComponent) {
|
if (ChakraComponent) {
|
||||||
console.log(
|
console.log(
|
||||||
@ -393,6 +397,7 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
const ret = (
|
const ret = (
|
||||||
<ChakraComponent {...(thing?.props || {})}>
|
<ChakraComponent {...(thing?.props || {})}>
|
||||||
|
{rawChildren}
|
||||||
{inner}
|
{inner}
|
||||||
</ChakraComponent>
|
</ChakraComponent>
|
||||||
)
|
)
|
||||||
@ -406,7 +411,7 @@ export const Thingtime = (props) => {
|
|||||||
// TODO: Is it safe to spread props
|
// TODO: Is it safe to spread props
|
||||||
// because having props as a dependency will cause a re-render every time
|
// because having props as a dependency will cause a re-render every time
|
||||||
|
|
||||||
if (props?.chakraChildren) {
|
if (props?.chakraChild) {
|
||||||
return inner
|
return inner
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,7 +437,7 @@ export const Thingtime = (props) => {
|
|||||||
circular,
|
circular,
|
||||||
seen,
|
seen,
|
||||||
type,
|
type,
|
||||||
props?.chakraChildren,
|
props?.chakraChild,
|
||||||
props?.path,
|
props?.path,
|
||||||
props?.edit,
|
props?.edit,
|
||||||
chakra,
|
chakra,
|
||||||
@ -460,30 +465,34 @@ export const Thingtime = (props) => {
|
|||||||
}, [updateValue])
|
}, [updateValue])
|
||||||
|
|
||||||
const onChangeType = React.useCallback(
|
const onChangeType = React.useCallback(
|
||||||
(type) => {
|
(args) => {
|
||||||
const newType =
|
const { type, wrap } = args
|
||||||
type?.key || type?.value || type?.label || type?.icon || type
|
const typeValue =
|
||||||
|
typeof type?.value === "function" ? type?.value() : type?.value
|
||||||
|
|
||||||
if (newType === "object") {
|
if (type) {
|
||||||
updateValue({ value: {} })
|
const wrapTarget = type?.wrap
|
||||||
} else if (newType === "array") {
|
if (wrap && wrapTarget) {
|
||||||
updateValue({ value: [] })
|
const newValue = append({
|
||||||
} else if (newType === "string") {
|
thing: typeValue[wrapTarget],
|
||||||
updateValue({ value: "" })
|
value: thing,
|
||||||
} else if (newType === "number") {
|
})
|
||||||
updateValue({ value: 0 })
|
typeValue[wrapTarget] = newValue
|
||||||
} else if (newType === "boolean") {
|
if (typeValue) {
|
||||||
updateValue({ value: false })
|
updateValue({ value: typeValue })
|
||||||
} else if (newType === "undefined") {
|
}
|
||||||
updateValue({ value: undefined })
|
} else {
|
||||||
} else if (newType === "null") {
|
updateValue({ value: typeValue })
|
||||||
updateValue({ value: null })
|
}
|
||||||
} else if (newType === "any") {
|
|
||||||
updateValue({ value: null })
|
|
||||||
} else {
|
|
||||||
console.error("Unknown type", newType)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
[updateValue, thing, append, fullPath]
|
||||||
|
)
|
||||||
|
|
||||||
|
const onWrapType = React.useCallback(
|
||||||
|
(type) => {
|
||||||
|
// nothing
|
||||||
|
},
|
||||||
[updateValue]
|
[updateValue]
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -704,7 +713,7 @@ export const Thingtime = (props) => {
|
|||||||
const pathRef = React.useRef(null)
|
const pathRef = React.useRef(null)
|
||||||
|
|
||||||
const pathDom = React.useMemo(() => {
|
const pathDom = React.useMemo(() => {
|
||||||
if (chakras) {
|
if (chakraChild) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +735,7 @@ export const Thingtime = (props) => {
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}, [renderedPath, pl, chakras, props?.edit, props?.pathPl])
|
}, [renderedPath, pl, chakraChild, props?.edit, props?.pathPl])
|
||||||
|
|
||||||
const handleMouseEvent = React.useCallback(
|
const handleMouseEvent = React.useCallback(
|
||||||
(e) => {
|
(e) => {
|
||||||
@ -740,33 +749,73 @@ export const Thingtime = (props) => {
|
|||||||
[uuid]
|
[uuid]
|
||||||
)
|
)
|
||||||
|
|
||||||
const addNewChild = React.useCallback(() => {
|
const addNewChild = React.useCallback(
|
||||||
const newChild = null
|
(args) => {
|
||||||
|
const { type } = args
|
||||||
|
const newChild =
|
||||||
|
typeof type?.value === "function" ? type?.value() : type?.value || null
|
||||||
|
|
||||||
if (thing instanceof Array) {
|
if (thing instanceof Array) {
|
||||||
// add new child to array
|
// add new child to array
|
||||||
const newValue = [...thing, newChild]
|
const newValue = [...thing, newChild]
|
||||||
setThingtime(fullPath, newValue)
|
setThingtime(fullPath, newValue)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const newChildBasePath = "New Value"
|
const newChildBasePath = "New Value"
|
||||||
// find increment that thing doesn't already have New Value N+1
|
// find increment that thing doesn't already have New Value N+1
|
||||||
let increment = 0
|
let increment = 0
|
||||||
let newPath = newChildBasePath
|
let newPath = newChildBasePath
|
||||||
while (Object.hasOwnProperty.call(thing, newPath) && increment <= 999) {
|
while (Object.hasOwnProperty.call(thing, newPath) && increment <= 999) {
|
||||||
increment++
|
increment++
|
||||||
newPath = newChildBasePath + " " + increment
|
newPath = newChildBasePath + " " + increment
|
||||||
}
|
}
|
||||||
const newChildPath = newPath
|
const newChildPath = newPath
|
||||||
const newChildFullPath = fullPath + "." + newChildPath
|
const newChildFullPath = fullPath + "." + newChildPath
|
||||||
// create new child on thing using setThingtime
|
// create new child on thing using setThingtime
|
||||||
setThingtime(newChildFullPath, newChild)
|
setThingtime(newChildFullPath, newChild)
|
||||||
}, [fullPath, setThingtime, thing])
|
},
|
||||||
|
[fullPath, setThingtime, thing]
|
||||||
|
)
|
||||||
|
|
||||||
const [showContextIcon, setShowContextIcon] = React.useState(false)
|
const [showContextIcon, setShowContextIcon] = React.useState(false)
|
||||||
|
const [showNewContextIcon, setShowNewContextIcon] = React.useState(false)
|
||||||
|
|
||||||
if (props?.chakraChildren) {
|
// should be absolute last
|
||||||
|
React.useEffect(() => {
|
||||||
|
try {
|
||||||
|
window.meta.things[uuid] = {
|
||||||
|
thing: props?.thing,
|
||||||
|
props,
|
||||||
|
state: {
|
||||||
|
chakra,
|
||||||
|
chakraChild,
|
||||||
|
circular,
|
||||||
|
depth,
|
||||||
|
fullPath,
|
||||||
|
parent,
|
||||||
|
parentPath,
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
thing,
|
||||||
|
props,
|
||||||
|
uuid,
|
||||||
|
chakra,
|
||||||
|
chakraChild,
|
||||||
|
circular,
|
||||||
|
depth,
|
||||||
|
fullPath,
|
||||||
|
parent,
|
||||||
|
parentPath,
|
||||||
|
path,
|
||||||
|
])
|
||||||
|
|
||||||
|
if (chakra || chakraChild) {
|
||||||
return thingtimeChildren
|
return thingtimeChildren
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -790,7 +839,7 @@ export const Thingtime = (props) => {
|
|||||||
data-path={props?.path}
|
data-path={props?.path}
|
||||||
>
|
>
|
||||||
{/* {uuid?.current} */}
|
{/* {uuid?.current} */}
|
||||||
{!chakras && !chakra && (
|
{!chakraChild && !chakra && (
|
||||||
<Flex position="relative" flexDirection="row">
|
<Flex position="relative" flexDirection="row">
|
||||||
<Flex
|
<Flex
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
@ -824,7 +873,7 @@ export const Thingtime = (props) => {
|
|||||||
uuid={uuid}
|
uuid={uuid}
|
||||||
fullPath={fullPath}
|
fullPath={fullPath}
|
||||||
readonly={!props?.edit}
|
readonly={!props?.edit}
|
||||||
onChangeType={onChangeType}
|
onType={onChangeType}
|
||||||
onDelete={deleteValue}
|
onDelete={deleteValue}
|
||||||
></SettingsMenu>
|
></SettingsMenu>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -848,14 +897,37 @@ export const Thingtime = (props) => {
|
|||||||
{thingtimeChildren}
|
{thingtimeChildren}
|
||||||
{!render && type === "object" && (
|
{!render && type === "object" && (
|
||||||
<Flex
|
<Flex
|
||||||
|
position="relative"
|
||||||
width="100%"
|
width="100%"
|
||||||
paddingLeft={multiplyPl(2)}
|
paddingLeft={multiplyPl(2)}
|
||||||
opacity={props?.edit ? 1 : 0}
|
opacity={props?.edit ? 1 : 0}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
transition="all 0.2s ease-out"
|
transition="all 0.2s ease-out"
|
||||||
onClick={addNewChild}
|
onClick={addNewChild}
|
||||||
|
onMouseEnter={() => {
|
||||||
|
setShowFullPathContext(true)
|
||||||
|
setShowNewContextIcon(true)
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setShowFullPathContext(false)
|
||||||
|
setShowNewContextIcon(false)
|
||||||
|
}}
|
||||||
paddingY={2}
|
paddingY={2}
|
||||||
>
|
>
|
||||||
|
<Flex
|
||||||
|
position="absolute"
|
||||||
|
bottom="100%"
|
||||||
|
left={0}
|
||||||
|
display={showFullPathContext ? "flex" : "none"}
|
||||||
|
fontSize="sm"
|
||||||
|
background="greys.light"
|
||||||
|
borderRadius={6}
|
||||||
|
pointerEvents="none"
|
||||||
|
paddingX={3}
|
||||||
|
paddingY={1}
|
||||||
|
>
|
||||||
|
{fullPath}
|
||||||
|
</Flex>
|
||||||
<Icon
|
<Icon
|
||||||
_focus={{
|
_focus={{
|
||||||
outline: "none !important",
|
outline: "none !important",
|
||||||
@ -870,6 +942,25 @@ export const Thingtime = (props) => {
|
|||||||
size={10}
|
size={10}
|
||||||
name="seedling"
|
name="seedling"
|
||||||
></Icon>
|
></Icon>
|
||||||
|
<Flex
|
||||||
|
marginLeft={2}
|
||||||
|
onClick={(e) => {
|
||||||
|
e?.preventDefault()
|
||||||
|
e?.stopPropagation()
|
||||||
|
e?.nativeEvent?.stopImmediatePropagation()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SettingsMenu
|
||||||
|
transition="all 0.2s ease-in-out"
|
||||||
|
opacity={showNewContextIcon ? 1 : 0}
|
||||||
|
uuid={uuid}
|
||||||
|
iconSize={10}
|
||||||
|
fullPath={fullPath}
|
||||||
|
readonly={!props?.edit}
|
||||||
|
onType={addNewChild}
|
||||||
|
></SettingsMenu>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
{/* <Icon size={7} name="plus"></Icon>
|
{/* <Icon size={7} name="plus"></Icon>
|
||||||
<Icon size={7} name="plus"></Icon> */}
|
<Icon size={7} name="plus"></Icon> */}
|
||||||
</Flex>
|
</Flex>
|
||||||
|
@ -103,14 +103,14 @@ export const ThingtimeURL = (props) => {
|
|||||||
width="600px"
|
width="600px"
|
||||||
// width="100%"
|
// width="100%"
|
||||||
maxHeight="100vh"
|
maxHeight="100vh"
|
||||||
paddingY={2}
|
// paddingY={2}
|
||||||
>
|
>
|
||||||
<Thingtime
|
<Thingtime
|
||||||
path={path}
|
path={path}
|
||||||
thing={thing}
|
thing={thing}
|
||||||
render
|
render
|
||||||
chakras={{ marginY: "200px" }}
|
chakras={{ marginY: "200px" }}
|
||||||
width="600px"
|
// width="600px"
|
||||||
></Thingtime>
|
></Thingtime>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
|
55
remix/app/hooks/usePath.tsx
Normal file
55
remix/app/hooks/usePath.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import React from "react"
|
||||||
|
import { useLocation } from "@remix-run/react"
|
||||||
|
import { useNavigate } from "@remix-run/react"
|
||||||
|
export const usePath = (props?: any) => {
|
||||||
|
const location = useLocation()
|
||||||
|
const { pathname } = location
|
||||||
|
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
|
const [mode, setMode] = React.useState("")
|
||||||
|
|
||||||
|
const modes = React.useMemo(() => {
|
||||||
|
// make sure any substrings come first
|
||||||
|
return [
|
||||||
|
"edit",
|
||||||
|
"editor",
|
||||||
|
"code",
|
||||||
|
"coder",
|
||||||
|
"thing",
|
||||||
|
"things",
|
||||||
|
"thingtime",
|
||||||
|
"thingtimes",
|
||||||
|
]
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
let set = false
|
||||||
|
modes.forEach((mode) => {
|
||||||
|
const pathPart = pathname.slice(1, mode.length + 1)
|
||||||
|
if (pathPart === mode) {
|
||||||
|
setMode(mode)
|
||||||
|
set = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// if (!set) {
|
||||||
|
// setMode("things")
|
||||||
|
// }
|
||||||
|
}, [pathname, modes])
|
||||||
|
|
||||||
|
const changePath = React.useCallback(
|
||||||
|
(props) => {
|
||||||
|
const { path } = props
|
||||||
|
|
||||||
|
navigate(`${mode}/${path}`)
|
||||||
|
},
|
||||||
|
[navigate, mode]
|
||||||
|
)
|
||||||
|
|
||||||
|
const ret = {
|
||||||
|
mode,
|
||||||
|
changePath,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
34
remix/app/hooks/useThings.tsx
Normal file
34
remix/app/hooks/useThings.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import React from "react"
|
||||||
|
|
||||||
|
export const useThings = (props?: any) => {
|
||||||
|
const append = React.useCallback((args) => {
|
||||||
|
const { thing, value } = args
|
||||||
|
|
||||||
|
if (thing instanceof Array) {
|
||||||
|
const newValue = [...thing, value]
|
||||||
|
return newValue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof thing === "object") {
|
||||||
|
const newChildBasePath = "New Value"
|
||||||
|
// find increment that thing doesn't already have New Value N+1
|
||||||
|
let increment = 0
|
||||||
|
let newPath = newChildBasePath
|
||||||
|
while (Object.hasOwnProperty.call(thing, newPath) && increment <= 999) {
|
||||||
|
increment++
|
||||||
|
newPath = newChildBasePath + " " + increment
|
||||||
|
}
|
||||||
|
const newChildPath = newPath
|
||||||
|
|
||||||
|
const newValue = { ...thing }
|
||||||
|
newValue[newChildPath] = value
|
||||||
|
return newValue
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const ret = {
|
||||||
|
append,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
@ -68,7 +68,7 @@ const setThingtime = (glob) => {
|
|||||||
stats: {
|
stats: {
|
||||||
db: {},
|
db: {},
|
||||||
limit: 9999,
|
limit: 9999,
|
||||||
maxDepth: 10,
|
maxDepth: 99,
|
||||||
count: 0,
|
count: 0,
|
||||||
},
|
},
|
||||||
things: {},
|
things: {},
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
"@vercel/analytics": "^0.1.11",
|
"@vercel/analytics": "^0.1.11",
|
||||||
"@vercel/remix": "^1.15.0",
|
"@vercel/remix": "^1.15.0",
|
||||||
"draft-js": "^0.11.7",
|
"draft-js": "^0.11.7",
|
||||||
|
"emojis-list": "^3.0.0",
|
||||||
"flatted": "^3.2.7",
|
"flatted": "^3.2.7",
|
||||||
"fuse.js": "^6.6.2",
|
"fuse.js": "^6.6.2",
|
||||||
"gradient-path": "^2.3.0",
|
"gradient-path": "^2.3.0",
|
||||||
|
@ -44,6 +44,9 @@ dependencies:
|
|||||||
draft-js:
|
draft-js:
|
||||||
specifier: ^0.11.7
|
specifier: ^0.11.7
|
||||||
version: 0.11.7(react-dom@18.2.0)(react@18.2.0)
|
version: 0.11.7(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
emojis-list:
|
||||||
|
specifier: ^3.0.0
|
||||||
|
version: 3.0.0
|
||||||
flatted:
|
flatted:
|
||||||
specifier: ^3.2.7
|
specifier: ^3.2.7
|
||||||
version: 3.2.7
|
version: 3.2.7
|
||||||
@ -2572,6 +2575,7 @@ packages:
|
|||||||
|
|
||||||
/@emotion/memoize@0.7.4:
|
/@emotion/memoize@0.7.4:
|
||||||
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
||||||
|
requiresBuild: true
|
||||||
dev: false
|
dev: false
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -4501,6 +4505,7 @@ packages:
|
|||||||
|
|
||||||
/bindings@1.5.0:
|
/bindings@1.5.0:
|
||||||
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
|
||||||
|
requiresBuild: true
|
||||||
dependencies:
|
dependencies:
|
||||||
file-uri-to-path: 1.0.0
|
file-uri-to-path: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
@ -5192,7 +5197,6 @@ packages:
|
|||||||
/emojis-list@3.0.0:
|
/emojis-list@3.0.0:
|
||||||
resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
|
resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/encodeurl@1.0.2:
|
/encodeurl@1.0.2:
|
||||||
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==}
|
||||||
@ -6159,6 +6163,7 @@ packages:
|
|||||||
|
|
||||||
/file-uri-to-path@1.0.0:
|
/file-uri-to-path@1.0.0:
|
||||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||||
|
requiresBuild: true
|
||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@ -7939,6 +7944,7 @@ packages:
|
|||||||
|
|
||||||
/node-addon-api@1.7.2:
|
/node-addon-api@1.7.2:
|
||||||
resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==}
|
resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==}
|
||||||
|
requiresBuild: true
|
||||||
dev: true
|
dev: true
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user