mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Various fixes
(cherry picked from commit 0b448bf68fd7ae92526bb6ca8ac6b0e2d20a366b)
This commit is contained in:
parent
25a3ae793b
commit
e39a3dbdd6
@ -14320,3 +14320,16 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Story.Editor.TooltipSelection_1" = "Tap here to view your %@ story";
|
"Story.Editor.TooltipSelection_1" = "Tap here to view your %@ story";
|
||||||
"Story.Editor.TooltipSelection_any" = "Tap here to view your %@ stories";
|
"Story.Editor.TooltipSelection_any" = "Tap here to view your %@ stories";
|
||||||
|
|
||||||
|
"Gift.Buy.ErrorUnknown" = "An error occurred. Please try again.";
|
||||||
|
"Gift.Buy.ErrorPriceChanged.Title" = "Warning";
|
||||||
|
"Gift.Buy.ErrorPriceChanged.Text" = "The price has increased from **%1$@** to **%2$@**. Buy the gift anyway?";
|
||||||
|
"Gift.Buy.ErrorPriceChanged.Text.Stars_1" = "%@ Star";
|
||||||
|
"Gift.Buy.ErrorPriceChanged.Text.Stars_any" = "%@ Stars";
|
||||||
|
|
||||||
|
"ChatbotSetup.Gift.Warning.Title" = "Warning";
|
||||||
|
"ChatbotSetup.Gift.Warning.CombinedText" = "The bot **%@** will be able to **manage your gifts and stars**, including giving them away to other users.";
|
||||||
|
"ChatbotSetup.Gift.Warning.GiftsText" = "The bot **%@** will be able to **manage your gifts**, including giving them away to other users.";
|
||||||
|
"ChatbotSetup.Gift.Warning.StarsText" = "The bot **%@** will be able to **transfer your stars**.";
|
||||||
|
"ChatbotSetup.Gift.Warning.UsernameText" = "The bot **%@** will be able to **edit your username**, which will make your current username available for others to claim.";
|
||||||
|
"ChatbotSetup.Gift.Warning.Proceed" = "Proceed";
|
||||||
|
@ -1841,7 +1841,7 @@ public final class ContactListNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var isEmpty = false
|
var isEmpty = false
|
||||||
if (authorizationStatus == .notDetermined || authorizationStatus == .denied) && peers.isEmpty {
|
if (authorizationStatus == .notDetermined || authorizationStatus == .denied) && peers.isEmpty && topPeers.isEmpty {
|
||||||
isEmpty = true
|
isEmpty = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,6 +854,7 @@ public enum TransferStarGiftError {
|
|||||||
|
|
||||||
public enum BuyStarGiftError {
|
public enum BuyStarGiftError {
|
||||||
case generic
|
case generic
|
||||||
|
case priceChanged(Int64)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum UpdateStarGiftPriceError {
|
public enum UpdateStarGiftPriceError {
|
||||||
@ -865,7 +866,7 @@ public enum UpgradeStarGiftError {
|
|||||||
case generic
|
case generic
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_buyStarGift(account: Account, slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
func _internal_buyStarGift(account: Account, slug: String, peerId: EnginePeer.Id, price: Int64?) -> Signal<Never, BuyStarGiftError> {
|
||||||
let source: BotPaymentInvoiceSource = .starGiftResale(slug: slug, toPeerId: peerId)
|
let source: BotPaymentInvoiceSource = .starGiftResale(slug: slug, toPeerId: peerId)
|
||||||
return _internal_fetchBotPaymentForm(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, source: source, themeParams: nil)
|
return _internal_fetchBotPaymentForm(accountPeerId: account.peerId, postbox: account.postbox, network: account.network, source: source, themeParams: nil)
|
||||||
|> map(Optional.init)
|
|> map(Optional.init)
|
||||||
@ -874,6 +875,9 @@ func _internal_buyStarGift(account: Account, slug: String, peerId: EnginePeer.Id
|
|||||||
}
|
}
|
||||||
|> mapToSignal { paymentForm in
|
|> mapToSignal { paymentForm in
|
||||||
if let paymentForm {
|
if let paymentForm {
|
||||||
|
if let paymentPrice = paymentForm.invoice.prices.first?.amount, let price, paymentPrice > price {
|
||||||
|
return .fail(.priceChanged(paymentPrice))
|
||||||
|
}
|
||||||
return _internal_sendStarsPaymentForm(account: account, formId: paymentForm.id, source: source)
|
return _internal_sendStarsPaymentForm(account: account, formId: paymentForm.id, source: source)
|
||||||
|> mapError { _ -> BuyStarGiftError in
|
|> mapError { _ -> BuyStarGiftError in
|
||||||
return .generic
|
return .generic
|
||||||
@ -1473,26 +1477,53 @@ private final class ProfileGiftsContextImpl {
|
|||||||
return _internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId)
|
return _internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buyStarGift(slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
func buyStarGift(slug: String, peerId: EnginePeer.Id, price: Int64?) -> Signal<Never, BuyStarGiftError> {
|
||||||
if let count = self.count {
|
var listingPrice: Int64?
|
||||||
self.count = max(0, count - 1)
|
if let gift = self.gifts.first(where: { gift in
|
||||||
|
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}), case let .unique(uniqueGift) = gift.gift {
|
||||||
|
listingPrice = uniqueGift.resellStars
|
||||||
}
|
}
|
||||||
self.gifts.removeAll(where: { gift in
|
|
||||||
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
self.filteredGifts.removeAll(where: { gift in
|
|
||||||
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
self.pushState()
|
|
||||||
|
|
||||||
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId)
|
if listingPrice == nil {
|
||||||
|
if let gift = self.filteredGifts.first(where: { gift in
|
||||||
|
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}), case let .unique(uniqueGift) = gift.gift {
|
||||||
|
listingPrice = uniqueGift.resellStars
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId, price: price ?? listingPrice)
|
||||||
|
|> afterCompleted { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.queue.async {
|
||||||
|
if let count = self.count {
|
||||||
|
self.count = max(0, count - 1)
|
||||||
|
}
|
||||||
|
self.gifts.removeAll(where: { gift in
|
||||||
|
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
self.filteredGifts.removeAll(where: { gift in
|
||||||
|
if case let .unique(uniqueGift) = gift.gift, uniqueGift.slug == slug {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
|
||||||
|
self.pushState()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeStarGift(gift: TelegramCore.StarGift) {
|
func removeStarGift(gift: TelegramCore.StarGift) {
|
||||||
@ -1975,11 +2006,11 @@ public final class ProfileGiftsContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func buyStarGift(slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
public func buyStarGift(slug: String, peerId: EnginePeer.Id, price: Int64? = nil) -> Signal<Never, BuyStarGiftError> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
self.impl.with { impl in
|
self.impl.with { impl in
|
||||||
disposable.set(impl.buyStarGift(slug: slug, peerId: peerId).start(error: { error in
|
disposable.set(impl.buyStarGift(slug: slug, peerId: peerId, price: price).start(error: { error in
|
||||||
subscriber.putError(error)
|
subscriber.putError(error)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
@ -2606,8 +2637,18 @@ private final class ResaleGiftsContextImpl {
|
|||||||
self.loadMore()
|
self.loadMore()
|
||||||
}
|
}
|
||||||
|
|
||||||
func buyStarGift(slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
func buyStarGift(slug: String, peerId: EnginePeer.Id, price: Int64?) -> Signal<Never, BuyStarGiftError> {
|
||||||
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId)
|
var listingPrice: Int64?
|
||||||
|
if let gift = self.gifts.first(where: { gift in
|
||||||
|
if case let .unique(uniqueGift) = gift, uniqueGift.slug == slug {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}), case let .unique(uniqueGift) = gift {
|
||||||
|
listingPrice = uniqueGift.resellStars
|
||||||
|
}
|
||||||
|
|
||||||
|
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId, price: price ?? listingPrice)
|
||||||
|> afterCompleted { [weak self] in
|
|> afterCompleted { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
@ -2754,11 +2795,11 @@ public final class ResaleGiftsContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func buyStarGift(slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
public func buyStarGift(slug: String, peerId: EnginePeer.Id, price: Int64? = nil) -> Signal<Never, BuyStarGiftError> {
|
||||||
return Signal { subscriber in
|
return Signal { subscriber in
|
||||||
let disposable = MetaDisposable()
|
let disposable = MetaDisposable()
|
||||||
self.impl.with { impl in
|
self.impl.with { impl in
|
||||||
disposable.set(impl.buyStarGift(slug: slug, peerId: peerId).start(error: { error in
|
disposable.set(impl.buyStarGift(slug: slug, peerId: peerId, price: price).start(error: { error in
|
||||||
subscriber.putError(error)
|
subscriber.putError(error)
|
||||||
}, completed: {
|
}, completed: {
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
|
@ -125,8 +125,8 @@ public extension TelegramEngine {
|
|||||||
return _internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId)
|
return _internal_transferStarGift(account: self.account, prepaid: prepaid, reference: reference, peerId: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func buyStarGift(slug: String, peerId: EnginePeer.Id) -> Signal<Never, BuyStarGiftError> {
|
public func buyStarGift(slug: String, peerId: EnginePeer.Id, price: Int64?) -> Signal<Never, BuyStarGiftError> {
|
||||||
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId)
|
return _internal_buyStarGift(account: self.account, slug: slug, peerId: peerId, price: price)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> {
|
public func upgradeStarGift(formId: Int64?, reference: StarGiftReference, keepOriginalInfo: Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError> {
|
||||||
|
@ -269,8 +269,8 @@ final class GiftStoreScreenComponent: Component {
|
|||||||
subject: .uniqueGift(uniqueGift, state.peerId),
|
subject: .uniqueGift(uniqueGift, state.peerId),
|
||||||
allSubjects: allSubjects,
|
allSubjects: allSubjects,
|
||||||
index: index,
|
index: index,
|
||||||
buyGift: { slug, peerId in
|
buyGift: { slug, peerId, price in
|
||||||
return self.state?.starGiftsContext.buyStarGift(slug: slug, peerId: peerId) ?? .complete()
|
return self.state?.starGiftsContext.buyStarGift(slug: slug, peerId: peerId, price: price) ?? .complete()
|
||||||
},
|
},
|
||||||
updateResellStars: { price in
|
updateResellStars: { price in
|
||||||
return self.state?.starGiftsContext.updateStarGiftResellPrice(slug: uniqueGift.slug, price: price) ?? .complete()
|
return self.state?.starGiftsContext.updateStarGiftResellPrice(slug: uniqueGift.slug, price: price) ?? .complete()
|
||||||
|
@ -1145,7 +1145,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func commitBuy(skipConfirmation: Bool = false) {
|
func commitBuy(acceptedPrice: Int64? = nil, skipConfirmation: Bool = false) {
|
||||||
guard let resellStars = self.subject.arguments?.resellStars, let starsContext = self.context.starsContext, let starsState = starsContext.currentState, case let .unique(uniqueGift) = self.subject.arguments?.gift else {
|
guard let resellStars = self.subject.arguments?.resellStars, let starsContext = self.context.starsContext, let starsState = starsContext.currentState, case let .unique(uniqueGift) = self.subject.arguments?.gift else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1157,7 +1157,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
let recipientPeerId = self.recipientPeerId ?? self.context.account.peerId
|
let recipientPeerId = self.recipientPeerId ?? self.context.account.peerId
|
||||||
|
|
||||||
let action = {
|
let action = {
|
||||||
let proceed: (Int64) -> Void = { formId in
|
let proceed: () -> Void = {
|
||||||
guard let controller = self.getController() as? GiftViewScreen else {
|
guard let controller = self.getController() as? GiftViewScreen else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1165,38 +1165,66 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
self.inProgress = true
|
self.inProgress = true
|
||||||
self.updated()
|
self.updated()
|
||||||
|
|
||||||
let buyGiftImpl: ((String, EnginePeer.Id) -> Signal<Never, BuyStarGiftError>)
|
let buyGiftImpl: ((String, EnginePeer.Id, Int64?) -> Signal<Never, BuyStarGiftError>)
|
||||||
if let buyGift = controller.buyGift {
|
if let buyGift = controller.buyGift {
|
||||||
buyGiftImpl = { slug, peerId in
|
buyGiftImpl = { slug, peerId, price in
|
||||||
return buyGift(slug, peerId)
|
return buyGift(slug, peerId, price)
|
||||||
|> afterCompleted {
|
|> afterCompleted {
|
||||||
context.starsContext?.load(force: true)
|
context.starsContext?.load(force: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buyGiftImpl = { slug, peerId in
|
buyGiftImpl = { slug, peerId, price in
|
||||||
return self.context.engine.payments.buyStarGift(slug: slug, peerId: peerId)
|
return self.context.engine.payments.buyStarGift(slug: slug, peerId: peerId, price: price)
|
||||||
|> afterCompleted {
|
|> afterCompleted {
|
||||||
context.starsContext?.load(force: true)
|
context.starsContext?.load(force: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buyDisposable = (buyGiftImpl(uniqueGift.slug, recipientPeerId)
|
self.buyDisposable = (buyGiftImpl(uniqueGift.slug, recipientPeerId, acceptedPrice ?? resellStars)
|
||||||
|> deliverOnMainQueue).start(error: { [weak self] error in
|
|> deliverOnMainQueue).start(
|
||||||
guard let self, let controller = self.getController() else {
|
error: { [weak self] error in
|
||||||
return
|
guard let self, let controller = self.getController() else {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
self.inProgress = false
|
|
||||||
self.updated()
|
self.inProgress = false
|
||||||
|
self.updated()
|
||||||
let errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
|
||||||
|
switch error {
|
||||||
let alertController = textAlertController(context: context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
|
case let .priceChanged(newPrice):
|
||||||
controller.present(alertController, in: .window(.root))
|
let errorTitle = presentationData.strings.Gift_Buy_ErrorPriceChanged_Title
|
||||||
}, completed: { [weak self, weak starsContext] in
|
let originalPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(resellStars))
|
||||||
guard let self, let controller = self.getController() as? GiftViewScreen else {
|
let newPriceString = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text_Stars(Int32(newPrice))
|
||||||
|
let errorText = presentationData.strings.Gift_Buy_ErrorPriceChanged_Text(originalPriceString, newPriceString).string
|
||||||
|
|
||||||
|
let alertController = textAlertController(
|
||||||
|
context: context,
|
||||||
|
title: errorTitle,
|
||||||
|
text: errorText,
|
||||||
|
actions: [
|
||||||
|
TextAlertAction(type: .defaultAction, title: presentationData.strings.Gift_Buy_Confirm_BuyFor(Int32(newPrice)), action: { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.commitBuy(acceptedPrice: newPrice, skipConfirmation: true)
|
||||||
|
}),
|
||||||
|
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||||
|
})
|
||||||
|
],
|
||||||
|
actionLayout: .vertical,
|
||||||
|
parseMarkdown: true
|
||||||
|
)
|
||||||
|
controller.present(alertController, in: .window(.root))
|
||||||
|
default:
|
||||||
|
let alertController = textAlertController(context: context, title: nil, text: presentationData.strings.Gift_Buy_ErrorUnknown, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true)
|
||||||
|
controller.present(alertController, in: .window(.root))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
completed: { [weak self, weak starsContext] in
|
||||||
|
guard let self,
|
||||||
|
let controller = self.getController() as? GiftViewScreen else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.inProgress = false
|
self.inProgress = false
|
||||||
@ -1303,7 +1331,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
|
|
||||||
self.commitBuy(skipConfirmation: true)
|
self.commitBuy(skipConfirmation: true)
|
||||||
} else {
|
} else {
|
||||||
proceed(buyForm.id)
|
proceed()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -1312,7 +1340,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
controller.push(purchaseController)
|
controller.push(purchaseController)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
proceed(buyForm.id)
|
proceed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1321,7 +1349,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
action()
|
action()
|
||||||
} else {
|
} else {
|
||||||
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: recipientPeerId))
|
let _ = (self.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: recipientPeerId))
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||||
guard let self, let peer else {
|
guard let self, let peer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -3565,7 +3593,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
fileprivate let convertToStars: (() -> Void)?
|
fileprivate let convertToStars: (() -> Void)?
|
||||||
fileprivate let transferGift: ((Bool, EnginePeer.Id) -> Signal<Never, TransferStarGiftError>)?
|
fileprivate let transferGift: ((Bool, EnginePeer.Id) -> Signal<Never, TransferStarGiftError>)?
|
||||||
fileprivate let upgradeGift: ((Int64?, Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError>)?
|
fileprivate let upgradeGift: ((Int64?, Bool) -> Signal<ProfileGiftsContext.State.StarGift, UpgradeStarGiftError>)?
|
||||||
fileprivate let buyGift: ((String, EnginePeer.Id) -> Signal<Never, BuyStarGiftError>)?
|
fileprivate let buyGift: ((String, EnginePeer.Id, Int64?) -> Signal<Never, BuyStarGiftError>)?
|
||||||
fileprivate let updateResellStars: ((Int64?) -> Signal<Never, UpdateStarGiftPriceError>)?
|
fileprivate let updateResellStars: ((Int64?) -> Signal<Never, UpdateStarGiftPriceError>)?
|
||||||
fileprivate let togglePinnedToTop: ((Bool) -> Bool)?
|
fileprivate let togglePinnedToTop: ((Bool) -> Bool)?
|
||||||
fileprivate let shareStory: ((StarGift.UniqueGift) -> Void)?
|
fileprivate let shareStory: ((StarGift.UniqueGift) -> Void)?
|
||||||
@ -3582,7 +3610,7 @@ public class GiftViewScreen: ViewControllerComponentContainer {
|
|||||||
convertToStars: (() -> Void)? = nil,
|
convertToStars: (() -> Void)? = nil,
|
||||||
transferGift: ((Bool, EnginePeer.Id) -> Signal<Never, TransferStarGiftError>)? = 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,
|
||||||
buyGift: ((String, EnginePeer.Id) -> Signal<Never, BuyStarGiftError>)? = nil,
|
buyGift: ((String, EnginePeer.Id, Int64?) -> Signal<Never, BuyStarGiftError>)? = nil,
|
||||||
updateResellStars: ((Int64?) -> Signal<Never, UpdateStarGiftPriceError>)? = nil,
|
updateResellStars: ((Int64?) -> Signal<Never, UpdateStarGiftPriceError>)? = nil,
|
||||||
togglePinnedToTop: ((Bool) -> Bool)? = nil,
|
togglePinnedToTop: ((Bool) -> Bool)? = nil,
|
||||||
shareStory: ((StarGift.UniqueGift) -> Void)? = nil
|
shareStory: ((StarGift.UniqueGift) -> Void)? = nil
|
||||||
|
@ -2851,6 +2851,8 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
private var hiddenMediaDisposable: Disposable?
|
private var hiddenMediaDisposable: Disposable?
|
||||||
private let hiddenAvatarRepresentationDisposable = MetaDisposable()
|
private let hiddenAvatarRepresentationDisposable = MetaDisposable()
|
||||||
|
|
||||||
|
private var autoTranslateDisposable: Disposable?
|
||||||
|
|
||||||
private var resolvePeerByNameDisposable: MetaDisposable?
|
private var resolvePeerByNameDisposable: MetaDisposable?
|
||||||
private let navigationActionDisposable = MetaDisposable()
|
private let navigationActionDisposable = MetaDisposable()
|
||||||
private let enqueueMediaMessageDisposable = MetaDisposable()
|
private let enqueueMediaMessageDisposable = MetaDisposable()
|
||||||
@ -5113,6 +5115,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
self.joinChannelDisposable.dispose()
|
self.joinChannelDisposable.dispose()
|
||||||
self.boostStatusDisposable?.dispose()
|
self.boostStatusDisposable?.dispose()
|
||||||
self.personalChannelsDisposable?.dispose()
|
self.personalChannelsDisposable?.dispose()
|
||||||
|
self.autoTranslateDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
@ -9183,7 +9186,10 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func displayAutoTranslateLocked() {
|
private func displayAutoTranslateLocked() {
|
||||||
let _ = combineLatest(
|
guard self.autoTranslateDisposable == nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.autoTranslateDisposable = combineLatest(
|
||||||
queue: Queue.mainQueue(),
|
queue: Queue.mainQueue(),
|
||||||
context.engine.peers.getChannelBoostStatus(peerId: self.peerId),
|
context.engine.peers.getChannelBoostStatus(peerId: self.peerId),
|
||||||
context.engine.peers.getMyBoostStatus()
|
context.engine.peers.getMyBoostStatus()
|
||||||
@ -9197,6 +9203,9 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
controller.push(boostController)
|
controller.push(boostController)
|
||||||
|
|
||||||
|
self.autoTranslateDisposable?.dispose()
|
||||||
|
self.autoTranslateDisposable = nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,11 +604,11 @@ 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)
|
||||||
},
|
},
|
||||||
buyGift: { [weak self] slug, peerId in
|
buyGift: { [weak self] slug, peerId, price in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return .never()
|
return .never()
|
||||||
}
|
}
|
||||||
return self.profileGifts.buyStarGift(slug: slug, peerId: peerId)
|
return self.profileGifts.buyStarGift(slug: slug, peerId: peerId, price: price)
|
||||||
},
|
},
|
||||||
updateResellStars: { [weak self] price in
|
updateResellStars: { [weak self] price in
|
||||||
guard let self, let reference = product.reference else {
|
guard let self, let reference = product.reference else {
|
||||||
|
@ -174,6 +174,8 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
private var permissions: [Permission] = []
|
private var permissions: [Permission] = []
|
||||||
private var botRights: TelegramBusinessBotRights = []
|
private var botRights: TelegramBusinessBotRights = []
|
||||||
|
|
||||||
|
private var temporaryEnabledPermissions = Set<String>()
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
self.scrollView = ScrollView()
|
self.scrollView = ScrollView()
|
||||||
self.scrollView.showsVerticalScrollIndicator = true
|
self.scrollView.showsVerticalScrollIndicator = true
|
||||||
@ -505,6 +507,44 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func presentStarGiftsWarningIfNeeded(_ key: TelegramBusinessBotRights, completion: @escaping (Bool) -> Void) -> Bool {
|
||||||
|
guard let component = self.component, let environment = self.environment, let botResolutionState = self.botResolutionState, case let .found(peer, _) = botResolutionState.state, let controller = environment.controller() else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if !key.contains(.transferAndUpgradeGifts) && !key.contains(.transferStars) && !key.contains(.editUsername) {
|
||||||
|
completion(true)
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
let botUsername = "@\(peer.addressName ?? "")"
|
||||||
|
let text: String
|
||||||
|
if key.contains(.editUsername) {
|
||||||
|
text = environment.strings.ChatbotSetup_Gift_Warning_UsernameText(botUsername).string
|
||||||
|
} else if key == .transferAndUpgradeGifts {
|
||||||
|
text = environment.strings.ChatbotSetup_Gift_Warning_GiftsText(botUsername).string
|
||||||
|
} else if key == .transferStars {
|
||||||
|
text = environment.strings.ChatbotSetup_Gift_Warning_StarsText(botUsername).string
|
||||||
|
} else {
|
||||||
|
text = environment.strings.ChatbotSetup_Gift_Warning_CombinedText(botUsername).string
|
||||||
|
}
|
||||||
|
let alertController = textAlertController(context: component.context, title: environment.strings.ChatbotSetup_Gift_Warning_Title, text: text, actions: [
|
||||||
|
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {
|
||||||
|
completion(false)
|
||||||
|
}),
|
||||||
|
TextAlertAction(type: .defaultAction, title: environment.strings.ChatbotSetup_Gift_Warning_Proceed, action: {
|
||||||
|
completion(true)
|
||||||
|
})
|
||||||
|
], parseMarkdown: true)
|
||||||
|
alertController.dismissed = { byOutsideTap in
|
||||||
|
if byOutsideTap {
|
||||||
|
completion(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller.present(alertController, in: .window(.root))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func update(component: ChatbotSetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
func update(component: ChatbotSetupScreenComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<EnvironmentType>, transition: ComponentTransition) -> CGSize {
|
||||||
self.isUpdating = true
|
self.isUpdating = true
|
||||||
defer {
|
defer {
|
||||||
@ -741,7 +781,7 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
if case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.isBusiness) {
|
if case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.isBusiness) {
|
||||||
botResolutionState.state = .found(peer: peer, isInstalled: true)
|
botResolutionState.state = .found(peer: peer, isInstalled: true)
|
||||||
self.botResolutionState = botResolutionState
|
self.botResolutionState = botResolutionState
|
||||||
self.botRights = .All
|
self.botRights = [.reply, .readMessages, .deleteSentMessages, .deleteReceivedMessages]
|
||||||
self.state?.updated(transition: .spring(duration: 0.3))
|
self.state?.updated(transition: .spring(duration: 0.3))
|
||||||
} else {
|
} else {
|
||||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.ChatbotSetup_ErrorBotNotBusinessCapable, actions: [
|
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.ChatbotSetup_ErrorBotNotBusinessCapable, actions: [
|
||||||
@ -1074,6 +1114,10 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
selectedCount += 1
|
selectedCount += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if self.temporaryEnabledPermissions.contains(permission.id) {
|
||||||
|
value = true
|
||||||
|
}
|
||||||
|
|
||||||
titleItems.append(
|
titleItems.append(
|
||||||
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
|
AnyComponentWithIdentity(id: AnyHashable(1), component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(
|
text: .plain(NSAttributedString(
|
||||||
@ -1101,11 +1145,33 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let subpermissions = permission.subpermissions {
|
if let subpermissions = permission.subpermissions {
|
||||||
for subpermission in subpermissions {
|
if value {
|
||||||
if subpermission.enabled {
|
var combinedKey: TelegramBusinessBotRights = []
|
||||||
if let key = subpermission.key {
|
for subpermission in subpermissions {
|
||||||
|
if subpermission.enabled, let key = subpermission.key {
|
||||||
|
combinedKey.insert(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.temporaryEnabledPermissions.insert(permission.id)
|
||||||
|
|
||||||
|
let presentedWarning = self.presentStarGiftsWarningIfNeeded(combinedKey, completion: { [weak self] value in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if value {
|
||||||
|
self.botRights.insert(combinedKey)
|
||||||
|
}
|
||||||
|
self.temporaryEnabledPermissions.remove(permission.id)
|
||||||
|
self.state?.updated(transition: .spring(duration: 0.4))
|
||||||
|
})
|
||||||
|
|
||||||
|
if !presentedWarning {
|
||||||
|
self.state?.updated(transition: .spring(duration: 0.4))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for subpermission in subpermissions {
|
||||||
|
if subpermission.enabled, let key = subpermission.key {
|
||||||
if value {
|
if value {
|
||||||
self.botRights.insert(key)
|
|
||||||
} else {
|
} else {
|
||||||
self.botRights.remove(key)
|
self.botRights.remove(key)
|
||||||
}
|
}
|
||||||
@ -1170,7 +1236,15 @@ final class ChatbotSetupScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
if let key = subpermission.key {
|
if let key = subpermission.key {
|
||||||
if !value {
|
if !value {
|
||||||
self.botRights.insert(key)
|
let _ = self.presentStarGiftsWarningIfNeeded(key, completion: { [weak self] value in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if value {
|
||||||
|
self.botRights.insert(key)
|
||||||
|
}
|
||||||
|
self.state?.updated(transition: .spring(duration: 0.4))
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
self.botRights.remove(key)
|
self.botRights.remove(key)
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,18 @@ final class ChatTranslationPanelNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@objc private func closePressed() {
|
@objc private func closePressed() {
|
||||||
let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: self.context.sharedContext.accountManager, count: -100, timestamp: Int32(Date().timeIntervalSince1970) + 60 * 60 * 24 * 7).startStandalone()
|
let isPremium = self.chatInterfaceState?.isPremium ?? false
|
||||||
|
|
||||||
|
var translationAvailable = isPremium
|
||||||
|
if let channel = self.chatInterfaceState?.renderedPeer?.chatMainPeer as? TelegramChannel, channel.flags.contains(.autoTranslateEnabled) {
|
||||||
|
translationAvailable = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if translationAvailable {
|
||||||
|
self.interfaceInteraction?.hideTranslationPanel()
|
||||||
|
} else if !isPremium {
|
||||||
|
let _ = ApplicationSpecificNotice.incrementTranslationSuggestion(accountManager: self.context.sharedContext.accountManager, count: -100, timestamp: Int32(Date().timeIntervalSince1970) + 60 * 60 * 24 * 7).startStandalone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func buttonPressed() {
|
@objc private func buttonPressed() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user