Limit min stars

This commit is contained in:
Isaac 2025-06-29 14:23:52 +02:00
parent ea9f53acb8
commit b2909a3241
2 changed files with 47 additions and 9 deletions

View File

@ -1511,7 +1511,8 @@ public struct StarsSubscriptionConfiguration {
channelMessageSuggestionStarsCommissionPermille: 850,
channelMessageSuggestionTonCommissionPermille: 850,
channelMessageSuggestionMaxStarsAmount: 10000,
channelMessageSuggestionMaxTonAmount: 10000000000000
channelMessageSuggestionMaxTonAmount: 10000000000000,
channelMessageSuggestionMinStarsAmount: 5
)
}
@ -1528,6 +1529,7 @@ public struct StarsSubscriptionConfiguration {
public let channelMessageSuggestionTonCommissionPermille: Int32
public let channelMessageSuggestionMaxStarsAmount: Int64
public let channelMessageSuggestionMaxTonAmount: Int64
public let channelMessageSuggestionMinStarsAmount: Int64
fileprivate init(
maxFee: Int64,
@ -1542,7 +1544,8 @@ public struct StarsSubscriptionConfiguration {
channelMessageSuggestionStarsCommissionPermille: Int32,
channelMessageSuggestionTonCommissionPermille: Int32,
channelMessageSuggestionMaxStarsAmount: Int64,
channelMessageSuggestionMaxTonAmount: Int64
channelMessageSuggestionMaxTonAmount: Int64,
channelMessageSuggestionMinStarsAmount: Int64
) {
self.maxFee = maxFee
self.usdWithdrawRate = usdWithdrawRate
@ -1557,6 +1560,7 @@ public struct StarsSubscriptionConfiguration {
self.channelMessageSuggestionTonCommissionPermille = channelMessageSuggestionTonCommissionPermille
self.channelMessageSuggestionMaxStarsAmount = channelMessageSuggestionMaxStarsAmount
self.channelMessageSuggestionMaxTonAmount = channelMessageSuggestionMaxTonAmount
self.channelMessageSuggestionMinStarsAmount = channelMessageSuggestionMinStarsAmount
}
public static func with(appConfiguration: AppConfiguration) -> StarsSubscriptionConfiguration {
@ -1576,6 +1580,8 @@ public struct StarsSubscriptionConfiguration {
let channelMessageSuggestionMaxStarsAmount = (data["stars_suggested_post_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.channelMessageSuggestionMaxStarsAmount
let channelMessageSuggestionMaxTonAmount = (data["ton_suggested_post_amount_max"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.channelMessageSuggestionMaxTonAmount
let channelMessageSuggestionMinStarsAmount = (data["stars_suggested_post_amount_min"] as? Double).flatMap(Int64.init) ?? StarsSubscriptionConfiguration.defaultValue.channelMessageSuggestionMinStarsAmount
return StarsSubscriptionConfiguration(
maxFee: maxFee,
usdWithdrawRate: usdWithdrawRate,
@ -1589,7 +1595,8 @@ public struct StarsSubscriptionConfiguration {
channelMessageSuggestionStarsCommissionPermille: channelMessageSuggestionStarsCommissionPermille,
channelMessageSuggestionTonCommissionPermille: channelMessageSuggestionTonCommissionPermille,
channelMessageSuggestionMaxStarsAmount: channelMessageSuggestionMaxStarsAmount,
channelMessageSuggestionMaxTonAmount: channelMessageSuggestionMaxTonAmount
channelMessageSuggestionMaxTonAmount: channelMessageSuggestionMaxTonAmount,
channelMessageSuggestionMinStarsAmount: channelMessageSuggestionMinStarsAmount
)
} else {
return .defaultValue

View File

@ -157,6 +157,7 @@ private final class SheetContent: CombinedComponent {
var amountRightLabel: String?
let minAmount: StarsAmount?
var allowZero = false
let maxAmount: StarsAmount?
let withdrawConfiguration = StarsWithdrawConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 })
@ -222,13 +223,14 @@ private final class SheetContent: CombinedComponent {
case .stars:
amountTitle = "ENTER A PRICE IN STARS"
maxAmount = StarsAmount(value: resaleConfiguration.channelMessageSuggestionMaxStarsAmount, nanos: 0)
minAmount = StarsAmount(value: resaleConfiguration.channelMessageSuggestionMinStarsAmount, nanos: 0)
case .ton:
amountTitle = "ENTER A PRICE IN TON"
maxAmount = StarsAmount(value: resaleConfiguration.channelMessageSuggestionMaxTonAmount, nanos: 0)
minAmount = StarsAmount(value: 0, nanos: 0)
}
amountPlaceholder = "Price"
minAmount = StarsAmount(value: 0, nanos: 0)
allowZero = true
if let usdWithdrawRate = withdrawConfiguration.usdWithdrawRate, let tonUsdRate = withdrawConfiguration.tonUsdRate, let amount = state.amount, amount > StarsAmount.zero {
switch state.currency {
@ -535,6 +537,7 @@ private final class SheetContent: CombinedComponent {
accentColor: theme.list.itemAccentColor,
value: state.amount?.value,
minValue: minAmount?.value,
allowZero: allowZero,
maxValue: maxAmount?.value,
placeholderText: amountPlaceholder,
labelText: amountLabel,
@ -762,8 +765,8 @@ private final class SheetContent: CombinedComponent {
if let controller = controller() as? StarsWithdrawScreen, let state {
let amount = state.amount ?? StarsAmount.zero
if let minAmount, amount < minAmount {
controller.presentMinAmountTooltip(minAmount.value)
if let minAmount, amount < minAmount, (!allowZero || amount != .zero) {
controller.presentMinAmountTooltip(minAmount.value, currency: state.currency)
} else {
switch state.mode {
case let .withdraw(_, completion):
@ -1113,12 +1116,30 @@ public final class StarsWithdrawScreen: ViewControllerComponentContainer {
}
}
func presentMinAmountTooltip(_ minAmount: Int64) {
func presentMinAmountTooltip(_ minAmount: Int64, currency: CurrencyAmount.Currency) {
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
var text = presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum(presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum_Stars(Int32(minAmount))).string
if case .starGiftResell = self.mode {
//TODO:localize
text = "You cannot sell gift for less than \(presentationData.strings.Stars_Withdraw_Withdraw_ErrorMinimum_Stars(Int32(minAmount)))."
} else if case let .suggestedPost(mode, _, _, _) = self.mode {
let resaleConfiguration = StarsSubscriptionConfiguration.with(appConfiguration: self.context.currentAppConfiguration.with { $0 })
switch currency {
case .stars:
//TODO:localize
switch mode {
case .admin:
text = "You cannot request less than \(resaleConfiguration.channelMessageSuggestionMinStarsAmount) Stars."
case let .sender(_, isFromAdmin):
if isFromAdmin {
text = "You cannot request less than \(resaleConfiguration.channelMessageSuggestionMinStarsAmount) Stars."
} else {
text = "You cannot offer less than \(resaleConfiguration.channelMessageSuggestionMinStarsAmount) Stars."
}
}
case .ton:
break
}
}
let resultController = UndoOverlayController(
@ -1153,17 +1174,19 @@ private final class AmountFieldStarsFormatter: NSObject, UITextFieldDelegate {
private let textField: UITextField
private let minValue: Int64
private let allowZero: Bool
private let maxValue: Int64
private let updated: (Int64) -> Void
private let isEmptyUpdated: (Bool) -> Void
private let animateError: () -> Void
private let focusUpdated: (Bool) -> Void
init?(textField: UITextField, currency: CurrencyAmount.Currency, dateTimeFormat: PresentationDateTimeFormat, minValue: Int64, maxValue: Int64, updated: @escaping (Int64) -> Void, isEmptyUpdated: @escaping (Bool) -> Void, animateError: @escaping () -> Void, focusUpdated: @escaping (Bool) -> Void) {
init?(textField: UITextField, currency: CurrencyAmount.Currency, dateTimeFormat: PresentationDateTimeFormat, minValue: Int64, allowZero: Bool, maxValue: Int64, updated: @escaping (Int64) -> Void, isEmptyUpdated: @escaping (Bool) -> Void, animateError: @escaping () -> Void, focusUpdated: @escaping (Bool) -> Void) {
self.textField = textField
self.currency = currency
self.dateTimeFormat = dateTimeFormat
self.minValue = minValue
self.allowZero = allowZero
self.maxValue = maxValue
self.updated = updated
self.isEmptyUpdated = isEmptyUpdated
@ -1307,6 +1330,7 @@ private final class AmountFieldComponent: Component {
let accentColor: UIColor
let value: Int64?
let minValue: Int64?
let allowZero: Bool
let maxValue: Int64?
let placeholderText: String
let labelText: String?
@ -1322,6 +1346,7 @@ private final class AmountFieldComponent: Component {
accentColor: UIColor,
value: Int64?,
minValue: Int64?,
allowZero: Bool,
maxValue: Int64?,
placeholderText: String,
labelText: String?,
@ -1336,6 +1361,7 @@ private final class AmountFieldComponent: Component {
self.accentColor = accentColor
self.value = value
self.minValue = minValue
self.allowZero = allowZero
self.maxValue = maxValue
self.placeholderText = placeholderText
self.labelText = labelText
@ -1364,6 +1390,9 @@ private final class AmountFieldComponent: Component {
if lhs.minValue != rhs.minValue {
return false
}
if lhs.allowZero != rhs.allowZero {
return false
}
if lhs.maxValue != rhs.maxValue {
return false
}
@ -1470,6 +1499,7 @@ private final class AmountFieldComponent: Component {
currency: component.currency,
dateTimeFormat: component.dateTimeFormat,
minValue: component.minValue ?? 0,
allowZero: component.allowZero,
maxValue: component.maxValue ?? Int64.max,
updated: { [weak self] value in
guard let self, let component = self.component else {
@ -1505,6 +1535,7 @@ private final class AmountFieldComponent: Component {
currency: component.currency,
dateTimeFormat: component.dateTimeFormat,
minValue: component.minValue ?? 0,
allowZero: component.allowZero,
maxValue: component.maxValue ?? 10000000,
updated: { [weak self] value in
guard let self, let component = self.component else {