feat: feature/rainbow-component Fixed a few things

This commit is contained in:
Nikolaj Frey 2023-07-07 17:42:14 +10:00
parent c5c0958905
commit 2a8eb22976
7 changed files with 228 additions and 180 deletions

View File

@ -1,45 +1,46 @@
const g = { const g = {
grey: '#F1F1F3', grey: "#F1F1F3",
greys: { greys: {
light: '#F1F1F3', light: "#F1F1F3",
medium: '#E0E0E0', lightt: "#E7E6E8",
dark: '#BDBDBD' medium: "#E0E0E0",
} dark: "#BDBDBD",
},
} }
g.gray = g.grey g.gray = g.grey
g.grays = g.greys g.grays = g.greys
export const colors = { export const colors = {
white: '#FFFFFF', white: "#FFFFFF",
...g, ...g,
black: '#000000', black: "#000000",
// all colors of the chakras // all colors of the chakras
chakras: { chakras: {
root: '#C62828', root: "#C62828",
sacral: '#FF7043', sacral: "#FF7043",
solarPlexus: '#FFEE58', solarPlexus: "#FFEE58",
heart: '#66BB6A', heart: "#66BB6A",
throat: '#42A5F5', throat: "#42A5F5",
thirdEye: '#5C6BC0', thirdEye: "#5C6BC0",
crown: '#AB47BC', crown: "#AB47BC",
red: '#C62828', red: "#C62828",
orange: '#FF7043', orange: "#FF7043",
yellow: '#FFEE58', yellow: "#FFEE58",
green: '#66BB6A', green: "#66BB6A",
blue: '#42A5F5', blue: "#42A5F5",
indigo: '#5C6BC0', indigo: "#5C6BC0",
violet: '#AB47BC' violet: "#AB47BC",
}, },
// all colors of the rainbow // all colors of the rainbow
rainbow: { rainbow: {
red: '#FF0000', red: "#FF0000",
orange: '#FF7F00', orange: "#FF7F00",
yellow: '#FFFF00', yellow: "#FFFF00",
green: '#00FF00', green: "#00FF00",
blue: '#0000FF', blue: "#0000FF",
indigo: '#4B0082', indigo: "#4B0082",
violet: '#8F00FF' violet: "#8F00FF",
} },
} }

View File

@ -22,7 +22,7 @@ try {
const force = { const force = {
settings: { settings: {
commanderActive: true, commanderActive: false,
}, },
version: 22, version: 22,
} }
@ -89,6 +89,7 @@ export const ThingtimeProvider = (props: any): JSX.Element => {
thingtimeRef.current = thingtime thingtimeRef.current = thingtime
try { try {
console.log("Setting thingtime to localStorage")
window.localStorage.setItem("thingtime", JSON.stringify(thingtime)) window.localStorage.setItem("thingtime", JSON.stringify(thingtime))
} catch (err) { } catch (err) {
console.error("There was an error saving thingtime to localStorage") console.error("There was an error saving thingtime to localStorage")

View File

@ -45,14 +45,29 @@ export const Commander = (props) => {
if (commanderActive) { if (commanderActive) {
inputRef?.current?.focus?.() inputRef?.current?.focus?.()
} else { } else {
document.activeElement.blur()
if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) { if (thingtimeRef?.current?.settings?.clearCommanderOnToggle) {
setValue("") setValue("")
} }
if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) { if (thingtimeRef?.current?.settings?.clearCommanderContextOnToggle) {
setShowContext(false, "commanderActive useEffect") setShowContext(false, "commanderActive useEffect")
} }
if (contextPath !== undefined) {
setContextPath(undefined)
} }
}, [commanderActive, thingtimeRef, setShowContext]) if (showContext !== false) {
setShowContext(false)
}
}
}, [
commanderActive,
thingtimeRef,
setShowContext,
value,
contextPath,
showContext,
])
const onChange = React.useCallback((e) => { const onChange = React.useCallback((e) => {
setValue(e.target.value) setValue(e.target.value)
@ -92,16 +107,6 @@ export const Commander = (props) => {
return command?.[1] return command?.[1]
}, [command]) }, [command])
const commandContainsPath = React.useMemo(() => {
console.log("nik command", commandPath)
// const commandIncludesSuggestion = suggestions?.find(suggestion => {
// return commandPath?.includes(suggestion)
// })
// console.log('nik commandIncludesSuggestion', commandIncludesSuggestion)
return false
// return commandIncludesSuggestion
}, [commandPath])
const validQuotations = React.useMemo(() => { const validQuotations = React.useMemo(() => {
return ['"', "'"] return ['"', "'"]
}, []) }, [])
@ -148,34 +153,66 @@ export const Commander = (props) => {
// console.log('nik suggestions', suggestions) // console.log('nik suggestions', suggestions)
console.log("nik useEffect suggestions commandPath", commandPath) const removeSuggestions = [contextPath]
let ret = []
if (commandPath) { if (commandPath) {
const filteredSuggestions = suggestions.filter((suggestion, i) => { const filteredSuggestions = suggestions.filter((suggestion, i) => {
return suggestion?.toLowerCase()?.includes(commandPath?.toLowerCase()) return (
suggestion?.toLowerCase()?.includes(commandPath?.toLowerCase()) ||
suggestion?.includes(commandPath)
)
}) })
if (!filteredSuggestions?.includes(commandPath)) { if (!filteredSuggestions?.includes(commandPath)) {
const adjustedSuggestions = [commandPath, ...filteredSuggestions] const adjustedSuggestions = [commandPath, ...filteredSuggestions]
return adjustedSuggestions ret = adjustedSuggestions
} else { } else {
return filteredSuggestions ret = filteredSuggestions
} }
} else { } else {
return suggestions 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) { // if (value) {
// setShowContext(true, 'Thingtime changes update suggestions') // setShowContext(true, 'Thingtime changes update suggestions')
// } // }
} }
}, [value, thingtime, commandPath]) }, [value, thingtime, commandPath, contextPath])
const commandContainsPath = React.useMemo(() => {
console.log("nik command", commandPath)
console.log("nik suggestions", suggestions)
const commandIncludesSuggestion = suggestions?.find((suggestion) => {
return commandPath?.includes(suggestion)
})
console.log("nik commandIncludesSuggestion", commandIncludesSuggestion)
// return false
return commandIncludesSuggestion
}, [commandPath, suggestions])
const onEnter = React.useCallback( const onEnter = React.useCallback(
(props) => { (props) => {
// if first characters of value equal tt. then run command // if first characters of value equal tt. then run command
// or if first character is a dot then run command // or if first character is a dot then run command
try { try {
console.log("Commander onEnter") console.log("nik Commander onEnter")
console.log("nik commandIsAction", commandIsAction)
console.log("nik commandContainsPath", commandContainsPath)
console.log("nik onEnter commandPath", commandPath)
if (commandIsAction) { if (commandIsAction) {
// nothing // nothing
try { try {
@ -193,6 +230,10 @@ export const Commander = (props) => {
console.log("setThingtime errored in Commander", err) console.log("setThingtime errored in Commander", err)
} }
} else if (commandContainsPath) { } else if (commandContainsPath) {
// const prevValue = getThingtime(commandPath)
// 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") setShowContext(true, "commandContainsPath check")
@ -233,31 +274,16 @@ export const Commander = (props) => {
setThingtime("settings.commanderActive", true) setThingtime("settings.commanderActive", true)
}, [setThingtime]) }, [setThingtime])
const closeCommander = React.useCallback(() => { const closeCommander = React.useCallback(
(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")
setThingtime("settings.commanderActive", false) setThingtime("settings.commanderActive", false)
} }
},
document.activeElement.blur() [setThingtime, thingtime?.settings?.commanderActive]
)
if (value !== "") {
setValue("")
}
if (contextPath !== undefined) {
setContextPath(undefined)
}
if (showContext !== false) {
setShowContext(false)
}
}, [
setThingtime,
setShowContext,
value,
contextPath,
showContext,
thingtime?.settings?.commanderActive,
])
const toggleCommander = React.useCallback(() => { const toggleCommander = React.useCallback(() => {
if (thingtime?.settings?.commanderActive) { if (thingtime?.settings?.commanderActive) {
@ -311,7 +337,7 @@ export const Commander = (props) => {
return "calc(100vw - 45px)" return "calc(100vw - 45px)"
}, []) }, [])
const rainbowRepeats = 1 const rainbowRepeats = 2
return ( return (
<ClickAwayListener onClickAway={closeCommander}> <ClickAwayListener onClickAway={closeCommander}>
@ -326,11 +352,10 @@ export const Commander = (props) => {
justifyContent={["flex-start", "center"]} justifyContent={["flex-start", "center"]}
// display={["flex", commanderActive ? "flex" : "none"]} // display={["flex", commanderActive ? "flex" : "none"]}
maxWidth="100%" maxWidth="100%"
height="100%" height={12}
// height="100%"
pointerEvents="none" pointerEvents="none"
id="commander" id="commander"
paddingX={1}
paddingY={1}
> >
<Flex <Flex
position="absolute" position="absolute"
@ -364,7 +389,7 @@ export const Commander = (props) => {
<Flex <Flex
key={i} key={i}
_hover={{ _hover={{
bg: "greys.medium", bg: "greys.lightt",
}} }}
cursor="pointer" cursor="pointer"
onClick={() => selectSuggestion(suggestion)} onClick={() => selectSuggestion(suggestion)}
@ -397,6 +422,7 @@ export const Commander = (props) => {
opacity={commanderActive ? 0.25 : 0} opacity={commanderActive ? 0.25 : 0}
repeats={rainbowRepeats} repeats={rainbowRepeats}
thickness={8} thickness={8}
opacityTransition="all 1000ms ease"
overflow="visible" overflow="visible"
> >
<Center <Center
@ -411,10 +437,10 @@ export const Commander = (props) => {
outline="none" outline="none"
> >
<Rainbow <Rainbow
opacity={commanderActive ? 0.5 : 0} opacity={commanderActive ? 0.6 : 0}
position="absolute" position="absolute"
repeats={rainbowRepeats} repeats={rainbowRepeats}
opacityTransition="all 3000ms ease" opacityTransition="all 2500ms ease"
thickness={10} thickness={10}
></Rainbow> ></Rainbow>
<Input <Input
@ -435,7 +461,7 @@ export const Commander = (props) => {
onChange={onChange} onChange={onChange}
onFocus={openCommander} onFocus={openCommander}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
placeholder={"What's on your mind?"} placeholder="Imagine.."
value={value} value={value}
></Input> ></Input>
</Center> </Center>

View File

@ -1,10 +1,11 @@
import React from 'react' import React from "react"
import { Box, Flex } from '@chakra-ui/react' import { Box, Flex } from "@chakra-ui/react"
import { RainbowSkeleton } from '../Skeleton/RainbowSkeleton'
import { ProfileDrawer } from './ProfileDrawer'
import { Commander } from '../Commander/Commander'
export const Nav = props => { import { Commander } from "../Commander/Commander"
import { RainbowSkeleton } from "../Skeleton/RainbowSkeleton"
import { ProfileDrawer } from "./ProfileDrawer"
export const Nav = (props) => {
const [profileDrawerOpen, setProfileDrawerOpen] = React.useState(false) const [profileDrawerOpen, setProfileDrawerOpen] = React.useState(false)
const toggleProfileDrawer = React.useCallback(() => { const toggleProfileDrawer = React.useCallback(() => {
@ -14,36 +15,37 @@ export const Nav = props => {
return ( return (
<> <>
<Box <Box
position='fixed' position="fixed"
maxW='100vw'
top={0}
left={0}
right={0}
zIndex={999} zIndex={999}
top={0}
right={0}
left={0}
maxWidth="100vw"
> >
<Flex <Flex
as='nav' as="nav"
w='100%' position="relative"
maxW='100%' alignItems="center"
alignItems={'center'} justifyContent="center"
position='relative' flexDirection="row"
justifyContent='center' width="100%"
flexDir={'row'} maxWidth="100%"
py={'10px'} marginY={1}
px={2} paddingX="12px"
paddingY="10px"
// bg='white' // bg='white'
// boxShadow={'0px 0px 10px rgba(0,0,0,0.1)'} // boxShadow={'0px 0px 10px rgba(0,0,0,0.1)'}
> >
<Commander></Commander> <Commander></Commander>
<RainbowSkeleton <RainbowSkeleton
ml={'auto'} marginLeft="auto"
w='25px' width="25px"
h='25px' height="25px"
cursor='pointer' cursor="pointer"
onClick={toggleProfileDrawer} onClick={toggleProfileDrawer}
bg={'rgba(0,0,0,0.1)'} background="rgba(0,0,0,0.1)"
sx={{}} sx={{}}
borderRadius='999px' borderRadius="999px"
></RainbowSkeleton> ></RainbowSkeleton>
{/* <RainbowSkeleton w='40px' ml='auto' mr={"4px"}></RainbowSkeleton> {/* <RainbowSkeleton w='40px' ml='auto' mr={"4px"}></RainbowSkeleton>
<RainbowSkeleton></RainbowSkeleton> */} <RainbowSkeleton></RainbowSkeleton> */}

View File

@ -7,6 +7,8 @@ import { useTrace } from "~/hooks/useTrace"
import { useUuid } from "~/hooks/useUuid" import { useUuid } from "~/hooks/useUuid"
export const Rainbow = (allProps: any): JSX.Element => { export const Rainbow = (allProps: any): JSX.Element => {
// return allProps.children
const rainbow = ["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"] const rainbow = ["#f34a4a", "#ffbc48", "#58ca70", "#47b5e6", "#a555e8"]
const props = useProps(allProps) const props = useProps(allProps)
@ -71,6 +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",
stroke: colour, stroke: colour,
} }
}) })
@ -153,7 +156,7 @@ export const Rainbow = (allProps: any): JSX.Element => {
width: pathWidth || 1, width: pathWidth || 1,
animation: { animation: {
name: `rainbow-${uuid}`, name: `rainbow-${uuid}`,
duration: 5, duration: props?.duration || 7,
}, },
}) })
@ -169,6 +172,7 @@ export const Rainbow = (allProps: any): JSX.Element => {
} }
}, [ }, [
uuid, uuid,
props?.duration,
props?.segments, props?.segments,
props?.samples, props?.samples,
props?.precision, props?.precision,

View File

@ -1,9 +1,10 @@
import React from 'react' import React from "react"
import { Box, Flex } from '@chakra-ui/react' import { Box, Flex } from "@chakra-ui/react"
import { Safe } from '../Safety/Safe'
import { useThingtime } from './useThingtime'
export const Thingtime = props => { import { Safe } from "../Safety/Safe"
import { useThingtime } from "./useThingtime"
export const Thingtime = (props) => {
// TODO: Add a circular reference seen prop check // TODO: Add a circular reference seen prop check
// and add button to expand circular reference // and add button to expand circular reference
// up to 1 level deep // up to 1 level deep
@ -34,11 +35,11 @@ export const Thingtime = props => {
}, [props.thing]) }, [props.thing])
const mode = React.useMemo(() => { const mode = React.useMemo(() => {
return 'view' return "view"
}, []) }, [])
const validKeyTypes = React.useMemo(() => { const validKeyTypes = React.useMemo(() => {
return ['object', 'array'] return ["object", "array"]
}, []) }, [])
const keys = React.useMemo(() => { const keys = React.useMemo(() => {
@ -55,42 +56,42 @@ export const Thingtime = props => {
}, [thing]) }, [thing])
const valuePl = React.useMemo(() => { const valuePl = React.useMemo(() => {
if (typeof props?.valuePl === 'number') { if (typeof props?.valuePl === "number") {
return props?.valuePl return props?.valuePl
} }
return props?.path ? [4, 6] : [0, 0] return props?.path ? [4, 6] : [0, 0]
}, [props?.valuePl, props?.path]) }, [props?.valuePl, props?.path])
const renderableValue = React.useMemo(() => { const renderableValue = React.useMemo(() => {
if (type === 'string') { if (type === "string") {
if (!thing) { if (!thing) {
return 'Empty string' return "Empty string"
} }
return thing return thing
} else if (type === 'number') { } else if (type === "number") {
return thing return thing
} else if (type === 'boolean') { } else if (type === "boolean") {
return thing ? 'true' : 'false' return thing ? "true" : "false"
} else if (type === 'object') { } else if (type === "object") {
if (thing === null) { if (thing === null) {
return 'null' return "null"
} }
if (!keys?.length) { if (!keys?.length) {
return 'Empty object' return "Something!"
} }
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 {
return 'Undefined' return "Something!"
} }
}, [thing, type]) }, [thing, type])
@ -108,24 +109,24 @@ export const Thingtime = props => {
window.thingtime.tmp[randId] = 0 window.thingtime.tmp[randId] = 0
const recurse = (obj, prefix) => { const recurse = (obj, prefix) => {
Object.keys(obj).forEach(key => { Object.keys(obj).forEach((key) => {
if (typeof obj[key] === 'object') { if (typeof obj[key] === "object") {
if (window?.thingtime?.tmp[randId] < 1000) { if (window?.thingtime?.tmp[randId] < 1000) {
window.thingtime.tmp[randId]++ window.thingtime.tmp[randId]++
recurse(obj[key], `${prefix}${prefix && '.'}${key}`) recurse(obj[key], `${prefix}${prefix && "."}${key}`)
} else { } else {
console.error('Recursion limit reached in Thingtime.tsx') console.error("Recursion limit reached in Thingtime.tsx")
} }
} else { } else {
ret.push({ ret.push({
key: `${prefix}${prefix && '.'}${key}`, key: `${prefix}${prefix && "."}${key}`,
human: `${prefix}${prefix && ' '}${key}` human: `${prefix}${prefix && " "}${key}`,
}) })
} }
}) })
} }
recurse(thing, '') recurse(thing, "")
} catch (err) { } catch (err) {
// console.error('Error in Thingtime.tsx creating flattenedKeys', err) // console.error('Error in Thingtime.tsx creating flattenedKeys', err)
} }
@ -139,27 +140,27 @@ export const Thingtime = props => {
const keysToUse = keys const keysToUse = keys
// const keysToUse = flattenedKeys // const keysToUse = flattenedKeys
const template1Modes = ['view', 'edit'] const template1Modes = ["view", "edit"]
if (template1Modes?.includes(mode)) { if (template1Modes?.includes(mode)) {
if (keys?.length) { if (keys?.length) {
value = ( value = (
<Safe {...props}> <Safe {...props}>
<Flex <Flex
position='relative' position="relative"
flexDir='column' flexDirection="column"
// w={'500px'} // w={'500px'}
// w={['200px', '500px']} // w={['200px', '500px']}
maxW='100%' maxWidth="100%"
py={props?.path ? 3 : 0} paddingLeft={valuePl}
pl={valuePl} paddingY={props?.path ? 3 : 0}
> >
{keysToUse?.length && {keysToUse?.length &&
keysToUse.map((key, idx) => { keysToUse.map((key, idx) => {
if (!key?.human) { if (!key?.human) {
key = { key = {
human: key, human: key,
key: key key: key,
} }
} }
@ -183,13 +184,13 @@ export const Thingtime = props => {
} else { } else {
editableValue = ( editableValue = (
<Box <Box
contentEditable={mode === 'edit'} paddingLeft={pl}
border='none' fontSize="20px"
outline={'none'} border="none"
py={2} whiteSpace="pre-line"
pl={pl} outline="none"
fontSize={'20px'} contentEditable={mode === "edit"}
whiteSpace={'pre-line'} paddingY={2}
// dangerouslySetInnerHTML={{ __html: renderableValue }} // dangerouslySetInnerHTML={{ __html: renderableValue }}
> >
{renderableValue} {renderableValue}
@ -199,7 +200,13 @@ export const Thingtime = props => {
} }
const contextMenu = ( const contextMenu = (
<Flex pr={4} userSelect={'none'} position='absolute' top={0} right={0}> <Flex
position="absolute"
top={0}
right={0}
paddingRight={4}
userSelect="none"
>
Settings Settings
</Flex> </Flex>
) )
@ -207,26 +214,26 @@ export const Thingtime = props => {
const [showContextMenu, setShowContextMenu] = React.useState(false) const [showContextMenu, setShowContextMenu] = React.useState(false)
const humanPath = React.useMemo(() => { const humanPath = React.useMemo(() => {
if (typeof props?.path === 'string') { if (typeof props?.path === "string") {
return props?.path return props?.path
} }
return props?.path?.human || '' return props?.path?.human || ""
}, [props?.path]) }, [props?.path])
const path = React.useMemo(() => { const path = React.useMemo(() => {
if (humanPath?.includes?.('hidden')) { if (humanPath?.includes?.("hidden")) {
return null return null
} }
if (humanPath?.includes?.('unique')) { if (humanPath?.includes?.("unique")) {
// take only path from before the string unique // take only path from before the string unique
return humanPath.split?.('unique')?.[0] return humanPath.split?.("unique")?.[0]
} }
return ( return (
<Flex <Flex
maxW='100%' maxWidth="100%"
pl={props?.pathPl || pl} paddingLeft={props?.pathPl || pl}
wordBreak={'break-all'} fontSize="12px"
fontSize='12px' wordBreak="break-all"
> >
{humanPath} {humanPath}
</Flex> </Flex>
@ -234,12 +241,12 @@ export const Thingtime = props => {
}, [humanPath, pl, props?.pathPl]) }, [humanPath, pl, props?.pathPl])
const handleMouseEvent = React.useCallback( const handleMouseEvent = React.useCallback(
e => { (e) => {
const target = e?.target const target = e?.target
// extract uuid from className // extract uuid from className
const className = target?.className const className = target?.className
if (className?.includes(uuid?.current)) { if (className?.includes(uuid?.current)) {
setShowContextMenu(e?.type === 'mouseenter') setShowContextMenu(e?.type === "mouseenter")
} }
}, },
[uuid] [uuid]
@ -248,15 +255,15 @@ export const Thingtime = props => {
return ( return (
<Safe {...props} depth={depth} uuid={uuid?.current}> <Safe {...props} depth={depth} uuid={uuid?.current}>
<Flex <Flex
position="relative"
flexDirection="column"
width="500px"
maxWidth="100%"
paddingRight={pr}
onMouseEnter={handleMouseEvent} onMouseEnter={handleMouseEvent}
onMouseLeave={handleMouseEvent} onMouseLeave={handleMouseEvent}
position='relative'
flexDir='column'
py={3}
pr={pr}
w='500px'
// minW={depth === 1 ? '120px' : null} // minW={depth === 1 ? '120px' : null}
maxW='100%' paddingY={3}
{...props} {...props}
className={`thing-${uuid?.current}`} className={`thing-${uuid?.current}`}
> >

View File

@ -1,19 +1,26 @@
export const sanitise = str => { export const sanitise = (str) => {
const isTT = str?.slice(0, 3) === 'tt.' let ret = ""
const isThingtime = str?.slice(0, 10) === 'thingtime.'
const isDot = str?.slice(0, 1) === '.'
console.log('nik thingtime sanitis 1', str, isTT, isThingtime, isDot) const value = str?.trim()
if (isTT) { const sanitised = ["tt", "thingtime"]
str = str?.slice(3)
} else if (isThingtime) { const suffixes = [".", " "]
str = str?.slice(9)
} else if (isDot) { // find combination of sanitised + suffixes which str starts with
str = str?.slice(1)
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)
console.log('nik thingtime sanitise 2', str, isTT, isThingtime, isDot) return ret
return str
} }