mirror of https://github.com/espruino/BangleApps
commit
431100f724
|
@ -0,0 +1,62 @@
|
|||
# TV Remote
|
||||
A [BangleJS 2](https://shop.espruino.com/banglejs2) app that allows the user to send TV input signals from their watch to their TV.
|
||||
Currenly there is only support for Panasonic viera TV's however support for other brands may be considered in interest is there.
|
||||
|
||||
# Requirements
|
||||
1. The [Bangle GadgetBridge App](https://www.espruino.com/Gadgetbridge) with permissions allowed for `http requests`.
|
||||
2. A domain name and DNS created.
|
||||
3. A webserver that the DNS points to, that is set up to receive and process the watch http requests. [Here](https://github.com/Guptilious/banglejs-tvremote-webserver) is one I have created that should complete the full set up for users - provided they have their own domain name and DNS created.
|
||||
|
||||
# Set Up
|
||||
You will need to upload the below JSON file to your BangleJS, which will be used for config settings. At minimum you must provide:
|
||||
* `webServerDNS` address, which points to your webserver.
|
||||
* `username` which should mirror what is included in your webservers auth config. If using my webserver it would be `config.json`.
|
||||
* `password` which should mirror what is included in your webservers auth config. If using my webserver it would be `config.json`.
|
||||
|
||||
`port` and `tvIp` are optional as they can be manually assigned and updated via the tvremote watch app settings.
|
||||
|
||||
## Tv remote config example
|
||||
require("Storage").write("tvremote.settings.json", {
|
||||
"webServerDns": "",
|
||||
"tvIp": "",
|
||||
"port": "",
|
||||
"username": "",
|
||||
"password": ""
|
||||
});
|
||||
|
||||
# Usage
|
||||
Main Menu
|
||||
* Select TV type (panasonic is currently the only one supported)
|
||||
* Settings takes you to the settings menu, that allows you to manually assign ports and IP's.
|
||||
|
||||
Settings Menu
|
||||
* Device Select sends a http request to the webserver for a scrollable list devices to select.
|
||||
* Manual IP takes standard number inputs and swipping up will provide a `.` for IP's.
|
||||
|
||||
Power Screen
|
||||
* Press button - on/off.
|
||||
* Swipe left - `App Menu`.
|
||||
* Swipe Right - Main Menu
|
||||
|
||||
App Menu
|
||||
* Scroll and select to send App menu input.
|
||||
* Swipe left - Selection menu.
|
||||
* Swipe right - Power Screen.
|
||||
|
||||
Selection Menu
|
||||
* ^ - up
|
||||
* ! - down
|
||||
* < - left
|
||||
* `>` - right
|
||||
* Swipe right - back
|
||||
* Swipe left - select
|
||||
* Swipe Down - Number Menu ( used for inputting key passwords).
|
||||
* Swipe Up - Vol Commands
|
||||
|
||||
Vol Commands
|
||||
* Swipe Down - Selection Menu
|
||||
* Swipe right - rewind
|
||||
* Swipe left - fast forward
|
||||
* Swipe Up - Play/Pause
|
||||
|
||||
Back Button - Should take you back to the previous menu screen.
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4kA///7fOlMytX5muVt9T5lK6eMy2l1H4nO+i3d19jq2VxdCltTMf4A/AFsFqAYWqoXXGCxIEJqZIDGiYXCgpkTIYRjUFgIuUJAQuPgMRACEQC+0aw98+3ul3m/l3xQXMjVSkQAH/QUB2c7C48fCxEil4XBnOTC4+iC5Mi0IXKoQXKoJHKuQXKuJ3K4QXK4IXKsQXKsIXK8QXK8IXXjvd7vRC9Z3iU5hHKa5gXKoQXKoJHK0QXK0IXKj4WJksRI5UaqQXI5QXLDAOHvn290u838u+KIoZHIACAX0AH4A/ABo="))
|
|
@ -0,0 +1,655 @@
|
|||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
|
||||
let deviceFileName = "tvdevicelist.json";
|
||||
let serverDataFile = "tvremote.settings.json";
|
||||
let serverData = require("Storage").readJSON(serverDataFile, true);
|
||||
let devicefile = require("Storage").readJSON(deviceFileName, true);
|
||||
|
||||
//console.log(require("Storage").list());
|
||||
//console.log(devicefile);
|
||||
|
||||
|
||||
let serverDns = "webServerDns" in serverData ? serverData.webServerDns : 'undefined';
|
||||
|
||||
let serverPort = "port" in serverData ? serverData.port : 'undefined';
|
||||
let tvIp = "tvIp" in serverData ? serverData.tvIp : 'undefined';
|
||||
let username = "username" in serverData ? serverData.username : 'undefined';
|
||||
let password = "password" in serverData ? serverData.password : 'undefined';
|
||||
|
||||
let panaIp = tvIp;
|
||||
//"tvIp" in serverData ? serverData.tvIp : 'undefined';
|
||||
let settingsPort = "port" in serverData ? serverData.port : 'undefined';
|
||||
|
||||
let counter;
|
||||
let IPASSIGN;
|
||||
let samsIp;
|
||||
let countdownTimer = null;
|
||||
let currNumber = null;
|
||||
let selected = "NONE";
|
||||
let currentScreen = "power";
|
||||
let font = 'Vector';
|
||||
let RESULT_HEIGHT = 24;
|
||||
let RIGHT_MARGIN = 15;
|
||||
let midpoint = (g.getWidth() / 2);
|
||||
let IP_AREA = [0, RESULT_HEIGHT, g.getWidth(), g.getHeight()]; // values used for key buttons
|
||||
let KEY_AREA = [0, 24, g.getWidth(), g.getHeight()];
|
||||
let COLORS = {
|
||||
DEFAULT: ['#FF0000'],
|
||||
BLACK: ['#000000'],
|
||||
WHITE: ['#FFFFFF'],
|
||||
GREY: ['#808080', '#222222']
|
||||
}; // background
|
||||
|
||||
let sourceApps = {
|
||||
"selection": {
|
||||
'!': {
|
||||
grid: [0, 1],
|
||||
globalGrid: [0, 0],
|
||||
key: 'down'
|
||||
},
|
||||
'^': {
|
||||
grid: [0, 0],
|
||||
globalGrid: [0, 0],
|
||||
key: 'up'
|
||||
},
|
||||
'<': {
|
||||
grid: [1, 0],
|
||||
globalGrid: [1, 0],
|
||||
key: 'left'
|
||||
},
|
||||
'>': {
|
||||
grid: [1, 1],
|
||||
globalGrid: [1, 0],
|
||||
key: 'right'
|
||||
}
|
||||
},
|
||||
"volume": {
|
||||
'Vol Up': {
|
||||
grid: [0, 0],
|
||||
globalGrid: [0, 0],
|
||||
key: 'volume_up'
|
||||
},
|
||||
'Vol Dwn': {
|
||||
grid: [0, 1],
|
||||
globalGrid: [1, 0],
|
||||
key: 'volume_down'
|
||||
},
|
||||
'Mute': {
|
||||
grid: [1, 0],
|
||||
globalGrid: [2, 0],
|
||||
key: 'mute'
|
||||
},
|
||||
'Options': {
|
||||
grid: [1, 1],
|
||||
globalGrid: [2, 0],
|
||||
key: 'option'
|
||||
}
|
||||
},
|
||||
"numbers": {
|
||||
'<': {
|
||||
grid: [0, 3],
|
||||
globalGrid: [1, 4]
|
||||
},
|
||||
'0': {
|
||||
grid: [1, 3],
|
||||
globalGrid: [1, 4]
|
||||
},
|
||||
'ok': {
|
||||
grid: [2, 3],
|
||||
globalGrid: [2, 4]
|
||||
},
|
||||
'1': {
|
||||
grid: [0, 2],
|
||||
globalGrid: [0, 3]
|
||||
},
|
||||
'2': {
|
||||
grid: [1, 2],
|
||||
globalGrid: [1, 3]
|
||||
},
|
||||
'3': {
|
||||
grid: [2, 2],
|
||||
globalGrid: [2, 3]
|
||||
},
|
||||
'4': {
|
||||
grid: [0, 1],
|
||||
globalGrid: [0, 2]
|
||||
},
|
||||
'5': {
|
||||
grid: [1, 1],
|
||||
globalGrid: [1, 2]
|
||||
},
|
||||
'6': {
|
||||
grid: [2, 1],
|
||||
globalGrid: [2, 2]
|
||||
},
|
||||
'7': {
|
||||
grid: [0, 0],
|
||||
globalGrid: [0, 1]
|
||||
},
|
||||
'8': {
|
||||
grid: [1, 0],
|
||||
globalGrid: [1, 1]
|
||||
},
|
||||
'9': {
|
||||
grid: [2, 0],
|
||||
globalGrid: [2, 1]
|
||||
}
|
||||
},
|
||||
"apps": [{
|
||||
"name": "Disney +",
|
||||
"key": "disney"
|
||||
},
|
||||
{
|
||||
"name": "Netflix",
|
||||
"key": "netflix"
|
||||
},
|
||||
{
|
||||
"name": "Amazon Prime",
|
||||
"key": "prime"
|
||||
},
|
||||
{
|
||||
"name": "Youtube",
|
||||
"key": "youtube"
|
||||
},
|
||||
{
|
||||
"name": "Home",
|
||||
"key": "home"
|
||||
},
|
||||
{
|
||||
"name": "TV",
|
||||
"key": "tv"
|
||||
},
|
||||
{
|
||||
"name": "HDMI1",
|
||||
"key": "hdmi1"
|
||||
},
|
||||
{
|
||||
"name": "HDMI2",
|
||||
"key": "hdmi2"
|
||||
},
|
||||
{
|
||||
"name": "HDMI3",
|
||||
"key": "hdmi3"
|
||||
},
|
||||
{
|
||||
"name": "HDMI4",
|
||||
"key": "hdmi4"
|
||||
}
|
||||
]
|
||||
};
|
||||
let numbersGrid = [3, 4];
|
||||
let selectionGrid = [2, 2];
|
||||
let volumeGrid = [2, 2];
|
||||
let appData = sourceApps.apps;
|
||||
let volume = sourceApps.volume;
|
||||
let selection = sourceApps.selection;
|
||||
let numbers = sourceApps.numbers;
|
||||
|
||||
function assignScreen(screen) {
|
||||
currentScreen = screen;
|
||||
console.log(currentScreen);
|
||||
}
|
||||
|
||||
function sendPost(keyPress) {
|
||||
serverPort = settingsPort;
|
||||
tvIp = panaIp;
|
||||
let credentials = btoa(`${username}:${password}`);
|
||||
let serverUrl = `https://${serverDns}:${serverPort}`;
|
||||
|
||||
let keyJson = {
|
||||
"command": keyPress,
|
||||
"tvip": tvIp,
|
||||
};
|
||||
|
||||
Bangle.http(
|
||||
serverUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Basic ${credentials}`,
|
||||
},
|
||||
body: JSON.stringify(keyJson)
|
||||
})
|
||||
.then(response => {
|
||||
console.log("Response received:", response);
|
||||
}).catch(error => {
|
||||
console.error("Error sending data:", error);
|
||||
});
|
||||
}
|
||||
|
||||
function receiveDevices() {
|
||||
let serverPort = settingsPort;
|
||||
let credentials = btoa(`${username}:${password}`);
|
||||
let serverUrl = `https://${serverDns}:${serverPort}/ssdp-devices.json`;
|
||||
return Bangle.http(
|
||||
serverUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Authorization': `Basic ${credentials}`
|
||||
},
|
||||
}).then(data => {
|
||||
require("Storage").write(deviceFileName, data);
|
||||
devicefile = require("Storage").readJSON(deviceFileName, true);
|
||||
});
|
||||
}
|
||||
|
||||
function prepareScreen(screen, grid, defaultColor, area) { // grid, [3, 4], colour, grid area size
|
||||
for (let k in screen) {
|
||||
if (screen.hasOwnProperty(k)) {
|
||||
screen[k].color = screen[k].color || defaultColor;
|
||||
let position = [];
|
||||
let xGrid = (area[2] - area[0]) / grid[0];
|
||||
let yGrid = (area[3] - area[1]) / grid[1];
|
||||
|
||||
//console.log(xGrid + " " + yGrid);
|
||||
position[0] = area[0] + xGrid * screen[k].grid[0];
|
||||
position[1] = area[1] + yGrid * screen[k].grid[1];
|
||||
|
||||
position[2] = position[0] + xGrid - 1;
|
||||
position[3] = position[1] + yGrid - 1;
|
||||
|
||||
screen[k].xy = position;
|
||||
//console.log("prepared " + screen+"\n");
|
||||
}
|
||||
}
|
||||
Bangle.setUI({
|
||||
mode: "custom",
|
||||
back: function() {
|
||||
appMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function drawKey(name, k, selected) { // number, number data, NONE
|
||||
g.setColor(COLORS.DEFAULT[0]); // set color for rectangles
|
||||
g.setFont('Vector', 20).setFontAlign(0, 0);
|
||||
g.fillRect(k.xy[0], k.xy[1], k.xy[2], k.xy[3]); // create rectangles based on letters xy areas
|
||||
|
||||
g.setColor(COLORS.BLACK[0]).drawRect(k.xy[0], k.xy[1], k.xy[2], k.xy[3]);
|
||||
|
||||
g.setColor(COLORS.WHITE[0]); // color for numbers
|
||||
g.drawString(name, (k.xy[0] + k.xy[2]) / 2, (k.xy[1] + k.xy[3]) / 2); // center the keys to the rectangle that is drawn
|
||||
}
|
||||
|
||||
function drawKeys(area, buttons) {
|
||||
g.setColor(COLORS.DEFAULT[0]); // background colour
|
||||
g.fillRect(area[0], area[1], area[2], area[3]); // number grid area
|
||||
for (let k in buttons) {
|
||||
if (buttons.hasOwnProperty(k)) {
|
||||
drawKey(k, buttons[k], k == selected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayOutput(num, screenValue) { // top block
|
||||
num = num.toString();
|
||||
g.setFont('Vector', 18); //'7x11Numeric7Seg'
|
||||
g.setFontAlign(1, 0);
|
||||
g.setBgColor(0).clearRect(0, 0, g.getWidth(), RESULT_HEIGHT - 1);
|
||||
g.setColor(-1); // value
|
||||
|
||||
g.drawString(num, g.getWidth() - RIGHT_MARGIN, RESULT_HEIGHT / 2);
|
||||
}
|
||||
|
||||
function buttonPress(val, screenValue) {
|
||||
|
||||
if (screenValue === "ip") {
|
||||
if (val === "<") currNumber = currNumber.slice(0, -1);
|
||||
else if (val === ".") currNumber = currNumber + ".";
|
||||
else currNumber = currNumber == null ? val : currNumber + val; // currNumber is null if no value pressed
|
||||
|
||||
let ipcount = (currNumber.match(/\./g) || []).length;
|
||||
if (ipcount > 3 || currNumber.length > 15) currNumber = currNumber.slice(0, -1);
|
||||
|
||||
displayOutput(currNumber, screenValue);
|
||||
}
|
||||
|
||||
let checkValue = appData.some(app => app.name === screenValue); // check app data
|
||||
|
||||
if (checkValue) sendPost(val); // app values
|
||||
|
||||
if (screenValue === "numbers") {
|
||||
if (val === '<') sendPost('back');
|
||||
else if (val === 'ok') sendPost('enter');
|
||||
else sendPost("num_" + val);
|
||||
} else if (screenValue === "selection") sendPost(selection[val].key);
|
||||
else if (screenValue === "volume") sendPost(volume[val].key);
|
||||
}
|
||||
|
||||
const powerScreen = () => {
|
||||
currentScreen = "power";
|
||||
g.setColor(COLORS.GREY[0]).fillRect(0, 24, g.getWidth(), g.getWidth()); // outer circ
|
||||
g.setColor(COLORS.WHITE[0]).fillCircle(midpoint, 76 + 24, 50); // inner circ
|
||||
g.setColor(COLORS.BLACK[0]).setFont('Vector', 25).setFontAlign(0, 0).drawString("On/Off", 88, 76 + 24); // circ text
|
||||
|
||||
Bangle.setUI({
|
||||
mode: "custom",
|
||||
back: function() {
|
||||
mainMenu();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const appMenu = () => {
|
||||
|
||||
assignScreen("apps");
|
||||
E.showScroller({
|
||||
h: 54,
|
||||
c: appData.length,
|
||||
draw: (i, r) => {
|
||||
let sourceOption = appData[i];
|
||||
g.setColor(COLORS.DEFAULT[0]).fillRect((r.x), (r.y), (r.x + r.w), (r.y + r.h));
|
||||
g.setColor(COLORS.BLACK[0]).drawRect((r.x), (r.y), (r.x + r.w), (r.y + r.h));
|
||||
g.setColor(COLORS.WHITE[0]).setFont(font, 20).setFontAlign(-1, 1).drawString(sourceOption.name, 15, r.y + 32);
|
||||
},
|
||||
|
||||
select: i => {
|
||||
let sourceOption = appData[i];
|
||||
let appPressed = sourceOption.name;
|
||||
let appKey = sourceOption.key;
|
||||
buttonPress(appKey, appPressed);
|
||||
},
|
||||
|
||||
back: main => {
|
||||
E.showScroller();
|
||||
powerScreen();
|
||||
},
|
||||
});
|
||||
g.flip(); // force a render before widgets have finished drawing
|
||||
};
|
||||
|
||||
function ipScreen() {
|
||||
//require("widget_utils").hide();
|
||||
assignScreen("ip");
|
||||
currNumber = "";
|
||||
prepareScreen(numbers, numbersGrid, COLORS.DEFAULT, IP_AREA);
|
||||
drawKeys(IP_AREA, numbers);
|
||||
displayOutput(0);
|
||||
}
|
||||
|
||||
let tvSelector = {
|
||||
"": {
|
||||
title: "TV Selector",
|
||||
back: function() {
|
||||
load(); //E.showMenu(tvSelector);
|
||||
}
|
||||
},
|
||||
"Panasonic": function() {
|
||||
assignScreen("power");
|
||||
powerScreen();
|
||||
},
|
||||
"Samsung": function() {
|
||||
assignScreen("power");
|
||||
powerScreen();
|
||||
},
|
||||
"Settings": function() {
|
||||
subMenu();
|
||||
}
|
||||
};
|
||||
|
||||
function mainMenu() {
|
||||
assignScreen("mainmenu");
|
||||
E.showMenu(tvSelector);
|
||||
}
|
||||
|
||||
function clearCountdown() {
|
||||
if (countdownTimer) {
|
||||
clearTimeout(countdownTimer);
|
||||
countdownTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function countDown(callback) {
|
||||
require("widget_utils").show();
|
||||
if (counter === 0) {
|
||||
callback(); // Call the callback function when countdown reaches 0
|
||||
return;
|
||||
}
|
||||
E.showMessage(`Searching for devices...\n${counter}`, "Device Search");
|
||||
counter--;
|
||||
countdownTimer = setTimeout(() => countDown(callback), 1000);
|
||||
}
|
||||
|
||||
function clearDisplayOutput() {
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
}
|
||||
|
||||
function subMenu() {
|
||||
|
||||
if (typeof IPASSIGN !== 'undefined' && currNumber !== "") {
|
||||
if (IPASSIGN === "pana") {
|
||||
console.log("current numeber = " + currNumber);
|
||||
panaIp = currNumber;
|
||||
console.log("pana ip " + panaIp);
|
||||
console.log("default ip " + serverData.tvIp);
|
||||
serverData.tvIp = panaIp;
|
||||
require("Storage").write(serverDataFile, serverData);
|
||||
console.log("tv ip is now " + serverData.tvIp);
|
||||
|
||||
} else if (IPASSIGN === "sams") {
|
||||
samsIp = currNumber;
|
||||
|
||||
} else if (IPASSIGN === "port") {
|
||||
settingsPort = currNumber;
|
||||
console.log("setting port " + settingsPort);
|
||||
console.log("server port " + serverData.port);
|
||||
serverData.port = settingsPort;
|
||||
require("Storage").write(serverDataFile, serverData);
|
||||
console.log("port is now " + serverData.port);
|
||||
}
|
||||
}
|
||||
|
||||
require("widget_utils").show();
|
||||
assignScreen("settingssub");
|
||||
clearDisplayOutput();
|
||||
|
||||
let settingssub = {
|
||||
"": {
|
||||
title: "Settings",
|
||||
back: function() {
|
||||
E.showMenu(tvSelector);
|
||||
clearCountdown();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (typeof settingsPort !== 'undefined' && settingsPort !== 'undefined') {
|
||||
let portHeader = `Port: ${settingsPort}`;
|
||||
settingssub[portHeader] = function() {
|
||||
IPASSIGN = "port";
|
||||
ipScreen();
|
||||
};
|
||||
} else {
|
||||
settingssub["Set DNS Port"] = function() {
|
||||
IPASSIGN = "port";
|
||||
ipScreen();
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof panaIp !== 'undefined' && panaIp !== 'undefined') {
|
||||
let panaheader = `Pana IP: ${panaIp}`;
|
||||
settingssub[panaheader] = function() {
|
||||
IPASSIGN = "pana";
|
||||
E.showMenu(deviceSelect);
|
||||
devicefile = require("Storage").readJSON("tvdevicelist.json", true);
|
||||
console.log(devicefile);
|
||||
};
|
||||
} else {
|
||||
settingssub["Set Pana IP"] = function() {
|
||||
IPASSIGN = "pana";
|
||||
ipScreen();
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof samsIp !== 'undefined' && panaIp !== 'undefined') {
|
||||
let samsheader = `Sams IP: ${samsIp}`;
|
||||
settingssub[samsheader] = function() {
|
||||
IPASSIGN = "sams";
|
||||
ipScreen();
|
||||
};
|
||||
} else {
|
||||
settingssub["Set Sams IP"] = function() {
|
||||
IPASSIGN = "sams";
|
||||
ipScreen();
|
||||
};
|
||||
}
|
||||
|
||||
E.showMenu(settingssub);
|
||||
}
|
||||
|
||||
const deviceMenu = () => {
|
||||
let parsedResp = JSON.parse(devicefile.resp);
|
||||
E.showScroller({
|
||||
h: 54,
|
||||
c: parsedResp.length,
|
||||
draw: (i, r) => {
|
||||
let sourceOption = parsedResp[i];
|
||||
g.setColor(COLORS.DEFAULT[0]).fillRect((r.x), (r.y), (r.x + r.w), (r.y + r.h));
|
||||
g.setColor(COLORS.BLACK[0]).drawRect((r.x), (r.y), (r.x + r.w), (r.y + r.h));
|
||||
g.setColor(COLORS.WHITE[0]).setFont(font, 15).setFontAlign(-1, 1).drawString(sourceOption.name, 15, r.y + 32);
|
||||
},
|
||||
|
||||
select: i => {
|
||||
let sourceOption = parsedResp[i];
|
||||
//let devicePressed = sourceOption.name;
|
||||
let deviceIp = sourceOption.ip;
|
||||
|
||||
assignScreen("deviceSearch");
|
||||
serverData.tvIp = deviceIp.replace('http://', '');
|
||||
currNumber = serverData.tvIp;
|
||||
require("Storage").write(serverDataFile, serverData);
|
||||
console.log("tv ip is now " + serverData.tvIp);
|
||||
subMenu();
|
||||
},
|
||||
|
||||
back: main => {
|
||||
E.showScroller();
|
||||
E.showMenu(deviceSelect);
|
||||
},
|
||||
});
|
||||
g.flip(); // force a render before widgets have finished drawing
|
||||
};
|
||||
|
||||
|
||||
let deviceSelect = {
|
||||
"": {
|
||||
title: "Device Select",
|
||||
back: function() {
|
||||
subMenu();
|
||||
}
|
||||
},
|
||||
"Manual IP Assign": function() {
|
||||
ipScreen();
|
||||
},
|
||||
"Device Select": function() {
|
||||
receiveDevices();
|
||||
counter = 5;
|
||||
countDown(deviceMenu);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function swipeHandler(LR, UD) {
|
||||
if (LR == -1) { // swipe left
|
||||
if (currentScreen === "power") {
|
||||
assignScreen("apps");
|
||||
appMenu();
|
||||
|
||||
} else if (currentScreen === "apps") {
|
||||
//require("widget_utils").hide();
|
||||
assignScreen("selection");
|
||||
E.showScroller();
|
||||
prepareScreen(selection, selectionGrid, COLORS.DEFAULT, KEY_AREA);
|
||||
drawKeys(KEY_AREA, selection);
|
||||
|
||||
} else if (currentScreen === "volume") {
|
||||
sendPost("fast_forward");
|
||||
|
||||
} else if (currentScreen === "selection") {
|
||||
sendPost("enter");
|
||||
}
|
||||
}
|
||||
if (LR == 1) { // swipe right
|
||||
if (currentScreen === "apps") {
|
||||
assignScreen("power");
|
||||
E.showScroller();
|
||||
powerScreen();
|
||||
} else if (currentScreen === "volume") {
|
||||
sendPost("rewind");
|
||||
} else if (currentScreen === "selection") {
|
||||
sendPost("back");
|
||||
}
|
||||
}
|
||||
if (UD == -1) { // swipe up
|
||||
if (currentScreen === "selection") {
|
||||
assignScreen("volume");
|
||||
prepareScreen(volume, volumeGrid, COLORS.DEFAULT, KEY_AREA);
|
||||
drawKeys(KEY_AREA, volume);
|
||||
} else if (currentScreen === "volume") {
|
||||
sendPost("enter");
|
||||
} else if (currentScreen === "ip") {
|
||||
buttonPress(".", "ip");
|
||||
} else if (currentScreen == "numbers") {
|
||||
assignScreen("selection");
|
||||
prepareScreen(selection, selectionGrid, COLORS.DEFAULT, KEY_AREA);
|
||||
drawKeys(KEY_AREA, selection);
|
||||
}
|
||||
}
|
||||
if (UD == 1) { // swipe down
|
||||
if (currentScreen === "volume") {
|
||||
assignScreen("selection");
|
||||
prepareScreen(selection, selectionGrid, COLORS.DEFAULT, KEY_AREA);
|
||||
drawKeys(KEY_AREA, selection);
|
||||
} else if (currentScreen === "selection") {
|
||||
assignScreen("numbers");
|
||||
prepareScreen(numbers, numbersGrid, COLORS.DEFAULT, KEY_AREA);
|
||||
drawKeys(KEY_AREA, numbers);
|
||||
}
|
||||
}
|
||||
}
|
||||
Bangle.on('swipe', swipeHandler);
|
||||
|
||||
|
||||
function touchHandler(button, e) {
|
||||
const screenActions = {
|
||||
ip: () => checkButtons(numbers),
|
||||
volume: () => checkButtons(volume),
|
||||
numbers: () => checkButtons(numbers),
|
||||
selection: () => checkButtons(selection),
|
||||
power: () => {
|
||||
if (Math.pow(e.x - 88, 2) + Math.pow(e.y - 88, 2) < 2500) {
|
||||
sendPost("power");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function checkButtons(buttonMap) {
|
||||
for (let key in buttonMap) {
|
||||
if (typeof buttonMap[key] === "undefined") continue;
|
||||
let r = buttonMap[key].xy;
|
||||
|
||||
if (e.x >= r[0] && e.y >= r[1] && e.x < r[2] && e.y < r[3]) {
|
||||
if (currentScreen === "ip" && key === "ok") {
|
||||
subMenu();
|
||||
} else {
|
||||
buttonPress("" + key, currentScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentScreen in screenActions) screenActions[currentScreen]();
|
||||
}
|
||||
Bangle.on('touch', touchHandler);
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
if (serverData === undefined) {
|
||||
E.showAlert(`No settings.\nSee READ.me`, "Config Error").then(function() {
|
||||
mainMenu();
|
||||
});
|
||||
} else {
|
||||
mainMenu();
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 607 B |
|
@ -0,0 +1,15 @@
|
|||
{ "id": "tvremote",
|
||||
"name": "TV Remote",
|
||||
"shortName":"TV Remote",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"description": "remote for controlling your tv, using a webserver and the bangle Gadget Bridge (https://www.espruino.com/Gadgetbridge).",
|
||||
"icon": "app.png",
|
||||
"tags": "remote",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"tvremote.app.js","url":"app.js"},
|
||||
{"name":"tvremote.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue