fix ja language, instead fetch by axios
This commit is contained in:
19
bun.lock
19
bun.lock
@@ -4,6 +4,7 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "firefly-analytics",
|
"name": "firefly-analytics",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.9.0",
|
||||||
"chart.js": "^4.4.9",
|
"chart.js": "^4.4.9",
|
||||||
"chartjs-plugin-datalabels": "^2.2.0",
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"framer-motion": "^12.7.4",
|
"framer-motion": "^12.7.4",
|
||||||
@@ -316,10 +317,14 @@
|
|||||||
|
|
||||||
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
|
"async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="],
|
||||||
|
|
||||||
|
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||||
|
|
||||||
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
||||||
|
|
||||||
"axe-core": ["axe-core@4.10.3", "", {}, "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg=="],
|
"axe-core": ["axe-core@4.10.3", "", {}, "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg=="],
|
||||||
|
|
||||||
|
"axios": ["axios@1.9.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg=="],
|
||||||
|
|
||||||
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
"axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="],
|
||||||
|
|
||||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||||
@@ -360,6 +365,8 @@
|
|||||||
|
|
||||||
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
|
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
|
||||||
|
|
||||||
|
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||||
|
|
||||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||||
@@ -386,6 +393,8 @@
|
|||||||
|
|
||||||
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
"define-properties": ["define-properties@1.2.1", "", { "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } }, "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg=="],
|
||||||
|
|
||||||
|
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
|
||||||
|
|
||||||
"diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
|
"diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="],
|
||||||
@@ -476,8 +485,12 @@
|
|||||||
|
|
||||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||||
|
|
||||||
|
"follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
|
||||||
|
|
||||||
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
||||||
|
|
||||||
|
"form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="],
|
||||||
|
|
||||||
"framer-motion": ["framer-motion@12.9.4", "", { "dependencies": { "motion-dom": "^12.9.4", "motion-utils": "^12.9.4", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-yaeGDmGQ3eCQEwZ95/pRQMaSh/Q4E2CK6JYOclG/PdjyQad0MULJ+JFVV8911Fl5a6tF6o0wgW8Dpl5Qx4Adjg=="],
|
"framer-motion": ["framer-motion@12.9.4", "", { "dependencies": { "motion-dom": "^12.9.4", "motion-utils": "^12.9.4", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-yaeGDmGQ3eCQEwZ95/pRQMaSh/Q4E2CK6JYOclG/PdjyQad0MULJ+JFVV8911Fl5a6tF6o0wgW8Dpl5Qx4Adjg=="],
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
@@ -658,6 +671,10 @@
|
|||||||
|
|
||||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||||
|
|
||||||
|
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||||
|
|
||||||
|
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||||
|
|
||||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||||
|
|
||||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||||
@@ -728,6 +745,8 @@
|
|||||||
|
|
||||||
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
|
||||||
|
|
||||||
|
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
||||||
|
|
||||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||||
|
|
||||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||||
|
|||||||
108
messages/cn.json
Normal file
108
messages/cn.json
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
{
|
||||||
|
"TabTitle": {
|
||||||
|
"title": "Firefly 分析器",
|
||||||
|
"description": "Veritas 分析工具"
|
||||||
|
},
|
||||||
|
"DataAnalysisPage": {
|
||||||
|
"useSkill": "使用技能",
|
||||||
|
"totalDamage": "总伤害",
|
||||||
|
"damagePerAV": "每行动值伤害",
|
||||||
|
"totalAV": "总行动值",
|
||||||
|
"skillType": "技能类型",
|
||||||
|
"skillName": "技能名称",
|
||||||
|
"actionValue": "行动值",
|
||||||
|
"character": "角色",
|
||||||
|
"id": "ID",
|
||||||
|
"path": "命途",
|
||||||
|
"rarity": "稀有度",
|
||||||
|
"damageByActionValue": "此行动值的伤害",
|
||||||
|
"element": "属性",
|
||||||
|
"totalTurn": "总回合",
|
||||||
|
"technique": "密技",
|
||||||
|
"talent": "天赋",
|
||||||
|
"basic": "普攻",
|
||||||
|
"skill": "战技",
|
||||||
|
"ultimate": "终结技",
|
||||||
|
"servant": "忆灵",
|
||||||
|
"skillDamageBreakdown": "技能类别",
|
||||||
|
"skillUsageDistribution": "技能使用分布",
|
||||||
|
"damageOverTime": "累计伤害",
|
||||||
|
"damage": "伤害",
|
||||||
|
"cumulativeDamage": "累计伤害量",
|
||||||
|
"characterInformation": "角色信息",
|
||||||
|
"turnDetail": "轮次详情",
|
||||||
|
"damageDetails": "伤害详情",
|
||||||
|
"cycleCount": "轮次",
|
||||||
|
"chartInfo": "图表信息",
|
||||||
|
"actionBar": "行动轴",
|
||||||
|
"lineupInfo": "阵容信息",
|
||||||
|
"loadData": "加载战斗数据",
|
||||||
|
"exportData": "导出战斗数据",
|
||||||
|
"connectSetting": "连接设置",
|
||||||
|
"connected": "已连接",
|
||||||
|
"unconnected": "未连接",
|
||||||
|
"socketConnection": "socket连接",
|
||||||
|
"connectionType": "连接类型",
|
||||||
|
"status": "状态",
|
||||||
|
"connect": "连接",
|
||||||
|
"checkGameConnect": "检查游戏连接",
|
||||||
|
"other": "其他",
|
||||||
|
"host": "主机",
|
||||||
|
"port": "端口",
|
||||||
|
"hostPlaceHolder": "输入主机地址",
|
||||||
|
"portPlaceHolder": "输入端口号",
|
||||||
|
"noDamageDetail": "没有可用的伤害详情",
|
||||||
|
"noCharactersInLineup": "队伍中没有角色",
|
||||||
|
"noTurns": "尚未有回合",
|
||||||
|
"type": "类型 ",
|
||||||
|
"warrior": "毁灭",
|
||||||
|
"knight": "存护",
|
||||||
|
"mage": "智识",
|
||||||
|
"priest": "丰饶",
|
||||||
|
"rouge": "巡猎",
|
||||||
|
"shaman": "同协",
|
||||||
|
"warlock": "虚无",
|
||||||
|
"memory": "记忆",
|
||||||
|
"fire": "火",
|
||||||
|
"ice": "冰",
|
||||||
|
"imaginary": "虚数",
|
||||||
|
"physical": "物理",
|
||||||
|
"quantum": "量子",
|
||||||
|
"thunder": "雷",
|
||||||
|
"wind": "风",
|
||||||
|
"cycle": "回合",
|
||||||
|
"wave": "波次",
|
||||||
|
"hp": "生命值",
|
||||||
|
"atk": "攻击力",
|
||||||
|
"speed": "速度",
|
||||||
|
"critRate": "暴击率",
|
||||||
|
"critDmg": "暴击伤害",
|
||||||
|
"breakEffect": "击破特攻",
|
||||||
|
"effectRes": "效果抵抗",
|
||||||
|
"energyRegenerationRate": "能量回复效率",
|
||||||
|
"effectHitRate": "效果命中",
|
||||||
|
"outgoingHealingBoost": "治疗量加成",
|
||||||
|
"fireDmgBoost": "火属性伤害提高",
|
||||||
|
"iceDmgBoost": "冰属性伤害提高",
|
||||||
|
"imaginaryDmgBoost": "虚数属性伤害提高",
|
||||||
|
"physicalDmgBoost": "物理属性伤害提高",
|
||||||
|
"quantumDmgBoost": "量子属性伤害提高",
|
||||||
|
"thunderDmgBoost": "雷属性伤害提高",
|
||||||
|
"windDmgBoost": "风属性伤害提高",
|
||||||
|
"pursued": "附加伤害",
|
||||||
|
"true damage": "真实伤害",
|
||||||
|
"follow-up": "追加攻击",
|
||||||
|
"elemental damage": "击破与超击破伤害",
|
||||||
|
"dot": "持续伤害 ",
|
||||||
|
"damagePerCycle": "每轮伤害",
|
||||||
|
"damagePerCycleAndWave": "每轮/波伤害",
|
||||||
|
"damagePerWave": "每波伤害",
|
||||||
|
"lastTurn": "最后一回合",
|
||||||
|
"qte": "QTE技能",
|
||||||
|
"mazenormal": "普通迷宫",
|
||||||
|
"level": "等级",
|
||||||
|
"relics": "遗器",
|
||||||
|
"eidolons": "星魂",
|
||||||
|
"lightcones": "光锥"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,14 +29,7 @@ const nextConfig: NextConfig = {
|
|||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
async rewrites() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
source: '/api/hakushin',
|
|
||||||
destination: 'https://api.hakush.in/hsr/data/character.json',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default withNextIntl(nextConfig);
|
export default withNextIntl(nextConfig);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"axios": "^1.9.0",
|
||||||
"chart.js": "^4.4.9",
|
"chart.js": "^4.4.9",
|
||||||
"chartjs-plugin-datalabels": "^2.2.0",
|
"chartjs-plugin-datalabels": "^2.2.0",
|
||||||
"framer-motion": "^12.7.4",
|
"framer-motion": "^12.7.4",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { useTranslations } from "next-intl";
|
|||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { getNameChar } from "@/helper";
|
import { getNameChar } from "@/helper";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import NameAvatar from "../nameAvatar";
|
||||||
|
|
||||||
export default function ActionBar() {
|
export default function ActionBar() {
|
||||||
const [selectTurn, setSelectTurn] = useState<SkillBattleInfo | null>(null);
|
const [selectTurn, setSelectTurn] = useState<SkillBattleInfo | null>(null);
|
||||||
@@ -128,8 +129,11 @@ export default function ActionBar() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<NameAvatar
|
||||||
<div className="text-base-content text-center text-sm mt-1 font-medium">{getNameChar(locale, data)}</div>
|
locale={locale}
|
||||||
|
text={getNameChar(locale, data)}
|
||||||
|
className="text-base-content text-center text-sm mt-1 font-medium"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-1 justify-center gap-2 py-2 w-full">
|
<div className="grid grid-cols-1 justify-center gap-2 py-2 w-full">
|
||||||
<div className="bg-local text-primary text-xs max-w-full">
|
<div className="bg-local text-primary text-xs max-w-full">
|
||||||
@@ -180,14 +184,18 @@ export default function ActionBar() {
|
|||||||
<h4 className="text-lg font-semibold mb-2 text-pink-500">{transI18n("characterInformation")}</h4>
|
<h4 className="text-lg font-semibold mb-2 text-pink-500">{transI18n("characterInformation")}</h4>
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 items-center">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 items-center">
|
||||||
<div className="flex flex-col space-y-2">
|
<div className="flex flex-col space-y-2">
|
||||||
<p className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-medium text-base-content/70">{transI18n("id")}:</span>
|
<span className="font-medium text-base-content/70">{transI18n("id")}:</span>
|
||||||
<span className="font-bold">{selectAvatar.id}</span>
|
<span className="font-bold">{selectAvatar.id}</span>
|
||||||
</p>
|
</div>
|
||||||
<p className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="font-medium text-base-content/70">{transI18n("character")}:</span>
|
<span className="font-medium text-base-content/70">{transI18n("character")}:</span>
|
||||||
<span className="font-bold">{getNameChar(locale, selectAvatar)}</span>
|
<NameAvatar
|
||||||
</p>
|
locale={locale}
|
||||||
|
text={getNameChar(locale, selectAvatar)}
|
||||||
|
className="font-bold"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex justify-center items-center">
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -3,16 +3,12 @@
|
|||||||
import { getNameChar } from '@/helper';
|
import { getNameChar } from '@/helper';
|
||||||
import useLocaleStore from '@/stores/localeStore';
|
import useLocaleStore from '@/stores/localeStore';
|
||||||
import { AvatarHakushiType } from '@/types';
|
import { AvatarHakushiType } from '@/types';
|
||||||
|
import NameAvatar from '../nameAvatar';
|
||||||
|
|
||||||
interface CharacterCardProps {
|
interface CharacterCardProps {
|
||||||
data: AvatarHakushiType
|
data: AvatarHakushiType
|
||||||
}
|
}
|
||||||
|
|
||||||
export function parseRuby(text: string): string {
|
|
||||||
return text.replace(/\{RUBY_B#(.*?)\}(.*?)\{RUBY_E#\}/g, (_, furigana, kanji) => {
|
|
||||||
return `<ruby>${kanji}<rt>${furigana}</rt></ruby>`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export default function CharacterCard({ data }: CharacterCardProps) {
|
export default function CharacterCard({ data }: CharacterCardProps) {
|
||||||
@@ -20,47 +16,41 @@ export default function CharacterCard({ data }: CharacterCardProps) {
|
|||||||
const text = getNameChar(locale, data)
|
const text = getNameChar(locale, data)
|
||||||
return (
|
return (
|
||||||
<li className="z-10 flex flex-col w-28 items-center p-1 rounded-md shadow-lg bg-gradient-to-b from-customStart to-customEnd transform transition-transform duration-300 hover:scale-105 m-1">
|
<li className="z-10 flex flex-col w-28 items-center p-1 rounded-md shadow-lg bg-gradient-to-b from-customStart to-customEnd transform transition-transform duration-300 hover:scale-105 m-1">
|
||||||
<div
|
|
||||||
className={`w-[80px] rounded-md p-[2px] bg-gradient-to-br ${
|
|
||||||
data.rank === "CombatPowerAvatarRarityType5"
|
|
||||||
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
|
||||||
: "from-purple-300 via-purple-200 to-purple-400"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
|
|
||||||
<div className="relative w-full h-full">
|
|
||||||
<img
|
|
||||||
loading="lazy"
|
|
||||||
src={`https://api.hakush.in/hsr/UI/avatarshopicon/${data.id}.webp`}
|
|
||||||
className="w-full h-full rounded-md object-cover"
|
|
||||||
alt="ALT"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
loading='lazy'
|
|
||||||
src={`https://api.hakush.in/hsr/UI/element/${data.damageType.toLowerCase()}.webp`}
|
|
||||||
className="absolute top-0 left-0 w-6 h-6"
|
|
||||||
alt={data.damageType.toLowerCase()}
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
loading='lazy'
|
|
||||||
src={`https://api.hakush.in/hsr/UI/pathicon/${data.baseType.toLowerCase()}.webp`}
|
|
||||||
className="absolute top-0 right-0 w-6 h-6"
|
|
||||||
alt={data.baseType.toLowerCase()}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{locale === "jp" ? (
|
|
||||||
<div
|
<div
|
||||||
className="mt-2 text-center text-base font-normal leading-tight"
|
className={`w-[80px] rounded-md p-[2px] bg-gradient-to-br ${data.rank === "CombatPowerAvatarRarityType5"
|
||||||
dangerouslySetInnerHTML={{ __html: parseRuby(text) }}
|
? "from-yellow-400 via-yellow-300 to-yellow-500"
|
||||||
/>
|
: "from-purple-300 via-purple-200 to-purple-400"
|
||||||
) : (
|
}`}
|
||||||
<div className="mt-2 text-center text-base font-normal leading-tight">
|
>
|
||||||
{text}
|
|
||||||
|
<div className="relative w-full h-full">
|
||||||
|
<img
|
||||||
|
loading="lazy"
|
||||||
|
src={`https://api.hakush.in/hsr/UI/avatarshopicon/${data.id}.webp`}
|
||||||
|
className="w-full h-full rounded-md object-cover"
|
||||||
|
alt="ALT"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
loading='lazy'
|
||||||
|
src={`https://api.hakush.in/hsr/UI/element/${data.damageType.toLowerCase()}.webp`}
|
||||||
|
className="absolute top-0 left-0 w-6 h-6"
|
||||||
|
alt={data.damageType.toLowerCase()}
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
loading='lazy'
|
||||||
|
src={`https://api.hakush.in/hsr/UI/pathicon/${data.baseType.toLowerCase()}.webp`}
|
||||||
|
className="absolute top-0 right-0 w-6 h-6"
|
||||||
|
alt={data.baseType.toLowerCase()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</li>
|
<NameAvatar
|
||||||
|
locale={locale}
|
||||||
|
text={text}
|
||||||
|
className="mt-2 text-center text-base font-normal leading-tight"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export default function Header() {
|
|||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log(navigator.language.slice(0, 2))
|
|
||||||
const cookieLocale = document.cookie.split("; ")
|
const cookieLocale = document.cookie.split("; ")
|
||||||
.find((row) => row.startsWith("MYNEXTAPP_LOCALE"))
|
.find((row) => row.startsWith("MYNEXTAPP_LOCALE"))
|
||||||
?.split("=")[1];
|
?.split("=")[1];
|
||||||
|
|||||||
@@ -14,10 +14,11 @@ import { DamageLineForOne } from "../chart/damageLineForOne";
|
|||||||
import { DamagePerCycleForOne } from "../chart/damagePerCycleForOne";
|
import { DamagePerCycleForOne } from "../chart/damagePerCycleForOne";
|
||||||
import { useCalcTotalDmgAvatar, useCalcTotalTurnAvatar } from "@/hooks/useCalcAvatarData";
|
import { useCalcTotalDmgAvatar, useCalcTotalTurnAvatar } from "@/hooks/useCalcAvatarData";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
import NameAvatar from "../nameAvatar";
|
||||||
// import ShowCaseInfo from "../card/showCaseCard";
|
// import ShowCaseInfo from "../card/showCaseCard";
|
||||||
|
|
||||||
export default function LineupBar() {
|
export default function LineupBar() {
|
||||||
const [selectedCharacter, setSelectedCharacter] = useState<AvatarHakushiType | null>(null);
|
const [selectedCharacter, setSelectedCharacter] = useState<AvatarHakushiType | undefined>(undefined);
|
||||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||||
|
|
||||||
const transI18n = useTranslations("DataAnalysisPage");
|
const transI18n = useTranslations("DataAnalysisPage");
|
||||||
@@ -44,7 +45,7 @@ export default function LineupBar() {
|
|||||||
// Close modal handler
|
// Close modal handler
|
||||||
const handleCloseModal = (modalId: string) => {
|
const handleCloseModal = (modalId: string) => {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
setSelectedCharacter(null);
|
setSelectedCharacter(undefined);
|
||||||
const modal = document.getElementById(modalId) as HTMLDialogElement | null;
|
const modal = document.getElementById(modalId) as HTMLDialogElement | null;
|
||||||
if (modal) {
|
if (modal) {
|
||||||
modal.close()
|
modal.close()
|
||||||
@@ -80,7 +81,16 @@ export default function LineupBar() {
|
|||||||
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
<path strokeLinecap="round" strokeLinejoin="round" d="M17.982 18.725A7.488 7.488 0 0 0 12 15.75a7.488 7.488 0 0 0-5.982 2.975m11.963 0a9 9 0 1 0-11.963 0m11.963 0A8.966 8.966 0 0 1 12 21a8.966 8.966 0 0 1-5.982-2.275M15 9.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<span className="text-sm truncate">{transI18n("lastTurn")}: {getNameChar(locale, listAvatar.find(it => it.id === turnHistory.findLast(i => i?.avatarId)?.avatarId?.toString()))}</span>
|
<span className="text-sm truncate flex flex-row">
|
||||||
|
<div>
|
||||||
|
{transI18n("lastTurn")}:
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<NameAvatar
|
||||||
|
locale={locale}
|
||||||
|
text={getNameChar(locale, listAvatar.find(it => it.id === turnHistory.findLast(i => i?.avatarId)?.avatarId?.toString()))}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -132,9 +142,12 @@ export default function LineupBar() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
<div className="border-b border-purple-500/30 px-6 py-4 mb-4">
|
||||||
<h3 className="font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400">
|
|
||||||
{selectedCharacter ? getNameChar(locale, selectedCharacter).toUpperCase() : ""}
|
<NameAvatar
|
||||||
</h3>
|
locale={locale}
|
||||||
|
text={getNameChar(locale, selectedCharacter).toUpperCase()}
|
||||||
|
className={"font-bold text-2xl text-transparent bg-clip-text bg-gradient-to-r from-pink-400 to-cyan-400"}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{selectedCharacter && (
|
{selectedCharacter && (
|
||||||
|
|||||||
16
src/components/nameAvatar/index.tsx
Normal file
16
src/components/nameAvatar/index.tsx
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { parseRuby } from "@/helper";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
interface TextProps {
|
||||||
|
text: string;
|
||||||
|
locale: string;
|
||||||
|
className?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function NameAvatar({ text, locale, className }: TextProps) {
|
||||||
|
if (locale === "ja") {
|
||||||
|
return <div className={className} dangerouslySetInnerHTML={{ __html: parseRuby(text) }} />;
|
||||||
|
}
|
||||||
|
return <div className={className}>{text}</div>;
|
||||||
|
}
|
||||||
@@ -12,13 +12,19 @@ export function getNameChar(locale: string, data: AvatarHakushiType | undefined)
|
|||||||
|
|
||||||
let text = data.lang.get(listCurrentLanguage[locale as keyof typeof listCurrentLanguage].toLowerCase()) ?? "";
|
let text = data.lang.get(listCurrentLanguage[locale as keyof typeof listCurrentLanguage].toLowerCase()) ?? "";
|
||||||
if (!text) {
|
if (!text) {
|
||||||
text = data.lang.get("en") ?? "";
|
text = data.lang.get("en") ?? "";
|
||||||
}
|
}
|
||||||
if (Number(data.id) % 2 === 0 && Number(data.id) > 8000) {
|
if (Number(data.id) % 2 === 0 && Number(data.id) > 8000) {
|
||||||
text = `Female ${data.damageType} MC`
|
text = `Female ${data.damageType} MC`
|
||||||
} else if (Number(data.id) > 8000) {
|
} else if (Number(data.id) > 8000) {
|
||||||
text = `Male ${data.damageType} MC`
|
text = `Male ${data.damageType} MC`
|
||||||
}
|
}
|
||||||
|
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseRuby(text: string): string {
|
||||||
|
const rubyRegex = /\{RUBY_B#(.*?)\}(.*?)\{RUBY_E#\}/gs;
|
||||||
|
return text.replace(rubyRegex, (_match, furigana, kanji) => {
|
||||||
|
return `<ruby>${kanji}<rt>${furigana}</rt></ruby>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import useSocketStore from "@/stores/socketSettingStore";
|
import useSocketStore from "@/stores/socketSettingStore";
|
||||||
import { AvatarHakushiType, AvatarHakushiRawType } from "@/types/avatar";
|
import { AvatarHakushiType, AvatarHakushiRawType } from "@/types/avatar";
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
export async function checkConnectTcpApi(): Promise<boolean> {
|
export async function checkConnectTcpApi(): Promise<boolean> {
|
||||||
const { host, port, connectionType } = useSocketStore.getState()
|
const { host, port, connectionType } = useSocketStore.getState()
|
||||||
@@ -23,22 +23,27 @@ export async function checkConnectTcpApi(): Promise<boolean> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getCharacterListApi(): Promise<AvatarHakushiType[]> {
|
export async function getCharacterListApi(): Promise<AvatarHakushiType[]> {
|
||||||
const res = await fetch('/api/hakushin', {
|
try {
|
||||||
method: 'GET',
|
const res = await axios.get<Record<string, AvatarHakushiRawType>>(
|
||||||
headers: {
|
'https://api.hakush.in/hsr/data/character.json',
|
||||||
'Content-Type': 'application/json',
|
{
|
||||||
},
|
headers: {
|
||||||
});
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!res.ok) {
|
const data = new Map(Object.entries(res.data));
|
||||||
console.log(`Error ${res.status}: ${res.statusText}`);
|
|
||||||
|
return Array.from(data.entries()).map(([id, it]) => convertAvatar(id, it));
|
||||||
|
} catch (error: unknown) {
|
||||||
|
if (axios.isAxiosError(error)) {
|
||||||
|
console.log(`Error: ${error.response?.status} - ${error.message}`);
|
||||||
|
} else {
|
||||||
|
console.log(`Unexpected error: ${String(error)}`);
|
||||||
|
}
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const data: Map<string, AvatarHakushiRawType> = new Map(Object.entries(await res.json()));
|
|
||||||
|
|
||||||
|
|
||||||
return Array.from(data.entries()).map(([id, it]) => convertAvatar(id, it));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2017",
|
"target": "ES2018",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
@@ -19,9 +22,19 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": [
|
||||||
}
|
"./src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"esModuleInterop": true
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": [
|
||||||
"exclude": ["node_modules"]
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user