diff --git a/.editorconfig b/.editorconfig index 9d93cb3d..b802215c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,6 +6,7 @@ indent_style = space indent_size = 2 insert_final_newline = true trim_trailing_whitespace = true +end_of_line = lf [*.{js,ts,jsx,tsx,css,json,md,mdx,yml,yaml}] indent_size = 2 diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..b308e589 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint" + ] +} diff --git a/package.json b/package.json index 2ef8ef0b..e0de93ef 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "pinyin": "^3.0.0-alpha.5", "simplebig": "^0.0.3", "tailwindcss": "^3.1.4", - "typescript": "^5.3.3", + "typescript": "^5.5.0", "vite": "^4.2.1" }, "resolutions": { diff --git a/public/assets/operator-avatars/char_4058_pepe.png b/public/assets/operator-avatars/char_4058_pepe.png new file mode 100644 index 00000000..ba7ed586 Binary files /dev/null and b/public/assets/operator-avatars/char_4058_pepe.png differ diff --git a/public/assets/operator-avatars/char_4138_narant.png b/public/assets/operator-avatars/char_4138_narant.png new file mode 100644 index 00000000..bbd42216 Binary files /dev/null and b/public/assets/operator-avatars/char_4138_narant.png differ diff --git a/public/assets/operator-avatars/char_4139_papyrs.png b/public/assets/operator-avatars/char_4139_papyrs.png new file mode 100644 index 00000000..0f6e3164 Binary files /dev/null and b/public/assets/operator-avatars/char_4139_papyrs.png differ diff --git a/public/assets/operator-avatars/char_4140_lasher.png b/public/assets/operator-avatars/char_4140_lasher.png new file mode 100644 index 00000000..90744b43 Binary files /dev/null and b/public/assets/operator-avatars/char_4140_lasher.png differ diff --git a/public/assets/operator-avatars/char_4141_marcil.png b/public/assets/operator-avatars/char_4141_marcil.png new file mode 100644 index 00000000..16a96eb5 Binary files /dev/null and b/public/assets/operator-avatars/char_4141_marcil.png differ diff --git a/public/assets/operator-avatars/char_4142_laios.png b/public/assets/operator-avatars/char_4142_laios.png new file mode 100644 index 00000000..c9de533b Binary files /dev/null and b/public/assets/operator-avatars/char_4142_laios.png differ diff --git a/public/assets/operator-avatars/char_4143_sensi.png b/public/assets/operator-avatars/char_4143_sensi.png new file mode 100644 index 00000000..7ef101db Binary files /dev/null and b/public/assets/operator-avatars/char_4143_sensi.png differ diff --git a/public/assets/operator-avatars/char_4144_chilc.png b/public/assets/operator-avatars/char_4144_chilc.png new file mode 100644 index 00000000..43f3476a Binary files /dev/null and b/public/assets/operator-avatars/char_4144_chilc.png differ diff --git a/public/assets/operator-avatars/char_4146_nymph.png b/public/assets/operator-avatars/char_4146_nymph.png new file mode 100644 index 00000000..de812a55 Binary files /dev/null and b/public/assets/operator-avatars/char_4146_nymph.png differ diff --git a/public/assets/operator-avatars/char_4147_mitm.png b/public/assets/operator-avatars/char_4147_mitm.png new file mode 100644 index 00000000..d7bc6e73 Binary files /dev/null and b/public/assets/operator-avatars/char_4147_mitm.png differ diff --git a/public/assets/operator-avatars/char_4151_tinman.png b/public/assets/operator-avatars/char_4151_tinman.png new file mode 100644 index 00000000..712173e3 Binary files /dev/null and b/public/assets/operator-avatars/char_4151_tinman.png differ diff --git a/public/assets/operator-avatars/token_10036_lasher_mcbird.png b/public/assets/operator-avatars/token_10036_lasher_mcbird.png new file mode 100644 index 00000000..cfa02332 Binary files /dev/null and b/public/assets/operator-avatars/token_10036_lasher_mcbird.png differ diff --git a/public/assets/operator-avatars/token_10037_mitm_trshrb.png b/public/assets/operator-avatars/token_10037_mitm_trshrb.png new file mode 100644 index 00000000..7f7e35ef Binary files /dev/null and b/public/assets/operator-avatars/token_10037_mitm_trshrb.png differ diff --git a/scripts/shared.ts b/scripts/shared.ts index f953c4d6..66506a75 100644 --- a/scripts/shared.ts +++ b/scripts/shared.ts @@ -111,6 +111,7 @@ export async function getOperators() { return [ { id: id, + prof: op.profession, subProf: op.subProfessionId, ...transformOperatorName(op.name), rarity: diff --git a/src/components/AccountManager.tsx b/src/components/AccountManager.tsx index 20615e98..f09edaf8 100644 --- a/src/components/AccountManager.tsx +++ b/src/components/AccountManager.tsx @@ -33,6 +33,7 @@ const AccountMenu: FC = () => { const [authState, setAuthState] = useAtom(authAtom) const [logoutDialogOpen, setLogoutDialogOpen] = useState(false) const [editDialogOpen, setEditDialogOpen] = useState(false) + const { isSM } = useCurrentSize() const handleLogout = () => { setAuthState({}) @@ -72,6 +73,14 @@ const AccountMenu: FC = () => { /> )} + {isSM && ( + + )} + { } position={Position.BOTTOM_RIGHT}> - } - disabled={!pinned} - > - onPinHandle?.(operator as Operator) - } - /> - - - )} - - {!readOnly && selected && ( - - )} - -) diff --git a/src/components/editor/operator/sheet/SheetOperatorSkillAbout.tsx b/src/components/editor/operator/sheet/SheetOperatorSkillAbout.tsx index 357f4798..14b49b4a 100644 --- a/src/components/editor/operator/sheet/SheetOperatorSkillAbout.tsx +++ b/src/components/editor/operator/sheet/SheetOperatorSkillAbout.tsx @@ -13,13 +13,12 @@ import { EditorOperatorSkill } from '../EditorOperatorSkill' import { EditorOperatorSkillTimes } from '../EditorOperatorSkillTimes' import { EditorOperatorSkillUsage } from '../EditorOperatorSkillUsage' import { Operator } from '../EditorSheet' -import { OperatorModifyProps } from './SheetOperator' const needSkillTimeType = CopilotDocV1.SkillUsageType.ReadyToUseTimes export interface SkillAboutProps { operator?: Operator - onSkillChange?: OperatorModifyProps['operatorSkillHandle'] + onSkillChange?: (value: Operator) => void } const skillDic = operatorSkillUsages as DetailedSelectChoice[] @@ -85,7 +84,7 @@ export const SkillAboutTrigger = ({
- - {OperatorsPart} - - ) -} - const GroupTitle = ({ groupTitle, - editable, + // editable, renameSubmit, }: { editable: boolean - renameSubmit: (newName: string) => void + renameSubmit?: (newName: string) => void groupTitle: string }) => { + const editable = !!renameSubmit const [editName, setEditName] = useState('') const [nameEditState, setNameEditState] = useState(false) const [alertState, setAlertState] = useState(false) @@ -200,7 +93,7 @@ const GroupTitle = ({ className="flex items-center" onSubmit={handleSubmit(() => { ignoreBlur.current = true - renameSubmit(editName || groupTitle) + renameSubmit?.(editName || groupTitle) setNameEditState(false) inputRef.current?.blur() })} @@ -240,3 +133,256 @@ const GroupTitle = ({ ) } + +type ItemType = 'recommend' | 'selected' | 'fav' + +export interface SheetGroupItemProp { + groupInfo: Group + itemType: ItemType +} + +export const SheetGroupItem: FC = ({ + groupInfo, + itemType, +}) => { + const { + selected, + onGroupNameChange, + defaultOperatorCollapseOpen, + ActionList, + onOperatorSkillChange, + } = useSheetGroupItemController({ + groupInfo, + itemType, + }) + const [operatorCollapse, setOperatorCollapse] = useState( + defaultOperatorCollapseOpen, + ) + + return ( + +
+ +
+ setOperatorCollapse((prev) => !prev)} + /> + {ActionList} +
+
+ +
+ {groupInfo.opers?.length + ? groupInfo.opers?.map((item) => ( + + )) + : !selected && OperatorNoData} + {selected && } +
+
+
+ ) +} + +type SheetGroupItemController = { + selected: boolean + onGroupNameChange: ((name: string) => void) | undefined + defaultOperatorCollapseOpen: boolean + onOperatorSkillChange: OperatorInGroupItemProp['onOperatorSkillChange'] + ActionList: ReactNode +} + +const useSheetGroupItemController = ({ + groupInfo: { name, opers = [], ...rest }, + itemType, +}: SheetGroupItemProp): SheetGroupItemController => { + const { submitGroupInSheet, removeGroup, existedGroups } = useSheet() + const [favGroup, setFavGroup] = useAtom(favGroupAtom) + + switch (itemType) { + case 'selected': { + const findFavByName = favGroup.find( + ({ name: nameInFav }) => nameInFav === name, + ) + const pinned = isEqual({ name, opers }, findFavByName) + + const onPinChange: GroupPinOptionProp['onPinChange'] = () => { + const newFavGroup = [ + ...favGroup.filter(({ name: nameInFav }) => nameInFav !== name), + ] + setFavGroup( + pinned + ? newFavGroup + : [...newFavGroup, cloneDeep({ name, opers, ...rest })], + ) + } + return { + selected: true, + onGroupNameChange: (name: string) => + submitGroupInSheet({ opers, ...rest, name }), + defaultOperatorCollapseOpen: true, + onOperatorSkillChange: (operator: Operator) => { + opers.splice( + opers.findIndex( + ({ name: nameInExist }) => nameInExist === operator.name, + ), + 1, + operator, + ) + submitGroupInSheet({ opers, name, ...rest }) + }, + ActionList: ( + <> + + removeGroup( + existedGroups.findIndex( + ({ name: nameInExist }) => nameInExist === name, + ), + ) + } + /> + + + ), + } + } + case 'recommend': { + return { + selected: false, + onGroupNameChange: undefined, + defaultOperatorCollapseOpen: false, + onOperatorSkillChange: undefined, + ActionList: ( + <> + + } + disabled={!pinned && !isFavDuplicate} + > + + + ) + })()} + + )} + + {selected && ( + submitOperatorInSheet(value), + disabled: grouped, + }} + /> + )} + {grouped && ( + + + 已被编组 + + )} + + ) +} diff --git a/src/components/editor/operator/sheet/sheetOperator/ShowMore.tsx b/src/components/editor/operator/sheet/sheetOperator/ShowMore.tsx new file mode 100644 index 00000000..8e50cc0d --- /dev/null +++ b/src/components/editor/operator/sheet/sheetOperator/ShowMore.tsx @@ -0,0 +1,57 @@ +import { H6 } from '@blueprintjs/core' + +import { FC, useEffect } from 'react' + +import { + defaultPagination, + useOperatorFilterProvider, +} from './SheetOperatorFilterProvider' + +export interface ShowMoreProp { + toTop: () => void +} + +export const ShowMore: FC = ({ toTop }) => { + const { + operatorFiltered: { + meta: { dataTotal }, + }, + usePaginationFilterState: [{ current, size }, setPagination], + } = useOperatorFilterProvider() + + const lastIndex = current * size + + useEffect(() => { + if (current === 1) toTop() + }, [current, toTop]) + + return ( +
+ {lastIndex >= dataTotal ? ( + <> +
已经展示全部干员了({dataTotal})
+ {dataTotal > size && ( +
setPagination(defaultPagination)} + > + 收起 +
+ )} + + ) : ( +
+ setPagination(({ current, ...rest }) => ({ + ...rest, + current: current + 1, + })) + } + > + 显示更多干员(剩余{dataTotal - lastIndex}) +
+ )} +
+ ) +} diff --git a/src/components/editor/operator/sheet/sheetOperator/toolBox/OperatorBackToTop.tsx b/src/components/editor/operator/sheet/sheetOperator/toolBox/OperatorBackToTop.tsx new file mode 100644 index 00000000..17f663e9 --- /dev/null +++ b/src/components/editor/operator/sheet/sheetOperator/toolBox/OperatorBackToTop.tsx @@ -0,0 +1,28 @@ +import { Button } from '@blueprintjs/core' + +import { FC } from 'react' + +import { + defaultPagination, + useOperatorFilterProvider, +} from '../SheetOperatorFilterProvider' + +export interface OperatorBackToTopProp { + toTop: () => void +} + +export const OperatorBackToTop: FC = ({ toTop }) => { + const { + usePaginationFilterState: [{ current }, setPaginationFilter], + } = useOperatorFilterProvider() + + return ( +