对齐旅拍相册详情页 Android UI,并修复网格预览与布局问题。

重构相册详情为信息卡片、Tab 筛选、排序、批量删除与底部上传栏;修复网格重叠、禁用按钮蒙层,并支持点击预览大图。同步扩展素材列表 API 与 ViewModel 分页逻辑,并优化有线传图缩略图与传输性能。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-30 13:53:59 +08:00
parent c71b45bdfd
commit 5e620623eb
23 changed files with 2000 additions and 288 deletions

View File

@ -4,7 +4,6 @@
//
import SwiftUI
import UIKit
import Kingfisher
/// 线 file:// URL
@ -19,7 +18,8 @@ struct WiredTransferPhotoPreviewSheet: View {
self.imageSources = imageSources
self.startIndex = startIndex
self.onDismiss = onDismiss
_currentIndex = State(initialValue: startIndex)
let safeIndex = imageSources.isEmpty ? 0 : min(max(startIndex, 0), imageSources.count - 1)
_currentIndex = State(initialValue: safeIndex)
}
var body: some View {
@ -46,12 +46,7 @@ struct WiredTransferPhotoPreviewSheet: View {
@ViewBuilder
private func previewImage(_ source: String) -> some View {
if source.hasPrefix("file://"), let url = URL(string: source),
let uiImage = UIImage(contentsOfFile: url.path) {
Image(uiImage: uiImage)
.resizable()
.scaledToFit()
} else if let url = URL(string: source), !source.isEmpty {
if let url = URL(string: source), !source.isEmpty {
KFImage(url)
.resizable()
.scaledToFit()

View File

@ -3,6 +3,7 @@
// suixinkan
//
import Kingfisher
import SwiftUI
import UIKit
@ -23,36 +24,40 @@ struct WiredTransferPhotoRow: View {
var body: some View {
VStack(spacing: 0) {
HStack(alignment: .center, spacing: 8) {
if selectUploadMode {
Button(action: onToggleSelection) {
HStack(alignment: .center, spacing: 8) {
if selectUploadMode {
WiredTransferSelectIndicator(selected: selected, enabled: canSelect)
}
.buttonStyle(.plain)
.disabled(!canSelect)
}
thumbnailView
.frame(width: WiredTransferDesign.thumbnailSize, height: WiredTransferDesign.thumbnailSize)
.clipShape(RoundedRectangle(cornerRadius: WiredTransferDesign.thumbnailCornerRadius))
.opacity(rowOpacity)
.onTapGesture {
if !selectUploadMode { onPhotoClick() }
}
thumbnailView
.frame(width: WiredTransferDesign.thumbnailSize, height: WiredTransferDesign.thumbnailSize)
.clipShape(RoundedRectangle(cornerRadius: WiredTransferDesign.thumbnailCornerRadius))
.opacity(rowOpacity)
VStack(alignment: .leading, spacing: 3) {
HStack(spacing: 4) {
Text(photo.fileName)
.font(.system(size: 12, weight: .medium))
.foregroundStyle(WiredTransferDesign.text333.opacity(rowOpacity))
VStack(alignment: .leading, spacing: 3) {
HStack(spacing: 4) {
Text(photo.fileName)
.font(.system(size: 12, weight: .medium))
.foregroundStyle(WiredTransferDesign.text333.opacity(rowOpacity))
.lineLimit(1)
Spacer(minLength: 0)
WiredTransferStatusBadge(status: photo.status)
.opacity(rowOpacity)
}
Text(metaText)
.font(.system(size: 10))
.foregroundStyle(WiredTransferDesign.text999.opacity(rowOpacity))
.lineLimit(1)
Spacer(minLength: 0)
WiredTransferStatusBadge(status: photo.status)
.opacity(rowOpacity)
}
Text(metaText)
.font(.system(size: 10))
.foregroundStyle(WiredTransferDesign.text999.opacity(rowOpacity))
.lineLimit(1)
}
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(Rectangle())
.onTapGesture {
if selectUploadMode {
if canSelect { onToggleSelection() }
} else {
onPhotoClick()
}
}
if !selectUploadMode {
@ -71,10 +76,6 @@ struct WiredTransferPhotoRow: View {
}
.padding(.horizontal, 10)
.padding(.vertical, 8)
.contentShape(Rectangle())
.onTapGesture {
if selectUploadMode, canSelect { onToggleSelection() }
}
if photo.status == .transferring || photo.status == .uploading {
ProgressView(value: Double(photo.progress), total: 100)
@ -93,18 +94,20 @@ struct WiredTransferPhotoRow: View {
@ViewBuilder
private var thumbnailView: some View {
if photo.thumbnailURL.hasPrefix("file://"), let url = URL(string: photo.thumbnailURL) {
if let uiImage = UIImage(contentsOfFile: url.path) {
Image(uiImage: uiImage)
.resizable()
.aspectRatio(contentMode: .fill)
} else {
thumbnailPlaceholder
}
} else if !photo.thumbnailURL.isEmpty {
RemoteImage(urlString: photo.thumbnailURL) {
thumbnailPlaceholder
}
if let url = URL(string: photo.thumbnailURL), !photo.thumbnailURL.isEmpty {
KFImage(url)
.placeholder { thumbnailPlaceholder }
.setProcessor(
DownsamplingImageProcessor(
size: CGSize(
width: WiredTransferDesign.thumbnailSize,
height: WiredTransferDesign.thumbnailSize
)
)
)
.scaleFactor(UIScreen.main.scale)
.resizable()
.aspectRatio(contentMode: .fill)
} else {
thumbnailPlaceholder
}