Skip to content

Commit 1df46a5

Browse files
authored
Editor v2 (#402)
功能已完整,等合并到 dev 之后就可以上线测试了 新编辑器是独立运行的,虽然修改了一些和旧编辑器共用的代码,但不影响旧编辑器的使用
2 parents 3fef9b1 + e276421 commit 1df46a5

Some content is hidden

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

72 files changed

+10052
-925
lines changed

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: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ const CHARACTER_TABLE_JSON_URL_EN =
5656
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData_YoStar/main/en_US/gamedata/excel/character_table.json'
5757
const UNIEQUIP_TABLE_JSON_URL_EN =
5858
'https://raw.githubusercontent.com/Kengxxiao/ArknightsGameData_YoStar/main/en_US/gamedata/excel/uniequip_table.json'
59+
5960
const CHARACTER_BLOCKLIST = [
6061
'char_512_aprot', // 暮落(集成战略):It's just not gonna be there.
6162
'token_10012_rosmon_shield', // 迷迭香的战术装备:It's just not gonna be there.
@@ -85,8 +86,16 @@ export async function getOperators() {
8586
json(UNIEQUIP_TABLE_JSON_URL_EN),
8687
])
8788

88-
const { subProfDict: subProfDictCN } = uniequipTableCN
89+
const { subProfDict: subProfDictCN, equipDict } = uniequipTableCN
8990
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+
)
9099

91100
const opIds = Object.keys(charTableCN)
92101
const professions: Professions = []
@@ -129,6 +138,12 @@ export async function getOperators() {
129138
})
130139
}
131140
}
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))
132147
return [
133148
{
134149
id: id,
@@ -141,6 +156,7 @@ export async function getOperators() {
141156
? 0
142157
: Number(op.rarity?.split('TIER_').join('') || 0),
143158
alt_name: op.appellation,
159+
modules,
144160
},
145161
]
146162
}),

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+
}

src/components/Select.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Button, ButtonProps, Label } from '@blueprintjs/core'
1+
import { Button, ButtonProps, Classes, Label } from '@blueprintjs/core'
2+
import { Classes as Popover2Classes } from '@blueprintjs/popover2'
23
import {
34
QueryList,
45
Select2,
@@ -27,8 +28,9 @@ export const Select = <T,>({
2728
canReset ??= selectedItem !== undefined
2829

2930
return (
30-
<Label className={clsx('!flex items-center !mb-0', className)}>
31+
<Label className={clsx('!inline-flex items-center !mb-0', className)}>
3132
<Select2
33+
ref={patchHandleItemSelect}
3234
className="!mt-0"
3335
resetOnQuery={false} // 这个功能有无限 reset 的 bug,不要用
3436
inputProps={{
@@ -39,8 +41,6 @@ export const Select = <T,>({
3941
),
4042
}}
4143
{...props}
42-
// 传给 QueryList,给下面的补丁用
43-
{...{ _parentType: 'Select' }}
4444
/>
4545
{canReset && (
4646
<Button
@@ -60,8 +60,28 @@ export const Select = <T,>({
6060
)
6161
}
6262

63+
// 临时实现 PR 里的内容: https://github.com/palantir/blueprint/pull/6070
64+
// TODO: 升级到 BP 5 后删除
65+
function patchHandleItemSelect(instance: Select2<any> | null) {
66+
if (!instance || instance['handleItemSelect']._patched) return
67+
instance['handleItemSelect'] = (
68+
item: unknown,
69+
event?: React.SyntheticEvent<HTMLElement>,
70+
) => {
71+
const target = event?.target as HTMLElement
72+
const shouldDismiss =
73+
target
74+
?.closest(`.${Classes.MENU_ITEM}`)
75+
?.classList?.contains(Popover2Classes.POPOVER2_DISMISS) ?? true
76+
77+
instance.setState({ isOpen: !shouldDismiss })
78+
instance.props.onItemSelect?.(item, event)
79+
}
80+
instance['handleItemSelect']._patched = true
81+
}
82+
//
83+
6384
// 修复 BP 的远古 bug:https://github.com/palantir/blueprint/issues/3751
64-
// 补丁只对 Select 组件启用,因为不知道对 Suggest 和 MultiSelect 是否有效,先不管了
6585

6686
const originalSetQuery =
6787
(QueryList.prototype.setQuery as any)._original ??
@@ -77,10 +97,7 @@ const originalGetActiveIndex =
7797
(QueryList.prototype['getActiveIndex'] as any)._original ??
7898
QueryList.prototype['getActiveIndex']
7999
QueryList.prototype['getActiveIndex'] = function (items) {
80-
if (
81-
this.props['_parentType'] === 'Select' &&
82-
(this as any)._isCallingSetQuery
83-
) {
100+
if ((this as any)._isCallingSetQuery) {
84101
const activeItem =
85102
this.props.activeItem === undefined
86103
? this.state.activeItem

0 commit comments

Comments
 (0)