fix the document message in message info screen

pull/874/head
Ryan ZHAO 1 year ago
parent 408c889926
commit d1fa40c52e

@ -5,12 +5,15 @@ import SessionUIKit
import SessionMessagingKit
struct DocumentView_SwiftUI: View {
@Binding private var maxWidth: CGFloat?
static private let inset: CGFloat = 12
private let attachment: Attachment
private let textColor: ThemeValue
public init(attachment: Attachment, textColor: ThemeValue) {
public init(maxWidth: Binding<CGFloat?>, attachment: Attachment, textColor: ThemeValue) {
self._maxWidth = maxWidth
self.attachment = attachment
self.textColor = textColor
}
@ -51,6 +54,10 @@ struct DocumentView_SwiftUI: View {
.lineLimit(1)
.font(.system(size: Values.mediumFontSize))
.foregroundColor(themeColor: textColor)
.frame(
maxWidth: maxWidth,
alignment: .leading
)
Text(attachment.documentFileInfo)
.font(.system(size: Values.verySmallFontSize))
@ -64,13 +71,17 @@ struct DocumentView_SwiftUI: View {
.foregroundColor(themeColor: textColor)
.padding(.trailing, Self.inset)
}
.frame(width: maxWidth)
}
}
struct DocumentView_SwiftUI_Previews: PreviewProvider {
@State static private var maxWidth: CGFloat? = 200
static var previews: some View {
VStack {
DocumentView_SwiftUI(
maxWidth: $maxWidth,
attachment: Attachment(
variant: .standard,
contentType: "audio/mp4",
@ -78,12 +89,10 @@ struct DocumentView_SwiftUI_Previews: PreviewProvider {
),
textColor: .messageBubble_outgoingText
)
.frame(
width: 200,
height: 58
)
.frame(height: 58)
DocumentView_SwiftUI(
maxWidth: $maxWidth,
attachment: Attachment(
variant: .standard,
contentType: "txt",
@ -91,10 +100,7 @@ struct DocumentView_SwiftUI_Previews: PreviewProvider {
),
textColor: .messageBubble_outgoingText
)
.frame(
width: 200,
height: 58
)
.frame(height: 58)
}
}
}

@ -367,6 +367,8 @@ struct MessageInfoScreen: View {
}
struct MessageBubble: View {
@State private var maxWidth: CGFloat?
static private let cornerRadius: CGFloat = 18
static private let inset: CGFloat = 12
@ -462,8 +464,20 @@ struct MessageBubble: View {
}
case .audio, .genericAttachment:
if let attachment: Attachment = messageViewModel.attachments?.first {
VStack(spacing: Values.smallSpacing) {
DocumentView_SwiftUI(attachment: attachment, textColor: bodyLabelTextColor)
VStack(
alignment: .leading,
spacing: Values.smallSpacing
) {
DocumentView_SwiftUI(
maxWidth: $maxWidth,
attachment: attachment,
textColor: bodyLabelTextColor
)
.modifier(MaxWidthEqualizer.notify)
.frame(
width: maxWidth,
alignment: .leading
)
if let bodyText: NSAttributedString = VisibleMessageCell.getBodyAttributedText(
for: messageViewModel,
@ -474,11 +488,17 @@ struct MessageBubble: View {
) {
ZStack{
AttributedText(bodyText)
.padding(.horizontal, Self.inset)
.padding(.bottom, Self.inset)
}
.padding(.horizontal, Self.inset)
.padding(.bottom, Self.inset)
.modifier(MaxWidthEqualizer.notify)
.frame(
width: maxWidth,
alignment: .leading
)
}
}
.modifier(MaxWidthEqualizer(width: $maxWidth))
}
default: EmptyView()
}

@ -38,3 +38,54 @@ public struct UIView_SwiftUI: UIViewRepresentable {
uiView.layoutIfNeeded()
}
}
// MARK: MaxWidthEqualizer
/// PreferenceKey to report the max width of the view.
struct MaxWidthPreferenceKey: PreferenceKey {
static var defaultValue: CGFloat = 0.0
// We `reduce` to just take the max value from all values reported.
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = max(value, nextValue())
}
}
/// Convenience view modifier that observe its size, and notify the value back to parent view via `MaxWidthPreferenceKey`.
public struct MaxWidthNotify: ViewModifier {
/// We embed a transparent background view, to the current view to get the size via `GeometryReader`.
/// The `MaxWidthPreferenceKey` will be reported, when the frame of this view is updated.
private var sizeView: some View {
GeometryReader { geometry in
Color.clear.preference(key: MaxWidthPreferenceKey.self, value: geometry.frame(in: .global).size.width)
}
}
public func body(content: Content) -> some View {
content.background(sizeView)
}
}
/// Convenience modifier to use in the parent view to observe `MaxWidthPreferenceKey` from children, and bind the value to `$width`.
public struct MaxWidthEqualizer: ViewModifier {
@Binding var width: CGFloat?
public static var notify: MaxWidthNotify {
MaxWidthNotify()
}
public init(width: Binding<CGFloat?>) {
self._width = width
}
public func body(content: Content) -> some View {
content.onPreferenceChange(MaxWidthPreferenceKey.self) { value in
let oldWidth: CGFloat = width ?? 0
if value > oldWidth {
width = value
}
}
}
}

Loading…
Cancel
Save