mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Attachment menu improvements
This commit is contained in:
parent
970203e0dc
commit
b8e0fe64f2
@ -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 {
|
||||
|
@ -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()
|
||||
@ -283,6 +284,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]
|
||||
|
@ -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 {
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
@ -1165,3 +1191,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
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
2
third-party/webrtc/BUILD
vendored
2
third-party/webrtc/BUILD
vendored
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user