Merge commit '82104445dde2810d0f0dde0f58bb276cdcd1321b'

This commit is contained in:
Ali 2022-02-27 00:54:35 +04:00
commit 0d424f1663
13 changed files with 208 additions and 35 deletions

View File

@ -96,6 +96,14 @@ final class AttachmentContainer: ASDisplayNode, UIGestureRecognizerDelegate {
self.wrappingNode.view.addGestureRecognizer(panRecognizer)
}
func cancelPanGesture() {
if let panGestureRecognizer = self.panGestureRecognizer, panGestureRecognizer.isEnabled {
self.panGestureArguments = nil
panGestureRecognizer.isEnabled = false
panGestureRecognizer.isEnabled = true
}
}
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if let (layout, _, _) = self.validLayout {
if case .regular = layout.metrics.widthClass {

View File

@ -24,6 +24,7 @@ public protocol AttachmentContainable: ViewController {
var requestAttachmentMenuExpansion: () -> Void { get set }
var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void { get set }
var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void { get set }
var cancelPanGesture: () -> Void { get set }
func resetForReuse()
func prepareForReuse()
@ -57,14 +58,34 @@ private func generateShadowImage() -> UIImage? {
return generateImage(CGSize(width: 140.0, height: 140.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.saveGState()
context.setShadow(offset: CGSize(), blur: 60.0, color: UIColor(white: 0.0, alpha: 0.4).cgColor)
let path = UIBezierPath(roundedRect: CGRect(x: 60.0, y: 60.0, width: 20.0, height: 20.0), cornerRadius: 11.0 - UIScreenPixel).cgPath
let path = UIBezierPath(roundedRect: CGRect(x: 60.0, y: 60.0, width: 20.0, height: 20.0), cornerRadius: 10.0).cgPath
context.addPath(path)
context.fillPath()
context.restoreGState()
context.setBlendMode(.clear)
context.addPath(path)
context.fillPath()
})?.stretchableImage(withLeftCapWidth: 70, topCapHeight: 70)
}
private func generateMaskImage() -> UIImage? {
return generateImage(CGSize(width: 390.0, height: 620.0), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor.white.cgColor)
let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: 0.0, width: 390.0, height: 609.0), cornerRadius: 10.0).cgPath
context.addPath(path)
context.fillPath()
try? drawSvgPath(context, path: "M183.219,608.889 H206.781 C205.648,608.889 204.567,609.37 203.808,610.213 L197.23,617.522 C196.038,618.847 193.962,618.847 192.77,617.522 L186.192,610.213 C185.433,609.37 184.352,608.889 183.219,608.889 Z ")
})
}
public class AttachmentController: ViewController {
private let context: AccountContext
@ -79,6 +100,11 @@ public class AttachmentController: ViewController {
self.node.mediaPickerContext = newValue
}
}
private let _ready = Promise<Bool>()
override public var ready: Promise<Bool> {
return self._ready
}
private final class Node: ASDisplayNode {
private weak var controller: AttachmentController?
@ -265,6 +291,7 @@ public class AttachmentController: ViewController {
if let strongSelf = self {
strongSelf.mediaPickerContext = mediaPickerContext
if let controller = controller {
strongSelf.controller?._ready.set(controller.ready.get())
controller._presentedInModal = true
controller.navigation_setPresenting(strongSelf.controller)
controller.requestAttachmentMenuExpansion = { [weak self] in
@ -283,6 +310,11 @@ public class AttachmentController: ViewController {
strongSelf.panel.updateBackgroundAlpha(alpha, transition: transition)
}
}
controller.cancelPanGesture = { [weak self] in
if let strongSelf = self {
strongSelf.container.cancelPanGesture()
}
}
let previousController = strongSelf.currentControllers.last
let animateTransition = previousType != nil
strongSelf.currentControllers = [controller]
@ -327,6 +359,8 @@ public class AttachmentController: ViewController {
self.animating = true
if case .regular = layout.metrics.widthClass {
self.animating = false
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 0.1)
} else {
ContainedViewLayoutTransition.animated(duration: 0.3, curve: .linear).updateAlpha(node: self.dim, alpha: 1.0)
@ -402,20 +436,23 @@ public class AttachmentController: ViewController {
var containerLayout = layout
let containerRect: CGRect
if case .regular = layout.metrics.widthClass {
let size = CGSize(width: 390.0, height: 600.0)
let position: CGPoint
if layout.size.width > layout.size.height {
position = CGPoint(x: 225.0, y: layout.size.height - size.height - layout.intrinsicInsets.bottom - 54.0)
} else {
position = CGPoint(x: 152.0, y: layout.size.height - size.height - layout.intrinsicInsets.bottom - 54.0)
let size = CGSize(width: 390.0, height: 620.0)
let masterWidth = min(max(320.0, floor(layout.size.width / 3.0)), floor(layout.size.width / 2.0))
var position: CGPoint = CGPoint(x: masterWidth - 174.0, y: layout.size.height - size.height - layout.intrinsicInsets.bottom - 40.0)
if let inputHeight = layout.inputHeight {
position.y -= inputHeight
}
containerRect = CGRect(origin: position, size: size)
containerLayout.size = containerRect.size
containerLayout.intrinsicInsets.bottom = 0.0
containerLayout.intrinsicInsets.bottom = 12.0
containerLayout.inputHeight = nil
self.wrapperNode.cornerRadius = 10.0
if #available(iOS 13.0, *) {
self.wrapperNode.layer.cornerCurve = .continuous
if self.wrapperNode.view.mask == nil {
let maskView = UIImageView()
maskView.image = generateMaskImage()
maskView.frame = CGRect(origin: CGPoint(), size: maskView.image?.size ?? CGSize())
self.wrapperNode.view.mask = maskView
}
self.shadowNode.alpha = 1.0
@ -427,6 +464,8 @@ public class AttachmentController: ViewController {
self.wrapperNode.cornerRadius = 0.0
self.shadowNode.alpha = 0.0
self.wrapperNode.view.mask = nil
}
@ -438,7 +477,9 @@ public class AttachmentController: ViewController {
}
panelTransition.updateFrame(node: self.panel, frame: CGRect(origin: CGPoint(x: 0.0, y: containerRect.height - panelHeight), size: CGSize(width: containerRect.width, height: panelHeight)))
transition.updateFrame(node: self.shadowNode, frame: containerRect.insetBy(dx: -60.0, dy: -60.0))
var shadowFrame = containerRect.insetBy(dx: -60.0, dy: -60.0)
shadowFrame.size.height -= 12.0
transition.updateFrame(node: self.shadowNode, frame: shadowFrame)
transition.updateFrame(node: self.wrapperNode, frame: containerRect)
if !self.isUpdatingContainer && !self.isDismissing {

View File

@ -17,12 +17,6 @@ private let buttonSize = CGSize(width: 88.0, height: 49.0)
private let iconSize = CGSize(width: 30.0, height: 30.0)
private let sideInset: CGFloat = 0.0
private enum AttachmentButtonTransition {
case transitionIn
case selection
}
private final class AttachButtonComponent: CombinedComponent {
let context: AccountContext
let type: AttachmentButtonType

View File

@ -520,6 +520,7 @@ private class CreatePollControllerImpl: ItemListController, AttachmentContainabl
public var requestAttachmentMenuExpansion: () -> Void = {}
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var cancelPanGesture: () -> Void = { }
}
public func createPollController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (ComposedPoll) -> Void) -> AttachmentContainable {

View File

@ -408,6 +408,7 @@ open class LegacyController: ViewController, PresentableController, AttachmentCo
open var requestAttachmentMenuExpansion: () -> Void = {}
open var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
open var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
open var cancelPanGesture: () -> Void = { }
public init(presentation: LegacyControllerPresentation, theme: PresentationTheme? = nil, strings: PresentationStrings? = nil, initialLayout: ContainerViewLayout? = nil) {
self.sizeClass.set(SSignal.single(UIUserInterfaceSizeClass.compact.rawValue as NSNumber))

View File

@ -74,6 +74,7 @@ public final class LocationPickerController: ViewController, AttachmentContainab
public var requestAttachmentMenuExpansion: () -> Void = {}
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var cancelPanGesture: () -> Void = { }
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, mode: LocationPickerMode, completion: @escaping (TelegramMediaMap, String?) -> Void) {
self.context = context

View File

@ -105,7 +105,7 @@ final class MediaPickerGridItemNode: GridItemNode {
return self.asset?.localIdentifier ?? ""
}
private var asset: PHAsset? {
var asset: PHAsset? {
if let (fetchResult, index) = self.currentState {
return fetchResult[index]
} else {
@ -113,7 +113,7 @@ final class MediaPickerGridItemNode: GridItemNode {
}
}
func updateSelectionState() {
func updateSelectionState(animated: Bool = false) {
if self.checkNode == nil, let _ = self.interaction?.selectionState, let theme = self.theme {
let checkNode = InteractiveCheckNode(theme: CheckNodeTheme(theme: theme, style: .overlay))
checkNode.valueChanged = { [weak self] value in
@ -136,7 +136,7 @@ final class MediaPickerGridItemNode: GridItemNode {
self.checkNode?.content = .counter(Int(index))
}
}
self.checkNode?.setSelected(selected, animated: false)
self.checkNode?.setSelected(selected, animated: animated)
}
}

View File

@ -101,8 +101,9 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
public var requestAttachmentMenuExpansion: () -> Void = { }
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var cancelPanGesture: () -> Void = { }
private class Node: ViewControllerTracingNode {
private class Node: ViewControllerTracingNode, UIGestureRecognizerDelegate {
enum DisplayMode {
case all
case selected
@ -164,9 +165,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
self.gridNode = GridNode()
super.init()
// self.backgroundColor = self.presentationData.theme.list.plainBackgroundColor
self.addSubnode(self.containerNode)
self.containerNode.addSubnode(self.backgroundNode)
self.containerNode.addSubnode(self.gridNode)
@ -226,10 +225,12 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
})
if let selectionState = self.controller?.interaction?.selectionState {
func selectionChangedSignal(selectionState: TGMediaSelectionContext) -> Signal<Void, NoError> {
func selectionChangedSignal(selectionState: TGMediaSelectionContext) -> Signal<Bool, NoError> {
return Signal { subscriber in
let disposable = selectionState.selectionChangedSignal()?.start(next: { next in
subscriber.putNext(Void())
if let next = next as? TGMediaSelectionChange {
subscriber.putNext(next.animated)
}
}, completed: {})
return ActionDisposable {
disposable?.dispose()
@ -238,9 +239,9 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
}
self.selectionChangedDisposable = (selectionChangedSignal(selectionState: selectionState)
|> deliverOnMainQueue).start(next: { [weak self] _ in
|> deliverOnMainQueue).start(next: { [weak self] animated in
if let strongSelf = self {
strongSelf.updateSelectionState()
strongSelf.updateSelectionState(animated: animated)
}
})
}
@ -273,6 +274,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
self.itemsDimensionsUpdatedDisposable?.dispose()
}
private var selectionGesture: MediaPickerGridSelectionGesture?
override func didLoad() {
super.didLoad()
@ -295,8 +297,32 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
} else {
self.containerNode.clipsToBounds = true
}
// self.controller?.navigationBar?.updateBackgroundAlpha(0.0, transition: .immediate)
self.selectionGesture = MediaPickerGridSelectionGesture(target: nil, action: nil, gridNode: self.gridNode)
self.selectionGesture?.delegate = self
self.selectionGesture?.began = { [weak self] in
self?.controller?.cancelPanGesture()
}
self.selectionGesture?.itemAt = { [weak self] point in
if let strongSelf = self, let itemNode = strongSelf.gridNode.itemNodeAtPoint(point) as? MediaPickerGridItemNode, let asset = itemNode.asset.flatMap({ TGMediaAsset(phAsset: $0) }) {
return (asset, strongSelf.controller?.interaction?.selectionState?.isItemSelected(asset) ?? false)
} else {
return nil
}
}
self.selectionGesture?.updateSelection = { [weak self] asset, selected in
if let strongSelf = self {
strongSelf.controller?.interaction?.selectionState?.setItem(asset, selected: selected, animated: true, sender: nil)
}
}
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
if otherGestureRecognizer.view is UIScrollView || otherGestureRecognizer is UIPanGestureRecognizer {
return true
} else {
return false
}
}
fileprivate func dismissInput() {
@ -363,10 +389,10 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
self.updateNavigation(transition: .immediate)
}
private func updateSelectionState() {
private func updateSelectionState(animated: Bool = false) {
self.gridNode.forEachItemNode { itemNode in
if let itemNode = itemNode as? MediaPickerGridItemNode {
itemNode.updateSelectionState()
itemNode.updateSelectionState(animated: animated)
}
}
self.selectionNode?.updateSelectionState()
@ -743,7 +769,8 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
if !strongSelf.didSetReady && strongSelf.state != nil {
strongSelf.didSetReady = true
Queue.mainQueue().justDispatch {
strongSelf._ready.set(.single(true))
strongSelf._ready.set(.single(true)
|> delay(0.05, queue: Queue.mainQueue()))
Queue.mainQueue().after(0.5, {
strongSelf.preloadPromise.set(false)
@ -1165,3 +1192,98 @@ private final class MediaPickerContextReferenceContentSource: ContextReferenceCo
return ContextControllerReferenceViewInfo(referenceNode: self.sourceNode, contentAreaInScreenSpace: UIScreen.main.bounds)
}
}
private class MediaPickerGridSelectionGesture: UIPanGestureRecognizer {
var itemAt: (CGPoint) -> (TGMediaSelectableItem, Bool)? = { _ in return nil }
var updateSelection: (TGMediaSelectableItem, Bool) -> Void = { _, _ in}
var began: () -> Void = {}
private weak var gridNode: GridNode?
private var processing = false
private var selecting = false
private var initialLocation: CGPoint?
init(target: Any?, action: Selector?, gridNode: GridNode) {
self.gridNode = gridNode
super.init(target: target, action: action)
gridNode.view.addGestureRecognizer(self)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
guard let touch = touches.first, let gridNode = self.gridNode else {
return
}
let location = touch.location(in: gridNode.view)
self.initialLocation = location
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)
guard let touch = touches.first, let gridNode = self.gridNode, let initialLocation = self.initialLocation else {
self.state = .failed
return
}
let location = touch.location(in: gridNode.view)
let translation = CGPoint(x: location.x - initialLocation.x, y: location.y - initialLocation.y)
var additionalLocation: CGPoint?
if !self.processing {
if abs(translation.y) > 5.0 {
self.state = .failed
} else if abs(translation.x) > 4.0 {
self.processing = true
self.gridNode?.scrollView.isScrollEnabled = false
self.began()
if let (_, selected) = self.itemAt(location) {
self.selecting = !selected
}
additionalLocation = self.initialLocation
}
}
if self.processing {
if let additionalLocation = additionalLocation {
if let (item, selected) = self.itemAt(additionalLocation), selected != self.selecting {
self.updateSelection(item, self.selecting)
}
}
if let (item, selected) = self.itemAt(location), selected != self.selecting {
self.updateSelection(item, self.selecting)
}
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesEnded(touches, with: event)
self.state = .failed
self.reset()
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesCancelled(touches, with: event)
self.state = .failed
self.reset()
}
override func reset() {
super.reset()
self.processing = false
self.initialLocation = nil
self.gridNode?.scrollView.isScrollEnabled = true
}
}

View File

@ -227,6 +227,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI
self.scrollNode.view.delegate = self
self.scrollNode.view.panGestureRecognizer.cancelsTouchesInView = true
self.scrollNode.view.showsVerticalScrollIndicator = false
self.view.addGestureRecognizer(ReorderingGestureRecognizer(shouldBegin: { [weak self] point in
if let strongSelf = self, !strongSelf.scrollNode.view.isDragging {

View File

@ -167,6 +167,7 @@ private class AttachmentFileControllerImpl: ItemListController, AttachmentContai
public var requestAttachmentMenuExpansion: () -> Void = {}
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var cancelPanGesture: () -> Void = { }
var resetForReuseImpl: () -> Void = {}
public func resetForReuse() {

View File

@ -9122,7 +9122,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
}
var layout = layout
if let _ = self.attachmentController {
if case .compact = layout.metrics.widthClass, let _ = self.attachmentController {
layout = layout.withUpdatedInputHeight(nil)
}

View File

@ -78,6 +78,7 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
var requestAttachmentMenuExpansion: () -> Void = {}
var updateNavigationStack: (@escaping ([AttachmentContainable]) -> [AttachmentContainable]) -> Void = { _ in }
var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
var cancelPanGesture: () -> Void = { }
init(_ params: ContactSelectionControllerParams) {
self.context = params.context

View File

@ -1902,6 +1902,7 @@ webrtc_sources = [
"modules/audio_coding/neteq/timestamp_scaler.h",
"modules/audio_device/audio_device_buffer.h",
"modules/audio_device/audio_device_generic.h",
"modules/audio_device/audio_device_impl.h",
"modules/audio_device/dummy/audio_device_dummy.h",
"modules/audio_device/dummy/file_audio_device.h",
"modules/audio_device/dummy/file_audio_device_factory.h",
@ -2973,6 +2974,7 @@ ios_objc_sources = [
]
ios_sources = [
"objc/native/api/audio_device_module.h",
"objc/native/src/audio/audio_session_observer.h",
"objc/native/src/audio/helpers.h",
"objc/native/src/audio/helpers.mm",