gbmusic: simplify code some more
Remove Ticker classes, shorten some variable namesmaster
parent
5283f95320
commit
2de7a2dea0
|
|
@ -2,9 +2,8 @@
|
||||||
/**
|
/**
|
||||||
* Control the music on your Gadgetbridge-connected phone
|
* Control the music on your Gadgetbridge-connected phone
|
||||||
**/
|
**/
|
||||||
{
|
let auto = false; // auto close if opened automatically
|
||||||
let autoClose = false; // only if opened automatically
|
let stat = "";
|
||||||
let state = "";
|
|
||||||
let info = {
|
let info = {
|
||||||
artist: "",
|
artist: "",
|
||||||
album: "",
|
album: "",
|
||||||
|
|
@ -12,120 +11,68 @@
|
||||||
n: 0,
|
n: 0,
|
||||||
c: 0,
|
c: 0,
|
||||||
};
|
};
|
||||||
const TIMEOUT = 5*1000*60; // auto close timeout: 5 minutes
|
const TOUT = 300000; // auto close timeout: 5 minutes (in ms)
|
||||||
|
|
||||||
/**
|
///////////////////////
|
||||||
* Base ticker class, needs children to implement `redraw`
|
// Self-repeating timeouts
|
||||||
*/
|
///////////////////////
|
||||||
class Ticker {
|
|
||||||
constructor(ms) {
|
|
||||||
this.i = null;
|
|
||||||
this.ms = ms;
|
|
||||||
this.active = false;
|
|
||||||
this.onLCD = (on) => {
|
|
||||||
if (this.i) {
|
|
||||||
clearInterval(this.i);
|
|
||||||
this.i = null;
|
|
||||||
}
|
|
||||||
if (on) {
|
|
||||||
this.i = setInterval(() => {this.tick();}, this.ms);
|
|
||||||
this.redraw();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
start() {
|
|
||||||
if (this.i) {
|
|
||||||
clearInterval(this.i);
|
|
||||||
}
|
|
||||||
this.i = setInterval(() => {this.tick();}, this.ms);
|
|
||||||
this.active = true;
|
|
||||||
Bangle.on("lcdPower", this.onLCD);
|
|
||||||
}
|
|
||||||
stop() {
|
|
||||||
if (this.i) {
|
|
||||||
clearInterval(this.i);
|
|
||||||
this.i = null;
|
|
||||||
}
|
|
||||||
this.active = false;
|
|
||||||
Bangle.removeListener("lcdPower", this.onLCD);
|
|
||||||
}
|
|
||||||
tick() {
|
|
||||||
// default: just redraw
|
|
||||||
if (Bangle.isLCDOn()) {
|
|
||||||
this.redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Clock
|
||||||
* Draw time and date
|
let tock = -1;
|
||||||
*/
|
function tick() {
|
||||||
class Clock extends Ticker {
|
if (!Bangle.isLCDOn()) {
|
||||||
constructor() {
|
return;
|
||||||
super(1000);
|
|
||||||
this.lastTime = -1;
|
|
||||||
}
|
}
|
||||||
tick() {
|
|
||||||
// only redraw if time has changed
|
|
||||||
const now = new Date;
|
const now = new Date;
|
||||||
if (Bangle.isLCDOn() && now.getHours()*60+now.getMinutes()!==this.lastTime) {
|
if (now.getHours()*60+now.getMinutes()!==tock) {
|
||||||
this.redraw();
|
|
||||||
this.lastTime = now.getHours()*60+now.getMinutes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
redraw() {
|
|
||||||
drawDateTime();
|
drawDateTime();
|
||||||
|
tock = now.getHours()*60+now.getMinutes();
|
||||||
}
|
}
|
||||||
|
setTimeout(tick, 1000); // we only show minute precision anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Fade out while paused and auto closing
|
||||||
* Keep redrawing music while fading out
|
let fade = null;
|
||||||
*/
|
function fadeOut() {
|
||||||
class Fader extends Ticker {
|
if (!Bangle.isLCDOn() || !fade) {
|
||||||
constructor() {
|
return;
|
||||||
super(500);
|
|
||||||
}
|
}
|
||||||
redraw() {
|
|
||||||
drawMusic();
|
drawMusic();
|
||||||
|
setTimeout(fadeOut, 500);
|
||||||
}
|
}
|
||||||
start() {
|
function brightness() {
|
||||||
this.since = Date.now();
|
if (!fade) {
|
||||||
super.start();
|
|
||||||
}
|
|
||||||
stop() {
|
|
||||||
super.stop();
|
|
||||||
this.since = Date.now(); // force redraw at 100% brightness
|
|
||||||
this.redraw();
|
|
||||||
this.since = null;
|
|
||||||
}
|
|
||||||
brightness() {
|
|
||||||
if (!fadeOut.since) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return Math.max(0, 1-((Date.now()-fadeOut.since)/TIMEOUT));
|
return Math.max(0, 1-((Date.now()-fade)/TOUT));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Scroll long track names
|
||||||
* Scroll long track names
|
// use an interval to get smooth movement
|
||||||
*/
|
let offset = null, // scroll Offset: null = no scrolling
|
||||||
class Scroller extends Ticker {
|
scrollI;
|
||||||
constructor() {
|
function scroll() {
|
||||||
super(200);
|
offset += 10;
|
||||||
}
|
|
||||||
tick() {
|
|
||||||
this.offset += 10;
|
|
||||||
if (Bangle.isLCDOn()) {
|
|
||||||
this.redraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
redraw() {
|
|
||||||
drawScroller();
|
drawScroller();
|
||||||
}
|
}
|
||||||
start() {
|
function scrollStart() {
|
||||||
this.offset = 0;
|
if (offset!==null) {
|
||||||
super.start();
|
return; // already started
|
||||||
}
|
}
|
||||||
|
offset = 0;
|
||||||
|
if (Bangle.isLCDOn()) {
|
||||||
|
if (!scrollI) {
|
||||||
|
scrollI = setInterval(scroll, 200);
|
||||||
|
}
|
||||||
|
drawScroller();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function scrollStop() {
|
||||||
|
if (scrollI) {
|
||||||
|
clearInterval(scrollI);
|
||||||
|
scrollI = null;
|
||||||
|
}
|
||||||
|
offset = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -137,24 +84,47 @@
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
// make a guess, then shrink/grow until it fits
|
// make a guess, then shrink/grow until it fits
|
||||||
const getWidth = (size) => g.setFont("Vector", size).stringWidth(text);
|
const test = (s) => g.setFont("Vector", s).stringWidth(text);
|
||||||
let guess = Math.floor(24000/getWidth(100));
|
let best = Math.floor(24000/test(100));
|
||||||
if (getWidth(guess)===240) { // good guess!
|
if (test(best)===240) { // good guess!
|
||||||
return guess;
|
return best;
|
||||||
}
|
}
|
||||||
if (getWidth(guess)<240) {
|
if (test(best)<240) {
|
||||||
do {
|
do {
|
||||||
guess++;
|
best++;
|
||||||
} while(getWidth(guess)<=240);
|
} while(test(best)<=240);
|
||||||
return guess-1;
|
return best-1;
|
||||||
}
|
}
|
||||||
// width > 240
|
// width > 240
|
||||||
do {
|
do {
|
||||||
guess--;
|
best--;
|
||||||
} while(getWidth(guess)>240);
|
} while(test(best)>240);
|
||||||
return guess;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} text
|
||||||
|
* @return {number} Randomish but deterministic number from 0-360 for text
|
||||||
|
*/
|
||||||
|
function textCode(text) {
|
||||||
|
"ram";
|
||||||
|
let code = 0;
|
||||||
|
for(let i = 0; i<text.length; i++) {
|
||||||
|
code += text.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return code%360;
|
||||||
|
}
|
||||||
|
// dark magic
|
||||||
|
function hsv2rgb(h, s, v) {
|
||||||
|
const f = (n) => {
|
||||||
|
const k = (n+h/60)%6;
|
||||||
|
return v-v*s*Math.max(Math.min(k, 4-k, 1), 0);
|
||||||
|
};
|
||||||
|
return {r: f(5), g: f(3), b: f(1)};
|
||||||
|
}
|
||||||
|
function f2hex(f) {
|
||||||
|
return ("00"+(Math.round(f*255)).toString(16)).substr(-2);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @param name
|
* @param name
|
||||||
* @return {string} Semi-random color to use for given info
|
* @return {string} Semi-random color to use for given info
|
||||||
|
|
@ -168,13 +138,6 @@
|
||||||
} else {
|
} else {
|
||||||
// make color depend deterministically on info
|
// make color depend deterministically on info
|
||||||
let code = 0;
|
let code = 0;
|
||||||
const textCode = t => {
|
|
||||||
let c = 0;
|
|
||||||
for(let i = 0; i<t.length; i++) {
|
|
||||||
c += t.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return c%360;
|
|
||||||
};
|
|
||||||
switch(name) {
|
switch(name) {
|
||||||
case "track":
|
case "track":
|
||||||
code += textCode(info.track);
|
code += textCode(info.track);
|
||||||
|
|
@ -188,17 +151,8 @@
|
||||||
h = code%360;
|
h = code%360;
|
||||||
s = 0.7;
|
s = 0.7;
|
||||||
}
|
}
|
||||||
v = fadeOut.brightness();
|
v = brightness();
|
||||||
// dark magic
|
|
||||||
const hsv2rgb = (h, s, v) => {
|
|
||||||
const f = (n) => {
|
|
||||||
const k = (n+h/60)%6;
|
|
||||||
return v-v*s*Math.max(Math.min(k, 4-k, 1), 0);
|
|
||||||
};
|
|
||||||
return {r: f(5), g: f(3), b: f(1)};
|
|
||||||
};
|
|
||||||
const rgb = hsv2rgb(h, s, v);
|
const rgb = hsv2rgb(h, s, v);
|
||||||
const f2hex = (f) => ("00"+(Math.round(f*255)).toString(16)).substr(-2);
|
|
||||||
return "#"+f2hex(rgb.r)+f2hex(rgb.g)+f2hex(rgb.b);
|
return "#"+f2hex(rgb.r)+f2hex(rgb.g)+f2hex(rgb.b);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|
@ -207,7 +161,7 @@
|
||||||
* @return {string}
|
* @return {string}
|
||||||
*/
|
*/
|
||||||
function trackColor() {
|
function trackColor() {
|
||||||
if (!("track_color" in info) || fadeOut.active) {
|
if (!("track_color" in info) || fade) {
|
||||||
info.track_color = infoColor("track");
|
info.track_color = infoColor("track");
|
||||||
}
|
}
|
||||||
return info.track_color;
|
return info.track_color;
|
||||||
|
|
@ -223,17 +177,17 @@
|
||||||
function drawDateTime() {
|
function drawDateTime() {
|
||||||
const now = new Date;
|
const now = new Date;
|
||||||
const l = require("locale");
|
const l = require("locale");
|
||||||
const is12hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"];
|
const is12 = (require("Storage").readJSON("setting.json", 1) || {})["12hour"];
|
||||||
let time;
|
let time;
|
||||||
if (is12hour) {
|
if (is12) {
|
||||||
const date12 = new Date(now.getTime());
|
const d12 = new Date(now.getTime());
|
||||||
const hours = date12.getHours();
|
const hour = d12.getHours();
|
||||||
if (hours===0) {
|
if (hour===0) {
|
||||||
date12.setHours(12);
|
d12.setHours(12);
|
||||||
} else if (hours>12) {
|
} else if (hour>12) {
|
||||||
date12.setHours(hours-12);
|
d12.setHours(hour-12);
|
||||||
}
|
}
|
||||||
time = l.time(date12, true)+l.meridian(now);
|
time = l.time(d12, true)+l.meridian(now);
|
||||||
} else {
|
} else {
|
||||||
time = l.time(now, true);
|
time = l.time(now, true);
|
||||||
}
|
}
|
||||||
|
|
@ -265,7 +219,6 @@
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setFont("Vector", 30)
|
g.setFont("Vector", 30)
|
||||||
.setFontAlign(1, -1) // top right
|
.setFontAlign(1, -1) // top right
|
||||||
.setClipRect(225, 30, 120, 60)
|
|
||||||
.clearRect(225, 30, 120, 60)
|
.clearRect(225, 30, 120, 60)
|
||||||
.drawString(num, 225, 30);
|
.drawString(num, 225, 30);
|
||||||
}
|
}
|
||||||
|
|
@ -280,19 +233,17 @@
|
||||||
*/
|
*/
|
||||||
function drawTrack() {
|
function drawTrack() {
|
||||||
let size = fitText(info.track);
|
let size = fitText(info.track);
|
||||||
|
if (size<25) {
|
||||||
|
// the title is too long: start the scroller
|
||||||
|
scrollStart();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
scrollStop();
|
||||||
|
}
|
||||||
|
// stationary track
|
||||||
if (size>40) {
|
if (size>40) {
|
||||||
size = 40;
|
size = 40;
|
||||||
}
|
}
|
||||||
if (size<25) {
|
|
||||||
// the title is too long: start up the scroller
|
|
||||||
if (!scroller.active) {
|
|
||||||
scroller.start();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (scroller.active) {
|
|
||||||
scroller.stop();
|
|
||||||
}
|
|
||||||
// stationary track
|
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setFont("Vector", size)
|
g.setFont("Vector", size)
|
||||||
.setFontAlign(0, 1) // center bottom
|
.setFontAlign(0, 1) // center bottom
|
||||||
|
|
@ -307,12 +258,12 @@
|
||||||
g.reset();
|
g.reset();
|
||||||
g.setFont("Vector", 40);
|
g.setFont("Vector", 40);
|
||||||
const w = g.stringWidth(info.track)+40;
|
const w = g.stringWidth(info.track)+40;
|
||||||
scroller.offset = scroller.offset%w;
|
offset = offset%w;
|
||||||
g.setFontAlign(-1, 1) // left bottom
|
g.setFontAlign(-1, 1) // left bottom
|
||||||
.setColor(trackColor());
|
.setColor(trackColor());
|
||||||
clearTrack();
|
clearTrack();
|
||||||
g.drawString(info.track, -scroller.offset+40, 109)
|
g.drawString(info.track, -offset+40, 109)
|
||||||
.drawString(info.track, -scroller.offset+40+w, 109);
|
.drawString(info.track, -offset+40+w, 109);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -321,35 +272,43 @@
|
||||||
function drawArtistAlbum() {
|
function drawArtistAlbum() {
|
||||||
// we just use small enough fonts to make these always fit
|
// we just use small enough fonts to make these always fit
|
||||||
// calculate stuff before clear+redraw
|
// calculate stuff before clear+redraw
|
||||||
const artistColor = infoColor("artist");
|
const aCol = infoColor("artist");
|
||||||
const albumColor = infoColor("album");
|
const bCol = infoColor("album");
|
||||||
let artistSize = fitText(info.artist);
|
let aSiz = fitText(info.artist);
|
||||||
if (artistSize>30) {
|
if (aSiz>30) {
|
||||||
artistSize = 30;
|
aSiz = 30;
|
||||||
}
|
}
|
||||||
let albumSize = fitText(info.album);
|
let bSiz = fitText(info.album);
|
||||||
if (albumSize>20) {
|
if (bSiz>20) {
|
||||||
albumSize = 20;
|
bSiz = 20;
|
||||||
}
|
}
|
||||||
g.reset();
|
g.reset();
|
||||||
g.clearRect(0, 120, 240, 189);
|
g.clearRect(0, 120, 240, 189);
|
||||||
let top = 124;
|
let top = 124;
|
||||||
if (info.artist) {
|
if (info.artist) {
|
||||||
g.setFont("Vector", artistSize)
|
g.setFont("Vector", aSiz)
|
||||||
.setFontAlign(0, -1) // center top
|
.setFontAlign(0, -1) // center top
|
||||||
.setColor(artistColor)
|
.setColor(aCol)
|
||||||
.drawString(info.artist, 119, top);
|
.drawString(info.artist, 119, top);
|
||||||
top += artistSize+4; // fit album neatly under artist
|
top += aSiz+4; // fit album neatly under artist
|
||||||
}
|
}
|
||||||
if (info.album) {
|
if (info.album) {
|
||||||
g.setFont("Vector", albumSize)
|
g.setFont("Vector", bSiz)
|
||||||
.setFontAlign(0, -1) // center top
|
.setFontAlign(0, -1) // center top
|
||||||
.setColor(albumColor)
|
.setColor(bCol)
|
||||||
.drawString(info.album, 119, top);
|
.drawString(info.album, 119, top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const icons = {
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} icon Icon name
|
||||||
|
* @param {number} x
|
||||||
|
* @param {number} y
|
||||||
|
* @param {number} s Icon size
|
||||||
|
*/
|
||||||
|
function drawIcon(icon, x, y, s) {
|
||||||
|
({
|
||||||
pause: function(x, y, s) {
|
pause: function(x, y, s) {
|
||||||
const w1 = s/3;
|
const w1 = s/3;
|
||||||
g.drawRect(x, y, x+w1, y+s);
|
g.drawRect(x, y, x+w1, y+s);
|
||||||
|
|
@ -380,26 +339,27 @@
|
||||||
], true);
|
], true);
|
||||||
g.drawRect(x+w2, y, x+s, y+s);
|
g.drawRect(x+w2, y, x+s, y+s);
|
||||||
},
|
},
|
||||||
};
|
})[icon](x, y, s);
|
||||||
function controlColor(control) {
|
}
|
||||||
if (volCmd && control===volCmd) {
|
function controlColor(ctrl) {
|
||||||
|
if (vCmd && ctrl===vCmd) {
|
||||||
// volume button kept pressed down
|
// volume button kept pressed down
|
||||||
return "#ff0000";
|
return "#ff0000";
|
||||||
}
|
}
|
||||||
return (control in tCommand) ? "#ff0000" : "#008800";
|
return (ctrl in tCommand) ? "#ff0000" : "#008800";
|
||||||
}
|
}
|
||||||
function drawControl(control, x, y) {
|
function drawControl(ctrl, x, y) {
|
||||||
g.setColor(controlColor(control));
|
g.setColor(controlColor(ctrl));
|
||||||
const s = 20;
|
const s = 20;
|
||||||
if (state!==controlState) {
|
if (stat!==controlState) {
|
||||||
g.clearRect(x, y, x+s, y+s);
|
g.clearRect(x, y, x+s, y+s);
|
||||||
}
|
}
|
||||||
icons[control](x, y, s);
|
drawIcon(ctrl, x, y, s);
|
||||||
}
|
}
|
||||||
let controlState;
|
let controlState;
|
||||||
function drawControls() {
|
function drawControls() {
|
||||||
g.reset();
|
g.reset();
|
||||||
if (state==="play") {
|
if (stat==="play") {
|
||||||
// left touch
|
// left touch
|
||||||
drawControl("pause", 10, 190);
|
drawControl("pause", 10, 190);
|
||||||
// right touch
|
// right touch
|
||||||
|
|
@ -417,7 +377,7 @@
|
||||||
g.setFontAlign(1, 1);
|
g.setFontAlign(1, 1);
|
||||||
g.setColor(controlColor("volumedown"));
|
g.setColor(controlColor("volumedown"));
|
||||||
g.drawString("-", 240, 210);
|
g.drawString("-", 240, 210);
|
||||||
controlState = state;
|
controlState = stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawMusic() {
|
function drawMusic() {
|
||||||
|
|
@ -426,36 +386,40 @@
|
||||||
drawArtistAlbum();
|
drawArtistAlbum();
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////
|
////////////////////////
|
||||||
|
// GB event handlers
|
||||||
|
///////////////////////
|
||||||
/**
|
/**
|
||||||
* Update music info
|
* Update music info
|
||||||
* @param event
|
* @param e
|
||||||
*/
|
*/
|
||||||
function setInfo(event) {
|
function musicInfo(e) {
|
||||||
info = event;
|
info = e;
|
||||||
delete (info.t);
|
delete (info.t);
|
||||||
scroller.offset = 0;
|
offset = null;
|
||||||
if (Bangle.isLCDOn()) {
|
if (Bangle.isLCDOn()) {
|
||||||
drawMusic();
|
drawMusic();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tQuit;
|
let tXit;
|
||||||
function updateState() {
|
function musicState(e) {
|
||||||
|
stat = e.state;
|
||||||
// if paused for five minutes, load the clock
|
// if paused for five minutes, load the clock
|
||||||
// (but timeout resets if we get new info, even while paused)
|
// (but timeout resets if we get new info, even while paused)
|
||||||
if (tQuit) {
|
if (tXit) {
|
||||||
clearTimeout(tQuit);
|
clearTimeout(tXit);
|
||||||
}
|
}
|
||||||
tQuit = null;
|
tXit = null;
|
||||||
fadeOut.stop();
|
fade = null;
|
||||||
if (state!=="play" && autoClose) {
|
delete info.track_color;
|
||||||
if (state==="stop") { // never actually happens with my phone :-(
|
if (stat!=="play" && auto) {
|
||||||
|
if (stat==="stop") { // never actually happens with my phone :-(
|
||||||
load();
|
load();
|
||||||
} else { // also quit when paused for a long time
|
} else { // also quit when paused for a long time
|
||||||
tQuit = setTimeout(load, TIMEOUT);
|
tXit = setTimeout(load, TOUT);
|
||||||
fadeOut.start();
|
fade = Date.now();
|
||||||
|
fadeOut();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Bangle.isLCDOn()) {
|
if (Bangle.isLCDOn()) {
|
||||||
|
|
@ -463,11 +427,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create tickers
|
|
||||||
const clock = new Clock();
|
|
||||||
const fadeOut = new Fader();
|
|
||||||
const scroller = new Scroller();
|
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
// Events
|
// Events
|
||||||
////////////////////
|
////////////////////
|
||||||
|
|
@ -512,7 +471,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// BTN1/3: volume control (with repeat after long-press)
|
// BTN1/3: volume control (with repeat after long-press)
|
||||||
let tVol, volCmd;
|
let tVol, vCmd;
|
||||||
function volUp() {
|
function volUp() {
|
||||||
volStart("up");
|
volStart("up");
|
||||||
}
|
}
|
||||||
|
|
@ -523,11 +482,11 @@
|
||||||
const command = "volume"+dir;
|
const command = "volume"+dir;
|
||||||
stopVol();
|
stopVol();
|
||||||
sendCommand(command);
|
sendCommand(command);
|
||||||
volCmd = command;
|
vCmd = command;
|
||||||
tVol = setTimeout(repeatVol, 500);
|
tVol = setTimeout(repeatVol, 500);
|
||||||
}
|
}
|
||||||
function repeatVol() {
|
function repeatVol() {
|
||||||
sendCommand(volCmd);
|
sendCommand(vCmd);
|
||||||
tVol = setTimeout(repeatVol, 100);
|
tVol = setTimeout(repeatVol, 100);
|
||||||
}
|
}
|
||||||
function stopVol() {
|
function stopVol() {
|
||||||
|
|
@ -535,7 +494,7 @@
|
||||||
clearTimeout(tVol);
|
clearTimeout(tVol);
|
||||||
tVol = null;
|
tVol = null;
|
||||||
}
|
}
|
||||||
volCmd = null;
|
vCmd = null;
|
||||||
drawControls();
|
drawControls();
|
||||||
}
|
}
|
||||||
function startVolWatches() {
|
function startVolWatches() {
|
||||||
|
|
@ -547,16 +506,16 @@
|
||||||
|
|
||||||
// touch/swipe: navigation
|
// touch/swipe: navigation
|
||||||
function togglePlay() {
|
function togglePlay() {
|
||||||
sendCommand(state==="play" ? "pause" : "play");
|
sendCommand(stat==="play" ? "pause" : "play");
|
||||||
}
|
}
|
||||||
function startTouchWatches() {
|
function startTouchWatches() {
|
||||||
Bangle.on("touch", function(side) {
|
Bangle.on("touch", function(side) {
|
||||||
switch(side) {
|
switch(side) {
|
||||||
case 1:
|
case 1:
|
||||||
sendCommand(state==="play" ? "pause" : "previous");
|
sendCommand(stat==="play" ? "pause" : "previous");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
sendCommand(state==="play" ? "next" : "play");
|
sendCommand(stat==="play" ? "next" : "play");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
togglePlay();
|
togglePlay();
|
||||||
|
|
@ -569,7 +528,7 @@
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// Startup
|
// Startup
|
||||||
/////////////////////
|
/////////////////////
|
||||||
// check for saved music state (by widget) to load
|
// check for saved music stat (by widget) to load
|
||||||
g.clear();
|
g.clear();
|
||||||
global.gbmusic_active = true; // we don't need our widget
|
global.gbmusic_active = true; // we don't need our widget
|
||||||
Bangle.loadWidgets();
|
Bangle.loadWidgets();
|
||||||
|
|
@ -599,11 +558,10 @@
|
||||||
// we eat music events!
|
// we eat music events!
|
||||||
switch(event.t) {
|
switch(event.t) {
|
||||||
case "musicinfo":
|
case "musicinfo":
|
||||||
setInfo(event);
|
musicInfo(event);
|
||||||
break;
|
break;
|
||||||
case "musicstate":
|
case "musicstate":
|
||||||
state = event.state;
|
musicState(event);
|
||||||
updateState();
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// pass on other events
|
// pass on other events
|
||||||
|
|
@ -614,26 +572,38 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
drawMusic();
|
drawMusic();
|
||||||
updateState();
|
drawControls();
|
||||||
startWatches();
|
startWatches();
|
||||||
clock.start();
|
tick();
|
||||||
startEmulator();
|
startEmulator();
|
||||||
Bangle.on("lcdPower", function(on) {
|
Bangle.on("lcdPower", (on) => {
|
||||||
if (on) {
|
if (on) {
|
||||||
|
tick();
|
||||||
drawMusic();
|
drawMusic();
|
||||||
drawControls();
|
drawControls();
|
||||||
|
fadeOut();
|
||||||
|
if (offset!==null) {
|
||||||
|
drawScroller();
|
||||||
|
scrollI = setInterval(scroll, 200);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (scrollI) {
|
||||||
|
clearInterval(scrollI);
|
||||||
|
scrollI = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
let saved = require("Storage").readJSON("gbmusic.load.json", true);
|
let saved = require("Storage").readJSON("gbmusic.load.json", true);
|
||||||
require("Storage").erase("gbmusic.load.json");
|
require("Storage").erase("gbmusic.load.json");
|
||||||
if (saved) {
|
if (saved) {
|
||||||
// autoloaded: load state was saved by widget
|
// autoloaded: load state was saved by widget
|
||||||
info = saved.info;
|
info = saved.info;
|
||||||
state = saved.state;
|
stat = saved.state;
|
||||||
delete (saved);
|
delete (saved);
|
||||||
autoClose = true;
|
auto = true;
|
||||||
start();
|
start();
|
||||||
} else {
|
} else {
|
||||||
const s = require("Storage").readJSON("gbmusic.json", 1) || {};
|
const s = require("Storage").readJSON("gbmusic.json", 1) || {};
|
||||||
|
|
@ -653,3 +623,5 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
init();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue