mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Shared media improvements
This commit is contained in:
@@ -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?
|
||||
|
||||
Reference in New Issue
Block a user