Fixed issue with double rendering the message body

pull/1061/head
Morgan Pretty 1 week 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
if isMessageFailed {
let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo(
variant: messageViewModel.variant,
hasBeenReadByRecipient: messageViewModel.hasBeenReadByRecipient,
hasAttachments: (messageViewModel.attachments?.isEmpty == false)
) )
.fixedSize(horizontal: false, vertical: true)
.padding(.top, Values.smallSpacing)
.padding(.bottom, Values.verySmallSpacing)
.padding(.horizontal, Values.largeSpacing)
HStack(spacing: 6) {
if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) { if isMessageFailed {
Image(uiImage: image) let (image, statusText, tintColor) = messageViewModel.state.statusIconInfo(
.resizable() variant: messageViewModel.variant,
.scaledToFit() hasBeenReadByRecipient: messageViewModel.hasBeenReadByRecipient,
.foregroundColor(themeColor: tintColor) hasAttachments: (messageViewModel.attachments?.isEmpty == false)
.frame(width: 13, height: 12) )
}
if let statusText: String = statusText { HStack(spacing: 6) {
Text(statusText) if let image: UIImage = image?.withRenderingMode(.alwaysTemplate) {
.font(.system(size: Values.verySmallFontSize)) Image(uiImage: image)
.foregroundColor(themeColor: tintColor) .resizable()
.scaledToFit()
.foregroundColor(themeColor: tintColor)
.frame(width: 13, height: 12)
}
if let statusText: String = statusText {
Text(statusText)
.font(.system(size: Values.verySmallFontSize))
.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
)
if [ .downloaded, .uploaded ].contains(attachment.state) { .aspectRatio(1, contentMode: .fit)
Button { .clipShape(RoundedRectangle(cornerRadius: 15))
self.showMediaFullScreen(attachment: attachment) .padding(.horizontal, Values.largeSpacing)
} label: { }
ZStack {
Circle() if [ .downloaded, .uploaded ].contains(attachment.state) {
.foregroundColor(.init(white: 0, opacity: 0.4)) Button {
Image(systemName: "arrow.up.left.and.arrow.down.right") self.showMediaFullScreen(attachment: attachment)
.font(.system(size: 13)) } label: {
.foregroundColor(.white) ZStack {
Circle()
.foregroundColor(.init(white: 0, opacity: 0.4))
Image(systemName: "arrow.up.left.and.arrow.down.right")
.font(.system(size: 13))
.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)
case .openGroupInvitation: .padding(.top, Self.inset)
OpenGroupInvitationView_SwiftUI( .padding(.horizontal, Self.inset)
name: (linkPreview.title ?? ""), .padding(.bottom, (messageViewModel.body?.isEmpty == false ?
url: linkPreview.url, -Values.smallSpacing :
textColor: bodyLabelTextColor, Self.inset
isOutgoing: (messageViewModel.variant == .standardOutgoing)) ))
}
} }
}
else { if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
if let quote = messageViewModel.quote { for: messageViewModel,
QuoteView_SwiftUI( theme: ThemeManager.currentTheme,
info: .init( primaryColor: ThemeManager.primaryColor,
mode: .regular, textColor: bodyLabelTextColor,
authorId: quote.authorId, searchText: nil,
quotedText: quote.body, using: dependencies
threadVariant: messageViewModel.threadVariant, ) {
currentUserSessionId: messageViewModel.currentUserSessionId, AttributedText(bodyText)
currentUserBlinded15SessionId: messageViewModel.currentUserBlinded15SessionId, .padding(.all, Self.inset)
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)
} }
} }
else {
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText( switch messageViewModel.cellType {
for: messageViewModel, case .mediaMessage:
theme: ThemeManager.currentTheme, if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
primaryColor: ThemeManager.primaryColor, for: messageViewModel,
textColor: bodyLabelTextColor, theme: ThemeManager.currentTheme,
searchText: nil, primaryColor: ThemeManager.primaryColor,
using: dependencies textColor: bodyLabelTextColor,
) { searchText: nil,
AttributedText(bodyText) using: dependencies
.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