mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Merge commit 'd5b2d433635831d8b1e193dc6741b02810855f8b'
# Conflicts: # submodules/TelegramUI/Sources/AppDelegate.swift
This commit is contained in:
commit
6dd073e114
@ -352,6 +352,12 @@ public class AttachmentController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
self.panel.longPressed = { [weak self] _ in
|
||||
if let strongSelf = self, let currentController = strongSelf.currentControllers.last {
|
||||
currentController.longTapWithTabBar?()
|
||||
}
|
||||
}
|
||||
|
||||
self.panel.beganTextEditing = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.container.update(isExpanded: true, transition: .animated(duration: 0.4, curve: .spring))
|
||||
|
@ -124,6 +124,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
||||
let strings: PresentationStrings
|
||||
let theme: PresentationTheme
|
||||
let action: () -> Void
|
||||
let longPressAction: () -> Void
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
@ -131,7 +132,8 @@ private final class AttachButtonComponent: CombinedComponent {
|
||||
isSelected: Bool,
|
||||
strings: PresentationStrings,
|
||||
theme: PresentationTheme,
|
||||
action: @escaping () -> Void
|
||||
action: @escaping () -> Void,
|
||||
longPressAction: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.type = type
|
||||
@ -139,6 +141,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
||||
self.strings = strings
|
||||
self.theme = theme
|
||||
self.action = action
|
||||
self.longPressAction = longPressAction
|
||||
}
|
||||
|
||||
static func ==(lhs: AttachButtonComponent, rhs: AttachButtonComponent) -> Bool {
|
||||
@ -293,6 +296,11 @@ private final class AttachButtonComponent: CombinedComponent {
|
||||
.gesture(.tap {
|
||||
component.action()
|
||||
})
|
||||
.gesture(.longPress({ state in
|
||||
if case .began = state {
|
||||
component.longPressAction()
|
||||
}
|
||||
}))
|
||||
)
|
||||
|
||||
return context.availableSize
|
||||
@ -495,6 +503,8 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
var isStandalone: Bool = false
|
||||
|
||||
var selectionChanged: (AttachmentButtonType) -> Bool = { _ in return false }
|
||||
var longPressed: (AttachmentButtonType) -> Void = { _ in }
|
||||
|
||||
var beganTextEditing: () -> Void = {}
|
||||
var textUpdated: (NSAttributedString) -> Void = { _ in }
|
||||
var sendMessagePressed: (AttachmentTextInputPanelSendMode) -> Void = { _ in }
|
||||
@ -874,6 +884,10 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, longPressAction: { [weak self] in
|
||||
if let strongSelf = self, i == strongSelf.selectedIndex {
|
||||
strongSelf.longPressed(type)
|
||||
}
|
||||
})
|
||||
),
|
||||
environment: {},
|
||||
|
@ -128,6 +128,8 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
|
||||
private weak var copyProtectionTooltipController: TooltipController?
|
||||
|
||||
private lazy var hapticFeedback = { HapticFeedback() }()
|
||||
|
||||
private var didSetReady: Bool = false
|
||||
private let _ready = Promise<Void>()
|
||||
public override func ready() -> Signal<Void, NoError> {
|
||||
@ -1392,6 +1394,10 @@ public final class ChatListSearchContainerNode: SearchDisplayControllerContentNo
|
||||
let peerId = peer.id
|
||||
if let strongSelf = self, let _ = peerSelectionController {
|
||||
if peerId == strongSelf.context.account.peerId {
|
||||
Queue.mainQueue().after(0.88) {
|
||||
strongSelf.hapticFeedback.success()
|
||||
}
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
(strongSelf.navigationController?.topViewController as? ViewController)?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .window(.root))
|
||||
|
||||
|
@ -516,16 +516,51 @@ public final class ComposedPoll {
|
||||
}
|
||||
}
|
||||
|
||||
private class CreatePollControllerImpl: ItemListController, AttachmentContainable {
|
||||
private final class CreatePollContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(silently: Bool, mode: AttachmentMediaPickerSendMode) {
|
||||
}
|
||||
|
||||
func schedule() {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class CreatePollControllerImpl: ItemListController, AttachmentContainable {
|
||||
public var requestAttachmentMenuExpansion: () -> Void = {}
|
||||
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in }
|
||||
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
|
||||
public var cancelPanGesture: () -> Void = { }
|
||||
public var isContainerPanning: () -> Bool = { return false }
|
||||
public var isContainerExpanded: () -> Bool = { return false }
|
||||
|
||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||
return CreatePollContext()
|
||||
}
|
||||
}
|
||||
|
||||
public func createPollController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (ComposedPoll) -> Void) -> AttachmentContainable {
|
||||
public func createPollController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, isQuiz: Bool? = nil, completion: @escaping (ComposedPoll) -> Void) -> CreatePollControllerImpl {
|
||||
var initialState = CreatePollControllerState()
|
||||
if let isQuiz = isQuiz {
|
||||
initialState.isQuiz = isQuiz
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
@interface DeviceProximityManager : NSObject
|
||||
|
||||
@property (nonatomic, copy) void(^ _Nullable proximityChanged)(bool);
|
||||
|
||||
+ (DeviceProximityManager * _Nonnull)shared;
|
||||
|
||||
- (bool)currentValue;
|
||||
|
@ -46,6 +46,9 @@
|
||||
for (void (^f)(bool) in [strongSelf->_subscribers copyItems]) {
|
||||
f(proximityState);
|
||||
}
|
||||
if (strongSelf.proximityChanged != nil) {
|
||||
strongSelf.proximityChanged(proximityState);
|
||||
}
|
||||
} else if (!strongSelf->_proximityState && [strongSelf->_subscribers isEmpty]) {
|
||||
[UIDevice currentDevice].proximityMonitoringEnabled = false;
|
||||
}
|
||||
@ -90,6 +93,9 @@
|
||||
for (void (^f)(bool) in [_subscribers copyItems]) {
|
||||
f(_proximityState);
|
||||
}
|
||||
if (self.proximityChanged != nil) {
|
||||
self.proximityChanged(_proximityState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_proximityState) {
|
||||
@ -97,6 +103,9 @@
|
||||
for (void (^f)(bool) in [_subscribers copyItems]) {
|
||||
f(_proximityState);
|
||||
}
|
||||
if (self.proximityChanged != nil) {
|
||||
self.proximityChanged(_proximityState);
|
||||
}
|
||||
} else {
|
||||
[UIDevice currentDevice].proximityMonitoringEnabled = false;
|
||||
}
|
||||
|
@ -351,7 +351,7 @@ public func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> U
|
||||
let t = CGFloat(i) / CGFloat(colors.count - 1)
|
||||
locations.append(t)
|
||||
}
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
|
||||
@ -381,7 +381,7 @@ public func generateGradientImage(size: CGSize, colors: [UIColor], locations: [C
|
||||
UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
|
||||
if let context = UIGraphicsGetCurrentContext() {
|
||||
let gradientColors = colors.map { $0.cgColor } as CFArray
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||
|
||||
var locations = locations
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
|
||||
@ -403,7 +403,7 @@ public func generateGradientFilledCircleImage(diameter: CGFloat, colors: NSArray
|
||||
context.clip()
|
||||
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let colorSpace = DeviceGraphicsContextSettings.shared.colorSpace
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(), end: CGPoint(x: 0.0, y: bounds.size.height), options: CGGradientDrawingOptions())
|
||||
|
@ -433,8 +433,12 @@ open class NavigationController: UINavigationController, ContainableController,
|
||||
minHeight = 40.0
|
||||
}
|
||||
var inCallStatusBarFrame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: max(layout.statusBarHeight ?? 0.0, max(minHeight, layout.safeInsets.top))))
|
||||
if (layout.deviceMetrics.hasTopNotch || layout.deviceMetrics.hasDynamicIsland) && !isLandscape {
|
||||
if !isLandscape {
|
||||
if layout.deviceMetrics.hasTopNotch {
|
||||
inCallStatusBarFrame.size.height += 12.0
|
||||
} else if layout.deviceMetrics.hasDynamicIsland {
|
||||
inCallStatusBarFrame.size.height += 20.0
|
||||
}
|
||||
}
|
||||
if inCallStatusBar.frame.isEmpty {
|
||||
inCallStatusBar.frame = inCallStatusBarFrame
|
||||
|
@ -1190,6 +1190,7 @@ open class NavigationBar: ASDisplayNode {
|
||||
|
||||
self.badgeNode.updateTheme(fillColor: self.presentationData.theme.buttonColor, strokeColor: self.presentationData.theme.buttonColor, textColor: self.presentationData.theme.badgeTextColor)
|
||||
|
||||
self.updateLeftButton(animated: false)
|
||||
self.requestLayout()
|
||||
}
|
||||
}
|
||||
|
@ -1510,7 +1510,7 @@ open class TextNode: ASDisplayNode {
|
||||
continue
|
||||
}
|
||||
|
||||
var fixCoupleEmoji = false
|
||||
var fixDoubleEmoji = false
|
||||
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
|
||||
let range = CTRunGetStringRange(run)
|
||||
let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string
|
||||
@ -1518,17 +1518,21 @@ open class TextNode: ASDisplayNode {
|
||||
let heart = Unicode.Scalar(0x2764)!
|
||||
let man = Unicode.Scalar(0x1F468)!
|
||||
let woman = Unicode.Scalar(0x1F469)!
|
||||
let leftHand = Unicode.Scalar(0x1FAF1)!
|
||||
let rightHand = Unicode.Scalar(0x1FAF2)!
|
||||
|
||||
if substring.unicodeScalars.contains(heart) && (substring.unicodeScalars.contains(man) || substring.unicodeScalars.contains(woman)) {
|
||||
fixCoupleEmoji = true
|
||||
fixDoubleEmoji = true
|
||||
} else if substring.unicodeScalars.contains(leftHand) && substring.unicodeScalars.contains(rightHand) {
|
||||
fixDoubleEmoji = true
|
||||
}
|
||||
}
|
||||
|
||||
if fixCoupleEmoji {
|
||||
if fixDoubleEmoji {
|
||||
context.setBlendMode(.normal)
|
||||
}
|
||||
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
|
||||
if fixCoupleEmoji {
|
||||
if fixDoubleEmoji {
|
||||
context.setBlendMode(blendMode)
|
||||
}
|
||||
}
|
||||
|
@ -241,6 +241,7 @@ public final class WindowKeyboardGestureRecognizerDelegate: NSObject, UIGestureR
|
||||
public class Window1 {
|
||||
public let hostView: WindowHostView
|
||||
public let badgeView: UIImageView
|
||||
private let customProximityDimView: UIView
|
||||
|
||||
private var deviceMetrics: DeviceMetrics
|
||||
|
||||
@ -257,8 +258,6 @@ public class Window1 {
|
||||
private var updatingLayout: UpdatingLayout?
|
||||
private var updatedContainerLayout: ContainerViewLayout?
|
||||
private var upperKeyboardInputPositionBound: CGFloat?
|
||||
private var cachedWindowSubviewCount: Int = 0
|
||||
private var cachedHasPreview: Bool = false
|
||||
|
||||
private let presentationContext: PresentationContext
|
||||
private let overlayPresentationContext: GlobalOverlayPresentationContext
|
||||
@ -271,9 +270,6 @@ public class Window1 {
|
||||
|
||||
private var statusBarHidden = false
|
||||
|
||||
public var previewThemeAccentColor: UIColor = .blue
|
||||
public var previewThemeDarkBlur: Bool = false
|
||||
|
||||
private var shouldNotAnimateLikelyKeyboardAutocorrectionSwitch: Bool = false
|
||||
|
||||
public private(set) var forceInCallStatusBarText: String? = nil
|
||||
@ -333,6 +329,10 @@ public class Window1 {
|
||||
self.badgeView.image = UIImage(bundleImageName: "Components/AppBadge")
|
||||
self.badgeView.isHidden = true
|
||||
|
||||
self.customProximityDimView = UIView()
|
||||
self.customProximityDimView.backgroundColor = .black
|
||||
self.customProximityDimView.isHidden = true
|
||||
|
||||
self.systemUserInterfaceStyle = hostView.systemUserInterfaceStyle
|
||||
|
||||
let boundsSize = self.hostView.eventView.bounds.size
|
||||
@ -652,6 +652,7 @@ public class Window1 {
|
||||
self.windowPanRecognizer = recognizer
|
||||
self.hostView.containerView.addGestureRecognizer(recognizer)
|
||||
self.hostView.containerView.addSubview(self.badgeView)
|
||||
self.hostView.containerView.addSubview(self.customProximityDimView)
|
||||
}
|
||||
|
||||
public required init(coder aDecoder: NSCoder) {
|
||||
@ -685,6 +686,13 @@ public class Window1 {
|
||||
self.updateBadgeVisibility()
|
||||
}
|
||||
|
||||
public func setProximityDimHidden(_ hidden: Bool) {
|
||||
guard hidden != self.customProximityDimView.isHidden else {
|
||||
return
|
||||
}
|
||||
self.customProximityDimView.isHidden = hidden
|
||||
}
|
||||
|
||||
private func updateBadgeVisibility() {
|
||||
let badgeIsHidden = !self.deviceMetrics.showAppBadge || self.forceBadgeHidden || self.windowLayout.size.width > self.windowLayout.size.height
|
||||
if badgeIsHidden != self.badgeView.isHidden && !badgeIsHidden {
|
||||
@ -1141,6 +1149,8 @@ public class Window1 {
|
||||
self.updateBadgeVisibility()
|
||||
self.badgeView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((self.windowLayout.size.width - image.size.width) / 2.0), y: 5.0), size: image.size)
|
||||
}
|
||||
|
||||
self.customProximityDimView.frame = CGRect(origin: .zero, size: self.windowLayout.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1112,6 +1112,10 @@ public class GalleryController: ViewController, StandalonePresentableController,
|
||||
|
||||
let animatedOutNode = !simpleAnimation
|
||||
|
||||
if let chatController = strongSelf.baseNavigationController?.topViewController as? ChatController {
|
||||
chatController.updatePushedTransition(0.0, transition: .animated(duration: 0.45, curve: .customSpring(damping: 180.0, initialVelocity: 0.0)))
|
||||
}
|
||||
|
||||
strongSelf.galleryNode.animateOut(animateContent: animatedOutNode, completion: {
|
||||
})
|
||||
}
|
||||
|
@ -363,4 +363,38 @@ public final class LocationPickerController: ViewController, AttachmentContainab
|
||||
self.interaction?.dismissSearch()
|
||||
self.scrollToTop?()
|
||||
}
|
||||
|
||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||
return LocationPickerContext()
|
||||
}
|
||||
}
|
||||
|
||||
private final class LocationPickerContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(silently: Bool, mode: AttachmentMediaPickerSendMode) {
|
||||
}
|
||||
|
||||
func schedule() {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ private final class MediaGroupsGridAlbumItemNode : ListViewItemNode {
|
||||
override func didLoad() {
|
||||
super.didLoad()
|
||||
|
||||
self.imageNode.cornerRadius = 10.0
|
||||
self.imageNode.cornerRadius = 5.0
|
||||
if #available(iOS 13.0, *) {
|
||||
self.imageNode.layer.cornerCurve = .continuous
|
||||
}
|
||||
@ -221,11 +221,11 @@ private func preparedTransition(action: @escaping (PHAssetCollection) -> Void, f
|
||||
}
|
||||
|
||||
final class MediaGroupsAlbumGridItem: ListViewItem {
|
||||
let presentationData: ItemListPresentationData
|
||||
let presentationData: PresentationData
|
||||
let collections: [PHAssetCollection]
|
||||
let action: (PHAssetCollection) -> Void
|
||||
|
||||
public init(presentationData: ItemListPresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) {
|
||||
public init(presentationData: PresentationData, collections: [PHAssetCollection], action: @escaping (PHAssetCollection) -> Void) {
|
||||
self.presentationData = presentationData
|
||||
self.collections = collections
|
||||
self.action = action
|
||||
@ -347,7 +347,8 @@ private class MediaGroupsAlbumGridItemNode: ListViewItemNode {
|
||||
firstItem = result.firstObject
|
||||
}
|
||||
if let firstItem = firstItem {
|
||||
entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: presentationStringsFormattedNumber(Int32(result.count))))
|
||||
let count = presentationStringsFormattedNumber(Int32(result.count), item.presentationData.dateTimeFormat.groupingSeparator)
|
||||
entries.append(MediaGroupsGridAlbumEntry(theme: item.presentationData.theme, index: index, collection: collection, firstItem: firstItem, count: count))
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ private enum MediaGroupsEntry: Comparable, Identifiable {
|
||||
case let .albumsHeader(_, text), let .smartAlbumsHeader(_, text):
|
||||
return MediaGroupsHeaderItem(presentationData: ItemListPresentationData(presentationData), title: text)
|
||||
case let .albums(_, collections):
|
||||
return MediaGroupsAlbumGridItem(presentationData: ItemListPresentationData(presentationData), collections: collections, action: { collection in
|
||||
return MediaGroupsAlbumGridItem(presentationData: presentationData, collections: collections, action: { collection in
|
||||
openGroup(collection)
|
||||
})
|
||||
case let .smartAlbum(_, _, collection, count):
|
||||
|
@ -154,7 +154,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
public var openCamera: ((TGAttachmentCameraView?) -> Void)?
|
||||
public var presentSchedulePicker: (Bool, @escaping (Int32) -> Void) -> Void = { _, _ in }
|
||||
public var presentTimerPicker: (@escaping (Int32) -> Void) -> Void = { _ in }
|
||||
public var presentWebSearch: (MediaGroupsScreen) -> Void = { _ in }
|
||||
public var presentWebSearch: (MediaGroupsScreen, Bool) -> Void = { _, _ in }
|
||||
public var getCaptionPanelView: () -> TGCaptionPanelView? = { return nil }
|
||||
|
||||
private var completed = false
|
||||
@ -1350,6 +1350,12 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
}
|
||||
|
||||
self.updateSelectionState(count: Int32(selectionContext.count()))
|
||||
|
||||
self.longTapWithTabBar = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.presentSearch(activateOnDisplay: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
@ -1572,9 +1578,10 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
self.controllerNode.updateNavigation(delayDisappear: true, transition: .immediate)
|
||||
}
|
||||
|
||||
@objc private func searchOrMorePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) {
|
||||
switch self.moreButtonNode.iconNode.iconState {
|
||||
case .search:
|
||||
private func presentSearch(activateOnDisplay: Bool) {
|
||||
guard self.moreButtonNode.iconNode.iconState == .search else {
|
||||
return
|
||||
}
|
||||
self.requestAttachmentMenuExpansion()
|
||||
self.presentWebSearch(MediaGroupsScreen(context: self.context, updatedPresentationData: self.updatedPresentationData, mediaAssetsContext: self.controllerNode.mediaAssetsContext, openGroup: { [weak self] collection in
|
||||
if let strongSelf = self {
|
||||
@ -1592,7 +1599,13 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
mediaPicker.updateNavigationStack = strongSelf.updateNavigationStack
|
||||
strongSelf.updateNavigationStack({ _ in return ([strongSelf, mediaPicker], strongSelf.mediaPickerContext)})
|
||||
}
|
||||
}))
|
||||
}), activateOnDisplay)
|
||||
}
|
||||
|
||||
@objc private func searchOrMorePressed(node: ContextReferenceContentNode, gesture: ContextGesture?) {
|
||||
switch self.moreButtonNode.iconNode.iconState {
|
||||
case .search:
|
||||
self.presentSearch(activateOnDisplay: true)
|
||||
case .more:
|
||||
let strings = self.presentationData.strings
|
||||
let selectionCount = self.selectionCount
|
||||
|
@ -272,6 +272,7 @@ private func scanFiles(at path: String, olderThan minTimestamp: Int32, includeSu
|
||||
}*/
|
||||
|
||||
private func statForDirectory(path: String) -> Int64 {
|
||||
if #available(macOS 10.13, *) {
|
||||
var s = darwin_dirstat()
|
||||
var result = dirstat_np(path, 1, &s, MemoryLayout<darwin_dirstat>.size)
|
||||
if result != -1 {
|
||||
@ -284,6 +285,17 @@ private func statForDirectory(path: String) -> Int64 {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let fileManager = FileManager.default
|
||||
let folderURL = URL(fileURLWithPath: path)
|
||||
var folderSize: Int64 = 0
|
||||
if let files = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) {
|
||||
for file in files {
|
||||
folderSize += (fileSize(file.path) ?? 0)
|
||||
}
|
||||
}
|
||||
return folderSize
|
||||
}
|
||||
}
|
||||
|
||||
private final class TimeBasedCleanupImpl {
|
||||
|
@ -612,7 +612,18 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
|
||||
func updatePresentationData(_ presentationData: PresentationData) {
|
||||
let stringsUpdated = self.presentationData.strings !== presentationData.strings
|
||||
self.presentationData = presentationData
|
||||
|
||||
if stringsUpdated {
|
||||
if let snapshotView = self.view.snapshotView(afterScreenUpdates: false) {
|
||||
self.view.addSubview(snapshotView)
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
self.presentationDataValue.set(.single(presentationData))
|
||||
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
|
||||
self.listNode.keepTopItemOverscrollBackground = ListViewKeepTopItemOverscrollBackground(color: presentationData.theme.list.blocksBackgroundColor, direction: true)
|
||||
|
@ -876,7 +876,14 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
})
|
||||
self.completed?(peerIds)
|
||||
|
||||
Queue.mainQueue().after(0.44) {
|
||||
let delay: Double
|
||||
if let peerId = peerIds.first, peerIds.count == 1 && peerId == self.context?.account.peerId {
|
||||
delay = 0.88
|
||||
} else {
|
||||
delay = 0.44
|
||||
}
|
||||
|
||||
Queue.mainQueue().after(delay) {
|
||||
if self.hapticFeedback == nil {
|
||||
self.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
|
@ -2658,6 +2658,9 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
||||
if let strongSelf = self {
|
||||
strongSelf.call.setShouldBeRecording(false, title: nil, videoOrientation: nil)
|
||||
|
||||
Queue.mainQueue().after(0.88) {
|
||||
strongSelf.hapticFeedback.success()
|
||||
}
|
||||
|
||||
let text: String
|
||||
if let channel = strongSelf.peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
@ -2665,7 +2668,6 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
|
||||
} else {
|
||||
text = strongSelf.presentationData.strings.VideoChat_RecordingSaved
|
||||
}
|
||||
|
||||
strongSelf.presentUndoOverlay(content: .forward(savedMessages: true, text: text), action: { [weak self] value in
|
||||
if case .info = value, let strongSelf = self, let navigationController = strongSelf.controller?.navigationController as? NavigationController {
|
||||
let context = strongSelf.context
|
||||
|
@ -292,7 +292,7 @@ func managedProfilePhotoEmoji(postbox: Postbox, network: Network) -> Signal<Void
|
||||
|
||||
func managedGroupPhotoEmoji(postbox: Postbox, network: Network) -> Signal<Void, NoError> {
|
||||
let poll = managedRecentMedia(postbox: postbox, network: network, collectionId: Namespaces.OrderedItemList.CloudFeaturedGroupPhotoEmoji, extractItemId: { RecentMediaItemId($0).mediaId.id }, reverseHashOrder: false, forceFetch: false, fetch: { hash in
|
||||
return network.request(Api.functions.account.getDefaultProfilePhotoEmojis(hash: hash))
|
||||
return network.request(Api.functions.account.getDefaultGroupPhotoEmojis(hash: hash))
|
||||
|> retryRequest
|
||||
|> mapToSignal { result -> Signal<[OrderedItemListEntry]?, NoError> in
|
||||
switch result {
|
||||
|
@ -143,6 +143,7 @@ private extension StorageUsageStats {
|
||||
}
|
||||
|
||||
private func statForDirectory(path: String) -> Int64 {
|
||||
if #available(macOS 10.13, *) {
|
||||
var s = darwin_dirstat()
|
||||
var result = dirstat_np(path, 1, &s, MemoryLayout<darwin_dirstat>.size)
|
||||
if result != -1 {
|
||||
@ -155,6 +156,17 @@ private func statForDirectory(path: String) -> Int64 {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let fileManager = FileManager.default
|
||||
let folderURL = URL(fileURLWithPath: path)
|
||||
var folderSize: Int64 = 0
|
||||
if let files = try? fileManager.contentsOfDirectory(at: folderURL, includingPropertiesForKeys: nil, options: []) {
|
||||
for file in files {
|
||||
folderSize += (fileSize(file.path) ?? 0)
|
||||
}
|
||||
}
|
||||
return folderSize
|
||||
}
|
||||
}
|
||||
|
||||
private func collectDirectoryUsageReportRecursive(path: String, indent: String, log: inout String) {
|
||||
|
@ -302,7 +302,7 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
public var switchToTextInput: (() -> Void)?
|
||||
|
||||
private var currentState: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool)?
|
||||
private var currentState: (width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool)?
|
||||
|
||||
private var scheduledContentAnimationHint: EmojiPagerContentComponent.ContentAnimation?
|
||||
private var scheduledInnerTransition: Transition?
|
||||
@ -1690,22 +1690,22 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
}
|
||||
|
||||
private func performLayout(transition: Transition) {
|
||||
guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.currentState else {
|
||||
guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.currentState else {
|
||||
return
|
||||
}
|
||||
self.scheduledInnerTransition = transition
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
|
||||
public func simulateUpdateLayout(isVisible: Bool) {
|
||||
guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, _, isExpanded) = self.currentState else {
|
||||
guard let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, _, isExpanded) = self.currentState else {
|
||||
return
|
||||
}
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
|
||||
public override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
self.currentState = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded)
|
||||
public override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
self.currentState = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded)
|
||||
|
||||
let innerTransition: Transition
|
||||
if let scheduledInnerTransition = self.scheduledInnerTransition {
|
||||
@ -1774,13 +1774,17 @@ public final class ChatEntityKeyboardInputNode: ChatInputNode {
|
||||
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
|
||||
var keyboardBottomInset = bottomInset
|
||||
if case .regular = layoutMetrics.widthClass, inputHeight > 0.0 && inputHeight < 100.0 {
|
||||
keyboardBottomInset = inputHeight + 15.0
|
||||
}
|
||||
let entityKeyboardSize = self.entityKeyboardView.update(
|
||||
transition: mappedTransition,
|
||||
component: AnyComponent(EntityKeyboardComponent(
|
||||
theme: interfaceState.theme,
|
||||
strings: interfaceState.strings,
|
||||
isContentInFocus: isVisible,
|
||||
containerInsets: UIEdgeInsets(top: self.isEmojiSearchActive ? -34.0 : 0.0, left: leftInset, bottom: bottomInset, right: rightInset),
|
||||
containerInsets: UIEdgeInsets(top: self.isEmojiSearchActive ? -34.0 : 0.0, left: leftInset, bottom: keyboardBottomInset, right: rightInset),
|
||||
topPanelInsets: UIEdgeInsets(),
|
||||
emojiContent: emojiContent,
|
||||
stickerContent: stickerContent,
|
||||
@ -2427,6 +2431,7 @@ public final class EntityInputView: UIInputView, AttachmentTextInputPanelInputVi
|
||||
inputPanelHeight: 0.0,
|
||||
transition: .immediate,
|
||||
interfaceState: presentationInterfaceState,
|
||||
layoutMetrics: LayoutMetrics(widthClass: .compact, heightClass: .compact),
|
||||
deviceMetrics: DeviceMetrics.iPhone12,
|
||||
isVisible: true,
|
||||
isExpanded: false
|
||||
|
@ -28,7 +28,7 @@ open class ChatInputNode: ASDisplayNode {
|
||||
|
||||
}
|
||||
|
||||
open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
open func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
return (0.0, 0.0)
|
||||
}
|
||||
}
|
||||
|
@ -7141,7 +7141,7 @@ public final class EmojiPagerContentComponent: Component {
|
||||
topReactions = orderedView
|
||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji {
|
||||
featuredAvatarEmoji = orderedView
|
||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedProfilePhotoEmoji {
|
||||
} else if orderedView.collectionId == Namespaces.OrderedItemList.CloudFeaturedGroupPhotoEmoji {
|
||||
featuredAvatarEmoji = orderedView
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ import StoreKit
|
||||
import PhoneNumberFormat
|
||||
import AuthorizationUI
|
||||
import ManagedFile
|
||||
import DeviceProximity
|
||||
|
||||
#if canImport(AppCenter)
|
||||
import AppCenter
|
||||
@ -338,6 +339,7 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||
|
||||
let launchIconSize = CGSize(width: 99.0, height: 99.0)
|
||||
let launchIconView = UIImageView(image: UIImage(bundleImageName: "Components/LaunchLogo"))
|
||||
launchIconView.autoresizingMask = [.flexibleTopMargin, .flexibleLeftMargin, .flexibleRightMargin, .flexibleBottomMargin]
|
||||
launchIconView.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((hostView.containerView.frame.width - launchIconSize.width) / 2.0), y: floorToScreenPixels((hostView.containerView.frame.height - launchIconSize.height) / 2.0)), size: launchIconSize)
|
||||
hostView.containerView.addSubview(launchIconView)
|
||||
|
||||
@ -1336,6 +1338,13 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||
self.runForegroundTasks()
|
||||
}
|
||||
|
||||
|
||||
DeviceProximityManager.shared().proximityChanged = { [weak self] value in
|
||||
if let strongSelf = self {
|
||||
strongSelf.mainWindow.setProximityDimHidden(!value)
|
||||
}
|
||||
}
|
||||
|
||||
if UIApplication.shared.isStatusBarHidden {
|
||||
UIApplication.shared.internalSetStatusBarHidden(false, animation: .none)
|
||||
}
|
||||
|
@ -165,9 +165,6 @@ final class AuthorizedApplicationContext {
|
||||
|
||||
self.notificationController = NotificationContainerController(context: context)
|
||||
|
||||
self.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
||||
self.mainWindow.previewThemeDarkBlur = presentationData.theme.rootController.keyboardColor == .dark
|
||||
|
||||
self.rootController = TelegramRootController(context: context)
|
||||
|
||||
self.rootController.globalOverlayControllersUpdated = { [weak self] in
|
||||
@ -735,8 +732,6 @@ final class AuthorizedApplicationContext {
|
||||
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||
if let strongSelf = self {
|
||||
if previousTheme.swap(presentationData.theme) !== presentationData.theme {
|
||||
strongSelf.mainWindow.previewThemeAccentColor = presentationData.theme.rootController.navigationBar.accentTextColor
|
||||
strongSelf.mainWindow.previewThemeDarkBlur = presentationData.theme.rootController.keyboardColor == .dark
|
||||
strongSelf.lockedCoveringView.updateTheme(presentationData.theme)
|
||||
strongSelf.rootController.updateTheme(NavigationControllerTheme(presentationTheme: presentationData.theme))
|
||||
}
|
||||
|
@ -163,7 +163,37 @@ private func attachmentFileControllerEntries(presentationData: PresentationData,
|
||||
return entries
|
||||
}
|
||||
|
||||
private class AttachmentFileControllerImpl: ItemListController, AttachmentContainable {
|
||||
private final class AttachmentFileContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(silently: Bool, mode: AttachmentMediaPickerSendMode) {
|
||||
}
|
||||
|
||||
func schedule() {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
class AttachmentFileControllerImpl: ItemListController, AttachmentContainable {
|
||||
public var requestAttachmentMenuExpansion: () -> Void = {}
|
||||
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in }
|
||||
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
|
||||
@ -174,23 +204,27 @@ private class AttachmentFileControllerImpl: ItemListController, AttachmentContai
|
||||
var delayDisappear = false
|
||||
|
||||
var resetForReuseImpl: () -> Void = {}
|
||||
public func resetForReuse() {
|
||||
func resetForReuse() {
|
||||
self.resetForReuseImpl()
|
||||
self.scrollToTop?()
|
||||
}
|
||||
|
||||
public func prepareForReuse() {
|
||||
func prepareForReuse() {
|
||||
self.delayDisappear = true
|
||||
self.visibleBottomContentOffsetChanged?(self.visibleBottomContentOffset)
|
||||
self.delayDisappear = false
|
||||
}
|
||||
|
||||
public var mediaPickerContext: AttachmentMediaPickerContext? {
|
||||
return AttachmentFileContext()
|
||||
}
|
||||
}
|
||||
|
||||
private struct AttachmentFileControllerState: Equatable {
|
||||
var searching: Bool
|
||||
}
|
||||
|
||||
public func attachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentContainable {
|
||||
func attachmentFileController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, bannedSendMedia: (Int32, Bool)?, presentGallery: @escaping () -> Void, presentFiles: @escaping () -> Void, send: @escaping (AnyMediaReference) -> Void) -> AttachmentFileControllerImpl {
|
||||
let actionsDisposable = DisposableSet()
|
||||
|
||||
let statePromise = ValuePromise(AttachmentFileControllerState(searching: false), ignoreRepeated: true)
|
||||
|
@ -260,7 +260,7 @@ final class ChatButtonKeyboardInputNode: ChatInputNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(), size: CGSize(width: width, height: UIScreenPixel)))
|
||||
|
||||
if self.backgroundNode == nil {
|
||||
|
@ -10653,6 +10653,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if case .standard(false) = self.presentationInterfaceState.mode, self.raiseToListen == nil {
|
||||
self.raiseToListen = RaiseToListenManager(shouldActivate: { [weak self] in
|
||||
if let strongSelf = self, strongSelf.isNodeLoaded && strongSelf.canReadHistoryValue, strongSelf.presentationInterfaceState.interfaceState.editMessage == nil, strongSelf.playlistStateAndType == nil {
|
||||
if !strongSelf.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak }) {
|
||||
return false
|
||||
}
|
||||
|
||||
if strongSelf.presentationInterfaceState.inputTextPanelState.mediaRecordingState != nil {
|
||||
return false
|
||||
}
|
||||
@ -10670,13 +10674,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return false
|
||||
}
|
||||
|
||||
if case let .media(_, expanded, _) = strongSelf.presentationInterfaceState.inputMode, expanded != nil {
|
||||
if case .media = strongSelf.presentationInterfaceState.inputMode {
|
||||
return false
|
||||
}
|
||||
|
||||
if !strongSelf.context.sharedContext.currentMediaInputSettings.with({ $0.enableRaiseToSpeak }) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
}
|
||||
@ -10712,14 +10714,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
strongSelf.chatDisplayNode.historyNode.voicePlaylistItemChanged(previousItem, currentItem)
|
||||
// if let currentItem = currentItem?.id as? PeerMessagesMediaPlaylistItemId {
|
||||
// self.controllerInteraction?.currentlyPlayingMessageId = currentItem.messageId
|
||||
// if let previousItem = previousItem?.id as? PeerMessagesMediaPlaylistItemId, previousItem.messageId.peerId == peerId, currentItem.messageId.peerId == peerId, currentItem.messageId != previousItem.messageId {
|
||||
// if strongSelf.chatDisplayNode.historyNode.isMessageVisibleOnScreen(currentItem.messageId) {
|
||||
// strongSelf.navigateToMessage(from: nil, to: .id(currentItem.messageId, nil), scrollPosition: .center(.bottom), rememberInStack: false, animated: true, completion: nil)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -12630,8 +12624,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let inputText = strongSelf.presentationInterfaceState.interfaceState.effectiveInputState.inputText
|
||||
|
||||
let currentMediaController = Atomic<MediaPickerScreen?>(value: nil)
|
||||
let currentFilesController = Atomic<AttachmentContainable?>(value: nil)
|
||||
let currentLocationController = Atomic<AttachmentContainable?>(value: nil)
|
||||
let currentFilesController = Atomic<AttachmentFileControllerImpl?>(value: nil)
|
||||
let currentLocationController = Atomic<LocationPickerController?>(value: nil)
|
||||
|
||||
let attachmentController = AttachmentController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, chatLocation: strongSelf.chatLocation, buttons: buttons, initialButton: initialButton, makeEntityInputView: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
@ -12680,7 +12674,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.controllerNavigationDisposable.set(nil)
|
||||
let existingController = currentFilesController.with { $0 }
|
||||
if let controller = existingController {
|
||||
completion(controller, nil)
|
||||
completion(controller, controller.mediaPickerContext)
|
||||
controller.prepareForReuse()
|
||||
return
|
||||
}
|
||||
@ -12703,12 +12697,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
})
|
||||
})
|
||||
let _ = currentFilesController.swap(controller)
|
||||
completion(controller, nil)
|
||||
completion(controller, controller.mediaPickerContext)
|
||||
case .location:
|
||||
strongSelf.controllerNavigationDisposable.set(nil)
|
||||
let existingController = currentLocationController.with { $0 }
|
||||
if let controller = existingController {
|
||||
completion(controller, nil)
|
||||
completion(controller, controller.mediaPickerContext)
|
||||
controller.prepareForReuse()
|
||||
return
|
||||
}
|
||||
@ -12743,7 +12737,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}, nil)
|
||||
strongSelf.sendMessages([message])
|
||||
})
|
||||
completion(controller, nil)
|
||||
completion(controller, controller.mediaPickerContext)
|
||||
|
||||
let _ = currentLocationController.swap(controller)
|
||||
})
|
||||
@ -12909,7 +12903,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}))
|
||||
case .poll:
|
||||
let controller = strongSelf.configurePollCreation()
|
||||
completion(controller, nil)
|
||||
completion(controller, controller?.mediaPickerContext)
|
||||
strongSelf.controllerNavigationDisposable.set(nil)
|
||||
case let .app(bot, botName, _):
|
||||
let params = WebAppParameters(peerId: peer.id, botId: bot.id, botName: botName, url: nil, queryId: nil, payload: botPayload, buttonText: nil, keepAliveSignal: nil, fromMenu: false, isSimple: false)
|
||||
@ -13398,8 +13392,8 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
controller.openCamera = { [weak self] cameraView in
|
||||
self?.openCamera(cameraView: cameraView)
|
||||
}
|
||||
controller.presentWebSearch = { [weak self, weak controller] mediaGroups in
|
||||
self?.presentWebSearch(editingMessage: false, attachment: true, present: { [weak controller] c, a in
|
||||
controller.presentWebSearch = { [weak self, weak controller] mediaGroups, activateOnDisplay in
|
||||
self?.presentWebSearch(editingMessage: false, attachment: true, activateOnDisplay: activateOnDisplay, present: { [weak controller] c, a in
|
||||
controller?.present(c, in: .current)
|
||||
if let webSearchController = c as? WebSearchController {
|
||||
webSearchController.searchingUpdated = { [weak mediaGroups] searching in
|
||||
@ -13560,7 +13554,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
})
|
||||
}
|
||||
|
||||
private func presentWebSearch(editingMessage: Bool, attachment: Bool, present: @escaping (ViewController, Any?) -> Void) {
|
||||
private func presentWebSearch(editingMessage: Bool, attachment: Bool, activateOnDisplay: Bool = true, present: @escaping (ViewController, Any?) -> Void) {
|
||||
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
||||
return
|
||||
}
|
||||
@ -13583,7 +13577,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
}), activateOnDisplay: activateOnDisplay)
|
||||
controller.attemptItemSelection = { [weak strongSelf] item in
|
||||
guard let strongSelf, let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer else {
|
||||
return false
|
||||
@ -14158,7 +14152,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.present(tooltipScreen, in: .current)
|
||||
}
|
||||
|
||||
private func configurePollCreation(isQuiz: Bool? = nil) -> AttachmentContainable? {
|
||||
private func configurePollCreation(isQuiz: Bool? = nil) -> CreatePollControllerImpl? {
|
||||
guard let peer = self.presentationInterfaceState.renderedPeer?.peer else {
|
||||
return nil
|
||||
}
|
||||
@ -16072,6 +16066,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongSelf.searchResultsController = nil
|
||||
strongController.dismiss()
|
||||
} else if peerId == strongSelf.context.account.peerId {
|
||||
Queue.mainQueue().after(0.88) {
|
||||
strongSelf.chatDisplayNode.hapticFeedback.success()
|
||||
}
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { [weak self] value in
|
||||
if case .info = value, let strongSelf = self {
|
||||
@ -18218,6 +18216,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|
||||
public func updatePushedTransition(_ fraction: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
if !transition.isAnimated {
|
||||
self.chatDisplayNode.historyNodeContainer.layer.removeAllAnimations()
|
||||
}
|
||||
let scale: CGFloat = 1.0 - 0.06 * fraction
|
||||
transition.updateTransformScale(node: self.chatDisplayNode.historyNodeContainer, scale: scale)
|
||||
}
|
||||
|
@ -164,7 +164,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
private var scheduledAnimateInAsOverlayFromNode: ASDisplayNode?
|
||||
private var dismissAsOverlayLayout: ContainerViewLayout?
|
||||
|
||||
private var hapticFeedback: HapticFeedback?
|
||||
lazy var hapticFeedback = { HapticFeedback() }()
|
||||
private var scrollViewDismissStatus = false
|
||||
|
||||
var chatPresentationInterfaceState: ChatPresentationInterfaceState
|
||||
@ -1398,7 +1398,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
let inputHeight = layout.standardInputHeight + self.inputPanelContainerNode.expansionFraction * (maximumInputNodeHeight - layout.standardInputHeight)
|
||||
|
||||
let heightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: inputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, deviceMetrics: layout.deviceMetrics, isVisible: self.isInFocus, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
let heightAndOverflow = inputNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: inputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelNodeBaseHeight, transition: immediatelyLayoutInputNodeAndAnimateAppearance ? .immediate : transition, interfaceState: self.chatPresentationInterfaceState, layoutMetrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isVisible: self.isInFocus, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
|
||||
let boundedHeight = inputNode.followsDefaultHeight ? min(heightAndOverflow.0, layout.standardInputHeight) : heightAndOverflow.0
|
||||
|
||||
@ -1449,10 +1449,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.historyNode.isSelectionGestureEnabled = isSelectionEnabled
|
||||
|
||||
if let inputMediaNode = self.inputMediaNode, inputMediaNode != self.inputNode {
|
||||
let _ = inputMediaNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelSize?.height ?? 0.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, deviceMetrics: layout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
let _ = inputMediaNode.updateLayout(width: layout.size.width, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, bottomInset: cleanInsets.bottom, standardInputHeight: layout.standardInputHeight, inputHeight: layout.inputHeight ?? 0.0, maximumHeight: maximumInputNodeHeight, inputPanelHeight: inputPanelSize?.height ?? 0.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, layoutMetrics: layout.metrics, deviceMetrics: layout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 116.0)))
|
||||
transition.updateFrame(node: self.titleAccessoryPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: 200.0)))
|
||||
|
||||
transition.updateFrame(node: self.inputContextPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height)))
|
||||
transition.updateFrame(node: self.inputContextOverTextPanelContainer, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: layout.size.height)))
|
||||
@ -2684,7 +2684,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
self.inputMediaNode = inputNode
|
||||
if let (validLayout, _) = self.validLayout {
|
||||
let _ = inputNode.updateLayout(width: validLayout.size.width, leftInset: validLayout.safeInsets.left, rightInset: validLayout.safeInsets.right, bottomInset: validLayout.intrinsicInsets.bottom, standardInputHeight: validLayout.standardInputHeight, inputHeight: validLayout.inputHeight ?? 0.0, maximumHeight: validLayout.standardInputHeight, inputPanelHeight: 44.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, deviceMetrics: validLayout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
let _ = inputNode.updateLayout(width: validLayout.size.width, leftInset: validLayout.safeInsets.left, rightInset: validLayout.safeInsets.right, bottomInset: validLayout.intrinsicInsets.bottom, standardInputHeight: validLayout.standardInputHeight, inputHeight: validLayout.inputHeight ?? 0.0, maximumHeight: validLayout.standardInputHeight, inputPanelHeight: 44.0, transition: .immediate, interfaceState: self.chatPresentationInterfaceState, layoutMetrics: validLayout.metrics, deviceMetrics: validLayout.deviceMetrics, isVisible: false, isExpanded: self.inputPanelContainerNode.stableIsExpanded)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2904,10 +2904,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
|
||||
if let scrollContainerNode = self.scrollContainerNode, scrollView === scrollContainerNode.view {
|
||||
if self.hapticFeedback == nil {
|
||||
self.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
self.hapticFeedback?.prepareImpact()
|
||||
self.hapticFeedback.prepareImpact()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2917,7 +2914,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if dismissStatus != self.scrollViewDismissStatus {
|
||||
self.scrollViewDismissStatus = dismissStatus
|
||||
if !self.dismissedAsOverlay {
|
||||
self.hapticFeedback?.impact()
|
||||
self.hapticFeedback.impact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -543,7 +543,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
|
||||
var requestDisableStickerAnimations: ((Bool) -> Void)?
|
||||
|
||||
private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, DeviceMetrics, Bool, Bool)?
|
||||
private var validLayout: (CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, ChatPresentationInterfaceState, LayoutMetrics, DeviceMetrics, Bool, Bool)?
|
||||
private var paneArrangement: ChatMediaInputPaneArrangement
|
||||
private var initializedArrangement = false
|
||||
|
||||
@ -1439,7 +1439,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
})))
|
||||
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout {
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout {
|
||||
var isScheduledMessages = false
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
isScheduledMessages = true
|
||||
@ -1561,7 +1561,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
|> map { isStarred -> (UIView, CGRect, PeekControllerContent)? in
|
||||
if let strongSelf = self {
|
||||
var menuItems: [ContextMenuItem] = []
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout {
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout {
|
||||
var isScheduledMessages = false
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
isScheduledMessages = true
|
||||
@ -1715,7 +1715,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
|> map { isStarred, hasPremium -> (UIView, CGRect, PeekControllerContent)? in
|
||||
if let strongSelf = self {
|
||||
var menuItems: [ContextMenuItem] = []
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = strongSelf.validLayout {
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = strongSelf.validLayout {
|
||||
var isScheduledMessages = false
|
||||
if case .scheduledMessages = interfaceState.subject {
|
||||
isScheduledMessages = true
|
||||
@ -1892,8 +1892,8 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
self.paneArrangement = self.paneArrangement.withIndexTransition(0.0).withCurrentIndex(index)
|
||||
let updatedGifPanelWasActive = self.paneArrangement.panes[self.paneArrangement.currentIndex] == .gifs
|
||||
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: transition, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: transition, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
self.updateAppearanceTransition(transition: transition)
|
||||
}
|
||||
if updatedGifPanelWasActive != previousGifPanelWasActive {
|
||||
@ -1910,8 +1910,8 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2149,20 +2149,20 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
}
|
||||
|
||||
func simulateUpdateLayout(isVisible: Bool) {
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, _, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, _, isExpanded) = self.validLayout {
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
}
|
||||
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, standardInputHeight: CGFloat, inputHeight: CGFloat, maximumHeight: CGFloat, inputPanelHeight: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, layoutMetrics: LayoutMetrics, deviceMetrics: DeviceMetrics, isVisible: Bool, isExpanded: Bool) -> (CGFloat, CGFloat) {
|
||||
var searchMode: ChatMediaInputSearchMode?
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _) = self.validLayout, case let .media(_, maybeExpanded, _) = interfaceState.inputMode, let expanded = maybeExpanded, case let .search(mode) = expanded {
|
||||
if let (_, _, _, _, _, _, _, _, interfaceState, _, _, _, _) = self.validLayout, case let .media(_, maybeExpanded, _) = interfaceState.inputMode, let expanded = maybeExpanded, case let .search(mode) = expanded {
|
||||
searchMode = mode
|
||||
}
|
||||
|
||||
let wasVisible = self.validLayout?.10 ?? false
|
||||
let wasVisible = self.validLayout?.11 ?? false
|
||||
|
||||
self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded)
|
||||
self.validLayout = (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded)
|
||||
|
||||
if self.theme !== interfaceState.theme || self.strings !== interfaceState.strings {
|
||||
self.updateThemeAndStrings(chatWallpaper: interfaceState.chatWallpaper, theme: interfaceState.theme, strings: interfaceState.strings)
|
||||
@ -2515,7 +2515,7 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
self.stickerPane.removeFromSupernode()
|
||||
}
|
||||
case .changed:
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
let translationX = -recognizer.translation(in: self.view).x
|
||||
var indexTransition = translationX / width
|
||||
if self.paneArrangement.currentIndex == 0 {
|
||||
@ -2524,10 +2524,10 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
indexTransition = min(0.0, indexTransition)
|
||||
}
|
||||
self.paneArrangement = self.paneArrangement.withIndexTransition(indexTransition)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .immediate, interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
case .ended:
|
||||
if let (width, _, _, _, _, _, _, _, _, _, _, _) = self.validLayout {
|
||||
if let (width, _, _, _, _, _, _, _, _, _, _, _, _) = self.validLayout {
|
||||
var updatedIndex = self.paneArrangement.currentIndex
|
||||
if abs(self.paneArrangement.indexTransition * width) > 30.0 {
|
||||
if self.paneArrangement.indexTransition < 0.0 {
|
||||
@ -2540,9 +2540,9 @@ final class ChatMediaInputNode: ChatInputNode {
|
||||
self.setCurrentPane(self.paneArrangement.panes[updatedIndex], transition: .animated(duration: 0.25, curve: .spring))
|
||||
}
|
||||
case .cancelled:
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
if let (width, leftInset, rightInset, bottomInset, standardInputHeight, inputHeight, maximumHeight, inputPanelHeight, interfaceState, layoutMetrics, deviceMetrics, isVisible, isExpanded) = self.validLayout {
|
||||
self.paneArrangement = self.paneArrangement.withIndexTransition(0.0)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
let _ = self.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, bottomInset: bottomInset, standardInputHeight: standardInputHeight, inputHeight: inputHeight, maximumHeight: maximumHeight, inputPanelHeight: inputPanelHeight, transition: .animated(duration: 0.25, curve: .spring), interfaceState: interfaceState, layoutMetrics: layoutMetrics, deviceMetrics: deviceMetrics, isVisible: isVisible, isExpanded: isExpanded)
|
||||
}
|
||||
default:
|
||||
break
|
||||
|
@ -1297,6 +1297,34 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
}
|
||||
|
||||
if let forwardInfoNode = self.forwardInfoNode, forwardInfoNode.frame.contains(location) {
|
||||
if let item = self.item, let forwardInfo = item.message.forwardInfo {
|
||||
let performAction: () -> Void = {
|
||||
if let sourceMessageId = forwardInfo.sourceMessageId {
|
||||
if !item.message.id.peerId.isReplies, let channel = forwardInfo.author as? TelegramChannel, channel.addressName == nil {
|
||||
if case let .broadcast(info) = channel.info, info.flags.contains(.hasDiscussionGroup) {
|
||||
} else if case .member = channel.participationStatus {
|
||||
} else {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_PrivateChannelTooltip, forwardInfoNode, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||
} else if let peer = forwardInfo.source ?? forwardInfo.author {
|
||||
item.controllerInteraction.openPeer(EnginePeer(peer), peer is TelegramUser ? .info : .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
|
||||
} else if let _ = forwardInfo.authorSignature {
|
||||
item.controllerInteraction.displayMessageTooltip(item.message.id, item.presentationData.strings.Conversation_ForwardAuthorHiddenTooltip, forwardInfoNode, nil)
|
||||
}
|
||||
}
|
||||
|
||||
if forwardInfoNode.hasAction(at: self.view.convert(location, to: forwardInfoNode.view)) {
|
||||
return .action({})
|
||||
} else {
|
||||
return .optionalAction(performAction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let item = self.item, self.imageNode.frame.contains(location) {
|
||||
return .optionalAction({
|
||||
let _ = item.controllerInteraction.openMessage(item.message, .default)
|
||||
|
@ -735,7 +735,7 @@ private final class TranslationLanguagesContextMenuContent: ContextControllerIte
|
||||
}
|
||||
|
||||
func update(presentationData: PresentationData, constrainedWidth: CGFloat, maxHeight: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) -> (cleanSize: CGSize, apparentHeight: CGFloat) {
|
||||
let constrainedSize = CGSize(width: min(260.0, constrainedWidth), height: min(604.0, maxHeight))
|
||||
let constrainedSize = CGSize(width: min(220.0, constrainedWidth), height: min(604.0, maxHeight))
|
||||
|
||||
var topContentHeight: CGFloat = 0.0
|
||||
if let backButtonNode = self.backButtonNode {
|
||||
|
@ -306,7 +306,7 @@ final class PeerInfoHeaderNavigationTransition {
|
||||
final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
let context: AccountContext
|
||||
|
||||
private let containerNode: ContextControllerSourceNode
|
||||
let containerNode: ContextControllerSourceNode
|
||||
|
||||
let avatarNode: AvatarNode
|
||||
fileprivate var videoNode: UniversalVideoNode?
|
||||
@ -2509,11 +2509,11 @@ final class PeerInfoHeaderNode: ASDisplayNode {
|
||||
|
||||
func updateAvatarIsHidden(entry: AvatarGalleryEntry?) {
|
||||
if let entry = entry {
|
||||
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||
self.editingContentNode.avatarNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||
self.avatarListNode.avatarContainerNode.containerNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||
self.editingContentNode.isHidden = entry == self.avatarListNode.listContainerNode.galleryEntries.first
|
||||
} else {
|
||||
self.avatarListNode.avatarContainerNode.avatarNode.isHidden = false
|
||||
self.editingContentNode.avatarNode.isHidden = false
|
||||
self.avatarListNode.avatarContainerNode.containerNode.isHidden = false
|
||||
self.editingContentNode.isHidden = false
|
||||
}
|
||||
self.avatarListNode.listContainerNode.updateEntryIsHidden(entry: entry)
|
||||
}
|
||||
|
@ -1950,7 +1950,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
private var editingSections: [AnyHashable: PeerInfoScreenItemSectionContainerNode] = [:]
|
||||
private let paneContainerNode: PeerInfoPaneContainerNode
|
||||
private var ignoreScrolling: Bool = false
|
||||
private var hapticFeedback: HapticFeedback?
|
||||
private lazy var hapticFeedback = { HapticFeedback() }()
|
||||
|
||||
private var customStatusData: (PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?)
|
||||
private let customStatusPromise = Promise<(PeerInfoStatusData?, PeerInfoStatusData?, CGFloat?)>((nil, nil, nil))
|
||||
@ -3096,7 +3096,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
for (_, section) in strongSelf.editingSections {
|
||||
section.animateErrorIfNeeded()
|
||||
}
|
||||
strongSelf.hapticFeedback?.error()
|
||||
strongSelf.hapticFeedback.error()
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -3146,10 +3146,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
if (peer.firstName ?? "") != firstName || (peer.lastName ?? "") != lastName {
|
||||
if firstName.isEmpty && lastName.isEmpty {
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.error()
|
||||
strongSelf.hapticFeedback.error()
|
||||
strongSelf.headerNode.editingContentNode.shakeTextForKey(.firstName)
|
||||
} else {
|
||||
var dismissStatus: (() -> Void)?
|
||||
@ -3212,10 +3209,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let description = strongSelf.headerNode.editingContentNode.editingTextForKey(.description) ?? ""
|
||||
|
||||
if title.isEmpty {
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.error()
|
||||
strongSelf.hapticFeedback.error()
|
||||
|
||||
strongSelf.headerNode.editingContentNode.shakeTextForKey(.title)
|
||||
} else {
|
||||
@ -8024,6 +8018,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
if let strongSelf = self, let _ = peerSelectionController {
|
||||
if peerId == strongSelf.context.account.peerId {
|
||||
Queue.mainQueue().after(0.88) {
|
||||
strongSelf.hapticFeedback.success()
|
||||
}
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messageIds.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
|
||||
@ -9055,10 +9053,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
shouldBeExpanded = true
|
||||
|
||||
if self.canOpenAvatarByDragging && self.headerNode.isAvatarExpanded && offsetY <= -32.0 {
|
||||
if self.hapticFeedback == nil {
|
||||
self.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
self.hapticFeedback?.impact()
|
||||
self.hapticFeedback.impact()
|
||||
|
||||
self.canOpenAvatarByDragging = false
|
||||
let contentOffset = scrollView.contentOffset.y
|
||||
@ -9078,13 +9073,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
if let shouldBeExpanded = shouldBeExpanded, shouldBeExpanded != self.headerNode.isAvatarExpanded {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.35, curve: .spring)
|
||||
|
||||
if self.hapticFeedback == nil {
|
||||
self.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
if shouldBeExpanded {
|
||||
self.hapticFeedback?.impact()
|
||||
self.hapticFeedback.impact()
|
||||
} else {
|
||||
self.hapticFeedback?.tap()
|
||||
self.hapticFeedback.tap()
|
||||
}
|
||||
|
||||
self.headerNode.updateIsAvatarExpanded(shouldBeExpanded, transition: transition)
|
||||
|
@ -9,6 +9,7 @@ import TelegramAudio
|
||||
import AccountContext
|
||||
import TelegramUniversalVideoContent
|
||||
import DeviceProximity
|
||||
import RaiseToListen
|
||||
|
||||
private enum SharedMediaPlaybackItem: Equatable {
|
||||
case audio(MediaPlayer)
|
||||
@ -120,7 +121,9 @@ final class SharedMediaPlayer {
|
||||
|
||||
private var playbackRate: AudioPlaybackRate
|
||||
|
||||
private var proximityManagerIndex: Int?
|
||||
//private var proximityManagerIndex: Int?
|
||||
private var raiseToListen: RaiseToListenManager?
|
||||
|
||||
private let controlPlaybackWithProximity: Bool
|
||||
private var forceAudioToSpeaker = false
|
||||
|
||||
@ -346,9 +349,10 @@ final class SharedMediaPlayer {
|
||||
} else {
|
||||
strongSelf.playbackStateValue.set(.single(nil))
|
||||
if !state.loading {
|
||||
if let proximityManagerIndex = strongSelf.proximityManagerIndex {
|
||||
DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||
}
|
||||
strongSelf.raiseToListen = nil
|
||||
// if let proximityManagerIndex = strongSelf.proximityManagerIndex {
|
||||
// DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,18 +366,44 @@ final class SharedMediaPlayer {
|
||||
})
|
||||
|
||||
if controlPlaybackWithProximity {
|
||||
self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in
|
||||
let forceAudioToSpeaker = !value
|
||||
if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||
self.raiseToListen = RaiseToListenManager(shouldActivate: {
|
||||
return true
|
||||
}, activate: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let forceAudioToSpeaker = false
|
||||
if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||
strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||
strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||
if !forceAudioToSpeaker {
|
||||
strongSelf.control(.playback(.play))
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}, deactivate: { [weak self] in
|
||||
if let strongSelf = self {
|
||||
let forceAudioToSpeaker = true
|
||||
if strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||
strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||
strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||
if forceAudioToSpeaker {
|
||||
strongSelf.control(.playback(.pause))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
self.raiseToListen?.enabled = true
|
||||
// self.proximityManagerIndex = DeviceProximityManager.shared().add { [weak self] value in
|
||||
// let forceAudioToSpeaker = !value
|
||||
// if let strongSelf = self, strongSelf.forceAudioToSpeaker != forceAudioToSpeaker {
|
||||
// strongSelf.forceAudioToSpeaker = forceAudioToSpeaker
|
||||
// strongSelf.playbackItem?.setForceAudioToSpeaker(forceAudioToSpeaker)
|
||||
// if !forceAudioToSpeaker {
|
||||
// strongSelf.control(.playback(.play))
|
||||
// } else {
|
||||
// strongSelf.control(.playback(.pause))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,9 +414,9 @@ final class SharedMediaPlayer {
|
||||
self.playbackStateValueDisposable?.dispose()
|
||||
self.prefetchDisposable.dispose()
|
||||
|
||||
if let proximityManagerIndex = self.proximityManagerIndex {
|
||||
DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||
}
|
||||
// if let proximityManagerIndex = self.proximityManagerIndex {
|
||||
// DeviceProximityManager.shared().remove(proximityManagerIndex)
|
||||
// }
|
||||
|
||||
if let playbackItem = self.playbackItem {
|
||||
switch playbackItem {
|
||||
|
@ -222,14 +222,24 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id)
|
||||
let hypotheses = languageRecognizer.languageHypotheses(withMaximum: 4)
|
||||
languageRecognizer.reset()
|
||||
|
||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
||||
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
||||
let fromLang = language.key.rawValue
|
||||
func normalize(_ code: String) -> String {
|
||||
if code.contains("-") {
|
||||
return code.components(separatedBy: "-").first ?? code
|
||||
} else if code == "nb" {
|
||||
return "no"
|
||||
} else {
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value })
|
||||
if let language = filteredLanguages.first {
|
||||
let fromLang = normalize(language.key.rawValue)
|
||||
fromLangs[fromLang] = (fromLangs[fromLang] ?? 0) + message.text.count
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
if count >= 10 {
|
||||
if count >= 16 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,6 @@ public var supportedTranslationLanguages = [
|
||||
"ca",
|
||||
"ceb",
|
||||
"zh",
|
||||
// "zh-Hant",
|
||||
// "zh-CN", "zh"
|
||||
// "zh-TW"
|
||||
"co",
|
||||
"hr",
|
||||
"cs",
|
||||
@ -168,9 +165,20 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat
|
||||
supportedTranslationLanguages = ["uk", "ru"]
|
||||
}
|
||||
|
||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains($0.key.rawValue) }.sorted(by: { $0.value > $1.value })
|
||||
if let language = filteredLanguages.first(where: { supportedTranslationLanguages.contains($0.key.rawValue) }) {
|
||||
return (!dontTranslateLanguages.contains(language.key.rawValue), language.key.rawValue)
|
||||
func normalize(_ code: String) -> String {
|
||||
if code.contains("-") {
|
||||
return code.components(separatedBy: "-").first ?? code
|
||||
} else if code == "nb" {
|
||||
return "no"
|
||||
} else {
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
||||
let filteredLanguages = hypotheses.filter { supportedTranslationLanguages.contains(normalize($0.key.rawValue)) }.sorted(by: { $0.value > $1.value })
|
||||
if let language = filteredLanguages.first {
|
||||
let languageCode = normalize(language.key.rawValue)
|
||||
return (!dontTranslateLanguages.contains(languageCode), languageCode)
|
||||
} else {
|
||||
return (false, nil)
|
||||
}
|
||||
|
@ -85,6 +85,7 @@ public final class WebSearchController: ViewController {
|
||||
private let peer: EnginePeer?
|
||||
private let chatLocation: ChatLocation?
|
||||
private let configuration: EngineConfiguration.SearchBots
|
||||
private let activateOnDisplay: Bool
|
||||
|
||||
private var controllerNode: WebSearchControllerNode {
|
||||
return self.displayNode as! WebSearchControllerNode
|
||||
@ -121,12 +122,13 @@ public final class WebSearchController: ViewController {
|
||||
|
||||
public var attemptItemSelection: (ChatContextResult) -> Bool = { _ in return true }
|
||||
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, configuration: EngineConfiguration.SearchBots, mode: WebSearchControllerMode) {
|
||||
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer?, chatLocation: ChatLocation?, configuration: EngineConfiguration.SearchBots, mode: WebSearchControllerMode, activateOnDisplay: Bool = true) {
|
||||
self.context = context
|
||||
self.mode = mode
|
||||
self.peer = peer
|
||||
self.chatLocation = chatLocation
|
||||
self.configuration = configuration
|
||||
self.activateOnDisplay = activateOnDisplay
|
||||
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.interfaceState = WebSearchInterfaceState(presentationData: presentationData)
|
||||
@ -329,7 +331,7 @@ public final class WebSearchController: ViewController {
|
||||
self.didPlayPresentationAnimation = true
|
||||
self.controllerNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
}
|
||||
if !self.didActivateSearch {
|
||||
if !self.didActivateSearch && self.activateOnDisplay {
|
||||
self.didActivateSearch = true
|
||||
self.navigationContentNode?.activate(select: select)
|
||||
}
|
||||
|
@ -245,9 +245,9 @@ class WebSearchControllerNode: ASDisplayNode {
|
||||
self.addSubnode(self.segmentedContainerNode)
|
||||
self.segmentedContainerNode.addSubnode(self.segmentedBackgroundNode)
|
||||
self.segmentedContainerNode.addSubnode(self.segmentedSeparatorNode)
|
||||
if case .media = mode {
|
||||
self.segmentedContainerNode.addSubnode(self.segmentedControlNode)
|
||||
}
|
||||
// if case .media = mode {
|
||||
// self.segmentedContainerNode.addSubnode(self.segmentedControlNode)
|
||||
// }
|
||||
if !attachment {
|
||||
self.addSubnode(self.toolbarBackgroundNode)
|
||||
self.addSubnode(self.toolbarSeparatorNode)
|
||||
|
Loading…
x
Reference in New Issue
Block a user