|
1 |
| -import { Button, Divider, H4, H5, H6 } from '@blueprintjs/core' |
2 |
| -import { Popover2 } from '@blueprintjs/popover2' |
3 |
| -import { POPOVER2_DISMISS } from '@blueprintjs/popover2/lib/esm/classes' |
| 1 | +import { FC, useEffect, useRef, useState } from 'react' |
4 | 2 |
|
5 |
| -import clsx from 'clsx' |
6 |
| -import { useAtomValue } from 'jotai' |
7 |
| -import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react' |
8 |
| - |
9 |
| -import { OPERATORS, PROFESSIONS } from 'models/operator' |
10 |
| -import { favOperatorAtom } from 'store/useFavOperators' |
11 |
| - |
12 |
| -import { Operator } from '../EditorSheet' |
13 | 3 | import { SheetContainerSkeleton } from './SheetContainerSkeleton'
|
14 | 4 | import { OperatorNoData } from './SheetNoneData'
|
15 |
| -import { useSheet } from './SheetProvider' |
16 |
| -import { ProfClassification } from './sheetOperator/ProfClassification' |
| 5 | +import { |
| 6 | + ProfClassification, |
| 7 | + ProfClassificationProp, |
| 8 | + defaultProfFilter, |
| 9 | +} from './sheetOperator/ProfClassification' |
17 | 10 | import { SheetOperatorItem } from './sheetOperator/SheetOperatorItem'
|
| 11 | +import { ShowMore, defaultPagination } from './sheetOperator/ShowMore' |
| 12 | +import { |
| 13 | + PaginationFilter, |
| 14 | + useOperatorAfterFiltered, |
| 15 | +} from './sheetOperator/useOperatorFilter' |
18 | 16 |
|
19 | 17 | export interface SheetOperatorProps {}
|
20 | 18 |
|
21 |
| -export interface OperatorModifyProps { |
22 |
| - operatorPinHandle?: (value: Operator) => void |
23 |
| - operatorSelectHandle?: (value: string) => void |
24 |
| - // operatorSkillHandle?: (value: Operator) => void |
25 |
| -} |
26 |
| - |
27 |
| -// const defaultProf = [ |
28 |
| -// { |
29 |
| -// id: 'all', |
30 |
| -// name: '全部', |
31 |
| -// sub: [], |
32 |
| -// }, |
33 |
| -// { |
34 |
| -// id: 'fav', |
35 |
| -// name: '收藏', |
36 |
| -// sub: [], |
37 |
| -// }, |
38 |
| -// { |
39 |
| -// id: 'others', |
40 |
| -// name: '其它', |
41 |
| -// sub: [], |
42 |
| -// }, |
43 |
| -// ] |
44 |
| - |
45 |
| -// const defaultSubProf = [ |
46 |
| -// { id: 'allSubProf', name: '全部' }, |
47 |
| -// { id: 'selected', name: '已选择' }, |
48 |
| -// ] |
49 |
| - |
50 |
| -// const formattedProfessions = [ |
51 |
| -// ...defaultProf.slice(0, defaultProf.length - 1), |
52 |
| -// ...PROFESSIONS, |
53 |
| -// ...defaultProf.slice(defaultProf.length - 1), |
54 |
| -// ] |
55 |
| - |
56 | 19 | const paginationSize = 60
|
57 | 20 | // const defaultRarityFilter = Array.from(
|
58 | 21 | // new Array(Math.max(...OPERATORS.map(({ rarity }) => rarity)) + 1).keys(),
|
59 | 22 | // ).slice(Math.min(...OPERATORS.map(({ rarity }) => rarity)))
|
60 | 23 |
|
61 | 24 | const SheetOperator: FC<SheetOperatorProps> = () => {
|
62 |
| - const { submitOperator, existedOperators, removeOperator, existedGroups } = |
63 |
| - useSheet() |
64 | 25 | const operatorScrollRef = useRef<HTMLDivElement>(null)
|
65 | 26 |
|
66 |
| - // const [selectedProf, setSelectedProf] = useState(formattedProfessions[0]) |
67 |
| - // const [selectedSubProf, setSelectedSubProf] = useState(defaultSubProf[0]) |
68 |
| - // const [operatorRarity, setOperatorRarity] = useState(defaultRarityFilter) |
69 |
| - const [rarityReverse, setRarityReverse] = useState(false) |
70 |
| - // const favOperators = useAtomValue(favOperatorAtom) |
71 |
| - |
72 |
| - // const [formattedSubProfessions, operatorsGroupedByProf] = useMemo( |
73 |
| - // () => [ |
74 |
| - // // handle customize operators |
75 |
| - // [...defaultSubProf, ...(selectedProf.sub || [])], |
76 |
| - // [ |
77 |
| - // ...existedOperators |
78 |
| - // .filter((item) => !OPERATORS.find(({ name }) => name === item.name)) |
79 |
| - // .map(({ name }) => { |
80 |
| - // return { |
81 |
| - // name, |
82 |
| - // subProf: '', |
83 |
| - // rarity: 0, |
84 |
| - // } |
85 |
| - // }), |
86 |
| - // ...OPERATORS, |
87 |
| - // ].filter((item) => { |
88 |
| - // if (selectedProf.id === defaultProf[0].id) return true |
89 |
| - // if (selectedProf.id === defaultProf[1].id) |
90 |
| - // return !!favOperators.find(({ name }) => name === item.name) |
91 |
| - // else if (selectedProf.id === defaultProf[2].id) { |
92 |
| - // return item.subProf === 'notchar1' || !item.subProf |
93 |
| - // } else return !!selectedProf.sub?.find((op) => op.id === item.subProf) |
94 |
| - // }), |
95 |
| - // ], |
96 |
| - // [selectedProf.sub, selectedProf.id, existedOperators, favOperators], |
97 |
| - // ) |
98 |
| - |
99 |
| - const checkOperatorSelected = useCallback( |
100 |
| - (target: string) => { |
101 |
| - if (existedOperators.find((item) => item.name === target)) return true |
102 |
| - else |
103 |
| - return !!existedGroups |
104 |
| - .map((item) => item.opers) |
105 |
| - .flat() |
106 |
| - .find((item) => item?.name === target) |
107 |
| - }, |
108 |
| - [existedOperators, existedGroups], |
109 |
| - ) |
| 27 | + const [profFilter, setProfFilter] = |
| 28 | + useState<ProfClassificationProp['profFilter']>(defaultProfFilter) |
110 | 29 |
|
111 | 30 | // const getOperatorRarity = (target: string) =>
|
112 | 31 | // operatorsGroupedByProf.find((item) => item.name === target)!.rarity
|
113 | 32 |
|
114 |
| - // const operatorsGroupedBySubProf = useMemo(() => { |
115 |
| - // let result: Operator[] = [] |
116 |
| - // if (selectedSubProf.id === 'all') result = operatorsGroupedByProf |
117 |
| - // else if (selectedSubProf.id === 'selected') |
118 |
| - // result = operatorsGroupedByProf.filter((item) => |
119 |
| - // checkOperatorSelected(item.name), |
120 |
| - // ) |
121 |
| - // else |
122 |
| - // result = operatorsGroupedByProf.filter( |
123 |
| - // (item) => item.subProf === selectedSubProf.id, |
124 |
| - // ) |
125 |
| - |
126 |
| - // result = result |
127 |
| - // .filter(({ name }) => { |
128 |
| - // return ( |
129 |
| - // operatorRarity.findIndex( |
130 |
| - // (rarity) => getOperatorRarity(name) === rarity, |
131 |
| - // ) !== -1 |
132 |
| - // ) |
133 |
| - // }) |
134 |
| - // .sort( |
135 |
| - // ({ name: aName }, { name: bName }) => |
136 |
| - // getOperatorRarity(bName) - getOperatorRarity(aName), |
137 |
| - // ) |
138 |
| - |
139 |
| - // return rarityReverse ? result.reverse() : result |
140 |
| - // }, [ |
141 |
| - // selectedSubProf, |
142 |
| - // operatorsGroupedByProf, |
143 |
| - // checkOperatorSelected, |
144 |
| - // operatorRarity, |
145 |
| - // rarityReverse, |
146 |
| - // getOperatorRarity, |
147 |
| - // ]) |
148 |
| - |
149 | 33 | // pagination about via frontened
|
150 |
| - const [pageIndex, setPageIndex] = useState(0) |
151 |
| - const lastIndex = (pageIndex + 1) * paginationSize |
152 |
| - const backToTop = lastIndex > paginationSize |
153 |
| - |
154 |
| - const resetPaginationState = () => { |
155 |
| - setPageIndex(0) |
156 |
| - operatorScrollRef?.current?.scrollIntoView() |
157 |
| - } |
| 34 | + const [pagination, setPagination] = |
| 35 | + useState<PaginationFilter>(defaultPagination) |
158 | 36 |
|
159 | 37 | // useEffect(resetPaginationState, [selectedProf, selectedSubProf])
|
160 | 38 |
|
@@ -221,111 +99,55 @@ const SheetOperator: FC<SheetOperatorProps> = () => {
|
221 | 99 |
|
222 | 100 | // console.log(selectedProf, selectedSubProf)
|
223 | 101 |
|
224 |
| - // const ShowMoreButton = ( |
225 |
| - // <div className="flex items-center justify-center pt-3 cursor-default"> |
226 |
| - // {lastIndex >= operatorsGroupedBySubProf.length ? ( |
227 |
| - // <> |
228 |
| - // <H6>已经展示全部干员了({operatorsGroupedBySubProf.length})</H6> |
229 |
| - // {operatorsGroupedBySubProf.length > paginationSize && ( |
230 |
| - // <H6 |
231 |
| - // className="ml-1 cursor-pointer text-sm text-gray-500 hover:text-inherit hover:underline" |
232 |
| - // onClick={resetPaginationState} |
233 |
| - // > |
234 |
| - // 收起 |
235 |
| - // </H6> |
236 |
| - // )} |
237 |
| - // </> |
238 |
| - // ) : ( |
239 |
| - // <H6 |
240 |
| - // className="cursor-pointer mx-auto text-sm text-gray-500 hover:text-inherit hover:underline" |
241 |
| - // onClick={() => setPageIndex(pageIndex + 1)} |
242 |
| - // > |
243 |
| - // 显示更多干员(剩余{operatorsGroupedBySubProf.length - lastIndex}) |
244 |
| - // </H6> |
245 |
| - // )} |
246 |
| - // </div> |
247 |
| - // ) |
| 102 | + const toTop = () => { |
| 103 | + operatorScrollRef?.current?.scrollIntoView() |
| 104 | + } |
248 | 105 |
|
249 |
| - // const ProfSelect = ( |
250 |
| - // <div className="flex flex-row-reverse h-screen sticky top-0 relative"> |
251 |
| - // <div className="h-full flex flex-col mr-0.5 w-6 sm:w-12"> |
252 |
| - // {formattedProfessions.map((prof) => ( |
253 |
| - // <div |
254 |
| - // key={prof.id} |
255 |
| - // className="grow cursor-pointer relative flex justify-center items-center" |
256 |
| - // title={prof.name} |
257 |
| - // onClick={() => { |
258 |
| - // setSelectedProf(prof) |
259 |
| - // setSelectedSubProf(defaultSubProf[0]) |
260 |
| - // }} |
261 |
| - // role="presentation" |
262 |
| - // > |
263 |
| - // <img |
264 |
| - // className="invert dark:invert-0" |
265 |
| - // src={'/assets/prof-icons/' + prof.id + '.png'} |
266 |
| - // alt="" |
267 |
| - // onError={() => ( |
268 |
| - // <H5 className="!text-xs sm:!text-base truncate">{prof.name}</H5> |
269 |
| - // )} |
270 |
| - // title={prof.name} |
271 |
| - // /> |
272 |
| - // {prof.id === selectedProf.id && ( |
273 |
| - // <div className="h-full w-1 bg-black dark:bg-white absolute top-0 right-full rounded" /> |
274 |
| - // )} |
275 |
| - // </div> |
276 |
| - // ))} |
277 |
| - // </div> |
278 |
| - // <Divider className="mr-0" /> |
279 |
| - // <div className="mr-1 h-full flex flex-col justify-center items-end absolute right-full sm:relative sm:left-0"> |
280 |
| - // <div> |
281 |
| - // {formattedSubProfessions?.map((subProf) => ( |
282 |
| - // <H4 |
283 |
| - // key={subProf.id} |
284 |
| - // className={clsx( |
285 |
| - // 'truncate cursor-pointer my-3 opacity-50 hover:underline hover:opacity-90', |
286 |
| - // subProf.id === selectedSubProf.id && '!opacity-100 underline', |
287 |
| - // subProf.name.length > 3 && '!text-base', |
288 |
| - // )} |
289 |
| - // onClick={() => setSelectedSubProf(subProf)} |
290 |
| - // > |
291 |
| - // {subProf.name} |
292 |
| - // </H4> |
293 |
| - // ))} |
294 |
| - // </div> |
295 |
| - // {ActionList} |
296 |
| - // </div> |
297 |
| - // </div> |
298 |
| - // ) |
| 106 | + const { |
| 107 | + data: operatorsAfterFiltered, |
| 108 | + meta: { pagination: paginationAfterFiltered }, |
| 109 | + } = useOperatorAfterFiltered(profFilter, pagination) |
| 110 | + |
| 111 | + // prof listener |
| 112 | + useEffect(() => { |
| 113 | + setPagination(defaultPagination) |
| 114 | + toTop() |
| 115 | + }, [profFilter]) |
| 116 | + |
| 117 | + // pagination listener |
| 118 | + useEffect(() => { |
| 119 | + if (paginationAfterFiltered.total === pagination.total) return |
| 120 | + setPagination(paginationAfterFiltered) |
| 121 | + if (paginationAfterFiltered.current === 1) toTop() |
| 122 | + }, [pagination.total, paginationAfterFiltered]) |
299 | 123 |
|
300 | 124 | return (
|
301 | 125 | <>
|
302 | 126 | <div className="flex h-full">
|
303 | 127 | <div className="flex-auto px-1" ref={operatorScrollRef}>
|
304 |
| - {/* {operatorsGroupedBySubProf.length ? ( |
| 128 | + {operatorsAfterFiltered.length ? ( |
305 | 129 | <>
|
306 | 130 | <div
|
307 | 131 | key="operatorContainer"
|
308 | 132 | className="flex flex-wrap items-start content-start overscroll-contain relative"
|
309 | 133 | >
|
310 |
| - {operatorsGroupedBySubProf |
311 |
| - .slice(0, lastIndex) |
312 |
| - .map(({ name }, index) => ( |
313 |
| - <div |
314 |
| - className="flex items-center flex-0 w-32 h-32" |
315 |
| - key={index} |
316 |
| - > |
317 |
| - <SheetOperatorItem {...{ name }} /> |
318 |
| - </div> |
319 |
| - ))} |
| 134 | + {operatorsAfterFiltered.map(({ name }, index) => ( |
| 135 | + <div |
| 136 | + className="flex items-center flex-0 w-32 h-32" |
| 137 | + key={index} |
| 138 | + > |
| 139 | + <SheetOperatorItem {...{ name }} /> |
| 140 | + </div> |
| 141 | + ))} |
320 | 142 | </div>
|
321 |
| - {ShowMoreButton} |
| 143 | + <ShowMore {...{ pagination, setPagination }} /> |
322 | 144 | </>
|
323 | 145 | ) : (
|
324 | 146 | OperatorNoData
|
325 |
| - )} */} |
| 147 | + )} |
326 | 148 | </div>
|
327 | 149 | {/* {ProfSelect} */}
|
328 |
| - <ProfClassification /> |
| 150 | + <ProfClassification {...{ profFilter, setProfFilter }} /> |
329 | 151 | </div>
|
330 | 152 | </>
|
331 | 153 | )
|
|
0 commit comments