iOS 与传输修复:取消即时落终态 + 行操作统一 + 记录按用户分桶 + 发送端进度/完成对齐接收端

- 取消传输无效:web cancelTransfer 拆除本端 p2p/relay 后立即 completeTransfer(sessionId, "CANCELLED") 落终态,不再仅依赖服务端 transfer:state CANCELLED 回显——回显延迟、或因设备名变更致路由不中而未送达时,旧实现使记录永停“进行中”,即用户所见“取消无效”。completeTransfer 幂等,随后回显安全重入。
- 进行中/已完成传输行操作统一:进行中行新增滑动“取消”+ 长按菜单“取消/切中继”,与历史行滑动+长按“删除”对称。取消即时无确认、随 transferDone 移入 history,析构滑动动画与现实一致不抖。详情页取消/切中继入口保留。
- 传输历史/消息持久化:记录按登录用户 userId 分桶持久化(EngineController recordKey/activateRecords/persist*,含旧无桶文件一次性回退)。reset() 改为只清内存、不再 RecordsStore.clear 磁盘——会话失效(authExpired/被吊销)属凭证层事件,不应连用户数据一并销毁;同一账户重登经 activateRecords 即恢复,换账号各读各桶天然防跨账号泄露。CDropApp 在 onAppear 与 onChange(session.user.id) 激活记录。
- 发送端进度/完成对齐接收端:接收端经数据通道节流(200ms)+finalize 即时回传已收字节(ack 帧);发送端进度改用 ackedBytes(单调取大),取代仅反映本地 SCTP 缓冲抽干的 senderDeliveredBytes——避免 Windows→iOS 等慢接收端组合下发送端进度虚高领先、完成早十数秒(4MB)。streamFile 抽干 buffer 后再等 ack 追平总量才宣告完成;ackedBytes==0(旧版本接收端)走旧“抽干即完成”行为、30s 超时兜底、接收端权威 /done 经 SSE 独立完成。
This commit is contained in:
2026-06-27 20:15:08 +08:00
parent 2caf1ab921
commit c1dda6759c
5 changed files with 192 additions and 26 deletions
+20 -3
View File
@@ -227,9 +227,10 @@ struct TransferListView: View
}
}
// + /
// /
//
// + /
//
// / transferDone
// history /
@ViewBuilder
private func transferRow(_ item: TransferItem, history: Bool) -> some View
{
@@ -256,6 +257,22 @@ struct TransferListView: View
else
{
card
.swipeActions(edge: .trailing)
{
Button(role: .destructive) { engine.cancelTransfer(item.sessionId) }
label: { Label(t("ios.transfer.cancel"), systemImage: "xmark.circle") }
}
.contextMenu
{
Button(role: .destructive) { engine.cancelTransfer(item.sessionId) }
label: { Label(t("ios.transfer.cancel"), systemImage: "xmark.circle") }
if item.mode != "relay"
{
Button { engine.switchToRelay(item.sessionId) }
label: { Label(t("ios.transfer.forceRelay"),
systemImage: "antenna.radiowaves.left.and.right") }
}
}
}
}