mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
fed338985d
commit
2effcb42b7
@ -14032,3 +14032,5 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Privacy.Gifts.PremiumToast.Text" = "Subscribe to **Telegram Premium** to use this setting.";
|
"Privacy.Gifts.PremiumToast.Text" = "Subscribe to **Telegram Premium** to use this setting.";
|
||||||
"Privacy.Gifts.PremiumToast.Action" = "Open";
|
"Privacy.Gifts.PremiumToast.Action" = "Open";
|
||||||
|
|
||||||
|
"Gift.Send.ErrorDisallowed" = "**%@** doesn't accept this kind of gifts.";
|
||||||
|
@ -1059,7 +1059,7 @@ public protocol SharedAccountContext: AnyObject {
|
|||||||
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
func makePremiumLimitController(context: AccountContext, subject: PremiumLimitSubject, count: Int32, forceDark: Bool, cancel: @escaping () -> Void, action: @escaping () -> Bool) -> ViewController
|
||||||
|
|
||||||
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
func makeStarsGiftController(context: AccountContext, birthdays: [EnginePeer.Id: TelegramBirthday]?, completion: @escaping (([EnginePeer.Id]) -> Void)) -> ViewController
|
||||||
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController
|
func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Signal<Never, TransferStarGiftError>)?) -> ViewController
|
||||||
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], hasBirthday: Bool, completion: (() -> Void)?) -> ViewController
|
func makeGiftOptionsController(context: AccountContext, peerId: EnginePeer.Id, premiumOptions: [CachedPremiumGiftOption], hasBirthday: Bool, completion: (() -> Void)?) -> ViewController
|
||||||
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
func makePremiumPrivacyControllerController(context: AccountContext, subject: PremiumPrivacySubject, peerId: EnginePeer.Id) -> ViewController
|
||||||
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
func makePremiumBoostLevelsController(context: AccountContext, peerId: EnginePeer.Id, subject: BoostSubject, boostStatus: ChannelBoostStatus, myBoostStatus: MyBoostStatus, forceDark: Bool, openStats: (() -> Void)?) -> ViewController
|
||||||
|
@ -177,6 +177,7 @@ public enum BotPaymentFormRequestError {
|
|||||||
case generic
|
case generic
|
||||||
case alreadyActive
|
case alreadyActive
|
||||||
case noPaymentNeeded
|
case noPaymentNeeded
|
||||||
|
case disallowedStarGift
|
||||||
}
|
}
|
||||||
|
|
||||||
extension BotPaymentInvoice {
|
extension BotPaymentInvoice {
|
||||||
@ -473,6 +474,8 @@ func _internal_fetchBotPaymentForm(accountPeerId: PeerId, postbox: Postbox, netw
|
|||||||
|> `catch` { error -> Signal<Api.payments.PaymentForm, BotPaymentFormRequestError> in
|
|> `catch` { error -> Signal<Api.payments.PaymentForm, BotPaymentFormRequestError> in
|
||||||
if error.errorDescription == "NO_PAYMENT_NEEDED" {
|
if error.errorDescription == "NO_PAYMENT_NEEDED" {
|
||||||
return .fail(.noPaymentNeeded)
|
return .fail(.noPaymentNeeded)
|
||||||
|
} else if error.errorDescription == "USER_DISALLOWED_STARGIFTS" {
|
||||||
|
return .fail(.disallowedStarGift)
|
||||||
}
|
}
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -635,6 +638,7 @@ public enum SendBotPaymentFormError {
|
|||||||
case paymentFailed
|
case paymentFailed
|
||||||
case alreadyPaid
|
case alreadyPaid
|
||||||
case starGiftOutOfStock
|
case starGiftOutOfStock
|
||||||
|
case disallowedStarGift
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SendBotPaymentResult {
|
public enum SendBotPaymentResult {
|
||||||
|
@ -766,7 +766,7 @@ func _internal_updateStarGiftsPinnedToTop(account: Account, peerId: EnginePeer.I
|
|||||||
|
|
||||||
public enum TransferStarGiftError {
|
public enum TransferStarGiftError {
|
||||||
case generic
|
case generic
|
||||||
case disallowed
|
case disallowedStarGift
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_transferStarGift(account: Account, prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> {
|
func _internal_transferStarGift(account: Account, prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> {
|
||||||
@ -783,7 +783,10 @@ func _internal_transferStarGift(account: Account, prepaid: Bool, reference: Star
|
|||||||
}
|
}
|
||||||
if prepaid {
|
if prepaid {
|
||||||
return account.network.request(Api.functions.payments.transferStarGift(stargift: starGift, toId: inputPeer))
|
return account.network.request(Api.functions.payments.transferStarGift(stargift: starGift, toId: inputPeer))
|
||||||
|> mapError { _ -> TransferStarGiftError in
|
|> mapError { error -> TransferStarGiftError in
|
||||||
|
if error.errorDescription == "USER_DISALLOWED_STARGIFTS" {
|
||||||
|
return .disallowedStarGift
|
||||||
|
}
|
||||||
return .generic
|
return .generic
|
||||||
}
|
}
|
||||||
|> mapToSignal { updates -> Signal<Void, TransferStarGiftError> in
|
|> mapToSignal { updates -> Signal<Void, TransferStarGiftError> in
|
||||||
@ -798,6 +801,8 @@ func _internal_transferStarGift(account: Account, prepaid: Bool, reference: Star
|
|||||||
|> `catch` { error -> Signal<BotPaymentForm?, TransferStarGiftError> in
|
|> `catch` { error -> Signal<BotPaymentForm?, TransferStarGiftError> in
|
||||||
if case .noPaymentNeeded = error {
|
if case .noPaymentNeeded = error {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
|
} else if case .disallowedStarGift = error {
|
||||||
|
return .fail(.disallowedStarGift)
|
||||||
}
|
}
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
@ -1335,16 +1340,15 @@ private final class ProfileGiftsContextImpl {
|
|||||||
self.pushState()
|
self.pushState()
|
||||||
}
|
}
|
||||||
|
|
||||||
func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) {
|
func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> {
|
||||||
self.actionDisposable.set(
|
|
||||||
_internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId).startStrict()
|
|
||||||
)
|
|
||||||
if let count = self.count {
|
if let count = self.count {
|
||||||
self.count = max(0, count - 1)
|
self.count = max(0, count - 1)
|
||||||
}
|
}
|
||||||
self.gifts.removeAll(where: { $0.reference == reference })
|
self.gifts.removeAll(where: { $0.reference == reference })
|
||||||
self.filteredGifts.removeAll(where: { $0.reference == reference })
|
self.filteredGifts.removeAll(where: { $0.reference == reference })
|
||||||
self.pushState()
|
self.pushState()
|
||||||
|
|
||||||
|
return _internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> {
|
func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> {
|
||||||
@ -1703,9 +1707,17 @@ public final class ProfileGiftsContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) {
|
public func transferStarGift(prepaid: Bool, reference: StarGiftReference, peerId: EnginePeer.Id) -> Signal<Never, TransferStarGiftError> {
|
||||||
self.impl.with { impl in
|
return Signal { subscriber in
|
||||||
impl.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId)
|
let disposable = MetaDisposable()
|
||||||
|
self.impl.with { impl in
|
||||||
|
disposable.set(impl.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId).start(error: { error in
|
||||||
|
subscriber.putError(error)
|
||||||
|
}, completed: {
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
return disposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +513,9 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let context = component.context
|
let context = component.context
|
||||||
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
|
var dismissAlertImpl: (() -> Void)?
|
||||||
let alertController = giftTransferAlertController(
|
let alertController = giftTransferAlertController(
|
||||||
context: context,
|
context: context,
|
||||||
gift: transferGift,
|
gift: transferGift,
|
||||||
@ -521,65 +524,102 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
navigationController: mainController.navigationController as? NavigationController,
|
navigationController: mainController.navigationController as? NavigationController,
|
||||||
commit: { [weak self, weak mainController] in
|
commit: { [weak self, weak mainController] in
|
||||||
let proceed: (Bool) -> Void = { waitForTopUp in
|
let proceed: (Bool) -> Void = { waitForTopUp in
|
||||||
|
var errorImpl: ((TransferStarGiftError) -> Void)?
|
||||||
|
var completedImpl: (() -> Void)?
|
||||||
|
|
||||||
if waitForTopUp, let starsContext = context.starsContext {
|
if waitForTopUp, let starsContext = context.starsContext {
|
||||||
let _ = (starsContext.onUpdate
|
let _ = (starsContext.onUpdate
|
||||||
|> deliverOnMainQueue).start(next: {
|
|> deliverOnMainQueue).start(next: {
|
||||||
let _ = (context.engine.payments.transferStarGift(prepaid: gift.transferStars == 0, reference: reference, peerId: peer.id)
|
let _ = (context.engine.payments.transferStarGift(prepaid: gift.transferStars == 0, reference: reference, peerId: peer.id)
|
||||||
|> deliverOnMainQueue).start()
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
|
errorImpl?(error)
|
||||||
|
}, completed: {
|
||||||
|
completedImpl?()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let _ = (context.engine.payments.transferStarGift(prepaid: gift.transferStars == 0, reference: reference, peerId: peer.id)
|
let _ = (context.engine.payments.transferStarGift(prepaid: gift.transferStars == 0, reference: reference, peerId: peer.id)
|
||||||
|> deliverOnMainQueue).start()
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
|
errorImpl?(error)
|
||||||
|
}, completed: {
|
||||||
|
completedImpl?()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let controller = mainController, let navigationController = controller.navigationController as? NavigationController else {
|
guard let controller = mainController, let navigationController = controller.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if peer.id.namespace == Namespaces.Peer.CloudChannel {
|
errorImpl = { [weak navigationController] error in
|
||||||
var controllers = navigationController.viewControllers
|
guard let navigationController else {
|
||||||
controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) }
|
return
|
||||||
var foundController = false
|
}
|
||||||
for controller in controllers.reversed() {
|
dismissAlertImpl?()
|
||||||
if let controller = controller as? PeerInfoScreen, controller.peerId == component.peerId {
|
|
||||||
foundController = true
|
var errorText: String?
|
||||||
break
|
switch error {
|
||||||
|
case .disallowedStarGift:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorDisallowed(peer.compactDisplayTitle).string
|
||||||
|
default:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if let errorText = errorText {
|
||||||
|
let alertController = textAlertController(context: context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
|
||||||
|
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||||
|
lastController.present(alertController, in: .window(.root))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !foundController {
|
|
||||||
if let controller = context.sharedContext.makePeerInfoController(
|
|
||||||
context: context,
|
|
||||||
updatedPresentationData: nil,
|
|
||||||
peer: peer._asPeer(),
|
|
||||||
mode: .gifts,
|
|
||||||
avatarInitiallyExpanded: false,
|
|
||||||
fromChat: false,
|
|
||||||
requestsContext: nil
|
|
||||||
) {
|
|
||||||
controllers.append(controller)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
|
||||||
} else {
|
|
||||||
var controllers = navigationController.viewControllers
|
|
||||||
controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) }
|
|
||||||
var foundController = false
|
|
||||||
for controller in controllers.reversed() {
|
|
||||||
if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation {
|
|
||||||
chatController.hintPlayNextOutgoingGift()
|
|
||||||
foundController = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundController {
|
|
||||||
let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
|
||||||
chatController.hintPlayNextOutgoingGift()
|
|
||||||
controllers.append(chatController)
|
|
||||||
}
|
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
|
||||||
}
|
}
|
||||||
if let completion = component.completion {
|
|
||||||
completion()
|
completedImpl = {
|
||||||
|
dismissAlertImpl?()
|
||||||
|
|
||||||
|
if peer.id.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
var controllers = navigationController.viewControllers
|
||||||
|
controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) }
|
||||||
|
var foundController = false
|
||||||
|
for controller in controllers.reversed() {
|
||||||
|
if let controller = controller as? PeerInfoScreen, controller.peerId == component.peerId {
|
||||||
|
foundController = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundController {
|
||||||
|
if let controller = context.sharedContext.makePeerInfoController(
|
||||||
|
context: context,
|
||||||
|
updatedPresentationData: nil,
|
||||||
|
peer: peer._asPeer(),
|
||||||
|
mode: .gifts,
|
||||||
|
avatarInitiallyExpanded: false,
|
||||||
|
fromChat: false,
|
||||||
|
requestsContext: nil
|
||||||
|
) {
|
||||||
|
controllers.append(controller)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
|
} else {
|
||||||
|
var controllers = navigationController.viewControllers
|
||||||
|
controllers = controllers.filter { !($0 is GiftSetupScreen) && !($0 is GiftOptionsScreenProtocol) && !($0 is PeerInfoScreen) && !($0 is ContactSelectionController) }
|
||||||
|
var foundController = false
|
||||||
|
for controller in controllers.reversed() {
|
||||||
|
if let chatController = controller as? ChatController, case .peer(id: component.peerId) = chatController.chatLocation {
|
||||||
|
chatController.hintPlayNextOutgoingGift()
|
||||||
|
foundController = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundController {
|
||||||
|
let chatController = component.context.sharedContext.makeChatController(context: component.context, chatLocation: .peer(id: component.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
||||||
|
chatController.hintPlayNextOutgoingGift()
|
||||||
|
controllers.append(chatController)
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
|
}
|
||||||
|
if let completion = component.completion {
|
||||||
|
completion()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +650,10 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
controller.present(alertController, in: .window(.root))
|
controller.present(alertController, in: .window(.root))
|
||||||
|
|
||||||
|
dismissAlertImpl = { [weak alertController] in
|
||||||
|
alertController?.dismissAnimated()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(component: GiftOptionsScreenComponent, availableSize: CGSize, state: State, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
func update(component: GiftOptionsScreenComponent, availableSize: CGSize, state: State, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||||
|
@ -465,12 +465,14 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
switch error {
|
switch error {
|
||||||
case .starGiftOutOfStock:
|
case .starGiftOutOfStock:
|
||||||
errorText = presentationData.strings.Gift_Send_ErrorOutOfStock
|
errorText = presentationData.strings.Gift_Send_ErrorOutOfStock
|
||||||
|
case .disallowedStarGift:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorDisallowed(self.peerMap[peerId]?.compactDisplayTitle ?? "").string
|
||||||
default:
|
default:
|
||||||
errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
if let errorText = errorText {
|
if let errorText = errorText {
|
||||||
let alertController = textAlertController(context: component.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
let alertController = textAlertController(context: component.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
|
||||||
controller.present(alertController, in: .window(.root))
|
controller.present(alertController, in: .window(.root))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -50,6 +50,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/PremiumLockButtonSubtitleComponent",
|
"//submodules/TelegramUI/Components/PremiumLockButtonSubtitleComponent",
|
||||||
"//submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent",
|
"//submodules/TelegramUI/Components/Stars/StarsBalanceOverlayComponent",
|
||||||
"//submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController",
|
"//submodules/TelegramUI/Components/Chat/ChatMessagePaymentAlertController",
|
||||||
|
"//submodules/ActivityIndicator",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -13,6 +13,7 @@ import AvatarNode
|
|||||||
import Markdown
|
import Markdown
|
||||||
import GiftItemComponent
|
import GiftItemComponent
|
||||||
import ChatMessagePaymentAlertController
|
import ChatMessagePaymentAlertController
|
||||||
|
import ActivityIndicator
|
||||||
|
|
||||||
private final class GiftTransferAlertContentNode: AlertContentNode {
|
private final class GiftTransferAlertContentNode: AlertContentNode {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
@ -31,9 +32,19 @@ private final class GiftTransferAlertContentNode: AlertContentNode {
|
|||||||
private let actionNodesSeparator: ASDisplayNode
|
private let actionNodesSeparator: ASDisplayNode
|
||||||
private let actionNodes: [TextAlertContentActionNode]
|
private let actionNodes: [TextAlertContentActionNode]
|
||||||
private let actionVerticalSeparators: [ASDisplayNode]
|
private let actionVerticalSeparators: [ASDisplayNode]
|
||||||
|
|
||||||
|
private var activityIndicator: ActivityIndicator?
|
||||||
|
|
||||||
private var validLayout: CGSize?
|
private var validLayout: CGSize?
|
||||||
|
|
||||||
|
var inProgress = false {
|
||||||
|
didSet {
|
||||||
|
if let size = self.validLayout {
|
||||||
|
let _ = self.updateLayout(size: size, transition: .immediate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override var dismissOnOutsideTap: Bool {
|
override var dismissOnOutsideTap: Bool {
|
||||||
return self.isUserInteractionEnabled
|
return self.isUserInteractionEnabled
|
||||||
}
|
}
|
||||||
@ -248,6 +259,23 @@ private final class GiftTransferAlertContentNode: AlertContentNode {
|
|||||||
nodeIndex += 1
|
nodeIndex += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.inProgress {
|
||||||
|
let activityIndicator: ActivityIndicator
|
||||||
|
if let current = self.activityIndicator {
|
||||||
|
activityIndicator = current
|
||||||
|
} else {
|
||||||
|
activityIndicator = ActivityIndicator(type: .custom(self.presentationTheme.list.freeInputField.controlColor, 18.0, 1.5, false))
|
||||||
|
self.addSubnode(activityIndicator)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let actionNode = self.actionNodes.first {
|
||||||
|
actionNode.isHidden = true
|
||||||
|
|
||||||
|
let indicatorSize = CGSize(width: 22.0, height: 22.0)
|
||||||
|
transition.updateFrame(node: activityIndicator, frame: CGRect(origin: CGPoint(x: actionNode.frame.minX + floor((actionNode.frame.width - indicatorSize.width) / 2.0), y: actionNode.frame.minY + floor((actionNode.frame.height - indicatorSize.height) / 2.0)), size: indicatorSize))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return resultSize
|
return resultSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,17 +302,18 @@ public func giftTransferAlertController(
|
|||||||
buttonText = strings.Gift_Transfer_Confirmation_TransferFree
|
buttonText = strings.Gift_Transfer_Confirmation_TransferFree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var contentNode: GiftTransferAlertContentNode?
|
||||||
var dismissImpl: ((Bool) -> Void)?
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: buttonText, action: {
|
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: buttonText, action: { [weak contentNode] in
|
||||||
dismissImpl?(true)
|
contentNode?.inProgress = true
|
||||||
commit()
|
commit()
|
||||||
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
dismissImpl?(true)
|
dismissImpl?(true)
|
||||||
})]
|
})]
|
||||||
|
|
||||||
let contentNode = GiftTransferAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: strings, gift: gift, peer: peer, title: title, text: text, actions: actions)
|
contentNode = GiftTransferAlertContentNode(context: context, theme: AlertControllerTheme(presentationData: presentationData), ptheme: presentationData.theme, strings: strings, gift: gift, peer: peer, title: title, text: text, actions: actions)
|
||||||
|
|
||||||
let controller = ChatMessagePaymentAlertController(context: context, presentationData: presentationData, contentNode: contentNode, navigationController: navigationController, showBalance: transferStars > 0)
|
let controller = ChatMessagePaymentAlertController(context: context, presentationData: presentationData, contentNode: contentNode!, navigationController: navigationController, showBalance: transferStars > 0)
|
||||||
dismissImpl = { [weak controller] animated in
|
dismissImpl = { [weak controller] animated in
|
||||||
if animated {
|
if animated {
|
||||||
controller?.dismissAnimated()
|
controller?.dismissAnimated()
|
||||||
|
@ -2415,7 +2415,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
case upgradePreview([StarGift.UniqueGift.Attribute], String)
|
case upgradePreview([StarGift.UniqueGift.Attribute], String)
|
||||||
case wearPreview(StarGift.UniqueGift)
|
case wearPreview(StarGift.UniqueGift)
|
||||||
|
|
||||||
var arguments: (peerId: EnginePeer.Id?, fromPeerId: EnginePeer.Id?, fromPeerName: String?, messageId: EngineMessage.Id?, reference: StarGiftReference?, incoming: Bool, gift: StarGift, date: Int32, convertStars: Int64?, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, converted: Bool, upgraded: Bool, canUpgrade: Bool, upgradeStars: Int64?, transferStars: Int64?, canExportDate: Int32?, upgradeMessageId: Int32?)? {
|
var arguments: (peerId: EnginePeer.Id?, fromPeerId: EnginePeer.Id?, fromPeerName: String?, messageId: EngineMessage.Id?, reference: StarGiftReference?, incoming: Bool, gift: StarGift, date: Int32, convertStars: Int64?, text: String?, entities: [MessageTextEntity]?, nameHidden: Bool, savedToProfile: Bool, pinnedToTop: Bool?, converted: Bool, upgraded: Bool, canUpgrade: Bool, upgradeStars: Int64?, transferStars: Int64?, canExportDate: Int32?, upgradeMessageId: Int32?)? {
|
||||||
switch self {
|
switch self {
|
||||||
case let .message(message):
|
case let .message(message):
|
||||||
if let action = message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction {
|
if let action = message.media.first(where: { $0 is TelegramMediaAction }) as? TelegramMediaAction {
|
||||||
@ -2427,7 +2427,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
} else {
|
} else {
|
||||||
reference = .message(messageId: message.id)
|
reference = .message(messageId: message.id)
|
||||||
}
|
}
|
||||||
return (message.id.peerId, senderId ?? message.author?.id, message.author?.compactDisplayTitle, message.id, reference, message.flags.contains(.Incoming), gift, message.timestamp, convertStars, text, entities, nameHidden, savedToProfile, converted, upgraded, canUpgrade, upgradeStars, nil, nil, upgradeMessageId)
|
return (message.id.peerId, senderId ?? message.author?.id, message.author?.compactDisplayTitle, message.id, reference, message.flags.contains(.Incoming), gift, message.timestamp, convertStars, text, entities, nameHidden, savedToProfile, nil, converted, upgraded, canUpgrade, upgradeStars, nil, nil, upgradeMessageId)
|
||||||
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, _, peerId, senderId, savedId):
|
case let .starGiftUnique(gift, isUpgrade, isTransferred, savedToProfile, canExportDate, transferStars, _, peerId, senderId, savedId):
|
||||||
var reference: StarGiftReference
|
var reference: StarGiftReference
|
||||||
if let peerId, let savedId {
|
if let peerId, let savedId {
|
||||||
@ -2447,19 +2447,19 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
} else {
|
} else {
|
||||||
incoming = message.flags.contains(.Incoming)
|
incoming = message.flags.contains(.Incoming)
|
||||||
}
|
}
|
||||||
return (message.id.peerId, senderId ?? message.author?.id, message.author?.compactDisplayTitle, message.id, reference, incoming, gift, message.timestamp, nil, nil, nil, false, savedToProfile, false, false, false, nil, transferStars, canExportDate, nil)
|
return (message.id.peerId, senderId ?? message.author?.id, message.author?.compactDisplayTitle, message.id, reference, incoming, gift, message.timestamp, nil, nil, nil, false, savedToProfile, nil, false, false, false, nil, transferStars, canExportDate, nil)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .uniqueGift(gift), let .wearPreview(gift):
|
case let .uniqueGift(gift), let .wearPreview(gift):
|
||||||
return (nil, nil, nil, nil, nil, false, .unique(gift), 0, nil, nil, nil, false, false, false, false, false, nil, nil, nil, nil)
|
return (nil, nil, nil, nil, nil, false, .unique(gift), 0, nil, nil, nil, false, false, nil, false, false, false, nil, nil, nil, nil)
|
||||||
case let .profileGift(peerId, gift):
|
case let .profileGift(peerId, gift):
|
||||||
var messageId: EngineMessage.Id?
|
var messageId: EngineMessage.Id?
|
||||||
if case let .message(messageIdValue) = gift.reference {
|
if case let .message(messageIdValue) = gift.reference {
|
||||||
messageId = messageIdValue
|
messageId = messageIdValue
|
||||||
}
|
}
|
||||||
return (peerId, gift.fromPeer?.id, gift.fromPeer?.compactDisplayTitle, messageId, gift.reference, false, gift.gift, gift.date, gift.convertStars, gift.text, gift.entities, gift.nameHidden, gift.savedToProfile, false, false, gift.canUpgrade, gift.upgradeStars, gift.transferStars, gift.canExportDate, nil)
|
return (peerId, gift.fromPeer?.id, gift.fromPeer?.compactDisplayTitle, messageId, gift.reference, false, gift.gift, gift.date, gift.convertStars, gift.text, gift.entities, gift.nameHidden, gift.savedToProfile, gift.pinnedToTop, false, false, gift.canUpgrade, gift.upgradeStars, gift.transferStars, gift.canExportDate, nil)
|
||||||
case .soldOutGift:
|
case .soldOutGift:
|
||||||
return nil
|
return nil
|
||||||
case .upgradePreview:
|
case .upgradePreview:
|
||||||
@ -2488,8 +2488,9 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
forceDark: Bool = false,
|
forceDark: Bool = false,
|
||||||
updateSavedToProfile: ((StarGiftReference, Bool) -> Void)? = nil,
|
updateSavedToProfile: ((StarGiftReference, Bool) -> Void)? = nil,
|
||||||
convertToStars: (() -> Void)? = nil,
|
convertToStars: (() -> Void)? = nil,
|
||||||
transferGift: ((Bool, EnginePeer.Id) -> Void)? = nil,
|
transferGift: ((Bool, EnginePeer.Id) -> Signal<Never, TransferStarGiftError>)? = nil,
|
||||||
upgradeGift: ((Int64?, Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError>)? = nil,
|
upgradeGift: ((Int64?, Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError>)? = nil,
|
||||||
|
togglePinnedToTop: ((Bool) -> Bool)? = nil,
|
||||||
shareStory: ((StarGift.UniqueGift) -> Void)? = nil
|
shareStory: ((StarGift.UniqueGift) -> Void)? = nil
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@ -2822,19 +2823,19 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
}
|
}
|
||||||
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .starGiftTransfer(birthdays, reference, gift, transferStars, arguments.canExportDate, showSelf), completion: { peerIds in
|
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .starGiftTransfer(birthdays, reference, gift, transferStars, arguments.canExportDate, showSelf), completion: { peerIds in
|
||||||
guard let peerId = peerIds.first else {
|
guard let peerId = peerIds.first else {
|
||||||
return
|
return .complete()
|
||||||
}
|
}
|
||||||
if let transferGift {
|
Queue.mainQueue().after(1.5, {
|
||||||
transferGift(transferStars == 0, peerId)
|
|
||||||
} else {
|
|
||||||
let _ = (context.engine.payments.transferStarGift(prepaid: transferStars == 0, reference: reference, peerId: peerId)
|
|
||||||
|> deliverOnMainQueue).start()
|
|
||||||
}
|
|
||||||
Queue.mainQueue().after(1.0, {
|
|
||||||
if transferStars > 0 {
|
if transferStars > 0 {
|
||||||
context.starsContext?.load(force: true)
|
context.starsContext?.load(force: true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
if let transferGift {
|
||||||
|
return transferGift(transferStars == 0, peerId)
|
||||||
|
} else {
|
||||||
|
return (context.engine.payments.transferStarGift(prepaid: transferStars == 0, reference: reference, peerId: peerId)
|
||||||
|
|> deliverOnMainQueue)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
})
|
})
|
||||||
@ -2979,6 +2980,37 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
|
let strings = presentationData.strings
|
||||||
|
|
||||||
|
if let _ = arguments.reference, case .unique = arguments.gift, let togglePinnedToTop, let pinnedToTop = arguments.pinnedToTop {
|
||||||
|
items.append(.action(ContextMenuActionItem(text: pinnedToTop ? strings.PeerInfo_Gifts_Context_Unpin : strings.PeerInfo_Gifts_Context_Pin , icon: { theme in generateTintedImage(image: UIImage(bundleImageName: pinnedToTop ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||||
|
c?.dismiss(completion: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let pinnedToTop = !pinnedToTop
|
||||||
|
if togglePinnedToTop(pinnedToTop) {
|
||||||
|
if pinnedToTop {
|
||||||
|
self.dismissAnimated()
|
||||||
|
} else {
|
||||||
|
let toastText = strings.PeerInfo_Gifts_ToastUnpinned_Text
|
||||||
|
self.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_toastunpin", scale: 0.06, colors: [:], title: nil, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
|
if case let .profileGift(peerId, gift) = self.subject {
|
||||||
|
self.subject = .profileGift(peerId, gift.withPinnedToTop(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var maxPinnedCount: Int = 6
|
||||||
|
if let value = context.currentAppConfiguration.with({ $0 }).data?["stargifts_pinned_to_top_limit"] as? Double {
|
||||||
|
maxPinnedCount = Int(value)
|
||||||
|
}
|
||||||
|
self.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_CopyLink, icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Gift_View_Context_CopyLink, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
||||||
}, action: { [weak self] c, _ in
|
}, action: { [weak self] c, _ in
|
||||||
|
@ -4855,9 +4855,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
},
|
},
|
||||||
transferGift: { [weak profileGifts] prepaid, peerId in
|
transferGift: { [weak profileGifts] prepaid, peerId in
|
||||||
guard let profileGifts, let reference = gift.reference else {
|
guard let profileGifts, let reference = gift.reference else {
|
||||||
return
|
return .complete()
|
||||||
}
|
}
|
||||||
profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId)
|
return profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId)
|
||||||
},
|
},
|
||||||
upgradeGift: { [weak profileGifts] formId, keepOriginalInfo in
|
upgradeGift: { [weak profileGifts] formId, keepOriginalInfo in
|
||||||
guard let profileGifts, let reference = gift.reference else {
|
guard let profileGifts, let reference = gift.reference else {
|
||||||
|
@ -518,9 +518,9 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
},
|
},
|
||||||
transferGift: { [weak self] prepaid, peerId in
|
transferGift: { [weak self] prepaid, peerId in
|
||||||
guard let self, let reference = product.reference else {
|
guard let self, let reference = product.reference else {
|
||||||
return
|
return .complete()
|
||||||
}
|
}
|
||||||
self.profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId)
|
return self.profileGifts.transferStarGift(prepaid: prepaid, reference: reference, peerId: peerId)
|
||||||
},
|
},
|
||||||
upgradeGift: { [weak self] formId, keepOriginalInfo in
|
upgradeGift: { [weak self] formId, keepOriginalInfo in
|
||||||
guard let self, let reference = product.reference else {
|
guard let self, let reference = product.reference else {
|
||||||
@ -528,6 +528,27 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
}
|
}
|
||||||
return self.profileGifts.upgradeStarGift(formId: formId, reference: reference, keepOriginalInfo: keepOriginalInfo)
|
return self.profileGifts.upgradeStarGift(formId: formId, reference: reference, keepOriginalInfo: keepOriginalInfo)
|
||||||
},
|
},
|
||||||
|
togglePinnedToTop: { [weak self] pinnedToTop in
|
||||||
|
guard let self else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if pinnedToTop && self.pinnedReferences.count >= self.maxPinnedCount {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if let reference = product.reference {
|
||||||
|
self.profileGifts.updateStarGiftPinnedToTop(reference: reference, pinnedToTop: pinnedToTop)
|
||||||
|
|
||||||
|
if pinnedToTop {
|
||||||
|
let _ = self.scrollToTop()
|
||||||
|
Queue.mainQueue().after(0.35) {
|
||||||
|
let toastTitle = params.presentationData.strings.PeerInfo_Gifts_ToastPinned_Title
|
||||||
|
let toastText = params.presentationData.strings.PeerInfo_Gifts_ToastPinned_Text
|
||||||
|
self.parentController?.present(UndoOverlayController(presentationData: params.presentationData, content: .universal(animation: "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
},
|
||||||
shareStory: { [weak self] uniqueGift in
|
shareStory: { [weak self] uniqueGift in
|
||||||
guard let self, let parentController = self.parentController else {
|
guard let self, let parentController = self.parentController else {
|
||||||
return
|
return
|
||||||
@ -977,7 +998,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
let pinnedToTop = !gift.pinnedToTop
|
let pinnedToTop = !gift.pinnedToTop
|
||||||
|
|
||||||
if pinnedToTop && self.pinnedReferences.count >= self.maxPinnedCount {
|
if pinnedToTop && self.pinnedReferences.count >= self.maxPinnedCount {
|
||||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(self.maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(self.maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,10 +1010,10 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
let toastText: String
|
let toastText: String
|
||||||
if !pinnedToTop {
|
if !pinnedToTop {
|
||||||
toastTitle = nil
|
toastTitle = nil
|
||||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastUnpinned_Text
|
toastText = strings.PeerInfo_Gifts_ToastUnpinned_Text
|
||||||
} else {
|
} else {
|
||||||
toastTitle = presentationData.strings.PeerInfo_Gifts_ToastPinned_Title
|
toastTitle = strings.PeerInfo_Gifts_ToastPinned_Title
|
||||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastPinned_Text
|
toastText = strings.PeerInfo_Gifts_ToastPinned_Text
|
||||||
}
|
}
|
||||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: !pinnedToTop ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: !pinnedToTop ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||||
})
|
})
|
||||||
@ -1200,14 +1221,14 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||||||
let transferStars = gift.transferStars ?? 0
|
let transferStars = gift.transferStars ?? 0
|
||||||
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .starGiftTransfer(birthdays, reference, uniqueGift, transferStars, gift.canExportDate, showSelf), completion: { [weak self] peerIds in
|
let controller = context.sharedContext.makePremiumGiftController(context: context, source: .starGiftTransfer(birthdays, reference, uniqueGift, transferStars, gift.canExportDate, showSelf), completion: { [weak self] peerIds in
|
||||||
guard let self, let peerId = peerIds.first else {
|
guard let self, let peerId = peerIds.first else {
|
||||||
return
|
return .complete()
|
||||||
}
|
}
|
||||||
self.profileGifts.transferStarGift(prepaid: transferStars == 0, reference: reference, peerId: peerId)
|
Queue.mainQueue().after(1.5, {
|
||||||
Queue.mainQueue().after(1.0, {
|
|
||||||
if transferStars > 0 {
|
if transferStars > 0 {
|
||||||
context.starsContext?.load(force: true)
|
context.starsContext?.load(force: true)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
return self.profileGifts.transferStarGift(prepaid: transferStars == 0, reference: reference, peerId: peerId)
|
||||||
})
|
})
|
||||||
self.parentController?.push(controller)
|
self.parentController?.push(controller)
|
||||||
})
|
})
|
||||||
|
@ -2674,7 +2674,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Void)?) -> ViewController {
|
public func makePremiumGiftController(context: AccountContext, source: PremiumGiftSource, completion: (([EnginePeer.Id]) -> Signal<Never, TransferStarGiftError>)?) -> ViewController {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
var presentExportAlertImpl: (() -> Void)?
|
var presentExportAlertImpl: (() -> Void)?
|
||||||
@ -2912,6 +2912,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
guard let controller, case let .starGiftTransfer(_, _, gift, transferStars, _, _) = source else {
|
guard let controller, case let .starGiftTransfer(_, _, gift, transferStars, _, _) = source else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var dismissAlertImpl: (() -> Void)?
|
||||||
let alertController = giftTransferAlertController(
|
let alertController = giftTransferAlertController(
|
||||||
context: context,
|
context: context,
|
||||||
gift: gift,
|
gift: gift,
|
||||||
@ -2920,61 +2921,89 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
navigationController: controller.navigationController as? NavigationController,
|
navigationController: controller.navigationController as? NavigationController,
|
||||||
commit: { [weak controller] in
|
commit: { [weak controller] in
|
||||||
let proceed: (Bool) -> Void = { waitForTopUp in
|
let proceed: (Bool) -> Void = { waitForTopUp in
|
||||||
completion?([peer.id])
|
|
||||||
|
|
||||||
guard let controller, let navigationController = controller.navigationController as? NavigationController else {
|
guard let controller, let navigationController = controller.navigationController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var controllers = navigationController.viewControllers
|
|
||||||
controllers = controllers.filter { !($0 is ContactSelectionController) }
|
|
||||||
|
|
||||||
if !isChannelGift {
|
if let completion {
|
||||||
if peer.id.namespace == Namespaces.Peer.CloudChannel {
|
let _ = (completion([peer.id])
|
||||||
if let controller = context.sharedContext.makePeerInfoController(
|
|> deliverOnMainQueue).startStandalone(error: { [weak navigationController] error in
|
||||||
context: context,
|
guard let navigationController else {
|
||||||
updatedPresentationData: nil,
|
return
|
||||||
peer: peer._asPeer(),
|
|
||||||
mode: .gifts,
|
|
||||||
avatarInitiallyExpanded: false,
|
|
||||||
fromChat: false,
|
|
||||||
requestsContext: nil
|
|
||||||
) {
|
|
||||||
controllers.append(controller)
|
|
||||||
}
|
}
|
||||||
} else {
|
dismissAlertImpl?()
|
||||||
var foundController = false
|
|
||||||
for controller in controllers.reversed() {
|
var errorText: String?
|
||||||
if let chatController = controller as? ChatController, case .peer(id: peer.id) = chatController.chatLocation {
|
switch error {
|
||||||
chatController.hintPlayNextOutgoingGift()
|
case .disallowedStarGift:
|
||||||
foundController = true
|
errorText = presentationData.strings.Gift_Send_ErrorDisallowed(peer.compactDisplayTitle).string
|
||||||
break
|
default:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if let errorText = errorText {
|
||||||
|
let alertController = textAlertController(context: context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
|
||||||
|
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||||
|
lastController.present(alertController, in: .window(.root))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !foundController {
|
}, completed: { [weak navigationController] in
|
||||||
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
guard let navigationController else {
|
||||||
chatController.hintPlayNextOutgoingGift()
|
return
|
||||||
controllers.append(chatController)
|
|
||||||
}
|
}
|
||||||
}
|
dismissAlertImpl?()
|
||||||
}
|
|
||||||
navigationController.setViewControllers(controllers, animated: true)
|
|
||||||
|
|
||||||
Queue.mainQueue().after(0.3) {
|
|
||||||
let tooltipController = UndoOverlayController(
|
|
||||||
presentationData: presentationData,
|
|
||||||
content: .forward(savedMessages: false, text: presentationData.strings.Gift_Transfer_Success("\(gift.title) #\(presentationStringsFormattedNumber(gift.number, presentationData.dateTimeFormat.groupingSeparator))", peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string),
|
|
||||||
elevatedLayout: false,
|
|
||||||
action: { _ in return true }
|
|
||||||
)
|
|
||||||
if let lastController = controllers.last as? ViewController {
|
|
||||||
lastController.present(tooltipController, in: .window(.root))
|
|
||||||
}
|
|
||||||
|
|
||||||
Queue.mainQueue().after(0.5) {
|
|
||||||
var controllers = navigationController.viewControllers
|
var controllers = navigationController.viewControllers
|
||||||
controllers = controllers.filter { !($0 is GiftViewScreen) }
|
controllers = controllers.filter { !($0 is ContactSelectionController) }
|
||||||
navigationController.setViewControllers(controllers, animated: false)
|
if !isChannelGift {
|
||||||
}
|
if peer.id.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
if let controller = context.sharedContext.makePeerInfoController(
|
||||||
|
context: context,
|
||||||
|
updatedPresentationData: nil,
|
||||||
|
peer: peer._asPeer(),
|
||||||
|
mode: .gifts,
|
||||||
|
avatarInitiallyExpanded: false,
|
||||||
|
fromChat: false,
|
||||||
|
requestsContext: nil
|
||||||
|
) {
|
||||||
|
controllers.append(controller)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var foundController = false
|
||||||
|
for controller in controllers.reversed() {
|
||||||
|
if let chatController = controller as? ChatController, case .peer(id: peer.id) = chatController.chatLocation {
|
||||||
|
chatController.hintPlayNextOutgoingGift()
|
||||||
|
foundController = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundController {
|
||||||
|
let chatController = context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(.default), params: nil)
|
||||||
|
chatController.hintPlayNextOutgoingGift()
|
||||||
|
controllers.append(chatController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
navigationController.setViewControllers(controllers, animated: true)
|
||||||
|
|
||||||
|
Queue.mainQueue().after(0.3) {
|
||||||
|
let tooltipController = UndoOverlayController(
|
||||||
|
presentationData: presentationData,
|
||||||
|
content: .forward(savedMessages: false, text: presentationData.strings.Gift_Transfer_Success("\(gift.title) #\(presentationStringsFormattedNumber(gift.number, presentationData.dateTimeFormat.groupingSeparator))", peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string),
|
||||||
|
elevatedLayout: false,
|
||||||
|
action: { _ in return true }
|
||||||
|
)
|
||||||
|
if let lastController = navigationController.viewControllers.last as? ViewController {
|
||||||
|
lastController.present(tooltipController, in: .window(.root))
|
||||||
|
}
|
||||||
|
|
||||||
|
Queue.mainQueue().after(0.5) {
|
||||||
|
var controllers = navigationController.viewControllers
|
||||||
|
controllers = controllers.filter { !($0 is GiftViewScreen) }
|
||||||
|
navigationController.setViewControllers(controllers, animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3005,6 +3034,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
controller.present(alertController, in: .window(.root))
|
controller.present(alertController, in: .window(.root))
|
||||||
|
|
||||||
|
dismissAlertImpl = { [weak alertController] in
|
||||||
|
alertController?.dismissAnimated()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return controller
|
return controller
|
||||||
|
Loading…
x
Reference in New Issue
Block a user