Skip to content
Merged
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
24 changes: 15 additions & 9 deletions src/app/routes/trade.$ticker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as cookie from 'cookie';
import { AnimatePresence } from 'motion/react';
import { useState } from 'react';
import { Suspense, lazy, useState } from 'react';
import { Outlet, redirect } from 'react-router';

import { CoinPriceWithName, api as coinApi } from '~/entities/coin';
Expand All @@ -10,13 +10,15 @@ import { CoinListWithSearchBar } from '~/features/coin-search-list';
import { OrderForm, OrderFormFallback } from '~/features/order';
import { ExecutionList } from '~/features/order-execution-list';
import useTradeNotification from '~/features/trade/hooks/useTradeNotification';
import { Orderbook, StockChart } from '~/features/tradeview';
import Container from '~/shared/ui/Container';
import ContainerTitle from '~/shared/ui/ContainerTitle';
import { NavBar, SideBar } from '~/widgets/navbar';
import { useUserId } from '../provider/UserInfoProvider';
import type { Route } from './+types/trade.$ticker';

const LazyStockChart = lazy(() => import('~/features/tradeview/ui/StockChart'));
const LazyOrderBook = lazy(() => import('~/features/tradeview/ui/Orderbook'));

export async function loader({ request, params }: Route.LoaderArgs) {
const rawCookie = request.headers.get('Cookie');
const cookies = cookie.parse(rawCookie || '');
Expand Down Expand Up @@ -79,12 +81,14 @@ export default function TradeRouteComponent({
<div className="h-auto md:col-span-full md:row-span-2 md:row-start-1 xl:col-span-full xl:row-span-1 xl:row-start-1 2xl:col-span-2 2xl:col-start-2 2xl:row-start-1">
<Container>
<ContainerTitle>실시간 차트</ContainerTitle>
{coinInfo && (
<StockChart
key={`chart-${coinInfo.ticker}`}
ticker={coinInfo.ticker}
/>
)}
<Suspense fallback="차트데이터를 가져오고 있습니다.">
{coinInfo && (
<LazyStockChart
key={`chart-${coinInfo.ticker}`}
ticker={coinInfo.ticker}
/>
)}
</Suspense>
</Container>
</div>
<div className="md:col-span-1 md:col-start-2 md:row-span-2 md:row-start-3 xl:col-span-1 xl:col-start-3 xl:row-span-1 xl:row-start2 2xl:col-start-4 2xl:row-span-1 2xl:row-start-1">
Expand All @@ -100,7 +104,9 @@ export default function TradeRouteComponent({
<div className="md:col-span-1 md:col-start-1 md:row-span-2 md:row-start-3 xl:col-span-1 xl:col-start-2 xl:row-span-1 xl:row-start-2 2xl:col-start-4 2xl:row-span-full 2xl:row-start-2">
<Container>
<ContainerTitle>실시간 호가</ContainerTitle>
{coinInfo && <Orderbook ticker={coinInfo.ticker} />}
<Suspense fallback={null}>
{coinInfo && <LazyOrderBook ticker={coinInfo.ticker} />}
</Suspense>
</Container>
</div>
<div className="md:col-span-full md:row-span-1 md:row-start-5 xl:col-span-1 xl:col-start-1 xl:row-span-1 xl:row-start-2 2xl:col-span-2 2xl:col-start-2 2xl:row-start-2">
Expand Down
61 changes: 35 additions & 26 deletions src/features/chat/ui/AIChatBot/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { useMachine } from '@xstate/react';
import { AnimatePresence } from 'motion/react';
import { type ChangeEvent, type FormEvent, useState } from 'react';
import {
type ChangeEvent,
type FormEvent,
Suspense,
lazy,
useState,
} from 'react';

import useScrollToBottom from '~/shared/hooks/useScrollToBottom';
import { chatMachine } from '../../model/chat.machine';
import ChatButton from '../ChatButton';
import ChatWindow from '../ChatWindow';
import MessageBox from '../MessageBox';

const LazyChatWindow = lazy(() => import('~/features/chat/ui/ChatWindow'));

export default function AIChatBot() {
const [state, send] = useMachine(chatMachine);
const [isOpen, setIsOpen] = useState(false);
Expand All @@ -32,30 +39,32 @@ export default function AIChatBot() {

return (
<AnimatePresence mode="wait" propagate>
{isOpen ? (
<ChatWindow
handleClose={handleCloseChatWindow}
inputValue={state.context.question}
handleSubmit={handleSubmitQuestion}
handleInputValueChange={handleQuestionFieldChange}
state={state.context.state}
key="chat-window"
>
{state.context.messageList.map((message, index) => {
const key = `msg-${index}-${message.isMine ? 'user' : 'ai'}`;
return (
<MessageBox
key={key}
direction={message.isMine ? 'right' : 'left'}
message={message.message}
/>
);
})}
<div ref={messagesEndRef} />
</ChatWindow>
) : (
<ChatButton handleClick={handleOpenChatWindow} isOpen={isOpen} />
)}
<Suspense fallback={null}>
{isOpen ? (
<LazyChatWindow
handleClose={handleCloseChatWindow}
inputValue={state.context.question}
handleSubmit={handleSubmitQuestion}
handleInputValueChange={handleQuestionFieldChange}
state={state.context.state}
key="chat-window"
>
{state.context.messageList.map((message, index) => {
const key = `msg-${index}-${message.isMine ? 'user' : 'ai'}`;
return (
<MessageBox
key={key}
direction={message.isMine ? 'right' : 'left'}
message={message.message}
/>
);
})}
<div ref={messagesEndRef} />
</LazyChatWindow>
) : (
<ChatButton handleClick={handleOpenChatWindow} isOpen={isOpen} />
)}
</Suspense>
</AnimatePresence>
);
}
2 changes: 1 addition & 1 deletion stats.html

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export default defineConfig({
optimizeDeps: {
exclude: ['@amcharts/amcharts5'],
},
ssr: {
noExternal: ['@amcharts/amcharts5'],
build: {
rollupOptions: {
external: ['d3-geo,d3-selection,d3-transition'],
},
},
});
Loading