Files
Commilitia-Drop/web/src/features/transfer/ActivityFeed.tsx
T
admin f21fa5b5e8 cdrop — 跨 OS 剪贴板与文件传输服务
Commilitia Drop:自托管的跨设备剪贴板同步与点对点文件传输。

- 后端 Go(chi / SQLite WAL / SSE Hub / WebRTC signaling + 状态机 / Relay ring buffer),编译进单个 distroless 镜像(前端 go:embed)。
- 前端 React + TanStack Router + Zustand,自实现 SSE + WebRTC P2P,NAT 受阻时回退服务端中继;聚珍(Juzhen)CJK 综合排版。
- 桌面端 Wails v2(macOS / Windows),瘦客户端复用 web。
- 鉴权 OIDC PKCE(自建 Casdoor 等),refresh_token 信封加密存系统密钥库;iOS Shortcut 用 HS256 scoped token。

架构文档与变更记录见 docs 分支(PROJECT_BRIEF / FRONTEND_DESIGN / CHANGELOG)。

本次为公开发布初始提交:完整开发历史(含部署细节)留存于私有归档,公开仓库自此干净起步。
2026-06-15 21:38:28 +08:00

59 lines
1.9 KiB
TypeScript

import { useEffect, useState } from "react";
import type { TransferRecord } from "../../store";
import { TransferRow } from "./TransferRow";
import { t } from "../../i18n";
import s from "./ActivityFeed.module.css";
export interface ActivityFeedProps
{
active: TransferRecord[];
history: TransferRecord[];
}
// 1Hz now tick:仅在有 active 时启动,避免空转。
function useNowTick(activeKey: string)
{
const [ now, setNow ] = useState(() => Date.now());
useEffect(() =>
{
if (!activeKey) { return; }
const id = window.setInterval(() => setNow(Date.now()), 1000);
return () => window.clearInterval(id);
}, [ activeKey ]);
return now;
}
export function ActivityFeed(props: ActivityFeedProps)
{
const { active, history } = props;
const activeKey = active.map((t) => t.sessionId).sort().join("|");
const now = useNowTick(activeKey);
if (active.length === 0 && history.length === 0) { return null; }
return (
<section className={s.section}>
{active.length > 0 && (
<div>
<div className={s.subhead}>{t("home.transfer.active")}</div>
<div className={s.list}>
{active.map((tr) => (
<TransferRow key={tr.sessionId} record={tr} active now={now} />
))}
</div>
</div>
)}
{history.length > 0 && (
<div>
<div className={s.subhead}>{t("home.transfer.history")}</div>
<div className={s.list}>
{history.map((tr) => (
<TransferRow key={tr.sessionId} record={tr} active={false} now={now} />
))}
</div>
</div>
)}
</section>
);
}