Share post as image close #885

This commit is contained in:
Thomas Ricouard 2023-02-19 15:29:07 +01:00
parent dd2ebe5506
commit ccc504fc6f
25 changed files with 257 additions and 56 deletions

View file

@ -7,6 +7,8 @@ import Lists
import Status import Status
import SwiftUI import SwiftUI
import Timeline import Timeline
import LinkPresentation
import Models
@MainActor @MainActor
extension View { extension View {
@ -92,6 +94,8 @@ extension View {
case let .report(status): case let .report(status):
ReportView(status: status) ReportView(status: status)
.withEnvironments() .withEnvironments()
case let .shareImage(image, status):
ActivityView(image: image, status: status)
} }
} }
} }
@ -106,3 +110,42 @@ extension View {
.environmentObject(AppAccountsManager.shared.currentClient) .environmentObject(AppAccountsManager.shared.currentClient)
} }
} }
struct ActivityView: UIViewControllerRepresentable {
let image: UIImage
let status: Status
class LinkDelegate: NSObject, UIActivityItemSource {
let image: UIImage
let status: Status
init(image: UIImage, status: Status) {
self.image = image
self.status = status
}
func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
let imageProvider = NSItemProvider(object: image)
let metadata = LPLinkMetadata()
metadata.imageProvider = imageProvider
metadata.title = status.reblog?.content.asRawText ?? status.content.asRawText
return metadata
}
func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
image
}
func activityViewController(_ activityViewController: UIActivityViewController,
itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
nil
}
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
return UIActivityViewController(activityItems: [image, LinkDelegate(image: image, status: status)],
applicationActivities: nil)
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {}
}

View file

@ -372,6 +372,9 @@
"status.action.reply" = "Адказаць"; "status.action.reply" = "Адказаць";
"status.action.section.your-post" = "Ваш допіс"; "status.action.section.your-post" = "Ваш допіс";
"status.action.share" = "Падзяліцца гэтым допісам"; "status.action.share" = "Падзяліцца гэтым допісам";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Скасаваць закладку"; "status.action.unbookmark" = "Скасаваць закладку";
"status.action.unboost" = "Адмяніць павышэнне"; "status.action.unboost" = "Адмяніць павышэнне";
"status.action.unfavorite" = "Выдаліць з улюбенага"; "status.action.unfavorite" = "Выдаліць з улюбенага";

View file

@ -382,6 +382,9 @@
"status.action.reply" = "Respon"; "status.action.reply" = "Respon";
"status.action.section.your-post" = "La vostra publicació"; "status.action.section.your-post" = "La vostra publicació";
"status.action.share" = "Comparteix la publicació"; "status.action.share" = "Comparteix la publicació";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Elimina dels marcadors"; "status.action.unbookmark" = "Elimina dels marcadors";
"status.action.unboost" = "Desfés l'impulsa"; "status.action.unboost" = "Desfés l'impulsa";
"status.action.unfavorite" = "Desfés el preferit"; "status.action.unfavorite" = "Desfés el preferit";

View file

@ -379,6 +379,9 @@
"status.action.reply" = "Antworten"; "status.action.reply" = "Antworten";
"status.action.section.your-post" = "Dein Beitrag"; "status.action.section.your-post" = "Dein Beitrag";
"status.action.share" = "Diesen Beitrag teilen"; "status.action.share" = "Diesen Beitrag teilen";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Lesezeichen entfernen"; "status.action.unbookmark" = "Lesezeichen entfernen";
"status.action.unboost" = "Boost entfernen"; "status.action.unboost" = "Boost entfernen";
"status.action.unfavorite" = "Favorit entfernen"; "status.action.unfavorite" = "Favorit entfernen";

View file

@ -385,6 +385,9 @@
"status.action.reply" = "Reply"; "status.action.reply" = "Reply";
"status.action.section.your-post" = "Your post"; "status.action.section.your-post" = "Your post";
"status.action.share" = "Share this post"; "status.action.share" = "Share this post";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Unbookmark"; "status.action.unbookmark" = "Unbookmark";
"status.action.unboost" = "Unboost"; "status.action.unboost" = "Unboost";
"status.action.unfavorite" = "Unfavourite"; "status.action.unfavorite" = "Unfavourite";

View file

@ -384,6 +384,9 @@
"status.action.reply" = "Reply"; "status.action.reply" = "Reply";
"status.action.section.your-post" = "Your post"; "status.action.section.your-post" = "Your post";
"status.action.share" = "Share this post"; "status.action.share" = "Share this post";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Unbookmark"; "status.action.unbookmark" = "Unbookmark";
"status.action.unboost" = "Unboost"; "status.action.unboost" = "Unboost";
"status.action.unfavorite" = "Unfavorite"; "status.action.unfavorite" = "Unfavorite";

View file

@ -384,6 +384,9 @@
"status.action.reply" = "Responder"; "status.action.reply" = "Responder";
"status.action.section.your-post" = "Tus publicaciones"; "status.action.section.your-post" = "Tus publicaciones";
"status.action.share" = "Compartir esta publicación"; "status.action.share" = "Compartir esta publicación";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Quitar de marcadores"; "status.action.unbookmark" = "Quitar de marcadores";
"status.action.unboost" = "Deshacer Retoot"; "status.action.unboost" = "Deshacer Retoot";
"status.action.unfavorite" = "Eliminar de favoritos"; "status.action.unfavorite" = "Eliminar de favoritos";

View file

@ -377,6 +377,9 @@
"status.action.reply" = "Erantzun"; "status.action.reply" = "Erantzun";
"status.action.section.your-post" = "Zure bidalketa"; "status.action.section.your-post" = "Zure bidalketa";
"status.action.share" = "Partekatu bidalketa"; "status.action.share" = "Partekatu bidalketa";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Kendu laster-marka"; "status.action.unbookmark" = "Kendu laster-marka";
"status.action.unboost" = "Kendu bultzada"; "status.action.unboost" = "Kendu bultzada";
"status.action.unfavorite" = "Kendu gogokoa"; "status.action.unfavorite" = "Kendu gogokoa";

View file

@ -379,6 +379,9 @@
"status.action.reply" = "Répondre"; "status.action.reply" = "Répondre";
"status.action.section.your-post" = "Votre publication"; "status.action.section.your-post" = "Votre publication";
"status.action.share" = "Partager cette publication"; "status.action.share" = "Partager cette publication";
"status.action.share-link" = "Partager le lien";
"status.action.share-image" = "Partager comme image";
"status.action.share-title" = "Partager";
"status.action.unbookmark" = "Démarquer"; "status.action.unbookmark" = "Démarquer";
"status.action.unboost" = "Annuler la promotion"; "status.action.unboost" = "Annuler la promotion";
"status.action.unfavorite" = "Retirer des favoris"; "status.action.unfavorite" = "Retirer des favoris";

View file

@ -384,6 +384,9 @@
"status.action.reply" = "Rispondi"; "status.action.reply" = "Rispondi";
"status.action.section.your-post" = "I tuoi post"; "status.action.section.your-post" = "I tuoi post";
"status.action.share" = "Condividi questo post"; "status.action.share" = "Condividi questo post";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Rimuovi il segnalibro"; "status.action.unbookmark" = "Rimuovi il segnalibro";
"status.action.unboost" = "Rimuovi la condivisione"; "status.action.unboost" = "Rimuovi la condivisione";
"status.action.unfavorite" = "Rimuovi l'apprezzamento"; "status.action.unfavorite" = "Rimuovi l'apprezzamento";

View file

@ -383,6 +383,9 @@
"status.action.reply" = "リプライ"; "status.action.reply" = "リプライ";
"status.action.section.your-post" = "あなたの投稿"; "status.action.section.your-post" = "あなたの投稿";
"status.action.share" = "投稿を共有する"; "status.action.share" = "投稿を共有する";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "ブックマークを外す"; "status.action.unbookmark" = "ブックマークを外す";
"status.action.unboost" = "ブーストをやめる"; "status.action.unboost" = "ブーストをやめる";
"status.action.unfavorite" = "お気に入りから外す"; "status.action.unfavorite" = "お気に入りから外す";

View file

@ -385,6 +385,9 @@
"status.action.reply" = "댓글"; "status.action.reply" = "댓글";
"status.action.section.your-post" = "내 글"; "status.action.section.your-post" = "내 글";
"status.action.share" = "공유"; "status.action.share" = "공유";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "보관함에서 제거"; "status.action.unbookmark" = "보관함에서 제거";
"status.action.unboost" = "부스트 취소"; "status.action.unboost" = "부스트 취소";
"status.action.unfavorite" = "좋아요 취소"; "status.action.unfavorite" = "좋아요 취소";

View file

@ -383,6 +383,9 @@
"status.action.reply" = "Svar"; "status.action.reply" = "Svar";
"status.action.section.your-post" = "Ditt innlegg"; "status.action.section.your-post" = "Ditt innlegg";
"status.action.share" = "Del dette innlegget"; "status.action.share" = "Del dette innlegget";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Fjern bokmerke"; "status.action.unbookmark" = "Fjern bokmerke";
"status.action.unboost" = "Opphev forsterkningen"; "status.action.unboost" = "Opphev forsterkningen";
"status.action.unfavorite" = "Ikke favoritt"; "status.action.unfavorite" = "Ikke favoritt";

View file

@ -377,6 +377,9 @@
"status.action.reply" = "Antwoord"; "status.action.reply" = "Antwoord";
"status.action.section.your-post" = "Jouw post"; "status.action.section.your-post" = "Jouw post";
"status.action.share" = "Deel deze post"; "status.action.share" = "Deel deze post";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Verwijder bladwijzer"; "status.action.unbookmark" = "Verwijder bladwijzer";
"status.action.unboost" = "Maak boost ongedaan"; "status.action.unboost" = "Maak boost ongedaan";
"status.action.unfavorite" = "Verwijder favoriet"; "status.action.unfavorite" = "Verwijder favoriet";

View file

@ -379,6 +379,9 @@
"status.action.reply" = "Odpowiedz"; "status.action.reply" = "Odpowiedz";
"status.action.section.your-post" = "Twój post"; "status.action.section.your-post" = "Twój post";
"status.action.share" = "Udostępnij ten post"; "status.action.share" = "Udostępnij ten post";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Usuń zakładkę"; "status.action.unbookmark" = "Usuń zakładkę";
"status.action.unboost" = "Cofnij podbicie"; "status.action.unboost" = "Cofnij podbicie";
"status.action.unfavorite" = "Usuń z polubionych"; "status.action.unfavorite" = "Usuń z polubionych";

View file

@ -383,6 +383,9 @@
"status.action.reply" = "Responder"; "status.action.reply" = "Responder";
"status.action.section.your-post" = "Sua postagem"; "status.action.section.your-post" = "Sua postagem";
"status.action.share" = "Compartilhe esta postagem"; "status.action.share" = "Compartilhe esta postagem";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Remover dos salvos"; "status.action.unbookmark" = "Remover dos salvos";
"status.action.unboost" = "Unboost"; "status.action.unboost" = "Unboost";
"status.action.unfavorite" = "Desfavoritar"; "status.action.unfavorite" = "Desfavoritar";

View file

@ -379,6 +379,9 @@
"status.action.reply" = "Cevapla"; "status.action.reply" = "Cevapla";
"status.action.section.your-post" = "Senin gönderin"; "status.action.section.your-post" = "Senin gönderin";
"status.action.share" = "Bu gönderiyi paylaş"; "status.action.share" = "Bu gönderiyi paylaş";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "Yer İmini Kaldır"; "status.action.unbookmark" = "Yer İmini Kaldır";
"status.action.unboost" = "Yükseltmeyi Kaldır"; "status.action.unboost" = "Yükseltmeyi Kaldır";
"status.action.unfavorite" = "Favoriyi Kaldır"; "status.action.unfavorite" = "Favoriyi Kaldır";

View file

@ -384,6 +384,9 @@
"status.action.reply" = "回复"; "status.action.reply" = "回复";
"status.action.section.your-post" = "你的嘟文"; "status.action.section.your-post" = "你的嘟文";
"status.action.share" = "分享嘟文"; "status.action.share" = "分享嘟文";
"status.action.share-link" = "Share post link";
"status.action.share-image" = "Share post as image";
"status.action.share-title" = "Share";
"status.action.unbookmark" = "取消书签"; "status.action.unbookmark" = "取消书签";
"status.action.unboost" = "取消转发"; "status.action.unboost" = "取消转发";
"status.action.unfavorite" = "取消收藏"; "status.action.unfavorite" = "取消收藏";

View file

@ -1,8 +1,10 @@
import NukeUI import NukeUI
import Nuke
import Shimmer import Shimmer
import SwiftUI import SwiftUI
public struct AvatarView: View { public struct AvatarView: View {
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@Environment(\.redactionReasons) private var reasons @Environment(\.redactionReasons) private var reasons
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
@ -53,6 +55,12 @@ public struct AvatarView: View {
RoundedRectangle(cornerRadius: size.cornerRadius) RoundedRectangle(cornerRadius: size.cornerRadius)
.fill(.gray) .fill(.gray)
.frame(width: size.size.width, height: size.size.height) .frame(width: size.size.width, height: size.size.height)
} else {
if isInCaptureMode, let image = Nuke.ImagePipeline.shared.cache.cachedImage(for: .init(url: url))?.image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: size.size.width, height: size.size.height)
} else { } else {
LazyImage(url: url) { state in LazyImage(url: url) { state in
if let image = state.image { if let image = state.image {
@ -63,9 +71,11 @@ public struct AvatarView: View {
placeholderView placeholderView
} }
} }
.animation(nil)
.frame(width: size.size.width, height: size.size.height) .frame(width: size.size.width, height: size.size.height)
} }
} }
}
.clipShape(clipShape) .clipShape(clipShape)
.overlay( .overlay(
clipShape.stroke(Color.primary.opacity(0.25), lineWidth: 1) clipShape.stroke(Color.primary.opacity(0.25), lineWidth: 1)

View file

@ -13,6 +13,10 @@ private struct IsCompact: EnvironmentKey {
static let defaultValue: Bool = false static let defaultValue: Bool = false
} }
private struct IsInCaptureMode: EnvironmentKey {
static let defaultValue: Bool = false
}
public extension EnvironmentValues { public extension EnvironmentValues {
var isSecondaryColumn: Bool { var isSecondaryColumn: Bool {
get { self[SecondaryColumnKey.self] } get { self[SecondaryColumnKey.self] }
@ -28,4 +32,9 @@ public extension EnvironmentValues {
get { self[IsCompact.self] } get { self[IsCompact.self] }
set { self[IsCompact.self] = newValue } set { self[IsCompact.self] = newValue }
} }
var isInCaptureMode: Bool {
get { self[IsInCaptureMode.self] }
set { self[IsInCaptureMode.self] = newValue }
}
} }

View file

@ -34,6 +34,7 @@ public enum SheetDestinations: Identifiable {
case settings case settings
case accountPushNotficationsSettings case accountPushNotficationsSettings
case report(status: Status) case report(status: Status)
case shareImage(image: UIImage, status: Status)
public var id: String { public var id: String {
switch self { switch self {
@ -52,6 +53,8 @@ public enum SheetDestinations: Identifiable {
return "statusEditHistory" return "statusEditHistory"
case .report: case .report:
return "report" return "report"
case .shareImage:
return "shareImage"
} }
} }
} }

View file

@ -1,12 +1,15 @@
import DesignSystem import DesignSystem
import Models import Models
import Nuke
import NukeUI import NukeUI
import Shimmer import Shimmer
import SwiftUI import SwiftUI
public struct StatusRowCardView: View { public struct StatusRowCardView: View {
@EnvironmentObject private var theme: Theme
@Environment(\.openURL) private var openURL @Environment(\.openURL) private var openURL
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@EnvironmentObject private var theme: Theme
let card: Card let card: Card
public init(card: Card) { public init(card: Card) {
@ -16,8 +19,10 @@ public struct StatusRowCardView: View {
public var body: some View { public var body: some View {
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) {
if let imageURL = card.image { if let imageURL = card.image, !isInCaptureMode {
GeometryReader { proxy in GeometryReader { proxy in
let processors: [ImageProcessing] = [.resize(size: .init(width: proxy.frame(in: .local).width,
height: 200))]
LazyImage(url: imageURL) { state in LazyImage(url: imageURL) { state in
if let image = state.image { if let image = state.image {
image image
@ -32,6 +37,7 @@ public struct StatusRowCardView: View {
.frame(height: 200) .frame(height: 200)
} }
} }
.processors(processors)
} }
.frame(height: 200) .frame(height: 200)
} }

View file

@ -1,8 +1,13 @@
import Env import Env
import Foundation import Foundation
import SwiftUI import SwiftUI
import DesignSystem
import Network
struct StatusRowContextMenu: View { struct StatusRowContextMenu: View {
@Environment(\.displayScale) var displayScale
@EnvironmentObject private var sceneDelegate: SceneDelegate
@EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var preferences: UserPreferences
@EnvironmentObject private var account: CurrentAccount @EnvironmentObject private var account: CurrentAccount
@EnvironmentObject private var currentInstance: CurrentInstance @EnvironmentObject private var currentInstance: CurrentInstance
@ -56,6 +61,7 @@ struct StatusRowContextMenu: View {
Divider() Divider()
Menu("status.action.share-title") {
if let urlString = viewModel.status.reblog?.url ?? viewModel.status.url, if let urlString = viewModel.status.reblog?.url ?? viewModel.status.url,
let url = URL(string: urlString) let url = URL(string: urlString)
{ {
@ -64,6 +70,37 @@ struct StatusRowContextMenu: View {
message: Text(viewModel.status.reblog?.content.asRawText ?? viewModel.status.content.asRawText)) { message: Text(viewModel.status.reblog?.content.asRawText ?? viewModel.status.content.asRawText)) {
Label("status.action.share", systemImage: "square.and.arrow.up") Label("status.action.share", systemImage: "square.and.arrow.up")
} }
ShareLink(item: url) {
Label("status.action.share-link", systemImage: "link")
}
Button {
let view = HStack {
StatusRowView(viewModel: viewModel)
.padding(16)
}
.environment(\.isInCaptureMode, true)
.environmentObject(Theme.shared)
.environmentObject(preferences)
.environmentObject(account)
.environmentObject(currentInstance)
.environmentObject(SceneDelegate())
.environmentObject(QuickLook())
.environmentObject(viewModel.client)
.preferredColorScheme(Theme.shared.selectedScheme == .dark ? .dark : .light)
.background(Theme.shared.primaryBackgroundColor)
.cornerRadius(4)
.frame(width: sceneDelegate.windowWidth)
let renderer = ImageRenderer(content: view)
renderer.scale = displayScale
if let image = renderer.uiImage {
viewModel.routerPath.presentedSheet = .shareImage(image: image, status: viewModel.status)
}
} label: {
Label("status.action.share-image", systemImage: "photo")
}
}
} }
if let url = URL(string: viewModel.status.reblog?.url ?? viewModel.status.url ?? "") { if let url = URL(string: viewModel.status.reblog?.url ?? viewModel.status.url ?? "") {
@ -144,3 +181,13 @@ struct StatusRowContextMenu: View {
} }
} }
} }
struct ActivityView: UIViewControllerRepresentable {
let image: Image
func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityView>) -> UIActivityViewController {
return UIActivityViewController(activityItems: [image], applicationActivities: nil)
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityView>) {}
}

View file

@ -3,6 +3,7 @@ import Models
import SwiftUI import SwiftUI
struct StatusRowHeaderView: View { struct StatusRowHeaderView: View {
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@EnvironmentObject private var theme: Theme @EnvironmentObject private var theme: Theme
let status: AnyStatus let status: AnyStatus
@ -17,9 +18,11 @@ struct StatusRowHeaderView: View {
} }
.buttonStyle(.plain) .buttonStyle(.plain)
Spacer() Spacer()
if !isInCaptureMode {
threadIcon threadIcon
contextMenuButton contextMenuButton
} }
}
.accessibilityElement() .accessibilityElement()
.accessibilityLabel(Text("\(status.account.displayName)")) .accessibilityLabel(Text("\(status.account.displayName)"))
} }

View file

@ -7,8 +7,9 @@ import SwiftUI
public struct StatusRowMediaPreviewView: View { public struct StatusRowMediaPreviewView: View {
@Environment(\.openURL) private var openURL @Environment(\.openURL) private var openURL
@Environment(\.isSecondaryColumn) private var isSecondaryColumn @Environment(\.isSecondaryColumn) private var isSecondaryColumn: Bool
@Environment(\.extraLeadingInset) private var extraLeadingInset: CGFloat @Environment(\.extraLeadingInset) private var extraLeadingInset: CGFloat
@Environment(\.isInCaptureMode) private var isInCaptureMode: Bool
@EnvironmentObject var sceneDelegate: SceneDelegate @EnvironmentObject var sceneDelegate: SceneDelegate
@EnvironmentObject private var preferences: UserPreferences @EnvironmentObject private var preferences: UserPreferences
@ -150,8 +151,19 @@ public struct StatusRowMediaPreviewView: View {
let size: CGSize = size(for: attachment) ?? .init(width: imageMaxHeight, height: imageMaxHeight) let size: CGSize = size(for: attachment) ?? .init(width: imageMaxHeight, height: imageMaxHeight)
let newSize = imageSize(from: size, let newSize = imageSize(from: size,
newWidth: availableWidth - appLayoutWidth) newWidth: availableWidth - appLayoutWidth)
let processors: [ImageProcessing] = [.resize(size: .init(width: newSize.width, height: newSize.height))]
switch attachment.supportedType { switch attachment.supportedType {
case .image: case .image:
if isInCaptureMode,
let image = Nuke.ImagePipeline.shared.cache.cachedImage(for: .init(url: attachment.url,
processors: processors))?.image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: newSize.width, height: newSize.height)
.clipped()
.cornerRadius(4)
} else {
LazyImage(url: attachment.url) { state in LazyImage(url: attachment.url) { state in
if let image = state.image { if let image = state.image {
image image
@ -168,6 +180,7 @@ public struct StatusRowMediaPreviewView: View {
} }
.processors([.resize(size: .init(width: newSize.width, height: newSize.height))]) .processors([.resize(size: .init(width: newSize.width, height: newSize.height))])
.frame(width: newSize.width, height: newSize.height) .frame(width: newSize.width, height: newSize.height)
}
case .gifv, .video, .audio: case .gifv, .video, .audio:
if let url = attachment.url { if let url = attachment.url {
@ -177,10 +190,10 @@ public struct StatusRowMediaPreviewView: View {
case .none: case .none:
EmptyView() EmptyView()
} }
if sensitive { if !isInCaptureMode, sensitive {
cornerSensitiveButton cornerSensitiveButton
} }
if let alt = attachment.description, !alt.isEmpty, !isNotifications, preferences.showAltTextForMedia { if !isInCaptureMode, let alt = attachment.description, !alt.isEmpty, !isNotifications, preferences.showAltTextForMedia {
Group { Group {
Button { Button {
altTextDisplayed = alt altTextDisplayed = alt
@ -207,7 +220,18 @@ public struct StatusRowMediaPreviewView: View {
switch type { switch type {
case .image: case .image:
let width = isNotifications ? imageMaxHeight : proxy.frame(in: .local).width let width = isNotifications ? imageMaxHeight : proxy.frame(in: .local).width
let processors: [ImageProcessing] = [.resize(size: .init(width: width, height: imageMaxHeight))]
ZStack(alignment: .bottomTrailing) { ZStack(alignment: .bottomTrailing) {
if isInCaptureMode,
let image = Nuke.ImagePipeline.shared.cache.cachedImage(for: .init(url: attachment.previewUrl ?? attachment.url, processors: processors))?.image {
Image(uiImage: image)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(maxWidth: width)
.frame(maxHeight: imageMaxHeight)
.clipped()
.cornerRadius(4)
} else {
LazyImage(url: attachment.previewUrl ?? attachment.url) { state in LazyImage(url: attachment.previewUrl ?? attachment.url) { state in
if let image = state.image { if let image = state.image {
image image
@ -224,11 +248,16 @@ public struct StatusRowMediaPreviewView: View {
.frame(maxWidth: width) .frame(maxWidth: width)
} }
} }
.processors([.resize(size: .init(width: width, height: imageMaxHeight))]) .processors(processors)
if sensitive { }
if sensitive, !isInCaptureMode {
cornerSensitiveButton cornerSensitiveButton
} }
if let alt = attachment.description, !alt.isEmpty, !isNotifications, preferences.showAltTextForMedia { if !isInCaptureMode,
let alt = attachment.description,
!alt.isEmpty,
!isNotifications,
preferences.showAltTextForMedia {
Button { Button {
altTextDisplayed = alt altTextDisplayed = alt
isAltAlertDisplayed = true isAltAlertDisplayed = true