Various fixes

This commit is contained in:
Ilya Laktyushin 2023-07-14 22:17:06 +02:00
parent 2e09bfe14f
commit 2e6bc7f69d
9 changed files with 132 additions and 61 deletions

View File

@ -1100,9 +1100,6 @@ public struct StoriesConfiguration {
} }
public static func with(appConfiguration: AppConfiguration) -> StoriesConfiguration { public static func with(appConfiguration: AppConfiguration) -> StoriesConfiguration {
//#if DEBUG
// return StoriesConfiguration(posting: .premium)
//#else
if let data = appConfiguration.data, let postingString = data["stories_posting"] as? String { if let data = appConfiguration.data, let postingString = data["stories_posting"] as? String {
var posting: PostingAvailability var posting: PostingAvailability
switch postingString { switch postingString {
@ -1117,7 +1114,6 @@ public struct StoriesConfiguration {
} else { } else {
return .defaultValue return .defaultValue
} }
//#endif
} }
} }

View File

@ -464,6 +464,7 @@ public final class DrawingEntitiesView: UIView, TGPhotoDrawingEntitiesView {
self.selectedEntityView = nil self.selectedEntityView = nil
self.selectionChanged(nil) self.selectionChanged(nil)
self.hasSelectionChanged(false) self.hasSelectionChanged(false)
view.selectionView?.removeFromSuperview()
} }
if animated { if animated {
view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak view] _ in view.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak view] _ in

View File

@ -110,6 +110,8 @@ struct Month: Equatable {
} }
} }
private var savedStoriesContentOffset: CGFloat?
public final class MediaPickerScreen: ViewController, AttachmentContainable { public final class MediaPickerScreen: ViewController, AttachmentContainable {
public enum Subject { public enum Subject {
public enum Media: Equatable { public enum Media: Equatable {
@ -207,7 +209,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
private let containerNode: ASDisplayNode private let containerNode: ASDisplayNode
private let backgroundNode: NavigationBackgroundNode private let backgroundNode: NavigationBackgroundNode
private let gridNode: GridNode fileprivate let gridNode: GridNode
fileprivate var cameraView: TGAttachmentCameraView? fileprivate var cameraView: TGAttachmentCameraView?
private var cameraActivateAreaNode: AccessibilityAreaNode private var cameraActivateAreaNode: AccessibilityAreaNode
private var placeholderNode: MediaPickerPlaceholderNode? private var placeholderNode: MediaPickerPlaceholderNode?
@ -1076,12 +1078,21 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
} }
} }
private var didRestoreContentOffset = false
private func dequeueTransaction() { private func dequeueTransaction() {
if self.enqueuedTransactions.isEmpty { if self.enqueuedTransactions.isEmpty {
return return
} }
let transaction = self.enqueuedTransactions.removeFirst() let transaction = self.enqueuedTransactions.removeFirst()
self.gridNode.transaction(GridNodeTransaction(deleteItems: transaction.deletions, insertItems: transaction.insertions, updateItems: transaction.updates, scrollToItem: transaction.scrollToItem, updateLayout: nil, itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in }) self.gridNode.transaction(GridNodeTransaction(deleteItems: transaction.deletions, insertItems: transaction.insertions, updateItems: transaction.updates, scrollToItem: transaction.scrollToItem, updateLayout: nil, itemTransition: .immediate, stationaryItems: .none, updateFirstIndexInSectionOffset: nil), completion: { _ in })
if let subject = self.controller?.subject, case .assets(_, .story) = subject, let contentOffset = savedStoriesContentOffset, !self.didRestoreContentOffset {
if contentOffset > 64.0 {
self.gridNode.scrollView.setContentOffset(CGPoint(x: 0.0, y: contentOffset), animated: false)
self.controller?.requestAttachmentMenuExpansion()
}
self.didRestoreContentOffset = true
}
} }
func scrollToTop(animated: Bool = false) { func scrollToTop(animated: Bool = false) {
@ -1861,10 +1872,17 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
self.dismiss() self.dismiss()
} }
public override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { public override func dismiss(completion: (() -> Void)? = nil) {
self.controllerNode.cancelAssetDownloads() self.controllerNode.cancelAssetDownloads()
super.dismiss(animated: flag, completion: completion) if case .assets(_, .story) = self.subject {
let contentOffset = self.controllerNode.gridNode.scrollView.contentOffset.y
if contentOffset > 100.0 || savedStoriesContentOffset != nil {
savedStoriesContentOffset = contentOffset
}
}
super.dismiss(completion: completion)
} }
@objc private func rightButtonPressed() { @objc private func rightButtonPressed() {

View File

@ -5744,6 +5744,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return false return false
} }
private var isPanningList = false
@objc func panGesture(_ recognizer: UIPanGestureRecognizer) { @objc func panGesture(_ recognizer: UIPanGestureRecognizer) {
guard let (layout, _) = self.validLayout else { guard let (layout, _) = self.validLayout else {
return return
@ -5765,6 +5766,19 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
self.controller?.dismissAllTooltips() self.controller?.dismissAllTooltips()
let location = recognizer.location(in: self.listContainer.view)
let isPanningList: Bool
if self.listNode.frame.contains(location) {
if case let .known(value) = contentOffset, value <= 0.5 {
isPanningList = false
} else {
isPanningList = true
}
} else {
isPanningList = false
}
self.isPanningList = isPanningList
if case .fullscreen = self.displayMode, case .compact = layout.metrics.widthClass { if case .fullscreen = self.displayMode, case .compact = layout.metrics.widthClass {
self.isPanning = true self.isPanning = true
@ -5789,9 +5803,11 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
return return
} }
let translateBounds: Bool var translateBounds = false
if case .regular = layout.metrics.widthClass { if case .regular = layout.metrics.widthClass {
translateBounds = true if !self.isPanningList {
translateBounds = true
}
} else { } else {
switch self.displayMode { switch self.displayMode {
case let .modal(isExpanded, previousIsFilled): case let .modal(isExpanded, previousIsFilled):
@ -5960,52 +5976,56 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
} else { } else {
self.panGestureArguments = nil self.panGestureArguments = nil
var dismissing = false var dismissing = false
if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) { if case .regular = layout.metrics.widthClass, self.isPanningList {
if self.isScheduling {
self.dismissScheduled() } else {
dismissing = true if bounds.minY < -60 || (bounds.minY < 0.0 && velocity.y > 300.0) {
} else if case .regular = layout.metrics.widthClass { if self.isScheduling {
self.controller?.dismiss(closing: false, manual: true) self.dismissScheduled()
dismissing = true dismissing = true
} else { } else if case .regular = layout.metrics.widthClass {
if case .fullscreen = self.displayMode {
} else {
self.controller?.dismiss(closing: false, manual: true) self.controller?.dismiss(closing: false, manual: true)
dismissing = true dismissing = true
} else {
if case .fullscreen = self.displayMode {
} else {
self.controller?.dismiss(closing: false, manual: true)
dismissing = true
}
} }
} } else if !self.isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) {
} else if !self.isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) { if velocity.y > -2200.0 && !self.isFullscreen {
if velocity.y > -2200.0 && !self.isFullscreen { DispatchQueue.main.async {
DispatchQueue.main.async { self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) }
} }
let initialVelocity: CGFloat = offset.isZero ? 0.0 : abs(velocity.y / offset)
let transition = ContainedViewLayoutTransition.animated(duration: 0.45, curve: .customSpring(damping: 124.0, initialVelocity: initialVelocity))
if case .modal = self.displayMode {
self.displayMode = .modal(isExpanded: true, isFilled: true)
}
self.updateDecorationsColors()
self.animatingExpansion = true
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: transition)
}
self.updateDecorationsLayout(transition: transition, completion: {
self.animatingExpansion = false
})
} else if !self.isScheduling {
self.updateDecorationsColors()
self.animatingExpansion = true
self.listNode.scroller.setContentOffset(CGPoint(), animated: false)
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .easeInOut))
}
self.updateDecorationsLayout(transition: .animated(duration: 0.3, curve: .easeInOut), completion: {
self.animatingExpansion = false
})
} }
let initialVelocity: CGFloat = offset.isZero ? 0.0 : abs(velocity.y / offset)
let transition = ContainedViewLayoutTransition.animated(duration: 0.45, curve: .customSpring(damping: 124.0, initialVelocity: initialVelocity))
if case .modal = self.displayMode {
self.displayMode = .modal(isExpanded: true, isFilled: true)
}
self.updateDecorationsColors()
self.animatingExpansion = true
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: transition)
}
self.updateDecorationsLayout(transition: transition, completion: {
self.animatingExpansion = false
})
} else if !self.isScheduling {
self.updateDecorationsColors()
self.animatingExpansion = true
self.listNode.scroller.setContentOffset(CGPoint(), animated: false)
if let (layout, navigationHeight) = self.validLayout {
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .easeInOut))
}
self.updateDecorationsLayout(transition: .animated(duration: 0.3, curve: .easeInOut), completion: {
self.animatingExpansion = false
})
} }
if !dismissing { if !dismissing {
var bounds = self.contentContainer.bounds var bounds = self.contentContainer.bounds

View File

@ -245,7 +245,16 @@ private final class CameraScreenComponent: CombinedComponent {
func setupRecentAssetSubscription() { func setupRecentAssetSubscription() {
let mediaAssetsContext = MediaAssetsContext() let mediaAssetsContext = MediaAssetsContext()
self.mediaAssetsContext = mediaAssetsContext self.mediaAssetsContext = mediaAssetsContext
self.lastGalleryAssetsDisposable = (mediaAssetsContext.recentAssets()
self.lastGalleryAssetsDisposable = (
mediaAssetsContext.mediaAccess()
|> mapToSignal { [weak mediaAssetsContext] status in
if case .authorized = status, let mediaAssetsContext {
return mediaAssetsContext.recentAssets()
} else {
return .complete()
}
}
|> map { fetchResult in |> map { fetchResult in
return fetchResult?.lastObject return fetchResult?.lastObject
} }
@ -258,6 +267,13 @@ private final class CameraScreenComponent: CombinedComponent {
}) })
} }
func requestMediaAccess(completion: @escaping () -> Void) {
guard let mediaAssetsContext = self.mediaAssetsContext else {
return
}
mediaAssetsContext.requestMediaAccess(completion: completion)
}
func setupVolumeButtonsHandler() { func setupVolumeButtonsHandler() {
guard self.volumeButtonsListener == nil else { guard self.volumeButtonsListener == nil else {
return return
@ -687,11 +703,13 @@ private final class CameraScreenComponent: CombinedComponent {
} }
state.togglePosition(animateFlipAction) state.togglePosition(animateFlipAction)
}, },
galleryTapped: { galleryTapped: { [weak state] in
guard let controller = environment.controller() as? CameraScreen else { guard let controller = environment.controller() as? CameraScreen else {
return return
} }
controller.presentGallery() state?.requestMediaAccess {
controller.presentGallery()
}
}, },
swipeHintUpdated: { [weak state] hint in swipeHintUpdated: { [weak state] hint in
if let state { if let state {

View File

@ -95,8 +95,13 @@ public final class MediaAssetsContext: NSObject, PHPhotoLibraryChangeObserver {
) )
} }
public func requestMediaAccess() -> Void { public func requestMediaAccess(completion: @escaping () -> Void = {}) -> Void {
PHPhotoLibrary.requestAuthorization { [weak self] status in PHPhotoLibrary.requestAuthorization { [weak self] status in
Queue.mainQueue().async {
if case .authorized = status {
completion()
}
}
self?.mediaAccessSink.putNext(status) self?.mediaAccessSink.putNext(status)
} }
} }

View File

@ -3799,7 +3799,7 @@ public final class EmojiPagerContentComponent: Component {
} }
} }
contextGesture.activatedAfterCompletion = { [weak self] point, wasTap in contextGesture.activatedAfterCompletion = { [weak self] point, wasTap in
guard let `self` = self, let component = self.component else { guard let self, let component = self.component, !self.isSearchActivated else {
return return
} }

View File

@ -1038,13 +1038,15 @@ final class MediaEditorScreenComponent: Component {
isGeneralThreadClosed: nil isGeneralThreadClosed: nil
) )
let heightAndOverflow = inputMediaNode.updateLayout(width: availableSize.width, leftInset: 0.0, rightInset: 0.0, bottomInset: component.bottomSafeInset, standardInputHeight: environment.deviceMetrics.standardInputHeight(inLandscape: false), inputHeight: environment.inputHeight, maximumHeight: availableSize.height, inputPanelHeight: 0.0, transition: .immediate, interfaceState: presentationInterfaceState, layoutMetrics: environment.metrics, deviceMetrics: environment.deviceMetrics, isVisible: true, isExpanded: false) let availableInputMediaWidth = previewSize.width
let heightAndOverflow = inputMediaNode.updateLayout(width: availableInputMediaWidth, leftInset: 0.0, rightInset: 0.0, bottomInset: component.bottomSafeInset, standardInputHeight: environment.deviceMetrics.standardInputHeight(inLandscape: false), inputHeight: environment.inputHeight, maximumHeight: availableSize.height, inputPanelHeight: 0.0, transition: .immediate, interfaceState: presentationInterfaceState, layoutMetrics: environment.metrics, deviceMetrics: environment.deviceMetrics, isVisible: true, isExpanded: false)
let inputNodeHeight = heightAndOverflow.0 let inputNodeHeight = heightAndOverflow.0
let inputNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - inputNodeHeight), size: CGSize(width: availableSize.width, height: inputNodeHeight)) let inputNodeFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((availableSize.width - availableInputMediaWidth) / 2.0), y: availableSize.height - inputNodeHeight), size: CGSize(width: availableInputMediaWidth, height: inputNodeHeight))
transition.setFrame(layer: inputMediaNode.layer, frame: inputNodeFrame) transition.setFrame(layer: inputMediaNode.layer, frame: inputNodeFrame)
inputHeight = heightAndOverflow.0 if inputNodeHeight > 0.0 {
keyboardHeight = max(keyboardHeight, heightAndOverflow.0) inputHeight = inputNodeHeight
}
} else if let inputMediaNode = self.inputMediaNode { } else if let inputMediaNode = self.inputMediaNode {
self.inputMediaNode = nil self.inputMediaNode = nil
@ -1074,6 +1076,8 @@ final class MediaEditorScreenComponent: Component {
}) })
} }
keyboardHeight = inputHeight
let nextInputMode: MessageInputPanelComponent.InputMode let nextInputMode: MessageInputPanelComponent.InputMode
switch self.currentInputMode { switch self.currentInputMode {
case .text: case .text:

View File

@ -305,6 +305,7 @@ final class ShareWithPeersScreenComponent: Component {
private var ignoreScrolling: Bool = false private var ignoreScrolling: Bool = false
private var isDismissed: Bool = false private var isDismissed: Bool = false
private var savedSelectedPeers: [EnginePeer.Id] = []
private var selectedPeers: [EnginePeer.Id] = [] private var selectedPeers: [EnginePeer.Id] = []
private var selectedCategories = Set<CategoryId>() private var selectedCategories = Set<CategoryId>()
private var selectedOptions = Set<OptionId>() private var selectedOptions = Set<OptionId>()
@ -586,6 +587,7 @@ final class ShareWithPeersScreenComponent: Component {
visibleBounds.size.height += itemLayout.topInset visibleBounds.size.height += itemLayout.topInset
var visibleFrame = self.scrollView.frame var visibleFrame = self.scrollView.frame
visibleFrame.origin.x = 0.0
visibleFrame.origin.y -= itemLayout.topInset visibleFrame.origin.y -= itemLayout.topInset
visibleFrame.size.height += itemLayout.topInset visibleFrame.size.height += itemLayout.topInset
@ -675,7 +677,7 @@ final class ShareWithPeersScreenComponent: Component {
if minSectionHeader == nil { if minSectionHeader == nil {
minSectionHeader = sectionHeaderView minSectionHeader = sectionHeaderView
} }
sectionHeaderTransition.setFrame(view: sectionHeaderView, frame: sectionHeaderFrame) sectionHeaderTransition.setFrame(view: sectionHeaderView, frame: sectionHeaderFrame.offsetBy(dx: self.scrollView.frame.minX, dy: 0.0))
} }
} }
} }
@ -721,7 +723,14 @@ final class ShareWithPeersScreenComponent: Component {
} }
if self.selectedCategories.contains(categoryId) { if self.selectedCategories.contains(categoryId) {
} else { } else {
self.selectedPeers = [] if self.selectedCategories.contains(.selectedContacts) {
self.savedSelectedPeers = self.selectedPeers
}
if categoryId == .selectedContacts {
self.selectedPeers = self.savedSelectedPeers
} else {
self.selectedPeers = []
}
self.selectedCategories.removeAll() self.selectedCategories.removeAll()
self.selectedCategories.insert(categoryId) self.selectedCategories.insert(categoryId)