Skip to content

Commit 7dcbfec

Browse files
authored
Jetpack Social: Use AsyncImage to download social icons (#22527)
2 parents 1fb4f59 + 1a68605 commit 7dcbfec

1 file changed

Lines changed: 37 additions & 38 deletions

File tree

WordPress/Classes/ViewRelated/Jetpack/Social/JetpackSocialNoConnectionView.swift

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import SwiftUI
22

33
struct JetpackSocialNoConnectionView: View {
44

5-
@StateObject private var viewModel: JetpackSocialNoConnectionViewModel
5+
private let viewModel: JetpackSocialNoConnectionViewModel
66

77
var body: some View {
88
VStack(alignment: .leading, spacing: 12.0) {
99
HStack(spacing: -5.0) {
1010
ForEach(viewModel.icons, id: \.self) { icon in
11-
iconImage(icon)
11+
iconImage(image: icon.image, url: icon.url)
1212
}
1313
}
1414
.accessibilityElement()
@@ -39,13 +39,14 @@ struct JetpackSocialNoConnectionView: View {
3939
.background(Color(viewModel.preferredBackgroundColor))
4040
}
4141

42-
func iconImage(_ image: UIImage) -> some View {
43-
Image(uiImage: image)
44-
.resizable()
45-
.frame(width: 32.0, height: 32.0)
46-
.background(Color(viewModel.preferredBackgroundColor))
47-
.clipShape(Circle())
48-
.overlay(Circle().stroke(Color(viewModel.preferredBackgroundColor), lineWidth: 2.0))
42+
func iconImage(image: UIImage, url: URL?) -> some View {
43+
AsyncImage(url: url) { image in
44+
image
45+
.icon(backgroundColor: viewModel.preferredBackgroundColor)
46+
} placeholder: {
47+
Image(uiImage: image)
48+
.icon(backgroundColor: viewModel.preferredBackgroundColor)
49+
}
4950
}
5051
}
5152

@@ -60,16 +61,35 @@ extension JetpackSocialNoConnectionView {
6061
}
6162
}
6263

64+
// MARK: - Image Extension
65+
66+
private extension Image {
67+
func icon(backgroundColor: UIColor) -> some View {
68+
self
69+
.resizable()
70+
.frame(width: 32.0, height: 32.0)
71+
.background(Color(backgroundColor))
72+
.clipShape(Circle())
73+
.overlay(Circle().stroke(Color(backgroundColor), lineWidth: 2.0))
74+
}
75+
}
76+
6377
// MARK: - View model
6478

65-
class JetpackSocialNoConnectionViewModel: ObservableObject {
79+
struct JetpackSocialNoConnectionViewModel {
80+
81+
struct IconInfo: Hashable {
82+
let image: UIImage
83+
let url: URL?
84+
}
85+
6686
let padding: EdgeInsets
6787
let hideNotNow: Bool
6888
let preferredBackgroundColor: UIColor
6989
let bodyTextColor: UIColor
7090
let onConnectTap: (() -> Void)?
7191
let onNotNowTap: (() -> Void)?
72-
@MainActor @Published var icons: [UIImage] = [UIImage()]
92+
let icons: [IconInfo]
7393

7494
init(services: [PublicizeService] = [],
7595
padding: EdgeInsets = Constants.defaultPadding,
@@ -84,37 +104,16 @@ class JetpackSocialNoConnectionViewModel: ObservableObject {
84104
self.bodyTextColor = bodyTextColor
85105
self.onConnectTap = onConnectTap
86106
self.onNotNowTap = onNotNowTap
87-
updateIcons(services)
88-
}
89107

90-
private func updateIcons(_ services: [PublicizeService]) {
91-
var icons: [UIImage] = []
92-
var downloadTasks: [(url: URL, index: Int)] = []
93-
for (index, service) in services.enumerated() {
108+
var images = [IconInfo]()
109+
for service in services {
94110
let icon = WPStyleGuide.socialIcon(for: service.serviceID as NSString)
95-
icons.append(icon)
96-
97-
if service.name == .unknown {
98-
guard let iconUrl = URL(string: service.icon) else {
99-
continue
100-
}
101-
downloadTasks.append((url: iconUrl, index: index))
102-
}
103-
}
104-
105-
DispatchQueue.main.async {
106-
self.icons = icons
107-
108-
for task in downloadTasks {
109-
let (url, index) = task
110-
Task { @MainActor in
111-
if let image = try? await ImageDownloader.shared.image(from: url) {
112-
self.icons[index] = image
113-
}
114-
}
115-
}
111+
let url: URL? = service.name == .unknown ? URL(string: service.icon) : nil
112+
images.append(IconInfo(image: icon, url: url))
116113
}
114+
self.icons = images
117115
}
116+
118117
}
119118

120119
// MARK: - Constants

0 commit comments

Comments
 (0)