mirror of https://github.com/espruino/BangleApps
Merge remote-tracking branch 'upstream/master'
commit
c82d06e573
|
@ -3044,7 +3044,7 @@
|
||||||
"name": "Gadgetbridge Music Controls",
|
"name": "Gadgetbridge Music Controls",
|
||||||
"shortName":"Music Controls",
|
"shortName":"Music Controls",
|
||||||
"icon": "icon.png",
|
"icon": "icon.png",
|
||||||
"version":"0.03",
|
"version":"0.04",
|
||||||
"description": "Control the music on your Gadgetbridge-connected phone",
|
"description": "Control the music on your Gadgetbridge-connected phone",
|
||||||
"tags": "tools,bluetooth,gadgetbridge,music",
|
"tags": "tools,bluetooth,gadgetbridge,music",
|
||||||
"type":"app",
|
"type":"app",
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: Initial version
|
0.01: Initial version
|
||||||
0.02: Increase text brightness, improve controls, (try to) reduce memory usage
|
0.02: Increase text brightness, improve controls, (try to) reduce memory usage
|
||||||
0.03: Only auto-start if active app is a clock, auto close after 1 hour of inactivity
|
0.03: Only auto-start if active app is a clock, auto close after 1 hour of inactivity
|
||||||
|
0.04: Setting to disable touch controls, minor bugfix
|
||||||
|
|
|
@ -16,10 +16,15 @@ Download the [latest Gadgetbridge for Android here](https://f-droid.org/packages
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
The app can automatically load when you play music and close when the music stops.
|
You can change these under `Settings`->`App/Widget Settings`->`Music Controls`.
|
||||||
You can change this under `Settings`->`App/Widget Settings`->`Music Controls`.
|
|
||||||
|
**Auto start**:
|
||||||
|
Automatically load the app when you play music and close when the music stops.
|
||||||
(If the app opened automatically, it closes after music has been paused for 5 minutes.)
|
(If the app opened automatically, it closes after music has been paused for 5 minutes.)
|
||||||
|
|
||||||
|
**Touch**:
|
||||||
|
Enable touch controls?
|
||||||
|
|
||||||
## Controls
|
## Controls
|
||||||
|
|
||||||
### Buttons
|
### Buttons
|
||||||
|
|
|
@ -13,6 +13,10 @@ let info = {
|
||||||
};
|
};
|
||||||
const POUT = 300000; // auto close timeout when paused: 5 minutes (in ms)
|
const POUT = 300000; // auto close timeout when paused: 5 minutes (in ms)
|
||||||
const IOUT = 3600000; // auto close timeout for inactivity: 1 hour (in ms)
|
const IOUT = 3600000; // auto close timeout for inactivity: 1 hour (in ms)
|
||||||
|
// Touch controls? 0: off, 1: when LCD on, 2: always
|
||||||
|
let s = require("Storage").readJSON("gbmusic.json", 1) || {};
|
||||||
|
const TCTL = ("touch" in s) ? (s.touch|0)%3 : 1;
|
||||||
|
delete s;
|
||||||
|
|
||||||
///////////////////////
|
///////////////////////
|
||||||
// Self-repeating timeouts
|
// Self-repeating timeouts
|
||||||
|
@ -138,16 +142,13 @@ function infoColor(name) {
|
||||||
s = 0;
|
s = 0;
|
||||||
} else {
|
} else {
|
||||||
// make color depend deterministically on info
|
// make color depend deterministically on info
|
||||||
let code = 0;
|
let code = textCode(info[name]);
|
||||||
switch(name) {
|
switch(name) {
|
||||||
case "track":
|
case "track": // also use album
|
||||||
code += textCode(info.track);
|
|
||||||
// fallthrough: also use album+artist
|
|
||||||
case "album":
|
|
||||||
code += textCode(info.album);
|
code += textCode(info.album);
|
||||||
// fallthrough: also use artist
|
// fallthrough
|
||||||
default:
|
case "album": // also use artist
|
||||||
code += textCode(info[name]);
|
code += textCode(info.artist);
|
||||||
}
|
}
|
||||||
h = code%360;
|
h = code%360;
|
||||||
s = 0.7;
|
s = 0.7;
|
||||||
|
@ -346,6 +347,7 @@ function controlColor(ctrl) {
|
||||||
return (ctrl in tCommand) ? "#ff0000" : "#008800";
|
return (ctrl in tCommand) ? "#ff0000" : "#008800";
|
||||||
}
|
}
|
||||||
function drawControl(ctrl, x, y) {
|
function drawControl(ctrl, x, y) {
|
||||||
|
if (!TCTL) {return;}
|
||||||
g.setColor(controlColor(ctrl));
|
g.setColor(controlColor(ctrl));
|
||||||
const s = 20;
|
const s = 20;
|
||||||
if (stat!==controlState) {
|
if (stat!==controlState) {
|
||||||
|
@ -518,7 +520,9 @@ function togglePlay() {
|
||||||
sendCommand(stat==="play" ? "pause" : "play");
|
sendCommand(stat==="play" ? "pause" : "play");
|
||||||
}
|
}
|
||||||
function startTouchWatches() {
|
function startTouchWatches() {
|
||||||
|
if (!TCTL) {return;}
|
||||||
Bangle.on("touch", side => {
|
Bangle.on("touch", side => {
|
||||||
|
if (TCTL<2 && !Bangle.isLCDOn()) {return;}
|
||||||
switch(side) {
|
switch(side) {
|
||||||
case 1:
|
case 1:
|
||||||
sendCommand(stat==="play" ? "pause" : "previous");
|
sendCommand(stat==="play" ? "pause" : "previous");
|
||||||
|
@ -531,6 +535,7 @@ function startTouchWatches() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Bangle.on("swipe", dir => {
|
Bangle.on("swipe", dir => {
|
||||||
|
if (TCTL<2 && !Bangle.isLCDOn()) {return;}
|
||||||
sendCommand(dir===1 ? "previous" : "next");
|
sendCommand(dir===1 ? "previous" : "next");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,35 +4,40 @@
|
||||||
(function(back) {
|
(function(back) {
|
||||||
const SETTINGS_FILE = "gbmusic.json",
|
const SETTINGS_FILE = "gbmusic.json",
|
||||||
storage = require("Storage"),
|
storage = require("Storage"),
|
||||||
translate = require("locale").translate
|
translate = require("locale").translate;
|
||||||
|
const TOUCH_OPTIONS = ["Off", "When LCD on", "Always"];
|
||||||
|
|
||||||
// initialize with default settings...
|
// initialize with default settings...
|
||||||
let s = {
|
let s = {
|
||||||
autoStart: true,
|
autoStart: true,
|
||||||
}
|
touch: 1,
|
||||||
|
};
|
||||||
// ...and overwrite them with any saved values
|
// ...and overwrite them with any saved values
|
||||||
// This way saved values are preserved if a new version adds more settings
|
// This way saved values are preserved if a new version adds more settings
|
||||||
const saved = storage.readJSON(SETTINGS_FILE, 1) || {}
|
const saved = storage.readJSON(SETTINGS_FILE, 1) || {};
|
||||||
for(const key in saved) {
|
for(const key in saved) {
|
||||||
s[key] = saved[key]
|
s[key] = saved[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a function to safe a specific setting, e.g. save('autoStart')(true)
|
function save(key, value) {
|
||||||
function save(key) {
|
s[key] = value;
|
||||||
return function(value) {
|
storage.write(SETTINGS_FILE, s);
|
||||||
s[key] = value
|
|
||||||
storage.write(SETTINGS_FILE, s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const menu = {
|
let menu = {
|
||||||
"": {"title": "Music Control"},
|
"": {"title": "Music Control"},
|
||||||
"< Back": back,
|
};
|
||||||
"Auto start": {
|
menu[translate("< Back")] = back;
|
||||||
value: s.autoStart,
|
menu[translate("Auto start")] = {
|
||||||
format: v => translate(v ? "Yes" : "No"),
|
value: s.autoStart,
|
||||||
onchange: save("autoStart"),
|
format: v => translate(v ? "Yes" : "No"),
|
||||||
}
|
onchange: v => {save("autoStart", v);},
|
||||||
}
|
};
|
||||||
E.showMenu(menu)
|
menu[translate("Touch")] = {
|
||||||
})
|
value: s.touch|0,
|
||||||
|
format: v => translate(TOUCH_OPTIONS[(v+3)%3]),
|
||||||
|
onchange: v => {save("touch", (v+3)%3);},
|
||||||
|
};
|
||||||
|
|
||||||
|
E.showMenu(menu);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue