import { useEffect } from 'react'; import { useContactStore } from '../stores/contactStore'; import { useSessionStore } from '../stores/sessionStore'; import { useUIStore } from '../stores/uiStore'; import { useMailStore } from '../stores/mailStore'; import type { Contact } from '../types'; import { ArchiveIcon, ComposeIcon, CheckIcon, CloseIcon, ChevronRightIcon, ListViewIcon, CardViewIcon } from './icons'; import { WorkCard } from './WorkCard'; /** * 左侧联系人面板:列出所有 name@path.session,支持 * - 点击进入该会话 * - 写信(预填收件人为该三维地址) * - 归档(Agent 侧会话归档 + 邮箱界面移除) */ export default function ContactPanel() { const contacts = useContactStore(s => s.contacts); const archivedContacts = useContactStore(s => s.archivedContacts); const showArchived = useContactStore(s => s.showArchived); const loading = useContactStore(s => s.loading); const error = useContactStore(s => s.error); const pendingArchive = useContactStore(s => s.pendingArchive); const fetchContacts = useContactStore(s => s.fetchContacts); const toggleArchivedView = useContactStore(s => s.toggleArchivedView); const requestArchive = useContactStore(s => s.requestArchive); const cancelArchive = useContactStore(s => s.cancelArchive); const archive = useContactStore(s => s.archive); const view = useContactStore(s => s.view); const setView = useContactStore(s => s.setView); const selectSession = useSessionStore(s => s.selectSession); const currentSession = useSessionStore(s => s.currentSession); const clearCurrentMail = useMailStore(s => s.clearCurrentMail); const startCompose = useUIStore(s => s.startCompose); const cancelCompose = useUIStore(s => s.cancelCompose); const showDetail = useUIStore(s => s.showDetail); useEffect(() => { fetchContacts(); }, []); const open = (c: Contact) => { cancelCompose(); clearCurrentMail(); selectSession(c.session_id); showDetail(); // 窄屏下切到会话内容栏 }; return (
{error}
}加载中
)} {contacts.map(c => // 归档确认态两种视图共用同一个确认框:那是个破坏性操作, // 换个视图就换套确认 UI 只会让人对「点了什么」更没底 pendingArchive === c.address ? ({view === 'card' ? '暂无进行中的工作,发一封邮件即可开始' : '暂无联系人,发一封邮件即可建立'}
)} {showArchived && (已归档 {archivedContacts.length}
{archivedContacts.map(c => ({c.address}
{c.mail_count} 封 · 已归档
无归档会话
)}归档 {contact.address}?
对应 Agent 的 session 将被归档,此列表与邮箱界面同时移除