Various fixes

This commit is contained in:
Ilya Laktyushin 2024-09-25 20:37:17 +04:00
parent 2ea141ca1c
commit d0fe102210
8 changed files with 84 additions and 31 deletions

View File

@ -1011,14 +1011,15 @@ final class GiftOptionsScreenComponent: Component {
} }
} }
public final class GiftOptionsScreen: ViewControllerComponentContainer, GiftOptionsScreenProtocol { open class GiftOptionsScreen: ViewControllerComponentContainer, GiftOptionsScreenProtocol {
private let context: AccountContext private let context: AccountContext
public init( public init(
context: AccountContext, context: AccountContext,
starsContext: StarsContext, starsContext: StarsContext,
peerId: EnginePeer.Id, peerId: EnginePeer.Id,
premiumOptions: [CachedPremiumGiftOption] premiumOptions: [CachedPremiumGiftOption],
completion: @escaping () -> Void = {}
) { ) {
self.context = context self.context = context

View File

@ -341,7 +341,7 @@ final class GiftSetupScreenComponent: Component {
autocapitalizationType: .none, autocapitalizationType: .none,
autocorrectionType: .no, autocorrectionType: .no,
returnKeyType: .done, returnKeyType: .done,
characterLimit: 70, characterLimit: 255,
displayCharacterLimit: true, displayCharacterLimit: true,
emptyLineHandling: .notAllowed, emptyLineHandling: .notAllowed,
updated: { _ in updated: { _ in

View File

@ -17,7 +17,7 @@ swift_library(
"//submodules/SSignalKit/SwiftSignalKit", "//submodules/SSignalKit/SwiftSignalKit",
"//submodules/AccountContext", "//submodules/AccountContext",
"//submodules/AttachmentUI", "//submodules/AttachmentUI",
"//submodules/PremiumUI", "//submodules/TelegramUI/Components/Gifts/GiftOptionsScreen",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -5,15 +5,17 @@ import AsyncDisplayKit
import ComponentFlow import ComponentFlow
import SwiftSignalKit import SwiftSignalKit
import AccountContext import AccountContext
import PremiumUI
import AttachmentUI import AttachmentUI
import GiftOptionsScreen
public class PremiumGiftAttachmentScreen: PremiumGiftScreen, AttachmentContainable { public class PremiumGiftAttachmentScreen: GiftOptionsScreen, AttachmentContainable {
public var requestAttachmentMenuExpansion: () -> Void = {} public var requestAttachmentMenuExpansion: () -> Void = {}
public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in } public var updateNavigationStack: (@escaping ([AttachmentContainable]) -> ([AttachmentContainable], AttachmentMediaPickerContext?)) -> Void = { _ in }
public var parentController: () -> ViewController? = { public var parentController: () -> ViewController? = {
return nil return nil
} }
public var updateTabBarAlpha: (CGFloat, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var updateTabBarVisibility: (Bool, ContainedViewLayoutTransition) -> Void = { _, _ in }
public var cancelPanGesture: () -> Void = { } public var cancelPanGesture: () -> Void = { }
public var isContainerPanning: () -> Bool = { return false } public var isContainerPanning: () -> Bool = { return false }
public var isContainerExpanded: () -> Bool = { return false } public var isContainerExpanded: () -> Bool = { return false }
@ -25,17 +27,16 @@ public class PremiumGiftAttachmentScreen: PremiumGiftScreen, AttachmentContainab
} }
private final class PremiumGiftContext: AttachmentMediaPickerContext { private final class PremiumGiftContext: AttachmentMediaPickerContext {
private weak var controller: PremiumGiftScreen? private weak var controller: GiftOptionsScreen?
public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> { public var mainButtonState: Signal<AttachmentMainButtonState?, NoError> {
return self.controller?.mainButtonStatePromise.get() ?? .single(nil) return .single(nil)
} }
init(controller: PremiumGiftScreen) { init(controller: GiftOptionsScreen) {
self.controller = controller self.controller = controller
} }
func mainButtonAction() { func mainButtonAction() {
self.controller?.mainButtonPressed()
} }
} }

View File

@ -588,19 +588,17 @@ extension ChatControllerImpl {
strongSelf.controllerNavigationDisposable.set(nil) strongSelf.controllerNavigationDisposable.set(nil)
} }
case .gift: case .gift:
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer { if let peer = strongSelf.presentationInterfaceState.renderedPeer?.peer, let starsContext = context.starsContext {
let premiumGiftOptions = strongSelf.presentationInterfaceState.premiumGiftOptions let premiumGiftOptions = strongSelf.presentationInterfaceState.premiumGiftOptions
if !premiumGiftOptions.isEmpty { if !premiumGiftOptions.isEmpty {
let controller = PremiumGiftAttachmentScreen(context: context, peerIds: [peer.id], options: premiumGiftOptions, source: .attachMenu, pushController: { [weak self] c in let controller = PremiumGiftAttachmentScreen(context: context, starsContext: starsContext, peerId: peer.id, premiumOptions: premiumGiftOptions, completion: { [weak self] in
if let strongSelf = self { guard let self else {
strongSelf.push(c) return
}
}, completion: { [weak self] in
if let strongSelf = self {
strongSelf.hintPlayNextOutgoingGift()
strongSelf.attachmentController?.dismiss(animated: true)
} }
self.hintPlayNextOutgoingGift()
self.attachmentController?.dismiss(animated: true)
}) })
completion(controller, controller.mediaPickerContext) completion(controller, controller.mediaPickerContext)
strongSelf.controllerNavigationDisposable.set(nil) strongSelf.controllerNavigationDisposable.set(nil)

View File

@ -14,6 +14,7 @@ import AttachmentUI
import SearchBarNode import SearchBarNode
import ChatSendAudioMessageContextPreview import ChatSendAudioMessageContextPreview
import ChatSendMessageActionUI import ChatSendMessageActionUI
import ContextUI
class ContactSelectionControllerImpl: ViewController, ContactSelectionController, PresentableController, AttachmentContainable { class ContactSelectionControllerImpl: ViewController, ContactSelectionController, PresentableController, AttachmentContainable {
private let context: AccountContext private let context: AccountContext
@ -42,6 +43,9 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
private let multipleSelection: Bool private let multipleSelection: Bool
private let requirePhoneNumbers: Bool private let requirePhoneNumbers: Bool
private let openProfile: ((EnginePeer) -> Void)?
private let sendMessage: ((EnginePeer) -> Void)?
private var _ready = Promise<Bool>() private var _ready = Promise<Bool>()
override var ready: Promise<Bool> { override var ready: Promise<Bool> {
return self._ready return self._ready
@ -105,6 +109,9 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
self.multipleSelection = params.multipleSelection self.multipleSelection = params.multipleSelection
self.requirePhoneNumbers = params.requirePhoneNumbers self.requirePhoneNumbers = params.requirePhoneNumbers
self.openProfile = params.openProfile
self.sendMessage = params.sendMessage
self.presentationData = params.updatedPresentationData?.initial ?? params.context.sharedContext.currentPresentationData.with { $0 } self.presentationData = params.updatedPresentationData?.initial ?? params.context.sharedContext.currentPresentationData.with { $0 }
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData)) super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: self.presentationData))
@ -219,15 +226,15 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
} }
self.contactsNode.requestOpenPeerFromSearch = { [weak self] peer in self.contactsNode.requestOpenPeerFromSearch = { [weak self] peer in
self?.openPeer(peer: peer, action: .generic) self?.openPeer(peer: peer, action: .generic, node: nil, gesture: nil)
} }
self.contactsNode.contactListNode.activateSearch = { [weak self] in self.contactsNode.contactListNode.activateSearch = { [weak self] in
self?.activateSearch() self?.activateSearch()
} }
self.contactsNode.contactListNode.openPeer = { [weak self] peer, action, _, _ in self.contactsNode.contactListNode.openPeer = { [weak self] peer, action, node, gesture in
self?.openPeer(peer: peer, action: action) self?.openPeer(peer: peer, action: action, node: node, gesture: gesture)
} }
self.contactsNode.contactListNode.suppressPermissionWarning = { [weak self] in self.contactsNode.contactListNode.suppressPermissionWarning = { [weak self] in
@ -357,7 +364,40 @@ class ContactSelectionControllerImpl: ViewController, ContactSelectionController
} }
} }
private func openPeer(peer: ContactListPeer, action: ContactListAction) { private func openPeer(peer: ContactListPeer, action: ContactListAction, node: ASDisplayNode?, gesture: ContextGesture?) {
if case .more = action {
guard case let .peer(peer, _, _) = peer, let node = node as? ContextReferenceContentNode else {
return
}
let presentationData = self.presentationData
var items: [ContextMenuItem] = []
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Premium_Gift_ContactSelection_SendMessage, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MessageBubble"), color: theme.contextMenu.primaryColor)
}, iconPosition: .left, action: { [weak self] _, a in
a(.default)
if let self {
self.sendMessage?(EnginePeer(peer))
}
})))
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Premium_Gift_ContactSelection_OpenProfile, icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.contextMenu.primaryColor)
}, iconPosition: .left, action: { [weak self] _, a in
a(.default)
if let self {
self.openProfile?(EnginePeer(peer))
}
})))
let contextController = ContextController(presentationData: presentationData, source: .reference(ContactContextReferenceContentSource(controller: self, sourceNode: node)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
self.present(contextController, in: .window(.root))
return
}
self.contactsNode.contactListNode.listNode.clearHighlightAnimated(true) self.contactsNode.contactListNode.listNode.clearHighlightAnimated(true)
self.confirmationDisposable.set((self.confirmation(peer) |> deliverOnMainQueue).startStrict(next: { [weak self] value in self.confirmationDisposable.set((self.confirmation(peer) |> deliverOnMainQueue).startStrict(next: { [weak self] value in
if let strongSelf = self { if let strongSelf = self {
@ -477,3 +517,17 @@ final class ContactsPickerContext: AttachmentMediaPickerContext {
func mainButtonAction() { func mainButtonAction() {
} }
} }
private final class ContactContextReferenceContentSource: ContextReferenceContentSource {
private let controller: ViewController
private let sourceNode: ContextReferenceContentNode
init(controller: ViewController, sourceNode: ContextReferenceContentNode) {
self.controller = controller
self.sourceNode = sourceNode
}
func transitionInfo() -> ContextControllerReferenceViewInfo? {
return ContextControllerReferenceViewInfo(referenceView: self.sourceNode.view, contentAreaInScreenSpace: UIScreen.main.bounds)
}
}

View File

@ -41,6 +41,7 @@ final class ContactSelectionControllerNode: ASDisplayNode {
var requestMultipleAction: ((_ silent: Bool, _ scheduleTime: Int32?, _ parameters: ChatSendMessageActionSheetController.SendParameters?) -> Void)? var requestMultipleAction: ((_ silent: Bool, _ scheduleTime: Int32?, _ parameters: ChatSendMessageActionSheetController.SendParameters?) -> Void)?
var dismiss: (() -> Void)? var dismiss: (() -> Void)?
var cancelSearch: (() -> Void)? var cancelSearch: (() -> Void)?
var openPeerMore: ((ContactListPeer, ASDisplayNode?, ContextGesture?) -> Void)?
var presentationData: PresentationData { var presentationData: PresentationData {
didSet { didSet {

View File

@ -2277,17 +2277,17 @@ public final class SharedAccountContextImpl: SharedAccountContext {
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
var presentBirthdayPickerImpl: (() -> Void)? var presentBirthdayPickerImpl: (() -> Void)?
var starsMode: ContactSelectionControllerMode = .generic var mode: ContactSelectionControllerMode = .generic
var currentBirthdays: [EnginePeer.Id: TelegramBirthday]? var currentBirthdays: [EnginePeer.Id: TelegramBirthday]?
if case let .chatList(birthdays) = source, let birthdays, !birthdays.isEmpty { if case let .chatList(birthdays) = source, let birthdays, !birthdays.isEmpty {
starsMode = .starsGifting(birthdays: birthdays, hasActions: true) mode = .starsGifting(birthdays: birthdays, hasActions: true)
currentBirthdays = birthdays currentBirthdays = birthdays
} else if case let .settings(birthdays) = source, let birthdays, !birthdays.isEmpty { } else if case let .settings(birthdays) = source, let birthdays, !birthdays.isEmpty {
starsMode = .starsGifting(birthdays: birthdays, hasActions: true) mode = .starsGifting(birthdays: birthdays, hasActions: true)
currentBirthdays = birthdays currentBirthdays = birthdays
} else { } else {
starsMode = .starsGifting(birthdays: nil, hasActions: true) mode = .starsGifting(birthdays: nil, hasActions: true)
} }
let contactOptions: Signal<[ContactListAdditionalOption], NoError> let contactOptions: Signal<[ContactListAdditionalOption], NoError>
@ -2320,7 +2320,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil)) options.set(context.engine.payments.premiumGiftCodeOptions(peerId: nil))
let controller = context.sharedContext.makeContactSelectionController(ContactSelectionControllerParams( let controller = context.sharedContext.makeContactSelectionController(ContactSelectionControllerParams(
context: context, context: context,
mode: starsMode, mode: mode,
autoDismiss: false, autoDismiss: false,
title: { strings in return "Gift Premium or Stars" }, title: { strings in return "Gift Premium or Stars" },
options: contactOptions, options: contactOptions,
@ -2331,7 +2331,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
sendMessageImpl?(peer) sendMessageImpl?(peer)
} }
)) ))
let _ = combineLatest(queue: Queue.mainQueue(), contactsController.result, options.get()) let _ = combineLatest(queue: Queue.mainQueue(), controller.result, options.get())
.startStandalone(next: { [weak controller] result, options in .startStandalone(next: { [weak controller] result, options in
if let (peers, _, _, _, _, _) = result, let contactPeer = peers.first, case let .peer(peer, _, _) = contactPeer, let starsContext = context.starsContext { if let (peers, _, _, _, _, _) = result, let contactPeer = peers.first, case let .peer(peer, _, _) = contactPeer, let starsContext = context.starsContext {
let premiumOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) } let premiumOptions = options.filter { $0.users == 1 }.map { CachedPremiumGiftOption(months: $0.months, currency: $0.currency, amount: $0.amount, botUrl: "", storeProductId: $0.storeProductId) }
@ -2339,8 +2339,6 @@ public final class SharedAccountContextImpl: SharedAccountContext {
giftController.navigationPresentation = .modal giftController.navigationPresentation = .modal
controller?.push(giftController) controller?.push(giftController)
// completion?([peer.id])
if case .chatList = source, let _ = currentBirthdays { if case .chatList = source, let _ = currentBirthdays {
let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone() let _ = context.engine.notices.dismissServerProvidedSuggestion(suggestion: .todayBirthdays).startStandalone()
} }