Fixed issue with double rendering the message body

pull/1061/head
Morgan Pretty 1 month ago
parent 5d5b7635bd
commit 6ff2bf7047

@ -27,114 +27,148 @@ struct MessageInfoScreen: View {
alignment: .leading, alignment: .leading,
spacing: 10 spacing: 10
) { ) {
// Message bubble snapshot VStack(
MessageBubble( alignment: .leading,
messageViewModel: messageViewModel, spacing: 0
dependencies: dependencies ) {
) // Message bubble snapshot
.background( MessageBubble(
RoundedRectangle(cornerRadius: Self.cornerRadius) messageViewModel: messageViewModel,
.fill( attachmentOnly: false,
themeColor: (messageViewModel.variant == .standardIncoming || messageViewModel.variant == .standardIncomingDeleted || messageViewModel.variant == .standardIncomingDeletedLocally ? dependencies: dependencies
.messageBubble_incomingBackground : )
.messageBubble_outgoingBackground) .background(
) RoundedRectangle(cornerRadius: Self.cornerRadius)
) .fill(
.frame( themeColor: (messageViewModel.variant == .standardIncoming || messageViewModel.variant == .standardIncomingDeleted || messageViewModel.variant == .standardIncomingDeletedLocally ?
maxWidth: .infinity, .messageBubble_incomingBackground :
maxHeight: .infinity, .messageBubble_outgoingBackground)
alignment: .topLeading )
) )
.fixedSize(horizontal: false, vertical: true) .frame(
.padding(.top, Values.smallSpacing) maxWidth: .infinity,
.padding(.bottom, Values.verySmallSpacing) maxHeight: .infinity,
.padding(.horizontal, Values.largeSpacing) alignment: .topLeading
)
.fixedSize(horizontal: false, vertical: true)
.padding(.top, Values.smallSpacing)
.padding(.bottom, Values.verySmallSpacing)
.padding(.horizontal, Values.largeSpacing)
if isMessageFailed { if isMessageFailed {
let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo( let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo(
variant: messageViewModel.variant, variant: messageViewModel.variant,
hasBeenReadByRecipient: messageViewModel.hasBeenReadByRecipient, hasBeenReadByRecipient: messageViewModel.hasBeenReadByRecipient,
hasAttachments: (messageViewModel.attachments?.isEmpty == false) hasAttachments: (messageViewModel.attachments?.isEmpty == false)
) )
HStack(spacing: 6) { HStack(spacing: 6) {
if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) { if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) {
Image(uiImage: image) Image(uiImage: image)
.resizable() .resizable()
.scaledToFit() .scaledToFit()
.foregroundColor(themeColor: tintColor) .foregroundColor(themeColor: tintColor)
.frame(width: 13, height: 12) .frame(width: 13, height: 12)
} }
if let statusText: String = statusText { if let statusText: String = statusText {
Text(statusText) Text(statusText)
.font(.system(size: Values.verySmallFontSize)) .font(.system(size: Values.verySmallFontSize))
.foregroundColor(themeColor: tintColor) .foregroundColor(themeColor: tintColor)
}
} }
.padding(.top, -Values.smallSpacing)
.padding(.bottom, Values.verySmallSpacing)
.padding(.horizontal, Values.largeSpacing)
} }
.padding(.top, -Values.smallSpacing)
.padding(.bottom, Values.verySmallSpacing)
.padding(.horizontal, Values.largeSpacing)
}
if let attachments = messageViewModel.attachments,
messageViewModel.cellType == .mediaMessage
{
let attachment: Attachment = attachments[(index - 1 + attachments.count) % attachments.count]
ZStack(alignment: .bottomTrailing) { if let attachments = messageViewModel.attachments {
if attachments.count > 1 { switch messageViewModel.cellType {
// Attachment carousel view case .mediaMessage:
SessionCarouselView_SwiftUI( let attachment: Attachment = attachments[(index - 1 + attachments.count) % attachments.count]
index: $index,
isOutgoing: (messageViewModel.variant == .standardOutgoing), ZStack(alignment: .bottomTrailing) {
contentInfos: attachments, if attachments.count > 1 {
using: dependencies // Attachment carousel view
) SessionCarouselView_SwiftUI(
.frame( index: $index,
maxWidth: .infinity, isOutgoing: (messageViewModel.variant == .standardOutgoing),
maxHeight: .infinity, contentInfos: attachments,
alignment: .topLeading using: dependencies
) )
} else { .frame(
MediaView_SwiftUI( maxWidth: .infinity,
attachment: attachments[0], maxHeight: .infinity,
isOutgoing: (messageViewModel.variant == .standardOutgoing), alignment: .topLeading
shouldSupressControls: true, )
cornerRadius: 0, } else {
using: dependencies MediaView_SwiftUI(
) attachment: attachments[0],
.frame( isOutgoing: (messageViewModel.variant == .standardOutgoing),
maxWidth: .infinity, shouldSupressControls: true,
maxHeight: .infinity, cornerRadius: 0,
alignment: .topLeading using: dependencies
) )
.aspectRatio(1, contentMode: .fit) .frame(
.clipShape(RoundedRectangle(cornerRadius: 15)) maxWidth: .infinity,
.padding(.horizontal, Values.largeSpacing) maxHeight: .infinity,
} alignment: .topLeading
)
.aspectRatio(1, contentMode: .fit)
.clipShape(RoundedRectangle(cornerRadius: 15))
.padding(.horizontal, Values.largeSpacing)
}
if [ .downloaded, .uploaded ].contains(attachment.state) { if [ .downloaded, .uploaded ].contains(attachment.state) {
Button { Button {
self.showMediaFullScreen(attachment: attachment) self.showMediaFullScreen(attachment: attachment)
} label: { } label: {
ZStack { ZStack {
Circle() Circle()
.foregroundColor(.init(white: 0, opacity: 0.4)) .foregroundColor(.init(white: 0, opacity: 0.4))
Image(systemName: "arrow.up.left.and.arrow.down.right") Image(systemName: "arrow.up.left.and.arrow.down.right")
.font(.system(size: 13)) .font(.system(size: 13))
.foregroundColor(.white) .foregroundColor(.white)
}
.frame(width: 26, height: 26)
}
.padding(.bottom, Values.smallSpacing)
.padding(.trailing, 38)
}
} }
.frame(width: 26, height: 26) .padding(.vertical, Values.verySmallSpacing)
}
.padding(.bottom, Values.smallSpacing) default:
.padding(.trailing, 38) MessageBubble(
messageViewModel: messageViewModel,
attachmentOnly: true,
dependencies: dependencies
)
.background(
RoundedRectangle(cornerRadius: Self.cornerRadius)
.fill(
themeColor: (messageViewModel.variant == .standardIncoming || messageViewModel.variant == .standardIncomingDeleted || messageViewModel.variant == .standardIncomingDeletedLocally ?
.messageBubble_incomingBackground :
.messageBubble_outgoingBackground)
)
)
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .topLeading
)
.fixedSize(horizontal: false, vertical: true)
.padding(.bottom, Values.verySmallSpacing)
.padding(.horizontal, Values.largeSpacing)
} }
} }
.padding(.vertical, Values.verySmallSpacing) }
// Attachment Info
if let attachments = messageViewModel.attachments {
let attachment: Attachment = attachments[(index - 1 + attachments.count) % attachments.count]
// Attachment Info
ZStack { ZStack {
VStack( VStack(
alignment: .leading, alignment: .leading,
@ -381,6 +415,7 @@ struct MessageBubble: View {
static private let inset: CGFloat = 12 static private let inset: CGFloat = 12
let messageViewModel: MessageViewModel let messageViewModel: MessageViewModel
let attachmentOnly: Bool
let dependencies: Dependencies let dependencies: Dependencies
var bodyLabelTextColor: ThemeValue { var bodyLabelTextColor: ThemeValue {
@ -397,124 +432,130 @@ struct MessageBubble: View {
alignment: .leading, alignment: .leading,
spacing: 0 spacing: 0
) { ) {
// FIXME: We should support rendering link previews alongside quotes (bigger refactor) if !attachmentOnly {
if let linkPreview: LinkPreview = messageViewModel.linkPreview { // FIXME: We should support rendering link previews alongside quotes (bigger refactor)
switch linkPreview.variant { if let linkPreview: LinkPreview = messageViewModel.linkPreview {
case .standard: switch linkPreview.variant {
LinkPreviewView_SwiftUI( case .standard:
state: LinkPreview.SentState( LinkPreviewView_SwiftUI(
linkPreview: linkPreview, state: LinkPreview.SentState(
imageAttachment: messageViewModel.linkPreviewAttachment, linkPreview: linkPreview,
using: dependencies imageAttachment: messageViewModel.linkPreviewAttachment,
using: dependencies
),
isOutgoing: (messageViewModel.variant == .standardOutgoing),
maxWidth: maxWidth,
messageViewModel: messageViewModel,
bodyLabelTextColor: bodyLabelTextColor,
lastSearchText: nil
)
case .openGroupInvitation:
OpenGroupInvitationView_SwiftUI(
name: (linkPreview.title ?? ""),
url: linkPreview.url,
textColor: bodyLabelTextColor,
isOutgoing: (messageViewModel.variant == .standardOutgoing))
}
}
else {
if let quote = messageViewModel.quote {
QuoteView_SwiftUI(
info: .init(
mode: .regular,
authorId: quote.authorId,
quotedText: quote.body,
threadVariant: messageViewModel.threadVariant,
currentUserSessionId: messageViewModel.currentUserSessionId,
currentUserBlinded15SessionId: messageViewModel.currentUserBlinded15SessionId,
currentUserBlinded25SessionId: messageViewModel.currentUserBlinded25SessionId,
direction: (messageViewModel.variant == .standardOutgoing ? .outgoing : .incoming),
attachment: messageViewModel.quoteAttachment
), ),
isOutgoing: (messageViewModel.variant == .standardOutgoing), using: dependencies
maxWidth: maxWidth,
messageViewModel: messageViewModel,
bodyLabelTextColor: bodyLabelTextColor,
lastSearchText: nil
) )
.fixedSize(horizontal: false, vertical: true)
.padding(.top, Self.inset)
.padding(.horizontal, Self.inset)
.padding(.bottom, (messageViewModel.body?.isEmpty == false ?
-Values.smallSpacing :
Self.inset
))
}
}
case .openGroupInvitation: if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
OpenGroupInvitationView_SwiftUI( for: messageViewModel,
name: (linkPreview.title ?? ""), theme: ThemeManager.currentTheme,
url: linkPreview.url, primaryColor: ThemeManager.primaryColor,
textColor: bodyLabelTextColor, textColor: bodyLabelTextColor,
isOutgoing: (messageViewModel.variant == .standardOutgoing)) searchText: nil,
using: dependencies
) {
AttributedText(bodyText)
.padding(.all, Self.inset)
} }
} }
else { else {
if let quote = messageViewModel.quote { switch messageViewModel.cellType {
QuoteView_SwiftUI( case .mediaMessage:
info: .init( if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
mode: .regular, for: messageViewModel,
authorId: quote.authorId, theme: ThemeManager.currentTheme,
quotedText: quote.body, primaryColor: ThemeManager.primaryColor,
threadVariant: messageViewModel.threadVariant, textColor: bodyLabelTextColor,
currentUserSessionId: messageViewModel.currentUserSessionId, searchText: nil,
currentUserBlinded15SessionId: messageViewModel.currentUserBlinded15SessionId, using: dependencies
currentUserBlinded25SessionId: messageViewModel.currentUserBlinded25SessionId,
direction: (messageViewModel.variant == .standardOutgoing ? .outgoing : .incoming),
attachment: messageViewModel.quoteAttachment
),
using: dependencies
)
.fixedSize(horizontal: false, vertical: true)
.padding(.top, Self.inset)
.padding(.horizontal, Self.inset)
.padding(.bottom, -Values.smallSpacing)
}
}
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
for: messageViewModel,
theme: ThemeManager.currentTheme,
primaryColor: ThemeManager.primaryColor,
textColor: bodyLabelTextColor,
searchText: nil,
using: dependencies
) {
AttributedText(bodyText)
.padding(.all, Self.inset)
}
switch messageViewModel.cellType {
case .mediaMessage:
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
for: messageViewModel,
theme: ThemeManager.currentTheme,
primaryColor: ThemeManager.primaryColor,
textColor: bodyLabelTextColor,
searchText: nil,
using: dependencies
) {
AttributedText(bodyText)
.padding(.all, Self.inset)
}
case .voiceMessage:
if let attachment: Attachment = messageViewModel.attachments?.first(where: { $0.isAudio }){
// TODO: Playback Info and check if playing function is needed
VoiceMessageView_SwiftUI(attachment: attachment)
}
case .audio, .genericAttachment:
if let attachment: Attachment = messageViewModel.attachments?.first {
VStack(
alignment: .leading,
spacing: Values.smallSpacing
) { ) {
DocumentView_SwiftUI( AttributedText(bodyText)
maxWidth: $maxWidth, .padding(.all, Self.inset)
attachment: attachment, }
textColor: bodyLabelTextColor case .voiceMessage:
) if let attachment: Attachment = messageViewModel.attachments?.first(where: { $0.isAudio }){
.modifier(MaxWidthEqualizer.notify) // TODO: Playback Info and check if playing function is needed
.frame( VoiceMessageView_SwiftUI(attachment: attachment)
width: maxWidth, }
alignment: .leading case .audio, .genericAttachment:
) if let attachment: Attachment = messageViewModel.attachments?.first {
VStack(
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText( alignment: .leading,
for: messageViewModel, spacing: Values.smallSpacing
theme: ThemeManager.currentTheme,
primaryColor: ThemeManager.primaryColor,
textColor: bodyLabelTextColor,
searchText: nil,
using: dependencies
) { ) {
ZStack{ DocumentView_SwiftUI(
AttributedText(bodyText) maxWidth: $maxWidth,
.padding(.horizontal, Self.inset) attachment: attachment,
.padding(.bottom, Self.inset) textColor: bodyLabelTextColor
} )
.modifier(MaxWidthEqualizer.notify) .modifier(MaxWidthEqualizer.notify)
.frame( .frame(
width: maxWidth, width: maxWidth,
alignment: .leading alignment: .leading
) )
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
for: messageViewModel,
theme: ThemeManager.currentTheme,
primaryColor: ThemeManager.primaryColor,
textColor: bodyLabelTextColor,
searchText: nil,
using: dependencies
) {
ZStack{
AttributedText(bodyText)
.padding(.horizontal, Self.inset)
.padding(.bottom, Self.inset)
}
.modifier(MaxWidthEqualizer.notify)
.frame(
width: maxWidth,
alignment: .leading
)
}
} }
.modifier(MaxWidthEqualizer(width: $maxWidth))
} }
.modifier(MaxWidthEqualizer(width: $maxWidth)) default: EmptyView()
} }
default: EmptyView()
} }
} }
} }

Loading…
Cancel
Save