mirror of https://github.com/espruino/BangleApps
Merge pull request #731 from rigrig/gbmusic
Gadgetbridge Music Controls: only auto-start from clock apps, auto close after 1 hour of inactivitypull/732/head
commit
302d63a985
|
@ -3044,7 +3044,7 @@
|
|||
"name": "Gadgetbridge Music Controls",
|
||||
"shortName":"Music Controls",
|
||||
"icon": "icon.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Control the music on your Gadgetbridge-connected phone",
|
||||
"tags": "tools,bluetooth,gadgetbridge,music",
|
||||
"type":"app",
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
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
|
||||
|
|
|
@ -11,7 +11,8 @@ let info = {
|
|||
n: 0,
|
||||
c: 0,
|
||||
};
|
||||
const TOUT = 300000; // auto close timeout: 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)
|
||||
|
||||
///////////////////////
|
||||
// Self-repeating timeouts
|
||||
|
@ -44,7 +45,7 @@ function brightness() {
|
|||
if (!fade) {
|
||||
return 1;
|
||||
}
|
||||
return Math.max(0, 1-((Date.now()-fade)/TOUT));
|
||||
return Math.max(0, 1-((Date.now()-fade)/POUT));
|
||||
}
|
||||
|
||||
// Scroll long track names
|
||||
|
@ -396,26 +397,50 @@ function musicInfo(e) {
|
|||
if (Bangle.isLCDOn()) {
|
||||
drawMusic();
|
||||
}
|
||||
if (tIxt) {
|
||||
clearTimeout(tIxt);
|
||||
tIxt = null;
|
||||
}
|
||||
if (auto && stat==="play") {
|
||||
// if inactive for double song duration (or an hour if unknown), load the clock
|
||||
// i.e. phone finished playing without bothering to notify the watch
|
||||
tIxt = setTimeout(load, (info.dur*2000) || IOUT);
|
||||
}
|
||||
}
|
||||
|
||||
let tXit;
|
||||
let tPxt, tIxt;
|
||||
function musicState(e) {
|
||||
stat = e.state;
|
||||
// if paused for five minutes, load the clock
|
||||
// (but timeout resets if we get new info, even while paused)
|
||||
if (tXit) {
|
||||
clearTimeout(tXit);
|
||||
if (tPxt) {
|
||||
clearTimeout(tPxt);
|
||||
tPxt = null;
|
||||
}
|
||||
if (tIxt) {
|
||||
clearTimeout(tIxt);
|
||||
tIxt = null;
|
||||
}
|
||||
tXit = null;
|
||||
fade = null;
|
||||
delete info.track_color;
|
||||
if (stat!=="play" && auto) {
|
||||
if (stat==="stop") { // never actually happens with my phone :-(
|
||||
load();
|
||||
} else { // also quit when paused for a long time
|
||||
tXit = setTimeout(load, TOUT);
|
||||
fade = Date.now();
|
||||
fadeOut();
|
||||
if (auto) { // auto opened -> auto close
|
||||
switch(stat) {
|
||||
case "stop": // never actually happens with my phone :-(
|
||||
load();
|
||||
break;
|
||||
case "play":
|
||||
// if inactive for double song duration (or an hour if unknown), load the clock
|
||||
// i.e. phone finished playing without bothering to notify the watch
|
||||
tIxt = setTimeout(load, (info.dur*2000) || IOUT);
|
||||
break;
|
||||
case "pause":
|
||||
default:
|
||||
// quit when paused for a long time
|
||||
// also fade out track info while waiting for this
|
||||
tPxt = setTimeout(load, POUT);
|
||||
fade = Date.now();
|
||||
fadeOut();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Bangle.isLCDOn()) {
|
||||
|
@ -538,7 +563,7 @@ function startLCDWatch() {
|
|||
/////////////////////
|
||||
// check for saved music stat (by widget) to load
|
||||
g.clear();
|
||||
global.gbmusic_active = true; // we don't need our widget
|
||||
global.gbmusic_active = true; // we don't need our widget (needed for <2.09 devices)
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
delete (global.gbmusic_active);
|
||||
|
|
|
@ -1,38 +1,44 @@
|
|||
(() => {
|
||||
if (global.gbmusic_active || !(require("Storage").readJSON("gbmusic.json", 1) || {}).autoStart) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
if (typeof __FILE__ === 'string') { // only exists since 2v09
|
||||
const info = require("Storage").readJSON(__FILE__.split(".")[0]+".info", 1) || false;
|
||||
if (info && info.type!=="clock") { // info can have no type (but then it isn't a clock)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let state, info
|
||||
let state, info;
|
||||
function checkMusic() {
|
||||
if (state!=="play" || !info) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
// playing music: launch music app
|
||||
require("Storage").writeJSON("gbmusic.load.json", {
|
||||
state: state,
|
||||
info: info,
|
||||
})
|
||||
load("gbmusic.app.js")
|
||||
});
|
||||
load("gbmusic.app.js");
|
||||
}
|
||||
|
||||
const _GB = global.GB
|
||||
const _GB = global.GB;
|
||||
global.GB = (event) => {
|
||||
// we eat music events!
|
||||
switch(event.t) {
|
||||
case "musicinfo":
|
||||
info = event
|
||||
delete(info.t)
|
||||
checkMusic()
|
||||
break
|
||||
info = event;
|
||||
delete (info.t);
|
||||
checkMusic();
|
||||
break;
|
||||
case "musicstate":
|
||||
state = event.state
|
||||
checkMusic()
|
||||
break
|
||||
state = event.state;
|
||||
checkMusic();
|
||||
break;
|
||||
default:
|
||||
if (_GB) {
|
||||
setTimeout(_GB, 0, event)
|
||||
setTimeout(_GB, 0, event);
|
||||
}
|
||||
}
|
||||
}
|
||||
})()
|
||||
};
|
||||
})();
|
||||
|
|
Loading…
Reference in New Issue