修复边拍边传自动上传范围,并避免上传状态被旧快照回退。
拍后传输下载的历史照片切换模式后不再自动补传;刷新相机文件仅同步本地。重试上传后刷新单张状态,并忽略乱序 pipeline 通知导致的已上传回退。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -678,6 +678,7 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
|
||||
if pipeline.task(forAssetID: id) != nil {
|
||||
await pipeline.uploadAssets(withIDs: [id])
|
||||
await refreshPhotoFromPipelineTask(id: id)
|
||||
return
|
||||
}
|
||||
|
||||
@ -695,6 +696,7 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
filename: record.fileName,
|
||||
localPath: record.localPath
|
||||
)
|
||||
await refreshPhotoFromPipelineTask(id: id)
|
||||
}
|
||||
|
||||
/// 删除本地照片记录。
|
||||
@ -764,6 +766,11 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
replacePhoto(updated, rebuildGroups: photo.status != status)
|
||||
}
|
||||
|
||||
private func refreshPhotoFromPipelineTask(id: String) async {
|
||||
guard let task = pipeline.task(forAssetID: id) else { return }
|
||||
await applyPipelineTasks([task], enforceAlbumBinding: false)
|
||||
}
|
||||
|
||||
private func persistPhotoStatus(
|
||||
id: String,
|
||||
status: WiredTransferUploadStatus,
|
||||
@ -884,7 +891,7 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
setPhotos(records.map { $0.toPhotoItem() }.sortedByCaptureTimeDescending(), rebuildGroups: true)
|
||||
}
|
||||
|
||||
private func applyPipelineTasks(_ tasks: [CameraTransferTask]) async {
|
||||
private func applyPipelineTasks(_ tasks: [CameraTransferTask], enforceAlbumBinding: Bool = true) async {
|
||||
guard let userIDProvider else { return }
|
||||
let userID = userIDProvider()
|
||||
|
||||
@ -896,14 +903,17 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
)
|
||||
|
||||
for task in tasks {
|
||||
guard belongsToCurrentAlbum(task.assetID) else { continue }
|
||||
guard !enforceAlbumBinding || belongsToCurrentAlbum(task.assetID) else { continue }
|
||||
|
||||
let status = mapPipelineStatus(task.status)
|
||||
let existing = existingByID[task.assetID] ?? existingByFileName[task.filename]
|
||||
if shouldIgnoreStalePipelineStatus(existing: existing?.status, incoming: status) {
|
||||
continue
|
||||
}
|
||||
let storedLocalPath = task.localPath ?? ""
|
||||
let localURL = task.localURL
|
||||
let fileSizeBytes = await CameraDownloadStorage.fileSizeBytes(for: localURL)
|
||||
|
||||
let existing = existingByID[task.assetID] ?? existingByFileName[task.filename]
|
||||
let existingRecord = persistedRecordsByID[task.assetID]
|
||||
let capturedAt = await resolveCapturedAt(
|
||||
existing: existing,
|
||||
@ -1027,6 +1037,21 @@ final class WiredCameraTransferViewModel: ObservableObject {
|
||||
}
|
||||
}
|
||||
|
||||
/// 忽略异步通知乱序产生的旧状态,避免上传中或已上传被旧快照回退成待上传。
|
||||
private func shouldIgnoreStalePipelineStatus(
|
||||
existing: WiredTransferUploadStatus?,
|
||||
incoming: WiredTransferUploadStatus
|
||||
) -> Bool {
|
||||
switch (existing, incoming) {
|
||||
case (.uploaded?, .pending), (.uploaded?, .transferring), (.uploaded?, .uploading), (.uploaded?, .failed):
|
||||
return true
|
||||
case (.uploading?, .pending), (.uploading?, .transferring):
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/// 仅在状态、路径或远程 URL 变化,或进度跨越大步长时落盘,避免高频 IO。
|
||||
private func shouldPersistPipelineUpdate(
|
||||
photoID: String,
|
||||
|
||||
Reference in New Issue
Block a user