mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '2242097992f2bd9b0ad889554a97d2fc074242ae'
This commit is contained in:
commit
c64c8ab240
@ -1811,6 +1811,7 @@ plist_fragment(
|
|||||||
<string>ucbrowser</string>
|
<string>ucbrowser</string>
|
||||||
<string>dolphin</string>
|
<string>dolphin</string>
|
||||||
<string>instagram-stories</string>
|
<string>instagram-stories</string>
|
||||||
|
<string>yangomaps</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
@ -235,6 +235,13 @@ private func allOpenInOptions(context: AccountContext, item: OpenInItem) -> [Ope
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
options.append(OpenInOption(identifier: "yangoMaps", application: .other(title: "Yango Maps", identifier: 1665672451, scheme: "yangomaps", store: nil), action: {
|
||||||
|
if let _ = directions {
|
||||||
|
return .openUrl(url: "yangomaps://build_route_on_map?lat_to=\(lat)&lon_to=\(lon)")
|
||||||
|
} else {
|
||||||
|
return .openUrl(url: "yangomaps://maps.yango.com/?pt=\(lon),\(lat)&z=16")
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
options.append(OpenInOption(identifier: "yandexMaps", application: .other(title: "Yandex.Maps", identifier: 313877526, scheme: "yandexmaps", store: nil), action: {
|
options.append(OpenInOption(identifier: "yandexMaps", application: .other(title: "Yandex.Maps", identifier: 313877526, scheme: "yandexmaps", store: nil), action: {
|
||||||
if let _ = directions {
|
if let _ = directions {
|
||||||
|
@ -264,8 +264,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
|||||||
} else if let _ = media as? TelegramMediaExpiredContent {
|
} else if let _ = media as? TelegramMediaExpiredContent {
|
||||||
result.removeAll()
|
result.removeAll()
|
||||||
result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||||
needReactions = false
|
break inner
|
||||||
return (result, false, false)
|
|
||||||
} else if let _ = media as? TelegramMediaPoll {
|
} else if let _ = media as? TelegramMediaPoll {
|
||||||
result.append((message, ChatMessagePollBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
result.append((message, ChatMessagePollBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||||
needReactions = false
|
needReactions = false
|
||||||
@ -2735,6 +2734,8 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
default:
|
default:
|
||||||
centerAligned = true
|
centerAligned = true
|
||||||
}
|
}
|
||||||
|
} else if let _ = media as? TelegramMediaExpiredContent {
|
||||||
|
centerAligned = true
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -299,8 +299,6 @@ public func canAddMessageReactions(message: Message) -> Bool {
|
|||||||
if story.isMention {
|
if story.isMention {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else if let _ = media as? TelegramMediaExpiredContent {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
@ -24,6 +24,7 @@ swift_library(
|
|||||||
"//submodules/AppBundle",
|
"//submodules/AppBundle",
|
||||||
"//submodules/PresentationDataUtils",
|
"//submodules/PresentationDataUtils",
|
||||||
"//submodules/TelegramUI/Components/LottieComponent",
|
"//submodules/TelegramUI/Components/LottieComponent",
|
||||||
|
"//submodules/TelegramUI/Components/PlainButtonComponent",
|
||||||
"//submodules/AvatarNode",
|
"//submodules/AvatarNode",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
|
@ -22,22 +22,19 @@ private final class QuickShareScreenComponent: Component {
|
|||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let sourceNode: ASDisplayNode
|
let sourceNode: ASDisplayNode
|
||||||
let gesture: ContextGesture
|
let gesture: ContextGesture
|
||||||
let openPeer: (EnginePeer.Id) -> Void
|
let completion: (EnginePeer, CGRect) -> Void
|
||||||
let completion: (EnginePeer.Id) -> Void
|
|
||||||
let ready: Promise<Bool>
|
let ready: Promise<Bool>
|
||||||
|
|
||||||
init(
|
init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
sourceNode: ASDisplayNode,
|
sourceNode: ASDisplayNode,
|
||||||
gesture: ContextGesture,
|
gesture: ContextGesture,
|
||||||
openPeer: @escaping (EnginePeer.Id) -> Void,
|
completion: @escaping (EnginePeer, CGRect) -> Void,
|
||||||
completion: @escaping (EnginePeer.Id) -> Void,
|
|
||||||
ready: Promise<Bool>
|
ready: Promise<Bool>
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.sourceNode = sourceNode
|
self.sourceNode = sourceNode
|
||||||
self.gesture = gesture
|
self.gesture = gesture
|
||||||
self.openPeer = openPeer
|
|
||||||
self.completion = completion
|
self.completion = completion
|
||||||
self.ready = ready
|
self.ready = ready
|
||||||
}
|
}
|
||||||
@ -184,24 +181,9 @@ private final class QuickShareScreenComponent: Component {
|
|||||||
|
|
||||||
func highlightGestureFinished(performAction: Bool) {
|
func highlightGestureFinished(performAction: Bool) {
|
||||||
if let selectedPeerId = self.selectedPeerId, performAction {
|
if let selectedPeerId = self.selectedPeerId, performAction {
|
||||||
if let component = self.component, let peer = self.peers?.first(where: { $0.id == selectedPeerId }), let view = self.items[selectedPeerId]?.view as? ItemComponent.View, let controller = self.environment?.controller() {
|
if let component = self.component, let peer = self.peers?.first(where: { $0.id == selectedPeerId }), let view = self.items[selectedPeerId]?.view as? ItemComponent.View {
|
||||||
controller.window?.forEachController({ controller in
|
component.completion(peer, view.convert(view.bounds, to: nil))
|
||||||
if let controller = controller as? QuickShareToastScreen {
|
|
||||||
controller.dismiss()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
let toastScreen = QuickShareToastScreen(
|
|
||||||
context: component.context,
|
|
||||||
peer: peer,
|
|
||||||
sourceFrame: view.convert(view.bounds, to: nil),
|
|
||||||
action: {
|
|
||||||
component.openPeer(peer.id)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
controller.present(toastScreen, in: .window(.root))
|
|
||||||
view.avatarNode.isHidden = true
|
view.avatarNode.isHidden = true
|
||||||
|
|
||||||
component.completion(peer.id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.animateOut {
|
self.animateOut {
|
||||||
@ -296,7 +278,7 @@ private final class QuickShareScreenComponent: Component {
|
|||||||
|
|
||||||
if theme.overallDarkAppearance {
|
if theme.overallDarkAppearance {
|
||||||
self.backgroundView.updateColor(color: theme.contextMenu.backgroundColor, forceKeepBlur: true, transition: .immediate)
|
self.backgroundView.updateColor(color: theme.contextMenu.backgroundColor, forceKeepBlur: true, transition: .immediate)
|
||||||
self.backgroundTintView.backgroundColor = UIColor(white: 1.0, alpha: 0.5)
|
self.backgroundTintView.backgroundColor = .clear
|
||||||
} else {
|
} else {
|
||||||
self.backgroundView.updateColor(color: .clear, forceKeepBlur: true, transition: .immediate)
|
self.backgroundView.updateColor(color: .clear, forceKeepBlur: true, transition: .immediate)
|
||||||
self.backgroundTintView.backgroundColor = theme.contextMenu.backgroundColor
|
self.backgroundTintView.backgroundColor = theme.contextMenu.backgroundColor
|
||||||
@ -411,8 +393,7 @@ public class QuickShareScreen: ViewControllerComponentContainer {
|
|||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
sourceNode: ASDisplayNode,
|
sourceNode: ASDisplayNode,
|
||||||
gesture: ContextGesture,
|
gesture: ContextGesture,
|
||||||
openPeer: @escaping (EnginePeer.Id) -> Void,
|
completion: @escaping (EnginePeer, CGRect) -> Void
|
||||||
completion: @escaping (EnginePeer.Id) -> Void
|
|
||||||
) {
|
) {
|
||||||
let componentReady = Promise<Bool>()
|
let componentReady = Promise<Bool>()
|
||||||
|
|
||||||
@ -422,7 +403,6 @@ public class QuickShareScreen: ViewControllerComponentContainer {
|
|||||||
context: context,
|
context: context,
|
||||||
sourceNode: sourceNode,
|
sourceNode: sourceNode,
|
||||||
gesture: gesture,
|
gesture: gesture,
|
||||||
openPeer: openPeer,
|
|
||||||
completion: completion,
|
completion: completion,
|
||||||
ready: componentReady
|
ready: componentReady
|
||||||
),
|
),
|
||||||
@ -528,7 +508,7 @@ private final class ItemComponent: Component {
|
|||||||
private weak var state: EmptyComponentState?
|
private weak var state: EmptyComponentState?
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 14.0))
|
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 26.0))
|
||||||
self.backgroundNode = NavigationBackgroundNode(color: .clear)
|
self.backgroundNode = NavigationBackgroundNode(color: .clear)
|
||||||
|
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
@ -14,18 +14,19 @@ import MultilineTextComponent
|
|||||||
import AvatarNode
|
import AvatarNode
|
||||||
import Markdown
|
import Markdown
|
||||||
import LottieComponent
|
import LottieComponent
|
||||||
|
import PlainButtonComponent
|
||||||
|
|
||||||
private final class QuickShareToastScreenComponent: Component {
|
private final class QuickShareToastScreenComponent: Component {
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
let peer: EnginePeer
|
let peer: EnginePeer
|
||||||
let sourceFrame: CGRect
|
let sourceFrame: CGRect
|
||||||
let action: () -> Void
|
let action: (QuickShareToastScreen.Action) -> Void
|
||||||
|
|
||||||
init(
|
init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
peer: EnginePeer,
|
peer: EnginePeer,
|
||||||
sourceFrame: CGRect,
|
sourceFrame: CGRect,
|
||||||
action: @escaping () -> Void
|
action: @escaping (QuickShareToastScreen.Action) -> Void
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
@ -51,6 +52,7 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
private let animation = ComponentView<Empty>()
|
private let animation = ComponentView<Empty>()
|
||||||
|
|
||||||
private let content = ComponentView<Empty>()
|
private let content = ComponentView<Empty>()
|
||||||
|
private let actionButton = ComponentView<Empty>()
|
||||||
|
|
||||||
private var isUpdating: Bool = false
|
private var isUpdating: Bool = false
|
||||||
private var component: QuickShareToastScreenComponent?
|
private var component: QuickShareToastScreenComponent?
|
||||||
@ -93,7 +95,8 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
guard let component = self.component else {
|
guard let component = self.component else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
component.action()
|
component.action(.info)
|
||||||
|
self.doneTimer?.invalidate()
|
||||||
self.environment?.controller()?.dismiss()
|
self.environment?.controller()?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,10 +190,10 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
|
|
||||||
if self.component == nil {
|
if self.component == nil {
|
||||||
self.doneTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false, block: { [weak self] _ in
|
self.doneTimer = Foundation.Timer.scheduledTimer(withTimeInterval: 3.0, repeats: false, block: { [weak self] _ in
|
||||||
guard let self else {
|
guard let self, let controller = self.environment?.controller() as? QuickShareToastScreen else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.environment?.controller()?.dismiss()
|
controller.dismissWithCommitAction()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +233,29 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
tooltipText = environment.strings.Conversation_ForwardTooltip_Chat_One(component.peer.compactDisplayTitle).string
|
tooltipText = environment.strings.Conversation_ForwardTooltip_Chat_One(component.peer.compactDisplayTitle).string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let actionButtonSize = self.actionButton.update(
|
||||||
|
transition: .immediate,
|
||||||
|
component: AnyComponent(PlainButtonComponent(
|
||||||
|
content: AnyComponent(MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(string: "Undo", font: Font.regular(17.0), textColor: environment.theme.list.itemAccentColor.withMultiplied(hue: 0.933, saturation: 0.61, brightness: 1.0)))
|
||||||
|
)),
|
||||||
|
effectAlignment: .center,
|
||||||
|
contentInsets: UIEdgeInsets(top: -8.0, left: -8.0, bottom: -8.0, right: -8.0),
|
||||||
|
action: { [weak self] in
|
||||||
|
guard let self, let _ = self.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.doneTimer?.invalidate()
|
||||||
|
self.environment?.controller()?.dismiss()
|
||||||
|
},
|
||||||
|
animateAlpha: true,
|
||||||
|
animateScale: false,
|
||||||
|
animateContents: false
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: availableContentSize.width - contentInsets.left - contentInsets.right - spacing - iconSize.width, height: availableContentSize.height)
|
||||||
|
)
|
||||||
|
|
||||||
let contentSize = self.content.update(
|
let contentSize = self.content.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(MultilineTextComponent(text: .markdown(
|
component: AnyComponent(MultilineTextComponent(text: .markdown(
|
||||||
@ -279,6 +305,13 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
transition.setFrame(view: contentView, frame: CGRect(origin: CGPoint(x: contentInsets.left + iconSize.width + spacing, y: floor((contentHeight - contentSize.height) * 0.5)), size: contentSize))
|
transition.setFrame(view: contentView, frame: CGRect(origin: CGPoint(x: contentInsets.left + iconSize.width + spacing, y: floor((contentHeight - contentSize.height) * 0.5)), size: contentSize))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let actionButtonView = self.actionButton.view {
|
||||||
|
if actionButtonView.superview == nil {
|
||||||
|
self.backgroundView.addSubview(actionButtonView)
|
||||||
|
}
|
||||||
|
transition.setFrame(view: actionButtonView, frame: CGRect(origin: CGPoint(x: availableContentSize.width - contentInsets.right - 16.0 - actionButtonSize.width, y: floor((contentHeight - actionButtonSize.height) * 0.5)), size: actionButtonSize))
|
||||||
|
}
|
||||||
|
|
||||||
let size = CGSize(width: availableContentSize.width, height: contentHeight)
|
let size = CGSize(width: availableContentSize.width, height: contentHeight)
|
||||||
let backgroundFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: availableSize.height - containerInsets.bottom - size.height), size: size)
|
let backgroundFrame = CGRect(origin: CGPoint(x: containerInsets.left, y: availableSize.height - containerInsets.bottom - size.height), size: size)
|
||||||
|
|
||||||
@ -301,16 +334,24 @@ private final class QuickShareToastScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class QuickShareToastScreen: ViewControllerComponentContainer {
|
public final class QuickShareToastScreen: ViewControllerComponentContainer {
|
||||||
|
public enum Action {
|
||||||
|
case info
|
||||||
|
case commit
|
||||||
|
}
|
||||||
|
|
||||||
private var processedDidAppear: Bool = false
|
private var processedDidAppear: Bool = false
|
||||||
private var processedDidDisappear: Bool = false
|
private var processedDidDisappear: Bool = false
|
||||||
|
|
||||||
init(
|
private let action: (Action) -> Void
|
||||||
|
|
||||||
|
public init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
peer: EnginePeer,
|
peer: EnginePeer,
|
||||||
sourceFrame: CGRect,
|
sourceFrame: CGRect,
|
||||||
action: @escaping () -> Void
|
action: @escaping (Action) -> Void
|
||||||
) {
|
) {
|
||||||
|
self.action = action
|
||||||
super.init(
|
super.init(
|
||||||
context: context,
|
context: context,
|
||||||
component: QuickShareToastScreenComponent(
|
component: QuickShareToastScreenComponent(
|
||||||
@ -334,11 +375,11 @@ final class QuickShareToastScreen: ViewControllerComponentContainer {
|
|||||||
deinit {
|
deinit {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
public override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||||
super.containerLayoutUpdated(layout, transition: transition)
|
super.containerLayoutUpdated(layout, transition: transition)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
public override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
if !self.processedDidAppear {
|
if !self.processedDidAppear {
|
||||||
@ -353,7 +394,12 @@ final class QuickShareToastScreen: ViewControllerComponentContainer {
|
|||||||
super.dismiss()
|
super.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func dismiss(completion: (() -> Void)? = nil) {
|
public func dismissWithCommitAction() {
|
||||||
|
self.action(.commit)
|
||||||
|
self.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func dismiss(completion: (() -> Void)? = nil) {
|
||||||
if !self.processedDidDisappear {
|
if !self.processedDidDisappear {
|
||||||
self.processedDidDisappear = true
|
self.processedDidDisappear = true
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ public func peerMessageAllowedReactions(context: AccountContext, message: Messag
|
|||||||
return .single((.all, false))
|
return .single((.all, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
if message.containsSecretMedia {
|
// if message.containsSecretMedia {
|
||||||
return .single((AllowedReactions.set(Set()), false))
|
// return .single((AllowedReactions.set(Set()), false))
|
||||||
}
|
// }
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.engine.data.get(
|
context.engine.data.get(
|
||||||
|
@ -593,7 +593,6 @@ private final class SheetContent: CombinedComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
starsContext.add(balance: StarsAmount(value: stars, nanos: 0))
|
starsContext.add(balance: StarsAmount(value: stars, nanos: 0))
|
||||||
|
|
||||||
let _ = (starsContext.onUpdate
|
let _ = (starsContext.onUpdate
|
||||||
|> deliverOnMainQueue).start(next: {
|
|> deliverOnMainQueue).start(next: {
|
||||||
completion()
|
completion()
|
||||||
|
@ -243,9 +243,6 @@ func openWebAppImpl(
|
|||||||
return navigationController ?? (context.sharedContext.mainWindow?.viewController as? NavigationController)
|
return navigationController ?? (context.sharedContext.mainWindow?.viewController as? NavigationController)
|
||||||
})
|
})
|
||||||
controller.navigationPresentation = .flatModal
|
controller.navigationPresentation = .flatModal
|
||||||
if let parentController = parentController as? ChatControllerImpl {
|
|
||||||
parentController.currentWebAppController = controller
|
|
||||||
}
|
|
||||||
parentController.push(controller)
|
parentController.push(controller)
|
||||||
|
|
||||||
presentImpl = { [weak controller] c, a in
|
presentImpl = { [weak controller] c, a in
|
||||||
@ -297,9 +294,6 @@ func openWebAppImpl(
|
|||||||
return navigationController ?? (context.sharedContext.mainWindow?.viewController as? NavigationController)
|
return navigationController ?? (context.sharedContext.mainWindow?.viewController as? NavigationController)
|
||||||
})
|
})
|
||||||
controller.navigationPresentation = .flatModal
|
controller.navigationPresentation = .flatModal
|
||||||
if let parentController = parentController as? ChatControllerImpl {
|
|
||||||
parentController.currentWebAppController = controller
|
|
||||||
}
|
|
||||||
parentController.push(controller)
|
parentController.push(controller)
|
||||||
|
|
||||||
presentImpl = { [weak controller] c, a in
|
presentImpl = { [weak controller] c, a in
|
||||||
@ -355,7 +349,7 @@ public extension ChatControllerImpl {
|
|||||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: EnginePeer(peer), chatPeer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: EnginePeer(peer), chatPeer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func botRequestSwitchInline(context: AccountContext, controller: ChatControllerImpl?, peerId: EnginePeer.Id, botAddress: String, query: String, chatTypes: [ReplyMarkupButtonRequestPeerType]?, completion: @escaping () -> Void) -> Void {
|
fileprivate static func botRequestSwitchInline(context: AccountContext, controller: ChatControllerImpl?, peerId: EnginePeer.Id, botAddress: String, query: String, chatTypes: [ReplyMarkupButtonRequestPeerType]?, completion: @escaping () -> Void) -> Void {
|
||||||
let activateSwitchInline: (EnginePeer?) -> Void = { selectedPeer in
|
let activateSwitchInline: (EnginePeer?) -> Void = { selectedPeer in
|
||||||
var chatController: ChatControllerImpl?
|
var chatController: ChatControllerImpl?
|
||||||
if let current = controller {
|
if let current = controller {
|
||||||
@ -429,7 +423,7 @@ public extension ChatControllerImpl {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static func botOpenUrl(context: AccountContext, peerId: EnginePeer.Id, controller: ChatControllerImpl?, url: String, concealed: Bool, forceUpdate: Bool, present: @escaping (ViewController, Any?) -> Void, commit: @escaping () -> Void = {}) {
|
fileprivate static func botOpenUrl(context: AccountContext, peerId: EnginePeer.Id, controller: ChatControllerImpl?, url: String, concealed: Bool, forceUpdate: Bool, present: @escaping (ViewController, Any?) -> Void, commit: @escaping () -> Void = {}) {
|
||||||
if let controller {
|
if let controller {
|
||||||
controller.openUrl(url, concealed: concealed, forceExternal: true, commit: commit)
|
controller.openUrl(url, concealed: concealed, forceExternal: true, commit: commit)
|
||||||
} else {
|
} else {
|
||||||
@ -437,41 +431,52 @@ public extension ChatControllerImpl {
|
|||||||
present(c, nil)
|
present(c, nil)
|
||||||
}, openResolved: { result in
|
}, openResolved: { result in
|
||||||
var navigationController: NavigationController?
|
var navigationController: NavigationController?
|
||||||
if let current = controller?.navigationController as? NavigationController {
|
if let main = context.sharedContext.mainWindow?.viewController as? NavigationController {
|
||||||
navigationController = current
|
|
||||||
} else if let main = context.sharedContext.mainWindow?.viewController as? NavigationController {
|
|
||||||
navigationController = main
|
navigationController = main
|
||||||
}
|
}
|
||||||
|
if case let .peer(peer, navigation) = result, case let .withBotApp(botApp) = navigation, let botPeer = peer.flatMap(EnginePeer.init), let parentController = navigationController?.viewControllers.last as? ViewController {
|
||||||
|
self.presentBotApp(context: context, parentController: parentController, botApp: botApp.botApp, botPeer: botPeer, payload: botApp.payload, mode: botApp.mode)
|
||||||
|
} else {
|
||||||
context.sharedContext.openResolvedUrl(result, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, forceUpdate: forceUpdate, openPeer: { peer, navigation in
|
context.sharedContext.openResolvedUrl(result, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, forceUpdate: forceUpdate, openPeer: { peer, navigation in
|
||||||
if let navigationController {
|
if let navigationController {
|
||||||
ChatControllerImpl.botOpenPeer(context: context, peerId: peer.id, navigation: navigation, navigationController: navigationController)
|
ChatControllerImpl.botOpenPeer(context: context, peerId: peer.id, navigation: navigation, navigationController: navigationController)
|
||||||
}
|
}
|
||||||
commit()
|
commit()
|
||||||
}, sendFile: nil, sendSticker: nil, sendEmoji: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: { peerId, invite, call in
|
}, sendFile: nil, sendSticker: nil, sendEmoji: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: { peerId, invite, call in
|
||||||
},
|
}, present: { c, a in
|
||||||
present: { c, a in
|
|
||||||
present(c, a)
|
present(c, a)
|
||||||
}, dismissInput: {
|
}, dismissInput: {
|
||||||
context.sharedContext.mainWindow?.viewController?.view.endEditing(false)
|
context.sharedContext.mainWindow?.viewController?.view.endEditing(false)
|
||||||
}, contentContext: nil, progress: nil, completion: nil)
|
}, contentContext: nil, progress: nil, completion: nil)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func presentBotApp(botApp: BotApp?, botPeer: EnginePeer, payload: String?, mode: ResolvedStartAppMode, concealed: Bool = false, commit: @escaping () -> Void = {}) {
|
func presentBotApp(botApp: BotApp?, botPeer: EnginePeer, payload: String?, mode: ResolvedStartAppMode, concealed: Bool = false, commit: @escaping () -> Void = {}) {
|
||||||
guard let peerId = self.chatLocation.peerId else {
|
ChatControllerImpl.presentBotApp(context: self.context, parentController: self, botApp: botApp, botPeer: botPeer, payload: payload, mode: mode, concealed: concealed, commit: commit)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
self.attachmentController?.dismiss(animated: true, completion: nil)
|
|
||||||
|
fileprivate static func presentBotApp(context: AccountContext, parentController: ViewController, botApp: BotApp?, botPeer: EnginePeer, payload: String?, mode: ResolvedStartAppMode, concealed: Bool = false, commit: @escaping () -> Void = {}) {
|
||||||
|
let chatController = parentController as? ChatControllerImpl
|
||||||
|
let peerId: EnginePeer.Id
|
||||||
|
let threadId = chatController?.chatLocation.threadId
|
||||||
|
if let chatPeerId = chatController?.chatLocation.peerId {
|
||||||
|
peerId = chatPeerId
|
||||||
|
} else {
|
||||||
|
peerId = botPeer.id
|
||||||
|
}
|
||||||
|
|
||||||
|
chatController?.attachmentController?.dismiss(animated: true, completion: nil)
|
||||||
|
|
||||||
|
let updatedPresentationData = chatController?.updatedPresentationData
|
||||||
|
let presentationData = updatedPresentationData?.0 ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
if let botApp {
|
if let botApp {
|
||||||
let openBotApp: (Bool, Bool, BotAppSettings?) -> Void = { [weak self] allowWrite, justInstalled, appSettings in
|
let openBotApp: (Bool, Bool, BotAppSettings?) -> Void = { [weak parentController, weak chatController] allowWrite, justInstalled, appSettings in
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
commit()
|
commit()
|
||||||
|
|
||||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
chatController?.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||||
return $0.updatedTitlePanelContext {
|
return $0.updatedTitlePanelContext {
|
||||||
if !$0.contains(where: {
|
if !$0.contains(where: {
|
||||||
switch $0 {
|
switch $0 {
|
||||||
@ -489,10 +494,10 @@ public extension ChatControllerImpl {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let updateProgress = { [weak self] in
|
let updateProgress = { [weak chatController] in
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
if let strongSelf = self {
|
if let chatController {
|
||||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
chatController.updateChatPresentationInterfaceState(animated: true, interactive: true, {
|
||||||
return $0.updatedTitlePanelContext {
|
return $0.updatedTitlePanelContext {
|
||||||
if let index = $0.firstIndex(where: {
|
if let index = $0.firstIndex(where: {
|
||||||
switch $0 {
|
switch $0 {
|
||||||
@ -514,63 +519,56 @@ public extension ChatControllerImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let botAddress = botPeer.addressName ?? ""
|
let botAddress = botPeer.addressName ?? ""
|
||||||
strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestAppWebView(peerId: peerId, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: payload, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), compact: mode == .compact, fullscreen: mode == .fullscreen, allowWrite: allowWrite)
|
let _ = ((context.engine.messages.requestAppWebView(peerId: peerId, appReference: .id(id: botApp.id, accessHash: botApp.accessHash), payload: payload, themeParams: generateWebAppThemeParams(presentationData.theme), compact: mode == .compact, fullscreen: mode == .fullscreen, allowWrite: allowWrite)
|
||||||
|> afterDisposed {
|
|> afterDisposed {
|
||||||
updateProgress()
|
updateProgress()
|
||||||
})
|
})
|
||||||
|> deliverOnMainQueue).startStrict(next: { [weak self] result in
|
|> deliverOnMainQueue).startStandalone(next: { [weak parentController, weak chatController] result in
|
||||||
guard let strongSelf = self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let context = strongSelf.context
|
|
||||||
let params = WebAppParameters(source: .generic, peerId: peerId, botId: botPeer.id, botName: botApp.title, botVerified: botPeer.isVerified, botAddress: botPeer.addressName ?? "", appName: botApp.shortName, url: result.url, queryId: 0, payload: payload, buttonText: "", keepAliveSignal: nil, forceHasSettings: botApp.flags.contains(.hasSettings), fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen), appSettings: appSettings)
|
let params = WebAppParameters(source: .generic, peerId: peerId, botId: botPeer.id, botName: botApp.title, botVerified: botPeer.isVerified, botAddress: botPeer.addressName ?? "", appName: botApp.shortName, url: result.url, queryId: 0, payload: payload, buttonText: "", keepAliveSignal: nil, forceHasSettings: botApp.flags.contains(.hasSettings), fullSize: result.flags.contains(.fullSize), isFullscreen: result.flags.contains(.fullScreen), appSettings: appSettings)
|
||||||
var presentImpl: ((ViewController, Any?) -> Void)?
|
var presentImpl: ((ViewController, Any?) -> Void)?
|
||||||
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url, concealed, forceUpdate, commit in
|
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { url, concealed, forceUpdate, commit in
|
||||||
ChatControllerImpl.botOpenUrl(context: context, peerId: peerId, controller: self, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
ChatControllerImpl.botOpenUrl(context: context, peerId: peerId, controller: chatController, url: url, concealed: concealed, forceUpdate: forceUpdate, present: { c, a in
|
||||||
presentImpl?(c, a)
|
presentImpl?(c, a)
|
||||||
}, commit: commit)
|
}, commit: commit)
|
||||||
}, requestSwitchInline: { [weak self] query, chatTypes, completion in
|
}, requestSwitchInline: { query, chatTypes, completion in
|
||||||
ChatControllerImpl.botRequestSwitchInline(context: context, controller: self, peerId: peerId, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
ChatControllerImpl.botRequestSwitchInline(context: context, controller: chatController, peerId: peerId, botAddress: botAddress, query: query, chatTypes: chatTypes, completion: completion)
|
||||||
}, completion: { [weak self] in
|
}, completion: {
|
||||||
self?.chatDisplayNode.historyNode.scrollToEndOfHistory()
|
chatController?.chatDisplayNode.historyNode.scrollToEndOfHistory()
|
||||||
}, getNavigationController: { [weak self] in
|
}, getNavigationController: {
|
||||||
return self?.effectiveNavigationController ?? context.sharedContext.mainWindow?.viewController as? NavigationController
|
if let navigationController = parentController?.navigationController as? NavigationController {
|
||||||
|
return navigationController
|
||||||
|
} else {
|
||||||
|
return context.sharedContext.mainWindow?.viewController as? NavigationController
|
||||||
|
}
|
||||||
})
|
})
|
||||||
controller.navigationPresentation = .flatModal
|
controller.navigationPresentation = .flatModal
|
||||||
strongSelf.currentWebAppController = controller
|
parentController?.push(controller)
|
||||||
strongSelf.push(controller)
|
|
||||||
|
|
||||||
presentImpl = { [weak controller] c, a in
|
presentImpl = { [weak controller] c, a in
|
||||||
controller?.present(c, in: .window(.root), with: a)
|
controller?.present(c, in: .window(.root), with: a)
|
||||||
}
|
}
|
||||||
|
|
||||||
if justInstalled {
|
if justInstalled {
|
||||||
let content: UndoOverlayContent = .succeed(text: strongSelf.presentationData.strings.WebApp_ShortcutsSettingsAdded(botPeer.compactDisplayTitle).string, timeout: 5.0, customUndoText: nil)
|
let content: UndoOverlayContent = .succeed(text: presentationData.strings.WebApp_ShortcutsSettingsAdded(botPeer.compactDisplayTitle).string, timeout: 5.0, customUndoText: nil)
|
||||||
controller.present(UndoOverlayController(presentationData: strongSelf.presentationData, content: content, elevatedLayout: false, position: .top, action: { _ in return false }), in: .current)
|
controller.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, position: .top, action: { _ in return false }), in: .current)
|
||||||
}
|
}
|
||||||
}, error: { [weak self] error in
|
}, error: { [weak parentController] error in
|
||||||
if let strongSelf = self {
|
parentController?.present(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
||||||
strongSelf.present(textAlertController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, title: nil, text: strongSelf.presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {
|
|
||||||
})]), in: .window(.root))
|
})]), in: .window(.root))
|
||||||
}
|
})
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = combineLatest(
|
let _ = combineLatest(
|
||||||
queue: Queue.mainQueue(),
|
queue: Queue.mainQueue(),
|
||||||
ApplicationSpecificNotice.getBotGameNotice(accountManager: self.context.sharedContext.accountManager, peerId: botPeer.id),
|
ApplicationSpecificNotice.getBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id),
|
||||||
self.context.engine.messages.attachMenuBots(),
|
context.engine.messages.attachMenuBots(),
|
||||||
self.context.engine.messages.getAttachMenuBot(botId: botPeer.id, cached: true)
|
context.engine.messages.getAttachMenuBot(botId: botPeer.id, cached: true)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
|> `catch` { _ -> Signal<AttachMenuBot?, NoError> in
|
|> `catch` { _ -> Signal<AttachMenuBot?, NoError> in
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
},
|
},
|
||||||
self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.BotAppSettings(id: botPeer.id))
|
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.BotAppSettings(id: botPeer.id))
|
||||||
).startStandalone(next: { [weak self] noticed, attachMenuBots, attachMenuBot, appSettings in
|
).startStandalone(next: { [weak parentController, weak chatController] noticed, attachMenuBots, attachMenuBot, appSettings in
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var isAttachMenuBotInstalled: Bool?
|
var isAttachMenuBotInstalled: Bool?
|
||||||
if let _ = attachMenuBot {
|
if let _ = attachMenuBot {
|
||||||
if let _ = attachMenuBots.first(where: { $0.peer.id == botPeer.id && !$0.flags.contains(.notActivated) }) {
|
if let _ = attachMenuBots.first(where: { $0.peer.id == botPeer.id && !$0.flags.contains(.notActivated) }) {
|
||||||
@ -580,11 +578,10 @@ public extension ChatControllerImpl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let context = self.context
|
|
||||||
if !noticed || botApp.flags.contains(.notActivated) || isAttachMenuBotInstalled == false {
|
if !noticed || botApp.flags.contains(.notActivated) || isAttachMenuBotInstalled == false {
|
||||||
if let isAttachMenuBotInstalled, let attachMenuBot {
|
if let isAttachMenuBotInstalled, let attachMenuBot {
|
||||||
if !isAttachMenuBotInstalled {
|
if !isAttachMenuBotInstalled {
|
||||||
let controller = webAppTermsAlertController(context: context, updatedPresentationData: self.updatedPresentationData, bot: attachMenuBot, completion: { allowWrite in
|
let controller = webAppTermsAlertController(context: context, updatedPresentationData: updatedPresentationData, bot: attachMenuBot, completion: { allowWrite in
|
||||||
let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone()
|
let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone()
|
||||||
let _ = (context.engine.messages.addBotToAttachMenu(botId: botPeer.id, allowWrite: allowWrite)
|
let _ = (context.engine.messages.addBotToAttachMenu(botId: botPeer.id, allowWrite: allowWrite)
|
||||||
|> deliverOnMainQueue).startStandalone(error: { _ in
|
|> deliverOnMainQueue).startStandalone(error: { _ in
|
||||||
@ -592,31 +589,29 @@ public extension ChatControllerImpl {
|
|||||||
openBotApp(allowWrite, true, appSettings)
|
openBotApp(allowWrite, true, appSettings)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
self.present(controller, in: .window(.root))
|
parentController?.present(controller, in: .window(.root))
|
||||||
} else {
|
} else {
|
||||||
openBotApp(false, false, appSettings)
|
openBotApp(false, false, appSettings)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let controller = webAppLaunchConfirmationController(context: context, updatedPresentationData: self.updatedPresentationData, peer: botPeer, requestWriteAccess: botApp.flags.contains(.notActivated) && botApp.flags.contains(.requiresWriteAccess), completion: { allowWrite in
|
let controller = webAppLaunchConfirmationController(context: context, updatedPresentationData: updatedPresentationData, peer: botPeer, requestWriteAccess: botApp.flags.contains(.notActivated) && botApp.flags.contains(.requiresWriteAccess), completion: { allowWrite in
|
||||||
let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone()
|
let _ = ApplicationSpecificNotice.setBotGameNotice(accountManager: context.sharedContext.accountManager, peerId: botPeer.id).startStandalone()
|
||||||
openBotApp(allowWrite, false, appSettings)
|
openBotApp(allowWrite, false, appSettings)
|
||||||
}, showMore: { [weak self] in
|
}, showMore: chatController == nil ? nil : { [weak chatController] in
|
||||||
if let self {
|
if let chatController {
|
||||||
self.openResolved(result: .peer(botPeer._asPeer(), .info(nil)), sourceMessageId: nil)
|
chatController.openResolved(result: .peer(botPeer._asPeer(), .info(nil)), sourceMessageId: nil)
|
||||||
}
|
|
||||||
}, openTerms: { [weak self] in
|
|
||||||
if let self {
|
|
||||||
self.context.sharedContext.openExternalUrl(context: self.context, urlContext: .generic, url: self.presentationData.strings.WebApp_LaunchTermsConfirmation_URL, forceExternal: false, presentationData: self.presentationData, navigationController: self.effectiveNavigationController, dismissInput: {})
|
|
||||||
}
|
}
|
||||||
|
}, openTerms: {
|
||||||
|
context.sharedContext.openExternalUrl(context: context, urlContext: .generic, url: presentationData.strings.WebApp_LaunchTermsConfirmation_URL, forceExternal: false, presentationData: presentationData, navigationController: parentController?.navigationController as? NavigationController, dismissInput: {})
|
||||||
})
|
})
|
||||||
self.present(controller, in: .window(.root))
|
parentController?.present(controller, in: .window(.root))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
openBotApp(false, false, appSettings)
|
openBotApp(false, false, appSettings)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, botPeer: botPeer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
context.sharedContext.openWebApp(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, botPeer: botPeer, chatPeer: nil, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,8 @@ extension ChatControllerImpl {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: totalAmount), completion: { _ in
|
let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: totalAmount), completion: { stars in
|
||||||
|
starsContext.add(balance: StarsAmount(value: stars, nanos: 0))
|
||||||
let _ = (starsContext.onUpdate
|
let _ = (starsContext.onUpdate
|
||||||
|> deliverOnMainQueue).start(next: {
|
|> deliverOnMainQueue).start(next: {
|
||||||
completion(false)
|
completion(false)
|
||||||
|
@ -12,22 +12,27 @@ extension ChatControllerImpl {
|
|||||||
context: self.context,
|
context: self.context,
|
||||||
sourceNode: node,
|
sourceNode: node,
|
||||||
gesture: gesture,
|
gesture: gesture,
|
||||||
openPeer: { [weak self] peerId in
|
completion: { [weak self] peer, sourceFrame in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
self.window?.forEachController({ controller in
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
if let controller = controller as? QuickShareToastScreen {
|
||||||
guard let self else {
|
controller.dismissWithCommitAction()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
self.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil)
|
|
||||||
})
|
})
|
||||||
},
|
let toastScreen = QuickShareToastScreen(
|
||||||
completion: { [weak self] peerId in
|
context: self.context,
|
||||||
|
peer: peer,
|
||||||
|
sourceFrame: sourceFrame,
|
||||||
|
action: { [weak self] action in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
switch action {
|
||||||
|
case .info:
|
||||||
|
self.openPeer(peer: peer, navigation: .chat(textInputState: nil, subject: nil, peekData: nil), fromMessage: nil)
|
||||||
|
case .commit:
|
||||||
let enqueueMessage = StandaloneSendEnqueueMessage(
|
let enqueueMessage = StandaloneSendEnqueueMessage(
|
||||||
content: .forward(forward: StandaloneSendEnqueueMessage.Forward(
|
content: .forward(forward: StandaloneSendEnqueueMessage.Forward(
|
||||||
sourceId: id,
|
sourceId: id,
|
||||||
@ -41,11 +46,15 @@ extension ChatControllerImpl {
|
|||||||
network: self.context.account.network,
|
network: self.context.account.network,
|
||||||
stateManager: self.context.account.stateManager,
|
stateManager: self.context.account.stateManager,
|
||||||
auxiliaryMethods: self.context.account.auxiliaryMethods,
|
auxiliaryMethods: self.context.account.auxiliaryMethods,
|
||||||
peerId: peerId,
|
peerId: peer.id,
|
||||||
threadId: nil,
|
threadId: nil,
|
||||||
messages: [enqueueMessage]
|
messages: [enqueueMessage]
|
||||||
)).startStandalone()
|
)).startStandalone()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.present(toastScreen, in: .window(.root))
|
||||||
|
}
|
||||||
)
|
)
|
||||||
self.presentInGlobalOverlay(controller)
|
self.presentInGlobalOverlay(controller)
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,7 @@ import AdsReportScreen
|
|||||||
import AdUI
|
import AdUI
|
||||||
import ChatMessagePaymentAlertController
|
import ChatMessagePaymentAlertController
|
||||||
import TelegramCallsUI
|
import TelegramCallsUI
|
||||||
|
import QuickShareScreen
|
||||||
|
|
||||||
public enum ChatControllerPeekActions {
|
public enum ChatControllerPeekActions {
|
||||||
case standard
|
case standard
|
||||||
@ -544,7 +545,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
let chatLocationContextHolder: Atomic<ChatLocationContextHolder?>
|
||||||
|
|
||||||
weak var attachmentController: AttachmentController?
|
weak var attachmentController: AttachmentController?
|
||||||
weak var currentWebAppController: ViewController?
|
|
||||||
|
|
||||||
weak var currentImportMessageTooltip: UndoOverlayController?
|
weak var currentImportMessageTooltip: UndoOverlayController?
|
||||||
|
|
||||||
@ -10740,6 +10740,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
if let controller = controller as? UndoOverlayController {
|
if let controller = controller as? UndoOverlayController {
|
||||||
controller.dismissWithCommitAction()
|
controller.dismissWithCommitAction()
|
||||||
}
|
}
|
||||||
|
if let controller = controller as? QuickShareToastScreen {
|
||||||
|
controller.dismissWithCommitAction()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
self.forEachController({ controller in
|
self.forEachController({ controller in
|
||||||
if let controller = controller as? UndoOverlayController {
|
if let controller = controller as? UndoOverlayController {
|
||||||
|
@ -1062,9 +1062,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
|||||||
case "web_app_open_tg_link":
|
case "web_app_open_tg_link":
|
||||||
if let json = json, let path = json["path_full"] as? String {
|
if let json = json, let path = json["path_full"] as? String {
|
||||||
let forceRequest = json["force_request"] as? Bool ?? false
|
let forceRequest = json["force_request"] as? Bool ?? false
|
||||||
controller.openUrl("https://t.me\(path)", false, forceRequest, { [weak controller] in
|
controller.openUrl("https://t.me\(path)", false, forceRequest, {
|
||||||
let _ = controller
|
|
||||||
// controller?.dismiss()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
case "web_app_open_invoice":
|
case "web_app_open_invoice":
|
||||||
|
Loading…
x
Reference in New Issue
Block a user