Skip to content

Commit ecd7910

Browse files
committed
[iOS] Fix photo message UI
1 parent ffab43b commit ecd7910

File tree

1 file changed

+136
-21
lines changed

1 file changed

+136
-21
lines changed

apple/InlineIOS/Chat/UIMessageView.swift

+136-21
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@ class UIMessageView: UIView {
6161
label.font = .systemFont(ofSize: 18)
6262
label.textColor = textColor
6363
label.numberOfLines = 0
64-
// label.setContentHuggingPriority(.defaultLow, for: .horizontal)
65-
// label.setContentCompressionResistancePriority(.required, for: .horizontal)
64+
6665
return label
6766
}()
6867

@@ -105,11 +104,7 @@ class UIMessageView: UIView {
105104
}
106105

107106
private var isMultiline: Bool {
108-
if let file = fullMessage.file,
109-
let width = file.width,
110-
let height = file.height,
111-
height > width && width < 250
112-
{
107+
if fullMessage.file != nil {
113108
return true
114109
}
115110

@@ -181,23 +176,63 @@ class UIMessageView: UIView {
181176

182177
private func setupMessageContainer() {
183178
if isMultiline {
184-
multiLineContainer.addArrangedSubview(messageLabel)
179+
setupMultilineMessage()
180+
} else {
181+
setupSingleLineMessage()
182+
}
183+
}
184+
185+
private func setupMultilineMessage() {
186+
if message.hasFile, message.hasText {
187+
let innerContainer = UIStackView()
188+
innerContainer.axis = .vertical
189+
innerContainer.translatesAutoresizingMaskIntoConstraints = false
190+
innerContainer.layoutMargins = UIEdgeInsets(
191+
top: 0,
192+
left: StackPadding.leading,
193+
bottom: 0,
194+
right: StackPadding.trailing
195+
)
196+
innerContainer.spacing = 10
197+
innerContainer.isLayoutMarginsRelativeArrangement = true
198+
innerContainer.insetsLayoutMarginsFromSafeArea = false
199+
200+
innerContainer.addArrangedSubview(messageLabel)
185201

186202
let metadataContainer = UIStackView()
187203
metadataContainer.axis = .horizontal
188-
metadataContainer.addArrangedSubview(UIView()) // Spacer
204+
metadataContainer.translatesAutoresizingMaskIntoConstraints = false
205+
metadataContainer.addArrangedSubview(UIView())
189206
metadataContainer.addArrangedSubview(metadataView)
190-
multiLineContainer.addArrangedSubview(metadataContainer)
207+
innerContainer.addArrangedSubview(metadataContainer)
191208

192-
containerStack.addArrangedSubview(multiLineContainer)
193-
} else {
194-
singleLineContainer.addArrangedSubview(messageLabel)
195-
singleLineContainer.addArrangedSubview(metadataView)
209+
multiLineContainer.addArrangedSubview(innerContainer)
196210

197-
containerStack.addArrangedSubview(singleLineContainer)
211+
containerStack.addArrangedSubview(innerContainer)
212+
} else {
213+
multiLineContainer.addArrangedSubview(messageLabel)
214+
if !message.hasFile || message.hasText {
215+
setupMultilineMetadata()
216+
containerStack.addArrangedSubview(multiLineContainer)
217+
return
218+
}
198219
}
199220
}
200221

222+
private func setupMultilineMetadata() {
223+
let metadataContainer = UIStackView()
224+
metadataContainer.axis = .horizontal
225+
metadataContainer.addArrangedSubview(UIView()) // Spacer
226+
metadataContainer.addArrangedSubview(metadataView)
227+
multiLineContainer.addArrangedSubview(metadataContainer)
228+
}
229+
230+
private func setupSingleLineMessage() {
231+
singleLineContainer.addArrangedSubview(messageLabel)
232+
singleLineContainer.addArrangedSubview(metadataView)
233+
containerStack.addArrangedSubview(singleLineContainer)
234+
}
235+
201236
private func addGestureRecognizer() {
202237
bubbleView.isUserInteractionEnabled = true
203238
messageLabel.isUserInteractionEnabled = true
@@ -206,29 +241,98 @@ class UIMessageView: UIView {
206241
bubbleView.addGestureRecognizer(tapGesture)
207242
}
208243

244+
enum StackPadding {
245+
static let top: CGFloat = 9
246+
static let leading: CGFloat = 12
247+
static let bottom: CGFloat = 9
248+
static let trailing: CGFloat = 12
249+
}
250+
209251
private func setupConstraints() {
210-
NSLayoutConstraint.activate([
252+
let padding = NSDirectionalEdgeInsets(
253+
top: StackPadding.top,
254+
leading: StackPadding.leading,
255+
bottom: isMultiline ? 14 : StackPadding.bottom,
256+
trailing: StackPadding.trailing
257+
)
258+
259+
let baseConstraints: [NSLayoutConstraint] = [
211260
bubbleView.topAnchor.constraint(equalTo: topAnchor),
212261
bubbleView.bottomAnchor.constraint(equalTo: bottomAnchor),
213262
bubbleView.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor, multiplier: 0.9),
263+
]
264+
265+
let withoutFileConstraints: [NSLayoutConstraint] = [
266+
containerStack.topAnchor.constraint(
267+
equalTo: bubbleView.topAnchor,
268+
constant: padding.top
269+
),
270+
containerStack.leadingAnchor.constraint(
271+
equalTo: bubbleView.leadingAnchor,
272+
constant: padding.leading
273+
),
274+
containerStack.trailingAnchor.constraint(
275+
equalTo: bubbleView.trailingAnchor,
276+
constant: -padding.trailing
277+
),
278+
containerStack.bottomAnchor.constraint(
279+
equalTo: bubbleView.bottomAnchor,
280+
constant: -padding.bottom
281+
).withPriority(.defaultHigh),
282+
]
214283

284+
let withFileConstraints: [NSLayoutConstraint] = [
215285
containerStack.topAnchor.constraint(
216286
equalTo: bubbleView.topAnchor,
217-
constant: labelVerticalPadding
287+
constant: 0
218288
),
219289
containerStack.leadingAnchor.constraint(
220290
equalTo: bubbleView.leadingAnchor,
221-
constant: labelHorizantalPadding
291+
constant: 0
222292
),
223293
containerStack.trailingAnchor.constraint(
224294
equalTo: bubbleView.trailingAnchor,
225-
constant: -labelHorizantalPadding
295+
constant: 0
226296
),
227297
containerStack.bottomAnchor.constraint(
228298
equalTo: bubbleView.bottomAnchor,
229-
constant: isMultiline ? -14 : -labelVerticalPadding
299+
constant: 0
230300
).withPriority(.defaultHigh),
231-
])
301+
]
302+
303+
let withFileAndTextConstraints: [NSLayoutConstraint] = [
304+
containerStack.topAnchor.constraint(
305+
equalTo: bubbleView.topAnchor,
306+
constant: 0
307+
),
308+
containerStack.leadingAnchor.constraint(
309+
equalTo: bubbleView.leadingAnchor,
310+
constant: 0
311+
),
312+
containerStack.trailingAnchor.constraint(
313+
equalTo: bubbleView.trailingAnchor,
314+
constant: 0
315+
),
316+
containerStack.bottomAnchor.constraint(
317+
equalTo: bubbleView.bottomAnchor,
318+
constant: -padding.bottom
319+
).withPriority(.defaultHigh),
320+
]
321+
322+
let constraints: [NSLayoutConstraint] = switch (message.hasFile, message.hasText) {
323+
case (true, false):
324+
// File only
325+
withFileConstraints
326+
case (true, true):
327+
// File with text
328+
withFileAndTextConstraints
329+
default:
330+
// Text only
331+
withoutFileConstraints
332+
}
333+
334+
NSLayoutConstraint.activate(baseConstraints + constraints)
335+
232336
if outgoing {
233337
bubbleView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8).isActive = true
234338
} else {
@@ -575,3 +679,14 @@ extension String {
575679
contains { $0.isEmoji }
576680
}
577681
}
682+
683+
extension Message {
684+
var hasFile: Bool {
685+
fileId != nil
686+
}
687+
688+
var hasText: Bool {
689+
guard let text else { return false }
690+
return !text.isEmpty
691+
}
692+
}

0 commit comments

Comments
 (0)