Пример #1
0
        /// <summary>
        /// Once we have a setting we need to process the corresponding value.
        /// </summary>
        /// <param name="sc">Step Context.</param>
        /// <returns>Dialog Turn Result.</returns>
        private async Task <DialogTurnResult> ProcessVehicleSettingsChange(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            var state = await Accessor.GetAsync(sc.Context);

            if (state.Changes.Any())
            {
                var settingValues = state.GetUniqueSettingValues();
                if (!settingValues.Any())
                {
                    // This shouldn't happen because the SettingFilter would just add all possible values to let the user select from them.
                    await sc.Context.SendActivityAsync(ResponseManager.GetResponse(VehicleSettingsResponses.VehicleSettingsMissingSettingValue));

                    return(await sc.EndDialogAsync());
                }
                else
                {
                    // We have found multiple setting values, which we need to prompt the user to resolve
                    if (settingValues.Count() > 1)
                    {
                        var settingName = state.Changes.First().SettingName;
                        var setting     = this.settingList.FindSetting(settingName);

                        // If an image filename is provided we'll use it otherwise fall back to the generic car one
                        var imageName = setting.ImageFileName ?? FallbackSettingImageFileName;

                        // If we have more than one setting value matching, prompt the user to choose
                        var options = new PromptOptions()
                        {
                            Choices = new List <Choice>(),
                        };

                        for (var i = 0; i < settingValues.Count; ++i)
                        {
                            var item     = settingValues[i];
                            var synonyms = new List <string>
                            {
                                item,
                                (i + 1).ToString()
                            };
                            synonyms.AddRange(settingList.GetAlternativeNamesForSettingValue(settingName, item));
                            var choice = new Choice()
                            {
                                Value    = item,
                                Synonyms = synonyms,
                            };
                            options.Choices.Add(choice);
                        }

                        var promptReplacements = new StringDictionary {
                            { "settingName", settingName }
                        };
                        var cardModel = new AutomotiveCardModel()
                        {
                            ImageUrl = GetSettingCardImageUri(imageName)
                        };

                        var card = new Card(GetDivergedCardName(sc.Context, "AutomotiveCard"), cardModel);

                        options.Prompt = ResponseManager.GetCardResponse(VehicleSettingsResponses.VehicleSettingsSettingValueSelection, card, promptReplacements);

                        // Default Text property is clumsy for speech
                        options.Prompt.Speak = SpeechUtility.ListToSpeechReadyString(options.Prompt);

                        // Workaround. In teams, prompt will be changed to HeroCard and adaptive card could not be shown. So send them separatly
                        if (Channel.GetChannelId(sc.Context) == Channels.Msteams)
                        {
                            await sc.Context.SendActivityAsync(options.Prompt);

                            options.Prompt = null;
                        }

                        return(await sc.PromptAsync(Actions.SettingValueSelectionPrompt, options));
                    }
                    else
                    {
                        // We only have one setting value so proceed to next step
                        return(await sc.NextAsync());
                    }
                }
            }
            else
            {
                // No setting value was understood
                await sc.Context.SendActivityAsync(ResponseManager.GetResponse(VehicleSettingsResponses.VehicleSettingsOutOfDomain));

                return(await sc.EndDialogAsync());
            }
        }
Пример #2
0
        /// <summary>
        /// Once we have a setting we need to process the corresponding value.
        /// </summary>
        /// <param name="sc">Step Context.</param>
        /// <returns>Dialog Turn Result.</returns>
        private async Task <DialogTurnResult> ProcessVehicleSettingsChange(WaterfallStepContext sc, CancellationToken cancellationToken = default(CancellationToken))
        {
            var state = await Accessor.GetAsync(sc.Context);

            if (state.Changes.Any())
            {
                var settingValues = state.GetUniqueSettingValues();
                if (!settingValues.Any())
                {
                    // This shouldn't happen because the SettingFilter would just add all possible values to let the user select from them.
                    await sc.Context.SendActivityAsync(ResponseManager.GetResponse(VehicleSettingsResponses.VehicleSettingsMissingSettingValue));

                    return(await sc.EndDialogAsync());
                }
                else
                {
                    // We have found multiple setting values, which we need to prompt the user to resolve
                    if (settingValues.Count() > 1)
                    {
                        string settingName = state.Changes.First().SettingName;
                        var    setting     = this.settingList.FindSetting(settingName);

                        // If an image filename is provided we'll use it otherwise fall back to the generic car one
                        string imageName = setting.ImageFileName ?? FallbackSettingImageFileName;

                        // If we have more than one setting value matching, prompt the user to choose
                        var options = new PromptOptions()
                        {
                            Choices = new List <Choice>(),
                        };

                        for (var i = 0; i < settingValues.Count; ++i)
                        {
                            var           item     = settingValues[i];
                            List <string> synonyms = new List <string>();
                            synonyms.Add(item);
                            synonyms.Add((i + 1).ToString());
                            synonyms.AddRange(settingList.GetAlternativeNamesForSettingValue(settingName, item));
                            var choice = new Choice()
                            {
                                Value    = item,
                                Synonyms = synonyms,
                            };
                            options.Choices.Add(choice);
                        }

                        var promptReplacements = new StringDictionary {
                            { "settingName", settingName }
                        };
                        options.Prompt = ResponseManager.GetResponse(VehicleSettingsResponses.VehicleSettingsSettingValueSelection, promptReplacements);

                        var card = new ThumbnailCard
                        {
                            Text   = options.Prompt.Text,
                            Images = new List <CardImage> {
                                new CardImage(GetSettingCardImageUri(imageName))
                            },
                            Buttons = options.Choices.Select(choice =>
                                                             new CardAction(ActionTypes.ImBack, choice.Value, value: choice.Value)).ToList(),
                        };

                        options.Prompt.Attachments.Add(card.ToAttachment());

                        // Default Text property is clumsy for speech
                        options.Prompt.Speak = $"{options.Prompt.Text} {GetSpeakableOptions(options.Choices)}";

                        return(await sc.PromptAsync(Actions.SettingValueSelectionPrompt, options));
                    }
                    else
                    {
                        // We only have one setting value so proceed to next step
                        return(await sc.NextAsync());
                    }
                }
            }
            else
            {
                // No setting value was understood
                await sc.Context.SendActivityAsync(ResponseManager.GetResponse(VehicleSettingsResponses.VehicleSettingsOutOfDomain));

                return(await sc.EndDialogAsync());
            }
        }