mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
5659120fa9
commit
8e8f997021
@ -7,6 +7,7 @@ import Display
|
||||
import DirectionalPanGesture
|
||||
import TelegramPresentationData
|
||||
import MapKit
|
||||
import WebKit
|
||||
|
||||
private let overflowInset: CGFloat = 0.0
|
||||
|
||||
@ -160,11 +161,22 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
}
|
||||
return true
|
||||
}
|
||||
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer.description.contains("WKDeferringGesture") {
|
||||
if gestureRecognizer is UIPanGestureRecognizer {
|
||||
func findWebViewAncestor(view: UIView?) -> WKWebView? {
|
||||
guard let view else {
|
||||
return nil
|
||||
}
|
||||
if let view = view as? WKWebView {
|
||||
return view
|
||||
} else if view != self.view {
|
||||
return findWebViewAncestor(view: view.superview)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if let otherView = otherGestureRecognizer.view, let _ = findWebViewAncestor(view: otherView) {
|
||||
return true
|
||||
}
|
||||
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer.description.contains("UIWebTouchEventsGesture") {
|
||||
return true
|
||||
}
|
||||
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer is UILongPressGestureRecognizer {
|
||||
return true
|
||||
|
@ -391,33 +391,12 @@ public class AttachmentController: ViewController {
|
||||
|
||||
self.container.interactivelyDismissed = { [weak self] velocity in
|
||||
if let strongSelf = self, let layout = strongSelf.validLayout {
|
||||
if let controller = strongSelf.controller, controller.shouldMinimizeOnSwipe?(strongSelf.currentType) == true, let navigationController = controller.navigationController as? NavigationController {
|
||||
|
||||
if let controller = strongSelf.controller, controller.shouldMinimizeOnSwipe?(strongSelf.currentType) == true {
|
||||
let delta = layout.size.height - controller.minimizedTopEdgeOffset
|
||||
let damping: CGFloat = 180
|
||||
let damping: CGFloat = 180.0
|
||||
let initialVelocity: CGFloat = delta > 0.0 ? velocity / delta : 0.0
|
||||
|
||||
navigationController.minimizeViewController(controller, damping: damping, velocity: initialVelocity, setupContainer: { [weak self] current in
|
||||
let minimizedContainer: MinimizedContainerImpl?
|
||||
if let current = current as? MinimizedContainerImpl {
|
||||
minimizedContainer = current
|
||||
} else if let context = self?.controller?.context {
|
||||
minimizedContainer = MinimizedContainerImpl(sharedContext: context.sharedContext)
|
||||
} else {
|
||||
minimizedContainer = nil
|
||||
}
|
||||
return minimizedContainer
|
||||
}, animated: true)
|
||||
|
||||
strongSelf.dim.isHidden = true
|
||||
|
||||
strongSelf.isMinimizing = true
|
||||
strongSelf.container.update(isExpanded: true, force: true, transition: .immediate)
|
||||
strongSelf.isMinimizing = false
|
||||
|
||||
Queue.mainQueue().after(0.45, {
|
||||
strongSelf.dim.isHidden = false
|
||||
})
|
||||
strongSelf.minimize(damping: damping, initialVelocity: initialVelocity)
|
||||
|
||||
return false
|
||||
} else {
|
||||
@ -588,6 +567,33 @@ public class AttachmentController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private func minimize(damping: CGFloat? = nil, initialVelocity: CGFloat? = nil) {
|
||||
guard let controller = self.controller, let navigationController = controller.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
navigationController.minimizeViewController(controller, damping: damping, velocity: initialVelocity, setupContainer: { [weak self] current in
|
||||
let minimizedContainer: MinimizedContainerImpl?
|
||||
if let current = current as? MinimizedContainerImpl {
|
||||
minimizedContainer = current
|
||||
} else if let context = self?.controller?.context {
|
||||
minimizedContainer = MinimizedContainerImpl(sharedContext: context.sharedContext)
|
||||
} else {
|
||||
minimizedContainer = nil
|
||||
}
|
||||
return minimizedContainer
|
||||
}, animated: true)
|
||||
|
||||
self.dim.isHidden = true
|
||||
|
||||
self.isMinimizing = true
|
||||
self.container.update(isExpanded: true, force: true, transition: .immediate)
|
||||
self.isMinimizing = false
|
||||
|
||||
Queue.mainQueue().after(0.45, {
|
||||
self.dim.isHidden = false
|
||||
})
|
||||
}
|
||||
|
||||
fileprivate func updateSelectionCount(_ count: Int, animated: Bool = true) {
|
||||
self.selectionCount = count
|
||||
if let layout = self.validLayout {
|
||||
@ -600,8 +606,12 @@ public class AttachmentController: ViewController {
|
||||
return
|
||||
}
|
||||
if case .ended = recognizer.state {
|
||||
if let controller = self.currentControllers.last {
|
||||
controller.requestDismiss(completion: { [weak self] in
|
||||
if let lastController = self.currentControllers.last {
|
||||
if let controller = self.controller, controller.shouldMinimizeOnSwipe?(self.currentType) == true {
|
||||
self.minimize()
|
||||
return
|
||||
}
|
||||
lastController.requestDismiss(completion: { [weak self] in
|
||||
self?.controller?.dismiss(animated: true)
|
||||
})
|
||||
} else {
|
||||
|
@ -188,6 +188,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
private let bannedSendPhotos: (Int32, Bool)?
|
||||
private let bannedSendVideos: (Int32, Bool)?
|
||||
private let canBoostToUnrestrict: Bool
|
||||
private let paidMediaAllowed: Bool
|
||||
private let subject: Subject
|
||||
private let saveEditedPhotos: Bool
|
||||
|
||||
@ -1750,6 +1751,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
bannedSendPhotos: (Int32, Bool)? = nil,
|
||||
bannedSendVideos: (Int32, Bool)? = nil,
|
||||
canBoostToUnrestrict: Bool = false,
|
||||
paidMediaAllowed: Bool = false,
|
||||
subject: Subject,
|
||||
editingContext: TGMediaEditingContext? = nil,
|
||||
selectionContext: TGMediaSelectionContext? = nil,
|
||||
@ -1769,6 +1771,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
self.bannedSendPhotos = bannedSendPhotos
|
||||
self.bannedSendVideos = bannedSendVideos
|
||||
self.canBoostToUnrestrict = canBoostToUnrestrict
|
||||
self.paidMediaAllowed = paidMediaAllowed
|
||||
self.subject = subject
|
||||
self.saveEditedPhotos = saveEditedPhotos
|
||||
self.mainButtonState = mainButtonState
|
||||
@ -2499,7 +2502,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
}
|
||||
|
||||
var isPaidAvailable = false
|
||||
if let peer = self.peer, case let .channel(channel) = peer, case .broadcast = channel.info, selectionCount <= 10 {
|
||||
if self.paidMediaAllowed, selectionCount <= 10 {
|
||||
isPaidAvailable = true
|
||||
}
|
||||
if isSpoilerAvailable || isPaidAvailable || (selectionCount > 0 && isCaptionAboveMediaAvailable) {
|
||||
|
@ -16,6 +16,7 @@ swift_library(
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/ComponentFlow",
|
||||
"//submodules/AccountContext",
|
||||
"//submodules/UIKitRuntimeUtils",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -6,6 +6,7 @@ import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import AccountContext
|
||||
import UIKitRuntimeUtils
|
||||
|
||||
private let minimizedNavigationHeight: CGFloat = 44.0
|
||||
private let minimizedTopMargin: CGFloat = 3.0
|
||||
@ -42,6 +43,8 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
}
|
||||
}
|
||||
|
||||
var isReady = false
|
||||
|
||||
let item: Item
|
||||
private let containerNode: ASDisplayNode
|
||||
private let headerNode: MinimizedHeaderNode
|
||||
@ -49,7 +52,9 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
private let shadowNode: ASImageNode
|
||||
|
||||
private var controllerView: UIView?
|
||||
fileprivate let snapshotContainerView = UIView()
|
||||
fileprivate var snapshotView: UIView?
|
||||
fileprivate var blurredSnapshotView: UIView?
|
||||
|
||||
var tapped: (() -> Void)?
|
||||
var highlighted: ((Bool) -> Void)?
|
||||
@ -88,6 +93,8 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
self.dimCoverNode.backgroundColor = UIColor.black
|
||||
self.dimCoverNode.isUserInteractionEnabled = false
|
||||
|
||||
self.snapshotContainerView.isUserInteractionEnabled = false
|
||||
|
||||
super.init()
|
||||
|
||||
self.clipsToBounds = true
|
||||
@ -102,11 +109,13 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
self.containerNode.view.addSubview(self.item.controller.displayNode.view)
|
||||
|
||||
Queue.mainQueue().after(0.45) {
|
||||
self.isReady = true
|
||||
if !self.isDismissed, let snapshotView = self.controllerView?.snapshotView(afterScreenUpdates: false) {
|
||||
self.containerNode.view.addSubview(self.snapshotContainerView)
|
||||
self.snapshotView = snapshotView
|
||||
self.controllerView?.removeFromSuperview()
|
||||
self.controllerView = snapshotView
|
||||
self.containerNode.view.addSubview(snapshotView)
|
||||
self.controllerView = nil
|
||||
self.snapshotContainerView.addSubview(snapshotView)
|
||||
self.requestLayout(transition: .immediate)
|
||||
}
|
||||
}
|
||||
@ -166,7 +175,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
}
|
||||
|
||||
@objc func tapLongTapOrDoubleTapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
|
||||
guard let (_, insets, _) = self.validLayout else {
|
||||
guard let (_, insets, _) = self.validLayout, self.isReady else {
|
||||
return
|
||||
}
|
||||
switch recognizer.state {
|
||||
@ -205,6 +214,8 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
self.containerNode.frame = CGRect(origin: .zero, size: size)
|
||||
self.containerNode.subnodeTransform = CATransform3DMakeTranslation(0.0, -topInset, 0.0)
|
||||
|
||||
self.snapshotContainerView.frame = CGRect(origin: .zero, size: size)
|
||||
|
||||
self.shadowNode.frame = CGRect(origin: .zero, size: CGSize(width: size.width, height: size.height - topInset))
|
||||
|
||||
var navigationHeight: CGFloat = minimizedNavigationHeight
|
||||
@ -217,9 +228,45 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
transition.updateFrame(node: self.headerNode, frame: headerFrame)
|
||||
transition.updateFrame(node: self.dimCoverNode, frame: CGRect(origin: .zero, size: size))
|
||||
|
||||
if let controllerView = self.snapshotView {
|
||||
let controllerFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - controllerView.bounds.size.width) / 2.0), y: 0.0), size: controllerView.bounds.size)
|
||||
transition.updateFrame(view: controllerView, frame: controllerFrame)
|
||||
if let snapshotView = self.snapshotView {
|
||||
var snapshotFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - snapshotView.bounds.size.width) / 2.0), y: 0.0), size: snapshotView.bounds.size)
|
||||
|
||||
var requiresBlur = false
|
||||
var blurFrame = snapshotFrame
|
||||
if snapshotView.frame.width * 1.1 < size.width {
|
||||
snapshotFrame = snapshotFrame.offsetBy(dx: 0.0, dy: -66.0)
|
||||
blurFrame = CGRect(origin: CGPoint(x: 0.0, y: snapshotFrame.minY), size: CGSize(width: size.width, height: snapshotFrame.height))
|
||||
requiresBlur = true
|
||||
} else if snapshotView.frame.width > size.width * 1.5 {
|
||||
snapshotFrame = snapshotFrame.offsetBy(dx: 0.0, dy: 66.0)
|
||||
blurFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - snapshotView.frame.width) / 2.0), y: snapshotFrame.minY), size: CGSize(width: snapshotFrame.width, height: size.height))
|
||||
requiresBlur = true
|
||||
}
|
||||
|
||||
if requiresBlur {
|
||||
let blurredSnapshotView: UIView?
|
||||
if let current = self.blurredSnapshotView {
|
||||
blurredSnapshotView = current
|
||||
} else {
|
||||
blurredSnapshotView = snapshotView.snapshotView(afterScreenUpdates: false)
|
||||
if let blurredSnapshotView {
|
||||
if let blurFilter = makeBlurFilter() {
|
||||
blurFilter.setValue(20.0 as NSNumber, forKey: "inputRadius")
|
||||
blurFilter.setValue(true as NSNumber, forKey: "inputNormalizeEdges")
|
||||
blurredSnapshotView.layer.filters = [blurFilter]
|
||||
}
|
||||
self.snapshotContainerView.insertSubview(blurredSnapshotView, at: 0)
|
||||
self.blurredSnapshotView = blurredSnapshotView
|
||||
}
|
||||
}
|
||||
blurredSnapshotView?.frame = blurFrame
|
||||
} else if let blurredSnapshotView = self.blurredSnapshotView {
|
||||
self.blurredSnapshotView = nil
|
||||
blurredSnapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in
|
||||
blurredSnapshotView.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
transition.updateFrame(view: snapshotView, frame: snapshotFrame)
|
||||
}
|
||||
|
||||
if !self.isDismissed {
|
||||
@ -357,6 +404,9 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
}
|
||||
|
||||
@objc func expandPanGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
|
||||
guard let lastItem = self.items.last, let itemNode = self.itemNodes[lastItem.id], itemNode.isReady else {
|
||||
return
|
||||
}
|
||||
let translation = gestureRecognizer.translation(in: self.view)
|
||||
if translation.y < -10.0 {
|
||||
gestureRecognizer.isEnabled = false
|
||||
@ -443,6 +493,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
case maximize(itemId: AnyHashable)
|
||||
case dismiss(itemId: AnyHashable)
|
||||
case dismissAll
|
||||
case collapse
|
||||
|
||||
func matches(item: Item) -> Bool {
|
||||
switch self {
|
||||
@ -452,6 +503,8 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
return item.id == itemId
|
||||
case .dismissAll:
|
||||
return true
|
||||
case .collapse:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,7 +542,7 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
}
|
||||
|
||||
public func expand() {
|
||||
guard !self.items.isEmpty && !self.isExpanded else {
|
||||
guard !self.items.isEmpty && !self.isExpanded && self.currentTransition == nil else {
|
||||
return
|
||||
}
|
||||
if self.items.count == 1, let item = self.items.first {
|
||||
@ -501,16 +554,24 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
}
|
||||
|
||||
public func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
guard self.isExpanded else {
|
||||
guard self.isExpanded, let layout = self.validLayout else {
|
||||
return
|
||||
}
|
||||
self.requestUpdate(transition: .immediate)
|
||||
|
||||
if scrollView.contentOffset.y < -64.0 {
|
||||
let contentOffset = scrollView.contentOffset
|
||||
if scrollView.contentOffset.y < -64.0, let lastItemId = self.items.last?.id, let itemNode = self.itemNodes[lastItemId] {
|
||||
let velocity = scrollView.panGestureRecognizer.velocity(in: self.view).y
|
||||
let distance = layout.size.height - self.collapsedHeight(layout: layout) - itemNode.frame.minY
|
||||
let initialVelocity = distance != 0.0 ? abs(velocity / distance) : 0.0
|
||||
|
||||
self.isExpanded = false
|
||||
scrollView.isScrollEnabled = false
|
||||
scrollView.panGestureRecognizer.isEnabled = false
|
||||
scrollView.panGestureRecognizer.isEnabled = true
|
||||
self.requestUpdate(transition: .animated(duration: 0.4, curve: .spring))
|
||||
scrollView.contentOffset = contentOffset
|
||||
self.currentTransition = .collapse
|
||||
self.requestUpdate(transition: .animated(duration: 0.4, curve: .customSpring(damping: 180.0, initialVelocity: initialVelocity)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,6 +852,10 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
dimView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
|
||||
itemNode.animateOut()
|
||||
if itemInsets.left > 0.0 {
|
||||
itemNode.updateLayout(size: layout.size, insets: itemInsets, isExpanded: true, transition: transition)
|
||||
transition.updateBounds(node: itemNode, bounds: CGRect(origin: .zero, size: layout.size))
|
||||
}
|
||||
transition.updateTransform(node: itemNode, transform: CATransform3DIdentity)
|
||||
transition.updatePosition(node: itemNode, position: CGPoint(x: layout.size.width / 2.0, y: layout.size.height / 2.0 + topInset + self.scrollView.contentOffset.y), completion: { _ in
|
||||
self.isApplyingTransition = false
|
||||
@ -798,16 +863,20 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
self.currentTransition = nil
|
||||
}
|
||||
|
||||
if let snaphotView = itemNode.snapshotView {
|
||||
itemNode.item.controller.displayNode.view.addSubview(snaphotView)
|
||||
completion(currentTransition)
|
||||
|
||||
if let _ = itemNode.snapshotView {
|
||||
let snapshotContainerView = itemNode.snapshotContainerView
|
||||
snapshotContainerView.layer.allowsGroupOpacity = true
|
||||
snapshotContainerView.center = CGPoint(x: itemNode.item.controller.displayNode.view.bounds.width / 2.0, y: snapshotContainerView.bounds.height / 2.0)
|
||||
itemNode.item.controller.displayNode.view.addSubview(snapshotContainerView)
|
||||
Queue.mainQueue().after(0.15, {
|
||||
snaphotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
snaphotView.removeFromSuperview()
|
||||
snapshotContainerView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
snapshotContainerView.removeFromSuperview()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
completion(currentTransition)
|
||||
self.itemNodes[itemId] = nil
|
||||
itemNode.removeFromSupernode()
|
||||
dimView.removeFromSuperview()
|
||||
@ -867,6 +936,14 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
completion(currentTransition)
|
||||
})
|
||||
transition.updatePosition(layer: self.scrollView.layer, position: self.scrollView.center.offsetBy(dx: 0.0, dy: dismissOffset))
|
||||
case .collapse:
|
||||
transition.updateBounds(layer: self.scrollView.layer, bounds: CGRect(origin: .zero, size: self.scrollView.bounds.size), completion: { _ in
|
||||
self.isApplyingTransition = false
|
||||
if self.currentTransition == currentTransition {
|
||||
self.currentTransition = nil
|
||||
}
|
||||
completion(currentTransition)
|
||||
})
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -42,6 +42,9 @@ extension ChatControllerImpl {
|
||||
filter.insert(.excludeChannels)
|
||||
break
|
||||
}
|
||||
if let _ = media as? TelegramMediaPaidContent {
|
||||
filter.insert(.excludeSecretChats)
|
||||
}
|
||||
}
|
||||
}
|
||||
var attemptSelectionImpl: ((EnginePeer, ChatListDisabledPeerReason) -> Void)?
|
||||
|
@ -1166,6 +1166,10 @@ extension ChatControllerImpl {
|
||||
if case .scheduledMessages = self.presentationInterfaceState.subject {
|
||||
isScheduledMessages = true
|
||||
}
|
||||
var paidMediaAllowed = false
|
||||
if let cachedData = self.peerView?.cachedData as? CachedChannelData, cachedData.flags.contains(.paidMediaAllowed) {
|
||||
paidMediaAllowed = true
|
||||
}
|
||||
let controller = MediaPickerScreen(
|
||||
context: self.context,
|
||||
updatedPresentationData: self.updatedPresentationData,
|
||||
@ -1176,6 +1180,7 @@ extension ChatControllerImpl {
|
||||
bannedSendPhotos: bannedSendPhotos,
|
||||
bannedSendVideos: bannedSendVideos,
|
||||
canBoostToUnrestrict: (self.presentationInterfaceState.boostsToUnrestrict ?? 0) > 0 && bannedSendPhotos?.1 != true && bannedSendVideos?.1 != true,
|
||||
paidMediaAllowed: paidMediaAllowed,
|
||||
subject: subject,
|
||||
saveEditedPhotos: saveEditedPhotos
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user