对齐旅拍相册详情页 Android UI,并修复网格预览与布局问题。
重构相册详情为信息卡片、Tab 筛选、排序、批量删除与底部上传栏;修复网格重叠、禁用按钮蒙层,并支持点击预览大图。同步扩展素材列表 API 与 ViewModel 分页逻辑,并优化有线传图缩略图与传输性能。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@ -161,6 +161,18 @@ struct TravelAlbumMaterial: Decodable, Identifiable, Equatable {
|
||||
createdAt = container.lossyString(forKey: .createdAt)
|
||||
updatedAt = container.lossyString(forKey: .updatedAt)
|
||||
}
|
||||
|
||||
/// 预览用大图 URL,优先原图地址。
|
||||
var previewURLString: String {
|
||||
if !fileURL.isEmpty { return fileURL }
|
||||
return coverURL
|
||||
}
|
||||
|
||||
/// 列表缩略图 URL,优先封面。
|
||||
var thumbnailURLString: String {
|
||||
if !coverURL.isEmpty { return coverURL }
|
||||
return fileURL
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建旅拍相册请求。
|
||||
@ -308,7 +320,10 @@ struct WiredTransferPhotoItem: Identifiable, Equatable {
|
||||
let id: String
|
||||
let sourceId: String
|
||||
let fileName: String
|
||||
/// 列表使用的缩略图 URL,优先指向本地小图或远程封面。
|
||||
let thumbnailURL: String
|
||||
/// 预览使用的大图 URL,优先指向本地原图。
|
||||
let previewURL: String
|
||||
let capturedAt: String
|
||||
let fileSizeText: String
|
||||
let resolutionText: String
|
||||
@ -321,6 +336,7 @@ struct WiredTransferPhotoItem: Identifiable, Equatable {
|
||||
sourceId: String? = nil,
|
||||
fileName: String,
|
||||
thumbnailURL: String,
|
||||
previewURL: String = "",
|
||||
capturedAt: String,
|
||||
fileSizeText: String,
|
||||
resolutionText: String = "",
|
||||
@ -332,6 +348,7 @@ struct WiredTransferPhotoItem: Identifiable, Equatable {
|
||||
self.sourceId = sourceId ?? id
|
||||
self.fileName = fileName
|
||||
self.thumbnailURL = thumbnailURL
|
||||
self.previewURL = previewURL
|
||||
self.capturedAt = capturedAt
|
||||
self.fileSizeText = fileSizeText
|
||||
self.resolutionText = resolutionText
|
||||
@ -385,8 +402,15 @@ struct WiredTransferPhotoRecord: Codable, Equatable {
|
||||
let updatedAt: TimeInterval
|
||||
|
||||
func toPhotoItem() -> WiredTransferPhotoItem {
|
||||
let previewCandidates = [thumbnailPath, localPath, remoteURL]
|
||||
let thumbnailURL = previewCandidates.compactMap { path -> String? in
|
||||
let thumbnailCandidates = [thumbnailPath, remoteURL]
|
||||
let thumbnailURL = thumbnailCandidates.compactMap { path -> String? in
|
||||
guard !path.isEmpty else { return nil }
|
||||
if path.hasPrefix("http") { return path }
|
||||
let preview = CameraDownloadStorage.previewURLString(from: path)
|
||||
return preview.isEmpty ? nil : preview
|
||||
}.first ?? ""
|
||||
let previewCandidates = [localPath, remoteURL, thumbnailPath]
|
||||
let previewURL = previewCandidates.compactMap { path -> String? in
|
||||
guard !path.isEmpty else { return nil }
|
||||
if path.hasPrefix("http") { return path }
|
||||
let preview = CameraDownloadStorage.previewURLString(from: path)
|
||||
@ -398,6 +422,7 @@ struct WiredTransferPhotoRecord: Codable, Equatable {
|
||||
sourceId: sourceId,
|
||||
fileName: fileName,
|
||||
thumbnailURL: thumbnailURL,
|
||||
previewURL: previewURL,
|
||||
capturedAt: capturedAt,
|
||||
fileSizeText: Self.formatFileSize(fileSizeBytes),
|
||||
status: WiredTransferUploadStatus(rawValue: status) ?? .pending,
|
||||
@ -465,6 +490,16 @@ extension Array where Element == WiredTransferPhotoItem {
|
||||
Set(filter { $0.canSelectForSpecifyUpload }.map(\.id))
|
||||
}
|
||||
|
||||
/// 按拍摄时间倒序排列,最新照片在最前。
|
||||
func sortedByCaptureTimeDescending() -> [WiredTransferPhotoItem] {
|
||||
sorted { lhs, rhs in
|
||||
let leftDate = lhs.capturedDate() ?? .distantPast
|
||||
let rightDate = rhs.capturedDate() ?? .distantPast
|
||||
if leftDate != rightDate { return leftDate > rightDate }
|
||||
return lhs.id > rhs.id
|
||||
}
|
||||
}
|
||||
|
||||
/// 构建 30 分钟时间段分组列表。
|
||||
func buildPhotoSections() -> [WiredTransferPhotoSection] {
|
||||
let grouped = Dictionary(grouping: compactMap { photo -> (Date, WiredTransferPhotoItem)? in
|
||||
|
||||
Reference in New Issue
Block a user