Skip to content

Commit 9812256

Browse files
Merge pull request #272 from MaaAssistantArknights/dev
Release
2 parents 2cccdc0 + cd95534 commit 9812256

Some content is hidden

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

44 files changed

+2148
-531
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
.eslintrc.js
2+
do not edit these files

.eslintrc.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ module.exports = {
1515
'plugin:import/recommended',
1616
'plugin:import/typescript',
1717
'plugin:react/jsx-runtime',
18+
"plugin:react-hooks/recommended"
1819
],
1920
parser: '@typescript-eslint/parser',
2021
parserOptions: {
@@ -35,6 +36,7 @@ module.exports = {
3536
'react/self-closing-comp': 'error',
3637
'no-unused-vars': 'off',
3738
eqeqeq: 'error',
39+
"react-hooks/exhaustive-deps": "error",
3840
},
3941
settings: {
4042
react: {

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
build
22
coverage
3+
do not edit these files

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
## 2024-04-01
2+
3+
- 添加了作业集功能
4+
- 添加了更新日志功能
5+
- 添加了对浏览器“返回”和“前进”按钮的支持
6+
- 调整了快捷干员选择器中的文字提示样式,让其能适应夜间模式
7+
- 修复了无法搜索神秘代码的问题
8+
- 修复了无法在编辑器中导入神秘代码的问题

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"linkify-react": "^3.0.4",
4545
"linkifyjs": "^3.0.5",
4646
"lodash-es": "^4.17.21",
47-
"maa-copilot-client": "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.726.3d19287",
47+
"maa-copilot-client": "https://github.com/MaaAssistantArknights/maa-copilot-client-ts.git#0.1.0-SNAPSHOT.758.dbc2eb1",
4848
"normalize.css": "^8.0.1",
4949
"prettier": "^3.2.5",
5050
"react": "^18.0.0",

src/apis/operation-set.ts

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import { useAtomValue } from 'jotai'
2+
import {
3+
CopilotSetPageRes,
4+
CopilotSetQuery,
5+
CopilotSetStatus,
6+
} from 'maa-copilot-client'
7+
import useSWR from 'swr'
8+
import useSWRInfinite from 'swr/infinite'
9+
10+
import { authAtom } from 'store/auth'
11+
import { OperationSetApi } from 'utils/maa-copilot-client'
12+
import { useSWRRefresh } from 'utils/swr'
13+
14+
export type OrderBy = 'views' | 'hot' | 'id'
15+
16+
export interface UseOperationSetsParams {
17+
keyword?: string
18+
byMyself?: boolean
19+
20+
disabled?: boolean
21+
suspense?: boolean
22+
}
23+
24+
export function useOperationSets({
25+
keyword,
26+
byMyself,
27+
disabled,
28+
suspense,
29+
}: UseOperationSetsParams) {
30+
const { userId } = useAtomValue(authAtom)
31+
32+
const {
33+
data: pages,
34+
error,
35+
setSize,
36+
isValidating,
37+
} = useSWRInfinite(
38+
(pageIndex, previousPage: CopilotSetPageRes) => {
39+
if (disabled) {
40+
return null
41+
}
42+
if (previousPage && !previousPage.hasNext) {
43+
return null // reached the end
44+
}
45+
46+
return [
47+
'operationSets',
48+
{
49+
limit: 50,
50+
page: pageIndex + 1,
51+
keyword,
52+
creatorId: byMyself ? userId : undefined,
53+
} satisfies CopilotSetQuery,
54+
byMyself,
55+
]
56+
},
57+
async ([, req, byMyself]) => {
58+
const res = await new OperationSetApi({
59+
sendToken: byMyself ? 'always' : 'optional', // 如果有 token 会用来获取自己的作业集
60+
requireData: true,
61+
}).querySets({ copilotSetQuery: req })
62+
return res.data
63+
},
64+
{
65+
suspense,
66+
focusThrottleInterval: 1000 * 60 * 30,
67+
},
68+
)
69+
70+
const isReachingEnd = !!pages?.some((page) => !page.hasNext)
71+
const operationSets = pages?.map((page) => page.data).flat()
72+
73+
return {
74+
operationSets,
75+
error,
76+
setSize,
77+
isValidating,
78+
isReachingEnd,
79+
}
80+
}
81+
82+
export function useRefreshOperationSets() {
83+
const refresh = useSWRRefresh()
84+
return () => refresh((key) => key.includes('operationSets'))
85+
}
86+
87+
interface UseOperationSetParams {
88+
id?: number
89+
suspense?: boolean
90+
}
91+
92+
export function useOperationSet({ id, suspense }: UseOperationSetParams) {
93+
return useSWR(
94+
id ? ['operationSet', id] : null,
95+
() => getOperationSet({ id: id! }),
96+
{ suspense },
97+
)
98+
}
99+
100+
export function useRefreshOperationSet() {
101+
const refresh = useSWRRefresh()
102+
return (id: number) =>
103+
refresh((key) => key.includes('operationSet') && key.includes(String(id)))
104+
}
105+
106+
export async function getOperationSet(req: { id: number }) {
107+
const res = await new OperationSetApi({
108+
sendToken: 'optional', // 如果有 token 会用来获取用户是否点赞
109+
requireData: true,
110+
}).getSet(req)
111+
return res.data
112+
}
113+
114+
export async function createOperationSet(req: {
115+
name: string
116+
description: string
117+
operationIds: number[]
118+
status: CopilotSetStatus
119+
}) {
120+
await new OperationSetApi().createSet({
121+
copilotSetCreateReq: {
122+
name: req.name,
123+
description: req.description,
124+
copilotIds: req.operationIds,
125+
status: req.status,
126+
},
127+
})
128+
}
129+
130+
export async function updateOperationSet(req: {
131+
id: number
132+
name: string
133+
description: string
134+
status: CopilotSetStatus
135+
}) {
136+
await new OperationSetApi().updateCopilotSet({ copilotSetUpdateReq: req })
137+
}
138+
139+
export async function deleteOperationSet(req: { id: number }) {
140+
await new OperationSetApi().deleteCopilotSet({ commonIdReqLong: req })
141+
}
142+
143+
export async function addToOperationSet(req: {
144+
operationSetId: number
145+
operationIds: number[]
146+
}) {
147+
await new OperationSetApi().addCopilotIds({
148+
copilotSetModCopilotsReq: {
149+
id: req.operationSetId,
150+
copilotIds: req.operationIds,
151+
},
152+
})
153+
}
154+
155+
export async function removeFromOperationSet(req: {
156+
operationSetId: number
157+
operationIds: number[]
158+
}) {
159+
await new OperationSetApi().removeCopilotIds({
160+
copilotSetModCopilotsReq: {
161+
id: req.operationSetId,
162+
copilotIds: req.operationIds,
163+
},
164+
})
165+
}

src/apis/operation.ts

Lines changed: 61 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
1-
import { CopilotPageInfo, QueriesCopilotRequest } from 'maa-copilot-client'
1+
import { QueriesCopilotRequest } from 'maa-copilot-client'
22
import useSWR from 'swr'
33
import useSWRInfinite from 'swr/infinite'
44

5-
import { OpRatingType } from 'models/operation'
5+
import { toCopilotOperation } from 'models/converter'
6+
import { OpRatingType, Operation } from 'models/operation'
7+
import { parseShortCode } from 'models/shortCode'
68
import { OperationApi } from 'utils/maa-copilot-client'
9+
import { useSWRRefresh } from 'utils/swr'
710

811
export type OrderBy = 'views' | 'hot' | 'id'
912

1013
export interface UseOperationsParams {
11-
orderBy: OrderBy
14+
orderBy?: OrderBy
1215
descending?: boolean
1316
keyword?: string
1417
levelKeyword?: string
1518
operator?: string
19+
operationIds?: number[]
1620
byMyself?: boolean
1721

1822
disabled?: boolean
@@ -25,23 +29,39 @@ export function useOperations({
2529
keyword,
2630
levelKeyword,
2731
operator,
32+
operationIds,
2833
byMyself,
2934
disabled,
3035
suspense,
3136
}: UseOperationsParams) {
3237
const {
38+
error,
3339
data: pages,
3440
setSize,
3541
isValidating,
3642
} = useSWRInfinite(
37-
(pageIndex, previousPage: CopilotPageInfo) => {
43+
(pageIndex, previousPage: { hasNext: boolean }) => {
3844
if (disabled) {
3945
return null
4046
}
4147
if (previousPage && !previousPage.hasNext) {
4248
return null // reached the end
4349
}
4450

51+
// 用户输入 maa://xxxxxx 时,只传这个 id,其他参数都不传
52+
if (keyword) {
53+
const id = parseShortCode(keyword)
54+
55+
if (id) {
56+
return [
57+
'operations',
58+
{
59+
copilotIds: [id],
60+
} satisfies QueriesCopilotRequest,
61+
]
62+
}
63+
}
64+
4565
return [
4666
'operations',
4767
{
@@ -52,16 +72,33 @@ export function useOperations({
5272
operator,
5373
orderBy,
5474
desc: descending,
75+
copilotIds: operationIds,
5576
uploaderId: byMyself ? 'me' : undefined,
5677
} satisfies QueriesCopilotRequest,
5778
]
5879
},
5980
async ([, req]) => {
81+
// 如果指定了 id 列表,但是列表为空,就直接返回空数据。不然要是直接传空列表,就相当于没有这个参数,
82+
// 会导致后端返回所有数据
83+
if (req.copilotIds?.length === 0) {
84+
return { data: [], hasNext: false }
85+
}
86+
6087
const res = await new OperationApi({
61-
sendToken: req.uploaderId === 'me' ? 'always' : 'never',
88+
sendToken:
89+
'uploaderId' in req && req.uploaderId === 'me' ? 'always' : 'never',
6290
requireData: true,
6391
}).queriesCopilot(req)
64-
return res.data
92+
93+
const parsedOperations: Operation[] = res.data.data.map((operation) => ({
94+
...operation,
95+
parsedContent: toCopilotOperation(operation),
96+
}))
97+
98+
return {
99+
...res.data,
100+
data: parsedOperations,
101+
}
65102
},
66103
{
67104
suspense,
@@ -74,13 +111,19 @@ export function useOperations({
74111
const operations = pages?.map((page) => page.data).flat()
75112

76113
return {
114+
error,
77115
operations,
78116
setSize,
79117
isValidating,
80118
isReachingEnd,
81119
}
82120
}
83121

122+
export function useRefreshOperations() {
123+
const refresh = useSWRRefresh()
124+
return () => refresh((key) => key.includes('operations'))
125+
}
126+
84127
interface UseOperationParams {
85128
id?: number
86129
suspense?: boolean
@@ -94,12 +137,22 @@ export function useOperation({ id, suspense }: UseOperationParams) {
94137
)
95138
}
96139

97-
export async function getOperation(req: { id: number }) {
140+
export function useRefreshOperation() {
141+
const refresh = useSWRRefresh()
142+
return (id: number) =>
143+
refresh((key) => key.includes('operation') && key.includes(String(id)))
144+
}
145+
146+
export async function getOperation(req: { id: number }): Promise<Operation> {
98147
const res = await new OperationApi({
99148
sendToken: 'optional', // 如果有 token 会用来获取用户是否点赞
100149
requireData: true,
101150
}).getCopilotById(req)
102-
return res.data
151+
152+
return {
153+
...res.data,
154+
parsedContent: toCopilotOperation(res.data),
155+
}
103156
}
104157

105158
export async function createOperation(req: { content: string }) {

0 commit comments

Comments
 (0)