Shared media improvements

This commit is contained in:
Ali
2021-10-24 22:27:23 +04:00
parent 05e57b1923
commit d28747cb00
9 changed files with 415 additions and 184 deletions

View File

@@ -1055,7 +1055,7 @@ private final class SparseItemGridBindingImpl: SparseItemGridBinding {
}
var duration: Int32?
if layer.bounds.width > 80.0, let file = selectedMedia as? TelegramMediaFile {
if layer.bounds.width > 80.0, let file = selectedMedia as? TelegramMediaFile, !file.isAnimated {
duration = file.duration
}
layer.updateDuration(duration: duration)
@@ -1172,6 +1172,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
weak var parentController: ViewController?
private let contextGestureContainerNode: ContextControllerSourceNode
private let itemGrid: SparseItemGrid
private let itemGridBinding: SparseItemGridBindingImpl
private let directMediaImageCache: DirectMediaImageCache
@@ -1221,6 +1222,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
private let stateTag: MessageTags
private var storedStateDisposable: Disposable?
private weak var currentGestureItem: SparseItemGridDisplayItem?
init(context: AccountContext, chatControllerInteraction: ChatControllerInteraction, peerId: PeerId, contentType: ContentType) {
self.context = context
@@ -1230,6 +1233,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
self.contentTypePromise = ValuePromise<ContentType>(contentType)
self.stateTag = tagMaskForType(contentType)
self.contextGestureContainerNode = ContextControllerSourceNode()
self.itemGrid = SparseItemGrid()
self.directMediaImageCache = DirectMediaImageCache(account: context.account)
@@ -1398,7 +1402,94 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
)
self.itemInteraction.selectedMessageIds = chatControllerInteraction.selectionState.flatMap { $0.selectedIds }
self.addSubnode(self.itemGrid)
self.contextGestureContainerNode.isGestureEnabled = !useListItems
self.contextGestureContainerNode.addSubnode(self.itemGrid)
self.addSubnode(self.contextGestureContainerNode)
self.contextGestureContainerNode.shouldBegin = { [weak self] point in
guard let strongSelf = self else {
return false
}
guard let item = strongSelf.itemGrid.item(at: point) else {
return false
}
strongSelf.currentGestureItem = item
return true
}
self.contextGestureContainerNode.customActivationProgress = { [weak self] progress, update in
guard let strongSelf = self, let currentGestureItem = strongSelf.currentGestureItem else {
return
}
guard let itemLayer = currentGestureItem.layer else {
return
}
let targetContentRect = CGRect(origin: CGPoint(), size: itemLayer.bounds.size)
let scaleSide = itemLayer.bounds.width
let minScale: CGFloat = max(0.7, (scaleSide - 15.0) / scaleSide)
let currentScale = 1.0 * (1.0 - progress) + minScale * progress
let originalCenterOffsetX: CGFloat = itemLayer.bounds.width / 2.0 - targetContentRect.midX
let scaledCenterOffsetX: CGFloat = originalCenterOffsetX * currentScale
let originalCenterOffsetY: CGFloat = itemLayer.bounds.height / 2.0 - targetContentRect.midY
let scaledCenterOffsetY: CGFloat = originalCenterOffsetY * currentScale
let scaleMidX: CGFloat = scaledCenterOffsetX - originalCenterOffsetX
let scaleMidY: CGFloat = scaledCenterOffsetY - originalCenterOffsetY
switch update {
case .update:
let sublayerTransform = CATransform3DTranslate(CATransform3DScale(CATransform3DIdentity, currentScale, currentScale, 1.0), scaleMidX, scaleMidY, 0.0)
itemLayer.transform = sublayerTransform
case .begin:
let sublayerTransform = CATransform3DTranslate(CATransform3DScale(CATransform3DIdentity, currentScale, currentScale, 1.0), scaleMidX, scaleMidY, 0.0)
itemLayer.transform = sublayerTransform
case .ended:
let sublayerTransform = CATransform3DTranslate(CATransform3DScale(CATransform3DIdentity, currentScale, currentScale, 1.0), scaleMidX, scaleMidY, 0.0)
let previousTransform = itemLayer.transform
itemLayer.transform = sublayerTransform
itemLayer.animate(from: NSValue(caTransform3D: previousTransform), to: NSValue(caTransform3D: sublayerTransform), keyPath: "transform", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.2)
}
}
self.contextGestureContainerNode.activated = { [weak self] gesture, _ in
guard let strongSelf = self, let currentGestureItem = strongSelf.currentGestureItem else {
return
}
strongSelf.currentGestureItem = nil
guard let itemLayer = currentGestureItem.layer as? ItemLayer else {
return
}
guard let message = itemLayer.item?.message else {
return
}
let rect = strongSelf.itemGrid.frameForItem(layer: itemLayer)
let proxyNode = ASDisplayNode()
proxyNode.frame = rect
proxyNode.contents = itemLayer.contents
proxyNode.isHidden = true
strongSelf.addSubnode(proxyNode)
let escapeNotification = EscapeNotification {
proxyNode.removeFromSupernode()
}
Queue.mainQueue().after(1.0, {
escapeNotification.keep()
})
strongSelf.chatControllerInteraction.openMessageContextActions(message, proxyNode, proxyNode.bounds, gesture)
strongSelf.itemGrid.cancelGestures()
}
self.storedStateDisposable = (visualMediaStoredState(postbox: context.account.postbox, peerId: peerId, messageTag: self.stateTag)
|> deliverOnMainQueue).start(next: { [weak self] value in
@@ -1509,7 +1600,7 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
} else if photoCount != 0 {
return PeerInfoStatusData(text: "\(photoCount) photos", isActivity: false)
} else if videoCount != 0 {
return PeerInfoStatusData(text: "\(photoCount) videos", isActivity: false)
return PeerInfoStatusData(text: "\(videoCount) videos", isActivity: false)
} else {
return nil
}
@@ -1607,6 +1698,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
self.contentType = contentType
self.contentTypePromise.set(contentType)
self.itemGrid.hideScrollingArea()
self.listSource = self.context.engine.messages.sparseMessageList(peerId: self.peerId, tag: tagMaskForType(self.contentType))
self.isRequestingView = false
self.requestHistoryAroundVisiblePosition(synchronous: true, reloadAtTop: true)
@@ -1836,6 +1929,8 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
func update(size: CGSize, topInset: CGFloat, sideInset: CGFloat, bottomInset: CGFloat, visibleHeight: CGFloat, isScrollingLockedAtTop: Bool, expandProgress: CGFloat, presentationData: PresentationData, synchronous: Bool, transition: ContainedViewLayoutTransition) {
self.currentParams = (size, topInset, sideInset, bottomInset, visibleHeight, isScrollingLockedAtTop, expandProgress, presentationData)
transition.updateFrame(node: self.contextGestureContainerNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)))
transition.updateFrame(node: self.itemGrid, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width, height: size.height)))
if let items = self.items {
let fixedItemHeight: CGFloat?