Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios

This commit is contained in:
Ilya Laktyushin 2022-04-05 16:50:18 +04:00
commit 45eb31ebc8
14 changed files with 195 additions and 26 deletions

View File

@ -1152,6 +1152,15 @@
"MuteFor.Days_many" = "Mute for %@ days";
"MuteFor.Days_0" = "Mute for %@ days";
"MutedForTime.Minutes_1" = "1 minute";
"MutedForTime.Minutes_any" = "%@ minutes";
"MutedForTime.Hours_1" = "1 hour";
"MutedForTime.Hours_any" = "%@ hours";
"MutedForTime.Days_1" = "1 day";
"MutedForTime.Days_any" = "%@ days";
"MuteExpires.Minutes_1" = "in 1 minute";
"MuteExpires.Minutes_2" = "in 2 minutes";
"MuteExpires.Minutes_3_10" = "in %@ minutes";
@ -7469,3 +7478,10 @@ Sorry for the inconvenience.";
"PeerInfo.ClearMessages" = "Clear Messages";
"PeerInfo.ClearConfirmationUser" = "Are you sure you want to delete all messages with %@?";
"PeerInfo.ClearConfirmationGroup" = "Are you sure you want to delete all messages in %@?";
"PeerInfo.TooltipSoundEnabled" = "You will receive notifications with sound.";
"PeerInfo.TooltipSoundDisabled" = "You will receive silent notifications.";
"PeerInfo.TooltipUnmuted" = "Notifications are unmuted.";
"PeerInfo.TooltipMutedFor" = "Notifications are muted for %@.";
"PeerInfo.TooltipMutedUntil" = "Notifications are muted until %@.";
"PeerInfo.TooltipMutedForever" = "Notifications are muted.";

View File

@ -44,7 +44,7 @@ class BazelCommandLine:
# repository), but disabling it also causes a noticeable build time regression
# so it can be explicitly re-enabled by users who are not affected by those
# crashes.
'--features=swift.use_global_module_cache',
#'--features=swift.use_global_module_cache',
# https://docs.bazel.build/versions/master/command-line-reference.html
# Print the subcommand details in case of failure.

View File

@ -554,7 +554,7 @@ public protocol CustomViewControllerNavigationDataSummary: AnyObject {
(self.navigationController as? NavigationController)?.pushViewController(controller)
}
public func present(_ controller: ViewController, in context: PresentationContextType, with arguments: Any? = nil, blockInteraction: Bool = false, completion: @escaping () -> Void = {}) {
open func present(_ controller: ViewController, in context: PresentationContextType, with arguments: Any? = nil, blockInteraction: Bool = false, completion: @escaping () -> Void = {}) {
if !(controller is StandalonePresentableController), case .window = context, let arguments = arguments as? ViewControllerPresentationArguments, case .modalSheet = arguments.presentationAnimation, self.navigationController != nil {
controller.navigationPresentation = .modal
self.push(controller)

View File

@ -146,6 +146,16 @@ public func muteForIntervalString(strings: PresentationStrings, value: Int32) ->
}
}
public func mutedForTimeIntervalString(strings: PresentationStrings, value: Int32) -> String {
if value < 60 * 60 {
return strings.MutedForTime_Minutes(max(1, value / (60)))
} else if value < 60 * 60 * 24 {
return strings.MutedForTime_Hours(max(1, value / (60 * 60)))
} else {
return strings.MutedForTime_Days(max(1, value / (60 * 60 * 24)))
}
}
public func unmuteIntervalString(strings: PresentationStrings, value: Int32) -> String {
if value < 60 * 60 {
return strings.MuteExpires_Minutes(max(1, value / 60))

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -316,20 +316,70 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
actionTitle = nil
}
var displayCloseButton = false
var displayListButton = false
if isReplyThread || actionTitle != nil {
self.closeButton.isHidden = true
self.listButton.isHidden = true
displayCloseButton = false
displayListButton = false
} else if let message = interfaceState.pinnedMessage {
if message.totalCount > 1 {
self.listButton.isHidden = false
self.closeButton.isHidden = true
displayCloseButton = false
displayListButton = true
} else {
self.listButton.isHidden = true
self.closeButton.isHidden = false
displayCloseButton = true
displayListButton = false
}
} else {
displayCloseButton = false
displayListButton = true
}
if displayCloseButton != !self.closeButton.isHidden {
if transition.isAnimated {
if displayCloseButton {
self.closeButton.isHidden = false
self.closeButton.layer.removeAllAnimations()
self.closeButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.closeButton.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
} else {
self.closeButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak self] completed in
guard let strongSelf = self, completed else {
return
}
strongSelf.closeButton.isHidden = true
strongSelf.closeButton.layer.removeAllAnimations()
})
self.closeButton.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
}
} else {
self.closeButton.isHidden = !displayCloseButton
self.closeButton.layer.removeAllAnimations()
}
}
if displayListButton != !self.listButton.isHidden {
if transition.isAnimated {
if displayListButton {
self.listButton.isHidden = false
self.closeButton.isHidden = true
self.listButton.layer.removeAllAnimations()
self.listButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.listButton.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
} else {
self.listButton.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak self] completed in
guard let strongSelf = self, completed else {
return
}
strongSelf.listButton.isHidden = true
strongSelf.listButton.layer.removeAllAnimations()
})
self.listButton.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
}
} else {
self.listButton.isHidden = !displayCloseButton
self.listButton.layer.removeAllAnimations()
}
}
let rightInset: CGFloat = 18.0 + rightInset
@ -343,8 +393,21 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
if let actionTitle = actionTitle {
var actionButtonTransition = transition
var animateButtonIn = false
if self.actionButton.isHidden {
actionButtonTransition = .immediate
animateButtonIn = true
} else if transition.isAnimated, messageUpdated, actionTitle != self.actionButtonTitleNode.attributedText?.string {
if let buttonSnapshot = self.actionButton.view.snapshotView(afterScreenUpdates: false) {
animateButtonIn = true
buttonSnapshot.frame = self.actionButton.frame
self.actionButton.view.superview?.insertSubview(buttonSnapshot, belowSubview: self.actionButton.view)
buttonSnapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak buttonSnapshot] _ in
buttonSnapshot?.removeFromSuperview()
})
buttonSnapshot.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2)
}
}
self.actionButton.isHidden = false
@ -361,10 +424,27 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
actionButtonTransition.updateFrame(node: self.actionButtonTitleNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((actionButtonFrame.width - actionButtonTitleSize.width) / 2.0), y: floorToScreenPixels((actionButtonFrame.height - actionButtonTitleSize.height) / 2.0)), size: actionButtonTitleSize))
tapButtonRightInset = 18.0 + actionButtonFrame.width
} else {
if animateButtonIn {
self.actionButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
self.actionButton.layer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
}
} else if !self.actionButton.isHidden {
self.actionButton.isHidden = true
self.actionButtonBackgroundNode.isHidden = true
self.actionButtonTitleNode.isHidden = true
if transition.isAnimated {
if let buttonSnapshot = self.actionButton.view.snapshotView(afterScreenUpdates: false) {
buttonSnapshot.frame = self.actionButton.frame
self.actionButton.view.superview?.insertSubview(buttonSnapshot, belowSubview: self.actionButton.view)
buttonSnapshot.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { [weak buttonSnapshot] _ in
buttonSnapshot?.removeFromSuperview()
})
buttonSnapshot.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2)
}
}
}
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: buttonsContainerSize.width - closeButtonSize.width + 1.0, y: 19.0), size: closeButtonSize))

View File

@ -487,6 +487,8 @@ class ChatTimerScreenNode: ViewControllerTracingNode, UIScrollViewDelegate, UIPi
if #available(iOS 13.4, *) {
pickerView.preferredDatePickerStyle = .wheels
}
pickerView.setValue(self.presentationData.theme.list.itemPrimaryTextColor, forKey: "textColor")
pickerView.setValue(false, forKey: "highlightsToday")
pickerView.selectorColor = UIColor(rgb: 0xffffff, alpha: 0.18)
pickerView.addTarget(self, action: #selector(self.dataPickerChanged), for: .valueChanged)

View File

@ -1857,7 +1857,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
UIPasteboard.general.string = linkForCopying
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
})))
}
@ -2898,7 +2898,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_PhoneCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_PhoneCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}
}))
}
@ -2909,7 +2909,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_UsernameCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_UsernameCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}
}))
}
@ -3534,6 +3534,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
case .mute:
if let notificationSettings = self.data?.notificationSettings, case .muted = notificationSettings.muteState {
let _ = self.context.engine.peers.updatePeerMuteSetting(peerId: self.peerId, muteInterval: nil).start()
let iconColor: UIColor = .white
self.controller?.present(UndoOverlayController(presentationData: self.presentationData, content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [
"Middle.Group 1.Fill 1": iconColor,
"Top.Group 1.Fill 1": iconColor,
"Bottom.Group 1.Fill 1": iconColor,
"EXAMPLE.Group 1.Fill 1": iconColor,
"Line.Group 1.Stroke 1": iconColor
], title: nil, text: self.presentationData.strings.PeerInfo_TooltipUnmuted), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
} else {
self.state = self.state.withHighlightedButton(.mute)
if let (layout, navigationHeight) = self.validLayout {
@ -3574,6 +3583,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
return
}
let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, muteInterval: value).start()
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: strongSelf.presentationData.strings, value: value)).string), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
}
@ -3610,6 +3621,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
return
}
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .default).start()
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundEnabled), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
} else {
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.PeerInfo_DisableSound, icon: { theme in
@ -3621,6 +3634,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
return
}
let _ = strongSelf.context.engine.peers.updatePeerNotificationSoundInteractive(peerId: strongSelf.peerId, sound: .none).start()
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipSoundDisabled), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
}
@ -3655,7 +3670,12 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}, updatePeerNotificationInterval: { peerId, muteInterval in
let _ = (updatePeerNotificationInterval(peerId, muteInterval)
|> deliverOnMainQueue).start(next: { _ in
guard let strongSelf = self else {
return
}
if let muteInterval = muteInterval, muteInterval == Int32.max {
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
@ -3680,6 +3700,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, muteInterval: Int32.max).start()
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedForever), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
})))
self.view.endEditing(true)
@ -3941,7 +3963,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
}
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
}
@ -4199,6 +4221,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, muteInterval: nil).start()
} else {
let _ = strongSelf.context.engine.peers.updatePeerMuteSetting(peerId: strongSelf.peerId, muteInterval: value).start()
let timeString = stringForPreciseRelativeTimestamp(strings: strongSelf.presentationData.strings, relativeTimestamp: Int32(Date().timeIntervalSince1970) + value, relativeTo: Int32(Date().timeIntervalSince1970), dateTimeFormat: strongSelf.presentationData.dateTimeFormat)
strongSelf.controller?.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: .universal(animation: "anim_mute_for", scale: 0.056, colors: [:], title: nil, text: strongSelf.presentationData.strings.PeerInfo_TooltipMutedUntil(timeString).string), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
self.controller?.view.endEditing(true)
@ -4422,7 +4448,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
}
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
}
@ -4430,7 +4456,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
shareController.actionCompleted = { [weak self] in
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}
}
self.view.endEditing(true)
@ -5151,7 +5177,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
}
}
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
}
})
}
@ -5159,7 +5185,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
shareController.actionCompleted = { [weak self] in
if let strongSelf = self {
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .linkCopied(text: presentationData.strings.Conversation_LinkCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}
}
strongSelf.view.endEditing(true)
@ -5409,7 +5435,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
var actions: [ContextMenuAction] = [ContextMenuAction(content: .text(title: presentationData.strings.Conversation_ContextMenuCopy, accessibilityLabel: presentationData.strings.Conversation_ContextMenuCopy), action: { [weak self] in
UIPasteboard.general.string = text
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_TextCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
})]
let (canTranslate, language) = canTranslateText(context: context, text: text, showTranslate: translationSettings.showTranslate, showTranslateIfTopical: false, ignoredLanguages: translationSettings.ignoredLanguages)
@ -5436,7 +5462,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
UIPasteboard.general.string = phone
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_PhoneCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: .copy(text: presentationData.strings.Conversation_PhoneCopied), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
})])
controller.present(contextMenuController, in: .window(.root), with: ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak self, weak sourceNode] in
if let controller = self?.controller, let sourceNode = sourceNode {
@ -5460,7 +5486,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
UIPasteboard.general.string = text
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
self?.controller?.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
})])
controller.present(contextMenuController, in: .window(.root), with: ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak self, weak sourceNode] in
if let controller = self?.controller, let sourceNode = sourceNode {
@ -6352,7 +6378,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
if let strongSelf = self, let _ = peerSelectionController {
if peerId == strongSelf.context.account.peerId {
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: .window(.root))
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)
strongSelf.headerNode.navigationButtonContainer.performAction?(.selectionDone, nil, nil)
@ -7874,6 +7900,12 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen {
})
}
override public func present(_ controller: ViewController, in context: PresentationContextType, with arguments: Any? = nil, blockInteraction: Bool = false, completion: @escaping () -> Void = {}) {
self.dismissAllTooltips()
super.present(controller, in: context, with: arguments, blockInteraction: blockInteraction, completion: completion)
}
override public func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)

View File

@ -5,6 +5,7 @@
#import "Instance.h"
#import "InstanceImpl.h"
#import "v2/InstanceV2Impl.h"
#import "v2_4_0_0/InstanceV2_4_0_0Impl.h"
#include "StaticThreads.h"
#import "VideoCaptureInterface.h"
@ -918,6 +919,7 @@ static void (*InternalVoipLoggingFunction)(NSString *) = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
tgcalls::Register<tgcalls::InstanceImpl>();
tgcalls::Register<tgcalls::InstanceV2_4_0_0Impl>();
tgcalls::Register<tgcalls::InstanceV2Impl>();
});

@ -1 +1 @@
Subproject commit 96b2bbf3a7b352924998e93c649ef30174a1a433
Subproject commit 4c1a39c67d4b03dd96ac82a9aa2420243f5bd106

View File

@ -41,6 +41,7 @@ public enum UndoOverlayContent {
case inviteRequestSent(title: String, text: String)
case image(image: UIImage, text: String)
case notificationSoundAdded(title: String, text: String, action: (() -> Void)?)
case universal(animation: String, scale: CGFloat, colors: [String: UIColor], title: String?, text: String)
}
public enum UndoOverlayAction {

View File

@ -789,6 +789,29 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
}
}
}
case let .universal(animation, scale, colors, title, text):
self.avatarNode = nil
self.iconNode = nil
self.iconCheckNode = nil
self.animationNode = AnimationNode(animation: animation, colors: colors, scale: scale)
self.animatedStickerNode = nil
if let title = title {
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(14.0), textColor: .white)
} else {
self.titleNode.attributedText = nil
}
let body = MarkdownAttributeSet(font: Font.regular(14.0), textColor: .white)
let bold = MarkdownAttributeSet(font: Font.semibold(14.0), textColor: .white)
let link = MarkdownAttributeSet(font: Font.regular(14.0), textColor: undoTextColor)
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: link, linkAttribute: { contents in
return ("URL", contents)
}), textAlignment: .natural)
self.textNode.attributedText = attributedText
self.textNode.maximumNumberOfLines = 5
displayUndo = false
self.originalRemainingSeconds = 3
case let .image(image, text):
self.avatarNode = nil
self.iconNode = ASImageNode()
@ -831,7 +854,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
switch content {
case .removedChat:
self.panelWrapperNode.addSubnode(self.timerTextNode)
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion, .linkRevoked, .voiceChatRecording, .voiceChatFlag, .voiceChatCanSpeak, .sticker, .copy, .mediaSaved, .paymentSent, .image, .inviteRequestSent, .notificationSoundAdded:
case .archivedChat, .hidArchive, .revealedArchive, .autoDelete, .succeed, .emoji, .swipeToReply, .actionSucceeded, .stickersModified, .chatAddedToFolder, .chatRemovedFromFolder, .messagesUnpinned, .setProximityAlert, .invitedToVoiceChat, .linkCopied, .banned, .importedMessage, .audioRate, .forward, .gigagroupConversion, .linkRevoked, .voiceChatRecording, .voiceChatFlag, .voiceChatCanSpeak, .sticker, .copy, .mediaSaved, .paymentSent, .image, .inviteRequestSent, .notificationSoundAdded, .universal:
if self.textNode.tapAttributeAction != nil {
self.isUserInteractionEnabled = true
} else {