| 1 | import SwiftUI |
| 2 | |
| 3 | struct DocumentThumbnailData: Decodable, Sendable { |
| 4 | let bars: [Bar]? |
| 5 | let width: Double |
| 6 | let height: Double |
| 7 | enum CodingKeys: String, CodingKey { case bars = "Bars", width = "W", height = "H" } |
| 8 | struct Bar: Decodable, Sendable { |
| 9 | let x: Double; let y: Double; let width: Double; let height: Double |
| 10 | enum CodingKeys: String, CodingKey { case x = "X", y = "Y", width = "W", height = "H" } |
| 11 | } |
| 12 | } |
| 13 | |
| 14 | struct DocumentThumbnail: View { |
| 15 | let data: DocumentThumbnailData? |
| 16 | var width: CGFloat = 34 |
| 17 | var height: CGFloat = 44 |
| 18 | var body: some View { |
| 19 | Canvas { context, size in |
| 20 | guard let data, data.width > 0, data.height > 0 else { return } |
| 21 | let scale = min(size.width / data.width, size.height / data.height) |
| 22 | let x = (size.width - data.width * scale) / 2 |
| 23 | let y = (size.height - data.height * scale) / 2 |
| 24 | for bar in data.bars ?? [] { |
| 25 | context.fill(Path(CGRect(x: x + bar.x * scale, y: y + bar.y * scale, |
| 26 | width: max(0, bar.width * scale), height: max(0, bar.height * scale))), with: .foreground) |
| 27 | } |
| 28 | } |
| 29 | .foregroundStyle(.secondary) |
| 30 | .frame(width: width, height: height) |
| 31 | .background(.background) |
| 32 | .clipShape(.rect(cornerRadius: 3)) |
| 33 | .overlay { RoundedRectangle(cornerRadius: 3).strokeBorder(.quaternary) } |
| 34 | .accessibilityHidden(true) |
| 35 | } |
| 36 | } |
| 37 | |