From e1f08514a4151a9bc7f2dd709e768e8d807c73d7 Mon Sep 17 00:00:00 2001 From: Thomas Ricouard Date: Mon, 19 Dec 2022 17:18:16 +0100 Subject: [PATCH] Better status media --- IceCubesApp.xcodeproj/project.pbxproj | 4 +- .../Sources/Status/Row/StatusCardView.swift | 62 +++++++++++++++++++ .../Status/Row/StatusMediaPreviewView.swift | 60 ++++++++++++++---- .../Sources/Status/Row/StatusRowView.swift | 53 +--------------- 4 files changed, 112 insertions(+), 67 deletions(-) create mode 100644 Packages/Status/Sources/Status/Row/StatusCardView.swift diff --git a/IceCubesApp.xcodeproj/project.pbxproj b/IceCubesApp.xcodeproj/project.pbxproj index 90a2fc65..ddd6f36d 100644 --- a/IceCubesApp.xcodeproj/project.pbxproj +++ b/IceCubesApp.xcodeproj/project.pbxproj @@ -397,7 +397,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 0.0.2; + MARKETING_VERSION = 0.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; @@ -438,7 +438,7 @@ LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 0.0.2; + MARKETING_VERSION = 0.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.IceCubesApp; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = auto; diff --git a/Packages/Status/Sources/Status/Row/StatusCardView.swift b/Packages/Status/Sources/Status/Row/StatusCardView.swift new file mode 100644 index 00000000..b732ea62 --- /dev/null +++ b/Packages/Status/Sources/Status/Row/StatusCardView.swift @@ -0,0 +1,62 @@ +import SwiftUI +import Models + +struct StatusCardView: View { + @Environment(\.openURL) private var openURL + let status: AnyStatus + + var body: some View { + if let card = status.card, let title = card.title { + VStack(alignment: .leading) { + if let imageURL = card.image { + AsyncImage( + url: imageURL, + content: { image in + image.resizable() + .aspectRatio(contentMode: .fill) + }, + placeholder: { + ProgressView() + .frame(maxWidth: 40, maxHeight: 40) + } + ) + } + Spacer() + HStack { + VStack(alignment: .leading, spacing: 6) { + Text(title) + .font(.headline) + .lineLimit(3) + if let description = card.description, !description.isEmpty { + Text(description) + .font(.body) + .foregroundColor(.gray) + .lineLimit(3) + } else { + Text(card.url.absoluteString) + .font(.body) + .foregroundColor(.gray) + .lineLimit(3) + } + } + Spacer() + }.padding(8) + } + .background(Color.gray.opacity(0.15)) + .cornerRadius(16) + .overlay( + RoundedRectangle(cornerRadius: 16) + .stroke(.gray.opacity(0.35), lineWidth: 1) + ) + .onTapGesture { + openURL(card.url) + } + } + } +} + +struct StatusCardView_Previews: PreviewProvider { + static var previews: some View { + StatusCardView(status: Status.placeholder()) + } +} diff --git a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift index ab0d894d..2d303a18 100644 --- a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift @@ -2,8 +2,15 @@ import SwiftUI import Models import AVKit +// Could have just been a state, but SwiftUI .sheet is buggy ATM without @StateObject +class SelectedMediaSheetManager: ObservableObject { + @Published var selectedAttachement: MediaAttachement? +} + public struct StatusMediaPreviewView: View { public let attachements: [MediaAttachement] + + @StateObject private var selectedMediaSheetManager = SelectedMediaSheetManager() public var body: some View { VStack { @@ -24,6 +31,24 @@ public struct StatusMediaPreviewView: View { } } } + .sheet(item: $selectedMediaSheetManager.selectedAttachement) { attachement in + VStack { + Spacer() + AsyncImage( + url: attachement.url, + content: { image in + image + .resizable() + .aspectRatio(contentMode: .fit) + }, + placeholder: { + ProgressView() + .frame(maxWidth: 80, maxHeight: 80) + } + ) + Spacer() + } + } } @ViewBuilder @@ -31,20 +56,29 @@ public struct StatusMediaPreviewView: View { if let type = attachement.supportedType { switch type { case .image: - AsyncImage( - url: attachement.url, - content: { image in - image.resizable() - .aspectRatio(contentMode: .fit) - .frame(maxHeight: attachements.count > 2 ? 100 : 200) - .clipped() - .cornerRadius(4) - }, - placeholder: { - ProgressView() - .frame(maxWidth: 80, maxHeight: 80) + Group { + GeometryReader { proxy in + AsyncImage( + url: attachement.url, + content: { image in + image + .resizable() + .aspectRatio(contentMode: .fill) + .frame(height: attachements.count > 2 ? 100 : 200) + .frame(width: proxy.frame(in: .local).width) + }, + placeholder: { + ProgressView() + .frame(maxWidth: 80, maxHeight: 80) + } + ) } - ) + .frame(height: attachements.count > 2 ? 100 : 200) + } + .cornerRadius(4) + .onTapGesture { + selectedMediaSheetManager.selectedAttachement = attachement + } case .gifv: VideoPlayer(player: AVPlayer(url: attachement.url)) .frame(maxHeight: attachements.count > 2 ? 100 : 200) diff --git a/Packages/Status/Sources/Status/Row/StatusRowView.swift b/Packages/Status/Sources/Status/Row/StatusRowView.swift index 9a4f6032..e8ebd043 100644 --- a/Packages/Status/Sources/Status/Row/StatusRowView.swift +++ b/Packages/Status/Sources/Status/Row/StatusRowView.swift @@ -5,7 +5,6 @@ import DesignSystem import Network public struct StatusRowView: View { - @Environment(\.openURL) private var openURL @Environment(\.redactionReasons) private var reasons @EnvironmentObject private var client: Client @EnvironmentObject private var routeurPath: RouterPath @@ -64,7 +63,7 @@ public struct StatusRowView: View { StatusMediaPreviewView(attachements: status.mediaAttachments) .padding(.vertical, 4) } - makeCardView(status: status) + StatusCardView(status: status) } } @@ -85,54 +84,4 @@ public struct StatusRowView: View { } } } - - @ViewBuilder - private func makeCardView(status: AnyStatus) -> some View { - if let card = status.card, let title = card.title { - VStack(alignment: .leading) { - if let imageURL = card.image { - AsyncImage( - url: imageURL, - content: { image in - image.resizable() - .aspectRatio(contentMode: .fill) - }, - placeholder: { - ProgressView() - .frame(maxWidth: 40, maxHeight: 40) - } - ) - } - Spacer() - HStack { - VStack(alignment: .leading, spacing: 6) { - Text(title) - .font(.headline) - .lineLimit(3) - if let description = card.description, !description.isEmpty { - Text(description) - .font(.body) - .foregroundColor(.gray) - .lineLimit(3) - } else { - Text(card.url.absoluteString) - .font(.body) - .foregroundColor(.gray) - .lineLimit(3) - } - } - Spacer() - }.padding(8) - } - .background(Color.gray.opacity(0.15)) - .cornerRadius(16) - .overlay( - RoundedRectangle(cornerRadius: 16) - .stroke(.gray.opacity(0.35), lineWidth: 1) - ) - .onTapGesture { - openURL(card.url) - } - } - } }