💄 Better watchOS video attachment display

This commit is contained in:
2025-10-30 00:03:24 +08:00
parent 7a5a2407b7
commit 44c5d91620
2 changed files with 46 additions and 34 deletions

View File

@@ -46,26 +46,34 @@ struct AttachmentView: View {
} }
} else if mimeType.starts(with: "video") { } else if mimeType.starts(with: "video") {
if let serverUrl = appState.serverUrl, let videoUrl = getAttachmentUrl(for: attachment.id, serverUrl: serverUrl) { if let serverUrl = appState.serverUrl, let videoUrl = getAttachmentUrl(for: attachment.id, serverUrl: serverUrl) {
let thumbnailUrl = videoUrl.appendingPathComponent("thumbnail") // Construct thumbnail URL
NavigationLink(destination: VideoPlayerView(videoUrl: videoUrl)) { NavigationLink(destination: VideoPlayerView(videoUrl: videoUrl)) {
AsyncImage(url: thumbnailUrl) { phase in if imageLoader.isLoading {
if let image = phase.image { ProgressView()
} else if let image = imageLoader.image {
ZStack {
image image
.resizable() .resizable()
.aspectRatio(contentMode: .fit) .aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity) .frame(maxWidth: .infinity)
.cornerRadius(8) .cornerRadius(8)
} else if phase.error != nil {
Image(systemName: "play.rectangle.fill") // Placeholder for video thumbnail Image(systemName: "play.circle.fill")
.resizable() .resizable()
.aspectRatio(contentMode: .fit) .scaledToFit()
.frame(maxWidth: .infinity) .frame(width: 36, height: 36)
.foregroundColor(.gray) .foregroundColor(.white)
.cornerRadius(8) .shadow(color: .black.opacity(0.6), radius: 4, x: 0, y: 2)
} else {
ProgressView()
.cornerRadius(8)
} }
} else if imageLoader.errorMessage != nil {
Image(systemName: "play.rectangle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(maxWidth: .infinity)
.foregroundColor(.gray)
.cornerRadius(8)
} else {
ProgressView()
.cornerRadius(8)
} }
} }
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
@@ -90,6 +98,11 @@ struct AttachmentView: View {
if attachment.mimeType?.starts(with: "image") == true { if attachment.mimeType?.starts(with: "image") == true {
await imageLoader.loadImage(from: attachmentUrl, token: token) await imageLoader.loadImage(from: attachmentUrl, token: token)
} }
if attachment.mimeType?.starts(with: "video") == true {
let thumbnailUrl = attachmentUrl
.appending(queryItems: [URLQueryItem(name: "thumbnail", value: "true")]) // Construct thumbnail URL
await imageLoader.loadImage(from: thumbnailUrl, token: token)
}
} }
} }
} }

View File

@@ -82,27 +82,25 @@ 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 { if publisherImageLoader.isLoading {
if publisherImageLoader.isLoading { ProgressView()
ProgressView() .frame(width: 32, height: 32)
.frame(width: 32, height: 32) } else if let image = publisherImageLoader.image {
} else if let image = publisherImageLoader.image { image
image .resizable()
.resizable() .frame(width: 32, height: 32)
.frame(width: 32, height: 32) .clipShape(Circle())
.clipShape(Circle()) } else if let errorMessage = publisherImageLoader.errorMessage {
} else if let errorMessage = publisherImageLoader.errorMessage { Text("Failed: \(errorMessage)")
Text("Failed: \(errorMessage)") .font(.caption)
.font(.caption) .foregroundColor(.red)
.foregroundColor(.red) .frame(width: 32, height: 32)
.frame(width: 32, height: 32) } else {
} else { Image(systemName: "person.circle.fill")
Image(systemName: "person.circle.fill") .resizable()
.resizable() .frame(width: 32, height: 32)
.frame(width: 32, height: 32) .clipShape(Circle())
.clipShape(Circle()) .foregroundColor(.gray)
.foregroundColor(.gray)
}
} }
Text("@\(post.publisher.name)") Text("@\(post.publisher.name)")
.font(.headline) .font(.headline)
@@ -138,7 +136,7 @@ struct PostDetailView: View {
ForEach(post.tags) { tag in ForEach(post.tags) { tag in
Text("#\(tag.name ?? tag.slug)") Text("#\(tag.name ?? tag.slug)")
.font(.caption) .font(.caption)
.padding(.horizontal, 6) .padding(.horizontal, 8)
.padding(.vertical, 3) .padding(.vertical, 3)
.background(Capsule().fill(Color.accentColor.opacity(0.2))) .background(Capsule().fill(Color.accentColor.opacity(0.2)))
.cornerRadius(5) .cornerRadius(5)
@@ -147,6 +145,7 @@ struct PostDetailView: View {
} }
} }
.padding() .padding()
.frame(width: .infinity)
} }
.navigationTitle("Post") .navigationTitle("Post")
} }