增强有线传图手动上传并发能力,并稳定列表行布局。
指定/勾选/批量上传支持恢复仅本地持久化的待传照片,手动上传与 pipeline 均按 3 路并发;pipeline 任务签名去重避免状态回退,照片行固定高度并预留进度条占位。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -80,19 +80,40 @@ final class CameraTransferPipeline {
|
||||
/// 手动上传指定 asset 列表(拍完再传模式)。
|
||||
func uploadAssets(withIDs assetIDs: [String]) async {
|
||||
guard uploadSink != nil else { return }
|
||||
for assetID in assetIDs {
|
||||
if activeUploadAssetIDs.contains(assetID) { continue }
|
||||
guard let index = tasks.firstIndex(where: { $0.assetID == assetID }) else { continue }
|
||||
if tasks[index].status == .uploaded { continue }
|
||||
if tasks[index].localURL == nil {
|
||||
await downloadAsset(assetID: assetID)
|
||||
var seenAssetIDs: Set<String> = []
|
||||
let uniqueAssetIDs = assetIDs.filter { seenAssetIDs.insert($0).inserted }
|
||||
var currentIndex = 0
|
||||
while currentIndex < uniqueAssetIDs.count {
|
||||
let upperBound = min(currentIndex + maxConcurrentUploads, uniqueAssetIDs.count)
|
||||
let batch = uniqueAssetIDs[currentIndex ..< upperBound]
|
||||
let uploadTasks = batch.map { assetID in
|
||||
Task { @MainActor in
|
||||
await self.uploadAssetIfNeeded(assetID: assetID)
|
||||
}
|
||||
}
|
||||
guard let refreshedIndex = tasks.firstIndex(where: { $0.assetID == assetID }) else { continue }
|
||||
if tasks[refreshedIndex].status == .downloaded || tasks[refreshedIndex].status == .failed {
|
||||
tasks[refreshedIndex].status = .downloaded
|
||||
tasks[refreshedIndex].errorMessage = nil
|
||||
await uploadTask(assetID: assetID)
|
||||
for task in uploadTasks {
|
||||
await task.value
|
||||
}
|
||||
currentIndex = upperBound
|
||||
}
|
||||
}
|
||||
|
||||
private func uploadAssetIfNeeded(assetID: String) async {
|
||||
if activeUploadAssetIDs.contains(assetID) { return }
|
||||
guard let index = tasks.firstIndex(where: { $0.assetID == assetID }) else { return }
|
||||
if tasks[index].status == .uploaded { return }
|
||||
|
||||
activeUploadAssetIDs.insert(assetID)
|
||||
defer { activeUploadAssetIDs.remove(assetID) }
|
||||
|
||||
if tasks[index].localURL == nil {
|
||||
await downloadAsset(assetID: assetID)
|
||||
}
|
||||
guard let refreshedIndex = tasks.firstIndex(where: { $0.assetID == assetID }) else { return }
|
||||
if tasks[refreshedIndex].status == .downloaded || tasks[refreshedIndex].status == .failed {
|
||||
tasks[refreshedIndex].status = .downloaded
|
||||
tasks[refreshedIndex].errorMessage = nil
|
||||
await uploadTask(assetID: assetID)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user