/// <summary>
        /// Search for, and show details related to a single trip, if the trip can be
        /// found. This demonstrates a simple response flow in Cortana.
        /// </summary>
        /// <param name="destination">The destination, expected to be in the phrase list.</param>
        /// <returns></returns>
        private async Task SendCompletionMessageForDestination(string destination)
        {
            // If this operation is expected to take longer than 0.5 seconds, the task must
            // provide a progress response to Cortana prior to starting the operation, and
            // provide updates at most every 5 seconds.
            string loadingTripToDestination = string.Format(
                       cortanaResourceMap.GetValue("LoadingTripToDestination", cortanaContext).ValueAsString,
                       destination);
            await ShowProgressScreen(loadingTripToDestination);
            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // Look for the specified trip. The destination *should* be pulled from the grammar we
            // provided, and the subsequently updated phrase list, so it should be a 1:1 match, including case.
            // However, we might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable<Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

            var userMessage = new VoiceCommandUserMessage();
            var destinationsContentTiles = new List<VoiceCommandContentTile>();
            if (trips.Count() == 0)
            {
                // In this scenario, perhaps someone has modified data on your service outside of your 
                // control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                string foundNoTripToDestination = string.Format(
                       cortanaResourceMap.GetValue("FoundNoTripToDestination", cortanaContext).ValueAsString,
                       destination);
                userMessage.DisplayMessage = foundNoTripToDestination;
                userMessage.SpokenMessage = foundNoTripToDestination;
            }
            else
            {
                // Set a title message for the page.
                string message = "";
                if (trips.Count() > 1)
                {
                    message = cortanaResourceMap.GetValue("PluralUpcomingTrips", cortanaContext).ValueAsString;
                }
                else
                {
                    message = cortanaResourceMap.GetValue("SingularUpcomingTrip", cortanaContext).ValueAsString;
                }
                userMessage.DisplayMessage = message;
                userMessage.SpokenMessage = message;

                // file in tiles for each destination, to display information about the trips without
                // launching the app.
                foreach (Model.Trip trip in trips)
                {
                    int i = 1;
                    
                    var destinationTile = new VoiceCommandContentTile();

                    // To handle UI scaling, Cortana automatically looks up files with FileName.scale-<n>.ext formats based on the requested filename.
                    // See the VoiceCommandService\Images folder for an example.
                    destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
                    destinationTile.Image = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///AdventureWorks.VoiceCommands/Images/GreyTile.png"));

                    destinationTile.AppLaunchArgument = string.Format("destination={0}", trip.Destination);
                    destinationTile.Title = trip.Destination;
                    if (trip.StartDate != null)
                    {
                        destinationTile.TextLine1 = trip.StartDate.Value.ToString(dateFormatInfo.LongDatePattern);
                    }
                    else
                    {
                        destinationTile.TextLine1 = trip.Destination + " " + i;
                    }

                    destinationsContentTiles.Add(destinationTile);
                    i++;
                }
            }

            var response = VoiceCommandResponse.CreateResponse(userMessage, destinationsContentTiles);

            if (trips.Count() > 0)
            {
                response.AppLaunchArgument = string.Format("destination={0}", destination);
            }

            await voiceServiceConnection.ReportSuccessAsync(response);
        }
        /// <summary>
        /// Handle the Trip Cancellation task. This task demonstrates how to prompt a user
        /// for confirmation of an operation, show users a progress screen while performing
        /// a long-running task, and showing a completion screen.
        /// </summary>
        /// <param name="destination">The name of a destination, expected to match the phrase list.</param>
        /// <returns></returns>
        private async Task SendCompletionMessageForCancellation(string destination)
        {
            // Begin loading data to search for the target store. If this operation is going to take a long time,
            // for instance, requiring a response from a remote web service, consider inserting a progress screen 
            // here, in order to prevent Cortana from timing out. 
            string progressScreenString = string.Format(
                cortanaResourceMap.GetValue("ProgressLookingForTripToDest", cortanaContext).ValueAsString,
                destination);
            await ShowProgressScreen(progressScreenString);

            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // We might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable<Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);
            Model.Trip trip = null;
            if (trips.Count() > 1)
            {
                // If there is more than one trip, provide a disambiguation screen rather than just picking one
                // however, more advanced logic here might be ideal (ie, if there's a significant number of items,
                // you may want to just fall back to a link to your app where you can provide a deeper search experience.
                string disambiguationDestinationString = string.Format(
                    cortanaResourceMap.GetValue("DisambiguationWhichTripToDest", cortanaContext).ValueAsString,
                    destination);
                string disambiguationRepeatString = cortanaResourceMap.GetValue("DisambiguationRepeat", cortanaContext).ValueAsString;
                trip = await DisambiguateTrips(trips, disambiguationDestinationString, disambiguationRepeatString);
            }
            else
            {
                // One or no trips exist with that destination, so retrieve it, or return null.
                trip = trips.FirstOrDefault();
            }

            var userPrompt = new VoiceCommandUserMessage();
            
            VoiceCommandResponse response;
            if (trip == null)
            {
                var userMessage = new VoiceCommandUserMessage();
                // In this scenario, perhaps someone has modified data on your service outside of this 
                // apps control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                string noSuchTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("NoSuchTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userMessage.DisplayMessage = userMessage.SpokenMessage = noSuchTripToDestination;

                response = VoiceCommandResponse.CreateResponse(userMessage);
                await voiceServiceConnection.ReportSuccessAsync(response);
            }
            else
            {
                // Prompt the user for confirmation that we've selected the correct trip to cancel.
                string cancelTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("CancelTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userPrompt.DisplayMessage = userPrompt.SpokenMessage = cancelTripToDestination;
                var userReprompt = new VoiceCommandUserMessage();
                string confirmCancelTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("ConfirmCancelTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userReprompt.DisplayMessage = userReprompt.SpokenMessage = confirmCancelTripToDestination;
                
                response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt);

                var voiceCommandConfirmation = await voiceServiceConnection.RequestConfirmationAsync(response);

                // If RequestConfirmationAsync returns null, Cortana's UI has likely been dismissed.
                if (voiceCommandConfirmation != null)
                {
                    if (voiceCommandConfirmation.Confirmed == true)
                    {
                        string cancellingTripToDestination = string.Format(
                       cortanaResourceMap.GetValue("CancellingTripToDestination", cortanaContext).ValueAsString,
                       destination);
                        await ShowProgressScreen(cancellingTripToDestination);

                        // Perform the operation to remote the trip from the app's data. 
                        // Since the background task runs within the app package of the installed app,
                        // we can access local files belonging to the app without issue.
                        await store.DeleteTrip(trip);

                        // Provide a completion message to the user.
                        var userMessage = new VoiceCommandUserMessage();
                        string cancelledTripToDestination = string.Format(
                            cortanaResourceMap.GetValue("CancelledTripToDestination", cortanaContext).ValueAsString,
                            destination);
                        userMessage.DisplayMessage = userMessage.SpokenMessage = cancelledTripToDestination;
                        response = VoiceCommandResponse.CreateResponse(userMessage);
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                    else
                    {
                        // Confirm no action for the user.
                        var userMessage = new VoiceCommandUserMessage();
                        string keepingTripToDestination = string.Format(
                            cortanaResourceMap.GetValue("KeepingTripToDestination", cortanaContext).ValueAsString,
                            destination);
                        userMessage.DisplayMessage = userMessage.SpokenMessage = keepingTripToDestination;

                        response = VoiceCommandResponse.CreateResponse(userMessage);
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                }
            }
        }
Esempio n. 3
0
        private async Task LoadingTripToDestination(string destination)
        {
            // If this operation is expected to take longer than 0.5 seconds, the task must
            // provide a progress response to Cortana prior to starting the operation, and
            // provide updates at most every 5 seconds.
            string loadingTripToDestination = string.Format(
                cortanaResourceMap.GetValue("LoadingTripToDestination", cortanaContext).ValueAsString,
                destination);

            await ShowProgressScreen(loadingTripToDestination);

            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // Look for the specified trip. The destination *should* be pulled from the grammar we
            // provided, and the subsequently updated phrase list, so it should be a 1:1 match, including case.
            // However, we might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable <Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

            var userMessage = new VoiceCommandUserMessage();
            var destinationsContentTiles = new List <VoiceCommandContentTile>();

            if (trips.Count() == 0)
            {
                // In this scenario, perhaps someone has modified data on your service outside of your
                // control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                string foundNoTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("FoundNoTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userMessage.DisplayMessage = foundNoTripToDestination;
                userMessage.SpokenMessage  = foundNoTripToDestination;
            }
            else
            {
                // Set a title message for the page.
                string message = "";
                if (trips.Count() > 1)
                {
                    message = cortanaResourceMap.GetValue("PluralUpcomingTrips", cortanaContext).ValueAsString;
                }
                else
                {
                    message = cortanaResourceMap.GetValue("SingularUpcomingTrip", cortanaContext).ValueAsString;
                }
                userMessage.DisplayMessage = message;
                userMessage.SpokenMessage  = message;

                // file in tiles for each destination, to display information about the trips without
                // launching the app.
                foreach (Model.Trip trip in trips)
                {
                    int i = 1;

                    var destinationTile = new VoiceCommandContentTile();

                    // To handle UI scaling, Cortana automatically looks up files with FileName.scale-<n>.ext formats based on the requested filename.
                    // See the VoiceCommandService\Images folder for an example.
                    destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
                    destinationTile.Image           = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///ListenApp.VoiceCommands/Images/GreyTile.png"));

                    destinationTile.AppLaunchArgument = trip.Destination;
                    destinationTile.Title             = trip.Destination;
                    if (trip.StartDate != null)
                    {
                        destinationTile.TextLine1 = trip.StartDate.Value.ToString(dateFormatInfo.LongDatePattern);
                    }
                    else
                    {
                        destinationTile.TextLine1 = trip.Destination + " " + i;
                    }

                    destinationsContentTiles.Add(destinationTile);
                    i++;
                }
            }

            var response = VoiceCommandResponse.CreateResponse(userMessage, destinationsContentTiles);

            if (trips.Count() > 0)
            {
                response.AppLaunchArgument = destination;
            }

            await voiceServiceConnection.ReportSuccessAsync(response);
        }
        /// <summary>
        /// Handle the Trip Cancellation task. This task demonstrates how to prompt a user
        /// for confirmation of an operation, show users a progress screen while performing
        /// a long-running task, and showing a completion screen.
        /// </summary>
        /// <param name="destination">The name of a destination, expected to match the phrase list.</param>
        /// <returns></returns>
        private async Task SendCompletionMessageForCancellation(string destination)
        {
            // Begin loading data to search for the target store. If this operation is going to take a long time,
            // for instance, requiring a response from a remote web service, consider inserting a progress screen
            // here, in order to prevent Cortana from timing out.
            string progressScreenString = string.Format(
                cortanaResourceMap.GetValue("ProgressLookingForTripToDest", cortanaContext).ValueAsString,
                destination);

            await ShowProgressScreen(progressScreenString);

            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // We might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable <Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

            Model.Trip trip = null;
            if (trips.Count() > 1)
            {
                // If there is more than one trip, provide a disambiguation screen rather than just picking one
                // however, more advanced logic here might be ideal (ie, if there's a significant number of items,
                // you may want to just fall back to a link to your app where you can provide a deeper search experience.
                string disambiguationDestinationString = string.Format(
                    cortanaResourceMap.GetValue("DisambiguationWhichTripToDest", cortanaContext).ValueAsString,
                    destination);
                string disambiguationRepeatString = cortanaResourceMap.GetValue("DisambiguationRepeat", cortanaContext).ValueAsString;
                trip = await DisambiguateTrips(trips, disambiguationDestinationString, disambiguationRepeatString);
            }
            else
            {
                // One or no trips exist with that destination, so retrieve it, or return null.
                trip = trips.FirstOrDefault();
            }

            var userPrompt = new VoiceCommandUserMessage();

            VoiceCommandResponse response;

            if (trip == null)
            {
                var userMessage = new VoiceCommandUserMessage();
                // In this scenario, perhaps someone has modified data on your service outside of this
                // apps control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                string noSuchTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("NoSuchTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userMessage.DisplayMessage = userMessage.SpokenMessage = noSuchTripToDestination;

                response = VoiceCommandResponse.CreateResponse(userMessage);
                await voiceServiceConnection.ReportSuccessAsync(response);
            }
            else
            {
                // Prompt the user for confirmation that we've selected the correct trip to cancel.
                string cancelTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("CancelTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userPrompt.DisplayMessage = userPrompt.SpokenMessage = cancelTripToDestination;
                var    userReprompt = new VoiceCommandUserMessage();
                string confirmCancelTripToDestination = string.Format(
                    cortanaResourceMap.GetValue("ConfirmCancelTripToDestination", cortanaContext).ValueAsString,
                    destination);
                userReprompt.DisplayMessage = userReprompt.SpokenMessage = confirmCancelTripToDestination;

                //REVERT

                var cancelledContentTiles = new List <VoiceCommandContentTile>();
                if (xyz != null)
                {
                    cancelledContentTiles.Add(xyz);
                }
                response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt, cancelledContentTiles);

                var voiceCommandConfirmation = await voiceServiceConnection.RequestConfirmationAsync(response);

                // If RequestConfirmationAsync returns null, Cortana's UI has likely been dismissed.
                if (voiceCommandConfirmation != null)
                {
                    if (voiceCommandConfirmation.Confirmed == true)
                    {
                        string cancellingTripToDestination = string.Format(
                            cortanaResourceMap.GetValue("CancellingTripToDestination", cortanaContext).ValueAsString,
                            destination);
                        await ShowProgressScreen(cancellingTripToDestination);

                        // Perform the operation to remote the trip from the app's data.
                        // Since the background task runs within the app package of the installed app,
                        // we can access local files belonging to the app without issue.
                        await store.DeleteTrip(trip);

                        // Provide a completion message to the user.
                        var    userMessage = new VoiceCommandUserMessage();
                        string cancelledTripToDestination = string.Format(
                            cortanaResourceMap.GetValue("CancelledTripToDestination", cortanaContext).ValueAsString,
                            destination);
                        userMessage.DisplayMessage = userMessage.SpokenMessage = cancelledTripToDestination;

                        response = VoiceCommandResponse.CreateResponse(userMessage, cancelledContentTiles); //REVERT cancelledContentTiles
                        response.AppLaunchArgument = destination;                                           //REVERT
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                    else
                    {
                        // Confirm no action for the user.
                        var    userMessage = new VoiceCommandUserMessage();
                        string keepingTripToDestination = string.Format(
                            cortanaResourceMap.GetValue("KeepingTripToDestination", cortanaContext).ValueAsString,
                            destination);
                        userMessage.DisplayMessage = userMessage.SpokenMessage = keepingTripToDestination;

                        response = VoiceCommandResponse.CreateResponse(userMessage);
                        response.AppLaunchArgument = destination; //REVERT
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                }
            }
        }
        /// <summary>
        /// Search for, and show details related to a single trip, if the trip can be
        /// found. This demonstrates a simple response flow in Cortana.
        /// </summary>
        /// <param name="destination">The destination, expected to be in the phrase list.</param>
        /// <returns></returns>
        private async Task SendCompletionMessageForDestination(string destination)
        {
            // If this operation is expected to take longer than 0.5 seconds, the task must
            // provide a progress response to Cortana prior to starting the operation, and
            // provide updates at most every 5 seconds.
            await ShowProgressScreen("Adventure Works is loading details about trip to " + destination);

            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // Look for the specified trip. The destination *should* be pulled from the grammar we
            // provided, and the subsequently updated phrase list, so it should be a 1:1 match, including case.
            // However, we might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable <Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

            var userMessage = new VoiceCommandUserMessage();
            var destinationsContentTiles = new List <VoiceCommandContentTile>();

            if (trips.Count() == 0)
            {
                // In this scenario, perhaps someone has modified data on your service outside of your
                // control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                userMessage.DisplayMessage = "Sorry, you don't have any trips to " + destination;
                userMessage.SpokenMessage  = "Sorry, you don't have any trips to " + destination;
            }
            else
            {
                // Set a title message for the page.
                string message = "";
                if (trips.Count() > 1)
                {
                    message = "Here are your upcoming trips.";
                }
                else
                {
                    message = "Here's your upcoming trip.";
                }
                userMessage.DisplayMessage = message;
                userMessage.SpokenMessage  = message;

                // file in tiles for each destination, to display information about the trips without
                // launching the app.
                foreach (Model.Trip trip in trips)
                {
                    int i = 1;

                    var destinationTile = new VoiceCommandContentTile();

                    destinationTile.ContentTileType = VoiceCommandContentTileType.TitleWith68x68IconAndText;
                    destinationTile.Image           = await Package.Current.InstalledLocation.GetFileAsync("AdventureWorks.VoiceCommands\\Images\\GreyTile.png");

                    destinationTile.AppLaunchArgument = string.Format("destination={0}", trip.Destination);
                    destinationTile.Title             = trip.Destination;
                    if (trip.StartDate != null)
                    {
                        destinationTile.TextLine1 =
                            string.Format("{0:dddd MMMM dd yyyy}",
                                          trip.StartDate
                                          );
                    }
                    else
                    {
                        destinationTile.TextLine1 = trip.Destination + " " + i;
                    }

                    destinationsContentTiles.Add(destinationTile);
                    i++;
                }
            }

            var response = VoiceCommandResponse.CreateResponse(userMessage, destinationsContentTiles);

            if (trips.Count() > 0)
            {
                response.AppLaunchArgument = string.Format("destination={0}", destination);
            }

            await voiceServiceConnection.ReportSuccessAsync(response);
        }
        /// <summary>
        /// Handle the Trip Cancellation task. This task demonstrates how to prompt a user
        /// for confirmation of an operation, show users a progress screen while performing
        /// a long-running task, and showing a completion screen.
        /// </summary>
        /// <param name="destination">The name of a destination, expected to match the phrase list.</param>
        /// <returns></returns>
        private async Task SendCompletionMessageForCancellation(string destination)
        {
            // Begin loading data to search for the target store. If this operation is going to take a long time,
            // for instance, requiring a response from a remote web service, consider inserting a progress screen
            // here, in order to prevent Cortana from timing out.
            await ShowProgressScreen("Looking for a trip to " + destination);

            Model.TripStore store = new Model.TripStore();
            await store.LoadTrips();

            // We might have multiple trips to the destination. For now, we just pick the first.
            IEnumerable <Model.Trip> trips = store.Trips.Where(p => p.Destination == destination);

            Model.Trip trip = null;
            if (trips.Count() > 1)
            {
                // If there is more than one trip, provide a disambiguation screen rather than just picking one
                // however, more advanced logic here might be ideal (ie, if there's a significant number of items,
                // you may want to just fall back to a link to your app where you can provide a deeper search experience.
                trip = await DisambiguateTrips(
                    trips,
                    "Which trip to " + destination + " did you want to cancel?",
                    "Which one do you want to cancel?");
            }
            else
            {
                // One or no trips exist with that destination, so retrieve it, or return null.
                trip = trips.FirstOrDefault();
            }

            var userPrompt = new VoiceCommandUserMessage();

            VoiceCommandResponse response;

            if (trip == null)
            {
                var userMessage = new VoiceCommandUserMessage();
                // In this scenario, perhaps someone has modified data on your service outside of this
                // apps control. If you're accessing a remote service, having a background task that
                // periodically refreshes the phrase list so it's likely to be in sync is ideal.
                // This is unlikely to occur for this sample app, however.
                userMessage.DisplayMessage = userMessage.SpokenMessage = "Sorry, you don't have any trips to " + destination;

                response = VoiceCommandResponse.CreateResponse(userMessage);
                await voiceServiceConnection.ReportSuccessAsync(response);
            }
            else
            {
                // Prompt the user for confirmation that we've selected the correct trip to cancel.
                userPrompt.DisplayMessage = userPrompt.SpokenMessage = "Cancel this trip to " + destination + "?";
                var userReprompt = new VoiceCommandUserMessage();
                userReprompt.DisplayMessage = userReprompt.SpokenMessage = "Did you want to cancel this trip to " + destination + "?";

                response = VoiceCommandResponse.CreateResponseForPrompt(userPrompt, userReprompt);

                var voiceCommandConfirmation = await voiceServiceConnection.RequestConfirmationAsync(response);

                // If RequestConfirmationAsync returns null, Cortana's UI has likely been dismissed.
                if (voiceCommandConfirmation != null)
                {
                    if (voiceCommandConfirmation.Confirmed == true)
                    {
                        await ShowProgressScreen("Cancelling the trip to " + destination);

                        // Perform the operation to remote the trip from the app's data.
                        // Since the background task runs within the app package of the installed app,
                        // we can access local files belonging to the app without issue.
                        await store.DeleteTrip(trip);

                        // Provide a completion message to the user.
                        var userMessage = new VoiceCommandUserMessage();
                        userMessage.DisplayMessage = userMessage.SpokenMessage = "Cancelled the trip to " + destination;
                        response = VoiceCommandResponse.CreateResponse(userMessage);
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                    else
                    {
                        // Confirm no action for the user.
                        var userMessage = new VoiceCommandUserMessage();
                        userMessage.DisplayMessage = userMessage.SpokenMessage = "Okay, Keeping the trip to " + destination;

                        response = VoiceCommandResponse.CreateResponse(userMessage);
                        await voiceServiceConnection.ReportSuccessAsync(response);
                    }
                }
            }
        }