I have a button that links out to an external URL by using an action that triggers a result-view with an app-launch.
Button:
input-cell {
label ("#{value(button.text)}")
on-click {
intent {
goal: FetchUrl
value-set: UrlConcept { $expr(button.value) }
}
}
}
Action:
action (FetchUrl) {
description (Fetches External Url)
type (Constructor)
collect {
input (url) {
type (UrlConcept)
min (Required) max (One)
}
}
output (UrlConcept) {
evaluate {
UrlConcept$expr (url)
}
}
}
Model:
text (UrlConcept) {
description (External Url)
}
Result View:
result-view {
match: UrlConcept (this) {
min(Required) max (One)
}
render {
nothing
}
app-launch {
payload-uri {
template ("#{value(this)}")
}
}
}
This works as expected in the Bixby Simulator - clicking the button results in the message 'User successfully exits Bixby, redirecting to an app', and I can view the logs and see the correct URI.
However, this fails when tested on multiple physical devices. Clicking the button results in Bixby hanging forever.
Related
Currently able to play audio on a result view. And i wish to reach where the view will differ from audio to audio. And I start from the basic which is display the title of the audio.
match{
Result{
from-output: playNews{
from-input: audio.AudioInfo(this){
from-output: buildNewsAudioInfo{
from-input: newsAudio{
from-output: getNews{
from-input: userWantToHear(whatuserwant)
}
}
}
}
}
}
}
render{
list-of (this){
where-each (audio){
title-area{
slot2{
paragraph{
style(Title_XS)
value("#{value(this.audioItem.title)}")
}
}
}
}
}
}
But this only show a single title for the whole result view. Is it able to show different view from audio to audio?
In order to change the view for each audio file, you would need to have conditionals that sort through the audio files contained in the Result object within the where-each block. This will allow you to define different layouts for whatever if statements you choose to define.
Adding code to address your comment to this original answer.
result-view {
match {
YourAudioResult (this)
}
render {
if ("size(this) > 1") {
list-of (this) {
where-each (audioItem) {
//CONDITIONALS FOR DECIDING HOW EACH ITEM IS SHOWN IN THE LIST VIEW
}
}
} else-if ("size(this) == 1") {
// CONDITIONALS FOR DECIDING HOW EACH ITEM IS SHOWN IN DETAIL VIEW
}
}
This one view will allow you to define the layouts of audio items when the result has multiple items and when there is a single item.
I am trying to change the the name of the command buttons in the listView Command set dynamically. I could hard code it and change it in the manifest.json file.
In place of "Command One" and "Command Two" I want to take values from list and change the name of the button.
Create a custom list "CommandList" and add new column "CommandTitle", the default Title field store the command key like "COMMAND_1", CommandTitle field store the command title like "Command One".
Then get the list items and change the default command title in spfx onInit method.
Example code:
import { override } from '#microsoft/decorators';
import { Log } from '#microsoft/sp-core-library';
import {
BaseListViewCommandSet,
Command,
IListViewCommandSetListViewUpdatedParameters,
IListViewCommandSetExecuteEventParameters
} from '#microsoft/sp-listview-extensibility';
import { Dialog } from '#microsoft/sp-dialog';
import * as jQuery from 'jquery';
/**
* If your command set uses the ClientSideComponentProperties JSON input,
* it will be deserialized into the BaseExtension.properties object.
* You can define an interface to describe it.
*/
export interface IListviewbarCommandSetProperties {
// This is an example; replace with your own properties
sampleTextOne: string;
sampleTextTwo: string;
}
const LOG_SOURCE: string = 'ListviewbarCommandSet';
export default class ListviewbarCommandSet extends BaseListViewCommandSet<IListviewbarCommandSetProperties> {
#override
public onInit(): Promise<void> {
Log.info(LOG_SOURCE, 'Initialized ListviewbarCommandSet');
let currentThis=this;
jQuery.ajax({
url: this.context.pageContext.web.absoluteUrl + "/_api/web/lists/getbytitle('CommandList')/items",
type: "GET",
async:false,
headers: {
"Accept": "application/json;odata=verbose",
},
success: function (data) {
let items:any[] = data.d.results;
items.forEach((item:any)=>{
const compareOneCommand: Command = currentThis.tryGetCommand(item["Title"]);
compareOneCommand.title=item["CommandTitle"];
});
},
error: function (data) {
//alert("Error");
}
});
return Promise.resolve();
}
#override
public onListViewUpdated(event: IListViewCommandSetListViewUpdatedParameters): void {
// const compareOneCommand: Command = this.tryGetCommand('COMMAND_1');
// if (compareOneCommand) {
// // This command should be hidden unless exactly one row is selected.
// compareOneCommand.visible = event.selectedRows.length === 1;
// }
}
#override
public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
switch (event.itemId) {
case 'COMMAND_1':
Dialog.alert(`${this.properties.sampleTextOne}`);
break;
case 'COMMAND_2':
Dialog.alert(`${this.properties.sampleTextTwo}`);
break;
default:
throw new Error('Unknown command');
}
}
}
I am looking to pass/store user's speech input. Bixby gives the user a result-view list of items, of which the user will say what item they want. Bixby will then display a list of account names, of which the user will say what account. I want to store what the user says after each list to combine them for an API call later.
Currently, I have only created the lists Bixby displays after each user input, but I do not know how to go forward to use both of the user inputs to use in a API call. My authorization.bxb is all configured and works, it is strictly only being able to forward information from multiple "moments." I have tried creating a input-view using selection-of, but continued to have issues displaying a list.
PossibleDataMetrics.view.bxb
result-view {
match: Metric (metric) {
from-output: ListMetrics
}
message {
template ("What data metrics are you looking for?")
}
render {
layout {
section {
content {
partitioned {
content {
for-each (metric){
as (m) {
title-area {
slot1 {
text {
value ("#{value(m.metrics)}")
style (Title_S)
}
}
}
}
}
}
}
}
}
}
}
}
ProfileTitleCardResultView.view.bxb
result-view {
match: Profile (profile) {
from-output: GetProfiles
}
message {
template ("What profile would you like?")
}
render {
layout {
section {
content {
for-each (profile){
as (view) {
title-card {
title-area {
halign (Start)
slot1 {
single-line {
text {
style (Detail_L_Soft)
value ("Account: #{value(view.acctName)}")
}
}
}
slot2 {
single-line {
text {
style (Detail_M_Soft)
value ("Web property: #{value(view.webName)}")
}
}
}
slot3 {
single-line {
text {
style (Title_S)
value ("Profile: #{value(view.viewName)}")
}
}
}
}
}
}
}
}
}
}
}
}
When these result views are called, I am looking to take the user input from both of these list of results to use in another action to create another list that is based off the user's answer of the initial 2 results.
In general, To navigate away from result-view you have the following options
Use followup to pose a question to the user and use the answer to
navigate away from the result-view https://bixbydevelopers.com/dev/docs/reference/type/result-view.followup
Use on-click feature of cards https://bixbydevelopers.com/dev/docs/reference/type/layout-macro-def.content.map-card.on-click
The other way to accomplish the same is by calling an Action that collects these inputs which invokes the input-view for each of these.
Hope this helps!
How can I disable the physical device back button on Android with React-Native? I don't want to enable it for the user.
There is no out of the box support from React Native Navigation as of today on v2. However, you could use BackHandler from React native itself. To handle it and return false to disable it.
Doc on BackHandler
Example
BackHandler.addEventListener('hardwareBackPress', function() {
return false;
});
In activity you can override the onBackPressed() and comment the calling to super class.
#Override
public void onBackPressed() {
// super.onBackPressed(); comment this line to disable back button press
}
Current open screen is tracked with a listener created when the application is launched, in app.js. Main component of the app creates a BackHandler listener, which responds to the device back button according to the currently open screen.
Main component:
componentDidMount() {
BackHandler.addEventListener('hardwareBackPress', this.onBackPress);
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.onBackPress);
}
onBackPress = () => {
if (this.props.currentScreen.name === 'app.main') {
Alert.alert(
'Confirm exit',
'Do you want to exit App?',
[
{text: 'CANCEL', style: 'cancel'},
{text: 'OK', onPress: () => {
BackHandler.exitApp()
}
}
]
);
} else {
Navigation.pop(this.props.currentScreen.id);
}
return true;
}
App.js
//register to compomentDidApperaListener to keep track on which screen is currently open. The componentName and Id are stored in my redux store
Navigation.events().registerComponentDidAppearListener(({ componentId, componentName }) => {
store.dispatch(updateCurrentScreen({'name': componentName, 'id': componentId}))
})
I have a View with 2 textbox and a button that call an action on a ViewModel to show another View; that what will show in it depends on values of 2 texbox.
For that reason before to call my ViewModel i want to check textbox values and if its are empty show a Dialog. Now to call my ViewModel i have add a binding like this:
this.AddBindings(new Dictionary<object, string>()
{
{ btnSearch, "TouchUpInside GoParameterizedCommand" },
});
as Swiss Binding. Now if i want to use same event to check if my textbox are valorized and don't call GoParameterizedCommand, how could i do?
You could bind all your controls to ViewModel properties like:
this.AddBindings(new Dictionary<object, string>()
{
{ btnSearch, "TouchUpInside GoCommand" },
{ text1, "Text MyText" },
{ switch1, "On MyOption" },
// ...
};
Then inside the GoCommand handler you could put whatever logic you need:
public ICommand GoCommand
{
get
{
return new MvxCommand(() => {
if (MyOption)
{
ShowViewModel<OptionViewModel>();
}
else
{
ShowViewModel<DetailViewModel>(new { text = MyText });
}
});
}
}
For showing a dialog - eg an error dialog - then this might be best done using a messenger - sending an error message from the viewmodel. There are a few questions on here about error handling - eg http://slodge.blogspot.co.uk/2012/05/one-pattern-for-error-handling-in.html - plenty of other options are available for giving the user a hint about what to do - eg you could bind the background colour of the text field to an IsMyTextValid property.