@arcanewizards/timecode-toolbox 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +55 -0
- package/CHANGELOG.md +24 -0
- package/eslint.config.mjs +49 -0
- package/package.json +74 -0
- package/src/app.tsx +147 -0
- package/src/components/backend/index.ts +6 -0
- package/src/components/backend/toolbox-root.ts +119 -0
- package/src/components/frontend/constants.ts +81 -0
- package/src/components/frontend/entrypoint.ts +12 -0
- package/src/components/frontend/frontend.css +108 -0
- package/src/components/frontend/index.tsx +46 -0
- package/src/components/frontend/toolbox/content.tsx +45 -0
- package/src/components/frontend/toolbox/context.tsx +63 -0
- package/src/components/frontend/toolbox/core/size-aware-div.tsx +51 -0
- package/src/components/frontend/toolbox/core/timecode-display.tsx +592 -0
- package/src/components/frontend/toolbox/generators.tsx +318 -0
- package/src/components/frontend/toolbox/inputs.tsx +484 -0
- package/src/components/frontend/toolbox/outputs.tsx +581 -0
- package/src/components/frontend/toolbox/preferences.ts +25 -0
- package/src/components/frontend/toolbox/root.tsx +335 -0
- package/src/components/frontend/toolbox/settings.tsx +54 -0
- package/src/components/frontend/toolbox/types.ts +28 -0
- package/src/components/frontend/toolbox/util.tsx +61 -0
- package/src/components/proto.ts +420 -0
- package/src/config.ts +7 -0
- package/src/generators/clock.tsx +206 -0
- package/src/generators/index.tsx +15 -0
- package/src/index.ts +38 -0
- package/src/inputs/artnet.tsx +305 -0
- package/src/inputs/index.tsx +13 -0
- package/src/inputs/tcnet.tsx +272 -0
- package/src/outputs/artnet.tsx +170 -0
- package/src/outputs/index.tsx +11 -0
- package/src/start.ts +47 -0
- package/src/tree.ts +133 -0
- package/src/types.ts +12 -0
- package/src/urls.ts +49 -0
- package/src/util.ts +82 -0
- package/tailwind.config.cjs +7 -0
- package/tsconfig.json +10 -0
- package/tsup.config.ts +10 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FrontendComponentRenderer } from '@arcanejs/toolkit-frontend/types';
|
|
2
|
+
import {
|
|
3
|
+
BaseBrowserContext,
|
|
4
|
+
startSigilFrontend,
|
|
5
|
+
} from '@arcanewizards/sigil/frontend';
|
|
6
|
+
import { isTimecodeToolboxComponent, NAMESPACE } from '../proto';
|
|
7
|
+
import { ToolboxRoot } from './toolbox/root';
|
|
8
|
+
|
|
9
|
+
export type TimecodeToolboxBrowserContext = BaseBrowserContext;
|
|
10
|
+
|
|
11
|
+
export const timecodeToolboxFrontendComponents =
|
|
12
|
+
(): FrontendComponentRenderer => ({
|
|
13
|
+
namespace: NAMESPACE,
|
|
14
|
+
render: (info) => {
|
|
15
|
+
if (!isTimecodeToolboxComponent(info)) {
|
|
16
|
+
throw new Error(`Cannot render component ${info.namespace}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
switch (info.component) {
|
|
20
|
+
case 'toolbox-root':
|
|
21
|
+
return <ToolboxRoot info={info} />;
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const startTimecodeToolboxServerFrontend = (
|
|
27
|
+
browser?: TimecodeToolboxBrowserContext | null,
|
|
28
|
+
) => {
|
|
29
|
+
startSigilFrontend<TimecodeToolboxBrowserContext>({
|
|
30
|
+
browser,
|
|
31
|
+
appRenderers: [timecodeToolboxFrontendComponents()],
|
|
32
|
+
loadingState: () => (
|
|
33
|
+
<div style={{ width: '100%', textAlign: 'center', padding: '2rem' }}>
|
|
34
|
+
Loading Toolbox...
|
|
35
|
+
</div>
|
|
36
|
+
),
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
declare global {
|
|
41
|
+
interface Window {
|
|
42
|
+
startTimecodeToolboxServerFrontend?: typeof startTimecodeToolboxServerFrontend;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
window.startTimecodeToolboxServerFrontend = startTimecodeToolboxServerFrontend;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { useBrowserContext } from '@arcanewizards/sigil/frontend';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
import { SizeAwareDiv } from './core/size-aware-div';
|
|
4
|
+
import { Icon } from '@arcanejs/toolkit-frontend/components/core';
|
|
5
|
+
|
|
6
|
+
export const ExternalLink = ({
|
|
7
|
+
href,
|
|
8
|
+
children,
|
|
9
|
+
}: {
|
|
10
|
+
href: string;
|
|
11
|
+
children: React.ReactNode;
|
|
12
|
+
}) => {
|
|
13
|
+
const { openExternalLink } = useBrowserContext();
|
|
14
|
+
return (
|
|
15
|
+
<a
|
|
16
|
+
href={href}
|
|
17
|
+
target="_blank"
|
|
18
|
+
rel="noopener noreferrer"
|
|
19
|
+
onClick={(e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
openExternalLink(href);
|
|
22
|
+
}}
|
|
23
|
+
className="
|
|
24
|
+
text-sigil-usage-hint-foreground no-underline
|
|
25
|
+
hover:underline
|
|
26
|
+
"
|
|
27
|
+
>
|
|
28
|
+
{children}
|
|
29
|
+
</a>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const NoToolboxChildren: FC<{ text: string }> = ({ text }) => {
|
|
34
|
+
return (
|
|
35
|
+
<SizeAwareDiv
|
|
36
|
+
className="
|
|
37
|
+
flex grow flex-col items-center justify-center gap-1 bg-sigil-bg-light
|
|
38
|
+
p-1 text-sigil-foreground-muted
|
|
39
|
+
"
|
|
40
|
+
>
|
|
41
|
+
<Icon icon="handyman" className="text-block-icon" />
|
|
42
|
+
<div className="text-center">{text}</div>
|
|
43
|
+
</SizeAwareDiv>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ApplicationState,
|
|
4
|
+
AvailableHandlers,
|
|
5
|
+
ToolboxConfig,
|
|
6
|
+
ToolboxRootCallHandler,
|
|
7
|
+
ToolboxRootGetNetworkInterfacesReturn,
|
|
8
|
+
} from '../../proto';
|
|
9
|
+
import { Tree } from '../../../tree';
|
|
10
|
+
|
|
11
|
+
export type ConfigContextData = {
|
|
12
|
+
config: ToolboxConfig;
|
|
13
|
+
updateConfig: (change: (current: ToolboxConfig) => ToolboxConfig) => void;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const ConfigContext = createContext<ConfigContextData>(
|
|
17
|
+
new Proxy({} as ConfigContextData, {
|
|
18
|
+
get() {
|
|
19
|
+
throw new Error('ConfigContext not initialized');
|
|
20
|
+
},
|
|
21
|
+
}),
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const ApplicationStateContext = createContext<ApplicationState>(
|
|
25
|
+
new Proxy({} as ApplicationState, {
|
|
26
|
+
get() {
|
|
27
|
+
throw new Error('ApplicationStateContext not initialized');
|
|
28
|
+
},
|
|
29
|
+
}),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export const useApplicationState = () => useContext(ApplicationStateContext);
|
|
33
|
+
|
|
34
|
+
export type ApplicationHandlersContextData = {
|
|
35
|
+
handlers: Tree<AvailableHandlers>;
|
|
36
|
+
callHandler<H extends keyof AvailableHandlers>(
|
|
37
|
+
args: Pick<ToolboxRootCallHandler<H>, 'path' | 'handler' | 'args'>,
|
|
38
|
+
): Promise<void>;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const ApplicationHandlersContext =
|
|
42
|
+
createContext<ApplicationHandlersContextData>(
|
|
43
|
+
new Proxy({} as ApplicationHandlersContextData, {
|
|
44
|
+
get() {
|
|
45
|
+
throw new Error('ApplicationHandlersContext not initialized');
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
export const useApplicationHandlers = () =>
|
|
51
|
+
useContext(ApplicationHandlersContext);
|
|
52
|
+
|
|
53
|
+
type NetworkContextData = {
|
|
54
|
+
getNetworkInterfaces: () => Promise<ToolboxRootGetNetworkInterfacesReturn>;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const NetworkContext = createContext<NetworkContextData>(
|
|
58
|
+
new Proxy({} as NetworkContextData, {
|
|
59
|
+
get() {
|
|
60
|
+
throw new Error('NetworkContext not initialized');
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
63
|
+
);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { cssVariables } from '@arcanewizards/sigil/frontend/styling';
|
|
2
|
+
import React, { useEffect, useState } from 'react';
|
|
3
|
+
|
|
4
|
+
type SizeAwareDivProps = React.HTMLAttributes<HTMLDivElement>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A div component that sets CSS variables of it's current size,
|
|
8
|
+
* allowing children to use those variables to adapt to the size of the div.
|
|
9
|
+
* The variables set are --size-aware-div-width and --size-aware-div-height.
|
|
10
|
+
*/
|
|
11
|
+
export const SizeAwareDiv: React.FC<SizeAwareDivProps> = ({
|
|
12
|
+
children,
|
|
13
|
+
style,
|
|
14
|
+
...rest
|
|
15
|
+
}) => {
|
|
16
|
+
const [div, setDiv] = useState<HTMLDivElement | null>(null);
|
|
17
|
+
const [rect, setRect] = useState<DOMRectReadOnly | null>(null);
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
// Detect changes in div size
|
|
21
|
+
if (!div) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const resizeObserver = new ResizeObserver((entries) => {
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
setRect(entry.contentRect);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
resizeObserver.observe(div);
|
|
30
|
+
return () => {
|
|
31
|
+
resizeObserver.disconnect();
|
|
32
|
+
};
|
|
33
|
+
}, [div]);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
ref={setDiv}
|
|
38
|
+
{...rest}
|
|
39
|
+
style={{
|
|
40
|
+
...style,
|
|
41
|
+
...(rect &&
|
|
42
|
+
cssVariables({
|
|
43
|
+
'--size-aware-div-width': rect.width + 'px',
|
|
44
|
+
'--size-aware-div-height': rect.height + 'px',
|
|
45
|
+
})),
|
|
46
|
+
}}
|
|
47
|
+
>
|
|
48
|
+
{children}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
};
|