Skip to content

Commit 565a647

Browse files
committed
feat(web): add custom logo and improve docker config
- add Logo component with theme support - add favicon.svg for browser tab icon - update page title to MarketPulse - add chromadb healthcheck in docker-compose - add NO_PROXY config for internal docker network - simplify stock-fetcher proxy handling - fix chromadb client url parsing for new API
1 parent 800b05f commit 565a647

8 files changed

Lines changed: 77 additions & 18 deletions

File tree

docker-compose.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ services:
1414
environment:
1515
- IS_PERSISTENT=TRUE
1616
- ANONYMIZED_TELEMETRY=FALSE
17+
healthcheck:
18+
test: ["CMD-SHELL", "bash -c 'echo > /dev/tcp/localhost/8000'"]
19+
interval: 10s
20+
timeout: 5s
21+
start_period: 10s
22+
retries: 3
1723

1824
# MarketPulse Server
1925
server:
@@ -23,7 +29,8 @@ services:
2329
container_name: marketpulse-server
2430
restart: unless-stopped
2531
depends_on:
26-
- chromadb
32+
chromadb:
33+
condition: service_healthy
2734
volumes:
2835
# SQLite database persistence
2936
- ./data/core:/app/packages/core/data
@@ -56,9 +63,11 @@ services:
5663
# Server config
5764
- PORT=3000
5865
- HOST=0.0.0.0
59-
# Proxy for Twitter scraper (Clash on host)
66+
# Proxy for external requests (Binance, Twitter, etc.)
6067
- HTTP_PROXY=http://host.docker.internal:7890
6168
- HTTPS_PROXY=http://host.docker.internal:7890
69+
# Exclude internal Docker network from proxy
70+
- NO_PROXY=localhost,127.0.0.1,chromadb,host.docker.internal
6271
healthcheck:
6372
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
6473
interval: 30s

packages/core/src/rag.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,17 @@ import * as fs from 'fs'
99
import * as path from 'path'
1010

1111
const COLLECTION_NAME = 'financial_knowledge'
12-
const CHROMA_HOST = process.env.CHROMA_HOST || 'http://localhost:8000'
12+
const CHROMA_URL = process.env.CHROMA_HOST || 'http://localhost:8000'
13+
14+
// Parse CHROMA_URL into components for new API
15+
function parseChromaUrl(urlStr: string): { host: string; port: number; ssl: boolean } {
16+
const url = new URL(urlStr)
17+
return {
18+
host: url.hostname,
19+
port: parseInt(url.port) || (url.protocol === 'https:' ? 443 : 8000),
20+
ssl: url.protocol === 'https:',
21+
}
22+
}
1323

1424
let client: ChromaClient | null = null
1525
let collection: Collection | null = null
@@ -33,7 +43,8 @@ export async function initRAG(): Promise<void> {
3343
throw new Error('No embedding provider available. Set OLLAMA_BASE_URL or OPENAI_API_KEY.')
3444
}
3545

36-
client = new ChromaClient({ path: CHROMA_HOST })
46+
const chromaConfig = parseChromaUrl(CHROMA_URL)
47+
client = new ChromaClient(chromaConfig)
3748

3849
// 使用自定义 embedding function
3950
const embeddingFunction = new CustomEmbeddingFunction()

packages/core/src/stock-fetcher.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,11 @@
55

66
import YahooFinance from 'yahoo-finance2'
77
import { insertStockPrices, cleanupOldStocks, type StockRecord } from './stock-store'
8-
import { getProxyUrl } from './proxy-fetch'
98

10-
// Initialize Yahoo Finance client with proxy support
11-
const proxyUrl = getProxyUrl()
9+
// Initialize Yahoo Finance client
10+
// Note: yahoo-finance2 uses native fetch, proxy is handled via HTTP_PROXY env var
1211
const yahooFinance = new YahooFinance({
1312
suppressNotices: ['yahooSurvey'],
14-
...(proxyUrl && {
15-
fetchOptions: {
16-
agent: proxyUrl,
17-
},
18-
}),
1913
})
2014

2115
/**

packages/web/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
<html lang="en">
33
<head>
44
<meta charset="UTF-8" />
5-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
5+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>frontend</title>
7+
<title>MarketPulse</title>
88
</head>
99
<body>
1010
<div id="root"></div>

packages/web/public/favicon.svg

Lines changed: 9 additions & 0 deletions
Loading

packages/web/src/App.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { useState, useRef, useEffect, useCallback } from 'react'
2-
import { TrendingUp, Menu } from 'lucide-react'
2+
import { Menu } from 'lucide-react'
33
import { TooltipProvider } from '@/components/ui/tooltip'
44
import { Sidebar } from '@/components/Sidebar'
55
import { ChatMessage } from '@/components/ChatMessage'
66
import { ChatInput } from '@/components/ChatInput'
77
import { ScrapeNotification } from '@/components/ScrapeNotification'
88
import { SearchHistoryDropdown } from '@/components/SearchHistoryDropdown'
9+
import { Logo } from '@/components/Logo'
910
import { useConversations } from '@/hooks/useConversations'
1011
import { useTheme } from '@/hooks/useTheme'
1112
import { useSSEEvents } from '@/hooks/useSSEEvents'
@@ -573,7 +574,7 @@ function App() {
573574
{messages.length === 0 ? (
574575
<div className="welcome">
575576
<div className="welcome-icon">
576-
<TrendingUp strokeWidth={1.5} />
577+
<Logo size={64} theme={theme} />
577578
</div>
578579
<h1>MarketPulse</h1>
579580
<p>智能金融助手</p>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
interface LogoProps {
2+
size?: number
3+
className?: string
4+
theme?: 'light' | 'dark'
5+
}
6+
7+
export function Logo({ size = 24, className = '', theme }: LogoProps) {
8+
// 浅色模式:深色背景 + 白色折线
9+
// 深色模式:浅色背景 + 深色折线(背景比页面背景稍暗一点形成色差)
10+
const isDark = theme === 'dark'
11+
12+
const bgColor = isDark ? '#e5e5e5' : '#1a1a1a'
13+
const lineColor = isDark ? '#1a1a1a' : '#ffffff'
14+
15+
return (
16+
<svg
17+
xmlns="http://www.w3.org/2000/svg"
18+
viewBox="0 0 32 32"
19+
width={size}
20+
height={size}
21+
className={className}
22+
>
23+
<rect width="32" height="32" rx="6" fill={bgColor} />
24+
<path
25+
d="M4 18 L8 18 L10 12 L13 22 L16 8 L19 24 L22 14 L24 18 L28 18"
26+
fill="none"
27+
stroke={lineColor}
28+
strokeWidth="2"
29+
strokeLinecap="round"
30+
strokeLinejoin="round"
31+
/>
32+
</svg>
33+
)
34+
}

packages/web/src/components/Sidebar.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Plus, Trash2, MessageSquare, PanelLeftClose, PanelLeft, TrendingUp, Sun, Moon } from 'lucide-react'
1+
import { Plus, Trash2, MessageSquare, PanelLeftClose, PanelLeft, Sun, Moon } from 'lucide-react'
2+
import { Logo } from '@/components/Logo'
23
import {
34
Tooltip,
45
TooltipContent,
@@ -45,7 +46,7 @@ export function Sidebar({
4546
{/* Logo Area */}
4647
<div className="manus-sidebar-logo">
4748
<div className="manus-sidebar-brand">
48-
<TrendingUp className="manus-sidebar-brand-icon" />
49+
<Logo size={24} theme={theme} />
4950
{isOpen && <span className="manus-sidebar-brand-text">MarketPulse</span>}
5051
</div>
5152
<Tooltip>

0 commit comments

Comments
 (0)