mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-11-14 05:21:12 +00:00
Fix Preview Image Size of StatusRowCardView
. (#1904)
* fix preview image size and text spacing * Fix bg --------- Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
This commit is contained in:
parent
328ee2d090
commit
0b7fed2e9a
2 changed files with 61 additions and 22 deletions
|
@ -10,6 +10,8 @@ public struct Card: Codable, Identifiable, Equatable, Hashable {
|
||||||
public let description: String?
|
public let description: String?
|
||||||
public let type: String
|
public let type: String
|
||||||
public let image: URL?
|
public let image: URL?
|
||||||
|
public let width: CGFloat
|
||||||
|
public let height: CGFloat
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Card: Sendable {}
|
extension Card: Sendable {}
|
||||||
|
|
|
@ -45,9 +45,9 @@ public struct StatusRowCardView: View {
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
if let title = card.title, let url = URL(string: card.url) {
|
if let title = card.title, let url = URL(string: card.url) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
let sitesWithIcons = ["apps.apple.com", "music.apple.com", "open.spotify.com"]
|
let sitesWithIcons = ["apps.apple.com", "music.apple.com", "open.spotify.com"]
|
||||||
if (UIDevice.current.userInterfaceIdiom == .pad ||
|
if (UIDevice.current.userInterfaceIdiom == .pad ||
|
||||||
UIDevice.current.userInterfaceIdiom == .mac ||
|
UIDevice.current.userInterfaceIdiom == .mac ||
|
||||||
UIDevice.current.userInterfaceIdiom == .vision),
|
UIDevice.current.userInterfaceIdiom == .vision),
|
||||||
let host = url.host(), sitesWithIcons.contains(host) {
|
let host = url.host(), sitesWithIcons.contains(host) {
|
||||||
|
@ -94,25 +94,9 @@ public struct StatusRowCardView: View {
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private func defaultLinkPreview(_ title: String, _ url: URL) -> some View {
|
private func defaultLinkPreview(_ title: String, _ url: URL) -> some View {
|
||||||
if let imageURL = card.image, !isInCaptureMode {
|
if let imageURL = card.image, !isInCaptureMode {
|
||||||
LazyResizableImage(url: imageURL) { state, proxy in
|
DefaultPreviewImage(url: imageURL, originalWidth: card.width, originalHeight: card.height)
|
||||||
let width = imageWidthFor(proxy: proxy)
|
|
||||||
if let image = state.image {
|
|
||||||
image
|
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fill)
|
|
||||||
.frame(height: imageHeight)
|
|
||||||
.frame(maxWidth: width)
|
|
||||||
.clipped()
|
|
||||||
} else if state.isLoading {
|
|
||||||
Rectangle()
|
|
||||||
.fill(Color.gray)
|
|
||||||
.frame(height: imageHeight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// This image is decorative
|
|
||||||
.accessibilityHidden(true)
|
|
||||||
.frame(height: imageHeight)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text(title)
|
Text(title)
|
||||||
.font(.scaledHeadline)
|
.font(.scaledHeadline)
|
||||||
|
@ -129,8 +113,7 @@ public struct StatusRowCardView: View {
|
||||||
.lineLimit(1)
|
.lineLimit(1)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
.padding(.horizontal, 10)
|
.padding(10)
|
||||||
.padding(.bottom, 10)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func iconLinkPreview(_ title: String, _ url: URL) -> some View {
|
private func iconLinkPreview(_ title: String, _ url: URL) -> some View {
|
||||||
|
@ -173,3 +156,57 @@ public struct StatusRowCardView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DefaultPreviewImage: View {
|
||||||
|
@Environment(Theme.self) private var theme
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
let originalWidth: CGFloat
|
||||||
|
let originalHeight: CGFloat
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
_Layout(originalWidth: originalWidth, originalHeight: originalHeight) {
|
||||||
|
LazyResizableImage(url: url) { state, _ in
|
||||||
|
Rectangle()
|
||||||
|
.fill(theme.secondaryBackgroundColor)
|
||||||
|
.overlay {
|
||||||
|
if let image = state.image {
|
||||||
|
image.resizable().scaledToFill()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.accessibilityHidden(true) // This image is decorative
|
||||||
|
.clipped()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct _Layout: Layout {
|
||||||
|
let originalWidth: CGFloat
|
||||||
|
let originalHeight: CGFloat
|
||||||
|
|
||||||
|
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
||||||
|
guard !subviews.isEmpty else { return CGSize.zero }
|
||||||
|
return calculateSize(proposal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
||||||
|
guard let view = subviews.first else { return }
|
||||||
|
|
||||||
|
let size = calculateSize(proposal)
|
||||||
|
view.place(at: bounds.origin, proposal: ProposedViewSize(size))
|
||||||
|
}
|
||||||
|
|
||||||
|
private func calculateSize(_ proposal: ProposedViewSize) -> CGSize {
|
||||||
|
return switch (proposal.width, proposal.height) {
|
||||||
|
case (nil, nil):
|
||||||
|
CGSize(width: originalWidth, height: originalWidth)
|
||||||
|
case let (nil, .some(height)):
|
||||||
|
CGSize(width: originalWidth, height: min(height, originalWidth))
|
||||||
|
case (0, _):
|
||||||
|
CGSize.zero
|
||||||
|
case let (.some(width), _):
|
||||||
|
CGSize(width: width, height: width / originalWidth * originalHeight)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue