b2970e4c-45a2-423e-b84d-257.../Sources/ui/HeaderSlotView.swift
徐翔宇 e5a72bcf42 v0.2.0: initial 看盘侠 — Fund & Gold plugin for MioIsland
Real-time OTC fund and gold tracker for the macOS notch. Three tabs:
- 持仓: live intraday estimates from 天天基金, hero card with
  total value / today P&L / cumulative P&L, per-row 当日 + 累计.
- 黄金: SHFE 沪金 realtime + daily K-line + 伦敦金 reference.
- 添加: search 26k+ public funds via 东方财富 suggest API.

No API keys, no Python, no servers. All data comes from public
endpoints (天天基金, 东方财富, 新浪财经).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 20:20:15 +08:00

42 lines
1.4 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HeaderSlotView.swift
// plugin
//
// 20×20 icon that lives in the notch header bar. We can't fit text
// in 20pt, so the visual contract is: solid icon = idle / red icon
// = portfolio down today / green icon = portfolio up today. Tap
// opens the expanded panel.
//
import SwiftUI
struct HeaderSlotView: View {
@ObservedObject var store: FundStore = .shared
var body: some View {
ZStack {
Image(systemName: "chart.line.uptrend.xyaxis")
.font(.system(size: 12, weight: .semibold))
.foregroundStyle(tint)
.frame(width: 20, height: 20)
}
}
/// Composite tint: bias toward red/green when the day's average
/// estimated rate across watchlist funds has a sign. Falls back
/// to white when no estimates yet (e.g. first launch, off-hours).
private var tint: Color {
let rates = store.estimates.values.compactMap { $0.estimatedRate }
guard !rates.isEmpty else { return .white.opacity(0.85) }
let avg = rates.reduce(0, +) / Double(rates.count)
if avg > 0.05 {
// Chinese convention: red = up.
return Color(red: 1.0, green: 0.30, blue: 0.30)
} else if avg < -0.05 {
// Green = down.
return Color(red: 0.20, green: 0.80, blue: 0.40)
}
return .white.opacity(0.85)
}
}