@@ -57,7 +57,7 @@ import {
5757} from './utils'
5858import { ChatHistory , ChatHistoryList } from './features/history'
5959import { pairProgrammingModeOff , pairProgrammingModeOn , programmerModeCard } from './texts/pairProgramming'
60- import { paidTierSuccessCard , freeTierLimitReachedCard , upgradeQButton } from './texts/paidTier'
60+ import { paidTierSuccessCard , freeTierLimitCard , freeTierLimitStickyCard } from './texts/paidTier'
6161
6262export interface InboundChatApi {
6363 addChatResponse ( params : ChatResult , tabId : string , isPartialResult : boolean ) : void
@@ -827,34 +827,65 @@ export const createMynahUi = (
827827 * Shows a message if the user reaches free-tier limit.
828828 * Shows a message if the user just upgraded to paid-tier.
829829 */
830- const onPaidTierModeChange = (
831- tabId : string ,
832- mode : 'paidtier' | 'paidtier-success' | 'freetier' | 'freetier-limit'
833- ) => {
834- if ( ! [ 'paidtier' , 'paidtier-success' , 'freetier' , 'freetier-limit' ] . includes ( mode ) ) {
835- return // invalid mode
830+ const onPaidTierModeChange = ( tabId : string , mode : string | undefined ) => {
831+ if ( ! mode || ! [ 'freetier' , 'freetier-limit' , 'freetier-upgrade-pending' , 'paidtier' ] . includes ( mode ) ) {
832+ return false // invalid mode
836833 }
837834
838835 tabId = tabId !== '' ? tabId : getOrCreateTabId ( ) !
839836
840- // Detect if the tab is already showing the "Upgrade Q" calls-to-action.
841- const didShowLimitReached = mynahUi . getTabData ( tabId ) ?. getStore ( ) ?. promptInputButtons ?. [ 0 ] === upgradeQButton
842- if ( mode === 'freetier-limit' && ! didShowLimitReached ) {
843- mynahUi . addChatItem ( tabId , freeTierLimitReachedCard )
844- } else if ( mode === 'paidtier-success' ) {
845- mynahUi . addChatItem ( tabId , paidTierSuccessCard )
837+ // Detect if the tab is already showing the "Upgrade Q" UI.
838+ const isFreeTierLimitUi =
839+ mynahUi . getTabData ( tabId ) ?. getStore ( ) ?. promptInputStickyCard ?. messageId ===
840+ freeTierLimitStickyCard . messageId
841+
842+ if ( mode === 'freetier-limit' ) {
843+ mynahUi . updateStore ( tabId , {
844+ promptInputStickyCard : freeTierLimitStickyCard ,
845+ } )
846+
847+ if ( ! isFreeTierLimitUi ) {
848+ // Avoid duplicate "limit reached" cards.
849+ mynahUi . addChatItem ( tabId , freeTierLimitCard )
850+ }
851+ } else if ( mode === 'freetier-upgrade-pending' ) {
852+ // Change the sticky banner to show a progress spinner.
853+ const card : typeof freeTierLimitStickyCard = {
854+ ...freeTierLimitStickyCard ,
855+ icon : 'progress' ,
856+ }
857+ mynahUi . updateStore ( tabId , {
858+ // Show a progress ribbon.
859+ promptInputProgress : {
860+ status : 'default' ,
861+ text : 'Waiting for subscription status...' ,
862+ value : - 1 , // infinite
863+ // valueText: 'Waiting 2...',
864+ } ,
865+ promptInputStickyCard : card ,
866+ } )
867+ } else if ( mode === 'paidtier' ) {
868+ mynahUi . updateStore ( tabId , {
869+ promptInputStickyCard : null ,
870+ promptInputProgress : null ,
871+ } )
872+ if ( isFreeTierLimitUi ) {
873+ // Avoid duplicate "success" cards.
874+ mynahUi . addChatItem ( tabId , paidTierSuccessCard )
875+ }
846876 }
847877
848878 mynahUi . updateStore ( tabId , {
849- promptInputButtons : mode === 'freetier-limit' ? [ upgradeQButton ] : [ ] ,
879+ // promptInputButtons: mode === 'freetier-limit' ? [upgradeQButton] : [],
850880 promptInputDisabledState : mode === 'freetier-limit' ,
851881 } )
882+
883+ return true
852884 }
853885
854886 const updateChat = ( params : ChatUpdateParams ) => {
855887 // HACK: Special field sent by `agenticChatController.ts:setPaidTierMode()`.
856- if ( ( params as any ) . paidTierMode ) {
857- onPaidTierModeChange ( params . tabId , ( params as any ) . paidTierMode as any )
888+ if ( onPaidTierModeChange ( params . tabId , ( params as any ) . paidTierMode as string ) ) {
858889 return
859890 }
860891
0 commit comments