feat: feature/commander-updates
This commit is contained in:
parent
21ad6d7ba2
commit
71d9fade5e
@ -1,4 +1,5 @@
|
|||||||
import React, { createContext } from "react"
|
import React, { createContext } from "react"
|
||||||
|
import { parse, stringify } from "flatted"
|
||||||
|
|
||||||
import { sanitise } from "~/functions/sanitise"
|
import { sanitise } from "~/functions/sanitise"
|
||||||
import { smarts } from "~/smarts"
|
import { smarts } from "~/smarts"
|
||||||
@ -22,7 +23,7 @@ try {
|
|||||||
|
|
||||||
const force = {
|
const force = {
|
||||||
settings: {
|
settings: {
|
||||||
commanderActive: false,
|
// commanderActive: false,
|
||||||
},
|
},
|
||||||
version: 22,
|
version: 22,
|
||||||
}
|
}
|
||||||
@ -39,7 +40,7 @@ const newVersionData = {
|
|||||||
|
|
||||||
const initialValues = {
|
const initialValues = {
|
||||||
settings: {
|
settings: {
|
||||||
commanderActive: true,
|
commanderActive: false,
|
||||||
clearCommanderOnToggle: true,
|
clearCommanderOnToggle: true,
|
||||||
clearCommanderContextOnToggle: true,
|
clearCommanderContextOnToggle: true,
|
||||||
},
|
},
|
||||||
@ -54,47 +55,41 @@ const initialValues = {
|
|||||||
|
|
||||||
const initialThingtime = smarts.merge(initialValues, force)
|
const initialThingtime = smarts.merge(initialValues, force)
|
||||||
|
|
||||||
|
// TODO: Make localStorage be loaded first before initialValues if local version exists
|
||||||
|
// and is valid
|
||||||
|
// Issue seems to be server id is different to client hydration
|
||||||
|
|
||||||
|
// let thingtimeToUse = initialThingtime
|
||||||
|
|
||||||
|
// try {
|
||||||
|
// const thingtimeFromLocalStorage = window.localStorage.getItem("thingtime")
|
||||||
|
|
||||||
|
// if (thingtimeFromLocalStorage) {
|
||||||
|
// const parsed = parse(thingtimeFromLocalStorage)
|
||||||
|
// if (parsed) {
|
||||||
|
// const localIsValid = !parsed.version || parsed.version >= force.version
|
||||||
|
// if (localIsValid) {
|
||||||
|
// const newThingtime = smarts.merge(force, parsed)
|
||||||
|
// console.log("nik comm newThingtime", newThingtime)
|
||||||
|
// thingtimeToUse = newThingtime
|
||||||
|
// } else {
|
||||||
|
// const withVersionUpdates = smarts.merge(newVersionData, parsed)
|
||||||
|
// const newThingtime = smarts.merge(force, withVersionUpdates)
|
||||||
|
// thingtimeToUse = newThingtime
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (err) {
|
||||||
|
// console.error("Caught error restoring thingtime from localstorage", err)
|
||||||
|
// }
|
||||||
|
|
||||||
export const ThingtimeProvider = (props: any): JSX.Element => {
|
export const ThingtimeProvider = (props: any): JSX.Element => {
|
||||||
const [thingtime, set] = React.useState(smarts.merge(initialValues, force))
|
const [thingtime, set] = React.useState(initialThingtime)
|
||||||
|
|
||||||
const thingtimeRef = React.useRef(thingtime)
|
const thingtimeRef = React.useRef(thingtime)
|
||||||
|
const stateRef = React.useRef({
|
||||||
// get thingtime from localstorage
|
c: 1,
|
||||||
React.useEffect(() => {
|
})
|
||||||
try {
|
|
||||||
const thingtimeFromLocalStorage = window.localStorage.getItem("thingtime")
|
|
||||||
|
|
||||||
if (thingtimeFromLocalStorage) {
|
|
||||||
const parsed = JSON.parse(thingtimeFromLocalStorage)
|
|
||||||
if (parsed) {
|
|
||||||
const localIsValid =
|
|
||||||
!parsed.version || parsed.version >= force.version
|
|
||||||
if (localIsValid) {
|
|
||||||
const newThingtime = smarts.merge(force, parsed)
|
|
||||||
console.log("nik comm newThingtime", newThingtime)
|
|
||||||
set(newThingtime)
|
|
||||||
} else {
|
|
||||||
const withVersionUpdates = smarts.merge(newVersionData, parsed)
|
|
||||||
const newThingtime = smarts.merge(force, withVersionUpdates)
|
|
||||||
set(newThingtime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("There was an error getting thingtime from localStorage")
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
|
||||||
thingtimeRef.current = thingtime
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log("Setting thingtime to localStorage")
|
|
||||||
window.localStorage.setItem("thingtime", JSON.stringify(thingtime))
|
|
||||||
} catch (err) {
|
|
||||||
console.error("There was an error saving thingtime to localStorage")
|
|
||||||
}
|
|
||||||
}, [thingtime])
|
|
||||||
|
|
||||||
const setThingtime = React.useCallback(
|
const setThingtime = React.useCallback(
|
||||||
(path, value) => {
|
(path, value) => {
|
||||||
@ -106,7 +101,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
|||||||
|
|
||||||
// check if first characters of path starts with thingtime or tt and strip from path
|
// check if first characters of path starts with thingtime or tt and strip from path
|
||||||
|
|
||||||
path = sanitise(path)
|
// path = sanitise(path)
|
||||||
|
|
||||||
smarts.setsmart(newThingtime, path, value)
|
smarts.setsmart(newThingtime, path, value)
|
||||||
|
|
||||||
@ -132,21 +127,69 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
|||||||
const getThingtime = React.useCallback(
|
const getThingtime = React.useCallback(
|
||||||
(...args) => {
|
(...args) => {
|
||||||
const rawPath = args[0]
|
const rawPath = args[0]
|
||||||
if (
|
const path = rawPath
|
||||||
rawPath === "thingtime" ||
|
// do we need to sanitise?
|
||||||
rawPath === "tt" ||
|
// const path = sanitise(rawPath)
|
||||||
rawPath === "." ||
|
|
||||||
!rawPath
|
|
||||||
) {
|
|
||||||
return thingtime
|
|
||||||
}
|
|
||||||
const path = sanitise(rawPath)
|
|
||||||
console.log("Getting thingtime at path", path)
|
console.log("Getting thingtime at path", path)
|
||||||
return smarts.getsmart(thingtime, path)
|
return smarts.getsmart(thingtime, path)
|
||||||
},
|
},
|
||||||
[thingtime]
|
[thingtime]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const populatePaths = React.useCallback((obj, path, paths, seen = []) => {
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
const val = obj[key]
|
||||||
|
const newPath = path ? `${path}${path ? "." : ""}${key}` : key
|
||||||
|
if (typeof val === "object") {
|
||||||
|
paths.push(newPath)
|
||||||
|
if (!seen?.includes(val)) {
|
||||||
|
seen.push(val)
|
||||||
|
populatePaths(val, newPath, paths, seen)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
paths.push(newPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const paths = React.useMemo(() => {
|
||||||
|
// const paths = ["tt", "thingtime", "."]
|
||||||
|
const paths = []
|
||||||
|
|
||||||
|
// populatePaths(thingtime, commandPath)
|
||||||
|
populatePaths(thingtime, "", paths)
|
||||||
|
|
||||||
|
return paths
|
||||||
|
}, [populatePaths, thingtime])
|
||||||
|
|
||||||
|
// get thingtime from localstorage
|
||||||
|
React.useEffect(() => {
|
||||||
|
try {
|
||||||
|
const thingtimeFromLocalStorage = window.localStorage.getItem("thingtime")
|
||||||
|
|
||||||
|
if (thingtimeFromLocalStorage) {
|
||||||
|
const parsed = parse(thingtimeFromLocalStorage)
|
||||||
|
if (parsed) {
|
||||||
|
const localIsValid =
|
||||||
|
!parsed.version || parsed.version >= force.version
|
||||||
|
let newThingtime = null
|
||||||
|
if (localIsValid) {
|
||||||
|
newThingtime = smarts.merge(force, parsed)
|
||||||
|
} else {
|
||||||
|
const withVersionUpdates = smarts.merge(newVersionData, parsed)
|
||||||
|
newThingtime = smarts.merge(force, withVersionUpdates)
|
||||||
|
}
|
||||||
|
console.log("nik setting new thingtime", newThingtime)
|
||||||
|
console.log("nik localIsValid", localIsValid)
|
||||||
|
set(newThingtime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("There was an error getting thingtime from localStorage")
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// thingtime change listener
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
try {
|
try {
|
||||||
window.setThingtime = setThingtime
|
window.setThingtime = setThingtime
|
||||||
@ -156,6 +199,36 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
|||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("nik detected thingtime change", thingtime)
|
||||||
|
|
||||||
|
if (stateRef.current.initialized) {
|
||||||
|
if (thingtime.thingtime !== thingtime || thingtime.tt !== thingtime) {
|
||||||
|
if (!(stateRef?.current?.c >= 10)) {
|
||||||
|
stateRef.current.c++
|
||||||
|
const newThingtime = {
|
||||||
|
...thingtime,
|
||||||
|
}
|
||||||
|
newThingtime.thingtime = newThingtime
|
||||||
|
newThingtime.tt = newThingtime
|
||||||
|
set(newThingtime)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
console.log("Setting thingtime to localStorage", thingtime)
|
||||||
|
setTimeout(() => {
|
||||||
|
const stringified = stringify(thingtime)
|
||||||
|
window.localStorage.setItem("thingtime", stringified)
|
||||||
|
}, 600)
|
||||||
|
} catch (err) {
|
||||||
|
console.error("There was an error saving thingtime to localStorage")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stateRef.current.initialized = true
|
||||||
|
}
|
||||||
|
|
||||||
|
thingtimeRef.current = thingtime
|
||||||
|
|
||||||
const keyListener = (e) => {}
|
const keyListener = (e) => {}
|
||||||
|
|
||||||
window.addEventListener("keydown", keyListener)
|
window.addEventListener("keydown", keyListener)
|
||||||
@ -170,6 +243,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
|
|||||||
setThingtime,
|
setThingtime,
|
||||||
getThingtime,
|
getThingtime,
|
||||||
thingtimeRef,
|
thingtimeRef,
|
||||||
|
paths,
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -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 Fuse from "fuse.js"
|
||||||
|
|
||||||
import { Rainbow } from "../Rainbow/Rainbow"
|
import { Rainbow } from "../Rainbow/Rainbow"
|
||||||
import { Thingtime } from "../Thingtime/Thingtime"
|
import { Thingtime } from "../Thingtime/Thingtime"
|
||||||
@ -10,16 +11,25 @@ import { sanitise } from "~/functions/sanitise"
|
|||||||
import { getParentPath } from "~/smarts"
|
import { getParentPath } from "~/smarts"
|
||||||
|
|
||||||
export const Commander = (props) => {
|
export const Commander = (props) => {
|
||||||
const { thingtime, setThingtime, getThingtime, thingtimeRef } = useThingtime()
|
const { thingtime, setThingtime, getThingtime, thingtimeRef, paths } =
|
||||||
|
useThingtime()
|
||||||
|
|
||||||
const inputRef = React.useRef()
|
const inputRef = React.useRef()
|
||||||
|
|
||||||
const [value, setValue] = React.useState("")
|
const [inputValue, setInputValue] = React.useState("")
|
||||||
|
const [virtualValue, setVirtualValue] = React.useState("")
|
||||||
|
const [hoveredSuggestion, setHoveredSuggestion] = React.useState()
|
||||||
const [active, setActive] = React.useState(false)
|
const [active, setActive] = React.useState(false)
|
||||||
const [contextPath, setContextPath] = React.useState()
|
const [contextPath, setContextPath] = React.useState()
|
||||||
|
|
||||||
const [showContext, setShowContextState] = React.useState(false)
|
const [showContext, setShowContextState] = React.useState(false)
|
||||||
|
|
||||||
|
const mobileVW = React.useMemo(() => {
|
||||||
|
return "calc(100vw - 45px)"
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const rainbowRepeats = 2
|
||||||
|
|
||||||
const setShowContext = React.useCallback(
|
const setShowContext = React.useCallback(
|
||||||
(value, from?: string) => {
|
(value, from?: string) => {
|
||||||
setShowContextState(value)
|
setShowContextState(value)
|
||||||
@ -48,7 +58,8 @@ export const Commander = (props) => {
|
|||||||
document.activeElement.blur()
|
document.activeElement.blur()
|
||||||
|
|
||||||
if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) {
|
if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) {
|
||||||
setValue("")
|
setInputValue("")
|
||||||
|
setHoveredSuggestion(null)
|
||||||
}
|
}
|
||||||
if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) {
|
if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) {
|
||||||
setShowContext(false, "commanderActive useEffect")
|
setShowContext(false, "commanderActive useEffect")
|
||||||
@ -64,13 +75,14 @@ export const Commander = (props) => {
|
|||||||
commanderActive,
|
commanderActive,
|
||||||
thingtimeRef,
|
thingtimeRef,
|
||||||
setShowContext,
|
setShowContext,
|
||||||
value,
|
inputValue,
|
||||||
contextPath,
|
contextPath,
|
||||||
showContext,
|
showContext,
|
||||||
])
|
])
|
||||||
|
|
||||||
const onChange = React.useCallback((e) => {
|
const onInputChange = React.useCallback((e) => {
|
||||||
setValue(e.target.value)
|
setInputValue(e.target.value)
|
||||||
|
setHoveredSuggestion(null)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const validSetters = React.useMemo(() => {
|
const validSetters = React.useMemo(() => {
|
||||||
@ -78,7 +90,9 @@ export const Commander = (props) => {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const command = React.useMemo(() => {
|
const command = React.useMemo(() => {
|
||||||
const sanitizedCommand = sanitise(value)
|
// const sanitizedCommand = sanitise(value)
|
||||||
|
// const sanitizedCommand = inputValue
|
||||||
|
const sanitizedCommand = virtualValue
|
||||||
|
|
||||||
if (sanitizedCommand?.includes(validSetters[0])) {
|
if (sanitizedCommand?.includes(validSetters[0])) {
|
||||||
const indexOfSplitter = sanitizedCommand?.indexOf(validSetters[0])
|
const indexOfSplitter = sanitizedCommand?.indexOf(validSetters[0])
|
||||||
@ -97,10 +111,15 @@ export const Commander = (props) => {
|
|||||||
}
|
}
|
||||||
console.log("nik sanitizedCommand", sanitizedCommand)
|
console.log("nik sanitizedCommand", sanitizedCommand)
|
||||||
return [sanitizedCommand]
|
return [sanitizedCommand]
|
||||||
}, [value, validSetters])
|
}, [
|
||||||
|
// inputValue,
|
||||||
|
virtualValue,
|
||||||
|
validSetters,
|
||||||
|
])
|
||||||
|
|
||||||
const commandPath = React.useMemo(() => {
|
const commandPath = React.useMemo(() => {
|
||||||
return sanitise(command?.[0])
|
return command?.[0]
|
||||||
|
// return sanitise(command?.[0])
|
||||||
}, [command])
|
}, [command])
|
||||||
|
|
||||||
const commandValue = React.useMemo(() => {
|
const commandValue = React.useMemo(() => {
|
||||||
@ -132,64 +151,33 @@ export const Commander = (props) => {
|
|||||||
return commandPath && commandValue
|
return commandPath && commandValue
|
||||||
}, [commandPath, commandValue])
|
}, [commandPath, commandValue])
|
||||||
|
|
||||||
|
const showSuggestions = React.useMemo(() => {
|
||||||
|
return inputValue?.length
|
||||||
|
}, [inputValue])
|
||||||
|
|
||||||
const suggestions = React.useMemo(() => {
|
const suggestions = React.useMemo(() => {
|
||||||
if (value?.length) {
|
const fuse = new Fuse(paths)
|
||||||
const suggestions = ["tt", "thingtime", "."]
|
|
||||||
const populateSuggestions = (obj, path) => {
|
|
||||||
Object.keys(obj).forEach((key) => {
|
|
||||||
const val = obj[key]
|
|
||||||
const newPath = path ? `${path}${path ? "." : ""}${key}` : key
|
|
||||||
if (typeof val === "object") {
|
|
||||||
suggestions.push(newPath)
|
|
||||||
populateSuggestions(val, newPath)
|
|
||||||
} else {
|
|
||||||
suggestions.push(newPath)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// populateSuggestions(thingtime, commandPath)
|
const results = fuse.search(inputValue)
|
||||||
populateSuggestions(thingtime, "")
|
|
||||||
|
|
||||||
// console.log('nik suggestions', suggestions)
|
const mappedResults = results?.map((result) => {
|
||||||
|
return result?.item
|
||||||
|
})
|
||||||
|
|
||||||
const removeSuggestions = [contextPath]
|
return mappedResults
|
||||||
|
}, [inputValue, paths])
|
||||||
|
|
||||||
let ret = []
|
const selectSuggestion = React.useCallback(
|
||||||
|
(suggestionIdx) => {
|
||||||
|
const suggestion = suggestions?.[suggestionIdx]
|
||||||
|
|
||||||
if (commandPath) {
|
setInputValue(suggestion)
|
||||||
const filteredSuggestions = suggestions.filter((suggestion, i) => {
|
setHoveredSuggestion(null)
|
||||||
return (
|
setContextPath(suggestion)
|
||||||
suggestion?.toLowerCase()?.includes(commandPath?.toLowerCase()) ||
|
setShowContext(true, "Select suggestion")
|
||||||
suggestion?.includes(commandPath)
|
},
|
||||||
)
|
[setInputValue, setContextPath, setShowContext, suggestions]
|
||||||
})
|
)
|
||||||
if (!filteredSuggestions?.includes(commandPath)) {
|
|
||||||
const adjustedSuggestions = [commandPath, ...filteredSuggestions]
|
|
||||||
ret = adjustedSuggestions
|
|
||||||
} else {
|
|
||||||
ret = filteredSuggestions
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret = suggestions
|
|
||||||
}
|
|
||||||
|
|
||||||
const filtered = ret.filter((suggestion) => {
|
|
||||||
return !removeSuggestions?.includes(suggestion)
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log("nik useEffect suggestions commandPath", commandPath)
|
|
||||||
console.log("nik useEffect suggestions ret", ret)
|
|
||||||
console.log("nik useEffect suggestions suggestions", suggestions)
|
|
||||||
console.log("nik useEffect suggestions filtered", filtered)
|
|
||||||
|
|
||||||
return filtered
|
|
||||||
|
|
||||||
// if (value) {
|
|
||||||
// setShowContext(true, 'Thingtime changes update suggestions')
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}, [value, thingtime, commandPath, contextPath])
|
|
||||||
|
|
||||||
const commandContainsPath = React.useMemo(() => {
|
const commandContainsPath = React.useMemo(() => {
|
||||||
console.log("nik command", commandPath)
|
console.log("nik command", commandPath)
|
||||||
@ -202,83 +190,17 @@ export const Commander = (props) => {
|
|||||||
return commandIncludesSuggestion
|
return commandIncludesSuggestion
|
||||||
}, [commandPath, suggestions])
|
}, [commandPath, suggestions])
|
||||||
|
|
||||||
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 {
|
|
||||||
console.log("nik Commander onEnter")
|
|
||||||
console.log("nik commandIsAction", commandIsAction)
|
|
||||||
console.log("nik commandContainsPath", commandContainsPath)
|
|
||||||
|
|
||||||
console.log("nik onEnter commandPath", commandPath)
|
|
||||||
|
|
||||||
if (commandIsAction) {
|
|
||||||
// nothing
|
|
||||||
try {
|
|
||||||
const fn = `() => { return ${escapedCommandValue} }`
|
|
||||||
const evalFn = eval(fn)
|
|
||||||
const realVal = evalFn()
|
|
||||||
const prevVal = getThingtime(commandPath)
|
|
||||||
const parentPath = getParentPath(commandPath)
|
|
||||||
setThingtime(commandPath, realVal)
|
|
||||||
if (!prevVal) {
|
|
||||||
setContextPath(parentPath)
|
|
||||||
setShowContext(true, "commandIsAction check")
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.log("setThingtime errored in Commander", err)
|
|
||||||
}
|
|
||||||
} else if (commandContainsPath) {
|
|
||||||
// const prevValue = getThingtime(commandPath)
|
|
||||||
|
|
||||||
// const newValue = setThingtime(commandPath, prevValue)
|
|
||||||
|
|
||||||
console.log("Setting context path", commandPath)
|
|
||||||
setContextPath(commandPath)
|
|
||||||
setShowContext(true, "commandContainsPath check")
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error("Caught error on commander onEnter", err)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
setShowContext,
|
|
||||||
escapedCommandValue,
|
|
||||||
setThingtime,
|
|
||||||
getThingtime,
|
|
||||||
commandIsAction,
|
|
||||||
commandPath,
|
|
||||||
commandContainsPath,
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
// trigger on enter
|
|
||||||
const onKeyDown = React.useCallback(
|
|
||||||
(e) => {
|
|
||||||
if (e.key === "Enter") {
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
onEnter({ e })
|
|
||||||
// setThingtime(
|
|
||||||
// 'settings.commanderActive',
|
|
||||||
// !thingtime?.settings?.commanderActive
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[onEnter]
|
|
||||||
)
|
|
||||||
|
|
||||||
const openCommander = React.useCallback(() => {
|
const openCommander = React.useCallback(() => {
|
||||||
console.log("nik commander opening commander")
|
console.log("nik commander opening commander")
|
||||||
setThingtime("settings.commanderActive", true)
|
setThingtime("settings.commanderActive", true)
|
||||||
}, [setThingtime])
|
}, [setThingtime])
|
||||||
|
|
||||||
const closeCommander = React.useCallback(
|
const closeCommander = React.useCallback(
|
||||||
(e) => {
|
(e?: any) => {
|
||||||
console.log("nik e", e)
|
console.log("nik e", e)
|
||||||
if (thingtime?.settings?.commanderActive) {
|
if (thingtime?.settings?.commanderActive) {
|
||||||
console.log("nik commander closing commander")
|
console.log("nik commander closing commander")
|
||||||
|
console.log("nik setting commanderActive to false")
|
||||||
setThingtime("settings.commanderActive", false)
|
setThingtime("settings.commanderActive", false)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -293,51 +215,122 @@ export const Commander = (props) => {
|
|||||||
}
|
}
|
||||||
}, [thingtime?.settings?.commanderActive, closeCommander, openCommander])
|
}, [thingtime?.settings?.commanderActive, closeCommander, openCommander])
|
||||||
|
|
||||||
React.useEffect(() => {
|
const allCommanderKeyListener = React.useCallback(
|
||||||
const keyListener = (e: any) => {
|
(e: any) => {
|
||||||
|
console.log("commander key listener e?.code", e?.code)
|
||||||
if (e?.metaKey && e?.code === "KeyP") {
|
if (e?.metaKey && e?.code === "KeyP") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
toggleCommander()
|
toggleCommander()
|
||||||
}
|
}
|
||||||
// if key escape close all modals
|
// if key escape close all modals
|
||||||
console.log("commander key listener e?.code", e?.code)
|
else if (e?.code === "Escape") {
|
||||||
if (e?.code === "Escape") {
|
|
||||||
closeCommander()
|
closeCommander()
|
||||||
}
|
}
|
||||||
}
|
// if arrow keys then move selection
|
||||||
|
else if (e?.code === "ArrowUp") {
|
||||||
|
// move selection up
|
||||||
|
const curSuggestionIdx =
|
||||||
|
typeof hoveredSuggestion === "number"
|
||||||
|
? hoveredSuggestion
|
||||||
|
: suggestions?.length
|
||||||
|
const newSuggestionIdx = curSuggestionIdx - 1
|
||||||
|
if (newSuggestionIdx >= 0) {
|
||||||
|
setHoveredSuggestion(newSuggestionIdx)
|
||||||
|
} else {
|
||||||
|
setHoveredSuggestion(suggestions?.length - 1)
|
||||||
|
}
|
||||||
|
} else if (e?.code === "ArrowDown") {
|
||||||
|
// move selection down
|
||||||
|
const curSuggestionIdx =
|
||||||
|
typeof hoveredSuggestion === "number" ? hoveredSuggestion : -1
|
||||||
|
const newSuggestionIdx = curSuggestionIdx + 1
|
||||||
|
if (newSuggestionIdx < suggestions?.length) {
|
||||||
|
setHoveredSuggestion(newSuggestionIdx)
|
||||||
|
} else {
|
||||||
|
setHoveredSuggestion(0)
|
||||||
|
}
|
||||||
|
} else if (e?.code === "Enter") {
|
||||||
|
// if selection is active then select it
|
||||||
|
const curSuggestionIdx = hoveredSuggestion
|
||||||
|
if (curSuggestionIdx !== null) {
|
||||||
|
selectSuggestion(curSuggestionIdx)
|
||||||
|
}
|
||||||
|
if (commanderActive) {
|
||||||
|
try {
|
||||||
|
console.log("nik Commander onEnter")
|
||||||
|
console.log("nik commandIsAction", commandIsAction)
|
||||||
|
console.log("nik commandContainsPath", commandContainsPath)
|
||||||
|
|
||||||
window.addEventListener("keydown", keyListener)
|
console.log("nik onEnter commandPath", commandPath)
|
||||||
|
|
||||||
return () => {
|
if (commandIsAction) {
|
||||||
window.removeEventListener("keydown", keyListener)
|
// nothing
|
||||||
}
|
try {
|
||||||
}, [setThingtime, thingtime, toggleCommander, closeCommander])
|
const fn = `() => { return ${escapedCommandValue} }`
|
||||||
|
const evalFn = eval(fn)
|
||||||
|
const realVal = evalFn()
|
||||||
|
const prevVal = getThingtime(commandPath)
|
||||||
|
const parentPath = getParentPath(commandPath)
|
||||||
|
setThingtime(commandPath, realVal)
|
||||||
|
if (!prevVal) {
|
||||||
|
setContextPath(parentPath)
|
||||||
|
setShowContext(true, "commandIsAction check")
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.log("setThingtime errored in Commander", err)
|
||||||
|
}
|
||||||
|
} else if (commandContainsPath) {
|
||||||
|
// const prevValue = getThingtime(commandPath)
|
||||||
|
|
||||||
const selectSuggestion = React.useCallback(
|
// const newValue = setThingtime(commandPath, prevValue)
|
||||||
(suggestion) => {
|
|
||||||
setValue(suggestion)
|
console.log("Setting context path", commandPath)
|
||||||
setContextPath(suggestion)
|
setContextPath(commandPath)
|
||||||
setShowContext(true, "Select suggestion")
|
setShowContext(true, "commandContainsPath check")
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Caught error on commander onEnter", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[setValue, setContextPath, setShowContext]
|
[
|
||||||
|
closeCommander,
|
||||||
|
toggleCommander,
|
||||||
|
hoveredSuggestion,
|
||||||
|
selectSuggestion,
|
||||||
|
suggestions,
|
||||||
|
commanderActive,
|
||||||
|
commandIsAction,
|
||||||
|
commandContainsPath,
|
||||||
|
commandPath,
|
||||||
|
escapedCommandValue,
|
||||||
|
getThingtime,
|
||||||
|
setThingtime,
|
||||||
|
setShowContext,
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
const excludedSuggestions = React.useMemo(() => {
|
React.useEffect(() => {
|
||||||
return ["."]
|
window.addEventListener("keydown", allCommanderKeyListener)
|
||||||
}, [])
|
|
||||||
|
|
||||||
const renderedSuggestions = React.useMemo(() => {
|
return () => {
|
||||||
return suggestions?.filter((suggestion) => {
|
window.removeEventListener("keydown", allCommanderKeyListener)
|
||||||
return !excludedSuggestions?.includes(suggestion)
|
}
|
||||||
})
|
}, [allCommanderKeyListener])
|
||||||
}, [suggestions, excludedSuggestions])
|
|
||||||
|
|
||||||
const mobileVW = React.useMemo(() => {
|
React.useEffect(() => {
|
||||||
return "calc(100vw - 45px)"
|
if (typeof hoveredSuggestion === "number") {
|
||||||
}, [])
|
setVirtualValue(suggestions?.[hoveredSuggestion])
|
||||||
|
} else {
|
||||||
|
setVirtualValue(inputValue)
|
||||||
|
}
|
||||||
|
}, [hoveredSuggestion, inputValue, suggestions])
|
||||||
|
|
||||||
const rainbowRepeats = 2
|
React.useEffect(() => {
|
||||||
|
setVirtualValue(inputValue)
|
||||||
|
}, [inputValue])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClickAwayListener onClickAway={closeCommander}>
|
<ClickAwayListener onClickAway={closeCommander}>
|
||||||
@ -374,7 +367,7 @@ export const Commander = (props) => {
|
|||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
display={renderedSuggestions?.length ? "flex" : "none"}
|
display={showSuggestions ? "flex" : "none"}
|
||||||
width={["100%", "400px"]}
|
width={["100%", "400px"]}
|
||||||
maxWidth="100%"
|
maxWidth="100%"
|
||||||
marginBottom={3}
|
marginBottom={3}
|
||||||
@ -382,17 +375,20 @@ export const Commander = (props) => {
|
|||||||
borderRadius="12px"
|
borderRadius="12px"
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
id="commander-suggestions"
|
id="commander-suggestions"
|
||||||
|
onMouseLeave={() => setHoveredSuggestion(null)}
|
||||||
paddingY={3}
|
paddingY={3}
|
||||||
>
|
>
|
||||||
{renderedSuggestions?.map((suggestion, i) => {
|
{suggestions?.map((suggestion, i) => {
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
key={i}
|
key={i}
|
||||||
|
background={hoveredSuggestion === i ? "greys.lightt" : null}
|
||||||
_hover={{
|
_hover={{
|
||||||
bg: "greys.lightt",
|
background: "greys.lightt",
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => selectSuggestion(suggestion)}
|
onClick={() => selectSuggestion(i)}
|
||||||
|
onMouseEnter={() => setHoveredSuggestion(i)}
|
||||||
paddingX={4}
|
paddingX={4}
|
||||||
>
|
>
|
||||||
{suggestion}
|
{suggestion}
|
||||||
@ -458,11 +454,10 @@ export const Commander = (props) => {
|
|||||||
border="none"
|
border="none"
|
||||||
borderRadius="5px"
|
borderRadius="5px"
|
||||||
outline="none"
|
outline="none"
|
||||||
onChange={onChange}
|
onChange={onInputChange}
|
||||||
onFocus={openCommander}
|
onFocus={openCommander}
|
||||||
onKeyDown={onKeyDown}
|
|
||||||
placeholder="Imagine.."
|
placeholder="Imagine.."
|
||||||
value={value}
|
value={inputValue}
|
||||||
></Input>
|
></Input>
|
||||||
</Center>
|
</Center>
|
||||||
</Rainbow>
|
</Rainbow>
|
||||||
|
@ -73,7 +73,7 @@ export const Rainbow = (allProps: any): JSX.Element => {
|
|||||||
const keyframe = `${(i / (repeatedColours.length - 1)) * 100}%`
|
const keyframe = `${(i / (repeatedColours.length - 1)) * 100}%`
|
||||||
ret[keyframe] = {
|
ret[keyframe] = {
|
||||||
fill: colour,
|
fill: colour,
|
||||||
"animation-timing-function": "ease-out",
|
animationTimingFunction: "ease-out",
|
||||||
stroke: colour,
|
stroke: colour,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -108,10 +108,8 @@ export const Rainbow = (allProps: any): JSX.Element => {
|
|||||||
}, [state?.width, state?.height])
|
}, [state?.width, state?.height])
|
||||||
|
|
||||||
const svg = React.useMemo(() => {
|
const svg = React.useMemo(() => {
|
||||||
const id = Math.random().toString(36).substring(2, 15)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box width="100%" height="100%" id={id}>
|
<Box width="100%" height="100%" id={"rainbow-svg-container-" + uuid}>
|
||||||
<svg
|
<svg
|
||||||
overflow="visible"
|
overflow="visible"
|
||||||
viewBox={`0 0 ${state?.width || 100} ${state?.height || 100}`}
|
viewBox={`0 0 ${state?.width || 100} ${state?.height || 100}`}
|
||||||
@ -130,7 +128,7 @@ export const Rainbow = (allProps: any): JSX.Element => {
|
|||||||
</svg>
|
</svg>
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
}, [state, rect])
|
}, [state, rect, uuid])
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (uuid) {
|
if (uuid) {
|
||||||
|
@ -21,7 +21,7 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
const pr = React.useMemo(() => {
|
const pr = React.useMemo(() => {
|
||||||
return props?.pr || (depth === 1 ? [4, 6] : 0)
|
return props?.pr || (depth === 1 ? [4, 6] : 0)
|
||||||
}, [props?.pr])
|
}, [props?.pr, depth])
|
||||||
|
|
||||||
// will only run on the client
|
// will only run on the client
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
@ -34,6 +34,21 @@ export const Thingtime = (props) => {
|
|||||||
return props.thing
|
return props.thing
|
||||||
}, [props.thing])
|
}, [props.thing])
|
||||||
|
|
||||||
|
const seen = React.useMemo(() => {
|
||||||
|
if (props?.seen instanceof Array) {
|
||||||
|
if (props?.seen?.includes(thing)) {
|
||||||
|
return props?.seen
|
||||||
|
} else if (typeof thing === "object") {
|
||||||
|
return [...props.seen, thing]
|
||||||
|
}
|
||||||
|
return props?.seen || []
|
||||||
|
}
|
||||||
|
if (typeof thing === "object") {
|
||||||
|
return [thing]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, [props?.seen, thing])
|
||||||
|
|
||||||
const mode = React.useMemo(() => {
|
const mode = React.useMemo(() => {
|
||||||
return "view"
|
return "view"
|
||||||
}, [])
|
}, [])
|
||||||
@ -67,7 +82,7 @@ export const Thingtime = (props) => {
|
|||||||
const trimmed = thing.trim()
|
const trimmed = thing.trim()
|
||||||
|
|
||||||
if (!trimmed) {
|
if (!trimmed) {
|
||||||
return "Empty string"
|
return ""
|
||||||
}
|
}
|
||||||
return trimmed
|
return trimmed
|
||||||
} else if (type === "number") {
|
} else if (type === "number") {
|
||||||
@ -85,11 +100,11 @@ export const Thingtime = (props) => {
|
|||||||
try {
|
try {
|
||||||
return JSON.stringify(thing, null, 2)
|
return JSON.stringify(thing, null, 2)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(
|
// console.error(
|
||||||
"Caught error making renderableValue of thing",
|
// "Caught error making renderableValue of thing",
|
||||||
err,
|
// err,
|
||||||
thing
|
// thing
|
||||||
)
|
// )
|
||||||
return "Circular reference in object."
|
return "Circular reference in object."
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -145,7 +160,7 @@ export const Thingtime = (props) => {
|
|||||||
const template1Modes = ["view", "edit"]
|
const template1Modes = ["view", "edit"]
|
||||||
|
|
||||||
if (template1Modes?.includes(mode)) {
|
if (template1Modes?.includes(mode)) {
|
||||||
if (keys?.length) {
|
if (keys?.length && !props?.circular) {
|
||||||
value = (
|
value = (
|
||||||
<Safe {...props}>
|
<Safe {...props}>
|
||||||
<Flex
|
<Flex
|
||||||
@ -168,9 +183,17 @@ export const Thingtime = (props) => {
|
|||||||
|
|
||||||
const nextThing = thing[key?.key]
|
const nextThing = thing[key?.key]
|
||||||
|
|
||||||
|
const nextSeen = [...seen]
|
||||||
|
|
||||||
|
if (typeof nextThing === "object") {
|
||||||
|
nextSeen.push(nextThing)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Thingtime
|
<Thingtime
|
||||||
key={idx}
|
key={idx}
|
||||||
|
seen={nextSeen}
|
||||||
|
circular={seen?.includes?.(nextThing)}
|
||||||
depth={depth + 1}
|
depth={depth + 1}
|
||||||
parent={thing}
|
parent={thing}
|
||||||
path={key}
|
path={key}
|
||||||
@ -272,7 +295,7 @@ export const Thingtime = (props) => {
|
|||||||
onMouseLeave={handleMouseEvent}
|
onMouseLeave={handleMouseEvent}
|
||||||
// minW={depth === 1 ? '120px' : null}
|
// minW={depth === 1 ? '120px' : null}
|
||||||
paddingY={3}
|
paddingY={3}
|
||||||
{...props}
|
{...(props.chakras || {})}
|
||||||
className={`thing-${uuid?.current}`}
|
className={`thing-${uuid?.current}`}
|
||||||
>
|
>
|
||||||
{/* {uuid?.current} */}
|
{/* {uuid?.current} */}
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
import { Text } from '@chakra-ui/react'
|
import React from "react"
|
||||||
import React from 'react'
|
import { Text } from "@chakra-ui/react"
|
||||||
|
|
||||||
export const RainbowText = props => {
|
export const RainbowText = (props) => {
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
as='h1'
|
as="h1"
|
||||||
userSelect={'none'}
|
|
||||||
position='relative'
|
|
||||||
fontSize='6xl'
|
|
||||||
fontWeight='bold'
|
|
||||||
backgroundClip={'text'}
|
|
||||||
color='transparent'
|
|
||||||
bgGradient='linear-gradient(to right, #f34a4a, #ffbc48, #58ca70, #47b5e6, #a555e8, #f34a4a)'
|
|
||||||
backgroundSize='200%'
|
|
||||||
sx={{
|
sx={{
|
||||||
'@keyframes moving-rainbow': {
|
"@keyframes moving-rainbow": {
|
||||||
'0%': { backgroundPosition: '0 0' },
|
"0%": { backgroundPosition: "0 0" },
|
||||||
'100%': { backgroundPosition: '200% 0' }
|
"100%": { backgroundPosition: "200% 0" },
|
||||||
},
|
},
|
||||||
animation: 'moving-rainbow 5s infinite linear'
|
animation: "moving-rainbow 5s infinite linear",
|
||||||
}}
|
}}
|
||||||
|
position="relative"
|
||||||
|
color="transparent"
|
||||||
|
fontSize="6xl"
|
||||||
|
fontWeight="bold"
|
||||||
|
backgroundSize="200%"
|
||||||
|
bgGradient="linear-gradient(to right, #f34a4a, #ffbc48, #58ca70, #47b5e6, #a555e8, #f34a4a)"
|
||||||
|
backgroundClip="text"
|
||||||
|
userSelect="none"
|
||||||
>
|
>
|
||||||
{props?.children}
|
{props?.children}
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -1,26 +1,15 @@
|
|||||||
export const sanitise = (str) => {
|
export const sanitise = (str) => {
|
||||||
let ret = ""
|
return str
|
||||||
|
|
||||||
|
// TODO: maybe sanitise
|
||||||
|
|
||||||
|
const ret = ""
|
||||||
|
|
||||||
const value = str?.trim()
|
const value = str?.trim()
|
||||||
|
|
||||||
const sanitised = ["tt", "thingtime"]
|
// remove any leading "tt" or "thingtime"
|
||||||
|
|
||||||
const suffixes = [".", " "]
|
const toSanitise = ["tt", "thingtime"]
|
||||||
|
|
||||||
// find combination of sanitised + suffixes which str starts with
|
|
||||||
|
|
||||||
const match = sanitised.find((s) => value?.startsWith(s))
|
|
||||||
const withSuffix = suffixes.find(
|
|
||||||
(s) => match?.length && value[match?.length] === s
|
|
||||||
)
|
|
||||||
const noSuffix = match && value?.length === match?.length
|
|
||||||
|
|
||||||
if (match && withSuffix) {
|
|
||||||
ret = value?.slice(match.length + 1)
|
|
||||||
} else if (!noSuffix) {
|
|
||||||
ret = value
|
|
||||||
}
|
|
||||||
console.log("nik thingtime sanitis 1", match, withSuffix, ret)
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { ChakraWrapper } from './Providers/Chakra/ChakraWrapper'
|
|
||||||
// import type { MetaFunction } from "@vercel/remix"
|
// import type { MetaFunction } from "@vercel/remix"
|
||||||
import {
|
import {
|
||||||
Links,
|
Links,
|
||||||
@ -6,24 +5,26 @@ import {
|
|||||||
Meta,
|
Meta,
|
||||||
Outlet,
|
Outlet,
|
||||||
Scripts,
|
Scripts,
|
||||||
ScrollRestoration
|
ScrollRestoration,
|
||||||
} from '@remix-run/react'
|
} from "@remix-run/react"
|
||||||
import { Analytics } from '@vercel/analytics/react'
|
import { Analytics } from "@vercel/analytics/react"
|
||||||
import { Main } from './components/Layout/Main'
|
|
||||||
import { ThingtimeProvider } from './Providers/ThingtimeProvider'
|
|
||||||
|
|
||||||
function Document ({
|
import { Main } from "./components/Layout/Main"
|
||||||
|
import { ChakraWrapper } from "./Providers/Chakra/ChakraWrapper"
|
||||||
|
import { ThingtimeProvider } from "./Providers/ThingtimeProvider"
|
||||||
|
|
||||||
|
function Document({
|
||||||
children,
|
children,
|
||||||
title = 'Thingtime'
|
title = "Thingtime",
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
title?: string
|
title?: string
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang='en'>
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charSet='utf-8' />
|
<meta charSet="utf-8" />
|
||||||
<meta name='viewport' content='width=device-width,initial-scale=1' />
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
<Meta />
|
<Meta />
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
<Links />
|
<Links />
|
||||||
@ -39,7 +40,7 @@ function Document ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function App () {
|
export default function App() {
|
||||||
return (
|
return (
|
||||||
<Document>
|
<Document>
|
||||||
<ChakraWrapper>
|
<ChakraWrapper>
|
||||||
@ -54,7 +55,7 @@ export default function App () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// limiter
|
// limiter
|
||||||
const setThingtime = glob => {
|
const setThingtime = (glob) => {
|
||||||
try {
|
try {
|
||||||
glob.thingtime = {
|
glob.thingtime = {
|
||||||
tmp: {},
|
tmp: {},
|
||||||
@ -64,8 +65,8 @@ const setThingtime = glob => {
|
|||||||
db: {},
|
db: {},
|
||||||
limit: 9999,
|
limit: 9999,
|
||||||
maxDepth: 10,
|
maxDepth: 10,
|
||||||
count: 0
|
count: 0,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// will error on server
|
// will error on server
|
||||||
|
@ -20,13 +20,20 @@ export default function Index() {
|
|||||||
{/* <Box paddingTop={200}></Box> */}
|
{/* <Box paddingTop={200}></Box> */}
|
||||||
<Splash></Splash>
|
<Splash></Splash>
|
||||||
<Thingtime
|
<Thingtime
|
||||||
marginBottom={200}
|
chakras={{
|
||||||
|
marginBottom: 200,
|
||||||
|
}}
|
||||||
width="600px"
|
width="600px"
|
||||||
path="Content"
|
path="Content"
|
||||||
valuePl={0}
|
valuePl={0}
|
||||||
thing={thingtime["Content"]}
|
thing={thingtime["Content"]}
|
||||||
></Thingtime>
|
></Thingtime>
|
||||||
<ThingtimeDemo></ThingtimeDemo>
|
<ThingtimeDemo></ThingtimeDemo>
|
||||||
|
<Thingtime
|
||||||
|
thing={thingtime}
|
||||||
|
chakras={{ marginY: 200 }}
|
||||||
|
width="600px"
|
||||||
|
></Thingtime>
|
||||||
<ProfileDrawer></ProfileDrawer>
|
<ProfileDrawer></ProfileDrawer>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
)
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
"@remix-run/serve": "^1.15.0",
|
"@remix-run/serve": "^1.15.0",
|
||||||
"@vercel/analytics": "^0.1.11",
|
"@vercel/analytics": "^0.1.11",
|
||||||
"@vercel/remix": "^1.15.0",
|
"@vercel/remix": "^1.15.0",
|
||||||
|
"flatted": "^3.2.7",
|
||||||
|
"fuse.js": "^6.6.2",
|
||||||
"gradient-path": "^2.3.0",
|
"gradient-path": "^2.3.0",
|
||||||
"isbot": "latest",
|
"isbot": "latest",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
|
@ -23,6 +23,12 @@ dependencies:
|
|||||||
'@vercel/remix':
|
'@vercel/remix':
|
||||||
specifier: ^1.15.0
|
specifier: ^1.15.0
|
||||||
version: 1.15.0(react-dom@18.2.0)(react@18.2.0)
|
version: 1.15.0(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
flatted:
|
||||||
|
specifier: ^3.2.7
|
||||||
|
version: 3.2.7
|
||||||
|
fuse.js:
|
||||||
|
specifier: ^6.6.2
|
||||||
|
version: 6.6.2
|
||||||
gradient-path:
|
gradient-path:
|
||||||
specifier: ^2.3.0
|
specifier: ^2.3.0
|
||||||
version: 2.3.0
|
version: 2.3.0
|
||||||
@ -6087,7 +6093,6 @@ packages:
|
|||||||
|
|
||||||
/flatted@3.2.7:
|
/flatted@3.2.7:
|
||||||
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
|
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/focus-lock@0.11.6:
|
/focus-lock@0.11.6:
|
||||||
resolution: {integrity: sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==}
|
resolution: {integrity: sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==}
|
||||||
@ -6204,6 +6209,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fuse.js@6.6.2:
|
||||||
|
resolution: {integrity: sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/generic-names@4.0.0:
|
/generic-names@4.0.0:
|
||||||
resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==}
|
resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user