Merge commit '9ec342bc71fc84fffd63dcbc4b010a1d87fa19df'

This commit is contained in:
Isaac 2024-08-27 15:20:45 +08:00
commit 79592cf766
15 changed files with 165 additions and 47 deletions

View File

@ -12837,3 +12837,21 @@ Sorry for the inconvenience.";
"Chat.Giveaway.Message.Stars.Stars_any" = "**%@** Stars";
"Chat.Giveaway.Message.Stars.Winners_1" = "to **%@** winner";
"Chat.Giveaway.Message.Stars.Winners_any" = "among **%@** winners";
"Chat.Giveaway.Info.Stars.Stars_1" = "**%@ Star**";
"Chat.Giveaway.Info.Stars.Stars_any" = "**%@ Stars**";
"Chat.Giveaway.Info.Stars.OngoingIntro" = "The giveaway is sponsored by the admins of **%1$@**, who acquired %2$@ for its followers.";
"Chat.Giveaway.Info.Stars.EndedIntro" = "The giveaway was sponsored by the admins of **%1$@**, who acquired %2$@ for its followers.";
"Chat.Giveaway.Info.Stars.Group.OngoingIntro" = "The giveaway is sponsored by the admins of **%1$@**, who acquired %2$@ for its members.";
"Chat.Giveaway.Info.Stars.Group.EndedIntro" = "The giveaway was sponsored by the admins of **%1$@**, who acquired %2$@ for its members.";
"Stars.Transaction.Giveaway.Title" = "Received Prize";
"Stars.Transaction.Giveaway.Reason" = "Reason";
"Stars.Transaction.Giveaway.Giveaway" = "Giveaway";
"Stars.Transaction.Giveaway.Prize" = "Prize";
"Stars.Transaction.Giveaway.Stars_1" = "%@ Star";
"Stars.Transaction.Giveaway.Stars_any" = "%@ Stars";
"Stats.RevenueInTon" = "Revenue in TON";
"Stats.RevenueInStars" = "Revenue in Stars";
"Stats.RevenueInUsd" = "Revenue in USD";

View File

@ -35,6 +35,9 @@ class GeneralChartComponentController: ChartThemeContainer {
var initialHorizontalRange: ClosedRange<CGFloat> = BaseConstants.defaultRange
var initialVerticalRange: ClosedRange<CGFloat> = BaseConstants.defaultRange
var currency: GraphCurrency?
var conversionRate: Double = 1.0
public var cartViewBounds: (() -> CGRect) = { fatalError() }
public var chartFrame: (() -> CGRect) = { fatalError() }
@ -201,7 +204,7 @@ class GeneralChartComponentController: ChartThemeContainer {
var detailsVisible = false
func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animated: Bool, feedback: Bool) {
setDetailsViewModel?(chartDetailsViewModel(closestDate: date, pointIndex: dataIndex), animated, feedback)
setDetailsViewModel?(chartDetailsViewModel(closestDate: date, pointIndex: dataIndex, currency: self.currency, rate: self.conversionRate), animated, feedback)
setDetailsChartVisibleClosure?(true, true)
setDetailsViewPositionClosure?(detailsViewPosition)
detailsVisible = true
@ -329,8 +332,8 @@ class GeneralChartComponentController: ChartThemeContainer {
return (updatedRange, verticalLabels)
}
func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
let values: [ChartDetailsViewModel.Value] = chartsCollection.chartValues.enumerated().map { arg in
func chartDetailsViewModel(closestDate: Date, pointIndex: Int, currency: GraphCurrency? = nil, rate: Double = 1.0) -> ChartDetailsViewModel {
var values: [ChartDetailsViewModel.Value] = chartsCollection.chartValues.enumerated().map { arg in
let (index, component) = arg
return ChartDetailsViewModel.Value(prefix: nil,
title: component.name,
@ -338,6 +341,39 @@ class GeneralChartComponentController: ChartThemeContainer {
color: component.color,
visible: chartVisibility[index])
}
if let currency, let firstValue = values.first, let color = GColor(hexString: "#dda747") {
let updatedTitle: String
switch currency {
case .ton:
updatedTitle = self.strings.revenueInTon
case .xtr:
updatedTitle = self.strings.revenueInStars
}
values[0] = ChartDetailsViewModel.Value(
prefix: nil,
title: updatedTitle,
value: firstValue.value,
color: color,
visible: firstValue.visible
)
let convertedValue = (self.verticalLimitsNumberFormatter.number(from: firstValue.value) as? Double ?? 0.0) * rate
let convertedValueString: String
if convertedValue > 1.0 {
convertedValueString = String(format: "%0.1f", convertedValue)
} else {
convertedValueString = String(format: "%0.3f", convertedValue)
}
values.append(ChartDetailsViewModel.Value(
prefix: nil,
title: self.strings.revenueInUsd,
value: "≈$\(convertedValueString)",
color: color,
visible: firstValue.visible
))
}
let dateString: String
if isZoomed {
dateString = BaseConstants.timeDateFormatter.string(from: closestDate)

View File

@ -131,7 +131,7 @@ class PercentChartComponentController: GeneralChartComponentController {
verticalScalesRenderer.setVisible(visibility.contains(true), animated: animated)
}
override func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
override func chartDetailsViewModel(closestDate: Date, pointIndex: Int, currency: GraphCurrency? = nil, rate: Double = 1.0) -> ChartDetailsViewModel {
let visibleValues = visibleDetailsChartValues
let total = visibleValues.map { $0.values[pointIndex] }.reduce(0, +)

View File

@ -149,7 +149,6 @@ class BarsComponentController: GeneralChartComponentController {
components: visibleComponents)
}
var conversionRate: Double = 1.0
func verticalLimitsLabels(verticalRange: ClosedRange<CGFloat>, secondary: Bool) -> (ClosedRange<CGFloat>, [LinesChartLabel]) {
var (range, labels) = super.verticalLimitsLabels(verticalRange: verticalRange)
if secondary {
@ -223,8 +222,8 @@ class BarsComponentController: GeneralChartComponentController {
return visibleCharts
}
override func chartDetailsViewModel(closestDate: Date, pointIndex: Int) -> ChartDetailsViewModel {
var viewModel = super.chartDetailsViewModel(closestDate: closestDate, pointIndex: pointIndex)
override func chartDetailsViewModel(closestDate: Date, pointIndex: Int, currency: GraphCurrency? = nil, rate: Double = 1.0) -> ChartDetailsViewModel {
var viewModel = super.chartDetailsViewModel(closestDate: closestDate, pointIndex: pointIndex, currency: currency, rate: rate)
let visibleChartValues = self.visibleChartValues
let totalSumm: CGFloat = visibleChartValues.map { CGFloat($0.values[pointIndex]) }.reduce(0, +)
viewModel.hideAction = { [weak self] in

View File

@ -28,8 +28,6 @@ public enum GraphCurrency : String {
}
public class StackedBarsChartController: BaseChartController {
let barsController: BarsComponentController
let zoomedBarsController: BarsComponentController
@ -55,6 +53,7 @@ public class StackedBarsChartController: BaseChartController {
secondaryScalesRenderer: secondaryScalesRenderer,
previewBarsChartRenderer: BarChartRenderer())
if let currency {
barsController.currency = currency
barsController.conversionRate = rate
barsController.verticalLimitsNumberFormatter = currency.formatter
barsController.detailsNumberFormatter = currency.formatter

View File

@ -30,13 +30,31 @@ public protocol ChartThemeContainer {
public class ChartStrings {
public let zoomOut: String
public let total: String
public let revenueInTon: String
public let revenueInStars: String
public let revenueInUsd: String
public init(zoomOut: String, total: String) {
public init(
zoomOut: String,
total: String,
revenueInTon: String,
revenueInStars: String,
revenueInUsd: String
) {
self.zoomOut = zoomOut
self.total = total
self.revenueInTon = revenueInTon
self.revenueInStars = revenueInStars
self.revenueInUsd = revenueInUsd
}
public static var defaultStrings = ChartStrings(zoomOut: "Zoom Out", total: "Total")
public static var defaultStrings = ChartStrings(
zoomOut: "Zoom Out",
total: "Total",
revenueInTon: "Revenue in TON",
revenueInStars: "Revenue in Stars",
revenueInUsd: "Revenue in USD"
)
}
public class ChartTheme {

View File

@ -59,7 +59,6 @@ public func presentGiveawayInfoController(
stars = amount
}
}
let _ = stars
var prizeDescription: String?
if let giveaway {
@ -147,17 +146,36 @@ public func presentGiveawayInfoController(
title = presentationData.strings.Chat_Giveaway_Info_Title
let intro: String
if stars > 0 {
let starsString = presentationData.strings.Chat_Giveaway_Info_Stars_Stars(Int32(stars))
if case .almostOver = status {
if isGroup {
intro = presentationData.strings.Chat_Giveaway_Info_Group_EndedIntro(peerName, presentationData.strings.Chat_Giveaway_Info_Subscriptions(quantity), presentationData.strings.Chat_Giveaway_Info_Months(months)).string
intro = presentationData.strings.Chat_Giveaway_Info_Stars_Group_EndedIntro(peerName, starsString).string
} else {
intro = presentationData.strings.Chat_Giveaway_Info_EndedIntro(peerName, presentationData.strings.Chat_Giveaway_Info_Subscriptions(quantity), presentationData.strings.Chat_Giveaway_Info_Months(months)).string
intro = presentationData.strings.Chat_Giveaway_Info_Stars_EndedIntro(peerName, starsString).string
}
} else {
if isGroup {
intro = presentationData.strings.Chat_Giveaway_Info_Group_OngoingIntro(peerName, presentationData.strings.Chat_Giveaway_Info_Subscriptions(quantity), presentationData.strings.Chat_Giveaway_Info_Months(months)).string
intro = presentationData.strings.Chat_Giveaway_Info_Stars_Group_OngoingIntro(peerName, starsString).string
} else {
intro = presentationData.strings.Chat_Giveaway_Info_OngoingIntro(peerName, presentationData.strings.Chat_Giveaway_Info_Subscriptions(quantity), presentationData.strings.Chat_Giveaway_Info_Months(months)).string
intro = presentationData.strings.Chat_Giveaway_Info_Stars_OngoingIntro(peerName, starsString).string
}
}
} else {
let subscriptionsString = presentationData.strings.Chat_Giveaway_Info_Subscriptions(quantity)
let monthsString = presentationData.strings.Chat_Giveaway_Info_Months(months)
if case .almostOver = status {
if isGroup {
intro = presentationData.strings.Chat_Giveaway_Info_Group_EndedIntro(peerName, subscriptionsString, monthsString).string
} else {
intro = presentationData.strings.Chat_Giveaway_Info_EndedIntro(peerName, subscriptionsString, monthsString).string
}
} else {
if isGroup {
intro = presentationData.strings.Chat_Giveaway_Info_Group_OngoingIntro(peerName, subscriptionsString, monthsString).string
} else {
intro = presentationData.strings.Chat_Giveaway_Info_OngoingIntro(peerName, subscriptionsString, monthsString).string
}
}
}

View File

@ -1576,7 +1576,7 @@ private func monetizationEntries(
if canViewRevenue {
entries.append(.adsTonBalanceTitle(presentationData.theme, presentationData.strings.Monetization_TonBalanceTitle))
entries.append(.adsTonBalance(presentationData.theme, data, isCreator && data.balances.availableBalance > 0, monetizationConfiguration.withdrawalAvailable))
entries.append(.adsTonBalance(presentationData.theme, data, isCreator && data.balances.availableBalance > 0, data.balances.withdrawEnabled))
if isCreator {
let withdrawalInfoText: String

View File

@ -295,7 +295,16 @@ public final class StatsGraphItemNode: ListViewItemNode {
strongSelf.activityIndicator.type = .custom(item.presentationData.theme.list.itemSecondaryTextColor, 16.0, 2.0, false)
if let updatedTheme = updatedTheme {
strongSelf.chartNode.setup(theme: ChartTheme(presentationTheme: updatedTheme), strings: ChartStrings(zoomOut: item.presentationData.strings.Stats_ZoomOut, total: item.presentationData.strings.Stats_Total))
strongSelf.chartNode.setup(
theme: ChartTheme(presentationTheme: updatedTheme),
strings: ChartStrings(
zoomOut: item.presentationData.strings.Stats_ZoomOut,
total: item.presentationData.strings.Stats_Total,
revenueInTon: item.presentationData.strings.Stats_RevenueInTon,
revenueInStars: item.presentationData.strings.Stats_RevenueInStars,
revenueInUsd: item.presentationData.strings.Stats_RevenueInUsd
)
)
}
if let updatedGraph = updatedGraph {

View File

@ -106,7 +106,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[1113113093] = { return Api.BotMenuButton.parse_botMenuButtonCommands($0) }
dict[1966318984] = { return Api.BotMenuButton.parse_botMenuButtonDefault($0) }
dict[602479523] = { return Api.BotPreviewMedia.parse_botPreviewMedia($0) }
dict[-2076642874] = { return Api.BroadcastRevenueBalances.parse_broadcastRevenueBalances($0) }
dict[-1006669337] = { return Api.BroadcastRevenueBalances.parse_broadcastRevenueBalances($0) }
dict[1434332356] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionProceeds($0) }
dict[1121127726] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionRefund($0) }
dict[1515784568] = { return Api.BroadcastRevenueTransaction.parse_broadcastRevenueTransactionWithdrawal($0) }

View File

@ -772,14 +772,15 @@ public extension Api {
}
public extension Api {
enum BroadcastRevenueBalances: TypeConstructorDescription {
case broadcastRevenueBalances(currentBalance: Int64, availableBalance: Int64, overallRevenue: Int64)
case broadcastRevenueBalances(flags: Int32, currentBalance: Int64, availableBalance: Int64, overallRevenue: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .broadcastRevenueBalances(let currentBalance, let availableBalance, let overallRevenue):
case .broadcastRevenueBalances(let flags, let currentBalance, let availableBalance, let overallRevenue):
if boxed {
buffer.appendInt32(-2076642874)
buffer.appendInt32(-1006669337)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(currentBalance, buffer: buffer, boxed: false)
serializeInt64(availableBalance, buffer: buffer, boxed: false)
serializeInt64(overallRevenue, buffer: buffer, boxed: false)
@ -789,23 +790,26 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .broadcastRevenueBalances(let currentBalance, let availableBalance, let overallRevenue):
return ("broadcastRevenueBalances", [("currentBalance", currentBalance as Any), ("availableBalance", availableBalance as Any), ("overallRevenue", overallRevenue as Any)])
case .broadcastRevenueBalances(let flags, let currentBalance, let availableBalance, let overallRevenue):
return ("broadcastRevenueBalances", [("flags", flags as Any), ("currentBalance", currentBalance as Any), ("availableBalance", availableBalance as Any), ("overallRevenue", overallRevenue as Any)])
}
}
public static func parse_broadcastRevenueBalances(_ reader: BufferReader) -> BroadcastRevenueBalances? {
var _1: Int64?
_1 = reader.readInt64()
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: Int64?
_3 = reader.readInt64()
var _4: Int64?
_4 = reader.readInt64()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.BroadcastRevenueBalances.broadcastRevenueBalances(currentBalance: _1!, availableBalance: _2!, overallRevenue: _3!)
let _c4 = _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.BroadcastRevenueBalances.broadcastRevenueBalances(flags: _1!, currentBalance: _2!, availableBalance: _3!, overallRevenue: _4!)
}
else {
return nil

View File

@ -23,20 +23,24 @@ public struct RevenueStats: Equatable, Codable {
case currentBalance
case availableBalance
case overallRevenue
case withdrawEnabled
}
public let currentBalance: Int64
public let availableBalance: Int64
public let overallRevenue: Int64
public let withdrawEnabled: Bool
init(
currentBalance: Int64,
availableBalance: Int64,
overallRevenue: Int64
overallRevenue: Int64,
withdrawEnabled: Bool
) {
self.currentBalance = currentBalance
self.availableBalance = availableBalance
self.overallRevenue = overallRevenue
self.withdrawEnabled = withdrawEnabled
}
public init(from decoder: Decoder) throws {
@ -44,6 +48,7 @@ public struct RevenueStats: Equatable, Codable {
self.currentBalance = try container.decode(Int64.self, forKey: .currentBalance)
self.availableBalance = try container.decode(Int64.self, forKey: .availableBalance)
self.overallRevenue = try container.decode(Int64.self, forKey: .overallRevenue)
self.withdrawEnabled = try container.decode(Bool.self, forKey: .withdrawEnabled)
}
public func encode(to encoder: Encoder) throws {
@ -51,6 +56,7 @@ public struct RevenueStats: Equatable, Codable {
try container.encode(self.currentBalance, forKey: .currentBalance)
try container.encode(self.availableBalance, forKey: .availableBalance)
try container.encode(self.overallRevenue, forKey: .overallRevenue)
try container.encode(self.withdrawEnabled, forKey: .withdrawEnabled)
}
}
@ -122,8 +128,8 @@ extension RevenueStats {
extension RevenueStats.Balances {
init(apiRevenueBalances: Api.BroadcastRevenueBalances) {
switch apiRevenueBalances {
case let .broadcastRevenueBalances(currentBalance, availableBalance, overallRevenue):
self.init(currentBalance: currentBalance, availableBalance: availableBalance, overallRevenue: overallRevenue)
case let .broadcastRevenueBalances(flags, currentBalance, availableBalance, overallRevenue):
self.init(currentBalance: currentBalance, availableBalance: availableBalance, overallRevenue: overallRevenue, withdrawEnabled: ((flags & (1 << 0)) != 0))
}
}
}

View File

@ -300,7 +300,18 @@ private final class StarsTransactionSheetContent: CombinedComponent {
}
}
case let .transaction(transaction, parentPeer):
if let _ = transaction.subscriptionPeriod {
if let giveawayMessageIdValue = transaction.giveawayMessageId {
titleText = strings.Stars_Transaction_Giveaway_Title
descriptionText = ""
count = transaction.count
transactionId = transaction.id
date = transaction.date
giveawayMessageId = giveawayMessageIdValue
if case let .peer(peer) = transaction.peer {
toPeer = peer
}
transactionPeer = transaction.peer
} else if let _ = transaction.subscriptionPeriod {
titleText = strings.Stars_Transaction_SubscriptionFee
descriptionText = ""
count = transaction.count
@ -447,11 +458,11 @@ private final class StarsTransactionSheetContent: CombinedComponent {
toPeer = state.peerMap[message.id.peerId]
}
} else if case let .prizeStars(countValue, _, boostPeerId, _, giveawayMessageIdValue) = action.action {
titleText = "Received Prize"
titleText = strings.Stars_Transaction_Giveaway_Title
count = countValue
countOnTop = true
transactionId = nil//transactionIdValue
transactionId = nil
giveawayMessageId = giveawayMessageIdValue
if let boostPeerId {
toPeer = state.peerMap[boostPeerId]
@ -526,7 +537,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
} else {
imageSubject = .none
}
if isSubscription || isSubscriber || isSubscriptionFee {
if isSubscription || isSubscriber || isSubscriptionFee || giveawayMessageId != nil {
imageIcon = .star
} else {
imageIcon = nil
@ -646,19 +657,19 @@ private final class StarsTransactionSheetContent: CombinedComponent {
if let giveawayMessageId {
tableItems.append(.init(
id: "prize",
title: "Prize",
title: strings.Stars_Transaction_Giveaway_Prize,
component: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: "\(count) Stars", font: tableFont, textColor: tableTextColor)))
MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Stars_Transaction_Giveaway_Stars(Int32(count)), font: tableFont, textColor: tableTextColor)))
)
))
tableItems.append(.init(
id: "reason",
title: "Reason",
title: strings.Stars_Transaction_Giveaway_Reason,
component: AnyComponent(
Button(
content: AnyComponent(
MultilineTextComponent(text: .plain(NSAttributedString(string: "Giveaway", font: tableFont, textColor: tableLinkColor)))
MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Stars_Transaction_Giveaway_Giveaway, font: tableFont, textColor: tableLinkColor)))
),
action: {
component.openMessage(giveawayMessageId)

View File

@ -249,7 +249,7 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
return .share(url: url, text: text, to: to)
} else if peerName == "boost" {
for queryItem in queryItems {
if queryItem.name == "c", let value = queryItem.value, let channelId = Int64(value) {
if queryItem.name == "c", let value = queryItem.value, let channelId = Int64(value), channelId > 0 {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
return .peer(.id(peerId), .boost)
}
@ -502,7 +502,7 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
} else if pathComponents[0] == "m" {
return .messageLink(slug: pathComponents[1])
} else if pathComponents.count == 3 && pathComponents[0] == "c" {
if let channelId = Int64(pathComponents[1]), let messageId = Int32(pathComponents[2]) {
if let channelId = Int64(pathComponents[1]), let messageId = Int32(pathComponents[2]), channelId > 0 {
var threadId: Int32?
var timecode: Double?
if let queryItems = components.queryItems {
@ -531,7 +531,7 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
return nil
}
} else if pathComponents.count == 4 && pathComponents[0] == "c" {
if let channelId = Int64(pathComponents[1]), let threadId = Int32(pathComponents[2]), let messageId = Int32(pathComponents[3]) {
if let channelId = Int64(pathComponents[1]), let threadId = Int32(pathComponents[2]), let messageId = Int32(pathComponents[3]), channelId > 0 {
var timecode: Double?
if let queryItems = components.queryItems {
for queryItem in queryItems {
@ -549,7 +549,7 @@ public func parseInternalUrl(sharedContext: SharedAccountContext, query: String)
return nil
}
} else if pathComponents.count == 2 && pathComponents[0] == "c" {
if let channelId = Int64(pathComponents[1]) {
if let channelId = Int64(pathComponents[1]), channelId > 0 {
var threadId: Int32?
var boost: Bool = false
if let queryItems = components.queryItems {

View File

@ -1,5 +1,5 @@
{
"app": "11.0.2",
"app": "11.1",
"xcode": "15.2",
"bazel": "7.1.1",
"macos": "13.0"