Skip to content

Commit 034480b

Browse files
author
Isaac
committed
Merge commit '84a17115fa6082750c991bde783485fd4d92daf0'
# Conflicts: # submodules/TelegramUI/Components/MessageInputPanelComponent/Sources/MessageInputPanelComponent.swift
2 parents 1fb93ab + 84a1711 commit 034480b

File tree

157 files changed

+4727
-1584
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+4727
-1584
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,5 @@ build-input/*
6868
submodules/OpusBinding/SharedHeaders/*
6969
submodules/FFMpegBinding/SharedHeaders/*
7070
submodules/OpenSSLEncryptionProvider/SharedHeaders/*
71-
buildServer.json
71+
submodules/TelegramCore/FlatSerialization/Sources/*
72+
buildServer.json

Telegram/Telegram-iOS/en.lproj/Localizable.strings

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13819,12 +13819,12 @@ Sorry for the inconvenience.";
1381913819
"GroupInfo.Permissions.ChargeForMessages" = "Charge for Messages";
1382013820
"GroupInfo.Permissions.ChargeForMessagesInfo" = "If you turn this on, regular members of the group will have to pay Stars to send messages.";
1382113821
"GroupInfo.Permissions.MessagePrice" = "SET YOUR PRICE PER MESSAGE";
13822-
"GroupInfo.Permissions.MessagePriceInfo" = "Your group will receive 85% of the selected fee (%1$@) for each incoming message.";
13822+
"GroupInfo.Permissions.MessagePriceInfo" = "Your group will receive %1$@% of the selected fee (%2$@) for each incoming message.";
1382313823

1382413824
"Privacy.Messages.ChargeForMessages" = "Charge for Messages";
1382513825
"Privacy.Messages.ChargeForMessagesInfo" = "Charge a fee for messages from people outide your contacts or those you haven't messaged first.";
1382613826
"Privacy.Messages.MessagePrice" = "SET YOUR PRICE PER MESSAGE";
13827-
"Privacy.Messages.MessagePriceInfo" = "Your will receive 85% of the selected fee (%1$@) for each incoming message.";
13827+
"Privacy.Messages.MessagePriceInfo" = "Your will receive %1$@% of the selected fee (%2$@) for each incoming message.";
1382813828

1382913829
"Privacy.Messages.RemoveFeeHeader" = "EXCEPTIONS";
1383013830
"Privacy.Messages.RemoveFee" = "Remove Fee";
@@ -13839,9 +13839,15 @@ Sorry for the inconvenience.";
1383913839
"Notification.PaidMessage.Stars_1" = "%@ Star";
1384013840
"Notification.PaidMessage.Stars_any" = "%@ Stars";
1384113841

13842+
"Notification.PaidMessage.Messages_1" = "%@ message";
13843+
"Notification.PaidMessage.Messages_any" = "%@ messages";
13844+
1384213845
"Notification.PaidMessage" = "%1$@ paid %2$@ to send a message";
1384313846
"Notification.PaidMessageYou" = "You paid %1$@ to send a message";
1384413847

13848+
"Notification.PaidMessageMany" = "%1$@ paid %2$@ to send %3$@";
13849+
"Notification.PaidMessageYouMany" = "You paid %1$@ to send %2$@";
13850+
1384513851
"Stars.Transfer.Terms" = "By purchasing you agree to the [Terms of Service]().";
1384613852
"Stars.Transfer.Terms_URL" = "https://telegram.org/tos/stars";
1384713853

@@ -13850,10 +13856,31 @@ Sorry for the inconvenience.";
1385013856
"Settings.Privacy.Messages.ValuePaid" = "Paid";
1385113857

1385213858
"Stars.Transaction.PaidMessage_1" = "Fee for %@ Message";
13853-
"Stars.Transaction.PaidMessage_anu" = "Fee for %@ Messages";
13859+
"Stars.Transaction.PaidMessage_any" = "Fee for %@ Messages";
1385413860
"Stars.Transaction.PaidMessage.Text" = "You receive **%@%** of the price that you charge for each incoming message. [Change Fee >]()";
13861+
"Stars.Transaction.Paid" = "Paid";
13862+
1385513863
"Stars.Intro.Transaction.PaidMessage_1" = "Fee for %@ Message";
1385613864
"Stars.Intro.Transaction.PaidMessage_any" = "Fee for %@ Messages";
1385713865

1385813866
"Stars.Purchase.SendMessageInfo" = "Buy Stars to send a message to **%@**.";
1385913867
"Stars.Purchase.SendGroupMessageInfo" = "Buy Stars to send a message in **%@**.";
13868+
13869+
"Gift.Options.Gift.Transfer" = "Transfer";
13870+
"Gift.Options.Gift.Filter.MyGifts" = "My Gifts";
13871+
"Gift.Options.Premium.OrStars" = "or %@";
13872+
13873+
"Gift.Send.PayWithStars" = "Pay with %@";
13874+
"Gift.Send.PayWithStars.Info" = "Your balance is **%@**. [Get More Stars >]()";
13875+
13876+
"Chat.PanelCustomStatusShortInfo" = "%@ is a mark for [Premium subscribers >]()";
13877+
13878+
"Chat.InputTextPaidMessagePlaceholder" = "Message for %@";
13879+
13880+
"Privacy.Messages.Stars_1" = "%@ Star";
13881+
"Privacy.Messages.Stars_any" = "%@ Stars";
13882+
"Privacy.Messages.Unlock" = "Unlock with Telegram Premium";
13883+
13884+
"Premium.PaidMessages" = "Paid Messages";
13885+
"Premium.PaidMessagesInfo" = "Charge a fee for messages from non-contacts or new senders.";
13886+
"Premium.PaidMessages.Proceed" = "About Telegram Premium";

submodules/AccountContext/Sources/AccountContext.swift

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,8 @@ public protocol SharedAccountContext: AnyObject {
11161116
func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError>
11171117
func makeMiniAppListScreen(context: AccountContext, initialData: MiniAppListScreenInitialData) -> ViewController
11181118

1119+
func makeIncomingMessagePrivacyScreen(context: AccountContext, value: GlobalPrivacySettings.NonContactChatsPrivacy, exceptions: SelectivePrivacySettings, update: @escaping (GlobalPrivacySettings.NonContactChatsPrivacy) -> Void) -> ViewController
1120+
11191121
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, botPeer: EnginePeer, chatPeer: EnginePeer?, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?)
11201122

11211123
func makeAffiliateProgramSetupScreenInitialData(context: AccountContext, peerId: EnginePeer.Id, mode: AffiliateProgramSetupScreenMode) -> Signal<AffiliateProgramSetupScreenInitialData, NoError>
@@ -1351,20 +1353,50 @@ public struct StickersSearchConfiguration {
13511353

13521354
public struct StarsSubscriptionConfiguration {
13531355
static var defaultValue: StarsSubscriptionConfiguration {
1354-
return StarsSubscriptionConfiguration(maxFee: 2500, usdWithdrawRate: 1200)
1356+
return StarsSubscriptionConfiguration(
1357+
maxFee: 2500,
1358+
usdWithdrawRate: 1200,
1359+
paidMessageMaxAmount: 10000,
1360+
paidMessageCommissionPermille: 850,
1361+
paidMessagesAvailable: false
1362+
)
13551363
}
1356-
1357-
public let maxFee: Int64?
1358-
public let usdWithdrawRate: Int64?
1359-
1360-
fileprivate init(maxFee: Int64?, usdWithdrawRate: Int64?) {
1364+
1365+
public let maxFee: Int64
1366+
public let usdWithdrawRate: Int64
1367+
public let paidMessageMaxAmount: Int64
1368+
public let paidMessageCommissionPermille: Int32
1369+
public let paidMessagesAvailable: Bool
1370+
1371+
fileprivate init(
1372+
maxFee: Int64,
1373+
usdWithdrawRate: Int64,
1374+
paidMessageMaxAmount: Int64,
1375+
paidMessageCommissionPermille: Int32,
1376+
paidMessagesAvailable: Bool
1377+
) {
13611378
self.maxFee = maxFee
13621379
self.usdWithdrawRate = usdWithdrawRate
1380+
self.paidMessageMaxAmount = paidMessageMaxAmount
1381+
self.paidMessageCommissionPermille = paidMessageCommissionPermille
1382+
self.paidMessagesAvailable = paidMessagesAvailable
13631383
}
13641384

13651385
public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration {
1366-
if let data = appConfiguration.data, let value = data["stars_subscription_amount_max"] as? Double, let usdRate = data["stars_usd_withdraw_rate_x1000"] as? Double {
1367-
return StarsSubscriptionConfiguration(maxFee: Int64(value), usdWithdrawRate: Int64(usdRate))
1386+
if let data = appConfiguration.data {
1387+
let maxFee = (data["stars_subscription_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.maxFee
1388+
let usdWithdrawRate = (data["stars_usd_withdraw_rate_x1000"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.usdWithdrawRate
1389+
let paidMessageMaxAmount = (data["stars_paid_message_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.paidMessageMaxAmount
1390+
let paidMessageCommissionPermille = (data["stars_paid_message_commission_permille"] as? Double).flatMap(Int32.init) ?? StarsSubscriptionConfiguration.defaultValue.paidMessageCommissionPermille
1391+
let paidMessagesAvailable = (data["stars_paid_messages_available"] as? Bool) ?? StarsSubscriptionConfiguration.defaultValue.paidMessagesAvailable
1392+
1393+
return StarsSubscriptionConfiguration(
1394+
maxFee: maxFee,
1395+
usdWithdrawRate: usdWithdrawRate,
1396+
paidMessageMaxAmount: paidMessageMaxAmount,
1397+
paidMessageCommissionPermille: paidMessageCommissionPermille,
1398+
paidMessagesAvailable: paidMessagesAvailable
1399+
)
13681400
} else {
13691401
return .defaultValue
13701402
}

submodules/AccountContext/Sources/Premium.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public enum PremiumIntroSource {
4242
case folderTags
4343
case animatedEmoji
4444
case messageEffects
45+
case paidMessages
4546
}
4647

4748
public enum PremiumGiftSource: Equatable {
@@ -79,6 +80,7 @@ public enum PremiumDemoSubject {
7980
case folderTags
8081
case business
8182
case messageEffects
83+
case paidMessages
8284

8385
case businessLocation
8486
case businessHours
@@ -134,6 +136,7 @@ public enum StarsPurchasePurpose: Equatable {
134136
case unlockMedia(requiredStars: Int64)
135137
case starGift(peerId: EnginePeer.Id, requiredStars: Int64)
136138
case upgradeStarGift(requiredStars: Int64)
139+
case sendMessage(peerId: EnginePeer.Id, requiredStars: Int64)
137140
}
138141

139142
public struct PremiumConfiguration {

submodules/AccountContext/Sources/ShareController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,5 @@ public enum ShareControllerSubject {
7676
case image([ImageRepresentationWithReference])
7777
case media(AnyMediaReference, MediaParameters?)
7878
case mapMedia(TelegramMediaMap)
79-
case fromExternal(([PeerId], [PeerId: Int64], String, ShareControllerAccountContext, Bool) -> Signal<ShareControllerExternalStatus, ShareControllerError>)
79+
case fromExternal(Int, ([PeerId], [PeerId: Int64], [PeerId: StarsAmount], String, ShareControllerAccountContext, Bool) -> Signal<ShareControllerExternalStatus, ShareControllerError>)
8080
}

submodules/AttachmentTextInputPanelNode/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ swift_library(
3535
"//submodules/TelegramUI/Components/MultiAnimationRenderer:MultiAnimationRenderer",
3636
"//submodules/TelegramUI/Components/TextNodeWithEntities:TextNodeWithEntities",
3737
"//submodules/TelegramUI/Components/Chat/ChatInputTextNode",
38+
"//submodules/AnimatedCountLabelNode",
3839
],
3940
visibility = [
4041
"//visibility:public",

submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputActionButtonsNode.swift

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import ContextUI
88
import ChatPresentationInterfaceState
99
import ComponentFlow
1010
import AccountContext
11+
import AnimatedCountLabelNode
1112

1213
final class AttachmentTextInputActionButtonsNode: ASDisplayNode, ChatSendMessageActionSheetControllerSourceSendButtonNode {
1314
private let strings: PresentationStrings
@@ -17,7 +18,7 @@ final class AttachmentTextInputActionButtonsNode: ASDisplayNode, ChatSendMessage
1718
let sendButton: HighlightTrackingButtonNode
1819
var sendButtonHasApplyIcon = false
1920
var animatingSendButton = false
20-
let textNode: ImmediateTextNode
21+
let textNode: ImmediateAnimatedCountLabelNode
2122

2223
private var theme: PresentationTheme
2324

@@ -46,8 +47,7 @@ final class AttachmentTextInputActionButtonsNode: ASDisplayNode, ChatSendMessage
4647
self.backgroundNode.clipsToBounds = true
4748
self.sendButton = HighlightTrackingButtonNode(pointerStyle: nil)
4849

49-
self.textNode = ImmediateTextNode()
50-
self.textNode.attributedText = NSAttributedString(string: self.strings.MediaPicker_Send, font: Font.semibold(17.0), textColor: theme.chat.inputPanel.actionControlForegroundColor)
50+
self.textNode = ImmediateAnimatedCountLabelNode()
5151
self.textNode.isUserInteractionEnabled = false
5252

5353
super.init()
@@ -104,29 +104,51 @@ final class AttachmentTextInputActionButtonsNode: ASDisplayNode, ChatSendMessage
104104

105105
func updateTheme(theme: PresentationTheme, wallpaper: TelegramWallpaper) {
106106
self.backgroundNode.backgroundColor = theme.chat.inputPanel.actionControlFillColor
107-
108-
self.textNode.attributedText = NSAttributedString(string: self.strings.MediaPicker_Send, font: Font.semibold(17.0), textColor: theme.chat.inputPanel.actionControlForegroundColor)
109107
}
110108

111109
private var absoluteRect: (CGRect, CGSize)?
112110
func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize, transition: ContainedViewLayoutTransition) {
113111
self.absoluteRect = (rect, containerSize)
114112
}
115113

116-
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition, minimized: Bool, interfaceState: ChatPresentationInterfaceState) -> CGSize {
114+
func updateLayout(size: CGSize, transition: ContainedViewLayoutTransition, minimized: Bool, text: String, interfaceState: ChatPresentationInterfaceState) -> CGSize {
117115
self.validLayout = size
118116

119117
let width: CGFloat
120-
let textSize = self.textNode.updateLayout(CGSize(width: 100.0, height: 100.0))
118+
119+
var titleOffset: CGFloat = 0.0
120+
var segments: [AnimatedCountLabelNode.Segment] = []
121+
var buttonInset: CGFloat = 18.0
122+
if text.hasPrefix("⭐️") {
123+
let font = Font.with(size: 17.0, design: .round, weight: .semibold, traits: .monospacedNumbers)
124+
let badgeString = NSMutableAttributedString(string: "⭐️ ", font: font, textColor: interfaceState.theme.chat.inputPanel.actionControlForegroundColor)
125+
if let range = badgeString.string.range(of: "⭐️") {
126+
badgeString.addAttribute(.attachment, value: PresentationResourcesChat.chatPlaceholderStarIcon(interfaceState.theme)!, range: NSRange(range, in: badgeString.string))
127+
badgeString.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: badgeString.string))
128+
}
129+
segments.append(.text(0, badgeString))
130+
for char in text {
131+
if let intValue = Int(String(char)) {
132+
segments.append(.number(intValue, NSAttributedString(string: String(char), font: font, textColor: interfaceState.theme.chat.inputPanel.actionControlForegroundColor)))
133+
}
134+
}
135+
titleOffset -= 2.0
136+
buttonInset = 14.0
137+
} else {
138+
segments.append(.text(0, NSAttributedString(string: text, font: Font.semibold(17.0), textColor: interfaceState.theme.chat.inputPanel.actionControlForegroundColor)))
139+
}
140+
self.textNode.segments = segments
141+
142+
let textSize = self.textNode.updateLayout(size: CGSize(width: 100.0, height: 100.0), animated: transition.isAnimated)
121143
if minimized {
122144
width = 44.0
123145
} else {
124-
width = textSize.width + 36.0
146+
width = textSize.width + buttonInset * 2.0
125147
}
126148

127149
let buttonSize = CGSize(width: width, height: size.height)
128150

129-
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - textSize.width) / 2.0), y: floorToScreenPixels((buttonSize.height - textSize.height) / 2.0)), size: textSize))
151+
transition.updateFrame(node: self.textNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - textSize.width) / 2.0) + titleOffset, y: floorToScreenPixels((buttonSize.height - textSize.height) / 2.0)), size: textSize))
130152
transition.updateAlpha(node: self.textNode, alpha: minimized ? 0.0 : 1.0)
131153
transition.updateAlpha(node: self.sendButton.imageNode, alpha: minimized ? 1.0 : 0.0)
132154

submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -750,7 +750,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
750750
}
751751

752752
self.theme = interfaceState.theme
753-
753+
754754
self.actionButtons.updateTheme(theme: interfaceState.theme, wallpaper: interfaceState.chatWallpaper)
755755

756756
let textFieldMinHeight = calclulateTextFieldMinHeight(interfaceState, metrics: metrics)
@@ -957,7 +957,17 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
957957
var textBackgroundInset: CGFloat = 0.0
958958
let actionButtonsSize: CGSize
959959
if let presentationInterfaceState = self.presentationInterfaceState {
960-
actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, minimized: !self.isAttachment || inputHasText, interfaceState: presentationInterfaceState)
960+
let isMinimized: Bool
961+
let text: String
962+
if let sendPaidMessageStars = presentationInterfaceState.sendPaidMessageStars {
963+
isMinimized = false
964+
let count = max(1, presentationInterfaceState.interfaceState.forwardMessageIds?.count ?? 1)
965+
text = "⭐️\(sendPaidMessageStars.value * Int64(count))"
966+
} else {
967+
isMinimized = !self.isAttachment || inputHasText
968+
text = presentationInterfaceState.strings.MediaPicker_Send
969+
}
970+
actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, minimized: isMinimized, text: text, interfaceState: presentationInterfaceState)
961971
textBackgroundInset = 44.0 - actionButtonsSize.width
962972
} else {
963973
actionButtonsSize = CGSize(width: 44.0, height: minimalHeight)

submodules/AttachmentUI/Sources/AttachmentController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,7 @@ public class AttachmentController: ViewController, MinimizableController {
11411141
}
11421142

11431143
let isEffecitvelyCollapsedUpdated = (self.selectionCount > 0) != (self.panel.isSelecting)
1144-
let panelHeight = self.panel.update(layout: containerLayout, buttons: self.controller?.buttons ?? [], isSelecting: self.selectionCount > 0, elevateProgress: !hasPanel && !hasButton, transition: transition)
1144+
let panelHeight = self.panel.update(layout: containerLayout, buttons: self.controller?.buttons ?? [], isSelecting: self.selectionCount > 0, selectionCount: self.selectionCount, elevateProgress: !hasPanel && !hasButton, transition: transition)
11451145
if hasPanel || hasButton {
11461146
containerInsets.bottom = panelHeight
11471147
}

0 commit comments

Comments
 (0)