diff --git a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3fcadd06..db994717 100644 --- a/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/IceCubesApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -18,6 +18,15 @@ "revision" : "32a99b537d1c6f3529a08257c28a5feb70c0c5af" } }, + { + "identity" : "nuke", + "kind" : "remoteSourceControl", + "location" : "https://github.com/kean/Nuke", + "state" : { + "revision" : "1e7395a8931ad19659fd1e10137a862b9c1e2a38", + "version" : "11.5.0" + } + }, { "identity" : "swiftui-shimmer", "kind" : "remoteSourceControl", diff --git a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift index 4503be36..8355bdbe 100644 --- a/Packages/Account/Sources/Account/AccountDetailHeaderView.swift +++ b/Packages/Account/Sources/Account/AccountDetailHeaderView.swift @@ -2,6 +2,9 @@ import SwiftUI import Models import DesignSystem import Env +import Shimmer +import Nuke +import NukeUI struct AccountDetailHeaderView: View { @EnvironmentObject private var theme: Theme @@ -29,20 +32,21 @@ struct AccountDetailHeaderView: View { private var headerImageView: some View { GeometryReader { proxy in ZStack(alignment: .bottomTrailing) { - AsyncImage( - url: account.header, - content: { image in - image.resizable() - .aspectRatio(contentMode: .fill) + LazyImage(url: account.header) { state in + if let image = state.image { + image + .resizingMode(.aspectFill) + } else if state.isLoading { + Color.gray .frame(height: bannerHeight) - .frame(width: proxy.frame(in: .local).width) - .clipped() - }, - placeholder: { + .shimmering() + } else { Color.gray .frame(height: bannerHeight) } - ) + } + .frame(height: bannerHeight) + if relationship?.followedBy == true { Text("Follows You") .font(.footnote) diff --git a/Packages/DesignSystem/Package.swift b/Packages/DesignSystem/Package.swift index ff0bf80a..71d325bd 100644 --- a/Packages/DesignSystem/Package.swift +++ b/Packages/DesignSystem/Package.swift @@ -16,14 +16,16 @@ let package = Package( dependencies: [ .package(name: "Models", path: "../Models"), .package(name: "Env", path: "../Env"), - .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0")], + .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0"), + .package(url: "https://github.com/kean/Nuke", from: "11.5.0")], targets: [ .target( name: "DesignSystem", dependencies: [ .product(name: "Models", package: "Models"), .product(name: "Env", package: "Env"), - .product(name: "Shimmer", package: "SwiftUI-Shimmer") + .product(name: "Shimmer", package: "SwiftUI-Shimmer"), + .product(name: "NukeUI", package: "Nuke") ]), ] ) diff --git a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift index b7b26f62..442691b1 100644 --- a/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift +++ b/Packages/DesignSystem/Sources/DesignSystem/Views/AvatarView.swift @@ -1,5 +1,7 @@ import SwiftUI import Shimmer +import NukeUI +import Nuke public struct AvatarView: View { public enum Size { @@ -41,22 +43,20 @@ public struct AvatarView: View { .fill(.gray) .frame(maxWidth: size.size.width, maxHeight: size.size.height) } else { - AsyncImage(url: url) { phase in - switch phase { - case .empty: + LazyImage(url: url) { state in + if let image = state.image { + image + .resizingMode(.aspectFit) + } else if state.isLoading { placeholderView .shimmering() - case let .success(image): - image.resizable() - .aspectRatio(contentMode: .fit) - .cornerRadius(size.cornerRadius) - .frame(maxWidth: size.size.width, maxHeight: size.size.height) - case .failure: - placeholderView - @unknown default: + } else { placeholderView } } + .processors([ImageProcessors.Resize(size: size.size), + ImageProcessors.RoundedCorners(radius: size.cornerRadius)]) + .frame(width: size.size.width, height: size.size.height) } } diff --git a/Packages/Explore/Package.swift b/Packages/Explore/Package.swift index 306d72e9..850e1ea4 100644 --- a/Packages/Explore/Package.swift +++ b/Packages/Explore/Package.swift @@ -19,7 +19,7 @@ let package = Package( .package(name: "Models", path: "../Models"), .package(name: "Env", path: "../Env"), .package(name: "Status", path: "../Status"), - .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0") + .package(name: "DesignSystem", path: "../DesignSystem"), ], targets: [ .target( @@ -30,7 +30,7 @@ let package = Package( .product(name: "Models", package: "Models"), .product(name: "Env", package: "Env"), .product(name: "Status", package: "Status"), - .product(name: "Shimmer", package: "SwiftUI-Shimmer") + .product(name: "DesignSystem", package: "DesignSystem") ]) ] ) diff --git a/Packages/Models/Sources/Models/Ext/AccountExt.swift b/Packages/Models/Sources/Models/Ext/AccountExt.swift index fd675f9e..0a5e2f0d 100644 --- a/Packages/Models/Sources/Models/Ext/AccountExt.swift +++ b/Packages/Models/Sources/Models/Ext/AccountExt.swift @@ -1,23 +1,27 @@ import Foundation import SwiftUI +import Nuke +import NukeUI +@MainActor extension Account { public var displayNameWithEmojis: some View { let splittedDisplayName = displayName.split(separator: ":") return HStack(spacing: 0) { ForEach(splittedDisplayName, id: \.self) { part in if let emoji = emojis.first(where: { $0.shortcode == part }) { - AsyncImage( - url: emoji.url, - content: { image in - image.resizable() - .aspectRatio(contentMode: .fit) - .frame(maxWidth: 20, maxHeight: 20) - }, - placeholder: { + LazyImage(url: emoji.url) { state in + if let image = state.image { + image + .resizingMode(.aspectFit) + } else if state.isLoading { + ProgressView() + } else { ProgressView() } - ) + } + .processors([ImageProcessors.Resize(size: .init(width: 20, height: 20))]) + .frame(width: 20, height: 20) } else { Text(part) } diff --git a/Packages/Notifications/Package.swift b/Packages/Notifications/Package.swift index 4e81af01..c626ec86 100644 --- a/Packages/Notifications/Package.swift +++ b/Packages/Notifications/Package.swift @@ -18,7 +18,7 @@ let package = Package( .package(name: "Models", path: "../Models"), .package(name: "Env", path: "../Env"), .package(name: "Status", path: "../Status"), - .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0") + .package(name: "DesignSystem", path: "../DesignSystem"), ], targets: [ .target( @@ -28,7 +28,7 @@ let package = Package( .product(name: "Models", package: "Models"), .product(name: "Env", package: "Env"), .product(name: "Status", package: "Status"), - .product(name: "Shimmer", package: "SwiftUI-Shimmer") + .product(name: "DesignSystem", package: "DesignSystem") ]), ] ) diff --git a/Packages/Status/Package.swift b/Packages/Status/Package.swift index d6dc36e1..08b4b885 100644 --- a/Packages/Status/Package.swift +++ b/Packages/Status/Package.swift @@ -18,7 +18,6 @@ let package = Package( .package(name: "Network", path: "../Network"), .package(name: "Env", path: "../Env"), .package(name: "DesignSystem", path: "../DesignSystem"), - .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0"), .package(url: "https://github.com/Dimillian/TextView", branch: "main") ], targets: [ @@ -29,7 +28,6 @@ let package = Package( .product(name: "Network", package: "Network"), .product(name: "Env", package: "Env"), .product(name: "DesignSystem", package: "DesignSystem"), - .product(name: "Shimmer", package: "SwiftUI-Shimmer"), .product(name: "TextView", package: "TextView") ]), ] diff --git a/Packages/Status/Sources/Status/Row/StatusCardView.swift b/Packages/Status/Sources/Status/Row/StatusCardView.swift index 1359bdb1..ac7694c1 100644 --- a/Packages/Status/Sources/Status/Row/StatusCardView.swift +++ b/Packages/Status/Sources/Status/Row/StatusCardView.swift @@ -1,6 +1,8 @@ import SwiftUI import Models import Shimmer +import Nuke +import NukeUI public struct StatusCardView: View { @Environment(\.openURL) private var openURL @@ -14,21 +16,18 @@ public struct StatusCardView: View { if let title = card.title { VStack(alignment: .leading) { if let imageURL = card.image { - AsyncImage( - url: imageURL, - content: { image in - image.resizable() - .aspectRatio(contentMode: .fill) - .frame(maxHeight: 200) - .clipped() - }, - placeholder: { + LazyImage(url: imageURL) { state in + if let image = state.image { + image + .resizingMode(.aspectFill) + } else if state.isLoading { Rectangle() .fill(Color.gray) .frame(height: 200) .shimmering() } - ) + } + .frame(height: 200) } Spacer() HStack { diff --git a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift index d2ca076e..65c69975 100644 --- a/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift +++ b/Packages/Status/Sources/Status/Row/StatusMediaPreviewView.swift @@ -2,6 +2,8 @@ import SwiftUI import Models import Env import Shimmer +import Nuke +import NukeUI public struct StatusMediaPreviewView: View { @EnvironmentObject private var quickLook: QuickLook @@ -89,24 +91,21 @@ public struct StatusMediaPreviewView: View { GeometryReader { proxy in switch type { case .image: - AsyncImage( - url: attachement.url, - content: { image in + LazyImage(url: attachement.url) { state in + if let image = state.image { image - .resizable() - .aspectRatio(contentMode: attachements.count == 1 ? .fit : .fill) - .frame(height: imageMaxHeight) - .frame(width: proxy.frame(in: .local).width) + .resizingMode(.aspectFill) .cornerRadius(4) - }, - placeholder: { + } else if state.isLoading { RoundedRectangle(cornerRadius: 4) .fill(Color.gray) .frame(maxHeight: imageMaxHeight) .frame(width: proxy.frame(in: .local).width) .shimmering() } - ) + } + .frame(width: proxy.frame(in: .local).width) + .frame(height: imageMaxHeight) case .gifv: VideoPlayerView(viewModel: .init(url: attachement.url)) .frame(width: proxy.frame(in: .local).width) diff --git a/Packages/Timeline/Package.swift b/Packages/Timeline/Package.swift index 3f9edd01..2d617052 100644 --- a/Packages/Timeline/Package.swift +++ b/Packages/Timeline/Package.swift @@ -18,7 +18,7 @@ let package = Package( .package(name: "Models", path: "../Models"), .package(name: "Env", path: "../Env"), .package(name: "Status", path: "../Status"), - .package(url: "https://github.com/markiv/SwiftUI-Shimmer", exact: "1.1.0") + .package(name: "DesignSystem", path: "../DesignSystem"), ], targets: [ .target( @@ -28,7 +28,7 @@ let package = Package( .product(name: "Models", package: "Models"), .product(name: "Env", package: "Env"), .product(name: "Status", package: "Status"), - .product(name: "Shimmer", package: "SwiftUI-Shimmer") + .product(name: "DesignSystem", package: "DesignSystem") ]), .testTarget( name: "TimelineTests",