Skip to content

Commit 367e25a

Browse files
author
gemini2035
committed
perf(sheet): operator part of sheet optimized
1 parent 0c3e5ed commit 367e25a

File tree

2 files changed

+175
-125
lines changed

2 files changed

+175
-125
lines changed

src/components/editor/operator/sheet/SheetContainerSkeleton.tsx

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
Divider,
3-
H3,
4-
H4,
5-
Icon,
6-
IconName,
7-
MaybeElement,
8-
} from '@blueprintjs/core'
1+
import { Divider, H3, Icon, IconName, MaybeElement } from '@blueprintjs/core'
92

103
import clsx from 'clsx'
114
import { ReactNode, useMemo } from 'react'
@@ -31,11 +24,9 @@ export const SheetContainerSkeleton = ({
3124
() => (
3225
<>
3326
<Icon icon={icon} size={mini ? 16 : 20} />
34-
{mini ? (
35-
<H4 className="p-0 m-0 ml-3">{title}</H4>
36-
) : (
37-
<H3 className="p-0 m-0 ml-3">{title}</H3>
38-
)}
27+
<H3 className={clsx('p-0 m-0 ml-3 truncate', mini && '!text-lg')}>
28+
{title}
29+
</H3>
3930
</>
4031
),
4132
[mini],

src/components/editor/operator/sheet/SheetOperator.tsx

Lines changed: 171 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ const SheetOperator = ({
3232
existedGroups,
3333
miniMedia,
3434
}: SheetOperatorProps) => {
35+
// media warning
36+
useEffect(() => {
37+
return () => {
38+
if (miniMedia)
39+
AppToaster.show({
40+
intent: 'warning',
41+
message: '推荐使用大屏幕进行编辑(宽度>600px)!',
42+
})
43+
}
44+
}, [])
45+
3546
const operatorScrollRef = useRef<HTMLDivElement>(null)
3647

3748
const defaultProf = useMemo(
@@ -74,36 +85,33 @@ const SheetOperator = ({
7485
}
7586
}
7687

77-
const formattedSubProfessions = useMemo(
78-
() => [...defaultSubProf, ...(selectedProf.sub || [])],
88+
const [formattedSubProfessions, operatorsGroupedByProf] = useMemo(
89+
() => [
90+
// handle other operators
91+
[...defaultSubProf, ...(selectedProf.sub || [])],
92+
[
93+
...OPERATORS,
94+
...existedOperators
95+
.filter(
96+
(item) => !OPERATORS.find((opItem) => opItem.name === item.name),
97+
)
98+
.map(({ name }) => {
99+
return {
100+
name,
101+
id: '',
102+
pron: '',
103+
subProf: '',
104+
}
105+
}),
106+
].filter((item) => {
107+
if (selectedProf.id === defaultSubProf[0].id) return true
108+
else if (selectedProf.id === defaultSubProf[1].id)
109+
return item.subProf === 'notchar1' || !item.pron || !item.subProf
110+
else return !!selectedProf.sub?.find((op) => op.id === item.subProf)
111+
}),
112+
],
79113
[selectedProf],
80114
)
81-
const operatorsGroupedByProf = useMemo(() => {
82-
// 处理自命名干员
83-
const allOperators = [
84-
...OPERATORS,
85-
...existedOperators
86-
.filter(
87-
(item) => !OPERATORS.find((opItem) => opItem.name === item.name),
88-
)
89-
.map(({ name }) => {
90-
return {
91-
name,
92-
id: '',
93-
pron: '',
94-
subProf: '',
95-
}
96-
}),
97-
]
98-
if (selectedProf.id === 'all') return allOperators
99-
if (selectedProf.id === 'others')
100-
return allOperators.filter(
101-
(item) => item.subProf === 'notchar1' || !item.pron || !item.subProf,
102-
)
103-
return allOperators.filter(
104-
(op) => !!selectedProf.sub?.find((item) => item.id === op.subProf),
105-
)
106-
}, [selectedProf])
107115

108116
const operatorsGroupedBySubProf = useMemo(() => {
109117
if (selectedSubProf.id === 'all') return operatorsGroupedByProf
@@ -117,11 +125,6 @@ const SheetOperator = ({
117125
)
118126
}, [selectedSubProf, selectedProf])
119127

120-
const selectedAllState = useMemo(
121-
() => !defaultSubProf.find(({ id }) => id === selectedSubProf.id),
122-
[selectedSubProf],
123-
)
124-
125128
const eventHandleProxy = (
126129
type: EventType,
127130
value: Operator,
@@ -148,27 +151,6 @@ const SheetOperator = ({
148151
}
149152
}
150153
}
151-
const selectAll = () => {
152-
operatorsGroupedBySubProf.forEach((item) => {
153-
submitOperator(item, () => {})
154-
})
155-
}
156-
157-
const SelectAll = useMemo(
158-
() => (
159-
<>
160-
{selectedAllState && (
161-
<H6
162-
className="absolute bottom-full right-0 p-3 cursor-pointer m-0"
163-
onClick={selectAll}
164-
>
165-
全选
166-
</H6>
167-
)}
168-
</>
169-
),
170-
[selectedAllState, selectAll],
171-
)
172154

173155
// pagination about
174156
const [pageIndex, setPageIndex] = useState(0)
@@ -190,25 +172,77 @@ const SheetOperator = ({
190172
useEffect(resetPaginationState, [selectedProf, selectedSubProf])
191173

192174
const BackToTop = useMemo(
193-
() =>
194-
backToTop && (
175+
() => (
176+
<Button
177+
minimal
178+
icon="symbol-triangle-up"
179+
disabled={!backToTop}
180+
title={backToTop ? '回到顶部' : undefined}
181+
onClick={resetPaginationState}
182+
/>
183+
),
184+
[backToTop],
185+
)
186+
187+
const selectAll = () => {
188+
operatorsGroupedBySubProf.forEach((item) => {
189+
submitOperator(item, () => {})
190+
})
191+
}
192+
193+
const cancelAll = () => {
194+
const deleteIndexList: number[] = []
195+
operatorsGroupedBySubProf.forEach(({ name }) => {
196+
const index = existedOperators.findIndex((item) => item.name === name)
197+
if (index !== -1) deleteIndexList.push(index)
198+
})
199+
removeOperator(deleteIndexList)
200+
}
201+
202+
const SelectButtons = useMemo(() => {
203+
const [selectAllState, cancelAllState] = [
204+
!operatorsGroupedBySubProf.every(({ name }) =>
205+
checkOperatorSelected(name),
206+
),
207+
operatorsGroupedBySubProf.some(({ name }) => checkOperatorSelected(name)),
208+
]
209+
return (
210+
<>
195211
<Button
196-
className="absolute right-3 bottom-3"
197212
minimal
198-
icon="symbol-triangle-up"
199-
title="回到顶部"
200-
onClick={resetPaginationState}
213+
icon="circle"
214+
disabled={!cancelAllState}
215+
title={`取消选择全部${existedOperators.length}位干员`}
216+
onClick={cancelAll}
201217
/>
202-
),
203-
[backToTop],
218+
<Button
219+
minimal
220+
icon="selection"
221+
title={
222+
selectAllState
223+
? `全选${operatorsGroupedBySubProf.length}位干员`
224+
: undefined
225+
}
226+
disabled={!selectAllState}
227+
onClick={selectAll}
228+
/>
229+
</>
230+
)
231+
}, [operatorsGroupedBySubProf, existedOperators])
232+
233+
const ActionList = (
234+
<div className="absolute bottom-0">
235+
{SelectButtons}
236+
{BackToTop}
237+
</div>
204238
)
205239

206240
const ShowMoreButton = useMemo(
207241
() => (
208242
<div className="flex items-center justify-center pt-3 cursor-default">
209243
{noMore ? (
210244
<>
211-
<H6>已经展示全部干员了</H6>
245+
<H6>已经展示全部干员了({operatorsGroupedBySubProf.length})</H6>
212246
{canEclipse && (
213247
<H6
214248
className="ml-1 cursor-pointer text-sm text-gray-500 hover:text-inherit hover:underline"
@@ -228,61 +262,87 @@ const SheetOperator = ({
228262
)}
229263
</div>
230264
),
231-
[noMore, canEclipse, pageIndex],
265+
[noMore, canEclipse, pageIndex, operatorsGroupedBySubProf.length],
232266
)
233267

234-
const ProfSelect = useMemo(
235-
() => (
236-
<div className="flex flex-row-reverse h-screen sticky top-0 relative">
237-
<div className="h-full flex flex-col mr-0.5 w-12">
238-
{formattedProfessions.map((prof) => (
239-
<div
240-
key={prof.id}
241-
className="grow cursor-pointer relative flex justify-center items-center"
242-
title={prof.name}
243-
onClick={() => setSelectedProf(prof)}
244-
role="presentation"
245-
>
246-
{defaultProf.find(({ id }) => id === prof.id) ? (
247-
<H5>{prof.name}</H5>
248-
) : (
249-
<img
250-
className="invert dark:invert-0"
251-
src={'/assets/prof-icons/' + prof.id + '.png'}
252-
alt={prof.name}
253-
title={prof.name}
254-
/>
255-
)}
256-
{prof.id === selectedProf.id && (
257-
<div className="h-full w-1 bg-black dark:bg-white absolute top-0 right-full rounded" />
258-
)}
259-
</div>
260-
))}
261-
</div>
262-
<Divider />
263-
<div className="mr-1 h-full flex flex-col justify-center items-end">
264-
{formattedSubProfessions?.map((subProf) => (
265-
<H4
266-
key={subProf.id}
267-
className={clsx(
268-
'truncate cursor-pointer my-3 opacity-50 hover:underline hover:text-black hover:opacity-75',
269-
subProf.id === selectedSubProf.id && 'opacity-100 underline',
270-
)}
271-
onClick={() => setSelectedSubProf(subProf)}
272-
>
273-
{subProf.name}
274-
</H4>
275-
))}
276-
</div>
277-
{BackToTop}
268+
const ProfSelectProf = useMemo(() => {
269+
const ClassesManager = {
270+
profButton: miniMedia ? 'w-6' : 'w-12',
271+
specialProfButton: miniMedia ? '!text-xs truncate' : '',
272+
}
273+
return (
274+
<div
275+
className={clsx(
276+
'h-full flex flex-col mr-0.5',
277+
ClassesManager.profButton,
278+
)}
279+
>
280+
{formattedProfessions.map((prof) => (
281+
<div
282+
key={prof.id}
283+
className="grow cursor-pointer relative flex justify-center items-center"
284+
title={prof.name}
285+
onClick={() => {
286+
setSelectedProf(prof)
287+
setSelectedSubProf(defaultSubProf[0])
288+
}}
289+
role="presentation"
290+
>
291+
{defaultProf.find(({ id }) => id === prof.id) ? (
292+
<H5 className={ClassesManager.specialProfButton}>{prof.name}</H5>
293+
) : (
294+
<img
295+
className="invert dark:invert-0"
296+
src={'/assets/prof-icons/' + prof.id + '.png'}
297+
alt={prof.name}
298+
title={prof.name}
299+
/>
300+
)}
301+
{prof.id === selectedProf.id && (
302+
<div className="h-full w-1 bg-black dark:bg-white absolute top-0 right-full rounded" />
303+
)}
304+
</div>
305+
))}
278306
</div>
279-
),
280-
[selectedSubProf, selectedProf, backToTop],
307+
)
308+
}, [selectedProf])
309+
310+
const ProfSelectSubProf = useMemo(
311+
() =>
312+
formattedSubProfessions?.map((subProf) => (
313+
<H4
314+
key={subProf.id}
315+
className={clsx(
316+
'truncate cursor-pointer my-3 opacity-50 hover:underline hover:text-black hover:opacity-75',
317+
subProf.id === selectedSubProf.id && 'opacity-100 underline',
318+
)}
319+
onClick={() => setSelectedSubProf(subProf)}
320+
>
321+
{subProf.name}
322+
</H4>
323+
)),
324+
[selectedProf, selectedSubProf],
325+
)
326+
327+
const ProfSelect = (
328+
<div className="flex flex-row-reverse h-screen sticky top-0 relative">
329+
{ProfSelectProf}
330+
<Divider className="mr-0" />
331+
<div
332+
className={clsx(
333+
'mr-1 h-full flex flex-col justify-center items-end',
334+
miniMedia ? 'absolute right-full' : 'relative',
335+
)}
336+
>
337+
{ProfSelectSubProf}
338+
{ActionList}
339+
</div>
340+
</div>
281341
)
282342

283343
return (
284344
<div className="flex h-full">
285-
<div className="flex-auto px-2" ref={operatorScrollRef}>
345+
<div className="flex-auto px-1" ref={operatorScrollRef}>
286346
{operatorsGroupedBySubProf.length ? (
287347
<>
288348
<div
@@ -316,7 +376,6 @@ const SheetOperator = ({
316376
OperatorNoData
317377
)}
318378
</div>
319-
{/* <Divider /> */}
320379
{ProfSelect}
321380
</div>
322381
)

0 commit comments

Comments
 (0)