Various improvements

This commit is contained in:
Ilya Laktyushin 2024-10-28 18:21:47 +04:00
parent ebe812a56f
commit 30e4041149
14 changed files with 91 additions and 28 deletions

View File

@ -13146,13 +13146,21 @@ Sorry for the inconvenience.";
"TopApps.Info.Text" = "This catalogue ranks mini apps based on their daily revenue, measured in Stars. To be listed, developers must set their main mini app in [@botfather]() (as described [here](https://core.telegram.org/bots/webapps#launching-the-main-mini-app)), have over **1,000** daily users, and earn a daily revenue above **1,000** Stars, based on weekly average.";
"TopApps.Info.Done" = "Understood";
"Stars.Intro.Transaction.TelegramBotApi.Title" = "Paid Limit Extension";
"Stars.Intro.Transaction.TelegramBotApi.Subtitle" = "Bot API";
"Stars.Intro.Transaction.TelegramBotApi.Title" = "Paid Broadcast";
"Stars.Intro.Transaction.TelegramBotApi.Messages_1" = "%@ Message";
"Stars.Intro.Transaction.TelegramBotApi.Messages_any" = "%@ Messages";
"Stars.Transaction.TelegramBotApi.Title" = "Paid Limit Extension";
"Stars.Transaction.TelegramBotApi.Subtitle" = "Bot API";
"Stars.Transaction.TelegramBotApi.Title" = "Paid Broadcast";
"Stars.Transaction.TelegramBotApi.Messages_1" = "%@ Message";
"Stars.Transaction.TelegramBotApi.Messages_any" = "%@ Messages";
"Monetization.Bot.Header" = "Telegram shares 50% of the revenue from ads displayed in your bot. [Learn More >]()";
"Monetization.Bot.BalanceTitle" = "AVAILABLE BALANCE";
"Resolve.ChannelErrorNotFound" = "Sorry, this channel doesn't seem to exist.";
"Stats.TonBotRevenue.Title" = "TON Balance";
"PeerInfo.BotBalance.Title" = "BALANCE";
"PeerInfo.BotBalance.Ton" = "Ton";
"PeerInfo.BotBalance.Stars" = "Stars";

View File

@ -1438,6 +1438,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
verifiedIconView.removeFromSuperview()
}
var additionalRightInset: CGFloat = 0.0
if let (titleLayout, titleApply) = actionButtonTitleLayoutAndApply {
let actionButtonTitleNode = titleApply()
let actionButtonBackgroundNode: ASImageNode
@ -1487,6 +1488,8 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
let actionTitleFrame = CGRect(origin: CGPoint(x: actionButtonFrame.minX + 13.0, y: actionButtonFrame.minY + floorToScreenPixels((actionButtonFrame.height - titleLayout.size.height) / 2.0) + 1.0), size: titleLayout.size)
actionButtonTitleNode.frame = actionTitleFrame
additionalRightInset += actionButtonSize.width + 16.0
} else {
if let actionButtonTitleNode = strongSelf.actionButtonTitleNode {
strongSelf.actionButtonTitleNode = nil
@ -1588,7 +1591,7 @@ public class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
badgeBackgroundNode.image = currentBadgeBackgroundImage
badgeBackgroundWidth = max(badgeTextLayout.size.width + 10.0, currentBadgeBackgroundImage.size.width)
var badgeBackgroundFrame = CGRect(x: revealOffset + params.width - params.rightInset - badgeBackgroundWidth - 6.0, y: floor((nodeLayout.contentSize.height - currentBadgeBackgroundImage.size.height) / 2.0), width: badgeBackgroundWidth, height: currentBadgeBackgroundImage.size.height)
var badgeBackgroundFrame = CGRect(x: revealOffset + params.width - params.rightInset - badgeBackgroundWidth - additionalRightInset - 6.0, y: floor((nodeLayout.contentSize.height - currentBadgeBackgroundImage.size.height) / 2.0), width: badgeBackgroundWidth, height: currentBadgeBackgroundImage.size.height)
if let arrowButtonImage = arrowButtonImage {
badgeBackgroundFrame.origin.x -= arrowButtonImage.size.width + 6.0

View File

@ -2182,8 +2182,7 @@ public func channelStatsController(
var leftNavigationButton: ItemListNavigationButton?
var boostsOnly = false
if existingRevenueContext != nil {
//TODO:localize
title = .text("TON Balance")
title = .text(presentationData.strings.Stats_TonBotRevenue_Title)
canViewRevenue = true
} else if section == .boosts {
title = .text("")

View File

@ -264,7 +264,11 @@ final class StarsTransactionItemNode: ListViewItemNode, ItemListItemNode {
itemSubtitle = item.presentationData.strings.Stars_Intro_Transaction_TelegramAds_Subtitle
case .apiLimitExtension:
itemTitle = item.presentationData.strings.Stars_Intro_Transaction_TelegramBotApi_Title
itemSubtitle = item.presentationData.strings.Stars_Intro_Transaction_TelegramBotApi_Subtitle
if let floodskipNumber = item.transaction.floodskipNumber {
itemSubtitle = item.presentationData.strings.Stars_Intro_Transaction_TelegramBotApi_Messages(floodskipNumber)
} else {
itemSubtitle = nil
}
case .unsupported:
itemTitle = item.presentationData.strings.Stars_Intro_Transaction_Unsupported_Title
itemSubtitle = nil

View File

@ -364,7 +364,7 @@ open class TabBarControllerImpl: ViewController, TabBarController {
}
self.tabBarControllerNode.tabBarNode.selectedIndex = tabBarSelectedIndex
var transitionSale: CGFloat = 0.995
var transitionSale: CGFloat = 0.998
if let currentView = self.currentController?.view {
transitionSale = (currentView.frame.height - 3.0) / currentView.frame.height
}
@ -373,7 +373,7 @@ open class TabBarControllerImpl: ViewController, TabBarController {
//self.tabBarControllerNode.currentControllerNode = nil
if animated {
currentController.view.layer.animateScale(from: 1.0, to: transitionSale, duration: 0.15, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { completed in
currentController.view.layer.animateScale(from: 1.0, to: transitionSale, duration: 0.12, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { completed in
if completed {
currentController.view.layer.removeAllAnimations()
}
@ -395,9 +395,9 @@ open class TabBarControllerImpl: ViewController, TabBarController {
let commit = self.tabBarControllerNode.setCurrentControllerNode(currentController.displayNode)
if animated {
currentController.view.layer.animateScale(from: transitionSale, to: 1.0, duration: 0.15, delay: 0.15, timingFunction: kCAMediaTimingFunctionSpring)
currentController.view.layer.animateScale(from: transitionSale, to: 1.0, duration: 0.15, delay: 0.1, timingFunction: kCAMediaTimingFunctionSpring)
currentController.view.layer.allowsGroupOpacity = true
currentController.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, completion: { completed in
currentController.view.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1, completion: { completed in
if completed {
currentController.view.layer.allowsGroupOpacity = false
}

View File

@ -468,7 +468,7 @@ private final class StarsContextImpl {
}
var transactions = state.transactions
if addTransaction {
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil), at: 0)
transactions.insert(.init(flags: [.isLocal], id: "\(arc4random())", count: balance, date: Int32(Date().timeIntervalSince1970), peer: .appStore, title: nil, description: nil, photo: nil, transactionDate: nil, transactionUrl: nil, paidMessageId: nil, giveawayMessageId: nil, media: [], subscriptionPeriod: nil, starGift: nil, floodskipNumber: nil), at: 0)
}
self.updateState(StarsContext.State(flags: [.isPendingBalance], balance: max(0, state.balance + balance), subscriptions: state.subscriptions, canLoadMoreSubscriptions: state.canLoadMoreSubscriptions, transactions: transactions, canLoadMoreTransactions: state.canLoadMoreTransactions, isLoading: state.isLoading))
@ -491,8 +491,6 @@ private extension StarsContext.State.Transaction {
init?(apiTransaction: Api.StarsTransaction, peerId: EnginePeer.Id?, transaction: Transaction) {
switch apiTransaction {
case let .starsTransaction(apiFlags, id, stars, date, transactionPeer, title, description, photo, transactionDate, transactionUrl, _, messageId, extendedMedia, subscriptionPeriod, giveawayPostId, starGift, floodskipNumber):
let _ = floodskipNumber
let parsedPeer: StarsContext.State.Transaction.Peer
var paidMessageId: MessageId?
var giveawayMessageId: MessageId?
@ -548,7 +546,7 @@ private extension StarsContext.State.Transaction {
let media = extendedMedia.flatMap({ $0.compactMap { textMediaAndExpirationTimerFromApiMedia($0, PeerId(0)).media } }) ?? []
let _ = subscriptionPeriod
self.init(flags: flags, id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) })
self.init(flags: flags, id: id, count: stars, date: date, peer: parsedPeer, title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), transactionDate: transactionDate, transactionUrl: transactionUrl, paidMessageId: paidMessageId, giveawayMessageId: giveawayMessageId, media: media, subscriptionPeriod: subscriptionPeriod, starGift: starGift.flatMap { StarGift(apiStarGift: $0) }, floodskipNumber: floodskipNumber)
}
}
}
@ -619,6 +617,7 @@ public final class StarsContext {
public let media: [Media]
public let subscriptionPeriod: Int32?
public let starGift: StarGift?
public let floodskipNumber: Int32?
public init(
flags: Flags,
@ -635,7 +634,8 @@ public final class StarsContext {
giveawayMessageId: MessageId?,
media: [Media],
subscriptionPeriod: Int32?,
starGift: StarGift?
starGift: StarGift?,
floodskipNumber: Int32?
) {
self.flags = flags
self.id = id
@ -652,6 +652,7 @@ public final class StarsContext {
self.media = media
self.subscriptionPeriod = subscriptionPeriod
self.starGift = starGift
self.floodskipNumber = floodskipNumber
}
public static func == (lhs: Transaction, rhs: Transaction) -> Bool {
@ -700,6 +701,9 @@ public final class StarsContext {
if lhs.starGift != rhs.starGift {
return false
}
if lhs.floodskipNumber != rhs.floodskipNumber {
return false
}
return true
}
}

View File

@ -5125,12 +5125,16 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
}
item.controllerInteraction.longTap(.command(command), ChatControllerInteraction.LongTapParams(message: item.content.firstMessage, contentNode: contentNode, messageNode: self, progress: tapAction.activate?()))
})
case let .hashtag(_, hashtag):
case let .hashtag(peerName, hashtag):
var fullHashtag = hashtag
if let peerName {
fullHashtag += "@\(peerName)"
}
return .action(InternalBubbleTapAction.Action { [weak self] in
guard let self, let contentNode = self.contextContentNodeForLink(hashtag, rects: rects) else {
guard let self, let contentNode = self.contextContentNodeForLink(fullHashtag, rects: rects) else {
return
}
item.controllerInteraction.longTap(.hashtag(hashtag), ChatControllerInteraction.LongTapParams(message: item.content.firstMessage, contentNode: contentNode, messageNode: self, progress: tapAction.activate?()))
item.controllerInteraction.longTap(.hashtag(fullHashtag), ChatControllerInteraction.LongTapParams(message: item.content.firstMessage, contentNode: contentNode, messageNode: self, progress: tapAction.activate?()))
})
case .instantPage:
break

View File

@ -1514,7 +1514,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
if overallRevenueBalance > 0 || overallStarsBalance > 0 {
//TODO:localize
items[.balances]!.append(PeerInfoScreenHeaderItem(id: 20, text: "BALANCE"))
items[.balances]!.append(PeerInfoScreenHeaderItem(id: 20, text: presentationData.strings.PeerInfo_BotBalance_Title))
if overallRevenueBalance > 0 {
let string = "*\(formatTonAmountText(revenueBalance, dateTimeFormat: presentationData.dateTimeFormat))"
let attributedString = NSMutableAttributedString(string: string, font: Font.regular(presentationData.listsFontSize.itemListBaseFontSize), textColor: presentationData.theme.list.itemSecondaryTextColor)
@ -1522,7 +1522,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
attributedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .ton), range: NSRange(range, in: attributedString.string))
attributedString.addAttribute(.baselineOffset, value: 1.5, range: NSRange(range, in: attributedString.string))
}
items[.balances]!.append(PeerInfoScreenDisclosureItem(id: 21, label: .attributedText(attributedString), text: "Toncoin", icon: PresentationResourcesSettings.ton, action: {
items[.balances]!.append(PeerInfoScreenDisclosureItem(id: 21, label: .attributedText(attributedString), text: presentationData.strings.PeerInfo_BotBalance_Ton, icon: PresentationResourcesSettings.ton, action: {
interaction.editingOpenRevenue()
}))
}
@ -1534,7 +1534,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
attributedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: false)), range: NSRange(range, in: attributedString.string))
attributedString.addAttribute(.baselineOffset, value: 1.5, range: NSRange(range, in: attributedString.string))
}
items[.balances]!.append(PeerInfoScreenDisclosureItem(id: 22, label: .attributedText(attributedString), text: "Stars", icon: PresentationResourcesSettings.stars, action: {
items[.balances]!.append(PeerInfoScreenDisclosureItem(id: 22, label: .attributedText(attributedString), text: presentationData.strings.PeerInfo_BotBalance_Stars, icon: PresentationResourcesSettings.stars, action: {
interaction.editingOpenStars()
}))
}

View File

@ -274,7 +274,20 @@ public final class StarsAvatarComponent: Component {
self.iconView.isHidden = false
self.avatarNode.isHidden = true
self.iconView.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon"), color: .white)
case .unsupported, .apiLimitExtension:
case .apiLimitExtension:
self.backgroundView.image = generateGradientFilledCircleImage(
diameter: size.width,
colors: [
UIColor(rgb: 0x32b83b).cgColor,
UIColor(rgb: 0x87d93b).cgColor
],
direction: .vertical
)
self.backgroundView.isHidden = false
self.iconView.isHidden = false
self.avatarNode.isHidden = true
self.iconView.image = UIImage(bundleImageName: "Premium/Stars/PaidBroadcast")
case .unsupported:
iconInset = 7.0
self.backgroundView.image = generateGradientFilledCircleImage(
diameter: size.width,

View File

@ -788,7 +788,17 @@ public final class StarsImageComponent: Component {
direction: .mirroredDiagonal
)
iconView.image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Media/EntityInputPremiumIcon"), color: .white)
case .peer, .unsupported, .apiLimitExtension:
case .apiLimitExtension:
iconBackgroundView.image = generateGradientFilledCircleImage(
diameter: imageSize.width,
colors: [
UIColor(rgb: 0x32b83b).cgColor,
UIColor(rgb: 0x87d93b).cgColor
],
direction: .vertical
)
iconView.image = UIImage(bundleImageName: "Premium/Stars/PaidBroadcast")
case .peer, .unsupported:
iconInset = 15.0
iconBackgroundView.image = generateGradientFilledCircleImage(
diameter: imageSize.width,

View File

@ -412,11 +412,13 @@ private final class StarsTransactionSheetContent: CombinedComponent {
via = strings.Stars_Transaction_TelegramAds_Subtitle
case .apiLimitExtension:
titleText = strings.Stars_Transaction_TelegramBotApi_Title
via = strings.Stars_Transaction_TelegramBotApi_Subtitle
case .unsupported:
titleText = strings.Stars_Transaction_Unsupported_Title
}
if !transaction.media.isEmpty {
if let floodskipNumber = transaction.floodskipNumber {
descriptionText = strings.Stars_Transaction_TelegramBotApi_Messages(floodskipNumber)
} else if !transaction.media.isEmpty {
var description: String = ""
var photoCount: Int32 = 0
var videoCount: Int32 = 0

View File

@ -360,7 +360,11 @@ final class StarsTransactionsListPanelComponent: Component {
itemSubtitle = environment.strings.Stars_Intro_Transaction_TelegramAds_Subtitle
case .apiLimitExtension:
itemTitle = environment.strings.Stars_Intro_Transaction_TelegramBotApi_Title
itemSubtitle = environment.strings.Stars_Intro_Transaction_TelegramBotApi_Subtitle
if let floodskipNumber = item.floodskipNumber {
itemSubtitle = environment.strings.Stars_Intro_Transaction_TelegramBotApi_Messages(floodskipNumber)
} else {
itemSubtitle = nil
}
case .unsupported:
itemTitle = environment.strings.Stars_Intro_Transaction_Unsupported_Title
itemSubtitle = nil

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "paidbroadcast.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}