feature/random-nik-things
This commit is contained in:
parent
e77fe17675
commit
990cd108bd
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,6 +3,8 @@
|
|||||||
.env
|
.env
|
||||||
|
|
||||||
app/node_modules
|
app/node_modules
|
||||||
|
remix/node_modules
|
||||||
|
next/node_modules
|
||||||
app-next/node_modules
|
app-next/node_modules
|
||||||
api/node_modules
|
api/node_modules
|
||||||
node_modules
|
node_modules
|
||||||
|
@ -93,7 +93,6 @@
|
|||||||
"title": "Commander",
|
"title": "Commander",
|
||||||
"description": "Open Thingtime Commander",
|
"description": "Open Thingtime Commander",
|
||||||
"mode": "view",
|
"mode": "view",
|
||||||
"fallbackText": "test2",
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"commander",
|
"commander",
|
||||||
"thingtime",
|
"thingtime",
|
||||||
@ -107,7 +106,38 @@
|
|||||||
"key": "name",
|
"key": "name",
|
||||||
"title": "Name of Command to run",
|
"title": "Name of Command to run",
|
||||||
"description": "The name of the command/function to run",
|
"description": "The name of the command/function to run",
|
||||||
"defaultValue": "Menu"
|
"defaultValue": "MagicInput"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "commanderMagicInput",
|
||||||
|
"title": "Magic Input",
|
||||||
|
"description": "Evaluates a Magic Input",
|
||||||
|
"mode": "no-view",
|
||||||
|
"keywords": [
|
||||||
|
"commander",
|
||||||
|
"thingtime",
|
||||||
|
"ai"
|
||||||
|
],
|
||||||
|
"arguments": [
|
||||||
|
{
|
||||||
|
"placeholder": "Path",
|
||||||
|
"name": "path",
|
||||||
|
"type": "text",
|
||||||
|
"description": "The path to open the new finder window at",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"preferences": [
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"required": false,
|
||||||
|
"type": "textfield",
|
||||||
|
"key": "name",
|
||||||
|
"title": "Name of Command to run",
|
||||||
|
"description": "The name of the command/function to run",
|
||||||
|
"defaultValue": "openNewFinderWindow"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -116,7 +146,6 @@
|
|||||||
"title": "Open New Finder Window",
|
"title": "Open New Finder Window",
|
||||||
"description": "Open new finder window",
|
"description": "Open new finder window",
|
||||||
"mode": "no-view",
|
"mode": "no-view",
|
||||||
"fallbackText": "test2",
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"commander",
|
"commander",
|
||||||
"thingtime",
|
"thingtime",
|
||||||
@ -148,7 +177,6 @@
|
|||||||
"title": "Trim image",
|
"title": "Trim image",
|
||||||
"description": "Will trim all whitespace from an image",
|
"description": "Will trim all whitespace from an image",
|
||||||
"mode": "no-view",
|
"mode": "no-view",
|
||||||
"fallbackText": "test2",
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"commander",
|
"commander",
|
||||||
"thingtime",
|
"thingtime",
|
||||||
@ -171,7 +199,6 @@
|
|||||||
"title": "mp4 to mp3",
|
"title": "mp4 to mp3",
|
||||||
"description": "Converts an mp4 into an mp3 using ffmpeg at 320Kbps",
|
"description": "Converts an mp4 into an mp3 using ffmpeg at 320Kbps",
|
||||||
"mode": "no-view",
|
"mode": "no-view",
|
||||||
"fallbackText": "test2",
|
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"commander",
|
"commander",
|
||||||
"thingtime",
|
"thingtime",
|
||||||
|
11
remix/app/components/Branding/Branding.tsx
Normal file
11
remix/app/components/Branding/Branding.tsx
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { Box, Heading } from '@chakra-ui/react';
|
||||||
|
import { Logo } from './Logo';
|
||||||
|
|
||||||
|
export const Branding = () => {
|
||||||
|
return (
|
||||||
|
<Box w="100%" px={'18px'} maxW={'container'} textAlign={'left'}>
|
||||||
|
<Heading>Branding</Heading>
|
||||||
|
<Logo />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
87
remix/app/components/Branding/Logo.tsx
Normal file
87
remix/app/components/Branding/Logo.tsx
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
import { Box, Center, Flex, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from '@chakra-ui/react';
|
||||||
|
import React, { useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
export const Logo = () => {
|
||||||
|
// a completely dynamic and interactive logo
|
||||||
|
// uses borders, border radius, and colour themes to create a simple timeless beautiful logo
|
||||||
|
|
||||||
|
// const defaultThemeRaw = ['white', '#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
|
||||||
|
const defaultThemeRaw = ['#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
|
||||||
|
|
||||||
|
const [reverseColours, setReverseColours] = useState(false);
|
||||||
|
|
||||||
|
const defaultTheme = reverseColours ? defaultThemeRaw?.reverse() : defaultThemeRaw;
|
||||||
|
|
||||||
|
const [theme, setTheme] = useState('blue');
|
||||||
|
|
||||||
|
const [squares, setSquares] = useState(9);
|
||||||
|
|
||||||
|
const [width, setWidth] = useState(250);
|
||||||
|
|
||||||
|
const [height, setHeight] = useState(250);
|
||||||
|
|
||||||
|
// logo is a T/plus shape made of two intersecting squares
|
||||||
|
// you can toggle border sides on both squares to create different shapes
|
||||||
|
|
||||||
|
const [borderWidth, setBorderWidth] = useState(18);
|
||||||
|
|
||||||
|
const [borderRadius, setBorderRadius] = useState(12);
|
||||||
|
|
||||||
|
const squaresArray = Array.from({ length: squares }, (_, index) => index);
|
||||||
|
|
||||||
|
const [spacing, setSpacing] = useState(borderWidth);
|
||||||
|
|
||||||
|
// log squaresArray
|
||||||
|
console.debug('tt.squaresArray', squaresArray);
|
||||||
|
|
||||||
|
// basically the 5 squares that make up a plus but with the centre one missing
|
||||||
|
|
||||||
|
const [divisions, setDivisions] = useState(3);
|
||||||
|
|
||||||
|
const [divisionHeight, setDivisionHeight] = useState(100 / divisions);
|
||||||
|
|
||||||
|
const [divisionWidth, setDivisionWidth] = useState(100 / divisions);
|
||||||
|
|
||||||
|
const uuid = useMemo(() => {
|
||||||
|
return Math.random().toString(36).substring(2) + Date.now().toString(36);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* these are the controls */}
|
||||||
|
{/* border radius use chakra slider */}
|
||||||
|
<Center py={12}>
|
||||||
|
<Slider aria-label="slider-ex-1" defaultValue={borderRadius} onChange={setBorderRadius}>
|
||||||
|
<SliderTrack>
|
||||||
|
<SliderFilledTrack />
|
||||||
|
</SliderTrack>
|
||||||
|
<SliderThumb>🟡</SliderThumb>
|
||||||
|
</Slider>
|
||||||
|
</Center>
|
||||||
|
<Box className="tt.logo" overflow="hidden" w={width + 'px'} h={height + 'px'} position="relative">
|
||||||
|
{squaresArray.map((_, idx) => {
|
||||||
|
// technically not even in programming terms cause it starts at 0 😂
|
||||||
|
|
||||||
|
const humanIdx = idx + 1;
|
||||||
|
|
||||||
|
const even = humanIdx % 2 === 0;
|
||||||
|
|
||||||
|
const colourIndex = Math.round(idx / 2);
|
||||||
|
|
||||||
|
// log the colourIndex
|
||||||
|
console.debug('tt.colourIndex', colourIndex);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
display="inline-block"
|
||||||
|
key={`logo-${uuid}-${idx}`}
|
||||||
|
bg={even ? defaultTheme[colourIndex] : 'rgba(0,0,0,0)'}
|
||||||
|
w={`${divisionHeight}%`}
|
||||||
|
h={`${divisionWidth}%`}
|
||||||
|
></Box>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
129
remix/app/components/Branding/LogoOld2.tsx
Normal file
129
remix/app/components/Branding/LogoOld2.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import { Box, Center, Flex, Slider, SliderFilledTrack, SliderThumb, SliderTrack } from '@chakra-ui/react';
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
export const LogoOld2 = () => {
|
||||||
|
// a completely dynamic and interactive logo
|
||||||
|
// uses borders, border radius, and colour themes to create a simple timeless beautiful logo
|
||||||
|
|
||||||
|
// const defaultThemeRaw = ['white', '#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
|
||||||
|
const defaultThemeRaw = ['#F20009', '#FD5F00', '#FFEB03', '#52E013', '#09A7EC', '#982E77', 'white'];
|
||||||
|
|
||||||
|
const [reverseColours, setReverseColours] = useState(false);
|
||||||
|
|
||||||
|
const defaultTheme = reverseColours ? defaultThemeRaw?.reverse() : defaultThemeRaw;
|
||||||
|
|
||||||
|
const [theme, setTheme] = useState('blue');
|
||||||
|
|
||||||
|
const [squares, setSquares] = useState(8);
|
||||||
|
|
||||||
|
const [width, setWidth] = useState(50);
|
||||||
|
|
||||||
|
const [height, setHeight] = useState(50);
|
||||||
|
|
||||||
|
// logo is a T/plus shape made of two intersecting squares
|
||||||
|
// you can toggle border sides on both squares to create different shapes
|
||||||
|
|
||||||
|
const [borderWidth, setBorderWidth] = useState(18);
|
||||||
|
|
||||||
|
const [borderRadius, setBorderRadius] = useState(12);
|
||||||
|
|
||||||
|
const squaresArray = Array.from({ length: squares }, (_, index) => index);
|
||||||
|
|
||||||
|
const [spacing, setSpacing] = useState(borderWidth);
|
||||||
|
|
||||||
|
// log squaresArray
|
||||||
|
console.debug('tt.squaresArray', squaresArray);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{/* these are the controls */}
|
||||||
|
{/* border radius use chakra slider */}
|
||||||
|
<Center py={12}>
|
||||||
|
<Slider aria-label="slider-ex-1" defaultValue={borderRadius} onChange={setBorderRadius}>
|
||||||
|
<SliderTrack>
|
||||||
|
<SliderFilledTrack />
|
||||||
|
</SliderTrack>
|
||||||
|
<SliderThumb>🟡</SliderThumb>
|
||||||
|
</Slider>
|
||||||
|
</Center>
|
||||||
|
<Center overflow="hidden" w={width} h={height} position="relative">
|
||||||
|
{/* border top left squares */}
|
||||||
|
{squaresArray.map((_, index) => {
|
||||||
|
const top = index * spacing;
|
||||||
|
const left = index * spacing;
|
||||||
|
const colour = defaultTheme[index];
|
||||||
|
|
||||||
|
const square = (
|
||||||
|
<Box
|
||||||
|
zIndex={2}
|
||||||
|
backgroundColor={colour}
|
||||||
|
borderRadius={`${borderRadius}px`}
|
||||||
|
className="logo-square"
|
||||||
|
position={'absolute'}
|
||||||
|
width={width}
|
||||||
|
top={12}
|
||||||
|
left={12}
|
||||||
|
height={height}
|
||||||
|
transform={`translateY(${top}px) translateX(${left}px)`}
|
||||||
|
>
|
||||||
|
{/* another box which acts as a mask */}
|
||||||
|
|
||||||
|
{/* <Box
|
||||||
|
backgroundColor={theme}
|
||||||
|
borderRadius={`${borderRadius}px`}
|
||||||
|
className="logo-square"
|
||||||
|
position={'absolute'}
|
||||||
|
width={width}
|
||||||
|
top={12}
|
||||||
|
left={12}
|
||||||
|
height={height}
|
||||||
|
top={`${top}px`}
|
||||||
|
left={`${left}px`}
|
||||||
|
/> */}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
return square;
|
||||||
|
})}
|
||||||
|
|
||||||
|
{/* make squares for bottom right */}
|
||||||
|
|
||||||
|
{squaresArray.map((_, index) => {
|
||||||
|
const bottom = index * spacing + height * 2;
|
||||||
|
const right = index * spacing + width * 2;
|
||||||
|
const colour = defaultTheme[index];
|
||||||
|
|
||||||
|
const square = (
|
||||||
|
<Box
|
||||||
|
zIndex={1}
|
||||||
|
backgroundColor={colour}
|
||||||
|
borderRadius={`${borderRadius}px`}
|
||||||
|
className="logo-square"
|
||||||
|
position={'absolute'}
|
||||||
|
width={width}
|
||||||
|
top={14}
|
||||||
|
left={14}
|
||||||
|
height={height}
|
||||||
|
transform={`translateY(${-bottom}px) translateX(${-right}px)`}
|
||||||
|
>
|
||||||
|
{/* another box which acts as a mask */}
|
||||||
|
|
||||||
|
{/* <Box
|
||||||
|
backgroundColor={theme}
|
||||||
|
borderRadius={`${borderRadius}px`}
|
||||||
|
className="logo-square"
|
||||||
|
position={'absolute'}
|
||||||
|
width={width}
|
||||||
|
height={height}
|
||||||
|
top={`${top}px`}
|
||||||
|
left={`${left}px`}
|
||||||
|
/> */}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
|
||||||
|
return square;
|
||||||
|
})}
|
||||||
|
</Center>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -8,8 +8,8 @@ export const Editor = (props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box minH="60vh" w="100%" maxW={'container'} pos={'relative'}>
|
<Box minH="60vh" w="100%" maxW={'container'} pos={'relative'}>
|
||||||
{/* only on client side render editor */}
|
|
||||||
<Flex position="absolute" w={width} h={height} top={0} left={0} right={0} bottom={0}>
|
<Flex position="absolute" w={width} h={height} top={0} left={0} right={0} bottom={0}>
|
||||||
|
{/* only on client side render editor */}
|
||||||
<Suspense fallback={<div>Loading...</div>}>
|
<Suspense fallback={<div>Loading...</div>}>
|
||||||
<MonacoEditor defaultLanguage={defaultLanguage} defaultValue={defaultValue} />
|
<MonacoEditor defaultLanguage={defaultLanguage} defaultValue={defaultValue} />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
@ -136,11 +136,11 @@ export const Nav = (props) => {
|
|||||||
</Center>
|
</Center>
|
||||||
)}
|
)}
|
||||||
{/* TODO - Add conditional only show if loggedIn */}
|
{/* TODO - Add conditional only show if loggedIn */}
|
||||||
<Center transform={['', 'scaleX(-100%)']} cursor="pointer">
|
{/* <Center transform={['', 'scaleX(-100%)']} cursor="pointer">
|
||||||
<Link to="/logout">
|
<Link to="/logout">
|
||||||
<Icon size="12px" name="🗝️"></Icon>
|
<Icon size="12px" name="🗝️"></Icon>
|
||||||
</Link>
|
</Link>
|
||||||
</Center>
|
</Center> */}
|
||||||
<Center transform={['', 'scaleX(-100%)']} cursor="pointer">
|
<Center transform={['', 'scaleX(-100%)']} cursor="pointer">
|
||||||
<Link to="/login">
|
<Link to="/login">
|
||||||
<Icon size="12px" name="🌈"></Icon>
|
<Icon size="12px" name="🌈"></Icon>
|
||||||
|
@ -1,146 +1,143 @@
|
|||||||
import React, { useState } from "react"
|
import React, { useState } from 'react';
|
||||||
import ClickAwayListener from "react-click-away-listener"
|
import ClickAwayListener from 'react-click-away-listener';
|
||||||
import { Center, Flex, Text } from "@chakra-ui/react"
|
import { Center, Flex, Text } from '@chakra-ui/react';
|
||||||
|
|
||||||
import { Icon } from "../Icon/Icon"
|
import { Icon } from '../Icon/Icon';
|
||||||
import { useThingtime } from "./useThingtime"
|
import { useThingtime } from './useThingtime';
|
||||||
|
|
||||||
export const SettingsMenu = (props) => {
|
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 [pinStatus, setPinStatus] = React.useState(false);
|
||||||
|
|
||||||
const stateRef = React.useRef({
|
const stateRef = React.useRef({
|
||||||
pinStatus,
|
pinStatus
|
||||||
})
|
});
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
stateRef.current.pinStatus = pinStatus
|
stateRef.current.pinStatus = pinStatus;
|
||||||
}, [pinStatus])
|
}, [pinStatus]);
|
||||||
|
|
||||||
const { thingtime, events } = useThingtime()
|
const { thingtime, events } = useThingtime();
|
||||||
|
|
||||||
const opacityRef = React.useRef(null)
|
const opacityRef = React.useRef(null);
|
||||||
|
|
||||||
const waitTime = 1555
|
const waitTime = 1555;
|
||||||
|
|
||||||
const [uuid, setUuid] = React.useState(null)
|
const [uuid, setUuid] = React.useState(null);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setUuid(Math.random().toString(36).substring(7))
|
setUuid(Math.random().toString(36).substring(7));
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
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) {
|
||||||
if (!stateRef?.current?.pinStatus || event?.force) {
|
if (!stateRef?.current?.pinStatus || event?.force) {
|
||||||
setShow(false)
|
setShow(false);
|
||||||
setOpacity(0)
|
setOpacity(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
subscription?.unsubscribe?.()
|
subscription?.unsubscribe?.();
|
||||||
}
|
};
|
||||||
}, [events, uuid])
|
}, [events, uuid]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
clearInterval(opacityRef?.current)
|
clearInterval(opacityRef?.current);
|
||||||
if (props?.opacity) {
|
if (props?.opacity) {
|
||||||
setOpacity(props?.opacity)
|
setOpacity(props?.opacity);
|
||||||
} else {
|
} else {
|
||||||
opacityRef.current = setInterval(() => {
|
opacityRef.current = setInterval(() => {
|
||||||
if (!stateRef?.current?.pinStatus) {
|
if (!stateRef?.current?.pinStatus) {
|
||||||
setOpacity(props?.opacity)
|
setOpacity(props?.opacity);
|
||||||
setShow(false)
|
setShow(false);
|
||||||
}
|
}
|
||||||
}, waitTime)
|
}, waitTime);
|
||||||
}
|
}
|
||||||
}, [props?.opacity])
|
}, [props?.opacity]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (show || props?.opacity) {
|
if (show || props?.opacity) {
|
||||||
clearInterval(hideRef?.current)
|
clearInterval(hideRef?.current);
|
||||||
events.next({
|
events.next({
|
||||||
type: "settings-menu-hide",
|
type: 'settings-menu-hide',
|
||||||
uuid,
|
uuid
|
||||||
})
|
});
|
||||||
} else if (!show) {
|
} else if (!show) {
|
||||||
setPinStatus(false)
|
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(() => {
|
||||||
if (!stateRef?.current?.pinStatus) {
|
if (!stateRef?.current?.pinStatus) {
|
||||||
setShow(false)
|
setShow(false);
|
||||||
setOpacity(0)
|
setOpacity(0);
|
||||||
}
|
}
|
||||||
}, waitTime)
|
}, waitTime);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const showMenu = React.useCallback(() => {
|
const showMenu = React.useCallback(() => {
|
||||||
clearInterval(hideRef?.current)
|
clearInterval(hideRef?.current);
|
||||||
setShow(true)
|
setShow(true);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const hideMenu = React.useCallback(() => {
|
const hideMenu = React.useCallback(() => {
|
||||||
setShow(false)
|
setShow(false);
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const basePadding = React.useMemo(() => {
|
const basePadding = React.useMemo(() => {
|
||||||
return 4
|
return 4;
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
const types = React.useMemo(() => {
|
const types = React.useMemo(() => {
|
||||||
const baseTypes = thingtime?.settings?.types?.javascript || {}
|
const baseTypes = thingtime?.settings?.types?.javascript || {};
|
||||||
const baseTypeKeys = Object.keys(baseTypes)
|
const baseTypeKeys = Object.keys(baseTypes);
|
||||||
|
|
||||||
const customTypes = thingtime?.settings?.types?.custom || {}
|
const customTypes = thingtime?.settings?.types?.custom || {};
|
||||||
const customTypeKeysRaw = Object.keys(customTypes)
|
const customTypeKeysRaw = Object.keys(customTypes);
|
||||||
const customTypeKeys = customTypeKeysRaw?.filter((key) => {
|
const customTypeKeys = customTypeKeysRaw?.filter((key) => {
|
||||||
return !baseTypeKeys?.includes?.(key)
|
return !baseTypeKeys?.includes?.(key);
|
||||||
})
|
});
|
||||||
|
|
||||||
const types = [
|
const types = [
|
||||||
...(baseTypeKeys?.map?.((key) => {
|
...(baseTypeKeys?.map?.((key) => {
|
||||||
return {
|
return {
|
||||||
...baseTypes?.[key],
|
...baseTypes?.[key],
|
||||||
key,
|
key
|
||||||
}
|
};
|
||||||
}) || []),
|
}) || []),
|
||||||
...(customTypeKeys?.map?.((key) => {
|
...(customTypeKeys?.map?.((key) => {
|
||||||
return {
|
return {
|
||||||
...customTypes?.[key],
|
...customTypes?.[key],
|
||||||
key,
|
key
|
||||||
}
|
};
|
||||||
}) || []),
|
}) || [])
|
||||||
]
|
];
|
||||||
|
|
||||||
return types
|
return types;
|
||||||
}, [
|
}, [thingtime?.settings?.types?.javascript, thingtime?.settings?.types?.custom]);
|
||||||
thingtime?.settings?.types?.javascript,
|
|
||||||
thingtime?.settings?.types?.custom,
|
|
||||||
])
|
|
||||||
|
|
||||||
const onType = React.useCallback(
|
const onType = React.useCallback(
|
||||||
(args) => {
|
(args) => {
|
||||||
props?.onType?.(args)
|
props?.onType?.(args);
|
||||||
},
|
},
|
||||||
[props?.onType]
|
[props?.onType]
|
||||||
)
|
);
|
||||||
const onDelete = React.useCallback(
|
const onDelete = React.useCallback(
|
||||||
(type) => {
|
(type) => {
|
||||||
props?.onDelete?.()
|
props?.onDelete?.();
|
||||||
},
|
},
|
||||||
[props?.onDelete]
|
[props?.onDelete]
|
||||||
)
|
);
|
||||||
|
|
||||||
const childIconSize = 10
|
const childIconSize = 10;
|
||||||
const iconSize = props?.iconSize || 7
|
const iconSize = props?.iconSize || 7;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ClickAwayListener onClickAway={hideMenu}>
|
<ClickAwayListener onClickAway={hideMenu}>
|
||||||
@ -149,7 +146,7 @@ export const SettingsMenu = (props) => {
|
|||||||
// width="100%"
|
// width="100%"
|
||||||
paddingRight={36}
|
paddingRight={36}
|
||||||
opacity={opacity}
|
opacity={opacity}
|
||||||
transition={props?.transition || "all 0.2s ease-in-out"}
|
transition={props?.transition || 'all 0.2s ease-in-out'}
|
||||||
onMouseEnter={showMenu}
|
onMouseEnter={showMenu}
|
||||||
onMouseLeave={maybeHide}
|
onMouseLeave={maybeHide}
|
||||||
>
|
>
|
||||||
@ -159,6 +156,8 @@ export const SettingsMenu = (props) => {
|
|||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
// onClick={deleteValue}
|
// onClick={deleteValue}
|
||||||
transition="all 0.2s ease-in-out"
|
transition="all 0.2s ease-in-out"
|
||||||
|
// add title for hover context
|
||||||
|
title={`Options`}
|
||||||
>
|
>
|
||||||
<Icon name="wizard" size={iconSize}></Icon>
|
<Icon name="wizard" size={iconSize}></Icon>
|
||||||
</Flex>
|
</Flex>
|
||||||
@ -169,7 +168,7 @@ export const SettingsMenu = (props) => {
|
|||||||
left={0}
|
left={0}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
opacity={show ? 1 : 0}
|
opacity={show ? 1 : 0}
|
||||||
pointerEvents={show ? "all" : "none"}
|
pointerEvents={show ? 'all' : 'none'}
|
||||||
>
|
>
|
||||||
<Flex
|
<Flex
|
||||||
position="absolute"
|
position="absolute"
|
||||||
@ -178,19 +177,44 @@ export const SettingsMenu = (props) => {
|
|||||||
padding="5px"
|
padding="5px"
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => setPinStatus((prev) => !prev)}
|
onClick={() => setPinStatus((prev) => !prev)}
|
||||||
|
title={`Pin Options`}
|
||||||
>
|
>
|
||||||
<Icon
|
{show === true && <Icon opacity={pinStatus ? 1 : 0.5} name={pinStatus ? 'pinned' : 'pin'} size="8px"></Icon>}
|
||||||
opacity={pinStatus ? 1 : 0.5}
|
|
||||||
name={pinStatus ? "pinned" : "pin"}
|
|
||||||
size="8px"
|
|
||||||
></Icon>
|
|
||||||
</Flex>
|
</Flex>
|
||||||
|
{/* edit mode menu item */}
|
||||||
<Flex
|
<Flex
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
// rowGap={basePadding / 3}
|
// rowGap={basePadding / 3}
|
||||||
background="greys.lightt"
|
background="greys.lightt"
|
||||||
borderRadius={4}
|
borderRadius={4}
|
||||||
boxShadow={props?.boxShadow || "0px 2px 7px 0px rgba(0,0,0,0.2)"}
|
boxShadow={props?.boxShadow || '0px 2px 7px 0px rgba(0,0,0,0.2)'}
|
||||||
|
paddingY={basePadding}
|
||||||
|
>
|
||||||
|
<Flex
|
||||||
|
alignItems="center"
|
||||||
|
flexDirection="row"
|
||||||
|
// paddingRight={basePadding}
|
||||||
|
paddingLeft={basePadding}
|
||||||
|
_hover={{
|
||||||
|
background: 'greys.light'
|
||||||
|
}}
|
||||||
|
cursor="pointer"
|
||||||
|
// paddingX={basePadding * 1}
|
||||||
|
paddingY={basePadding / 2}
|
||||||
|
>
|
||||||
|
<Icon marginBottom="-2px" name="🎨" size={childIconSize}></Icon>
|
||||||
|
<Text marginTop="-2px" paddingLeft={2} fontSize="xs">
|
||||||
|
Toggle Edit Mode
|
||||||
|
</Text>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<Flex
|
||||||
|
flexDirection="column"
|
||||||
|
// rowGap={basePadding / 3}
|
||||||
|
background="greys.lightt"
|
||||||
|
borderRadius={4}
|
||||||
|
boxShadow={props?.boxShadow || '0px 2px 7px 0px rgba(0,0,0,0.2)'}
|
||||||
paddingY={basePadding}
|
paddingY={basePadding}
|
||||||
>
|
>
|
||||||
{!props?.readonly && (
|
{!props?.readonly && (
|
||||||
@ -200,17 +224,13 @@ export const SettingsMenu = (props) => {
|
|||||||
// paddingRight={basePadding}
|
// paddingRight={basePadding}
|
||||||
paddingLeft={basePadding}
|
paddingLeft={basePadding}
|
||||||
_hover={{
|
_hover={{
|
||||||
background: "greys.light",
|
background: 'greys.light'
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
// paddingX={basePadding * 1}
|
// paddingX={basePadding * 1}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon marginBottom="-2px" name="cyclone" size={childIconSize}></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>
|
||||||
@ -228,12 +248,12 @@ export const SettingsMenu = (props) => {
|
|||||||
types.map((type, idx) => {
|
types.map((type, idx) => {
|
||||||
const ret = (
|
const ret = (
|
||||||
<Flex
|
<Flex
|
||||||
key={props?.uuid + props?.fullPath + "-type-menu-" + idx}
|
key={props?.uuid + props?.fullPath + '-type-menu-' + idx}
|
||||||
width="100%"
|
width="100%"
|
||||||
_hover={{
|
_hover={{
|
||||||
"&>div": {
|
'&>div': {
|
||||||
background: "greys.light",
|
background: 'greys.light'
|
||||||
},
|
}
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={() => onType({ type })}
|
onClick={() => onType({ type })}
|
||||||
@ -247,11 +267,7 @@ export const SettingsMenu = (props) => {
|
|||||||
paddingLeft={basePadding * 2}
|
paddingLeft={basePadding * 2}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon marginBottom="-2px" name={type?.icon || type?.key || type?.label || type} size={childIconSize}></Icon>
|
||||||
marginBottom="-2px"
|
|
||||||
name={type?.icon || type?.key || type?.label || type}
|
|
||||||
size={childIconSize}
|
|
||||||
></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>
|
||||||
@ -259,18 +275,18 @@ export const SettingsMenu = (props) => {
|
|||||||
<Flex
|
<Flex
|
||||||
marginLeft="auto"
|
marginLeft="auto"
|
||||||
_hover={{
|
_hover={{
|
||||||
transform: "scale(1.3)",
|
transform: 'scale(1.3)'
|
||||||
}}
|
}}
|
||||||
transition="all 0.2s ease-out"
|
transition="all 0.2s ease-out"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e?.preventDefault?.()
|
e?.preventDefault?.();
|
||||||
e?.stopPropagation?.()
|
e?.stopPropagation?.();
|
||||||
// cancel bubble
|
// cancel bubble
|
||||||
e?.nativeEvent?.stopImmediatePropagation?.()
|
e?.nativeEvent?.stopImmediatePropagation?.();
|
||||||
onType({
|
onType({
|
||||||
type,
|
type,
|
||||||
wrap: true,
|
wrap: true
|
||||||
})
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name="wrap" size={childIconSize}></Icon>
|
<Icon name="wrap" size={childIconSize}></Icon>
|
||||||
@ -278,8 +294,8 @@ export const SettingsMenu = (props) => {
|
|||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
)
|
);
|
||||||
return ret
|
return ret;
|
||||||
})}
|
})}
|
||||||
</Flex>
|
</Flex>
|
||||||
{!props?.readonly && props?.onDelete && (
|
{!props?.readonly && props?.onDelete && (
|
||||||
@ -287,18 +303,14 @@ export const SettingsMenu = (props) => {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
_hover={{
|
_hover={{
|
||||||
background: "greys.light",
|
background: 'greys.light'
|
||||||
}}
|
}}
|
||||||
cursor="pointer"
|
cursor="pointer"
|
||||||
onClick={onDelete}
|
onClick={onDelete}
|
||||||
paddingX={basePadding * 1}
|
paddingX={basePadding * 1}
|
||||||
paddingY={basePadding / 2}
|
paddingY={basePadding / 2}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon marginBottom="-2px" name="bin" size={childIconSize}></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>
|
||||||
@ -308,5 +320,5 @@ export const SettingsMenu = (props) => {
|
|||||||
</Flex>
|
</Flex>
|
||||||
</Center>
|
</Center>
|
||||||
</ClickAwayListener>
|
</ClickAwayListener>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
15
remix/app/routes/branding.tsx
Normal file
15
remix/app/routes/branding.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import { Branding } from '~/components/Branding/Branding';
|
||||||
|
import { TopSpacing } from '~/components/Layout/TopSpacing';
|
||||||
|
import { Raw } from '~/components/MongoDB/Raw';
|
||||||
|
import { RawResults } from '~/components/MongoDB/RawResults';
|
||||||
|
|
||||||
|
export default function branding() {
|
||||||
|
const template = (
|
||||||
|
<>
|
||||||
|
<Branding />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
0
vercel.json
Normal file
0
vercel.json
Normal file
Loading…
Reference in New Issue
Block a user