Skip to content

Commit 1843515

Browse files
committed
feat(toy): add userAgent parser
1 parent c0509d5 commit 1843515

File tree

13 files changed

+176
-0
lines changed

13 files changed

+176
-0
lines changed

locales/en.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
"view.devtoys.others.cron.tooltip": "Simulate CRON Expression",
5454
"view.devtoys.others.label": "Others",
5555
"view.devtoys.others.tooltip": "All Other Tools",
56+
"view.devtoys.others.userAgent.label": "UserAgent",
57+
"view.devtoys.others.userAgent.panel.title": "User-Agent Parser",
58+
"view.devtoys.others.userAgent.tooltip": "Parser Your User-Agent",
5659
"view.devtoys.text.label": "Text",
5760
"view.devtoys.text.regexTester.label": "Regex Tester",
5861
"view.devtoys.text.regexTester.panel.title": "Regex Tester",

locales/zh-CN.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
"view.devtoys.others.cron.tooltip": "模拟 CRON 表达式",
5454
"view.devtoys.others.label": "其他",
5555
"view.devtoys.others.tooltip": "全部其他工具",
56+
"view.devtoys.others.userAgent.label": "UserAgent",
57+
"view.devtoys.others.userAgent.panel.title": "UserAgent解析",
58+
"view.devtoys.others.userAgent.tooltip": "解析你的UserAgent",
5659
"view.devtoys.text.label": "文本",
5760
"view.devtoys.text.regexTester.label": "正则表达式测试",
5861
"view.devtoys.text.regexTester.panel.title": "正则表达式测试",

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
"@types/qrcode": "^1.4.2",
112112
"@types/react": "^17.0.39",
113113
"@types/react-dom": "^17.0.11",
114+
"@types/ua-parser-js": "^0.7.36",
114115
"@types/vscode": "^1.64.0",
115116
"@typescript-eslint/eslint-plugin": "^5.9.1",
116117
"@typescript-eslint/parser": "^5.9.1",
@@ -154,6 +155,7 @@
154155
"svelte-preprocess": "^4.0.0",
155156
"ts-loader": "^9.2.6",
156157
"typescript": "^4.5.4",
158+
"ua-parser-js": "^1.0.2",
157159
"uuid": "^8.3.2",
158160
"vite": "^2.8.4",
159161
"vue": "^3.2.29",

src/Panel/UserAgent.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { PanelType } from "../shared";
2+
import { ToolPanel } from "../common/ToolPanel";
3+
import * as vscode from "vscode";
4+
import i18n from "../i18n";
5+
6+
export class UserAgent extends ToolPanel<UserAgent> {
7+
constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) {
8+
super(panel, extensionUri, PanelType.userAgent, "react");
9+
}
10+
11+
public static createOrShow(extensionUri: vscode.Uri) {
12+
super.createOrShow(
13+
extensionUri,
14+
PanelType.userAgent,
15+
i18n.t("view.devtoys.others.userAgent.panel.title"),
16+
UserAgent
17+
);
18+
}
19+
20+
public dispose(): void {
21+
super.dispose();
22+
UserAgent.currentPanel = undefined;
23+
}
24+
}
25+
26+
ToolPanel.allPanel.add(UserAgent);

src/commands/showTool.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { Qrcode } from "../Panel/Qrcode";
1212
import { RegexTester } from "../Panel/RegexTester";
1313
import { Timestamp } from "../Panel/Timestamp";
1414
import { Url } from "../Panel/Url";
15+
import { UserAgent } from "../Panel/UserAgent";
1516
import { UUID } from "../Panel/UUID";
1617
import { PanelType } from "../shared";
1718

@@ -59,5 +60,8 @@ export default (context: vscode.ExtensionContext) => (node?: DevToysNode) => {
5960
case PanelType.cron:
6061
Cron.createOrShow(context.extensionUri);
6162
break;
63+
case PanelType.userAgent:
64+
UserAgent.createOrShow(context.extensionUri);
65+
break;
6266
}
6367
};

src/explorer/explorerNodeManager.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ class ExplorerNodeManager implements Disposable {
9090
tooltip: i18n.t("view.devtoys.others.cron.tooltip"),
9191
panel: PanelType.cron,
9292
},
93+
{
94+
label: i18n.t("view.devtoys.others.userAgent.label"),
95+
tooltip: i18n.t("view.devtoys.others.userAgent.tooltip"),
96+
panel: PanelType.userAgent,
97+
},
9398
];
9499

95100
this.explorerNodeMap.set(

src/shared.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export enum PanelType {
1515
qrcode = "qrcode",
1616
timestamp = "timestamp",
1717
cron = "cron",
18+
userAgent = "userAgent",
1819
}
1920

2021
export enum Category {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import i18n from "i18next";
2+
import { initReactI18next } from "react-i18next";
3+
import en from "./locales/en.json";
4+
import zh_CN from "./locales/zh-CN.json";
5+
6+
i18n.use(initReactI18next).init({
7+
resources: {
8+
en: {
9+
translation: en,
10+
},
11+
"zh-cn": {
12+
translation: zh_CN,
13+
},
14+
},
15+
lng: window.displayLanguage,
16+
lowerCaseLng: true,
17+
fallbackLng: "en",
18+
});
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { useTranslation } from "react-i18next";
2+
import {
3+
VSCodeTextField,
4+
VSCodeTextArea,
5+
} from "@vscode/webview-ui-toolkit/react";
6+
import UAParser from "ua-parser-js";
7+
import { useEffect, useState } from "react";
8+
const uaParser = new UAParser();
9+
export default () => {
10+
const { t } = useTranslation();
11+
const [ua, setUa] = useState(window.navigator.userAgent);
12+
const [uaResult, setUaResult] = useState<UAParser.IResult>();
13+
const formatUA = (result: UAParser.IResult | undefined) => {
14+
if (!result) {
15+
return "";
16+
}
17+
let text = result.ua + "\n";
18+
if (result.browser.name) {
19+
text += `\n- ${t("tool.userAgent.result.browser")}: ${
20+
result.browser.name
21+
} ${result.browser.version}`;
22+
}
23+
if (result.device.type) {
24+
text += `\n- ${t("tool.userAgent.result.device")}: ${
25+
result.device.type
26+
} / ${result.device.vendor} / ${result.device.model}`;
27+
}
28+
if (result.os.name) {
29+
text += `\n- ${t("tool.userAgent.result.os")}: ${result.os.name} / ${
30+
result.os.version
31+
}`;
32+
}
33+
if (result.engine.name) {
34+
text += `\n- ${t("tool.userAgent.result.engine")}: ${
35+
result.engine.name
36+
} / ${result.engine.version}`;
37+
}
38+
if (result.cpu.architecture) {
39+
text += `\n- ${t("tool.userAgent.result.cpu")}: ${
40+
result.cpu.architecture
41+
}`;
42+
}
43+
return text;
44+
};
45+
useEffect(() => {
46+
uaParser.setUA(ua);
47+
setUaResult(uaParser.getResult());
48+
}, [ua]);
49+
// const [uaParser, setUaParser] = useState<UAParser>();
50+
return (
51+
<div>
52+
<h1>{t("tool.userAgent.title")}</h1>
53+
<VSCodeTextField
54+
value={ua}
55+
onInput={({ target }) => {
56+
setUa((target as HTMLInputElement).value);
57+
}}
58+
style={{ width: "100%" }}
59+
>
60+
{t("tool.userAgent.uaTextField.label")}
61+
</VSCodeTextField>
62+
<VSCodeTextArea
63+
style={{ width: "100%" }}
64+
value={formatUA(uaResult)}
65+
cols={20}
66+
rows={8}
67+
readOnly
68+
>
69+
{t("tool.userAgent.resultTextArea.label")}
70+
</VSCodeTextArea>
71+
</div>
72+
);
73+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"tool.userAgent.result.browser": "Browser",
3+
"tool.userAgent.result.cpu": "CPU",
4+
"tool.userAgent.result.device": "Device",
5+
"tool.userAgent.result.engine": "Engine",
6+
"tool.userAgent.result.os": "OS",
7+
"tool.userAgent.resultTextArea.label": "Result",
8+
"tool.userAgent.title": "UserAgent Parser",
9+
"tool.userAgent.uaTextField.label": "UA"
10+
}

0 commit comments

Comments
 (0)