mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Web app improvements
This commit is contained in:
parent
613bba57c2
commit
f5092b8d8d
@ -12473,6 +12473,10 @@ Sorry for the inconvenience.";
|
||||
"WebApp.MinimizedTitle.Others_1" = "%@ Other";
|
||||
"WebApp.MinimizedTitle.Others_any" = "%@ Others";
|
||||
|
||||
"WebApp.Minimized.CloseAllTitle" = "Are you sure you want to close all open tabs?";
|
||||
"WebApp.Minimized.CloseAll_1" = "Close All %@ Tab";
|
||||
"WebApp.Minimized.CloseAll_any" = "Close All %@ Tabs";
|
||||
|
||||
"Stars.SendStars.Title" = "Send Stars";
|
||||
"Stars.SendStars.AmountTitle" = "ENTER AMOUNT";
|
||||
"Stars.SendStars.AmountPlaceholder" = "Stars Amount";
|
||||
|
@ -71,6 +71,7 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
var isPanningUpdated: (Bool) -> Void = { _ in }
|
||||
var isExpandedUpdated: (Bool) -> Void = { _ in }
|
||||
var isPanGestureEnabled: (() -> Bool)?
|
||||
var isInnerPanGestureEnabled: (() -> Bool)?
|
||||
var onExpandAnimationCompleted: () -> Void = {}
|
||||
|
||||
init(isFullSize: Bool) {
|
||||
@ -146,6 +147,23 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if let isInnerPanGestureEnabled = self.isInnerPanGestureEnabled, !isInnerPanGestureEnabled() {
|
||||
func findWebViewAncestor(view: UIView?) -> WKWebView? {
|
||||
guard let view else {
|
||||
return nil
|
||||
}
|
||||
if let view = view as? WKWebView {
|
||||
return view
|
||||
} else if view != self.view {
|
||||
return findWebViewAncestor(view: view.superview)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if let otherView = self.hitTest(gestureRecognizer.location(in: self.view), with: nil), let _ = findWebViewAncestor(view: otherView) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -163,23 +181,6 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
}
|
||||
return true
|
||||
}
|
||||
if gestureRecognizer is UIPanGestureRecognizer {
|
||||
func findWebViewAncestor(view: UIView?) -> WKWebView? {
|
||||
guard let view else {
|
||||
return nil
|
||||
}
|
||||
if let view = view as? WKWebView {
|
||||
return view
|
||||
} else if view != self.view {
|
||||
return findWebViewAncestor(view: view.superview)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if let otherView = otherGestureRecognizer.view, let _ = findWebViewAncestor(view: otherView) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
if gestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer is UILongPressGestureRecognizer {
|
||||
return true
|
||||
}
|
||||
@ -197,7 +198,7 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
|
||||
private var panGestureArguments: (topInset: CGFloat, offset: CGFloat, scrollView: UIScrollView?, listNode: ListView?)?
|
||||
@objc func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||
guard let (layout, controllers, coveredByModalTransition) = self.validLayout else {
|
||||
guard let (layout, controllers, coveredByModalTransition) = self.validLayout, let lastController = controllers.last else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -271,10 +272,14 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
}
|
||||
|
||||
if !self.isExpanded || self.isFullSize, translation > 40.0, let shouldCancelPanGesture = self.shouldCancelPanGesture, shouldCancelPanGesture() {
|
||||
if lastController.isMinimizable {
|
||||
|
||||
} else {
|
||||
self.cancelPanGesture()
|
||||
self.requestDismiss?()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var bounds = self.bounds
|
||||
if self.isExpanded && !self.isFullSize {
|
||||
@ -323,8 +328,12 @@ final class AttachmentContainer: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
|
||||
var ignoreDismiss = false
|
||||
if let shouldCancelPanGesture = self.shouldCancelPanGesture, shouldCancelPanGesture() {
|
||||
if lastController.isMinimizable {
|
||||
|
||||
} else {
|
||||
ignoreDismiss = true
|
||||
}
|
||||
}
|
||||
|
||||
var minimizing = false
|
||||
var dismissing = false
|
||||
|
@ -121,6 +121,7 @@ public protocol AttachmentContainable: ViewController, MinimizableController {
|
||||
var isContainerPanning: () -> Bool { get set }
|
||||
var isContainerExpanded: () -> Bool { get set }
|
||||
var isPanGestureEnabled: (() -> Bool)? { get }
|
||||
var isInnerPanGestureEnabled: (() -> Bool)? { get }
|
||||
var mediaPickerContext: AttachmentMediaPickerContext? { get }
|
||||
var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)? { get }
|
||||
|
||||
@ -172,6 +173,10 @@ public extension AttachmentContainable {
|
||||
return nil
|
||||
}
|
||||
|
||||
var isInnerPanGestureEnabled: (() -> Bool)? {
|
||||
return nil
|
||||
}
|
||||
|
||||
var getCurrentSendMessageContextMediaPreview: (() -> ChatSendMessageContextScreenMediaPreview?)? {
|
||||
return nil
|
||||
}
|
||||
@ -196,6 +201,10 @@ public protocol AttachmentMediaPickerContext {
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> { get }
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void
|
||||
|
||||
var canMakePaidContent: Bool { get }
|
||||
var price: Int64? { get }
|
||||
func setPrice(_ price: Int64) -> Void
|
||||
|
||||
var loadingProgress: Signal<CGFloat?, NoError> { get }
|
||||
var mainButtonState: Signal<AttachmentMainButtonState?, NoError> { get }
|
||||
|
||||
@ -206,6 +215,58 @@ public protocol AttachmentMediaPickerContext {
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?)
|
||||
}
|
||||
|
||||
public extension AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
var canMakePaidContent: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var price: Int64? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func setPrice(_ price: Int64) -> Void {
|
||||
}
|
||||
|
||||
var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
private func generateShadowImage() -> UIImage? {
|
||||
return generateImage(CGSize(width: 140.0, height: 140.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
@ -444,6 +505,17 @@ public class AttachmentController: ViewController, MinimizableController {
|
||||
}
|
||||
}
|
||||
|
||||
self.container.isInnerPanGestureEnabled = { [weak self] in
|
||||
guard let self, let currentController = self.currentControllers.last else {
|
||||
return true
|
||||
}
|
||||
if let isInnerPanGestureEnabled = currentController.isInnerPanGestureEnabled {
|
||||
return isInnerPanGestureEnabled()
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
self.container.shouldCancelPanGesture = { [weak self] in
|
||||
if let strongSelf = self, let currentController = strongSelf.currentControllers.last {
|
||||
if !currentController.shouldDismissImmediately() {
|
||||
@ -1191,6 +1263,14 @@ public class AttachmentController: ViewController, MinimizableController {
|
||||
}
|
||||
}
|
||||
|
||||
public var isMinimizable: Bool {
|
||||
return self.mainController.isMinimizable
|
||||
}
|
||||
|
||||
public func shouldDismissImmediately() -> Bool {
|
||||
return self.mainController.shouldDismissImmediately()
|
||||
}
|
||||
|
||||
private var validLayout: ContainerViewLayout?
|
||||
|
||||
override public func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
|
@ -985,8 +985,12 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> = .single(false)
|
||||
var canMakePaidContent = false
|
||||
var currentPrice: Int64?
|
||||
if let controller = strongSelf.controller, let mediaPickerContext = controller.mediaPickerContext {
|
||||
captionIsAboveMedia = mediaPickerContext.captionIsAboveMedia
|
||||
canMakePaidContent = mediaPickerContext.canMakePaidContent
|
||||
currentPrice = mediaPickerContext.price
|
||||
}
|
||||
|
||||
let _ = (combineLatest(
|
||||
@ -1016,7 +1020,9 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
||||
messageEffect: nil,
|
||||
attachment: true,
|
||||
canSendWhenOnline: sendWhenOnlineAvailable,
|
||||
forwardMessageIds: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? []
|
||||
forwardMessageIds: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? [],
|
||||
canMakePaidContent: canMakePaidContent,
|
||||
currentPrice: currentPrice
|
||||
)),
|
||||
hasEntityKeyboard: hasEntityKeyboard,
|
||||
gesture: gesture,
|
||||
@ -1038,6 +1044,12 @@ final class AttachmentPanel: ASDisplayNode, ASScrollViewDelegate {
|
||||
schedule: { [weak textInputPanelNode] messageEffect in
|
||||
textInputPanelNode?.sendMessage(.schedule, messageEffect)
|
||||
},
|
||||
editPrice: { [weak strongSelf] price in
|
||||
guard let strongSelf, let controller = strongSelf.controller, let mediaPickerContext = controller.mediaPickerContext else {
|
||||
return
|
||||
}
|
||||
mediaPickerContext.setPrice(price)
|
||||
},
|
||||
openPremiumPaywall: { [weak self] c in
|
||||
guard let self else {
|
||||
return
|
||||
|
@ -10,23 +10,26 @@ swift_library(
|
||||
"-warnings-as-errors",
|
||||
],
|
||||
deps = [
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/Display:Display",
|
||||
"//submodules/Postbox:Postbox",
|
||||
"//submodules/TelegramCore:TelegramCore",
|
||||
"//submodules/TelegramPresentationData:TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences:TelegramUIPreferences",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/InstantPageUI:InstantPageUI",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
"//submodules/UndoUI:UndoUI",
|
||||
"//submodules/SSignalKit/SwiftSignalKit",
|
||||
"//submodules/AsyncDisplayKit",
|
||||
"//submodules/Display",
|
||||
"//submodules/Postbox",
|
||||
"//submodules/TelegramCore",
|
||||
"//submodules/TelegramPresentationData",
|
||||
"//submodules/TelegramUIPreferences",
|
||||
"//submodules/AppBundle",
|
||||
"//submodules/InstantPageUI",
|
||||
"//submodules/ContextUI",
|
||||
"//submodules/UndoUI",
|
||||
"//submodules/TranslateUI",
|
||||
"//submodules/ComponentFlow:ComponentFlow",
|
||||
"//submodules/Components/ViewControllerComponent:ViewControllerComponent",
|
||||
"//submodules/Components/MultilineTextComponent:MultilineTextComponent",
|
||||
"//submodules/Components/BundleIconComponent:BundleIconComponent",
|
||||
"//submodules/Components/BlurredBackgroundComponent:BlurredBackgroundComponent",
|
||||
"//submodules/TelegramUI/Components/MinimizedContainer",
|
||||
"//submodules/Pasteboard",
|
||||
"//submodules/SaveToCameraRoll",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -110,7 +110,7 @@ final class BrowserNavigationBarComponent: CombinedComponent {
|
||||
|
||||
return { context in
|
||||
var availableWidth = context.availableSize.width
|
||||
let sideInset: CGFloat = 11.0 + context.component.sideInset
|
||||
let sideInset: CGFloat = 16.0 + context.component.sideInset
|
||||
|
||||
let collapsedHeight: CGFloat = 24.0
|
||||
let expandedHeight = context.component.height
|
||||
@ -202,8 +202,8 @@ final class BrowserNavigationBarComponent: CombinedComponent {
|
||||
centerLeftInset += item.size.width + 8.0
|
||||
}
|
||||
|
||||
var centerRightInset = sideInset
|
||||
var rightItemX = context.availableSize.width - sideInset
|
||||
var centerRightInset = sideInset - 5.0
|
||||
var rightItemX = context.availableSize.width - (sideInset - 5.0)
|
||||
for item in rightItemList.reversed() {
|
||||
context.add(item
|
||||
.position(CGPoint(x: rightItemX - item.size.width / 2.0 + (item.size.width / 2.0 * 0.35 * context.component.collapseFraction), y: context.component.topInset + contentHeight / 2.0))
|
||||
|
@ -2,6 +2,7 @@ import Foundation
|
||||
import UIKit
|
||||
import SwiftSignalKit
|
||||
import Display
|
||||
import TelegramCore
|
||||
import TelegramPresentationData
|
||||
import ComponentFlow
|
||||
import ViewControllerComponent
|
||||
@ -14,6 +15,7 @@ import TelegramUIPreferences
|
||||
import OpenInExternalAppUI
|
||||
import MultilineTextComponent
|
||||
import MinimizedContainer
|
||||
import InstantPageUI
|
||||
|
||||
private let settingsTag = GenericComponentViewTag()
|
||||
|
||||
@ -72,8 +74,8 @@ private final class BrowserScreenComponent: CombinedComponent {
|
||||
let performAction = context.component.performAction
|
||||
|
||||
let navigationContent: AnyComponentWithIdentity<Empty>?
|
||||
let navigationLeftItems: [AnyComponentWithIdentity<Empty>]
|
||||
let navigationRightItems: [AnyComponentWithIdentity<Empty>]
|
||||
var navigationLeftItems: [AnyComponentWithIdentity<Empty>]
|
||||
var navigationRightItems: [AnyComponentWithIdentity<Empty>]
|
||||
if context.component.presentationState.isSearching {
|
||||
navigationContent = AnyComponentWithIdentity(
|
||||
id: "search",
|
||||
@ -113,23 +115,6 @@ private final class BrowserScreenComponent: CombinedComponent {
|
||||
|
||||
let isLoading = (context.component.contentState?.estimatedProgress ?? 1.0) < 1.0
|
||||
navigationRightItems = [
|
||||
AnyComponentWithIdentity(
|
||||
id: isLoading ? "stop" : "reload",
|
||||
component: AnyComponent(
|
||||
ReferenceButtonComponent(
|
||||
content: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: isLoading ? "Instant View/CloseIcon" : "Chat/Context Menu/Reload",
|
||||
tintColor: environment.theme.rootController.navigationBar.primaryTextColor
|
||||
)
|
||||
),
|
||||
tag: settingsTag,
|
||||
action: {
|
||||
performAction.invoke(isLoading ? .stop : .reload)
|
||||
}
|
||||
)
|
||||
)
|
||||
),
|
||||
AnyComponentWithIdentity(
|
||||
id: "settings",
|
||||
component: AnyComponent(
|
||||
@ -148,6 +133,28 @@ private final class BrowserScreenComponent: CombinedComponent {
|
||||
)
|
||||
)
|
||||
]
|
||||
if case .webPage = context.component.contentState?.contentType {
|
||||
navigationRightItems.insert(
|
||||
AnyComponentWithIdentity(
|
||||
id: isLoading ? "stop" : "reload",
|
||||
component: AnyComponent(
|
||||
ReferenceButtonComponent(
|
||||
content: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: isLoading ? "Instant View/CloseIcon" : "Chat/Context Menu/Reload",
|
||||
tintColor: environment.theme.rootController.navigationBar.primaryTextColor
|
||||
)
|
||||
),
|
||||
tag: settingsTag,
|
||||
action: {
|
||||
performAction.invoke(isLoading ? .stop : .reload)
|
||||
}
|
||||
)
|
||||
)
|
||||
),
|
||||
at: 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
let collapseFraction = context.component.presentationState.isSearching ? 0.0 : context.component.panelCollapseFraction
|
||||
@ -303,6 +310,8 @@ public class BrowserScreen: ViewController, MinimizableController {
|
||||
switch controller.subject {
|
||||
case let .webPage(url):
|
||||
content = BrowserWebContent(context: controller.context, url: url)
|
||||
case let .instantPage(webPage, sourceLocation):
|
||||
content = BrowserInstantPageContent(context: controller.context, webPage: webPage, url: webPage.content.url ?? "", sourceLocation: sourceLocation)
|
||||
}
|
||||
|
||||
self.content = content
|
||||
@ -717,6 +726,7 @@ public class BrowserScreen: ViewController, MinimizableController {
|
||||
|
||||
public enum Subject {
|
||||
case webPage(url: String)
|
||||
case instantPage(webPage: TelegramMediaWebpage, sourceLocation: InstantPageSourceLocation)
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
@ -754,6 +764,7 @@ public class BrowserScreen: ViewController, MinimizableController {
|
||||
}
|
||||
|
||||
public var isMinimized = false
|
||||
public var isMinimizable = true
|
||||
}
|
||||
|
||||
private final class BrowserReferenceContentSource: ContextReferenceContentSource {
|
||||
|
@ -20,6 +20,8 @@ public enum SendMessageActionSheetControllerParams {
|
||||
public let attachment: Bool
|
||||
public let canSendWhenOnline: Bool
|
||||
public let forwardMessageIds: [EngineMessage.Id]
|
||||
public let canMakePaidContent: Bool
|
||||
public let currentPrice: Int64?
|
||||
|
||||
public init(
|
||||
isScheduledMessages: Bool,
|
||||
@ -28,7 +30,9 @@ public enum SendMessageActionSheetControllerParams {
|
||||
messageEffect: (ChatSendMessageActionSheetControllerSendParameters.Effect?, (ChatSendMessageActionSheetControllerSendParameters.Effect?) -> Void)?,
|
||||
attachment: Bool,
|
||||
canSendWhenOnline: Bool,
|
||||
forwardMessageIds: [EngineMessage.Id]
|
||||
forwardMessageIds: [EngineMessage.Id],
|
||||
canMakePaidContent: Bool,
|
||||
currentPrice: Int64?
|
||||
) {
|
||||
self.isScheduledMessages = isScheduledMessages
|
||||
self.mediaPreview = mediaPreview
|
||||
@ -37,6 +41,8 @@ public enum SendMessageActionSheetControllerParams {
|
||||
self.attachment = attachment
|
||||
self.canSendWhenOnline = canSendWhenOnline
|
||||
self.forwardMessageIds = forwardMessageIds
|
||||
self.canMakePaidContent = canMakePaidContent
|
||||
self.currentPrice = currentPrice
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,6 +77,7 @@ public func makeChatSendMessageActionSheetController(
|
||||
completion: @escaping () -> Void,
|
||||
sendMessage: @escaping (ChatSendMessageActionSheetController.SendMode, ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
schedule: @escaping (ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
editPrice: @escaping (Int64) -> Void,
|
||||
openPremiumPaywall: @escaping (ViewController) -> Void,
|
||||
reactionItems: [ReactionItem]? = nil,
|
||||
availableMessageEffects: AvailableMessageEffects? = nil,
|
||||
@ -91,6 +98,7 @@ public func makeChatSendMessageActionSheetController(
|
||||
completion: completion,
|
||||
sendMessage: sendMessage,
|
||||
schedule: schedule,
|
||||
editPrice: editPrice,
|
||||
openPremiumPaywall: openPremiumPaywall,
|
||||
reactionItems: reactionItems,
|
||||
availableMessageEffects: availableMessageEffects,
|
||||
|
@ -67,6 +67,7 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
let completion: () -> Void
|
||||
let sendMessage: (ChatSendMessageActionSheetController.SendMode, ChatSendMessageActionSheetController.SendParameters?) -> Void
|
||||
let schedule: (ChatSendMessageActionSheetController.SendParameters?) -> Void
|
||||
let editPrice: (Int64) -> Void
|
||||
let openPremiumPaywall: (ViewController) -> Void
|
||||
let reactionItems: [ReactionItem]?
|
||||
let availableMessageEffects: AvailableMessageEffects?
|
||||
@ -87,6 +88,7 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
completion: @escaping () -> Void,
|
||||
sendMessage: @escaping (ChatSendMessageActionSheetController.SendMode, ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
schedule: @escaping (ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
editPrice: @escaping (Int64) -> Void,
|
||||
openPremiumPaywall: @escaping (ViewController) -> Void,
|
||||
reactionItems: [ReactionItem]?,
|
||||
availableMessageEffects: AvailableMessageEffects?,
|
||||
@ -106,6 +108,7 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
self.completion = completion
|
||||
self.sendMessage = sendMessage
|
||||
self.schedule = schedule
|
||||
self.editPrice = editPrice
|
||||
self.openPremiumPaywall = openPremiumPaywall
|
||||
self.reactionItems = reactionItems
|
||||
self.availableMessageEffects = availableMessageEffects
|
||||
@ -437,6 +440,8 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
var reminders = false
|
||||
var isSecret = false
|
||||
var canSchedule = false
|
||||
var canMakePaidContent = false
|
||||
var currentPrice: Int64?
|
||||
switch component.params {
|
||||
case let .sendMessage(sendMessage):
|
||||
if let peerId = component.peerId {
|
||||
@ -447,6 +452,8 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
if sendMessage.isScheduledMessages {
|
||||
canSchedule = false
|
||||
}
|
||||
canMakePaidContent = sendMessage.canMakePaidContent
|
||||
currentPrice = sendMessage.currentPrice
|
||||
case .editMessage:
|
||||
break
|
||||
}
|
||||
@ -566,6 +573,38 @@ final class ChatSendMessageContextScreenComponent: Component {
|
||||
}
|
||||
)))
|
||||
}
|
||||
if canMakePaidContent {
|
||||
let title: String
|
||||
let titleLayout: ContextMenuActionItemTextLayout
|
||||
if let currentPrice {
|
||||
title = environment.strings.Attachment_Paid_EditPrice
|
||||
titleLayout = .secondLineWithValue(environment.strings.Attachment_Paid_EditPrice_Stars(Int32(currentPrice)))
|
||||
} else {
|
||||
title = environment.strings.Attachment_Paid_Create
|
||||
titleLayout = .twoLinesMax
|
||||
}
|
||||
items.append(.action(ContextMenuActionItem(
|
||||
id: AnyHashable("paid"),
|
||||
text: title,
|
||||
textLayout: titleLayout,
|
||||
icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Media Grid/Paid"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, _ in
|
||||
guard let self, let component = self.component, case let .sendMessage(params) = component.params else {
|
||||
return
|
||||
}
|
||||
|
||||
let editPrice = component.editPrice
|
||||
let controller = component.context.sharedContext.makeStarsAmountScreen(context: component.context, initialValue: params.currentPrice, completion: { amount in
|
||||
editPrice(amount)
|
||||
})
|
||||
self.environment?.controller()?.dismiss()
|
||||
Queue.mainQueue().after(0.45) {
|
||||
component.openPremiumPaywall(controller)
|
||||
}
|
||||
}
|
||||
)))
|
||||
}
|
||||
case .editMessage:
|
||||
items.append(.action(ContextMenuActionItem(
|
||||
id: AnyHashable("silent"),
|
||||
@ -1385,6 +1424,7 @@ public class ChatSendMessageContextScreen: ViewControllerComponentContainer, Cha
|
||||
completion: @escaping () -> Void,
|
||||
sendMessage: @escaping (ChatSendMessageActionSheetController.SendMode, ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
schedule: @escaping (ChatSendMessageActionSheetController.SendParameters?) -> Void,
|
||||
editPrice: @escaping (Int64) -> Void,
|
||||
openPremiumPaywall: @escaping (ViewController) -> Void,
|
||||
reactionItems: [ReactionItem]?,
|
||||
availableMessageEffects: AvailableMessageEffects?,
|
||||
@ -1409,6 +1449,7 @@ public class ChatSendMessageContextScreen: ViewControllerComponentContainer, Cha
|
||||
completion: completion,
|
||||
sendMessage: sendMessage,
|
||||
schedule: schedule,
|
||||
editPrice: editPrice,
|
||||
openPremiumPaywall: openPremiumPaywall,
|
||||
reactionItems: reactionItems,
|
||||
availableMessageEffects: availableMessageEffects,
|
||||
|
@ -532,44 +532,7 @@ public final class ComposedPoll {
|
||||
}
|
||||
|
||||
private final class CreatePollContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,8 +24,10 @@ public protocol MinimizableController: ViewController {
|
||||
var minimizedTopEdgeOffset: CGFloat? { get }
|
||||
var minimizedBounds: CGRect? { get }
|
||||
var isMinimized: Bool { get set }
|
||||
var isMinimizable: Bool { get }
|
||||
|
||||
func makeContentSnapshotView() -> UIView?
|
||||
func shouldDismissImmediately() -> Bool
|
||||
}
|
||||
|
||||
public extension MinimizableController {
|
||||
@ -41,7 +43,15 @@ public extension MinimizableController {
|
||||
return false
|
||||
}
|
||||
|
||||
var isMinimizable: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func makeContentSnapshotView() -> UIView? {
|
||||
return self.displayNode.view.snapshotView(afterScreenUpdates: false)
|
||||
}
|
||||
|
||||
func shouldDismissImmediately() -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ public final class InstantPageContentNode : ASDisplayNode {
|
||||
// }
|
||||
}
|
||||
|
||||
func updateDetailsExpanded(_ index: Int, _ expanded: Bool, animated: Bool = true, requestLayout: Bool = true) {
|
||||
public func updateDetailsExpanded(_ index: Int, _ expanded: Bool, animated: Bool = true, requestLayout: Bool = true) {
|
||||
if var currentExpandedDetails = self.currentExpandedDetails {
|
||||
currentExpandedDetails[index] = expanded
|
||||
self.currentExpandedDetails = currentExpandedDetails
|
||||
@ -353,7 +353,7 @@ public final class InstantPageContentNode : ASDisplayNode {
|
||||
return contentOffset
|
||||
}
|
||||
|
||||
func nodeForDetailsItem(_ item: InstantPageDetailsItem) -> InstantPageDetailsNode? {
|
||||
public func nodeForDetailsItem(_ item: InstantPageDetailsItem) -> InstantPageDetailsNode? {
|
||||
for (_, itemNode) in self.visibleItemsWithNodes {
|
||||
if let detailsNode = itemNode as? InstantPageDetailsNode, detailsNode.item === item {
|
||||
return detailsNode
|
||||
|
@ -26,7 +26,7 @@ public final class InstantPageDetailsNode: ASDisplayNode, InstantPageNode {
|
||||
private let buttonNode: HighlightableButtonNode
|
||||
private let arrowNode: InstantPageDetailsArrowNode
|
||||
let separatorNode: ASDisplayNode
|
||||
let contentNode: InstantPageContentNode
|
||||
public let contentNode: InstantPageContentNode
|
||||
|
||||
private let updateExpanded: (Bool) -> Void
|
||||
var expanded: Bool
|
||||
@ -114,7 +114,7 @@ public final class InstantPageDetailsNode: ASDisplayNode, InstantPageNode {
|
||||
self.updateExpanded(expanded)
|
||||
}
|
||||
|
||||
func setExpanded(_ expanded: Bool, animated: Bool) {
|
||||
public func setExpanded(_ expanded: Bool, animated: Bool) {
|
||||
self.expanded = expanded
|
||||
self.arrowNode.setOpen(expanded, animated: animated)
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public final class InstantPageImageItem: InstantPageItem {
|
||||
|
||||
let webPage: TelegramMediaWebpage
|
||||
|
||||
let media: InstantPageMedia
|
||||
public let media: InstantPageMedia
|
||||
let attributes: [InstantPageImageAttribute]
|
||||
|
||||
public var medias: [InstantPageMedia] {
|
||||
|
@ -50,11 +50,11 @@ public final class InstantPageScrollableContentNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
final class InstantPageScrollableNode: ASScrollNode, InstantPageNode {
|
||||
let item: InstantPageScrollableItem
|
||||
public final class InstantPageScrollableNode: ASScrollNode, InstantPageNode {
|
||||
public let item: InstantPageScrollableItem
|
||||
let contentNode: InstantPageScrollableContentNode
|
||||
|
||||
var contentOffset: CGPoint {
|
||||
public var contentOffset: CGPoint {
|
||||
return self.view.contentOffset
|
||||
}
|
||||
|
||||
@ -90,19 +90,19 @@ final class InstantPageScrollableNode: ASScrollNode, InstantPageNode {
|
||||
}
|
||||
}
|
||||
|
||||
func updateIsVisible(_ isVisible: Bool) {
|
||||
public func updateIsVisible(_ isVisible: Bool) {
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
public func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
}
|
||||
|
||||
func transitionNode(media: InstantPageMedia) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
||||
public func transitionNode(media: InstantPageMedia) -> (ASDisplayNode, CGRect, () -> (UIView?, UIView?))? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateHiddenMedia(media: InstantPageMedia?) {
|
||||
public func updateHiddenMedia(media: InstantPageMedia?) {
|
||||
}
|
||||
|
||||
func update(strings: PresentationStrings, theme: InstantPageTheme) {
|
||||
public func update(strings: PresentationStrings, theme: InstantPageTheme) {
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ public final class InstantPageTextItem: InstantPageItem {
|
||||
let alignment: NSTextAlignment
|
||||
let opaqueBackground: Bool
|
||||
public let medias: [InstantPageMedia] = []
|
||||
let anchors: [String: (Int, Bool)]
|
||||
public let anchors: [String: (Int, Bool)]
|
||||
public let wantsNode: Bool = false
|
||||
public let separatesTiles: Bool = false
|
||||
public var selectable: Bool = true
|
||||
|
@ -84,32 +84,32 @@ public struct InstantPageTextCategories {
|
||||
}
|
||||
|
||||
public final class InstantPageTheme {
|
||||
let type: InstantPageThemeType
|
||||
let pageBackgroundColor: UIColor
|
||||
public let type: InstantPageThemeType
|
||||
public let pageBackgroundColor: UIColor
|
||||
|
||||
let textCategories: InstantPageTextCategories
|
||||
let serif: Bool
|
||||
public let textCategories: InstantPageTextCategories
|
||||
public let serif: Bool
|
||||
|
||||
let codeBlockBackgroundColor: UIColor
|
||||
public let codeBlockBackgroundColor: UIColor
|
||||
|
||||
let linkColor: UIColor
|
||||
let textHighlightColor: UIColor
|
||||
let linkHighlightColor: UIColor
|
||||
let markerColor: UIColor
|
||||
public let linkColor: UIColor
|
||||
public let textHighlightColor: UIColor
|
||||
public let linkHighlightColor: UIColor
|
||||
public let markerColor: UIColor
|
||||
|
||||
let panelBackgroundColor: UIColor
|
||||
let panelHighlightedBackgroundColor: UIColor
|
||||
let panelPrimaryColor: UIColor
|
||||
let panelSecondaryColor: UIColor
|
||||
let panelAccentColor: UIColor
|
||||
public let panelBackgroundColor: UIColor
|
||||
public let panelHighlightedBackgroundColor: UIColor
|
||||
public let panelPrimaryColor: UIColor
|
||||
public let panelSecondaryColor: UIColor
|
||||
public let panelAccentColor: UIColor
|
||||
|
||||
let tableBorderColor: UIColor
|
||||
let tableHeaderColor: UIColor
|
||||
let controlColor: UIColor
|
||||
public let tableBorderColor: UIColor
|
||||
public let tableHeaderColor: UIColor
|
||||
public let controlColor: UIColor
|
||||
|
||||
let imageTintColor: UIColor?
|
||||
public let imageTintColor: UIColor?
|
||||
|
||||
let overlayPanelColor: UIColor
|
||||
public let overlayPanelColor: UIColor
|
||||
|
||||
public init(type: InstantPageThemeType, pageBackgroundColor: UIColor, textCategories: InstantPageTextCategories, serif: Bool, codeBlockBackgroundColor: UIColor, linkColor: UIColor, textHighlightColor: UIColor, linkHighlightColor: UIColor, markerColor: UIColor, panelBackgroundColor: UIColor, panelHighlightedBackgroundColor: UIColor, panelPrimaryColor: UIColor, panelSecondaryColor: UIColor, panelAccentColor: UIColor, tableBorderColor: UIColor, tableHeaderColor: UIColor, controlColor: UIColor, imageTintColor: UIColor?, overlayPanelColor: UIColor) {
|
||||
self.type = type
|
||||
@ -308,7 +308,7 @@ func instantPageThemeTypeForSettingsAndTime(themeSettings: PresentationThemeSett
|
||||
return (settings.themeType, false)
|
||||
}
|
||||
|
||||
func instantPageThemeForType(_ type: InstantPageThemeType, settings: InstantPagePresentationSettings) -> InstantPageTheme {
|
||||
public func instantPageThemeForType(_ type: InstantPageThemeType, settings: InstantPagePresentationSettings) -> InstantPageTheme {
|
||||
switch type {
|
||||
case .light:
|
||||
return lightTheme.withUpdatedFontStyles(sizeMultiplier: fontSizeMultiplierForVariant(settings.fontSize), forceSerif: settings.forceSerif)
|
||||
|
@ -397,44 +397,6 @@ public final class LocationPickerController: ViewController, AttachmentContainab
|
||||
}
|
||||
|
||||
private final class LocationPickerContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
public func storyLocationPickerController(
|
||||
|
@ -188,7 +188,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
private let bannedSendPhotos: (Int32, Bool)?
|
||||
private let bannedSendVideos: (Int32, Bool)?
|
||||
private let canBoostToUnrestrict: Bool
|
||||
private let paidMediaAllowed: Bool
|
||||
fileprivate let paidMediaAllowed: Bool
|
||||
private let subject: Subject
|
||||
private let saveEditedPhotos: Bool
|
||||
|
||||
@ -2207,7 +2207,7 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable {
|
||||
})
|
||||
}
|
||||
|
||||
private var selectionCount: Int32 = 0
|
||||
fileprivate var selectionCount: Int32 = 0
|
||||
fileprivate func updateSelectionState(count: Int32) {
|
||||
self.selectionCount = count
|
||||
|
||||
@ -2667,6 +2667,45 @@ final class MediaPickerContext: AttachmentMediaPickerContext {
|
||||
return isForcedCaption
|
||||
}
|
||||
|
||||
var canMakePaidContent: Bool {
|
||||
guard let controller = self.controller else {
|
||||
return false
|
||||
}
|
||||
var isPaidAvailable = false
|
||||
if controller.paidMediaAllowed && controller.selectionCount <= 10 {
|
||||
isPaidAvailable = true
|
||||
}
|
||||
return isPaidAvailable
|
||||
}
|
||||
|
||||
var price: Int64? {
|
||||
guard let controller = self.controller else {
|
||||
return nil
|
||||
}
|
||||
var price: Int64?
|
||||
if let selectionContext = controller.interaction?.selectionState, let editingContext = controller.interaction?.editingState {
|
||||
for case let item as TGMediaEditableItem in selectionContext.selectedItems() {
|
||||
if price == nil, let itemPrice = editingContext.price(for: item) as? Int64 {
|
||||
price = itemPrice
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return price
|
||||
}
|
||||
|
||||
func setPrice(_ price: Int64) {
|
||||
guard let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
if let selectionContext = controller.interaction?.selectionState, let editingContext = controller.interaction?.editingState {
|
||||
selectionContext.selectionLimit = 10
|
||||
for case let item as TGMediaEditableItem in selectionContext.selectedItems() {
|
||||
editingContext.setPrice(NSNumber(value: price), for: item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return Signal { [weak self] subscriber in
|
||||
guard let interaction = self?.controller?.interaction else {
|
||||
|
@ -1516,11 +1516,14 @@ private func monetizationEntries(
|
||||
starsTransactionsInfo: StarsTransactionsContext.State,
|
||||
adsRestricted: Bool,
|
||||
premiumConfiguration: PremiumConfiguration,
|
||||
monetizationConfiguration: MonetizationConfiguration
|
||||
monetizationConfiguration: MonetizationConfiguration,
|
||||
canViewRevenue: Bool,
|
||||
canViewStarsRevenue: Bool
|
||||
) -> [StatsEntry] {
|
||||
var entries: [StatsEntry] = []
|
||||
entries.append(.adsHeader(presentationData.theme, presentationData.strings.Monetization_Header))
|
||||
|
||||
if canViewRevenue {
|
||||
if !data.topHoursGraph.isEmpty {
|
||||
entries.append(.adsImpressionsTitle(presentationData.theme, presentationData.strings.Monetization_ImpressionsTitle))
|
||||
entries.append(.adsImpressionsGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.topHoursGraph, .hourlyStep))
|
||||
@ -1530,11 +1533,14 @@ private func monetizationEntries(
|
||||
entries.append(.adsTonRevenueTitle(presentationData.theme, presentationData.strings.Monetization_AdRevenueTitle))
|
||||
entries.append(.adsTonRevenueGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.revenueGraph, .currency, data.usdRate))
|
||||
}
|
||||
}
|
||||
|
||||
if canViewStarsRevenue {
|
||||
if let starsData, !starsData.revenueGraph.isEmpty {
|
||||
entries.append(.adsStarsRevenueTitle(presentationData.theme, presentationData.strings.Monetization_StarsRevenueTitle))
|
||||
entries.append(.adsStarsRevenueGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, starsData.revenueGraph, .stars, starsData.usdRate))
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(.adsProceedsTitle(presentationData.theme, presentationData.strings.Monetization_OverviewTitle))
|
||||
entries.append(.adsProceedsOverview(presentationData.theme, data, starsData))
|
||||
@ -1543,6 +1549,8 @@ private func monetizationEntries(
|
||||
if let peer, case let .channel(channel) = peer, channel.flags.contains(.isCreator) {
|
||||
isCreator = true
|
||||
}
|
||||
|
||||
if canViewRevenue {
|
||||
entries.append(.adsTonBalanceTitle(presentationData.theme, presentationData.strings.Monetization_TonBalanceTitle))
|
||||
entries.append(.adsTonBalance(presentationData.theme, data, isCreator && data.balances.availableBalance > 0, monetizationConfiguration.withdrawalAvailable))
|
||||
|
||||
@ -1557,26 +1565,29 @@ private func monetizationEntries(
|
||||
}
|
||||
entries.append(.adsTonBalanceInfo(presentationData.theme, withdrawalInfoText))
|
||||
}
|
||||
}
|
||||
|
||||
if canViewStarsRevenue {
|
||||
if let starsData, starsData.balances.overallRevenue > 0 {
|
||||
entries.append(.adsStarsBalanceTitle(presentationData.theme, presentationData.strings.Monetization_StarsBalanceTitle))
|
||||
entries.append(.adsStarsBalance(presentationData.theme, starsData, isCreator && starsData.balances.availableBalance > 0, starsData.balances.withdrawEnabled, starsData.balances.nextWithdrawalTimestamp))
|
||||
entries.append(.adsStarsBalanceInfo(presentationData.theme, presentationData.strings.Monetization_Balance_StarsInfo))
|
||||
}
|
||||
}
|
||||
|
||||
var addedTransactionsTabs = false
|
||||
if !transactionsInfo.transactions.isEmpty && !starsTransactionsInfo.transactions.isEmpty {
|
||||
if !transactionsInfo.transactions.isEmpty && !starsTransactionsInfo.transactions.isEmpty && canViewRevenue && canViewStarsRevenue {
|
||||
addedTransactionsTabs = true
|
||||
entries.append(.adsTransactionsTabs(presentationData.theme, presentationData.strings.Monetization_TonTransactions, presentationData.strings.Monetization_StarsTransactions, state.starsSelected))
|
||||
}
|
||||
|
||||
var displayTonTransactions = false
|
||||
if !transactionsInfo.transactions.isEmpty && (starsTransactionsInfo.transactions.isEmpty || !state.starsSelected) {
|
||||
if canViewRevenue && !transactionsInfo.transactions.isEmpty && (starsTransactionsInfo.transactions.isEmpty || !state.starsSelected) {
|
||||
displayTonTransactions = true
|
||||
}
|
||||
|
||||
var displayStarsTransactions = false
|
||||
if !starsTransactionsInfo.transactions.isEmpty && (transactionsInfo.transactions.isEmpty || state.starsSelected) {
|
||||
if canViewStarsRevenue && !starsTransactionsInfo.transactions.isEmpty && (transactionsInfo.transactions.isEmpty || state.starsSelected) {
|
||||
displayStarsTransactions = true
|
||||
}
|
||||
|
||||
@ -1675,7 +1686,9 @@ private func channelStatsControllerEntries(
|
||||
starsTransactions: StarsTransactionsContext.State,
|
||||
adsRestricted: Bool,
|
||||
premiumConfiguration: PremiumConfiguration,
|
||||
monetizationConfiguration: MonetizationConfiguration
|
||||
monetizationConfiguration: MonetizationConfiguration,
|
||||
canViewRevenue: Bool,
|
||||
canViewStarsRevenue: Bool
|
||||
) -> [StatsEntry] {
|
||||
switch state.section {
|
||||
case .stats:
|
||||
@ -1715,7 +1728,9 @@ private func channelStatsControllerEntries(
|
||||
starsTransactionsInfo: starsTransactions,
|
||||
adsRestricted: adsRestricted,
|
||||
premiumConfiguration: premiumConfiguration,
|
||||
monetizationConfiguration: monetizationConfiguration
|
||||
monetizationConfiguration: monetizationConfiguration,
|
||||
canViewRevenue: canViewRevenue,
|
||||
canViewStarsRevenue: canViewStarsRevenue
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -2039,7 +2054,7 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
)
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, state, peer, data, messageView, stories, boostData, boostersState, giftsState, revenueState, revenueTransactions, starsState, starsTransactions, peerData, longLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let (adsRestricted, canViewRevenue, _) = peerData
|
||||
let (adsRestricted, canViewRevenue, canViewStarsRevenue) = peerData
|
||||
|
||||
var isGroup = false
|
||||
if let peer, case let .channel(channel) = peer, case .group = channel.info {
|
||||
@ -2124,14 +2139,14 @@ public func channelStatsController(context: AccountContext, updatedPresentationD
|
||||
var tabs: [String] = []
|
||||
tabs.append(presentationData.strings.Stats_Statistics)
|
||||
tabs.append(presentationData.strings.Stats_Boosts)
|
||||
if canViewRevenue {
|
||||
if canViewRevenue || canViewStarsRevenue {
|
||||
tabs.append(presentationData.strings.Stats_Monetization)
|
||||
}
|
||||
title = .textWithTabs(peer?.compactDisplayTitle ?? "", tabs, index)
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: title, leftNavigationButton: leftNavigationButton, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelStatsControllerEntries(presentationData: presentationData, state: state, peer: peer, data: data, messages: messages, stories: stories, interactions: interactions, boostData: boostData, boostersState: boostersState, giftsState: giftsState, giveawayAvailable: premiumConfiguration.giveawayGiftsPurchaseAvailable, isGroup: isGroup, boostsOnly: boostsOnly, revenueState: revenueState?.stats, revenueTransactions: revenueTransactions, starsState: starsState?.stats, starsTransactions: starsTransactions, adsRestricted: adsRestricted, premiumConfiguration: premiumConfiguration, monetizationConfiguration: monetizationConfiguration), style: .blocks, emptyStateItem: emptyStateItem, headerItem: headerItem, crossfadeState: previous == nil, animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelStatsControllerEntries(presentationData: presentationData, state: state, peer: peer, data: data, messages: messages, stories: stories, interactions: interactions, boostData: boostData, boostersState: boostersState, giftsState: giftsState, giveawayAvailable: premiumConfiguration.giveawayGiftsPurchaseAvailable, isGroup: isGroup, boostsOnly: boostsOnly, revenueState: revenueState?.stats, revenueTransactions: revenueTransactions, starsState: starsState?.stats, starsTransactions: starsTransactions, adsRestricted: adsRestricted, premiumConfiguration: premiumConfiguration, monetizationConfiguration: monetizationConfiguration, canViewRevenue: canViewRevenue, canViewStarsRevenue: canViewStarsRevenue), style: .blocks, emptyStateItem: emptyStateItem, headerItem: headerItem, crossfadeState: previous == nil, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
@ -179,7 +179,17 @@ private final class ChatMessageActionButtonNode: ASDisplayNode {
|
||||
case .text:
|
||||
iconImage = incoming ? graphics.chatBubbleActionButtonIncomingMessageIconImage : graphics.chatBubbleActionButtonOutgoingMessageIconImage
|
||||
case let .url(value):
|
||||
if isTelegramMeLink(value), let internalUrl = parseFullInternalUrl(sharedContext: context.sharedContext, url: value), case .peer(_, .appStart) = internalUrl {
|
||||
var isApp = false
|
||||
if isTelegramMeLink(value), let internalUrl = parseFullInternalUrl(sharedContext: context.sharedContext, url: value) {
|
||||
if case .peer(_, .appStart) = internalUrl {
|
||||
isApp = true
|
||||
} else if case .peer(_, .attachBotStart) = internalUrl {
|
||||
isApp = true
|
||||
} else if case .startAttach = internalUrl {
|
||||
isApp = true
|
||||
}
|
||||
}
|
||||
if isApp {
|
||||
iconImage = incoming ? graphics.chatBubbleActionButtonIncomingWebAppIconImage : graphics.chatBubbleActionButtonOutgoingWebAppIconImage
|
||||
} else if value.lowercased().contains("?startgroup=") {
|
||||
iconImage = incoming ? graphics.chatBubbleActionButtonIncomingAddToChatIconImage : graphics.chatBubbleActionButtonOutgoingAddToChatIconImage
|
||||
|
@ -697,11 +697,15 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
self.scrollView.addSubnode(itemNode)
|
||||
self.itemNodes[item.id] = itemNode
|
||||
}
|
||||
itemNode.closeTapped = { [weak self] in
|
||||
itemNode.closeTapped = { [weak self, weak itemNode] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if self.isExpanded {
|
||||
let proceed = { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
var needsLayout = true
|
||||
self.currentTransition = .dismiss(itemId: item.id)
|
||||
|
||||
@ -714,10 +718,72 @@ public class MinimizedContainerImpl: ASDisplayNode, MinimizedContainer, ASScroll
|
||||
if needsLayout {
|
||||
self.requestUpdate(transition: .animated(duration: 0.4, curve: .spring))
|
||||
}
|
||||
}
|
||||
if let item = itemNode?.item, !item.controller.shouldDismissImmediately() {
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
actionSheet.setItemGroups([
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetTextItem(title: self.presentationData.strings.WebApp_CloseConfirmation),
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.WebApp_CloseAnyway, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
proceed()
|
||||
})
|
||||
]),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
self.navigationController?.presentOverlay(controller: actionSheet, inGlobal: false, blockInteraction: false)
|
||||
} else {
|
||||
proceed()
|
||||
}
|
||||
} else {
|
||||
if self.items.count > 1 {
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
actionSheet.setItemGroups([
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetTextItem(title: self.presentationData.strings.WebApp_Minimized_CloseAllTitle),
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.WebApp_Minimized_CloseAll(Int32(self.items.count)), color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
self?.navigationController?.dismissMinimizedControllers(animated: true)
|
||||
})
|
||||
]),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
self.navigationController?.presentOverlay(controller: actionSheet, inGlobal: false, blockInteraction: false)
|
||||
} else if let item = self.items.first {
|
||||
if !item.controller.shouldDismissImmediately() {
|
||||
let actionSheet = ActionSheetController(presentationData: self.presentationData)
|
||||
actionSheet.setItemGroups([
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetTextItem(title: self.presentationData.strings.WebApp_CloseConfirmation),
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.WebApp_CloseAnyway, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
||||
self?.navigationController?.dismissMinimizedControllers(animated: true)
|
||||
})
|
||||
]),
|
||||
ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: self.presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])
|
||||
])
|
||||
self.navigationController?.presentOverlay(controller: actionSheet, inGlobal: false, blockInteraction: false)
|
||||
} else {
|
||||
self.navigationController?.dismissMinimizedControllers(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
itemNode.tapped = { [weak self, weak itemNode] in
|
||||
guard let self else {
|
||||
return
|
||||
|
@ -709,7 +709,9 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
messageEffect: nil,
|
||||
attachment: false,
|
||||
canSendWhenOnline: false,
|
||||
forwardMessageIds: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? []
|
||||
forwardMessageIds: strongSelf.presentationInterfaceState.interfaceState.forwardMessageIds ?? [],
|
||||
canMakePaidContent: false,
|
||||
currentPrice: nil
|
||||
)),
|
||||
hasEntityKeyboard: hasEntityKeyboard,
|
||||
gesture: gesture,
|
||||
@ -731,6 +733,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
||||
schedule: { [weak textInputPanelNode] messageEffect in
|
||||
textInputPanelNode?.sendMessage(.schedule, messageEffect)
|
||||
},
|
||||
editPrice: { _ in },
|
||||
openPremiumPaywall: { [weak controller] c in
|
||||
guard let controller else {
|
||||
return
|
||||
|
@ -27,29 +27,6 @@ public class PremiumGiftAttachmentScreen: PremiumGiftScreen, AttachmentContainab
|
||||
private final class PremiumGiftContext: AttachmentMediaPickerContext {
|
||||
private weak var controller: PremiumGiftScreen?
|
||||
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return self.controller?.mainButtonStatePromise.get() ?? .single(nil)
|
||||
}
|
||||
@ -58,15 +35,6 @@ private final class PremiumGiftContext: AttachmentMediaPickerContext {
|
||||
self.controller = controller
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
self.controller?.mainButtonPressed()
|
||||
}
|
||||
|
@ -355,29 +355,6 @@ public final class ThemeColorsGridController: ViewController, AttachmentContaina
|
||||
private final class ThemeColorsGridContext: AttachmentMediaPickerContext {
|
||||
private weak var controller: ThemeColorsGridController?
|
||||
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(self.controller?.mainButtonState)
|
||||
}
|
||||
@ -386,15 +363,6 @@ private final class ThemeColorsGridContext: AttachmentMediaPickerContext {
|
||||
self.controller = controller
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
self.controller?.mainButtonPressed()
|
||||
}
|
||||
|
@ -164,44 +164,6 @@ private func attachmentFileControllerEntries(presentationData: PresentationData,
|
||||
}
|
||||
|
||||
private final class AttachmentFileContext: AttachmentMediaPickerContext {
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
}
|
||||
}
|
||||
|
||||
class AttachmentFileControllerImpl: ItemListController, AttachmentFileController, AttachmentContainable {
|
||||
|
@ -78,7 +78,6 @@ public extension ChatControllerImpl {
|
||||
if source == .menu {
|
||||
self.updateChatPresentationInterfaceState(interactive: false) { state in
|
||||
return state.updatedForceInputCommandsHidden(true)
|
||||
// return state.updatedShowWebView(true).updatedForceInputCommandsHidden(true)
|
||||
}
|
||||
|
||||
if let navigationController = self.navigationController as? NavigationController, let minimizedContainer = navigationController.minimizedContainer {
|
||||
@ -199,7 +198,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
self.messageActionCallbackDisposable.set(((self.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(self.presentationData.theme), fromMenu: buttonText == "Menu", replyToMessageId: nil, threadId: self.chatLocation.threadId)
|
||||
self.messageActionCallbackDisposable.set(((self.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(self.presentationData.theme), fromMenu: false, replyToMessageId: nil, threadId: self.chatLocation.threadId)
|
||||
|> afterDisposed {
|
||||
updateProgress()
|
||||
})
|
||||
@ -208,7 +207,7 @@ public extension ChatControllerImpl {
|
||||
return
|
||||
}
|
||||
let context = strongSelf.context
|
||||
let params = WebAppParameters(source: .generic, peerId: peerId, botId: peerId, botName: botName, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
|
||||
let params = WebAppParameters(source: .button, peerId: peerId, botId: peerId, botName: botName, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
|
||||
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url, concealed, commit in
|
||||
self?.openUrl(url, concealed: concealed, forceExternal: true, commit: commit)
|
||||
}, completion: { [weak self] in
|
||||
|
@ -163,6 +163,8 @@ func chatMessageDisplaySendMessageOptions(selfController: ChatControllerImpl, no
|
||||
selfController.interfaceInteraction?.editMessage()
|
||||
},
|
||||
schedule: { _ in
|
||||
},
|
||||
editPrice: { _ in
|
||||
}, openPremiumPaywall: { [weak selfController] c in
|
||||
guard let selfController else {
|
||||
return
|
||||
@ -231,7 +233,9 @@ func chatMessageDisplaySendMessageOptions(selfController: ChatControllerImpl, no
|
||||
}),
|
||||
attachment: false,
|
||||
canSendWhenOnline: sendWhenOnlineAvailable,
|
||||
forwardMessageIds: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? []
|
||||
forwardMessageIds: selfController.presentationInterfaceState.interfaceState.forwardMessageIds ?? [],
|
||||
canMakePaidContent: false,
|
||||
currentPrice: nil
|
||||
)),
|
||||
hasEntityKeyboard: hasEntityKeyboard,
|
||||
gesture: gesture,
|
||||
@ -271,6 +275,7 @@ func chatMessageDisplaySendMessageOptions(selfController: ChatControllerImpl, no
|
||||
return
|
||||
}
|
||||
selfController.controllerInteraction?.scheduleCurrentMessage(params)
|
||||
}, editPrice: { _ in
|
||||
}, openPremiumPaywall: { [weak selfController] c in
|
||||
guard let selfController else {
|
||||
return
|
||||
|
@ -454,29 +454,6 @@ final class ContactsPickerContext: AttachmentMediaPickerContext {
|
||||
}
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
init(controller: ContactSelectionControllerImpl) {
|
||||
self.controller = controller
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import WebsiteType
|
||||
import GalleryData
|
||||
import StoryContainerScreen
|
||||
import WallpaperGalleryScreen
|
||||
import BrowserUI
|
||||
|
||||
func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
||||
var story: TelegramMediaStory?
|
||||
@ -373,7 +374,13 @@ func openChatInstantPageImpl(context: AccountContext, message: Message, sourcePe
|
||||
if let (webpage, anchor) = instantPageAndAnchor(message: message) {
|
||||
let sourceLocation = InstantPageSourceLocation(userLocation: .peer(message.id.peerId), peerType: sourcePeerType ?? .channel)
|
||||
|
||||
let pageController = InstantPageController(context: context, webPage: webpage, sourceLocation: sourceLocation, anchor: anchor)
|
||||
let pageController: ViewController
|
||||
if !"".isEmpty, context.sharedContext.immediateExperimentalUISettings.browserExperiment {
|
||||
let _ = anchor
|
||||
pageController = BrowserScreen(context: context, subject: .instantPage(webPage: webpage, sourceLocation: sourceLocation))
|
||||
} else {
|
||||
pageController = InstantPageController(context: context, webPage: webpage, sourceLocation: sourceLocation, anchor: anchor)
|
||||
}
|
||||
navigationController.pushViewController(pageController)
|
||||
}
|
||||
}
|
||||
|
@ -590,25 +590,6 @@ public class WebSearchPickerContext: AttachmentMediaPickerContext {
|
||||
}
|
||||
}
|
||||
|
||||
public var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
public var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
public func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
init(interaction: WebSearchControllerInteraction) {
|
||||
self.interaction = interaction
|
||||
}
|
||||
@ -624,8 +605,4 @@ public class WebSearchPickerContext: AttachmentMediaPickerContext {
|
||||
public func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
self.interaction?.schedule(parameters)
|
||||
}
|
||||
|
||||
public func mainButtonAction() {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ public class WebAppCancelButtonNode: ASDisplayNode {
|
||||
public struct WebAppParameters {
|
||||
public enum Source {
|
||||
case generic
|
||||
case button
|
||||
case menu
|
||||
case attachMenu
|
||||
case inline
|
||||
@ -1211,6 +1212,10 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
|
||||
self.openBotSettings()
|
||||
}
|
||||
case "web_app_setup_swipe_behavior":
|
||||
if let json = json, let isPanGestureEnabled = json["allow_vertical_swipe"] as? Bool {
|
||||
self.controller?._isPanGestureEnabled = isPanGestureEnabled
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1949,7 +1954,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
switch self.source {
|
||||
case .generic, .settings:
|
||||
completion()
|
||||
case .inline, .attachMenu, .menu, .simple:
|
||||
case .button, .inline, .attachMenu, .menu, .simple:
|
||||
let _ = (self.context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.Peer(id: self.peerId)
|
||||
)
|
||||
@ -2179,10 +2184,28 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
}
|
||||
}
|
||||
|
||||
public func shouldDismissImmediately() -> Bool {
|
||||
public var isMinimizable: Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
public func shouldDismissImmediately() -> Bool {
|
||||
if self.controllerNode.needDismissConfirmation {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate var _isPanGestureEnabled = true
|
||||
public var isInnerPanGestureEnabled: (() -> Bool)? {
|
||||
return { [weak self] in
|
||||
guard let self else {
|
||||
return true
|
||||
}
|
||||
return self._isPanGestureEnabled
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate var canMinimize: Bool {
|
||||
return self.controllerNode.canMinimize
|
||||
}
|
||||
@ -2191,25 +2214,6 @@ public final class WebAppController: ViewController, AttachmentContainable {
|
||||
final class WebAppPickerContext: AttachmentMediaPickerContext {
|
||||
private weak var controller: WebAppController?
|
||||
|
||||
var selectionCount: Signal<Int, NoError> {
|
||||
return .single(0)
|
||||
}
|
||||
|
||||
var caption: Signal<NSAttributedString?, NoError> {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
var hasCaption: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var captionIsAboveMedia: Signal<Bool, NoError> {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
func setCaptionIsAboveMedia(_ captionIsAboveMedia: Bool) -> Void {
|
||||
}
|
||||
|
||||
public var loadingProgress: Signal<CGFloat?, NoError> {
|
||||
return self.controller?.controllerNode.loadingProgressPromise.get() ?? .single(nil)
|
||||
}
|
||||
@ -2222,15 +2226,6 @@ final class WebAppPickerContext: AttachmentMediaPickerContext {
|
||||
self.controller = controller
|
||||
}
|
||||
|
||||
func setCaption(_ caption: NSAttributedString) {
|
||||
}
|
||||
|
||||
func send(mode: AttachmentMediaPickerSendMode, attachmentMode: AttachmentMediaPickerAttachmentMode, parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func schedule(parameters: ChatSendMessageActionSheetController.SendParameters?) {
|
||||
}
|
||||
|
||||
func mainButtonAction() {
|
||||
self.controller?.controllerNode.mainButtonPressed()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user