From 044383bae7a078b98705157756f0ff88c7f24eb7 Mon Sep 17 00:00:00 2001 From: Gaubee Date: Mon, 22 Dec 2025 20:52:19 +0800 Subject: [PATCH 1/6] feat(#81): refactor BottomSheet to use Stackflow Activities - Replace custom BottomSheet component with Stackflow wrapper - Convert all sheet components to Activities: - TransferConfirmSheetActivity (new) - All imports now from @/components/layout/bottom-sheet - Update pages to use Activity-based sheets: - HomePage uses ChainSelectorSheetActivity - SendPage uses TransferConfirmSheetActivity + PasswordConfirmSheetActivity - Delete redundant component files: - transfer-confirm-sheet, password-confirm-sheet - mnemonic-options-sheet, wallet-edit-sheet - contact-edit-sheet, bottom-sheet tests/stories Closes #81 --- .../address-book/contact-edit-sheet.tsx | 176 ------------- .../layout/bottom-sheet.stories.tsx | 101 -------- src/components/layout/bottom-sheet.test.tsx | 96 ------- src/components/layout/bottom-sheet.tsx | 195 ++++---------- .../mnemonic-options-sheet.stories.tsx | 98 ------- .../mnemonic-options-sheet.test.tsx | 200 --------------- .../onboarding/mnemonic-options-sheet.tsx | 106 -------- .../password-confirm-sheet.stories.tsx | 119 --------- .../security/password-confirm-sheet.test.tsx | 119 --------- .../security/password-confirm-sheet.tsx | 132 ---------- .../transfer-confirm-sheet.stories.tsx | 122 --------- .../transfer/transfer-confirm-sheet.test.tsx | 121 --------- .../transfer/transfer-confirm-sheet.tsx | 165 ------------ .../wallet/wallet-edit-sheet.stories.tsx | 72 ------ .../wallet/wallet-edit-sheet.test.tsx | 241 ------------------ src/components/wallet/wallet-edit-sheet.tsx | 225 ---------------- src/pages/home/index.tsx | 41 +-- src/pages/send/index.tsx | 62 +++-- .../sheets/ChainSelectorSheetActivity.tsx | 2 +- .../sheets/ContactEditSheetActivity.tsx | 2 +- .../sheets/MnemonicOptionsSheetActivity.tsx | 2 +- .../sheets/PasswordConfirmSheetActivity.tsx | 2 +- .../sheets/SecurityWarningSheetActivity.tsx | 2 +- .../sheets/TransferConfirmSheetActivity.tsx | 174 +++++++++++++ .../sheets/WalletAddSheetActivity.tsx | 2 +- .../sheets/WalletDeleteSheetActivity.tsx | 2 +- .../sheets/WalletRenameSheetActivity.tsx | 2 +- src/stackflow/activities/sheets/index.ts | 1 + src/stackflow/stackflow.ts | 4 +- 29 files changed, 268 insertions(+), 2318 deletions(-) delete mode 100644 src/components/address-book/contact-edit-sheet.tsx delete mode 100644 src/components/layout/bottom-sheet.stories.tsx delete mode 100644 src/components/layout/bottom-sheet.test.tsx delete mode 100644 src/components/onboarding/mnemonic-options-sheet.stories.tsx delete mode 100644 src/components/onboarding/mnemonic-options-sheet.test.tsx delete mode 100644 src/components/onboarding/mnemonic-options-sheet.tsx delete mode 100644 src/components/security/password-confirm-sheet.stories.tsx delete mode 100644 src/components/security/password-confirm-sheet.test.tsx delete mode 100644 src/components/security/password-confirm-sheet.tsx delete mode 100644 src/components/transfer/transfer-confirm-sheet.stories.tsx delete mode 100644 src/components/transfer/transfer-confirm-sheet.test.tsx delete mode 100644 src/components/transfer/transfer-confirm-sheet.tsx delete mode 100644 src/components/wallet/wallet-edit-sheet.stories.tsx delete mode 100644 src/components/wallet/wallet-edit-sheet.test.tsx delete mode 100644 src/components/wallet/wallet-edit-sheet.tsx create mode 100644 src/stackflow/activities/sheets/TransferConfirmSheetActivity.tsx diff --git a/src/components/address-book/contact-edit-sheet.tsx b/src/components/address-book/contact-edit-sheet.tsx deleted file mode 100644 index 197f783eb..000000000 --- a/src/components/address-book/contact-edit-sheet.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { useState, useCallback, useEffect } from 'react'; -import { useTranslation } from 'react-i18next'; -import { cn } from '@/lib/utils'; -import { BottomSheet } from '@/components/layout/bottom-sheet'; -import { addressBookActions, type Contact, type ChainType } from '@/stores'; -import { IconUser as User, IconWallet as Wallet, IconFileText as FileText } from '@tabler/icons-react'; - -export interface ContactEditSheetProps { - /** Contact to edit (null for new contact) */ - contact?: Contact | null | undefined; - /** Whether the sheet is open */ - open: boolean; - /** Close callback */ - onClose: () => void; - /** Success callback */ - onSuccess?: (() => void) | undefined; - /** Default chain for new contacts */ - defaultChain?: ChainType | undefined; - /** Additional class name */ - className?: string | undefined; -} - -/** - * Sheet for adding/editing contacts - */ -export function ContactEditSheet({ - contact, - open, - onClose, - onSuccess, - defaultChain = 'ethereum', - className, -}: ContactEditSheetProps) { - const { t } = useTranslation('common'); - const [name, setName] = useState(''); - const [address, setAddress] = useState(''); - const [memo, setMemo] = useState(''); - - const isEditing = !!contact; - - // Reset form when contact changes or sheet opens - useEffect(() => { - if (open) { - setName(contact?.name || ''); - setAddress(contact?.address || ''); - setMemo(contact?.memo || ''); - } - }, [open, contact]); - - const handleClose = useCallback(() => { - setName(''); - setAddress(''); - setMemo(''); - onClose(); - }, [onClose]); - - const handleSave = useCallback(() => { - const trimmedName = name.trim(); - const trimmedAddress = address.trim(); - const trimmedMemo = memo.trim(); - - if (!trimmedName || !trimmedAddress) return; - - if (isEditing && contact) { - addressBookActions.updateContact(contact.id, { - name: trimmedName, - address: trimmedAddress, - ...(trimmedMemo && { memo: trimmedMemo }), - }); - } else { - addressBookActions.addContact({ - name: trimmedName, - address: trimmedAddress, - chain: defaultChain, - ...(trimmedMemo && { memo: trimmedMemo }), - }); - } - - onSuccess?.(); - handleClose(); - }, [name, address, memo, isEditing, contact, defaultChain, onSuccess, handleClose]); - - const canSave = name.trim().length > 0 && address.trim().length > 0; - - return ( - -
- {/* 名称输入 */} -
- - setName(e.target.value)} - placeholder={t('contact.namePlaceholder')} - maxLength={20} - autoFocus - className={cn( - 'border-border bg-background w-full rounded-xl border px-4 py-3', - 'focus:ring-primary focus:ring-2 focus:outline-none', - )} - /> -
- - {/* 地址输入 */} -
- - setAddress(e.target.value)} - placeholder={t('contact.addressPlaceholder')} - className={cn( - 'border-border bg-background w-full rounded-xl border px-4 py-3 font-mono text-sm', - 'focus:ring-primary focus:ring-2 focus:outline-none', - )} - /> -
- - {/* 备注输入 */} -
- -