Skip to content

Commit 1ba2026

Browse files
authored
Release to Production (#414)
> *This PR is automatically created by actions defined in this repository. To see the run log of this action, please click [here](/ZOOT-Plus/zoot-plus-frontend/actions/runs/15231250540)*
2 parents 93ff1c5 + 32b6862 commit 1ba2026

File tree

86 files changed

+10812
-1071
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+10812
-1071
lines changed

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1+
## 2025-05-25
2+
3+
- 添加干员和职业的英文名称 [@Constrat](https://github.com/Constrat)
4+
- 修复了作业列表里的自定义关卡显示不正常的问题 [@Constrat](https://github.com/Constrat)
5+
- 修复了部分文字的翻译显示不正常的问题 [@guansss](https://github.com/guansss)
6+
- 添加编辑器v2 [@guansss](https://github.com/guansss)
7+
- 优化首页搜索逻辑 [@ChingCdesu](https://github.com/ChingCdesu) [@Aliothmoon](https://github.com/Aliothmoon) [@dragove](https://github.com/dragove)
8+
19
## 2025-05-11
210

3-
- 添加 i18n 及英文翻译 [@Constrat](https://github.com/Constrat) [@guansss](https://github.com/guansss)
11+
- 添加国际化及英文翻译 [@Constrat](https://github.com/Constrat) [@guansss](https://github.com/guansss)
412

513
## 2025-05-02
614

package.json

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
"@blueprintjs/core": "^4.15.1",
2424
"@blueprintjs/popover2": "^1.12.1",
2525
"@blueprintjs/select": "^4.8.18",
26-
"@dnd-kit/core": "^6.0.5",
27-
"@dnd-kit/sortable": "^7.0.1",
28-
"@dnd-kit/utilities": "^3.2.0",
26+
"@dnd-kit/core": "^6.3.1",
27+
"@dnd-kit/sortable": "^10.0.0",
28+
"@dnd-kit/utilities": "^3.2.2",
2929
"@iconify/icons-simple-icons": "^1.2.22",
3030
"@iconify/react": "^3.2.2",
3131
"@sentry/react": "^7.27.0",
@@ -40,7 +40,10 @@
4040
"eslint-plugin-react": "^7.33.2",
4141
"eslint-plugin-react-hooks": "^4.6.0",
4242
"fuse.js": "^6.6.2",
43+
"immer": "^10.1.1",
4344
"jotai": "^2.7.0",
45+
"jotai-devtools": "^0.11.0",
46+
"jotai-immer": "^0.4.1",
4447
"linkify-react": "^3.0.4",
4548
"linkifyjs": "^3.0.5",
4649
"lodash-es": "^4.17.21",
@@ -54,6 +57,7 @@
5457
"react-hook-form": "^7.33.1",
5558
"react-markdown": "^8.0.5",
5659
"react-rating": "^2.0.5",
60+
"react-resizable-panels": "^2.1.8",
5761
"react-rnd": "^10.4.1",
5862
"react-router-dom": "6",
5963
"react-spring": "^9.4.5",
@@ -62,9 +66,10 @@
6266
"remark-gfm": "^3.0.1",
6367
"snakecase-keys": "^5.4.4",
6468
"swr": "^2.2.5",
65-
"type-fest": "^4.10.2",
69+
"type-fest": "^4.40.1",
6670
"unfetch": "^4.2.0",
67-
"vite-tsconfig-paths": "^3.5.0"
71+
"vite-tsconfig-paths": "^3.5.0",
72+
"zod": "^4.0.0-beta.20250424T163858"
6873
},
6974
"devDependencies": {
7075
"@hookform/devtools": "^4.1.1",
@@ -75,7 +80,7 @@
7580
"@types/react": "^18.0.0",
7681
"@types/react-dom": "^18.0.0",
7782
"@typescript-eslint/parser": "^7.0.1",
78-
"@vitejs/plugin-react": "^1.3.0",
83+
"@vitejs/plugin-react": "^4.4.0",
7984
"autoprefixer": "^10.4.7",
8085
"eslint-config-prettier": "^9.1.0",
8186
"eslint-import-resolver-typescript": "^3.6.1",

scripts/shared.ts

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { access } from 'fs/promises'
2-
import { uniq, uniqBy } from 'lodash-es'
2+
import { capitalize, uniq, uniqBy } from 'lodash-es'
33
import fetch from 'node-fetch'
44
import { pinyin } from 'pinyin'
55
import simplebig from 'simplebig'
66

7-
type Profession = { id: string; name: string }
7+
type Profession = { id: string; name: string; name_en?: string }
88
type Professions = (Profession & { sub: Profession[] })[]
99

1010
export async function fileExists(file: string) {
@@ -48,10 +48,14 @@ function transformOperatorName(name: string) {
4848
}
4949
}
5050

51-
const CHARACTER_TABLE_JSON_URL =
51+
const CHARACTER_TABLE_JSON_URL_CN =
5252
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/character_table.json'
53-
const UNIEQUIP_TABLE_JSON_URL =
53+
const UNIEQUIP_TABLE_JSON_URL_CN =
5454
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData/master/zh_CN/gamedata/excel/uniequip_table.json'
55+
const CHARACTER_TABLE_JSON_URL_EN =
56+
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData_YoStar/main/en_US/gamedata/excel/character_table.json'
57+
const UNIEQUIP_TABLE_JSON_URL_EN =
58+
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData_YoStar/main/en_US/gamedata/excel/uniequip_table.json'
5559

5660
const CHARACTER_BLOCKLIST = [
5761
'char_512_aprot', // 暮落(集成战略):It's just not gonna be there.
@@ -74,51 +78,85 @@ async function json(url: string) {
7478
}
7579

7680
export async function getOperators() {
77-
const [charTable, uniequipTable] = await Promise.all([
78-
json(CHARACTER_TABLE_JSON_URL),
79-
json(UNIEQUIP_TABLE_JSON_URL),
80-
])
81+
const [charTableCN, uniequipTableCN, charTableEN, uniequipTableEN] =
82+
await Promise.all([
83+
json(CHARACTER_TABLE_JSON_URL_CN),
84+
json(UNIEQUIP_TABLE_JSON_URL_CN),
85+
json(CHARACTER_TABLE_JSON_URL_EN),
86+
json(UNIEQUIP_TABLE_JSON_URL_EN),
87+
])
8188

82-
const { subProfDict } = uniequipTable
89+
const { subProfDict: subProfDictCN, equipDict } = uniequipTableCN
90+
const { subProfDict: subProfDictEN } = uniequipTableEN
91+
const equipsByOperatorId = Object.values(equipDict).reduce(
92+
(acc: Record<string, any[]>, equip: any) => {
93+
acc[equip.charId] ||= []
94+
acc[equip.charId].push(equip)
95+
return acc
96+
},
97+
{},
98+
)
8399

84-
const opIds = Object.keys(charTable)
100+
const opIds = Object.keys(charTableCN)
85101
const professions: Professions = []
86102
const result = uniqBy(
87103
opIds.flatMap((id) => {
88-
const op = charTable[id]
104+
const op = charTableCN[id]
105+
const enName = charTableEN[id]?.name || op.appellation || op.name
106+
89107
if (['TRAP'].includes(op.profession)) return []
90108

91109
if (!['TOKEN'].includes(op.profession)) {
92110
const prof = professions.find((p) => p.id === op.profession)
93111
if (!prof) {
112+
const enSubProfName =
113+
subProfDictEN?.[op.subProfessionId]?.subProfessionName ||
114+
capitalize(op.subProfessionId)
115+
94116
professions.push({
95117
id: op.profession,
96118
name: PROFESSION_NAMES[op.profession],
119+
name_en:
120+
op.profession.charAt(0) + op.profession.slice(1).toLowerCase(),
97121
sub: [
98122
{
99123
id: op.subProfessionId,
100-
name: subProfDict[op.subProfessionId].subProfessionName,
124+
name: subProfDictCN[op.subProfessionId].subProfessionName,
125+
name_en: enSubProfName,
101126
},
102127
],
103128
})
104129
} else if (!prof.sub.find((p) => p.id === op.subProfessionId)) {
130+
const enSubProfName =
131+
subProfDictEN?.[op.subProfessionId]?.subProfessionName ||
132+
capitalize(op.subProfessionId)
133+
105134
prof.sub.push({
106135
id: op.subProfessionId,
107-
name: subProfDict[op.subProfessionId].subProfessionName,
136+
name: subProfDictCN[op.subProfessionId].subProfessionName,
137+
name_en: enSubProfName,
108138
})
109139
}
110140
}
141+
const modules = equipsByOperatorId[id]
142+
?.sort((a, b) => a.charEquipOrder - b.charEquipOrder)
143+
.map(({ typeName1, typeName2 }) => {
144+
return typeName1 === 'ORIGINAL' ? '' : typeName2
145+
})
146+
.map((m) => (m === 'A' ? 'α' : m === 'D' ? 'Δ' : m))
111147
return [
112148
{
113149
id: id,
114150
prof: op.profession,
115151
subProf: op.subProfessionId,
152+
name_en: enName,
116153
...transformOperatorName(op.name),
117154
rarity:
118155
op.subProfessionId === 'notchar1'
119156
? 0
120157
: Number(op.rarity?.split('TIER_').join('') || 0),
121158
alt_name: op.appellation,
159+
modules,
122160
},
123161
]
124162
}),

src/apis/announcement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const isMock = process.env.NODE_ENV === 'development'
77

88
const announcementURL = isMock
99
? mockFile
10-
: 'https://ota.maa.plus/MaaAssistantArknights/api/announcements/copilot.md'
10+
: 'https://api.maa.plus/MaaAssistantArknights/api/announcements/copilot.md'
1111

1212
export const announcementBaseURL = isMock
1313
? location.href

src/apis/operation.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
CopilotInfoStatusEnum,
55
QueriesCopilotRequest,
66
} from 'maa-copilot-client'
7-
import useSWR from 'swr'
7+
import useSWR, { SWRConfiguration } from 'swr'
88
import useSWRInfinite from 'swr/infinite'
99

1010
import { toCopilotOperation } from 'models/converter'
@@ -161,16 +161,15 @@ export function useRefreshOperations() {
161161
return () => refresh((key) => key.includes('operations'))
162162
}
163163

164-
interface UseOperationParams {
164+
interface UseOperationParams extends SWRConfiguration {
165165
id?: number
166-
suspense?: boolean
167166
}
168167

169-
export function useOperation({ id, suspense }: UseOperationParams) {
168+
export function useOperation({ id, ...config }: UseOperationParams) {
170169
return useSWR(
171170
id ? ['operation', id] : null,
172171
() => getOperation({ id: id! }),
173-
{ suspense },
172+
config,
174173
)
175174
}
176175

@@ -196,7 +195,8 @@ export async function createOperation(req: {
196195
content: string
197196
status: CopilotInfoStatusEnum
198197
}) {
199-
await new OperationApi().uploadCopilot({ copilotCUDRequest: req })
198+
return (await new OperationApi().uploadCopilot({ copilotCUDRequest: req }))
199+
.data
200200
}
201201

202202
export async function updateOperation(req: {

src/assets/icons/elite_0.png

23 KB
Loading

src/assets/icons/elite_1.png

16.8 KB
Loading

src/assets/icons/elite_2.png

28.6 KB
Loading

src/components/ActionCard.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,9 @@ export const ActionCard: FC<ActionCardProps> = ({
113113
{action.preDelay ? formatDuration(action.preDelay) : '-'}
114114
</InlineCondition>
115115
<InlineCondition title={t.components.ActionCard.rear_delay}>
116-
{action.rearDelay ? formatDuration(action.rearDelay) : '-'}
116+
{action.rearDelay || action.postDelay
117+
? formatDuration(action.rearDelay || action.postDelay!)
118+
: '-'}
117119
</InlineCondition>
118120
</div>
119121
</Card>

src/components/MasteryIcon.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { FC } from 'react'
2+
3+
interface MasteryIconProps extends React.SVGProps<SVGSVGElement> {
4+
mastery: number
5+
mainClassName?: string
6+
subClassName?: string
7+
}
8+
9+
export const MasteryIcon: FC<MasteryIconProps> = ({
10+
mastery,
11+
mainClassName = 'fill-current',
12+
subClassName = 'fill-gray-300 dark:fill-gray-600',
13+
...props
14+
}) => {
15+
return (
16+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" {...props}>
17+
<circle
18+
className={mastery >= 1 ? mainClassName : subClassName}
19+
cx="50"
20+
cy="27"
21+
r="22"
22+
/>
23+
<circle
24+
className={mastery >= 2 ? mainClassName : subClassName}
25+
cx="75"
26+
cy="70"
27+
r="22"
28+
/>
29+
<circle
30+
className={mastery >= 3 ? mainClassName : subClassName}
31+
cx="25"
32+
cy="70"
33+
r="22"
34+
/>
35+
</svg>
36+
)
37+
}

0 commit comments

Comments
 (0)