79 lines
2.9 KiB
Swift
79 lines
2.9 KiB
Swift
//
|
|
// SuggestedProfileCardView.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 11/8/23.
|
|
// Copyright © 2023 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
#if os(visionOS)
|
|
import SwiftUI
|
|
|
|
struct SuggestedProfileCardView: View {
|
|
let account: AccountMO
|
|
|
|
var body: some View {
|
|
VStack {
|
|
HeaderLayout {
|
|
AsyncImage(url: account.header) { image in
|
|
image
|
|
.resizable()
|
|
} placeholder: {
|
|
Rectangle().fill(.tertiary)
|
|
}
|
|
AsyncImage(url: account.avatar) { image in
|
|
image
|
|
.resizable()
|
|
.clipShape(RoundedRectangle(cornerRadius: 5))
|
|
} placeholder: {
|
|
Rectangle().fill(.tertiary)
|
|
}
|
|
VStack(alignment: .leading) {
|
|
AccountDisplayNameView(account: account, textStyle: .title, emojiSize: 24)
|
|
Text(verbatim: "@\(account.acct)")
|
|
}
|
|
}
|
|
|
|
NoteTextView(note: account.note)
|
|
}
|
|
.glassBackgroundEffect(in: RoundedRectangle(cornerRadius: 12.5))
|
|
}
|
|
}
|
|
|
|
private struct HeaderLayout: Layout {
|
|
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
|
let acceptedWidth = proposal.width ?? 200
|
|
let avatarSize = subviews[1].sizeThatFits(ProposedViewSize(width: 86, height: 86))
|
|
let accountInfoSize = subviews[2].sizeThatFits(ProposedViewSize(width: acceptedWidth - 8 - avatarSize.width, height: 43))
|
|
return CGSize(width: proposal.width ?? 200, height: 100 + 4 + accountInfoSize.height)
|
|
}
|
|
|
|
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
|
let headerSize = subviews[0].sizeThatFits(ProposedViewSize(width: bounds.width, height: 100))
|
|
subviews[0].place(at: .zero, proposal: ProposedViewSize(headerSize))
|
|
let avatarSize = subviews[1].sizeThatFits(ProposedViewSize(width: 86, height: 86))
|
|
subviews[1].place(at: CGPoint(x: 8, y: headerSize.height), anchor: .leading, proposal: ProposedViewSize(avatarSize))
|
|
subviews[2].place(at: CGPoint(x: 8 + avatarSize.width + 8, y: headerSize.height + 4), proposal: ProposedViewSize(width: bounds.width - 8 - avatarSize.width - 8, height: 43))
|
|
}
|
|
}
|
|
|
|
private struct NoteTextView: UIViewRepresentable {
|
|
typealias UIViewType = ContentTextView
|
|
let note: String
|
|
func makeUIView(context: Context) -> ContentTextView {
|
|
let view = ContentTextView()
|
|
view.isUserInteractionEnabled = false
|
|
view.isScrollEnabled = true
|
|
view.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
|
return view
|
|
}
|
|
func updateUIView(_ uiView: ContentTextView, context: Context) {
|
|
uiView.setBodyTextFromHTML(note)
|
|
}
|
|
}
|
|
|
|
//#Preview {
|
|
// SuggestedProfileCardView()
|
|
//}
|
|
#endif
|