IceCubes/IceCubesAppWidgetsExtension/Shared/PostsWidgetView.swift

97 lines
2.3 KiB
Swift
Raw Normal View History

2024-05-05 19:31:28 +02:00
import DesignSystem
import Models
2024-05-06 08:38:37 +02:00
import Network
import SwiftUI
2024-05-05 19:31:28 +02:00
import Timeline
2024-05-06 08:38:37 +02:00
import WidgetKit
2024-05-05 19:31:28 +02:00
2024-05-05 19:37:06 +02:00
struct PostsWidgetEntry: TimelineEntry {
2024-05-05 19:31:28 +02:00
let date: Date
2024-05-06 08:37:58 +02:00
let title: String
2024-05-05 19:31:28 +02:00
let statuses: [Status]
let images: [URL: UIImage]
}
2024-05-06 08:38:37 +02:00
struct PostsWidgetView: View {
2024-05-05 19:31:28 +02:00
var entry: LatestPostsWidgetProvider.Entry
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
@Environment(\.widgetFamily) var family
@Environment(\.redactionReasons) var redacted
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
var contentLineLimit: Int {
switch family {
case .systemSmall, .systemMedium:
2024-05-05 20:03:12 +02:00
return 5
2024-05-05 19:31:28 +02:00
default:
return 2
}
}
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
var body: some View {
VStack(alignment: .leading, spacing: 8) {
headerView
2024-05-05 20:03:12 +02:00
ForEach(entry.statuses) { status in
makeStatusView(status)
2024-05-05 19:31:28 +02:00
}
Spacer()
}
.frame(maxWidth: .infinity)
}
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
private var headerView: some View {
HStack {
2024-05-06 08:37:58 +02:00
Text(entry.title)
2024-05-05 19:31:28 +02:00
Spacer()
Image(systemName: "cube")
}
.font(.subheadline)
.fontWeight(.bold)
.foregroundStyle(Color("AccentColor"))
}
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
@ViewBuilder
private func makeStatusView(_ status: Status) -> some View {
if let url = URL(string: status.url ?? "") {
Link(destination: url, label: {
VStack(alignment: .leading, spacing: 2) {
makeStatusHeaderView(status)
Text(status.content.asSafeMarkdownAttributedString)
2024-05-05 20:03:12 +02:00
.font(.footnote)
2024-05-05 19:31:28 +02:00
.lineLimit(contentLineLimit)
.fixedSize(horizontal: false, vertical: true)
.padding(.leading, 20)
}
})
}
}
2024-05-06 08:38:37 +02:00
2024-05-05 19:31:28 +02:00
private func makeStatusHeaderView(_ status: Status) -> some View {
HStack(alignment: .center, spacing: 4) {
if let image = entry.images[status.account.avatar] {
Image(uiImage: image)
.resizable()
.frame(width: 16, height: 16)
.clipShape(Circle())
} else {
Circle()
.foregroundStyle(.secondary)
.frame(width: 16, height: 16)
}
HStack(spacing: 0) {
Text(status.account.safeDisplayName)
.foregroundStyle(.primary)
if family != .systemSmall {
Text(" @")
.foregroundStyle(.tertiary)
Text(status.account.username)
.foregroundStyle(.tertiary)
}
Spacer()
}
2024-05-05 20:03:12 +02:00
.font(.footnote)
2024-05-05 19:31:28 +02:00
.fontWeight(.semibold)
.lineLimit(1)
}
}
}