Skip to content

Commit 7b5a75f

Browse files
added a separate view for giphy attachments
1 parent 46ce059 commit 7b5a75f

File tree

7 files changed

+157
-64
lines changed

7 files changed

+157
-64
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//
2+
// Copyright © 2021 Stream.io Inc. All rights reserved.
3+
//
4+
5+
import Nuke
6+
import NukeUI
7+
import StreamChat
8+
import SwiftUI
9+
10+
/// View for the giphy attachments.
11+
public struct GiphyAttachmentView: View {
12+
let message: ChatMessage
13+
let width: CGFloat
14+
let isFirst: Bool
15+
16+
public var body: some View {
17+
ZStack {
18+
if message.text.isEmpty {
19+
LazyGiphyView(
20+
source: message.giphyAttachments[0].previewURL,
21+
width: width
22+
)
23+
.messageBubble(for: message, isFirst: isFirst)
24+
} else {
25+
VStack(spacing: 0) {
26+
LazyGiphyView(
27+
source: message.giphyAttachments[0].previewURL,
28+
width: width
29+
)
30+
31+
HStack {
32+
Text(message.text)
33+
.standardPadding()
34+
Spacer()
35+
}
36+
}
37+
.messageBubble(for: message, isFirst: isFirst)
38+
}
39+
}
40+
.frame(maxWidth: width)
41+
}
42+
}
43+
44+
struct LazyGiphyView: View {
45+
let source: URL
46+
let width: CGFloat
47+
48+
var body: some View {
49+
LazyImage(source: source) { state in
50+
if let imageContainer = state.imageContainer {
51+
Image(imageContainer)
52+
} else if state.error != nil {
53+
Color(.secondarySystemBackground)
54+
} else {
55+
ZStack {
56+
Color(.secondarySystemBackground)
57+
ProgressView()
58+
}
59+
}
60+
}
61+
.onDisappear(.reset)
62+
.processors([ImageProcessors.Resize(width: width)])
63+
.priority(.high)
64+
.aspectRatio(contentMode: .fit)
65+
}
66+
}

Sources/StreamChatSwiftUI/ChatChannel/MessageList/ImageAttachmentView.swift

Lines changed: 82 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,41 +8,47 @@ import StreamChat
88
import SwiftUI
99

1010
public struct ImageAttachmentContainer: View {
11+
@Injected(\.colors) var colors
12+
1113
let message: ChatMessage
1214
let width: CGFloat
1315
let isFirst: Bool
14-
let isGiphy: Bool
1516

1617
public var body: some View {
1718
if message.text.isEmpty {
1819
ImageAttachmentView(
1920
message: message,
20-
width: width,
21-
isGiphy: isGiphy
21+
width: width
2222
)
2323
.messageBubble(for: message, isFirst: isFirst)
2424
} else {
2525
VStack(spacing: 0) {
26-
if hasAttachments {
27-
ImageAttachmentView(
28-
message: message,
29-
width: width,
30-
isGiphy: isGiphy
31-
)
32-
}
33-
26+
ImageAttachmentView(
27+
message: message,
28+
width: width
29+
)
30+
3431
HStack {
3532
Text(message.text)
3633
.standardPadding()
3734
Spacer()
3835
}
36+
.background(Color(backgroundColor))
3937
}
4038
.messageBubble(for: message, isFirst: isFirst)
4139
}
4240
}
4341

44-
private var hasAttachments: Bool {
45-
isGiphy ? !message.giphyAttachments.isEmpty : !message.imageAttachments.isEmpty
42+
private var backgroundColor: UIColor {
43+
if message.isSentByCurrentUser {
44+
if message.type == .ephemeral {
45+
return colors.background8
46+
} else {
47+
return colors.background6
48+
}
49+
} else {
50+
return colors.background8
51+
}
4652
}
4753
}
4854

@@ -53,7 +59,6 @@ struct ImageAttachmentView: View {
5359

5460
let message: ChatMessage
5561
let width: CGFloat
56-
let isGiphy: Bool
5762

5863
private let spacing: CGFloat = 2
5964
private let maxDisplayedImages = 4
@@ -63,26 +68,11 @@ struct ImageAttachmentView: View {
6368
}
6469

6570
private var sources: [URL] {
66-
if isGiphy {
67-
return message.giphyAttachments.map { attachment in
68-
if let state = attachment.uploadingState {
69-
return state.localFileURL
70-
} else {
71-
let url = imageCDN.thumbnailURL(
72-
originalURL: attachment.previewURL,
73-
preferredSize: CGSize(width: width, height: width)
74-
)
75-
76-
return url
77-
}
78-
}
79-
} else {
80-
return message.imageAttachments.map { attachment in
81-
if let state = attachment.uploadingState {
82-
return state.localFileURL
83-
} else {
84-
return attachment.imagePreviewURL
85-
}
71+
message.imageAttachments.map { attachment in
72+
if let state = attachment.uploadingState {
73+
return state.localFileURL
74+
} else {
75+
return attachment.imagePreviewURL
8676
}
8777
}
8878
}
@@ -99,13 +89,15 @@ struct ImageAttachmentView: View {
9989
HStack(spacing: spacing) {
10090
MultiImageView(
10191
source: sources[0],
102-
width: width / 2
92+
width: width / 2,
93+
height: width
10394
)
10495
.withUploadingStateIndicator(for: uploadState(for: 0), url: sources[0])
10596

10697
MultiImageView(
10798
source: sources[1],
108-
width: width / 2
99+
width: width / 2,
100+
height: width
109101
)
110102
.withUploadingStateIndicator(for: uploadState(for: 1), url: sources[1])
111103
}
@@ -114,20 +106,23 @@ struct ImageAttachmentView: View {
114106
HStack(spacing: spacing) {
115107
MultiImageView(
116108
source: sources[0],
117-
width: width / 2
109+
width: width / 2,
110+
height: width
118111
)
119112
.withUploadingStateIndicator(for: uploadState(for: 0), url: sources[0])
120113

121114
VStack(spacing: spacing) {
122115
MultiImageView(
123116
source: sources[1],
124-
width: width / 2
117+
width: width / 2,
118+
height: width / 2
125119
)
126120
.withUploadingStateIndicator(for: uploadState(for: 1), url: sources[1])
127121

128122
MultiImageView(
129123
source: sources[2],
130-
width: width / 2
124+
width: width / 2,
125+
height: width / 2
131126
)
132127
.withUploadingStateIndicator(for: uploadState(for: 2), url: sources[2])
133128
}
@@ -138,28 +133,32 @@ struct ImageAttachmentView: View {
138133
VStack(spacing: spacing) {
139134
MultiImageView(
140135
source: sources[0],
141-
width: width / 2
136+
width: width / 2,
137+
height: width / 2
142138
)
143139
.withUploadingStateIndicator(for: uploadState(for: 0), url: sources[0])
144140

145141
MultiImageView(
146142
source: sources[1],
147-
width: width / 2
143+
width: width / 2,
144+
height: width / 2
148145
)
149146
.withUploadingStateIndicator(for: uploadState(for: 1), url: sources[1])
150147
}
151148

152149
VStack(spacing: spacing) {
153150
MultiImageView(
154151
source: sources[2],
155-
width: width / 2
152+
width: width / 2,
153+
height: width / 2
156154
)
157155
.withUploadingStateIndicator(for: uploadState(for: 2), url: sources[2])
158156

159157
ZStack {
160158
MultiImageView(
161159
source: sources[3],
162-
width: width / 2
160+
width: width / 2,
161+
height: width / 2
163162
)
164163
.withUploadingStateIndicator(for: uploadState(for: 3), url: sources[3])
165164

@@ -171,6 +170,7 @@ struct ImageAttachmentView: View {
171170
.font(fonts.title)
172171
}
173172
}
173+
.frame(width: width / 2, height: width / 2)
174174
}
175175
}
176176
.aspectRatio(1, contentMode: .fill)
@@ -184,11 +184,7 @@ struct ImageAttachmentView: View {
184184
}
185185

186186
private func uploadState(for index: Int) -> AttachmentUploadingState? {
187-
if isGiphy {
188-
return message.giphyAttachments[index].uploadingState
189-
} else {
190-
return message.imageAttachments[index].uploadingState
191-
}
187+
message.imageAttachments[index].uploadingState
192188
}
193189
}
194190

@@ -198,29 +194,40 @@ struct SingleImageView: View {
198194

199195
var body: some View {
200196
LazyLoadingImage(source: source, width: width)
201-
.aspectRatio(contentMode: .fit)
197+
.frame(width: width, height: 3 * width / 4)
202198
}
203199
}
204200

205201
struct MultiImageView: View {
206202
let source: URL
207203
let width: CGFloat
204+
let height: CGFloat
208205

209206
var body: some View {
210207
LazyLoadingImage(source: source, width: width)
211-
.frame(width: width)
208+
.frame(width: width, height: height)
209+
.clipped()
212210
}
213211
}
214212

215213
struct LazyLoadingImage: View {
214+
@Injected(\.utils) var utils
215+
216+
@State private var image: UIImage?
217+
@State private var error: Error?
218+
216219
let source: URL
217220
let width: CGFloat
218221

219222
var body: some View {
220-
LazyImage(source: source) { state in
221-
if let imageContainer = state.imageContainer {
222-
Image(imageContainer)
223-
} else if state.error != nil {
223+
ZStack {
224+
if let image = image {
225+
Image(uiImage: image)
226+
.resizable()
227+
.scaledToFill()
228+
.aspectRatio(contentMode: .fill)
229+
.clipped()
230+
} else if error != nil {
224231
Color(.secondarySystemBackground)
225232
} else {
226233
ZStack {
@@ -229,8 +236,26 @@ struct LazyLoadingImage: View {
229236
}
230237
}
231238
}
232-
.onDisappear(.reset)
233-
.processors([ImageProcessors.Resize(width: width)])
234-
.priority(.high)
239+
.onAppear {
240+
if image != nil {
241+
return
242+
}
243+
244+
utils.imageLoader.loadImage(
245+
url: source,
246+
imageCDN: utils.imageCDN,
247+
resize: true,
248+
preferredSize: CGSize(width: width, height: 3 * width / 4),
249+
completion: { result in
250+
switch result {
251+
case let .success(image):
252+
self.image = image
253+
case let .failure(error):
254+
self.error = error
255+
}
256+
}
257+
)
258+
}
259+
.clipped()
235260
}
236261
}

Sources/StreamChatSwiftUI/ChatChannel/MessageList/MessageAvatarView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public struct MessageAvatarView: View {
3131

3232
LazyImage(source: adjustedURL)
3333
.onDisappear(.reset)
34+
.priority(.normal)
3435
.clipShape(Circle())
3536
.frame(
3637
width: size.width,

Sources/StreamChatSwiftUI/ChatChannel/Reactions/ReactionsOverlayView.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ public struct ReactionsOverlayView<Factory: ViewFactory>: View {
7373
onBackgroundTap()
7474
}
7575
)
76-
.id(viewModel.message.reactionScoresId)
7776
.offset(
7877
x: messageDisplayInfo.frame.origin.x,
7978
y: -24

Sources/StreamChatSwiftUI/DefaultViewFactory.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,21 +126,19 @@ extension ViewFactory {
126126
ImageAttachmentContainer(
127127
message: message,
128128
width: availableWidth,
129-
isFirst: isFirst,
130-
isGiphy: false
129+
isFirst: isFirst
131130
)
132131
}
133132

134133
public func makeGiphyAttachmentView(
135134
for message: ChatMessage,
136135
isFirst: Bool,
137136
availableWidth: CGFloat
138-
) -> ImageAttachmentContainer {
139-
ImageAttachmentContainer(
137+
) -> GiphyAttachmentView {
138+
GiphyAttachmentView(
140139
message: message,
141140
width: availableWidth,
142-
isFirst: isFirst,
143-
isGiphy: true
141+
isFirst: isFirst
144142
)
145143
}
146144

0 commit comments

Comments
 (0)