12-28-2017 09:19
12-28-2017 09:19
We have three physical buttons, and some "control" on the right hand two buttons.
Is it possible to place an onclick/onactivate event hook onto the left hand button?
For example, we want confirmation from the user that they actually do want to exit the application, rather than lose all their collected activity data.
Thanks
Answered! Go to the Best Answer.
12-31-2017 01:25 - edited 12-31-2017 07:51
12-31-2017 01:25 - edited 12-31-2017 07:51
Just put together a little test to remap the "back" button to the "top" button.
So it is entirely possible to prevent accidental exit from the application.
Thanks to those who helped out on this
import document from "document"; import { me } from "appbit"; document.onkeypress = function(e) { console.log("Key pressed: " + e.key); e.preventDefault(); if (e.key==="up") { console.log("trapped"); me.exit(); }
Have updated this post to show a full solution in the hope it helps someone out in the community:
app/index.js
import document from "document";
import { me } from "appbit";
import clock from "clock";
let runningPage = document.getElementById("runningPage");
let exitPage = document.getElementById("exitPage");
let timeDisplay = document.getElementById("time");
let dateDisplay = document.getElementById("date");
let btnyes = document.getElementById("btn-yes");
btnyes.onclick = function(evt) {
me.exit();
}
let btnno = document.getElementById("btn-no");
btnno.onclick = function(evt) {
runningPage.style.display="inline";
exitPage.style.display="none";
}
runningPage.style.display="inline";
exitPage.style.display="none";
document.onkeypress = function(e) {
e.preventDefault();
if (e.key=="up" && exitPage.style.display=="inline") {
me.exit();
}
if (e.key==="back" || e.key==="down") {
if (exitPage.style.display==="inline") {
runningPage.style.display="inline";
exitPage.style.display="none";
} else {
runningPage.style.display="none";
exitPage.style.display="inline";
}
}
}
clock.granularity = "seconds";
clock.ontick = () => showData();
function showData() {
let myDate=new Date();
let secs=zeroPad(myDate.getSeconds());
let mins=zeroPad(myDate.getMinutes());
let hrs=myDate.getHours();
let day=zeroPad(myDate.getDate());
let month=zeroPad(myDate.getMonth()+1);
let year=zeroPad(myDate.getFullYear());
timeDisplay.text=`${hrs}:${mins}:${secs}`;
dateDisplay.text=`${day}/${month}/${year}`;
}
function zeroPad(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
resources/index.gui
<svg>
<svg id="runningPage">
<rect id="background2" pointer-events="none" />
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Clock</text>
<text y="160" x="50%" id="time" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Time: </text>
<text y="195" x="50%" id="date" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Date: </text>
</svg>
<svg id="exitPage">
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Exit: Are you sure?</text>
<svg y="$">
<use id="btn-yes" href="#square-button-toggle" x="50%" fill="fb-green">
<set href="#text" attributeName="text-buffer" to="Yes" />
</use>
<use id="btn-no" href="#square-button-toggle" value="1" fill="fb-red">
<set href="#text" attributeName="text-buffer" to="No" />
</use>
</svg>
</svg>
</svg>
resource/widgets.gui
<svg>
<defs>
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
<link rel="import" href="/mnt/sysassets/widgets/square_button_widget.gui" />
<link rel="import" href="/mnt/sysassets/widgets/baseview_widget.gui" />
</defs>
</svg>
That should be pretty much all you need. Press the back button to display the exit confirmation screen and then tap either of the two displayed buttons, or click back / down physical buttons to cancel exiting or the top button to confirm exit.
Running Page
Exit Confirmation Page
12-29-2017 12:13 - edited 01-02-2018 07:13
12-29-2017 12:13 - edited 01-02-2018 07:13
You add events to physical buttons. You can add an onunload event with the AppBit API and save data there.
12-29-2017 12:59
12-29-2017 12:59
Thank you FredFitbit.
Is mapping the left button in the development plan? The right hand two are effectively mapped against the right hand combo buttons.
At the moment it is too easy to accidentally exit the application when you didn't actually mean to (mid run when you tap the button to wake up but accidentally hit it twice --- frustrating.
Some thought would need to be given to prevent malicious code from stopping a user exiting an application. A double tap on the left button for example ....
12-29-2017 22:02
12-29-2017 22:02
I think the answer for an app is described here:
https://dev.fitbit.com/guides/user-interface/javascript/#using-the-physical-buttons
The document object emits keypress events when the user presses one of the physical buttons. Long press button events are reserved for system use only.
import document from "document"; document.onkeypress = function(e) { console.log("Key pressed: " + e.key); }
The possible values for e.key are down, up, and back.
12-30-2017 04:52
12-30-2017 04:52
My bad, it's only long press that are reserved for the system, I updated my answer, thaks @qooApps .
12-30-2017 14:54
12-30-2017 14:54
Thank you qooApps for your reply and useful information - help like this from the community is genuinely appreciated.
This however doesn't solve the issue with accidentally closing the application.
Yes indeed you do get a 'back' event firing - which you can save data automatically.- but how can you then present a "Are You Sure?" with a Yes / No selection.
Is this something that FitBit has in their development pathway?
12-30-2017 15:29
12-30-2017 15:29
You can prevent the default action of the back button (“exiting the app”) by using event.preventDefault() inside the onkeypressfunction but I’m not sure how to close the app programatically
document.onkeypress = function(evt) {
if (evt.key === "back") {
evt.preventDefault();
// display confirmation message
}
}
12-31-2017 01:12
12-31-2017 01:12
Thank you pautomas.
It would be good to know if there is a way to close the app programatically.
In the meantime it would be possible, when clicking the back button, to check whether the user has previously clicked and positively responded to a "are you sure message?" If they have then allow exit, otherwise evt.preventDefault() would be executed.
Clunky - but workable.
12-31-2017 01:25 - edited 12-31-2017 07:51
12-31-2017 01:25 - edited 12-31-2017 07:51
Just put together a little test to remap the "back" button to the "top" button.
So it is entirely possible to prevent accidental exit from the application.
Thanks to those who helped out on this
import document from "document"; import { me } from "appbit"; document.onkeypress = function(e) { console.log("Key pressed: " + e.key); e.preventDefault(); if (e.key==="up") { console.log("trapped"); me.exit(); }
Have updated this post to show a full solution in the hope it helps someone out in the community:
app/index.js
import document from "document";
import { me } from "appbit";
import clock from "clock";
let runningPage = document.getElementById("runningPage");
let exitPage = document.getElementById("exitPage");
let timeDisplay = document.getElementById("time");
let dateDisplay = document.getElementById("date");
let btnyes = document.getElementById("btn-yes");
btnyes.onclick = function(evt) {
me.exit();
}
let btnno = document.getElementById("btn-no");
btnno.onclick = function(evt) {
runningPage.style.display="inline";
exitPage.style.display="none";
}
runningPage.style.display="inline";
exitPage.style.display="none";
document.onkeypress = function(e) {
e.preventDefault();
if (e.key=="up" && exitPage.style.display=="inline") {
me.exit();
}
if (e.key==="back" || e.key==="down") {
if (exitPage.style.display==="inline") {
runningPage.style.display="inline";
exitPage.style.display="none";
} else {
runningPage.style.display="none";
exitPage.style.display="inline";
}
}
}
clock.granularity = "seconds";
clock.ontick = () => showData();
function showData() {
let myDate=new Date();
let secs=zeroPad(myDate.getSeconds());
let mins=zeroPad(myDate.getMinutes());
let hrs=myDate.getHours();
let day=zeroPad(myDate.getDate());
let month=zeroPad(myDate.getMonth()+1);
let year=zeroPad(myDate.getFullYear());
timeDisplay.text=`${hrs}:${mins}:${secs}`;
dateDisplay.text=`${day}/${month}/${year}`;
}
function zeroPad(i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
resources/index.gui
<svg>
<svg id="runningPage">
<rect id="background2" pointer-events="none" />
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Clock</text>
<text y="160" x="50%" id="time" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Time: </text>
<text y="195" x="50%" id="date" font-family="System-Regular" fill="white" font-size="40" font-weight="bold" text-length="20" text-anchor="middle">Date: </text>
</svg>
<svg id="exitPage">
<text y="110" x="50%" id="Title" font-family="System-Regular" fill="yellow" font-size="45" font-weight="bold" text-anchor="middle">Exit: Are you sure?</text>
<svg y="$">
<use id="btn-yes" href="#square-button-toggle" x="50%" fill="fb-green">
<set href="#text" attributeName="text-buffer" to="Yes" />
</use>
<use id="btn-no" href="#square-button-toggle" value="1" fill="fb-red">
<set href="#text" attributeName="text-buffer" to="No" />
</use>
</svg>
</svg>
</svg>
resource/widgets.gui
<svg>
<defs>
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
<link rel="import" href="/mnt/sysassets/widgets/square_button_widget.gui" />
<link rel="import" href="/mnt/sysassets/widgets/baseview_widget.gui" />
</defs>
</svg>
That should be pretty much all you need. Press the back button to display the exit confirmation screen and then tap either of the two displayed buttons, or click back / down physical buttons to cancel exiting or the top button to confirm exit.
Running Page
Exit Confirmation Page
12-31-2017 07:36 - edited 12-31-2017 12:09
12-31-2017 07:36 - edited 12-31-2017 12:09
Moved content into the post above. Apologies for duplicating.
10-14-2018 03:59
10-14-2018 03:59
Thanks - helped me also.