💄 Optimized post item row

This commit is contained in:
2025-10-29 23:52:18 +08:00
parent 234434f102
commit 7a5a2407b7

View File

@@ -15,28 +15,26 @@ struct PostRowView: View {
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {
HStack { HStack {
if let serverUrl = appState.serverUrl, let pictureId = post.publisher.picture?.id, let imageUrl = getAttachmentUrl(for: pictureId, serverUrl: serverUrl), let token = appState.token { if imageLoader.isLoading {
if imageLoader.isLoading { ProgressView()
ProgressView() .frame(width: 24, height: 24)
.frame(width: 24, height: 24) } else if let image = imageLoader.image {
} else if let image = imageLoader.image { image
image .resizable()
.resizable() .frame(width: 24, height: 24)
.frame(width: 24, height: 24) .clipShape(Circle())
.clipShape(Circle()) } else if let errorMessage = imageLoader.errorMessage {
} else if let errorMessage = imageLoader.errorMessage { Text("Failed: \(errorMessage)")
Text("Failed: \(errorMessage)") .font(.caption)
.font(.caption) .foregroundColor(.red)
.foregroundColor(.red) .frame(width: 24, height: 24)
.frame(width: 24, height: 24) } else {
} else { // Placeholder if no image and not loading
// Placeholder if no image and not loading Image(systemName: "person.circle.fill")
Image(systemName: "person.circle.fill") .resizable()
.resizable() .frame(width: 24, height: 24)
.frame(width: 24, height: 24) .clipShape(Circle())
.clipShape(Circle()) .foregroundColor(.gray)
.foregroundColor(.gray)
}
} }
Text(post.publisher.nick ?? post.publisher.name) Text(post.publisher.nick ?? post.publisher.name)
.font(.subheadline) .font(.subheadline)
@@ -57,7 +55,21 @@ struct PostRowView: View {
Text(content) Text(content)
.font(.body) .font(.body)
} }
}
if !post.attachments.isEmpty {
AttachmentView(attachment: post.attachments[0])
if post.attachments.count > 1 {
HStack(spacing: 8) {
Image(systemName: "paperclip.circle.fill")
.frame(width: 12, height: 12)
.foregroundStyle(.gray)
Text("\(post.attachments.count - 1)+ attachments")
.font(.footnote)
.foregroundStyle(.gray)
}
}
}
}.padding(.vertical)
} }
} }
@@ -70,7 +82,7 @@ struct PostDetailView: View {
ScrollView { ScrollView {
VStack(alignment: .leading, spacing: 8) { VStack(alignment: .leading, spacing: 8) {
HStack { HStack {
if let serverUrl = appState.serverUrl, let pictureId = post.publisher.picture?.id, let imageUrl = getAttachmentUrl(for: pictureId, serverUrl: serverUrl), let token = appState.token { if let serverUrl = appState.serverUrl, let pictureId = post.publisher.picture?.id {
if publisherImageLoader.isLoading { if publisherImageLoader.isLoading {
ProgressView() ProgressView()
.frame(width: 32, height: 32) .frame(width: 32, height: 32)
@@ -95,7 +107,8 @@ struct PostDetailView: View {
Text("@\(post.publisher.name)") Text("@\(post.publisher.name)")
.font(.headline) .font(.headline)
} }
.task(id: post.publisher.picture?.id) { // Use task(id:) to reload image when pictureId changes // Use task(id:) to reload image when pictureId changes
.task(id: post.publisher.picture?.id) {
if let serverUrl = appState.serverUrl, let pictureId = post.publisher.picture?.id, let imageUrl = getAttachmentUrl(for: pictureId, serverUrl: serverUrl), let token = appState.token { if let serverUrl = appState.serverUrl, let pictureId = post.publisher.picture?.id, let imageUrl = getAttachmentUrl(for: pictureId, serverUrl: serverUrl), let token = appState.token {
await publisherImageLoader.loadImage(from: imageUrl, token: token) await publisherImageLoader.loadImage(from: imageUrl, token: token)
} }
@@ -113,7 +126,6 @@ struct PostDetailView: View {
} }
if !post.attachments.isEmpty { if !post.attachments.isEmpty {
Divider()
Text("Attachments").font(.headline) Text("Attachments").font(.headline)
ForEach(post.attachments) { attachment in ForEach(post.attachments) { attachment in
AttachmentView(attachment: attachment) AttachmentView(attachment: attachment)
@@ -121,7 +133,6 @@ struct PostDetailView: View {
} }
if !post.tags.isEmpty { if !post.tags.isEmpty {
Divider()
Text("Tags").font(.headline) Text("Tags").font(.headline)
FlowLayout(alignment: .leading, spacing: 4) { FlowLayout(alignment: .leading, spacing: 4) {
ForEach(post.tags) { tag in ForEach(post.tags) { tag in