Skip to content

Commit 9d2d010

Browse files
committed
Add Converters
1 parent 752d5ca commit 9d2d010

16 files changed

+374
-427
lines changed

components/Converter.tsx

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
import Head from "next/head";
2+
import tw, { css } from "twin.macro";
3+
import { TextBox } from "./TextBox";
4+
import { useEffect, useState } from "react";
5+
import { ConversionError } from "../converters/converter";
6+
7+
const Converter = ({
8+
inputConfigs,
9+
outputConfigs,
10+
title,
11+
description,
12+
parser,
13+
}: {
14+
inputConfigs: Record<
15+
string,
16+
{
17+
language: string;
18+
name: string;
19+
}
20+
>;
21+
outputConfigs: Record<
22+
string,
23+
{
24+
name: string;
25+
}
26+
>;
27+
title: string;
28+
description: string;
29+
parser: (
30+
input: Record<string, string>
31+
) => ConversionError | { error: false; data: Record<string, string> };
32+
}) => {
33+
const [configs, setConfigs] = useState<Record<string, string>>(
34+
Object.assign(
35+
Object.keys(inputConfigs).map((key) => ({
36+
[key]: "",
37+
}))
38+
)
39+
);
40+
const [parsedConfigs, setParsedConfigs] = useState<
41+
undefined | Record<string, string>
42+
>({});
43+
const [error, setError] = useState<false | string>(false);
44+
45+
useEffect(() => {
46+
const parsed = parser(configs);
47+
if (parsed.error) {
48+
setError(parsed.message);
49+
setParsedConfigs(undefined);
50+
} else {
51+
setError(false);
52+
setParsedConfigs(parsed.data);
53+
}
54+
}, [configs]);
55+
56+
return (
57+
<div>
58+
<Head>
59+
<title>{title}</title>
60+
<meta name="description" content={description} />
61+
</Head>
62+
63+
<main
64+
css={css`
65+
${tw`flex flex-col md:height[calc(100vh - 3.5rem)]`}
66+
`}
67+
>
68+
<div css={tw`w-full md:px-8 p-16 h-48 text-center`}>
69+
<p css={tw`text-3xl font-bold`}>HelpChat</p>
70+
<p css={tw`text-lg`}>{title}</p>
71+
</div>
72+
<div
73+
css={tw`p-4 m-2 md:mx-6 lg:mx-12 bg-white/20 backdrop-blur-sm drop-shadow-lg rounded-lg`}
74+
>
75+
<div css={tw`flex flex-col md:flex-row flex-grow flex-shrink h-full`}>
76+
<div
77+
css={css`
78+
height: calc(100vh - 18.5em);
79+
${tw`md:w-1/2 p-4 pt-1 pr-2 md:max-width[50vw] flex flex-col`}
80+
`}
81+
>
82+
{Object.keys(inputConfigs).map((key) => {
83+
const config = inputConfigs[key];
84+
return (
85+
<div
86+
key={key}
87+
css={css`
88+
@media (min-width: 768px) {
89+
height: ${Math.floor(
90+
100 / Object.keys(inputConfigs).length
91+
)}%;
92+
}
93+
`}
94+
>
95+
<TextBox
96+
title={config.name}
97+
language={config.language}
98+
code={configs ? configs[key] ?? "" : ""}
99+
editor={(config: string) => {
100+
setConfigs({
101+
...configs,
102+
[key]: config,
103+
});
104+
}}
105+
/>
106+
</div>
107+
);
108+
})}
109+
</div>
110+
<div
111+
css={css`
112+
height: calc(100vh - 18.5em);
113+
${tw`md:w-1/2 p-4 pt-1 pr-2 md:max-width[50vw] flex flex-col`}
114+
`}
115+
>
116+
{error || !parsedConfigs ? (
117+
<div css={tw`flex flex-col h-full w-full pt-1`}>
118+
<div css={tw`flex flex-row pl-2`}>
119+
<p css={tw`text-xl font-semibold mx-auto mb-2`}>
120+
Validation Errors
121+
</p>
122+
</div>
123+
<div
124+
css={css`
125+
${tw`rounded-md overflow-auto h-full`} background-color: #2a2734
126+
`}
127+
>
128+
<div css={tw`py-2 px-4 text-base`}>
129+
<span
130+
css={css`
131+
${tw`text-base whitespace-pre`}
132+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
133+
`}
134+
>
135+
{error}
136+
</span>
137+
</div>
138+
</div>
139+
</div>
140+
) : (
141+
Object.keys(outputConfigs).map((key) => {
142+
const config = outputConfigs[key];
143+
return (
144+
<div
145+
key={key}
146+
css={css`
147+
@media (min-width: 768px) {
148+
height: ${Math.floor(
149+
100 / Object.keys(outputConfigs).length
150+
)}%;
151+
}
152+
`}
153+
>
154+
<TextBox
155+
key={config.name}
156+
title={config.name}
157+
language={"yaml"}
158+
code={parsedConfigs ? parsedConfigs[key] ?? "" : ""}
159+
/>
160+
</div>
161+
);
162+
})
163+
)}
164+
</div>
165+
</div>
166+
</div>
167+
</main>
168+
</div>
169+
);
170+
};
171+
172+
export default Converter;

components/TextBox.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ export const TextBox = ({
2121
}: {
2222
title: string;
2323
code: string;
24-
editor?: Dispatch<SetStateAction<string>>;
24+
editor?: Dispatch<SetStateAction<string>> | ((config: string) => void);
2525
language: string;
2626
}) => {
2727
if (!editor) {
2828
return (
2929
<div css={tw`flex flex-col h-full w-full pt-1 text-white`}>
30-
<div css={tw`flex flex-row pl-2`}>
30+
<div css={tw`flex flex-row pl-8`}>
3131
<p css={tw`text-xl font-semibold mx-auto mb-2`}>{title}</p>
32-
<div css={tw`flex flex-row h-8`}>
32+
<div css={tw`flex flex-row h-8 w-8`}>
3333
<div
3434
css={tw`py-1 px-2 bg-green-400 rounded-md hover:cursor-pointer`}
3535
onClick={() => {

components/Validator.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import duotoneDark from "prism-react-renderer/themes/duotoneDark";
77
import { useRouter } from "next/router";
88
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
99
import { faLink } from "@fortawesome/free-solid-svg-icons";
10+
import { ConversionError } from "../converters/converter";
1011

1112
const ReactJson = dynamic(import("react-json-view"), { ssr: false });
1213

@@ -17,9 +18,7 @@ const Validator = ({
1718
}: {
1819
language: string;
1920
lang: string;
20-
parser: (
21-
data: string
22-
) => { error: true; message: string } | { error: false; data: any };
21+
parser: (data: string) => ConversionError | { error: false; data: any };
2322
}) => {
2423
const router = useRouter();
2524

converters/chatchat/deluxechat.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Converter from "../converter";
22
import {
3+
DeluxeChat,
34
DeluxeChatConfig,
45
DeluxeChatFormat,
56
DeluxeChatPrivateMessageFormat,
@@ -14,10 +15,11 @@ import MiniMessage from "../minimessage";
1415
const schema = require("../types/deluxechat.json");
1516

1617
const ChatChatDeluxeChatConverter = new Converter<
17-
DeluxeChatConfig,
18+
DeluxeChat,
1819
{ format: ChatChatFormatsConfig; settings: ChatChatSettingsConfig }
1920
>({
20-
Convert(deluxechatConfig) {
21+
Convert(deluxechat) {
22+
const deluxechatConfig = deluxechat.deluxechat;
2123
const chatchatFormatsConfig: ChatChatFormatsConfig = {
2224
"default-format": "default",
2325
formats: {},

converters/chatchat/venturechat.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const ChatChatVentureChatConverter = new Converter<
7171
break;
7272
}
7373
}
74-
let hover = section.hover_text.filter((s) => s && s !== "");
74+
let hover = section.hover_text.filter((s: string) => s && s !== "");
7575
if (hover && hover.length > 0) {
7676
formattedSection =
7777
"<hover:show_text:'" +

converters/converter.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ export default class Converter<
1212
this.conversion = conversion;
1313
}
1414

15-
convert(input: any): Record<keyof OutputConfigs, string> | ConversionError {
15+
convert(
16+
input: Record<string, any>
17+
):
18+
| { error: false; data: Record<keyof OutputConfigs, string> }
19+
| ConversionError {
1620
let untypedInputConfig: any;
1721

1822
try {
19-
if (typeof input === "string") {
20-
untypedInputConfig = parse(input);
21-
} else {
22-
untypedInputConfig = {};
23-
for (const key of Object.keys(input)) {
24-
if (typeof input[key] === "string") {
25-
untypedInputConfig[key] = parse(input[key]);
26-
} else {
27-
untypedInputConfig[key] = input[key];
28-
}
23+
untypedInputConfig = {};
24+
for (const key of Object.keys(input)) {
25+
if (typeof input[key] === "string") {
26+
untypedInputConfig[key] = parse(input[key]);
27+
} else {
28+
untypedInputConfig[key] = input[key];
2929
}
3030
}
3131
} catch (e: any) {
@@ -70,7 +70,10 @@ export default class Converter<
7070
});
7171
});
7272

73-
return returnValue as Record<keyof OutputConfigs, string>;
73+
return {
74+
error: false,
75+
data: <Record<keyof OutputConfigs, string>>returnValue,
76+
};
7477
}
7578
}
7679

converters/minimessage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default function MiniMessage(input: string): string {
2727
"/&?#((?:[a-f0-9]{3}){1,2})": "<#$1>",
2828
};
2929

30-
let out = input;
30+
let out = input ?? "";
3131

3232
Object.keys(legacyReplacements).forEach((key) => {
3333
if (key.startsWith("/")) {

converters/types/deluxechat.json

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
{
22
"$schema": "http://json-schema.org/draft-07/schema#",
3-
"$ref": "#/definitions/DeluxeChatConfig",
3+
"$ref": "#/definitions/DeluxeChat",
44
"definitions": {
5+
"DeluxeChat": {
6+
"type": "object",
7+
"properties": {
8+
"deluxechat": {
9+
"$ref": "#/definitions/DeluxeChatConfig"
10+
}
11+
},
12+
"required": [
13+
"deluxechat"
14+
]
15+
},
516
"DeluxeChatConfig": {
617
"type": "object",
718
"properties": {
@@ -98,7 +109,10 @@
98109
"$ref": "#/definitions/DeluxeChatPrivateMessageFormat"
99110
}
100111
},
101-
"required": ["to_recipient", "to_sender"]
112+
"required": [
113+
"to_recipient",
114+
"to_sender"
115+
]
102116
},
103117
"formats": {
104118
"type": "object",
@@ -199,4 +213,4 @@
199213
]
200214
}
201215
}
202-
}
216+
}

converters/types/deluxechat.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// @ToolBox - DeluxeChatConfig
1+
// @ToolBox - DeluxeChat
2+
3+
export interface DeluxeChat {
4+
deluxechat: DeluxeChatConfig;
5+
}
26

37
export interface DeluxeChatConfig {
48
check_updates?: boolean;

converters/types/essentialschat.json

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"EssentialsChatTypes": {
66
"type": "object",
77
"properties": {
8-
"config": {
8+
"essentials": {
99
"$ref": "#/definitions/EssentialsChatConfig"
1010
},
1111
"language": {
@@ -17,7 +17,10 @@
1717
}
1818
}
1919
},
20-
"required": ["config", "language"]
20+
"required": [
21+
"essentials",
22+
"language"
23+
]
2124
},
2225
"EssentialsChatConfig": {
2326
"type": "object",
@@ -26,7 +29,10 @@
2629
"type": "object",
2730
"properties": {
2831
"format": {
29-
"type": ["string", "null"]
32+
"type": [
33+
"string",
34+
"null"
35+
]
3036
},
3137
"group-formats": {
3238
"anyOf": [
@@ -44,7 +50,9 @@
4450
}
4551
}
4652
},
47-
"required": ["chat"]
53+
"required": [
54+
"chat"
55+
]
4856
}
4957
}
50-
}
58+
}

0 commit comments

Comments
 (0)