feat: feature/mvp-sprint-1 progress commit

This commit is contained in:
Nikolaj Frey 2023-08-12 22:22:52 +10:00
parent 1183ce88f9
commit 6c1f798f23
5 changed files with 114 additions and 14 deletions

View File

@ -1,5 +1,5 @@
import React, { createContext } from "react" import React, { createContext } from "react"
import { parse, stringify } from "flatted" import flatted, { parse, stringify } from "flatted"
import { sanitise } from "~/functions/sanitise" import { sanitise } from "~/functions/sanitise"
import { smarts } from "~/smarts" import { smarts } from "~/smarts"
@ -17,15 +17,25 @@ export const ThingtimeContext = createContext<
try { try {
window.smarts = smarts window.smarts = smarts
window.flatted = {
parse,
stringify,
}
} catch (err) { } catch (err) {
// nothing // nothing
} }
const force = { const force = {
settings: { settings: {
commanders: {
nav: {
// commanderActive: false, // commanderActive: false,
// clearCommanderOnToggle: true,
// clearCommanderContextOnToggle: true,
// hideSuggestionsOnToggle: true, // hideSuggestionsOnToggle: true,
}, },
},
},
version: 23, version: 23,
} }
@ -41,11 +51,15 @@ const newVersionData = {
const initialValues = { const initialValues = {
settings: { settings: {
commanders: {
nav: {
commanderActive: false, commanderActive: false,
clearCommanderOnToggle: true, clearCommanderOnToggle: true,
clearCommanderContextOnToggle: true, clearCommanderContextOnToggle: true,
hideSuggestionsOnToggle: true, hideSuggestionsOnToggle: true,
}, },
},
},
Content: { Content: {
hidden1: "Edit this to your heart's desire.", hidden1: "Edit this to your heart's desire.",
"How?": "Just search for Content and edit the value to whatever you want.", "How?": "Just search for Content and edit the value to whatever you want.",
@ -220,6 +234,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
if (thingtimeFromLocalStorage) { if (thingtimeFromLocalStorage) {
const parsed = parse(thingtimeFromLocalStorage) const parsed = parse(thingtimeFromLocalStorage)
console.log("thingtime restored from localstorage", parsed)
if (parsed) { if (parsed) {
const localIsValid = const localIsValid =
!parsed.version || parsed.version >= force.version !parsed.version || parsed.version >= force.version
@ -230,10 +245,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
const withVersionUpdates = smarts.merge(newVersionData, parsed) const withVersionUpdates = smarts.merge(newVersionData, parsed)
newThingtime = smarts.merge(force, withVersionUpdates) newThingtime = smarts.merge(force, withVersionUpdates)
} }
console.log( console.log("restoring thingtime from localStorage", newThingtime)
"nik setting new thingtime from localStorage",
newThingtime
)
set(newThingtime) set(newThingtime)
} }
} else { } else {

View File

@ -14,6 +14,10 @@ export const Commander = (props) => {
const { thingtime, setThingtime, getThingtime, thingtimeRef, paths } = const { thingtime, setThingtime, getThingtime, thingtimeRef, paths } =
useThingtime() useThingtime()
const commanderId = React.useMemo(() => {
return props?.id || "global"
}, [props?.id])
const inputRef = React.useRef() const inputRef = React.useRef()
const [inputValue, setInputValue] = React.useState("") const [inputValue, setInputValue] = React.useState("")
@ -22,6 +26,10 @@ export const Commander = (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(() => {
return props?.mode || "value"
}, [props?.mode])
const [showContext, setShowContextState] = React.useState(false) const [showContext, setShowContextState] = React.useState(false)
const mobileVW = React.useMemo(() => { const mobileVW = React.useMemo(() => {
@ -45,8 +53,8 @@ export const Commander = (props) => {
}, [contextPath, getThingtime]) }, [contextPath, getThingtime])
const commanderActive = React.useMemo(() => { const commanderActive = React.useMemo(() => {
return thingtime?.settings?.commanderActive return getThingtime("settings.commanderActive." + commanderId)
}, [thingtime?.settings?.commanderActive]) }, [commanderId, getThingtime])
// commanderActive useEffect // commanderActive useEffect
React.useEffect(() => { React.useEffect(() => {

View File

@ -127,6 +127,19 @@ export const Icon = (props) => {
if (["thumb-down", "dislike"]?.includes(name)) { if (["thumb-down", "dislike"]?.includes(name)) {
return "👎" return "👎"
} }
if (["plus", "add"]?.includes(name)) {
return ""
}
if (["seedling", "seed"]?.includes(name)) {
return "🌱"
}
if (["undefined"]?.includes(name)) {
return "❓"
// return "🌫️"
}
if (["codex", "robot", "ai", "chatgpt"]?.includes(name)) {
return "🤖"
}
if (["thingtime"]?.includes(name)) { if (["thingtime"]?.includes(name)) {
if (Math.random() > 0.5) { if (Math.random() > 0.5) {
return "🌳" return "🌳"

View File

@ -49,7 +49,7 @@ export const Nav = (props) => {
<Icon size="12px" name="unicorn"></Icon> <Icon size="12px" name="unicorn"></Icon>
</Link> </Link>
</Center> </Center>
<Commander></Commander> <Commander global id="nav"></Commander>
<Center <Center
width="25px" width="25px"
height="25px" height="25px"

View File

@ -16,6 +16,7 @@ import {
Textarea, Textarea,
} from "@chakra-ui/react" } from "@chakra-ui/react"
import { Commander } from "../Commander/Commander"
import { Icon } from "../Icon/Icon" import { Icon } from "../Icon/Icon"
import { Safe } from "../Safety/Safe" import { Safe } from "../Safety/Safe"
import { useThingtime } from "./useThingtime" import { useThingtime } from "./useThingtime"
@ -48,6 +49,13 @@ export const Thingtime = (props) => {
return props?.pr || (depth === 1 ? [4, 6] : 0) return props?.pr || (depth === 1 ? [4, 6] : 0)
}, [props?.pr, depth]) }, [props?.pr, depth])
const multiplyPl = React.useCallback(
(num) => {
return pl.map((p) => p * num)
},
[pl]
)
// will only run on the client // will only run on the client
React.useEffect(() => { React.useEffect(() => {
setUuid(Math.random().toString(36).substring(7)) setUuid(Math.random().toString(36).substring(7))
@ -137,6 +145,9 @@ export const Thingtime = (props) => {
}, [thing, thingDep, validKeyTypes]) }, [thing, thingDep, validKeyTypes])
const type = React.useMemo(() => { const type = React.useMemo(() => {
if (thing === null) {
return "undefined"
}
return typeof thing return typeof thing
}, [thing]) }, [thing])
@ -152,6 +163,8 @@ export const Thingtime = (props) => {
return <Icon name="number" size={size}></Icon> return <Icon name="number" size={size}></Icon>
} else if (type === "boolean") { } else if (type === "boolean") {
return <Icon name="boolean" size={size}></Icon> return <Icon name="boolean" size={size}></Icon>
} else if (type === "undefined") {
return <Icon name="undefined" size={size}></Icon>
} else { } else {
return <Icon name="box" size={size}></Icon> return <Icon name="box" size={size}></Icon>
} }
@ -198,6 +211,8 @@ export const Thingtime = (props) => {
</Box> </Box>
) )
} }
} else if (type === "undefined") {
return "undefined"
} else { } else {
return "Something!" return "Something!"
} }
@ -287,6 +302,7 @@ export const Thingtime = (props) => {
const AtomicWrapper = React.useCallback((props) => { const AtomicWrapper = React.useCallback((props) => {
return ( return (
<Flex <Flex
position="relative"
flexDirection="row" flexDirection="row"
flexShrink={1} flexShrink={1}
width="100%" width="100%"
@ -440,6 +456,14 @@ export const Thingtime = (props) => {
</AtomicWrapper> </AtomicWrapper>
) )
} }
if (type === "undefined") {
return (
<AtomicWrapper>
{/* TODO: Implement UI-less commander */}
{/* <Commander></Commander> */}
</AtomicWrapper>
)
}
} }
return ( return (
@ -523,6 +547,48 @@ export const Thingtime = (props) => {
[uuid] [uuid]
) )
const addNewChild = React.useCallback(() => {
const newChild = null
if (thing instanceof Array) {
// add new child to array
const newValue = [...thing, newChild]
setThingtime(fullPath, newValue)
return
}
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 newChildFullPath = fullPath + "." + newChildPath
// create new child on thing using setThingtime
setThingtime(newChildFullPath, newChild)
}, [fullPath, setThingtime, thing])
const addChildUi = React.useMemo(() => {
if (type === "object" && props?.edit) {
return (
<Flex
width="100%"
paddingLeft={multiplyPl(2)}
cursor="pointer"
onClick={addNewChild}
paddingY={2}
>
<Icon size={12} name="seedling"></Icon>
{/* <Icon size={7} name="plus"></Icon>
<Icon size={7} name="plus"></Icon> */}
</Flex>
)
}
}, [props?.edit, type, multiplyPl, addNewChild])
const [showContextIcon, setShowContextIcon] = React.useState(false) const [showContextIcon, setShowContextIcon] = React.useState(false)
return ( return (
@ -582,6 +648,7 @@ export const Thingtime = (props) => {
{!loading && thingtimeChildren && ( {!loading && thingtimeChildren && (
<Box className="thingtimeChildren">{thingtimeChildren}</Box> <Box className="thingtimeChildren">{thingtimeChildren}</Box>
)} )}
{addChildUi}
</Flex> </Flex>
</Safe> </Safe>
) )