@@ -57,7 +57,15 @@ 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 {
61+ paidTierInfoCard ,
62+ paidTierUpgradeForm ,
63+ freeTierLimitSticky ,
64+ continueUpgradeQButton ,
65+ upgradeSuccessSticky ,
66+ upgradePendingSticky ,
67+ plansAndPricingTitle ,
68+ } from './texts/paidTier'
6169
6270export interface InboundChatApi {
6371 addChatResponse ( params : ChatResult , tabId : string , isPartialResult : boolean ) : void
@@ -87,6 +95,31 @@ const getTabPairProgrammingMode = (mynahUi: MynahUI, tabId: string) => {
8795 return promptInputOptions . find ( item => item . id === 'pair-programmer-mode' ) ?. value === 'true'
8896}
8997
98+ /** When user provides AWS account by clicking "Continue" or hitting Enter key. */
99+ function onLinkAwsAccountId (
100+ tabId : string ,
101+ messageId : string ,
102+ messager : Messager ,
103+ action : { id : string ; text ?: string ; formData ?: Record < string , string > }
104+ ) {
105+ const awsAccountId = action . formData ?. [ 'awsAccountId' ]
106+ if ( ! awsAccountId ) {
107+ return false
108+ // throw new Error(`onInBodyButtonClicked: ${continueUpgradeQButton.id} button did not provide awsAccountId`)
109+ }
110+ // HACK: emit "followUp" to send form data "outbound".
111+ const payload : FollowUpClickParams = {
112+ tabId,
113+ messageId,
114+ followUp : {
115+ pillText : awsAccountId ,
116+ type : 'awsAccountId' ,
117+ } ,
118+ }
119+ messager . onFollowUpClicked ( payload )
120+ return true
121+ }
122+
90123export const handlePromptInputChange = ( mynahUi : MynahUI , tabId : string , optionsValues : Record < string , string > ) => {
91124 const promptTypeValue = optionsValues [ 'pair-programmer-mode' ]
92125
@@ -374,7 +407,9 @@ export const createMynahUi = (
374407 messager . onInfoLinkClick ( payload )
375408 } ,
376409 onInBodyButtonClicked : ( tabId , messageId , action , eventId ) => {
377- if ( action . id === disclaimerAcknowledgeButtonId ) {
410+ if ( action . id === continueUpgradeQButton . id ) {
411+ onLinkAwsAccountId ( tabId , messageId , messager , { id : action . id , formData : action . formItemValues } )
412+ } else if ( action . id === disclaimerAcknowledgeButtonId ) {
378413 // Hide the legal disclaimer card
379414 disclaimerCardActive = false
380415
@@ -448,11 +483,20 @@ export const createMynahUi = (
448483 messager . onCreatePrompt ( action . formItemValues ! [ ContextPrompt . PromptNameFieldId ] )
449484 }
450485 } ,
451- onFormTextualItemKeyPress : ( event : KeyboardEvent , formData : Record < string , string > , itemId : string ) => {
486+ onFormTextualItemKeyPress : (
487+ event : KeyboardEvent ,
488+ formData : Record < string , string > ,
489+ itemId : string ,
490+ tabId : string ,
491+ eventId ?: string
492+ ) => {
452493 if ( itemId === ContextPrompt . PromptNameFieldId && event . key === 'Enter' ) {
453494 event . preventDefault ( )
454495 messager . onCreatePrompt ( formData [ ContextPrompt . PromptNameFieldId ] )
455496 return true
497+ } else if ( itemId === 'awsAccountId' && event . key === 'Enter' ) {
498+ event . preventDefault ( )
499+ return onLinkAwsAccountId ( tabId , '' , messager , { id : continueUpgradeQButton . id , formData : formData } )
456500 }
457501 return false
458502 } ,
@@ -839,34 +883,102 @@ export const createMynahUi = (
839883 * Shows a message if the user reaches free-tier limit.
840884 * Shows a message if the user just upgraded to paid-tier.
841885 */
842- const onPaidTierModeChange = (
843- tabId : string ,
844- mode : 'paidtier' | 'paidtier-success' | 'freetier' | 'freetier-limit'
845- ) => {
846- if ( ! [ 'paidtier' , 'paidtier-success' , 'freetier' , 'freetier-limit' ] . includes ( mode ) ) {
847- return // invalid mode
886+ const onPaidTierModeChange = ( tabId : string , mode : string | undefined ) => {
887+ if (
888+ ! mode ||
889+ ! [
890+ 'freetier' ,
891+ 'freetier-limit' ,
892+ 'freetier-upgrade-info' ,
893+ 'upgrade-start' ,
894+ 'upgrade-pending' ,
895+ 'paidtier' ,
896+ ] . includes ( mode )
897+ ) {
898+ return false // invalid mode
848899 }
849900
850- tabId = tabId !== '' ? tabId : getOrCreateTabId ( ) !
901+ tabId = ! ! tabId ? tabId : getOrCreateTabId ( ) !
902+
903+ // Detect if the tab is already showing the "Upgrade Q" UI.
904+ const isFreeTierLimitUi =
905+ mynahUi . getTabData ( tabId ) ?. getStore ( ) ?. promptInputStickyCard ?. messageId === freeTierLimitSticky . messageId
906+ const isUpgradePendingUi =
907+ mynahUi . getTabData ( tabId ) ?. getStore ( ) ?. promptInputStickyCard ?. messageId === upgradePendingSticky . messageId
908+ const isPlansAndPricingTab = plansAndPricingTitle === mynahUi . getTabData ( tabId ) . getStore ( ) ?. tabTitle
909+
910+ if ( mode === 'freetier-limit' ) {
911+ mynahUi . updateStore ( tabId , {
912+ promptInputStickyCard : freeTierLimitSticky ,
913+ } )
851914
852- // Detect if the tab is already showing the "Upgrade Q" calls-to-action.
853- const didShowLimitReached = mynahUi . getTabData ( tabId ) ?. getStore ( ) ?. promptInputButtons ?. [ 0 ] === upgradeQButton
854- if ( mode === 'freetier-limit' && ! didShowLimitReached ) {
855- mynahUi . addChatItem ( tabId , freeTierLimitReachedCard )
856- } else if ( mode === 'paidtier-success' ) {
857- mynahUi . addChatItem ( tabId , paidTierSuccessCard )
915+ if ( ! isFreeTierLimitUi ) {
916+ // Avoid duplicate "limit reached" cards.
917+ // REMOVED: don't want the "card", just use the "banner" only.
918+ // mynahUi.addChatItem(tabId, freeTierLimitCard)
919+ }
920+ } else if ( mode === 'freetier-upgrade-info' ) {
921+ mynahUi . addChatItem ( tabId , paidTierInfoCard )
922+ } else if ( mode === 'upgrade-start' ) {
923+ // Show the "Upgrade" form in its own tab.
924+ const newTabId = createTabId ( ) ?? tabId
925+ mynahUi . updateStore ( newTabId , {
926+ tabTitle : plansAndPricingTitle ,
927+ chatItems : [ ] , // Clear the tab.
928+ promptInputDisabledState : true , // This special tab is not a "chat" tab.
929+ promptInputButtons : [ ] ,
930+ promptInputOptions : [ ] ,
931+ promptInputPlaceholder : '' ,
932+ promptInputVisible : false ,
933+ } )
934+ mynahUi . addChatItem ( newTabId , paidTierUpgradeForm )
935+ // openTab('upgrade-start', { tabId: 'upgrade-start' })
936+ } else if ( mode === 'upgrade-pending' ) {
937+ // Change the sticky banner to show a progress spinner.
938+ const card : typeof freeTierLimitSticky = {
939+ ...( isFreeTierLimitUi ? freeTierLimitSticky : upgradePendingSticky ) ,
940+ icon : 'progress' ,
941+ }
942+ mynahUi . updateStore ( tabId , {
943+ // Show a progress ribbon.
944+ promptInputVisible : true ,
945+ promptInputProgress : {
946+ status : 'default' ,
947+ text : 'Waiting for subscription status...' ,
948+ value : - 1 , // infinite
949+ // valueText: 'Waiting 2...',
950+ } ,
951+ promptInputStickyCard : isFreeTierLimitUi ? card : null ,
952+ } )
953+ } else if ( mode === 'paidtier' ) {
954+ mynahUi . updateStore ( tabId , {
955+ promptInputStickyCard : null ,
956+ promptInputProgress : null ,
957+ promptInputVisible : ! isPlansAndPricingTab ,
958+ } )
959+ if ( isFreeTierLimitUi || isUpgradePendingUi || isPlansAndPricingTab ) {
960+ // Transitioning from 'upgrade-pending' to upgrade success.
961+ const card : typeof upgradeSuccessSticky = {
962+ ...upgradeSuccessSticky ,
963+ canBeDismissed : ! isPlansAndPricingTab ,
964+ }
965+ mynahUi . updateStore ( tabId , {
966+ promptInputStickyCard : card ,
967+ } )
968+ }
858969 }
859970
860971 mynahUi . updateStore ( tabId , {
861- promptInputButtons : mode === 'freetier-limit' ? [ upgradeQButton ] : [ ] ,
862- promptInputDisabledState : mode === 'freetier-limit' ,
972+ // promptInputButtons: mode === 'freetier-limit' ? [upgradeQButton] : [],
973+ // promptInputDisabledState: mode === 'freetier-limit',
863974 } )
975+
976+ return true
864977 }
865978
866979 const updateChat = ( params : ChatUpdateParams ) => {
867980 // HACK: Special field sent by `agenticChatController.ts:setPaidTierMode()`.
868- if ( ( params as any ) . paidTierMode ) {
869- onPaidTierModeChange ( params . tabId , ( params as any ) . paidTierMode as any )
981+ if ( onPaidTierModeChange ( params . tabId , ( params as any ) . paidTierMode as string ) ) {
870982 return
871983 }
872984
0 commit comments