I'm trying to take the data (concept) from a card a user selects from a results view containing multiple cards and instead of presenting the information from that card in a more detailed view i'm trying to use the properties of the Concept the card displays, ie: Song author, title ... and transform that into a audioPlayer.AudioInfo concept and start playing the audio.
I am familiar with how the audio demo capsule plays audio, where the audioPlayer.AudioInfo is first build, an then passed to the audio player in the same action: https://github.com/bixbydevelopers/capsule-samples-collection/tree/master/audio
action (PlaySessionOfDay) {
type (Search)
collect {
computed-input (sessionToPlay) {
description (Fetch the sessions to be played)
type (audioPlayer.AudioInfo)
min (Required) max (One)
compute {
intent {
goal: BuildSessionOfDayAudioInfo
}
}
hidden
}
computed-input (session) {
description (By passing in the AudioInfo object to the PlayAudio action, we ask the client to play our sound.)
type (audioPlayer.Result)
compute {
intent {
goal: audioPlayer.PlayAudio
value: $expr(sessionToPlay)
}
}
hidden
}
}
output (Result)
}
How an can you use the selected Song card from the list of cards as the input into the PlaySessionOfDay action and then pass it to an action like BuildSessionOfDayAudioInfo, to create an audioPlayer.AudioInfo.
It looks like you can't have compute block
compute {
intent {
goal: BuildSessionOfDayAudioInfo
}
}
unless you are using computed-input (sessionToPlay).
Edit: I think some of the trouble is because by default cards clicked on in a list-of (songs) view invoke a details view. Is there any way to avoid this and use the selected data as the input to an action?
Is there any way to avoid this and use the selected data as the input to an action?
Yes, set has-details (false) in your view model, read more here
You need to add on-click with the intend PlaySessionOfDay
You would also need implement PlaySessionOfDay so it could take an input (I assume you have more than one content to play)
Related
I have some result views that use "has-details" which is now deprecated.
e.g.
render {
if (size(this) > 1) {
list-of (this) {
default-sort-order {
sorting(this.name)
}
has-details (true)
where-each (item) {
layout-macro (altbrains-compound-card) {
param (altbrainsdata) {
expression (item)
}
}
}
}
https://bixbydevelopers.com/dev/docs/dev-guide/release-notes/deprecations.6812
DEPRECATED: has-details is deprecated. Consider using on-click.view-for in a list card components instead. [deprecation 6812]
What does this mean? Can someone provide an example?
The Movie Agent Sample Capsule in the Bixby Developers Github repo is an excellent example for this behavior.
The relevant files are:
Movie_Result.view.bxb
Movie_Summary.layout.bxb
Movie_Details.layout.bxb
Here's how it works:
User asks for something that results in multiple Movies
Movie_Result view displays a bunch of movies using the Movie_Summary layout macro for each Movie
User taps one Movie which triggers the on-click containing view-for (movie)
This reloads the Movie_Result view again since its match requirement is met and triggers the Movie_Details layout since there is only 1 Movie to display.
I want to access the user info in the result- and input-view to make a message like that
"Thanks [Username] for you sharing"
I assume result-view is easy, so I include an example here for input-view.
The challenge here is to render the [username] which is not part of the input value. The solution is to group these two values together with an action.
input-view {
match: IntAge(this) {
to-input: GetStructPerson (action)
}
message {
template ("Enter age of #{value(action.name)}")
}
render {
form {
elements {
number-input {
id (that)
label (Age)
type (IntAge)
}
}
on-submit {
goal: IntAge
value: viv.core.FormElement(that)
}
}
}
}
Action is nothing but a constructor
action (GetStructPerson) {
description (__DESCRIPTION__)
type (Constructor)
collect {
input (name) {
type (TextName)
min (Required) max (One)
}
input (age) {
type (IntAge)
min (Required) max (One)
}
}
output (StructPerson)
}
I think this is the similar render result you want.
User information is present in $vivContext which is accessible to the developer in the corresponding javascript file of an Action. One way to achieve what you are trying to do would be to create a hidden property in your structure (called in the result-view) called userName and use an Action FillUserName to populate this property.
The following resources will help too. Good luck!
https://bixbydevelopers.com/dev/docs/dev-guide/developers/actions.js-actions#passing-user-context-information
https://github.com/bixbydevelopers/capsule-samples-collection/tree/master/user-context
I want to make Bixby ask for input values when the user just states what he/she wants to do(without any valuable input given.)
For example,
user: I want to search something
Bixby: What do you want to search?
user: *possible-input-value*
Is this possible? If so, how can I implement this?
That's easy in Bixby. If you make an input to your action required...it will prompt the user for input. Let's say you have an action like this:
action (FindSomething) {
type(Search)
description (Search for something)
collect {
input (search) {
type (Search)
min (Required) max (One) // Force Bixby to prompt for an input.
}
}
output (viv.core.Text) // some result
}
And you have a search concept defined like this:
name (Search) {
description (Search term)
}
You can provide an input view for the user to enter the term (via screen).
input-view {
match: Search(search)
message {
template ("What do you want to search?")
}
render {
form {
elements {
text-input {
id (search)
label (Search Term)
type (Search)
max-length (50)
value ("#{raw(search)}")
}
}
on-submit {
goal: Search
value: viv.core.FormElement(search)
}
}
}
}
In addition to Pete's response, you need to enable this for voice input (UI only input will not pass capsule review for submission to the marketplace). To do so, you need to create natural language training for Search
Since you are asking for input at a prompt, you need to create a training that will be used when prompting for Search
Training source for this would look like:
[g:Search:prompt] (sample search text)[v:Search]
Or in the UI
Definitely check out the sample code at https://github.com/bixbydevelopers for more examples. A simple example of input would be in https://github.com/bixbydevelopers/capsule-sample-fact - note the training that uses tags
In addition to Pete's response, I would recommend taking a look the design principles for Bixby development. These principles will guide you in making a targeted capsule that solves the use case you would like to address.
I have downloaded the sample capsule and implemented into my capsule and it is working, but now i need to pass few ids and generate the content for songs.
So my intent on followup will be
intent{
goal:PlaySongs
value-set:MultipleArtistId{$expr(singleArtistEvent.artistId)}
}
My PlaySongs action file read like this
action (PlaySongs) {
type (Search)
collect {
computed-input (songToPlay) {
description (Create the playlist to play)
type (audioPlayer.AudioInfo)
min (Required) max (One)
compute {
intent {
goal: GetMeArtistSong
value-set: MultipleArtistId
}
}
hidden
}
computed-input (play) {
description (By passing in the AudioInfo object to the PlayAudio action, we ask the client to play our sound.)
type (audioPlayer.Result)
compute {
intent {
goal: audioPlayer.PlayAudio
value: $expr(songToPlay)
}
}
hidden
}
}
output (Result)
}
GetMeArtistSong action file reads like this
action (GetMeArtistSong) {
type(Search)
description (Artist Song)
collect {
input (artistId) {
type (MultipleArtistId)
min (Optional) max (One)
}
}
output (audioPlayer.AudioInfo)
}
I am unable to get the artist id on GetMeArtistSong js file.
What are things i am doing wrong?
And what is hidden for? please explain.
hidden means the linked JS function do not need to list that input as argument. Without hidden, your JS function need to have both songsToPlay and play as argument.
Without the actual JS file and endpoints file, I can only speculate your question about artistId. It should not be related to audio player. Check endpoints and do console.log(), my feeling is that the action model and JS function are not properly linked. Also, you may want to change to min(Required) to enforce an input.
Currently I am trying to set up a few continuation actions after an interaction. One such continuation will send an email to the user with the results from the last action. I set up the action that will get an email address and send the email. To fill this input, i would like to offer the email addresses contained in the profile/self capsule as selection options and alternatively allow the user to input a custom email.
i set up a default input to get email addresses from the profile capsule and then offer those as options for the email input:
input (emailAddress) {
type (contact.EmailAddress)
instantiation-behavior (ShowDefaultValueDecision)
min (Required) max (One)
default-init {
intent {
goal: ReturnSelfEmail
}
}
}
Then i display them in an input-view using selection-of:
Here is my view:
input-view {
match: contact.EmailAddress(this) {
to-input: EmailResults
}
message ("What is your Email address?")
render{
selection-of (this) {
where-each (email) {
paragraph {
value {
template ("#{value(email)}")
}
style (Detail_M)
}
}
}
form {
elements {
text-input {
id (emailAddress)
label("Email Address")
required (true)
type (contact.EmailAddress)
}
}
on-submit {
goal: contact.EmailAddress
value: viv.core.FormElement(emailAddress)
}
}
}
}
In that view, I tried to add a form component as well but this does not work. Any ideas on how to have a custom input option in addition to the selections? Or another way to deal with a situation where the selections do not satisfy the user?
You can't render a form after you've rendered a selection-of.
My IDE shows this error - does yours?
"Unreachable statement" means that that part of the code will never run.
Anyways, one possible way to model this is to offer a selection view of the user's real email addresses, and one final entry which is a dummy email address called "input my own." (this uses selection-of)
If that selection is made, you can do throw an error in your JavaScript, and replan to a goal such as EnterCustomEmail. (this uses the form).
Here is another way to approach the problem.
In the result-view of the interaction (assuming that the email is sent at the end of the interaction), I would ask the user a followup question "Should I send a confirmation email to the <email> on your profile.?"
If the user responds "Yes" then the Action associated with the goal for the on-confirm will send an email to the user.
If the user says "No", the Action associated with the goal for on-deny should prompt the user for an email address.
This approach uses the conversational features of the Bixby platform and makes this interaction a more natural experience for the end-user.