ios: better layout performance for chat item (#3911)

* ios: better layout performance for chat item

* different way of disabling menu

* two fixes

---------

Co-authored-by: Avently <avently@local>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
Stanislav Dmitrenko
2024-03-19 21:40:46 +07:00
committed by GitHub
parent 157c4722ca
commit 5fde879fea
3 changed files with 22 additions and 12 deletions

View File

@@ -253,6 +253,7 @@ struct FramedItemView: View {
ciQuotedMsgTextView(qi, lines: 3)
}
}
.fixedSize(horizontal: false, vertical: true)
.padding(.top, 6)
.padding(.horizontal, 12)
}

View File

@@ -646,7 +646,7 @@ struct ChatView: View {
playbackState: $playbackState,
playbackTime: $playbackTime
)
.uiKitContextMenu(menu: uiMenu, allowMenu: $allowMenu)
.uiKitContextMenu(maxWidth: maxWidth, menu: uiMenu, allowMenu: $allowMenu)
.accessibilityLabel("")
if ci.content.msgContent != nil && (ci.meta.itemDeleted == nil || revealed) && ci.reactions.count > 0 {
chatItemReactions(ci)

View File

@@ -11,26 +11,31 @@ import UIKit
import SwiftUI
extension View {
func uiKitContextMenu(menu: Binding<UIMenu>, allowMenu: Binding<Bool>) -> some View {
self.overlay {
if allowMenu.wrappedValue {
self.overlay(Color(uiColor: .systemBackground)).overlay(InteractionView(content: self, menu: menu))
}
func uiKitContextMenu(maxWidth: CGFloat, menu: Binding<UIMenu>, allowMenu: Binding<Bool>) -> some View {
Group {
if allowMenu.wrappedValue {
InteractionView(content: self, maxWidth: maxWidth, menu: menu)
.fixedSize(horizontal: true, vertical: false)
} else {
self
}
}
}
}
private struct InteractionConfig<Content: View> {
let content: Content
let menu: UIMenu
private class HostingViewHolder: UIView {
var contentSize: CGSize = CGSizeMake(0, 0)
override var intrinsicContentSize: CGSize { get { contentSize } }
}
private struct InteractionView<Content: View>: UIViewRepresentable {
struct InteractionView<Content: View>: UIViewRepresentable {
let content: Content
var maxWidth: CGFloat
@Binding var menu: UIMenu
func makeUIView(context: Context) -> UIView {
let view = UIView()
let view = HostingViewHolder()
view.contentSize = CGSizeMake(maxWidth, .infinity)
view.backgroundColor = .clear
let hostView = UIHostingController(rootView: content)
hostView.view.translatesAutoresizingMaskIntoConstraints = false
@@ -44,12 +49,16 @@ private struct InteractionView<Content: View>: UIViewRepresentable {
]
view.addSubview(hostView.view)
view.addConstraints(constraints)
view.layer.cornerRadius = 18
hostView.view.layer.cornerRadius = 18
let menuInteraction = UIContextMenuInteraction(delegate: context.coordinator)
view.addInteraction(menuInteraction)
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
func updateUIView(_ uiView: UIView, context: Context) {
(uiView as! HostingViewHolder).contentSize = uiView.subviews[0].sizeThatFits(CGSizeMake(maxWidth, .infinity))
}
func makeCoordinator() -> Coordinator {
Coordinator(self)