Input-view navigation-mode does not read list - bixby

I've tried implementing an input-view with navigation-mode so that the user can verbally select an option. The goal is to have my capsule completely usable without physical interaction.
The issue is that I tried to follow the example from the Developer Center, but it doesn't seem to work properly. https://bixbydevelopers.com/dev/docs/dev-guide/developers/enhancing-UX.list-navigation
input-view {
match: SpaceResort (result)
message ("Which space resort would you like?")
render {
if (size(result) > 1) {
selection-of (result) {
navigation-mode {
read-one {
list-summary ("I found #{size(result)} resorts.")
page-content {
underflow-statement (This is the first resort.)
item-selection-question (Do you want to book this resort?)
overflow-statement (Those are all the resorts that meet your search.)
overflow-question (What would you like to do?)
}
}
}
has-details (true)
select-button-text ("Book")
where-each (item) {
layout-macro (space-resort-summary) {
param (spaceResort) {
expression (item)
}
}
}
}
}
}
}
On my capsule, it would repeat the 'item-selection-question', 'list-summary', or the message template twice, and it will not read out loud the list of items.

The online DOC example is not very clear.
You need to add child-key spoken-summary in where-each (item). Please check more here
And in IDE testing, you need enable the "hands free" mode button.
Currently on-device testing this feature is not enabled, yet.
Again, the repeat twice message is a bug, and will be fixed soon.

Related

how to replace has-details with card component per deprecation 6812

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.

Bixby: hands free List-of navigation not working for single item

I have used hands-free list-of navigation in my capsule where I select a single item from multiple items to get the detailed information using voice command ("select one, choose second, etc").
But If I have a single item only, I am unable to give a voice command to go to another page. (hands-free list-of navigation not working when we have a single item).
So, how can I go to another page when I have a single item only, using voice command. (hands-free navigation)
Please help me with this.
For a single item case, should be checked first and probably not enter list-navigation at all. The logic for render in view is recommended as following:
if (size(this)==1) {
// render content (maybe different between HEF and non-HEF, but no navigation needed)
}
else {
if ($handsFree) {
// do list navigation here
}
else {
// render non-HEF content
}
}
Please consider the following code as a sample, this view works for multiple item list and single item. For HEF with multiple items, the flow is "do you want one of these" --> "yes" --> "which person would you like" --> "first/second one" --> Bixby renders the content in detail-stuctA macro. For HEF with single item, it directly renders detail-stuctA macro and skip all the navigation part.
It is true that if skip the (size(this)==1) check would result stuck in list-navigation forever, but that is understandable, because each time Bixby try to render, it fits the condition of list-navigation and take the list-navigation route.
result-view {
match: StructA(this)
message: template ("In result view")
render {
if (size(this)==1) {
layout-macro (detail-structA) {
param (person) {expression (this)}
}
}
else {
if ($handsFree) {
list-of (this) {
navigation-mode {
read-many {
page-size (6)
list-summary("In hands free")
page-content {
underflow-statement (This is the first page.)
page-selection-question (Do you want one of these?)
item-selection-question (Which person would you like?)
overflow-statement (Those are all the persons that meet your search.)
overflow-question (What would you like to do?)
}
}
}
where-each (item) {
layout-macro (summary-structA) {
param (person) {expression (item)}
}
}
}
}
else {
list-of (this) {
where-each (item) {
layout-macro (summary-structA) {
param (person) {expression (item)}
}
}
}
}
}
}
}
If the above does not answer your question, please submit a ticket using Bixby IDE --> Help --> Contact Support with a copy of sample capsule to demo the issue.

Bixby: want to implement stop watch in my capsule

I want to display a stopwatch(timer) for my capsule.
So, is there any way from which I can show timer in my view page which will get refreshed every second.
I am not understanding where to start. How will time get refreshed?
Any help on this.
You can use the built-in refresh command to repaint the screen. For example,
result-view {
match {
Activity (this) {
min (Required)
max (One)
from-output: CheckRideShareStatus (check)
}
}
message {
if (this.countdown != 0) {
template ("Your ride will arrive in #{value(this.countdown)} seconds.")
} else {
template ("I hope you are enjoying your ride")
}
}
refresh {
if (this.countdown != 0) {
spec {
delay-seconds (5)
with-request {
intent {
goal: CheckRideShareStatus
value {
$expr (this)
}
}
}
}
}
}
render {
layout-macro (activity-map-macro) {
param (activity) {
expression (this)
}
}
}
}
The Bixby team has provided a working example on Github
Detail on refresh here
Although it's possible to do a 1 second refresh this is definitely going to suffer from inaccuracy due to latency.
Depending upon your use case, simply creating an animated gif and displaying it may be simpler and definitely more accurate. Perhaps this combined with a refresh may be a better solution.
An example (from https://timertopia.files.wordpress.com/2018/06/30seccut.gif) would be something like this

How do I have bixby use app-launch to open google maps?

I am trying to open google maps using the on-click key from a compound card, but I don't know what to include in the payload-URI key for app-launch. The documentation uses the example which is commented out, but I do not know what to fill in for the application(google-maps).
I am getting two errors both being Unknown key message/app-launch.
This is the code we are trying to use, so that when a compound card is clicked, it opens google maps with app-launch.
// PersonSelectionView.view.bxb
input-view {
match: Spot (this)
// optional selection dialog to overwrite any other default dialog
message (Pick a spot)
render {
// used to iterate over the list of candidates
selection-of (this) {
navigation-mode {
read-none {
list-summary ("There are #{size(this)} #{value(categories)} spots near you")
item-selection-question (Which one would you like?)
}
}
where-each (one) {
// you can use conditional logic to control how candidates are displayed,
// using either a standard layout with a match pattern, or a layout macro
compound-card {
content {
map-card {
title-area {
slot1 {
text {
value("#{value (one.spotName)}")
}
}
slot3 {
single-line {
text {
value("#{value (one.distance)} Miles away")
}
}
}
}
aspect-ratio (1:1)
markers {
marker {
geo ("Location.point")
icon {
template (/images/icons/red-marker.png)
}
width (15)
height (20)
anchor-x (5)
anchor-y (15)
rotation (0)
}
}
}
paragraph {
value {
template ("#{raw(description)}")
}
style (Detail_L)
}
}
on-click {
message ("TESTING THIS MESSAGE")
app-launch {
//payload-uri ("bixby://com.android.systemui/DummySystem/punchOut")
}
}
}
}
}
}
}
An "Unknown Key" error means that the key you are trying to define is not one of the valid child keys of the key you are currently in. The reference section of the Bixby Developer Documentation provides each key with its valid child keys.
Both app-launch and message are not child keys of on-click.
app-launch cannot be defined within an on-click. It must be defined in its own result-view.
message can be defined in multiple keys but not on-click
Your on-click would need to redirect to a separate result-view which would contain the app-launch key with the correct payload-uri defined.
You would need the following to implement the behavior you described:
An Action (and backing Action Javascript) to return the URI
A Concept to hold the URI returned by the Action
A result-view with a match that matches the Concept
Example Action:
action (LaunchDefinedUri) {
description (Launches the defined uri)
type (Commit)
collect {
input (launchUri) {
type (LaunchUri)
min (Required) max (One)
}
}
output (LaunchUri)
}
Example Action Javascript:
module.exports = {
function: LaunchDefinedUri
}
function LaunchDefinedUri(launchUri) {
return launchUri
}
Example Concept:
text (LaunchUri) {
description (Uri to be launched)
}
Example Result View:
result-view {
match: LaunchUri(this)
app-launch {
payload-uri("#{value(this)}")
}
render {
nothing
}
}
As for Google Maps API in particular, the Google Maps documentation seems to provide information on how to define the correct URIs for your specific purpose and behavior.
Please look into this official library provided by the Bixby team, which provides punch-out to Google Maps.
https://bixbydevelopers.com/dev/docs/dev-guide/developers/library.navigation

How to trigger onclick on selection in bixby

My app is basically providing three option for selection to the user.
1: I am using result-view and cell-card. when i was using for each, i was able to click on the card and trigger an intent which is showing user the further details in the form of compound-card. Now, for user to select the option by saying first, second OR third, i need to use navigation-support and for that I need to use list-of in the result-view. After using list-of, I am unable to trigger the intent on-click. How to achieve that?
2: How to trigger that intent, if user is saying first, second or third. Right now, if user is choosing by saying first, second and third, it is popping out the said cell-card excluding other two. How to achieve that?
My result-view is:
result-view {
match: ArtistChoiceResult (artistchoice) {
from-output: ArtistChoice
}
message {template("Here is the upcoming event")}
list-of (artistchoice) {
navigation-mode {
read-many {
page-size(3)
underflow-statement (This is the first set)
item-selection-question (Which one would you like?)
overflow-statement (That's all I have)
}
}
where-each (one) {
layout-match (one) {
mode (Summary)
}
}
}
layout-match is like this
layout {
match: ArtistChoiceResult (singleArtist)
mode(Summary)
content{
section{
content{
cell-card {
slot1 {
image {
url ("#{value(singleArtist.multiple_image)}")
shape (Square)
}
}
slot2 {
content {
order (PrimarySecondary)
primary ("#{value(singleArtist.multiple_name)}")
secondary ("#{value(singleArtist.multiple_cat)}")
}
}
on-click {
intent {
goal: ArtistChoice
value-set:MultipleID{$expr(singleArtist.multiple_id)}
}
}
}
}
}
}
}
Navigation support file is
navigation-support {
match: ArtistChoiceResult (this)
ordinal-selection-patterns {
pattern ("(first)[v:viv.core.OrdinalSelector]")
pattern ("(first)[v:viv.core.OrdinalSelector] one")
pattern ("that (first)[v:viv.core.OrdinalSelector] one")
pattern ("yes (first)[v:viv.core.OrdinalSelector]")
pattern ("yes (first)[v:viv.core.OrdinalSelector] one")
pattern ("yes that (first)[v:viv.core.OrdinalSelector] one")
pattern ("result number (one)[v:viv.core.CardinalSelector:1]")
pattern ("the (first)[v:viv.core.CardinalSelector:1]")
pattern ("select (first)[v:viv.core.OrdinalSelector] one")
pattern ("select (first)[v:viv.core.OrdinalSelector]")
}
}
A couple of issues with your code
you have created an intent in a Summary layout. The documentation says,
https://bixbydevelopers.com/dev/docs/reference/type/layout-macro-def.content.cell-card
If you have this card to list results with list-of, then clicking the
card opens the selected item in Details mode and the defined intent is not passed
If you try to use layout-match inside where-each the IDE will show a WARN_DEPRECATED error. While this might not throw compile errors now, it is advisable to use layout-macro
Suggestions to try:
Use layout-macro to define your Layouts (both Summary and Details)
Add the intent in the Details layout

Resources