feat: feature/mvp-sprint-1 Progress on commander changes

This commit is contained in:
Nikolaj Frey 2023-08-13 00:06:33 +10:00
parent 6c1f798f23
commit 9223138d12
7 changed files with 160 additions and 88 deletions

View File

@ -27,14 +27,14 @@ try {
const force = { const force = {
settings: { settings: {
commanders: { // commander: {
nav: { // nav: {
// commanderActive: false, // commanderActive: false,
// clearCommanderOnToggle: true, // clearCommanderOnToggle: true,
// clearCommanderContextOnToggle: true, // clearCommanderContextOnToggle: true,
// hideSuggestionsOnToggle: true, // hideSuggestionsOnToggle: true,
}, // },
}, // },
}, },
version: 23, version: 23,
} }
@ -51,7 +51,7 @@ const newVersionData = {
const initialValues = { const initialValues = {
settings: { settings: {
commanders: { commander: {
nav: { nav: {
commanderActive: false, commanderActive: false,
clearCommanderOnToggle: true, clearCommanderOnToggle: true,

View File

@ -20,6 +20,16 @@ export const Commander = (props) => {
const inputRef = React.useRef() const inputRef = React.useRef()
const global = props?.global
const commanderSettings = React.useMemo(() => {
return thingtime?.settings?.commander?.[commanderId] || {}
}, [
thingtime?.settings?.commander,
thingtime?.settings?.commander?.[commanderId],
commanderId,
])
const [inputValue, setInputValue] = React.useState("") const [inputValue, setInputValue] = React.useState("")
const [virtualValue, setVirtualValue] = React.useState("") const [virtualValue, setVirtualValue] = React.useState("")
const [hoveredSuggestion, setHoveredSuggestion] = React.useState() const [hoveredSuggestion, setHoveredSuggestion] = React.useState()
@ -53,8 +63,8 @@ export const Commander = (props) => {
}, [contextPath, getThingtime]) }, [contextPath, getThingtime])
const commanderActive = React.useMemo(() => { const commanderActive = React.useMemo(() => {
return getThingtime("settings.commanderActive." + commanderId) return thingtime?.settings?.commander?.[commanderId]?.commanderActive
}, [commanderId, getThingtime]) }, [commanderSettings, commanderId])
// commanderActive useEffect // commanderActive useEffect
React.useEffect(() => { React.useEffect(() => {
@ -63,11 +73,18 @@ export const Commander = (props) => {
} else { } else {
document.activeElement.blur() document.activeElement.blur()
if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) { if (
thingtimeRef?.current?.settings?.commander?.[commanderId]
?.clearCommanderOnToggle
) {
setInputValue("") setInputValue("")
setHoveredSuggestion(null) setHoveredSuggestion(null)
} }
if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) { if (
thingtimeRef?.current?.settings?.commander?.[commanderId]?.commander?.[
commanderId
]?.clearCommanderContextOnToggle
) {
setShowContext(false, "commanderActive useEffect") setShowContext(false, "commanderActive useEffect")
} }
if (contextPath !== undefined && !inputValue) { if (contextPath !== undefined && !inputValue) {
@ -81,6 +98,7 @@ export const Commander = (props) => {
commanderActive, commanderActive,
thingtimeRef, thingtimeRef,
setShowContext, setShowContext,
commanderId,
inputValue, inputValue,
contextPath, contextPath,
showContext, showContext,
@ -178,13 +196,15 @@ export const Commander = (props) => {
inputValue?.length && inputValue?.length &&
suggestions?.length && suggestions?.length &&
commanderActive && commanderActive &&
thingtime?.settings?.hideSuggestionsOnToggle thingtime?.settings?.commander?.[commanderId]?.hideSuggestionsOnToggle
) )
}, [ }, [
inputValue, inputValue,
suggestions, suggestions,
commanderActive, commanderActive,
thingtime?.settings?.hideSuggestionsOnToggle, commanderId,
thingtime?.settings?.commander,
commanderSettings,
]) ])
const selectSuggestion = React.useCallback( const selectSuggestion = React.useCallback(
@ -208,27 +228,41 @@ export const Commander = (props) => {
}, [commandPath, suggestions]) }, [commandPath, suggestions])
const openCommander = React.useCallback(() => { const openCommander = React.useCallback(() => {
setThingtime("settings.commanderActive", true) setThingtime(`settings.commander.${commanderId}.commanderActive`, true)
}, [setThingtime]) }, [setThingtime, commanderId])
const closeCommander = React.useCallback( const closeCommander = React.useCallback(
(e?: any) => { (e?: any) => {
if (!e?.defaultPrevented) { if (!e?.defaultPrevented) {
if (thingtime?.settings?.commanderActive) { if (thingtime?.settings?.commander?.[commanderId]?.commanderActive) {
setThingtime("settings.commanderActive", false) setThingtime(
`settings.commander.${commanderId}.commanderActive`,
false
)
} }
} }
}, },
[setThingtime, thingtime?.settings?.commanderActive] [
setThingtime,
commanderId,
commanderSettings,
thingtime?.settings?.commander,
]
) )
const toggleCommander = React.useCallback(() => { const toggleCommander = React.useCallback(() => {
if (thingtime?.settings?.commanderActive) { if (thingtime?.settings?.commander?.[commanderId]?.commanderActive) {
closeCommander() closeCommander()
} else { } else {
openCommander() openCommander()
} }
}, [thingtime?.settings?.commanderActive, closeCommander, openCommander]) }, [
thingtime?.settings?.commander,
commanderSettings,
commanderId,
closeCommander,
openCommander,
])
const executeCommand = React.useCallback(() => { const executeCommand = React.useCallback(() => {
// if selection is active then select it // if selection is active then select it
@ -380,6 +414,58 @@ export const Commander = (props) => {
setVirtualValue(inputValue) setVirtualValue(inputValue)
}, [inputValue]) }, [inputValue])
const InputJSX = React.useMemo(() => {
return (
<Input
// display='none'
// opacity={0}
ref={inputRef}
sx={{
"&::placeholder": {
color: "greys.dark",
},
}}
width="100%"
height="100%"
background="grey"
border="none"
borderRadius="5px"
outline="none"
onChange={onInputChange}
onFocus={openCommander}
placeholder="Imagine.."
value={inputValue}
></Input>
)
}, [inputRef, inputValue, onInputChange, openCommander])
const MainInput = React.useMemo(() => {
return (
<Center
position="relative"
overflow="hidden"
width={["100%", "400px"]}
maxWidth={[mobileVW, "100%"]}
height="100%"
padding="1px"
borderRadius="6px"
pointerEvents="all"
outline="none"
>
{props?.rainbow && (
<Rainbow
opacity={commanderActive ? 0.6 : 0}
position="absolute"
repeats={rainbowRepeats}
opacityTransition="all 2500ms ease"
thickness={10}
></Rainbow>
)}
{InputJSX}
</Center>
)
}, [InputJSX, commanderActive, rainbowRepeats, props?.rainbow, mobileVW])
return ( return (
<ClickAwayListener onClickAway={closeCommander}> <ClickAwayListener onClickAway={closeCommander}>
<Flex <Flex
@ -479,6 +565,7 @@ export const Commander = (props) => {
maxWidth={[mobileVW, "100%"]} maxWidth={[mobileVW, "100%"]}
height="100%" height="100%"
> >
{props?.rainbow && (
<Rainbow <Rainbow
filter="blur(15px)" filter="blur(15px)"
opacity={commanderActive ? 0.25 : 0} opacity={commanderActive ? 0.25 : 0}
@ -487,46 +574,10 @@ export const Commander = (props) => {
opacityTransition="all 1000ms ease" opacityTransition="all 1000ms ease"
overflow="visible" overflow="visible"
> >
<Center {MainInput}
position="relative"
overflow="hidden"
width={["100%", "400px"]}
maxWidth={[mobileVW, "100%"]}
height="100%"
padding="1px"
borderRadius="6px"
pointerEvents="all"
outline="none"
>
<Rainbow
opacity={commanderActive ? 0.6 : 0}
position="absolute"
repeats={rainbowRepeats}
opacityTransition="all 2500ms ease"
thickness={10}
></Rainbow>
<Input
// display='none'
// opacity={0}
ref={inputRef}
sx={{
"&::placeholder": {
color: "greys.dark",
},
}}
width="100%"
height="100%"
background="grey"
border="none"
borderRadius="5px"
outline="none"
onChange={onInputChange}
onFocus={openCommander}
placeholder="Imagine.."
value={inputValue}
></Input>
</Center>
</Rainbow> </Rainbow>
)}
{!props?.rainbow && MainInput}
</Center> </Center>
</Flex> </Flex>
</ClickAwayListener> </ClickAwayListener>

View File

@ -133,13 +133,16 @@ export const Icon = (props) => {
if (["seedling", "seed"]?.includes(name)) { if (["seedling", "seed"]?.includes(name)) {
return "🌱" return "🌱"
} }
if (["undefined"]?.includes(name)) { if (["undefined", "null", "question", "confused"]?.includes(name)) {
return "❓" return "❓"
// return "🌫️" // return "🌫️"
} }
if (["codex", "robot", "ai", "chatgpt"]?.includes(name)) { if (["codex", "robot", "ai", "chatgpt"]?.includes(name)) {
return "🤖" return "🤖"
} }
if (["trash", "bin", "delete", "remove"]?.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 global id="nav"></Commander> <Commander global id="nav" rainbow></Commander>
<Center <Center
width="25px" width="25px"
height="25px" height="25px"

View File

@ -56,6 +56,12 @@ export const Thingtime = (props) => {
[pl] [pl]
) )
const propsRef = React.useRef(props)
React.useEffect(() => {
propsRef.current = props
}, [props])
// 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))
@ -99,15 +105,24 @@ export const Thingtime = (props) => {
return props.thing return props.thing
}, [props.thing, childrenRef.current]) }, [props.thing, childrenRef.current])
const fullPath = React.useMemo(() => {
const ret = props?.fullPath || props?.path
// store this thing in the global db
try {
window.meta.things[ret] = props?.thing
} catch {
// nothing
}
return ret
}, [props?.fullPath, props?.path, props?.thing])
React.useEffect(() => { React.useEffect(() => {
console.log("thingtime changed in path", props?.fullPath) console.log("thingtime changed in path", props?.fullPath)
createDependancies() createDependancies()
}, [thingtime, props?.fullPath, childrenRef]) }, [thingtime, props?.fullPath, childrenRef])
const fullPath = React.useMemo(() => {
return props?.fullPath || props?.path
}, [props?.fullPath, props?.path])
const seen = React.useMemo(() => { const seen = React.useMemo(() => {
if (props?.seen instanceof Array) { if (props?.seen instanceof Array) {
if (props?.seen?.includes(thing)) { if (props?.seen?.includes(thing)) {
@ -460,7 +475,7 @@ export const Thingtime = (props) => {
return ( return (
<AtomicWrapper> <AtomicWrapper>
{/* TODO: Implement UI-less commander */} {/* TODO: Implement UI-less commander */}
{/* <Commander></Commander> */} <Commander path={fullPath} id={uuid}></Commander>
</AtomicWrapper> </AtomicWrapper>
) )
} }
@ -476,6 +491,8 @@ export const Thingtime = (props) => {
renderableValue, renderableValue,
pl, pl,
type, type,
fullPath,
uuid,
AtomicWrapper, AtomicWrapper,
props?.edit, props?.edit,
thing, thing,

View File

@ -1,18 +1,18 @@
export const safe = (props) => { export const safe = (props) => {
// do not render more than the limit of things to prevent infinite loops // do not render more than the limit of things to prevent infinite loops
const thingtime = getThingtime() const meta = getMeta()
const uuid = props?.uuid const uuid = props?.uuid
try { try {
if ( if (
typeof thingtime?.things?.count === "number" && typeof meta?.stats?.count === "number" &&
thingtime?.things?.count >= thingtime?.things?.limit meta?.stats?.count >= meta?.stats?.limit
) { ) {
console.error( console.error(
"[codex] Maximum things reached", "[codex] Maximum things reached",
thingtime?.things?.count, meta?.stats?.count,
thingtime?.things?.limit meta?.stats?.limit
) )
return null return null
} }
@ -21,22 +21,22 @@ export const safe = (props) => {
} }
try { try {
if (!thingtime?.things?.db?.[uuid]) { if (!meta?.stats?.db?.[uuid]) {
thingtime.things.db[uuid] = { meta.stats.db[uuid] = {
count: 1, count: 1,
} }
thingtime.things.count++ meta.stats.count++
} }
} catch { } catch {
// empty // empty
} }
try { try {
if (props?.depth >= thingtime?.things?.maxDepth) { if (props?.depth >= meta?.stats?.maxDepth) {
console.error( console.error(
"[codex] Reached max depth", "[codex] Reached max depth",
props?.depth, props?.depth,
thingtime?.things?.maxDepth meta?.stats?.maxDepth
) )
return null return null
} }
@ -51,7 +51,7 @@ export const safe = (props) => {
} }
} }
export const getThingtime = () => { export const getMeta = () => {
try { try {
return window?.meta || globalThis?.meta return window?.meta || globalThis?.meta
} catch { } catch {

View File

@ -65,12 +65,13 @@ const setThingtime = (glob) => {
subscribers: {}, subscribers: {},
state: {}, state: {},
db: {}, db: {},
things: { stats: {
db: {}, db: {},
limit: 9999, limit: 9999,
maxDepth: 10, maxDepth: 10,
count: 0, count: 0,
}, },
things: {},
} }
} catch (err) { } catch (err) {
// will error on server // will error on server