Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import { useAppSelector } from './state/store'

import { ConsentBanner } from '@/components/ConsentBanner'
import { IconCircle } from '@/components/IconCircle'
import { AgenticChatFAB } from '@/features/agenticChat'
import { useAddAccountsGuard } from '@/hooks/useAddAccountsGuard/useAddAccountsGuard'
import { useAppleSearchAdsAttribution } from '@/hooks/useAppleSearchAdsAttribution/useAppleSearchAdsAttribution'
import { useFeatureFlag } from '@/hooks/useFeatureFlag/useFeatureFlag'
Expand Down Expand Up @@ -66,7 +65,6 @@ export const App = () => {
<>
{showConsentBanner && isMixpanelEnabled && !isMobileApp && <ConsentBanner />}
<AppRoutes />
<AgenticChatFAB />
</>
)
}
1 change: 1 addition & 0 deletions src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@
},
"agenticChat": {
"title": "ShapeShift Agent",
"aiChat": "AI Chat",
"openChat": "Open chat",
"closeChat": "Close chat",
"emptyState": "How can I help you today?",
Expand Down
11 changes: 10 additions & 1 deletion src/components/Layout/Header/NavBar/DrawerWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { ManageHiddenAssetsContent } from '@/components/ManageHiddenAssets/Manag
import { SettingsRoutes } from '@/components/Modals/Settings/SettingsCommon'
import { useModalRegistration } from '@/context/ModalStackProvider'
import { useModal } from '@/hooks/useModal/useModal'
import { agenticChatSlice } from '@/state/slices/agenticChatSlice/agenticChatSlice'
import { useAppDispatch } from '@/state/store'

const initialEntries = ['/', ...Object.values(SettingsRoutes)]

Expand Down Expand Up @@ -57,7 +59,14 @@ export const DrawerWalletInner: FC<DrawerWalletInnerProps> = memo(({ onClose, is
})

export const DrawerWallet: FC = memo(() => {
const { isOpen, close: onClose } = useModal('walletDrawer')
const { isOpen, close } = useModal('walletDrawer')
const dispatch = useAppDispatch()

const onClose = useCallback(() => {
dispatch(agenticChatSlice.actions.endChat())
close()
}, [dispatch, close])

const { modalContentProps, overlayProps, modalProps } = useModalRegistration({
isOpen,
onClose,
Expand Down
160 changes: 94 additions & 66 deletions src/components/Layout/Header/NavBar/DrawerWalletDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ import { AccountsListContent } from '@/components/Accounts/AccountsListContent'
import { SendIcon } from '@/components/Icons/SendIcon'
import { WalletBalanceChange } from '@/components/WalletBalanceChange/WalletBalanceChange'
import { WalletActions } from '@/context/WalletProvider/actions'
import { DrawerChatButton } from '@/features/agenticChat/components/DrawerChatButton'
import { DrawerChatContent } from '@/features/agenticChat/components/DrawerChatContent'
import { useModal } from '@/hooks/useModal/useModal'
import { useWallet } from '@/hooks/useWallet/useWallet'
import { agenticChatSlice } from '@/state/slices/agenticChatSlice/agenticChatSlice'
import { useAppDispatch, useAppSelector } from '@/state/store'
import { makeSuspenseful } from '@/utils/makeSuspenseful'

const tabSpinnerStyle = { height: '200px' }
Expand Down Expand Up @@ -123,8 +127,10 @@ type DrawerWalletDashboardProps = {
export const DrawerWalletDashboard: FC<DrawerWalletDashboardProps> = memo(
({ onClose, onSettingsClick, isOpen }) => {
const translate = useTranslate()
const reduxDispatch = useAppDispatch()
const send = useModal('send')
const receive = useModal('receive')
const isChatOpen = useAppSelector(agenticChatSlice.selectors.selectIsChatOpen)

const [activeTabIndex, setActiveTabIndex] = useState(0)
const [loadedTabs, setLoadedTabs] = useState(new Set<number>())
Expand Down Expand Up @@ -171,6 +177,10 @@ export const DrawerWalletDashboard: FC<DrawerWalletDashboardProps> = memo(
onClose()
}, [disconnect, onClose])

const handleBackFromChat = useCallback(() => {
reduxDispatch(agenticChatSlice.actions.endChat())
}, [reduxDispatch])

return (
<>
<DrawerWalletHeader
Expand All @@ -182,73 +192,91 @@ export const DrawerWalletDashboard: FC<DrawerWalletDashboardProps> = memo(
onSwitchProvider={handleSwitchProvider}
onClose={onClose}
onSettingsClick={onSettingsClick}
isChatOpen={isChatOpen}
onBackFromChat={handleBackFromChat}
/>
<Box pt={6} pb={8}>
<Suspense fallback={<Skeleton height='36px' width='100px' mx='auto' />}>
<WalletBalanceChange showErroredAccounts={false} />
</Suspense>
</Box>

<Flex width='100%' pb={4} gap={2} px={4}>
<ActionButton
icon={sendIcon}
label={translate('common.send')}
onClick={handleSendClick}
isDisabled={!isConnected}
/>
<ActionButton
icon={receiveIcon}
label={translate('common.receive')}
onClick={handleReceiveClick}
isDisabled={!isConnected}
/>
</Flex>

<Box flex='1' overflow='hidden' display='flex' flexDirection='column'>
<Tabs
index={activeTabIndex}
onChange={handleTabChange}
variant='soft-rounded'
size='sm'
isLazy
display='flex'
flexDirection='column'
height='100%'
>
<TabList bg='transparent' borderWidth={0} pt={2} pb={0} px={4} gap={2} flexShrink={0}>
<Tab>{translate('dashboard.portfolio.myCrypto')} </Tab>
<Tab>{translate('accounts.accounts')}</Tab>
<Tab>{translate('watchlist.title')}</Tab>
<Tab>{translate('navBar.defi')}</Tab>
<Tab>{translate('common.activity')}</Tab>
</TabList>
<TabPanels flex='1' overflow='auto' maxHeight={'100%'}>
<TabPanel px={2} pb={4} height='100%'>
{loadedTabs.has(0) ? (
<Suspense fallback={accountTableSkeletonFallback}>
<Box height='100%'>
<AccountTable forceCompactView />
</Box>
</Suspense>
) : (
accountTableSkeletonFallback
)}
</TabPanel>
<TabPanel px={2} pb={4}>
{loadedTabs.has(1) && <AccountsListContent onClose={onClose} isSimpleMenu />}
</TabPanel>
<TabPanel px={2} py={4}>
{loadedTabs.has(2) && <WatchlistTable />}
</TabPanel>
<TabPanel px={2} py={4}>
{loadedTabs.has(3) && <DeFiEarn forceCompactView />}
</TabPanel>
<TabPanel px={0} py={4}>
{loadedTabs.has(4) && <TransactionHistoryContent isCompact />}
</TabPanel>
</TabPanels>
</Tabs>
</Box>

{isChatOpen ? (
<DrawerChatContent />
) : (
<>
<Box pt={6} pb={8}>
<Suspense fallback={<Skeleton height='36px' width='100px' mx='auto' />}>
<WalletBalanceChange showErroredAccounts={false} />
</Suspense>
</Box>

<Flex width='100%' pb={4} gap={2} px={4}>
<ActionButton
icon={sendIcon}
label={translate('common.send')}
onClick={handleSendClick}
isDisabled={!isConnected}
/>
<ActionButton
icon={receiveIcon}
label={translate('common.receive')}
onClick={handleReceiveClick}
isDisabled={!isConnected}
/>
<DrawerChatButton />
</Flex>

<Box flex='1' overflow='hidden' display='flex' flexDirection='column'>
<Tabs
index={activeTabIndex}
onChange={handleTabChange}
variant='soft-rounded'
size='sm'
isLazy
display='flex'
flexDirection='column'
height='100%'
>
<TabList
bg='transparent'
borderWidth={0}
pt={2}
pb={0}
px={4}
gap={2}
flexShrink={0}
>
<Tab>{translate('dashboard.portfolio.myCrypto')} </Tab>
<Tab>{translate('accounts.accounts')}</Tab>
<Tab>{translate('watchlist.title')}</Tab>
<Tab>{translate('navBar.defi')}</Tab>
<Tab>{translate('common.activity')}</Tab>
</TabList>
<TabPanels flex='1' overflow='auto' maxHeight={'100%'}>
<TabPanel px={2} pb={4} height='100%'>
{loadedTabs.has(0) ? (
<Suspense fallback={accountTableSkeletonFallback}>
<Box height='100%'>
<AccountTable forceCompactView />
</Box>
</Suspense>
) : (
accountTableSkeletonFallback
)}
</TabPanel>
<TabPanel px={2} pb={4}>
{loadedTabs.has(1) && <AccountsListContent onClose={onClose} isSimpleMenu />}
</TabPanel>
<TabPanel px={2} py={4}>
{loadedTabs.has(2) && <WatchlistTable />}
</TabPanel>
<TabPanel px={2} py={4}>
{loadedTabs.has(3) && <DeFiEarn forceCompactView />}
</TabPanel>
<TabPanel px={0} py={4}>
{loadedTabs.has(4) && <TransactionHistoryContent isCompact />}
</TabPanel>
</TabPanels>
</Tabs>
</Box>
</>
)}
</>
)
},
Expand Down
16 changes: 15 additions & 1 deletion src/components/Layout/Header/NavBar/DrawerWalletHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from '@chakra-ui/react'
import type { FC } from 'react'
import { memo, useCallback, useMemo } from 'react'
import { FiArrowLeft } from 'react-icons/fi'
import { TbDots, TbEyeOff, TbSettings } from 'react-icons/tb'
import { useTranslate } from 'react-polyglot'
import { useNavigate } from 'react-router-dom'
Expand Down Expand Up @@ -43,6 +44,8 @@ type DrawerHeaderProps = {
onSwitchProvider: () => void
onClose?: () => void
onSettingsClick?: () => void
isChatOpen?: boolean
onBackFromChat?: () => void
}

export const DrawerWalletHeader: FC<DrawerHeaderProps> = memo(
Expand All @@ -54,6 +57,8 @@ export const DrawerWalletHeader: FC<DrawerHeaderProps> = memo(
onDisconnect,
onSwitchProvider,
onSettingsClick,
isChatOpen,
onBackFromChat,
}) => {
const translate = useTranslate()
const settings = useModal('settings')
Expand Down Expand Up @@ -107,8 +112,17 @@ export const DrawerWalletHeader: FC<DrawerHeaderProps> = memo(
if (!isConnected || isLocked || !walletInfo) return null

return (
<Flex align='center' px={4} pt={4} justify='space-between'>
<Flex align='center' px={4} pt={4} pb={isChatOpen ? 4 : 0} justify='space-between'>
<Flex align='center' gap={2}>
{isChatOpen && onBackFromChat && (
<IconButton
icon={<FiArrowLeft />}
aria-label={translate('common.back')}
onClick={onBackFromChat}
variant='ghost'
size='sm'
/>
)}
<ProfileAvatar size='md' borderRadius='full' />
<Text fontWeight='medium'>{label}</Text>
</Flex>
Expand Down
45 changes: 0 additions & 45 deletions src/features/agenticChat/components/AgenticChatFAB.tsx

This file was deleted.

5 changes: 3 additions & 2 deletions src/features/agenticChat/components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const Chat = ({ chat }: ChatProps) => {
const bottomRef = useRef<HTMLDivElement>(null)
const shouldAutoScrollRef = useRef(true)

const userBg = useColorModeValue('blue.50', 'blue.900')
const userBg = useColorModeValue('blue.50', 'blue.600')

useEffect(() => {
const viewport = viewportRef.current
Expand Down Expand Up @@ -97,7 +97,8 @@ export const Chat = ({ chat }: ChatProps) => {
gap={3}
flex={1}
overflowY='auto'
p={4}
px={4}
pb={2}
minHeight={0}
>
{isEmpty ? (
Expand Down
Loading