@@ -81,8 +81,8 @@ public PointOfInterestDialogBase(
8181
8282 AddDialog ( new TextPrompt ( Actions . CurrentLocationPrompt ) ) ;
8383 AddDialog ( new ConfirmPrompt ( Actions . ConfirmPrompt ) { Style = ListStyle . Auto , } ) ;
84- AddDialog ( new ChoicePrompt ( Actions . SelectPointOfInterestPrompt ) { Style = ListStyle . None } ) ;
85- AddDialog ( new ChoicePrompt ( Actions . SelectActionPrompt ) { Style = ListStyle . None } ) ;
84+ AddDialog ( new ChoicePrompt ( Actions . SelectPointOfInterestPrompt , InterruptablePromptValidator ) { Style = ListStyle . None } ) ;
85+ AddDialog ( new ChoicePrompt ( Actions . SelectActionPrompt , InterruptablePromptValidator ) { Style = ListStyle . None } ) ;
8686 AddDialog ( new ChoicePrompt ( Actions . SelectRoutePrompt ) { ChoiceOptions = new ChoiceFactoryOptions { InlineSeparator = string . Empty , InlineOr = string . Empty , InlineOrMore = string . Empty , IncludeNumbers = true } } ) ;
8787 }
8888
@@ -113,8 +113,29 @@ public static Activity CreateOpenDefaultAppReply(Activity activity, PointOfInter
113113 return replyEvent ;
114114 }
115115
116+ public override async Task < DialogTurnResult > ContinueDialogAsync ( DialogContext outerDc , CancellationToken cancellationToken = default ( CancellationToken ) )
117+ {
118+ var result = await base . ContinueDialogAsync ( outerDc , cancellationToken ) ;
119+ var state = await Accessor . GetAsync ( outerDc . Context ) ;
120+ if ( state . ShouldInterrupt )
121+ {
122+ // Assume already call CancelAllDialogsAsync
123+ // TODO Empty indicates RouteAsync in RouterDialog
124+ state . ShouldInterrupt = false ;
125+ return new DialogTurnResult ( DialogTurnStatus . Empty ) ;
126+ }
127+ else
128+ {
129+ return result ;
130+ }
131+ }
132+
116133 protected override async Task < DialogTurnResult > OnBeginDialogAsync ( DialogContext dc , object options , CancellationToken cancellationToken = default ( CancellationToken ) )
117134 {
135+ // Clear interrupt state
136+ var state = await Accessor . GetAsync ( dc . Context ) ;
137+ state . ShouldInterrupt = false ;
138+
118139 return await base . OnBeginDialogAsync ( dc , options , cancellationToken ) ;
119140 }
120141
@@ -183,6 +204,12 @@ protected async Task<DialogTurnResult> ProcessCurrentLocationSelection(Waterfall
183204 try
184205 {
185206 var state = await Accessor . GetAsync ( sc . Context ) ;
207+
208+ if ( state . ShouldInterrupt )
209+ {
210+ return await sc . CancelAllDialogsAsync ( ) ;
211+ }
212+
186213 var cancelMessage = ResponseManager . GetResponse ( POISharedResponses . CancellingMessage ) ;
187214
188215 if ( sc . Result != null )
@@ -323,6 +350,12 @@ protected async Task<DialogTurnResult> ProcessPointOfInterestSelection(Waterfall
323350 try
324351 {
325352 var state = await Accessor . GetAsync ( sc . Context ) ;
353+
354+ if ( state . ShouldInterrupt )
355+ {
356+ return await sc . CancelAllDialogsAsync ( ) ;
357+ }
358+
326359 var defaultReplyMessage = ResponseManager . GetResponse ( POISharedResponses . GetRouteToActiveLocationLater ) ;
327360
328361 if ( sc . Result != null )
@@ -404,6 +437,11 @@ protected async Task<DialogTurnResult> ProcessPointOfInterestAction(WaterfallSte
404437 {
405438 var state = await Accessor . GetAsync ( sc . Context ) ;
406439
440+ if ( state . ShouldInterrupt )
441+ {
442+ return await sc . CancelAllDialogsAsync ( ) ;
443+ }
444+
407445 var choice = sc . Result as FoundChoice ;
408446 int choiceIndex = choice . Index ;
409447
@@ -827,6 +865,33 @@ private string GetCardImageUri(string imagePath)
827865 return $ "{ serverUrl } /images/{ imagePath } ";
828866 }
829867
868+ private async Task < bool > InterruptablePromptValidator < T > ( PromptValidatorContext < T > promptContext , CancellationToken cancellationToken )
869+ {
870+ if ( promptContext . Recognized . Succeeded )
871+ {
872+ return true ;
873+ }
874+ else
875+ {
876+ var locale = CultureInfo . CurrentUICulture . TwoLetterISOLanguageName ;
877+ var localeConfig = Services . CognitiveModelSets [ locale ] ;
878+ localeConfig . LuisServices . TryGetValue ( "PointOfInterest" , out var poiService ) ;
879+ var poiResult = await poiService . RecognizeAsync < PointOfInterestLuis > ( promptContext . Context , CancellationToken . None ) ;
880+ var topIntent = poiResult . TopIntent ( ) ;
881+
882+ if ( topIntent . score > 0.5 && topIntent . intent != PointOfInterestLuis . Intent . None )
883+ {
884+ var state = await Accessor . GetAsync ( promptContext . Context ) ;
885+ state . ShouldInterrupt = true ;
886+ return true ;
887+ }
888+ else
889+ {
890+ return false ;
891+ }
892+ }
893+ }
894+
830895 private class ImageSize
831896 {
832897 public const int RouteWidth = 440 ;
0 commit comments