Skip to content

Commit 39b0fb3

Browse files
rnwynrclaude
andauthored
Refresh paid-message UI when the Stars price changes (#50)
* Fix stale paid message price after a group removes it The chat read the group's price from cached full channel data first, which refreshes rarely, so a removed price kept showing until it did. Read the price from the channel peer, which updates as soon as the price changes, matching iOS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Refresh paid-message price when chat fees change * Confirm paid messages again when the price changes Recheck "don't ask again" when the price or peer changes, so a higher price always asks for confirmation. Save the choice under the per-message price and ignore choices saved by older builds, which could hold a multi-message total. Show the current price in the media preview, and explain with an alert when a confirmed send is cancelled because the price changed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 30097e3 commit 39b0fb3

9 files changed

Lines changed: 417 additions & 98 deletions

File tree

‎packages/ChatUI/Sources/ChatUI/ChatController.swift‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4376,14 +4376,15 @@ open class ChatController<Context: AccountContextProtocol>: TelegramGenericViewC
43764376

43774377
verifyAlert(for: chatInteraction.interactionContext.window, header: strings().chatPayStarsConfirmTitle, information: strings().chatPayStarsConfirmText(peer.displayTitle, amount, amount, messageCountText), ok: strings().chatPayStarsConfirmPayOther(messagesCount), option: strings().chatPayStarsConfirmCheckbox, optionIsSelected: false, successHandler: { [weak chatInteraction] result in
43784378
guard let chatInteraction = chatInteraction else { return }
4379+
guard chatPaidMessagePriceIsCurrent(chatInteraction, payStars) else { return }
43794380
if starsState.balance.value > starsPrice {
43804381
chatInteraction.update({ current in
43814382
return current
43824383
.withUpdatedAlwaysPaidMessage(result == .thrid)
43834384
})
43844385
invoke()
43854386
if result == .thrid {
4386-
FastSettings.toggleCofirmPaid(peer.id, price: starsPrice)
4387+
FastSettings.toggleCofirmPaid(peer.id, price: Int(payStars.value))
43874388
}
43884389
} else {
43894390
FeatureNavigationHooks.shared.showStarsPurchaseWithContext(context, context.window, .stars, nil, Int64(starsPrice))
@@ -4865,14 +4866,14 @@ open class ChatController<Context: AccountContextProtocol>: TelegramGenericViewC
48654866
let messageCountText = strings().chatPayStarsConfirmMessagesOther(messagesCount)
48664867

48674868
verifyChatSendPayment(for: chatInteraction.interactionContext.window, header: strings().chatPayStarsConfirmTitle, information: strings().chatPayStarsConfirmText(peer.displayTitle, amount, amount, messageCountText), ok: strings().chatPayStarsConfirmPayOther(messagesCount), option: strings().chatPayStarsConfirmCheckbox, successHandler: { result in
4868-
4869+
guard chatPaidMessagePriceIsCurrent(chatInteraction, payStars) else { return }
48694870
if starsState.balance.value > starsPrice {
48704871
chatInteraction.update({ current in
48714872
return current
48724873
.withUpdatedAlwaysPaidMessage(result == .thrid)
48734874
})
48744875
if result == .thrid {
4875-
FastSettings.toggleCofirmPaid(peer.id, price: starsPrice)
4876+
FastSettings.toggleCofirmPaid(peer.id, price: Int(payStars.value))
48764877
}
48774878
invoke()
48784879
} else {
@@ -5682,14 +5683,14 @@ open class ChatController<Context: AccountContextProtocol>: TelegramGenericViewC
56825683
let messageCountText = strings().chatPayStarsConfirmMessagesOther(messagesCount)
56835684

56845685
verifyChatSendPayment(for: chatInteraction.interactionContext.window, header: strings().chatPayStarsConfirmTitle, information: strings().chatPayStarsConfirmText(peer.displayTitle, amount, amount, messageCountText), ok: strings().chatPayStarsConfirmPayOther(messagesCount), option: strings().chatPayStarsConfirmCheckbox, successHandler: { result in
5685-
5686+
guard chatPaidMessagePriceIsCurrent(chatInteraction, payStars) else { return }
56865687
if starsState.balance.value > starsPrice {
56875688
chatInteraction.update({ current in
56885689
return current
56895690
.withUpdatedAlwaysPaidMessage(result == .thrid)
56905691
})
56915692
if result == .thrid {
5692-
FastSettings.toggleCofirmPaid(peer.id, price: starsPrice)
5693+
FastSettings.toggleCofirmPaid(peer.id, price: Int(payStars.value))
56935694
}
56945695
invoke()
56955696
} else {
@@ -6766,13 +6767,14 @@ open class ChatController<Context: AccountContextProtocol>: TelegramGenericViewC
67666767
var confirmationResolved = false
67676768
verifyAlert(for: chatInteraction.interactionContext.window, header: strings().chatPayStarsConfirmTitle, information: strings().chatPayStarsConfirmText(peer.displayTitle, amount, amount, messageCountText), ok: strings().chatPayStarsConfirmPayOther(messagesCount), option: strings().chatPayStarsConfirmCheckbox, optionIsSelected: false, successHandler: { result in
67686769
confirmationResolved = true
6770+
guard chatPaidMessagePriceIsCurrent(chatInteraction, payStars) else { return }
67696771
if starsState.balance.value > starsPrice {
67706772
chatInteraction.update({ current in
67716773
return current
67726774
.withUpdatedAlwaysPaidMessage(result == .thrid)
67736775
})
67746776
if result == .thrid {
6775-
FastSettings.toggleCofirmPaid(peer.id, price: starsPrice)
6777+
FastSettings.toggleCofirmPaid(peer.id, price: Int(payStars.value))
67766778
}
67776779
invoke()
67786780
} else {

‎packages/ChatUI/Sources/ChatUI/ChatInputView.swift‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,10 @@ public class ChatInputView: View, Notifable {
12471247
if value.effectiveInput != oldValue.effectiveInput || oldValue.state != value.state || textPermissionChanged {
12481248
updateInput(value, prevState: oldValue, animated: animated)
12491249
}
1250+
if value.sendPaidMessageStars != oldValue.sendPaidMessageStars {
1251+
updatePlaceholder()
1252+
}
1253+
12501254
updateAttachments(value,animated)
12511255

12521256
var urlPreviewChanged:Bool

‎packages/ChatUI/Sources/ChatUI/ChatInterfaceInteraction.swift‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,12 @@ public final class ChatInteraction : InterfaceObserver {
217217

218218
public func update(animated:Bool = true, _ f:(ChatPresentationInterfaceState)->ChatPresentationInterfaceState)->Void {
219219
let oldValue = self.presentation
220-
_ = _presentation.swap(f(oldValue))
220+
var newValue = f(oldValue)
221+
if newValue.sendPaidMessageStars != oldValue.sendPaidMessageStars || newValue.peer?.id != oldValue.peer?.id {
222+
let alwaysPaidMessage = newValue.sendPaidMessageStars.flatMap { FastSettings.needConfirmPaid(newValue.peer?.id ?? peerId, price: Int($0.value)) } ?? false
223+
newValue = newValue.withUpdatedAlwaysPaidMessage(alwaysPaidMessage)
224+
}
225+
_ = _presentation.swap(newValue)
221226
if !chatHasSameDeferredSendState(oldValue, presentation) {
222227
invalidateDeferredSendActions()
223228
}

0 commit comments

Comments
 (0)