tweak swipe animations, use UI swipe mode for left right swipes to try to make it feel snappier, fix scrolling issues

master
Bryan 2024-08-10 22:34:23 -06:00
parent df67d082fa
commit 136c73a85f
4 changed files with 246 additions and 181 deletions

View File

@ -1,5 +1,3 @@
let options = {
srcFont: "6x8",
titleFont: "12x20",
@ -32,8 +30,8 @@ const centerString = (str, x, y, w) => {
HeaderBox = function(msg, messageRect) {
this.icon = require("messageicons").getImage(msg);
this.color = require("messageicons").getColor(msg, {default:g.theme.fg2});
this.iconW = 48;
this.titleW = messageRect.w - this.iconW;
this.iconSize = 48;
this.titleW = messageRect.w - this.iconSize;
if (!msg.body) this.titleLines = "";
else {
this.titleLines = (() => {
@ -50,14 +48,14 @@ HeaderBox = function(msg, messageRect) {
this.titleX = 0;
this.titleY = 0;
this.srcLineH = g.setFont(options.srcFont).getFontHeight();
this.srcLines = g.wrapString(msg.src, this.iconW);
this.srcLines = g.wrapString(msg.src, this.iconSize);
this.srcH = this.srcLineH * this.srcLines.length;
this.srcX = this.x2 - this.iconW;
this.srcX = this.x2 - this.iconSize;
this.srcY = 0;
this.im = g.imageMetrics(this.icon);
this.imgX = this.titleW + ((this.iconW - this.im.width) / 2);
this.imgX = this.titleW + ((this.iconSize - this.im.width) / 2);
this.minH = Math.max(this.titleLineH, this.srcH + this.im.height) + options.padding;
this.maxH = Math.max(this.titleLineH * this.titleLines.length, this.iconW) + options.padding;
this.maxH = Math.max(this.titleLineH * this.titleLines.length, this.iconSize) + options.padding;
this.h = this.maxH;
this.new = msg.new ?? false;
}; // HeaderBox
@ -77,7 +75,7 @@ HeaderBox.prototype.draw = function(messageRect) {
g.setColor(options.headerFgColor);
g.setFont(options.titleFont);
if (this.h > this.minH) { // multi-line title
let titleY = y + 3;
let titleY = Math.floor(((this.h - options.padding - (this.titleLineH * this.titleLines.length)) / 2) + y);
if (this.titleLines) {
for (let line of this.titleLines) {
centerString(line, x, titleY, this.titleW);
@ -92,7 +90,7 @@ HeaderBox.prototype.draw = function(messageRect) {
if (this.h == this.maxH) {
let srcY = y+4;
for (let line of this.srcLines) {
centerString(line, x2 - this.iconW, srcY, this.iconW);
centerString(line, x2 - this.iconSize, srcY, this.iconSize);
srcY += this.srcLineH;
}
}
@ -107,8 +105,7 @@ const TextBox = function(msg, messageRect) {
if (msg.subject) { // If there's a subject, add it to the top
lines.splice(0, 0, msg.subject);
}
this.initScrollY = 0;
this.scrollY = this.initScrollY;
this.scrollY = 0;
this.minY = messageRect.y2 - (this.lineH * (this.lines.length + 3));
if (this.minY > 0) this.minY = 0;
}; // TextBox
@ -144,7 +141,7 @@ MessageBox = function(msg, yOffset) {
this.headerBox = new HeaderBox(msg, this.rect);
this.textBox = new TextBox(msg, this.rect);
let messageH = this.textBox.lines.length * this.textBox.lineH;
let boxH = this.rect.h - this.headerBox.maxH;
let boxH = this.rect.h - this.headerBox.maxH - options.fh;
if ( messageH <= boxH) this.oneScreen = true;
else this.oneScreen = false;
this.top = true;
@ -155,6 +152,7 @@ MessageBox = function(msg, yOffset) {
this.bottom = false;
this.textBox.initScrollY = 0;
}
this.textBox.scrollY = this.textBox.initScrollY;
this.sbH = this.rect.h / messageH * this.rect.h; // scrollbar height
this.sbRatio = (this.rect.h - this.sbH) / Math.abs(this.textBox.minY); // scrollbar ratio
}; // MessageBox
@ -201,9 +199,10 @@ MessageBox.prototype.drawScrollbar = function() {
};
MessageBox.prototype.scroll = function(dy) {
if ((dy > 0 && this.top) || (dy < 0 && this.bottom)) {
return;
}
if (this.oneScreen) return;
// if ((dy > 0 && this.top) || (dy < 0 && this.bottom)) {
// return;
// }
if (this.headerBox.h > this.headerBox.minH && dy < 0) {
this.headerBox.h += dy;
if (this.headerBox.h < this.headerBox.minH) this.headerBox.h = this.headerBox.minH;
@ -228,44 +227,7 @@ MessageBox.prototype.scroll = function(dy) {
this.draw();
};
// SwipeBox = function(msg, screenRect) {
// this.msg = msg;
// this.screenRect = screenRect;
//
// console.log("screenRect = ", screenRect);
// console.log("this.screenRect = ", this.screenRect);
// this.headerBox = new HeaderBox(msg, screenRect);
// //this.bodyRect = {x: screenRect.x, y: screenRect.y + headerBox.h, x2: screenRect.x2, y2: screenRect.y2};
//
// };
//
// SwipeBox.prototype.draw = function(xOffset) {
// const x = this.screenRect.x, y = this.screenRect.y + this.headerBox.h, x2 = this.screenRect.x2, y2 = this.screenRect.y2;
// //const w = x2 - x + 1;
// const mx = (x + x2) / 2;
// //const yOff = 127 - this.headerBox.h;
// this.headerBox.draw(this.screenRect);
// g.reset();
//
// // g.setFont("6x15:2").setFontAlign(0,-1);
// // g.drawString(this.msg.body, mx, y);
// g.setColor(0,1,0);
// g.drawImage(incomingImg, mx-25, y+20);
//
// const drawArrows = function(xOffset) {
// g.setColor(1 ,0.25, 0.25);
// g.drawImage(leftImg, x+2, y2-50);
// g.setColor(0, 1, 0);
// g.drawImage(rightImg, x2-50, y2-50);
//
// }
//
// drawArrows(xOffset);
// };
module.exports.HeaderBox = HeaderBox;
module.exports.MessageBox = MessageBox;
//module.exports.SwipeBox = SwipeBox;
module.exports.setOptions = setOptions;
module.exports.setClipRect = setClipRect;

View File

@ -2,8 +2,8 @@
// let settings = require('Storage').readJSON("messages.settings.json", true) || {};
// const settings = () => require("messagegui").settings();
const fontTiny = "6x8"; // fixed size, don't use this for important things
let fontNormal;
// let fontTiny = "6x8"; // fixed size, don't use this for important things
// let fontNormal;
// setFont() is also called after we close the settings screen
// const setFont = function() {
// const fontSize = settings().fontSize;
@ -45,13 +45,15 @@ const setListener = function(event, callback) {
const _cleanup = function() {
for (let e in events) if (e) Bangle.removeListener(e, events[e]);
for (let t in timeouts) if (timeouts[t]) clearTimeout(timeouts[t]);
console.log(timeouts);
for (let t in timeouts) clearTimeout(timeouts[t]);
require("messages").stopBuzz();
require("widget_utils").show();
Bangle.drawWidgets();
};
const clearTimeouts = function() {
for (let t in timeouts) if (timeouts[t]) clearTimeout(timeouts[t]);
for (let t in timeouts) clearTimeout(timeouts[t]);
};
const showNoMessages = function() {
@ -120,31 +122,44 @@ const showCall = function(call) {
headerBox.draw(Bangle.appRect);
g.reset();
const drawLeftArrow = function(imgX) {
imgX = imgX ?? x+2;
g.setColor(1 ,0.25, 0.25);
g.drawImage(leftImg, imgX, y2-50);
};
const drawRightArrow = function(imgX) {
imgX = imgX ?? x2-50;
const drawAcceptArrow = function(xOffset) {
xOffset = xOffset??0;
imgX = x + 2 + xOffset;
g.setColor(0, 1, 0);
g.drawImage(rightImg, imgX, y2-50);
//if (xOffset > 0) g.fillRect(imgX+3, y2-43, x, y2-9);
};
const drawRejectArrow = function(xOffset) {
xOffset = xOffset??0;
let imgX = x2 - 50 - xOffset;
g.setColor(1, 0.25, 0.25);
g.drawImage(leftImg, imgX, y2-50);
//if (xOffset > 0) g.fillRect(imgX+45, y2-43, x2, y2-9);
};
if (cmd === "end") {
console.log("end");
if (timeouts.timer) clearTimeout(timeouts.timer);
let elapsedString = Bangle.elapsedString;
delete Bangle.elapsedString;
g.setColor(g.theme.fg).setFont("6x15:2").setFontAlign(0, -1);
g.drawString("Call Ended", mx, y+25);
endTimeout = setTimeout(() => g.clear(), 3000);
g.setFont("Vector:25").setFontAlign(0, -1).drawString(elapsedString, mx, y+25);
g.drawString("Call Ended", mx, y);
const done = new Promise((resolve, _reject) => {
setTimeout(() => {resolve();}, 5000);
});
done.then(goBack);
}
if (cmd === "incoming") {
drawLeftArrow();
drawRightArrow();
drawRejectArrow();
drawAcceptArrow();
g.setColor(0,1,0);
g.drawImage(ringingImg, mx-25, y+15);
}
if (cmd === "start" || cmd === "outgoing") {
drawLeftArrow(x2 - 52);
drawRejectArrow();
startTime = parseInt(Date.now()/1000);
g.setColor(g.theme.fg);
g.drawImage(cmd === "start" ? incomingImg : outgoingImg, x+10, y+20);
@ -154,23 +169,62 @@ const showCall = function(call) {
const h = ("0" + Math.floor((elapsed/3600)%60)).slice(-2);
const m = ("0" + Math.floor((elapsed/60)%60)).slice(-2);
const s = ("0" + Math.floor(elapsed%60)).slice(-2);
g.setFont("Vector:25").setFontAlign(0, -1).drawString(`${h}:${m}:${s}`, mx + 15, y+25);
timeouts.timer = setTimeout(timer, 1000);
Bangle.elapsedString = `${h}:${m}:${s}`;
g.setFont("Vector:25").setFontAlign(0, -1).drawString(Bangle.elapsedString, mx + 15, y+25);
timeouts["timer"] = setTimeout(timer, 1000);
};
timer();
}
const handler = function(dir) {
if (cmd === "end") return;
if (dir < 0) return Bangle.messageResponse(msg, false);
else if (dir > 0 && cmd === "incoming") return Bangle.messageResponse(msg, true);
if (dir < 0) leftHandler(dir);
else if (dir > 0 && cmd === "incoming") rightHandler();
};
const leftHandler = function(dir) {
let xOff = 0;
const animate = new Promise((resolve, _reject) => {
const swipeAnimation = () => {
xOff += 30;
g.clearRect(x, y2-50, x2, y2);
drawRejectArrow(xOff);
if (xOff > 160) return resolve();
else setTimeout(swipeAnimation, 30);
}
swipeAnimation();
});
animate.then(() => {
if (timeouts.timer) clearTimeout(timeouts["timer"]);
Bangle.messageResponse(msg, false);
goBack();
});
};
const rightHandler = function(dir) {
let xOff = 0;
const animate = new Promise((resolve, _reject) => {
const swipeAnimation = () => {
xOff += 30;
g.clearRect(x, y2-50, x2, y2);
drawAcceptArrow(xOff);
if (xOff > 160) return resolve();
else setTimeout(swipeAnimation, 30);
}
swipeAnimation();
});
animate.then(() => {
if (timeouts.timer) clearTimeout(timeouts["timer"]);
Bangle.messageResponse(msg, true);
goBack();
});
};
Bangle.setUI({
mode: "custom",
touch: () => {if (buzzing) return require("messages".stopBuzz())},
touch: () => {if (buzzing) return require("messages").stopBuzz()},
swipe: handler,
btn: _e => goBack(),
btn: _e => goBack,
remove: cleanup
});
};
@ -179,8 +233,8 @@ const showText = function(messageNum) {
g.reset().clear();
if (!Bangle.MESSAGES.length) return goBack(); // no messages
setBusy(); // busy until everything is set up
let showAll = false;
if (messageNum === undefined) {messageNum = 0; showAll = true;}
//let showAll = false;
if (messageNum === undefined) {messageNum = 0;} //showAll = true;}
else if (messageNum >= Bangle.MESSAGES.length - 1) messageNum = Bangle.MESSAGES.length - 1;
Bangle.setUI(); // make sure to clear setUI from anything previous
let switching = false;
@ -188,19 +242,19 @@ const showText = function(messageNum) {
require("messagebox").setOptions({fh: 20});
const step = 42;
const delay = 30;
const swipeThreshold = 20;
//const swipeThreshold = 20;
let mode = "scroll"; // one of "scroll", "next", "prev" (switch to next/prev message), "swipe" (swipe to delete or archive)
msgIdx = messageNum; // global message index
// TODO we might have to append array of (m.show && !m.new) to array of m.new so that all new messages are at the beginning of list
let messageList = showAll ? Bangle.MESSAGES : Bangle.MESSAGES.filter(m => m.new || m.show);
if (!messageList.length) return goBack();
//let messageList = showAll ? Bangle.MESSAGES : Bangle.MESSAGES.filter(m => m.new || m.show || !m.handled);
//if (!messageList.length) return goBack();
// Bangle.setLocked(false); // TODO make as option
// Bangle.setLCDPower(true); // TODO make as option
let msgBoxes = [];
let i = 0;
for (let msg of messageList) {
for (let msg of Bangle.MESSAGES) {
msgBoxes[i] = new MessageBox(msg);
if (i === messageNum - 1) msgBoxes[i].yOffset = MessageBox.prototype.prevOffset;
else if (i === messageNum) {
@ -214,30 +268,24 @@ const showText = function(messageNum) {
const drawFooter = function() {
let fh = 20; // footer height
// left hint: swipe from left for main menu
g.reset().setBgColor(g.theme.bg2).clearRect(Bangle.appRect.x, Bangle.appRect.y2-fh, Bangle.appRect.x2, Bangle.appRect.y2)
g.reset().setBgColor(g.theme.bg).clearRect(Bangle.appRect.x, Bangle.appRect.y2-fh, Bangle.appRect.x2, Bangle.appRect.y2)
.setColor(g.theme.bgH).drawLine(Bangle.appRect.x, Bangle.appRect.y2-fh, Bangle.appRect.x2, Bangle.appRect.y2-fh)
.setFont("6x15") // TODO make as option
.setFontAlign(-1, 1) // bottom left
.drawString(
//"\0"+atob("CAiBAEgkEgkSJEgA"), // >>
">>",
Bangle.appRect.x + 1, Bangle.appRect.y2
);
.setFontAlign(-1, 1).setColor(0, 1, 0) //bottom left
.drawString(">>", Bangle.appRect.x + 1, Bangle.appRect.y2);
// center message count+hints: swipe up/down for next/prev message
const footer = ` ${messageNum + 1}/${msgBoxes.length} `;
const fw = g.stringWidth(footer);
g.setFontAlign(0, 1); // bottom center
g.drawString(footer, Bangle.appRect.x+Bangle.appRect.w/2, Bangle.appRect.y2);
g.setFontAlign(0, 1).setColor(g.theme.fg) // bottom center
.drawString(footer, Bangle.appRect.x+Bangle.appRect.w/2, Bangle.appRect.y2);
if (messageNum < Bangle.MESSAGES.length - 1 && msgBoxes[messageNum].bottom)
g.drawString("\0"+atob("CAiBAABBIhRJIhQI"), Bangle.appRect.x+Bangle.appRect.w/2-fw/2 - 20, Bangle.appRect.y2); // v swipe to next
if (messageNum > 0 && msgBoxes[messageNum].top)
g.drawString("\0"+atob("CAiBABAoRJIoRIIA"), Bangle.appRect.x+Bangle.appRect.w/2+fw/2 + 20, Bangle.appRect.y2); // ^ swipe to prev
// right hint: swipe from right for message actions
g.setFontAlign(1, 1) // bottom right
.drawString(
//"\0"+atob("CAiBABIkSJBIJBIA"), // <<
"<<",
Bangle.appRect.x2 - 1, Bangle.appRect.y2
);
g.setFontAlign(1, 1).setColor(1, 0.25, 0.25) // bottom right
.drawString("<<", Bangle.appRect.x2 - 1, Bangle.appRect.y2)
.setColor(g.theme.fg);
};
const refresh = function() {
@ -317,8 +365,8 @@ const showText = function(messageNum) {
msgBoxes[messageNum].draw();
msgBoxes[messageNum + 1].draw();
drawFooter();
multiplier *= 2;
timeouts.animID = setTimeout(animate, delay);
multiplier *= 2.5;
timeouts["animID"] = setTimeout(animate, delay);
}
};
animate();
@ -352,8 +400,8 @@ const showText = function(messageNum) {
msgBoxes[messageNum].draw();
msgBoxes[messageNum - 1].draw();
drawFooter();
multiplier *= 2;
timeouts.animID = setTimeout(animate, delay);
multiplier *= 2.5;
timeouts["animID"] = setTimeout(animate, delay);
}
};
animate();
@ -361,17 +409,19 @@ const showText = function(messageNum) {
};
const drawLeftBackground = function() {
g.setBgColor(1, 0.5, 0); // red
g.setClipRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2);
g.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2);
g.setBgColor(g.theme.bg);
//g.setBgColor(1, 0.5, 0); // red
g.setBgColor(g.theme.bg)
.setClipRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2)
.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2)
.setBgColor(g.theme.bg);
};
const drawRightBackground = function() {
g.setBgColor(0, 0.5, 1); // red
g.setClipRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2);
g.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2);
g.setBgColor(g.theme.bg);
//g.setBgColor(0, 0.5, 1); // red
g.setBgColor(g.theme.bg)
.setClipRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2)
.clearRect(Bangle.appRect.x, Bangle.appRect.y, Bangle.appRect.x2, Bangle.appRect.y2)
.setBgColor(g.theme.bg);
};
const animateToLeft = function() {
@ -379,18 +429,20 @@ const showText = function(messageNum) {
clearTimeout(timeouts.animID);
timeouts.animID = undefined;
}
const endX = Bangle.appRect.x + (Bangle.appRect.w / 2);
let multiplier = 1;
const endX = Bangle.appRect.x - Bangle.appRect.w; //+ (Bangle.appRect.w / 2);
const msgBox = msgBoxes[messageNum];
return new Promise((resolve, _reject) => {
let animate = () => {
msgBox.xOffset -= step;
msgBox.xOffset -= step * multiplier;
multiplier *= 2.5;
drawLeftBackground();
if (msgBox.xOffset <= endX) {
return resolve();
} else {
msgBox.draw();
drawFooter();
timeouts.animID = setTimeout(animate, delay);
timeouts["animID"] = setTimeout(animate, delay);
}
};
animate();
@ -402,18 +454,20 @@ const showText = function(messageNum) {
clearTimeout(timeouts.animID);
timeouts.animID = undefined;
}
const endX = Bangle.appRect.x2 - (Bangle.appRect.w / 2);
let multiplier = 1;
const endX = Bangle.appRect.x2; // - (Bangle.appRect.w / 2);
const msgBox = msgBoxes[messageNum];
return new Promise((resolve, _reject) => {
let animate = () => {
msgBox.xOffset += step;
msgBox.xOffset += step * multiplier;
multiplier *= 2.5;
drawRightBackground();
if (msgBox.xOffset >= endX) {
return resolve();
} else {
msgBox.draw();
drawFooter();
timeouts.animID = setTimeout(animate, delay);
timeouts["animID"] = setTimeout(animate, delay);
}
};
animate();
@ -421,7 +475,7 @@ const showText = function(messageNum) {
};
let firstTouch = true;
const handler = function(e) {
const dragHandler = function(e) {
if (e.b === 0) {
firstTouch = true;
checkForNewMessages();
@ -438,28 +492,30 @@ const showText = function(messageNum) {
msgBoxes[messageNum].clearNew();
if (Math.abs(e.dy) > Math.abs(e.dx)) {
firstTouch = false;
if (e.dy > 0 && msgBoxes[messageNum].top) {
if (e.dy > 0 && msgBoxes[messageNum].top && messageNum > 0) {
mode = "prev";
} else if (msgBoxes[messageNum].bottom) { // e.dy will be < 0 here
} else if (e.dy < 0 && msgBoxes[messageNum].bottom && messageNum + 1 < msgBoxes.length) { // e.dy will be < 0 here
mode = "next";
} else {
mode = "scroll";
}
} else if (Math.abs(e.dx) > Math.abs(e.dy)) {
firstTouch = false;
if (e.dx < 0) {
mode = "left";
} else {
mode = "right";
}
} else {
// } else if (Math.abs(e.dx) > Math.abs(e.dy)) {
// firstTouch = false;
// if (e.dx < 0) {
// mode = "left";
// } else {
// mode = "right";
// }
// } else {
else {
mode = undefined;
return;
}
}
if (mode == "scroll") scrollHandler(e);
else if (mode == "left") leftHandler(e); // remove from phone and watch
else if (mode == "right") rightHandler(e); // remove from watch only
//else if (mode == "left") leftHandler(e); // remove from phone and watch
//else if (mode == "right") rightHandler(e); // remove from watch only
else if (mode == "next") nextHandler(e);
else if (mode == "prev") prevHandler(e);
};
@ -484,14 +540,20 @@ const showText = function(messageNum) {
});
};
const swipeHandler = function(dir) {
if (dir > 0) return rightHandler();
else if (dir < 0) return leftHandler();
else return;
};
const leftHandler = function(e) {
const msgBox = msgBoxes[messageNum];
if (e.b == 0) {
if (msgBox.xOffset > -swipeThreshold) {
msgBox.xOffset = 0;
msgBox.draw();
drawFooter();
} else {
// if (e.b == 0) {
// if (msgBox.xOffset > -swipeThreshold) {
// msgBox.xOffset = 0;
// msgBox.draw();
// drawFooter();
// } else {
switching = true;
animateToLeft().then(() => {
g.setBgColor(g.theme.bg);
@ -499,38 +561,38 @@ const showText = function(messageNum) {
removeMessage();
switching = false;
});
}
return;
}
msgBox.xOffset += e.dx;
if (msgBox.xOffset > 0) msgBox.xOffset = 0;
drawLeftBackground();
msgBox.draw();
drawFooter();
// }
// return;
// }
// msgBox.xOffset += e.dx;
// if (msgBox.xOffset > 0) msgBox.xOffset = 0;
// drawLeftBackground();
// msgBox.draw();
// drawFooter();
};
const rightHandler = function(e) {
const msgBox = msgBoxes[messageNum];
if (e.b == 0) {
if (msgBox.xOffset < swipeThreshold) {
msgBox.xOffset = 0;
msgBox.draw();
drawFooter();
} else {
// if (e.b == 0) {
// if (msgBox.xOffset < swipeThreshold) {
// msgBox.xOffset = 0;
// msgBox.draw();
// drawFooter();
// } else {
switching = true;
animateToRight().then(() => {
g.setBgColor(g.theme.bg);
removeMessage();
switching = false;
});
}
return;
}
msgBox.xOffset += e.dx;
if (msgBox.xOffset < 0) msgBox.xOffset = 0;
drawRightBackground();
msgBox.draw();
drawFooter();
// }
// return;
// }
// msgBox.xOffset += e.dx;
// if (msgBox.xOffset < 0) msgBox.xOffset = 0;
// drawRightBackground();
// msgBox.draw();
// drawFooter();
};
const scrollHandler = function(e) {
@ -541,7 +603,8 @@ const showText = function(messageNum) {
Bangle.setUI({
mode: "custom",
drag: e => handler(e),
drag: e => dragHandler(e),
swipe: dir => swipeHandler(dir),
btn: _e => goBack(),
remove: cleanup
});
@ -557,7 +620,7 @@ const checkForNewMessages = function(idleTime) {
idleTime = idleTime ?? 3000; // how much time without interaction before we are considered idle
idle = false;
if (timeouts.idleTimer) clearTimeout(timeouts.idleTimer);
timeouts.idleTimer = setTimeout(() => {
timeouts["idleTimer"] = setTimeout(() => {
if (haveNewMessage) {
haveNewMessage = false;
let idx = Bangle.MESSAGES.findIndex(m => !m.handled);
@ -580,17 +643,19 @@ const setBusy = function() {
timeouts.idleTimer = undefined;
};
const goBack = function(timedOut) { // TODO do we want this as a stack or by priority?
const goBack = function(timedOut) {
console.log("goBack()");
idle = true;
if (buzzing) require("messages").stopBuzz();
let backTo;
if (previous && previous.length) {
backTo = previous.pop();
clearTimeouts();
} else {
if (!timedOut) Bangle.MESSAGES.forEach((m) => {if (!m.new) m.show = false;});
require("messages").write(Bangle.MESSAGES);
cleanup = _cleanup;
Bangle.showClock();
Bangle.load();
}
//console.log("backTo = ", backTo);
switch (backTo) {
@ -676,7 +741,6 @@ const showMessage = function() {
idx = Bangle.MESSAGES.findIndex(m => !m.handled);
if (idx >= 0) {
Bangle.MESSAGES.every(m => m.handled = true); // set all text messages as handled
//for (let m of Bangle.MESSAGES) m.handled = true; // set all text messages as handled
setActive("text");
return showText(idx);
}
@ -688,7 +752,6 @@ const showMessage = function() {
saveMessages = function() {
require("messages").write(Bangle.MESSAGES);
};
//E.on("kill", events.saveMessages);
setListener("kill", saveMessages);
Bangle.loadWidgets();

View File

@ -1,3 +1,8 @@
let timeouts = {};
const goBack = function() {};
const cleanup = function() {};
const showCall = function(call) {
const incomingImg = require("heatshrink").decompress(atob("j0ewIQNgwDCnEAh0B4EAvEOgEB+F//kP4P/+E/weAgH+g8Agf4CQMH8EYgEfEYU8AYV4AQIhBAYMD8ADBg4vBgEPzwDBj/+AYM/AYV//ADCC4X/EwQiCABo="));
const outgoingImg = require("heatshrink").decompress(atob("j0ewIRO4ACBgeAh0Ag8AvEAh0B+F//kP4P/+E/wASB/0AjkD/EA8EH8EDgEfEwU8AYQhBgAhBFwXgAYMHGwUPzwDBj4mBgE/AYV/FQIDBC4X/EwQiCABoA=="));
@ -18,35 +23,38 @@ const showCall = function(call) {
const headerBox = new HeaderBox(msg, Bangle.appRect);
const x = Bangle.appRect.x, y = Bangle.appRect.y + headerBox.h, x2 = Bangle.appRect.x2, y2 = Bangle.appRect.y2;
const mx = (x + x2) / 2;
let timerInt; //TODO deal with this
headerBox.draw(Bangle.appRect);
g.reset();
const drawLeftArrow = function(imgX) {
imgX = imgX ?? x+2;
g.setColor(1 ,0.25, 0.25);
g.drawImage(leftImg, imgX, y2-50);
};
const drawRightArrow = function(imgX) {
imgX = imgX ?? x2-50;
const drawAcceptArrow = function(xOffset) {
xOffset = xOffset??0;
imgX = x + 2 + xOffset;
g.setColor(0, 1, 0);
g.drawImage(rightImg, imgX, y2-50);
if (xOffset > 0) g.fillRect(imgX+3, y2-43, x, y2-9);
};
const drawRejectArrow = function(xOffset) {
xOffset = xOffset??0;
let imgX = x2 - 50 - xOffset;
g.setColor(1, 0.25, 0.25);
g.drawImage(leftImg, imgX, y2-50);
if (xOffset > 0) g.fillRect(imgX+45, y2-43, x2, y2-9);
};
if (cmd === "end") {
if (timerInt) clearTimeout(timerInt); //TODO change timerInt variable
if (timeouts.timer) clearTimeout(timeouts.timer);
g.setColor(g.theme.fg).setFont("6x15:2").setFontAlign(0, -1);
g.drawString("Call Ended", mx, y+25);
endTimeout = setTimeout(() => g.clear(), 3000);
timeouts["endTimeout"] = setTimeout(() => g.clear(), 3000);
}
if (cmd === "incoming") {
drawLeftArrow();
drawRightArrow();
drawRejectArrow();
drawAcceptArrow();
g.setColor(0,1,0);
g.drawImage(ringingImg, mx-25, y+15);
}
if (cmd === "start" || cmd === "outgoing") {
drawLeftArrow(x2 - 52);
drawRejectArrow();
startTime = parseInt(Date.now()/1000);
g.setColor(g.theme.fg);
g.drawImage(cmd === "start" ? incomingImg : outgoingImg, x+10, y+20);
@ -57,25 +65,57 @@ const showCall = function(call) {
const m = ("0" + Math.floor((elapsed/60)%60)).slice(-2);
const s = ("0" + Math.floor(elapsed%60)).slice(-2);
g.setFont("Vector:25").setFontAlign(0, -1).drawString(`${h}:${m}:${s}`, mx + 15, y+25);
timerInt = setTimeout(timer, 1000); //TODO put into intervals object
timeouts["timer"] = setTimeout(timer, 1000);
};
timer();
}
const handler = function(dir) {
if (cmd === "end") return;
if (dir < 0) leftHandler(dir);
else if (dir > 0 && cmd === "incoming") rightHandler();
};
const leftHandler = function(dir) {
let xOff = 0;
const swipeAnimation = () => {
xOff += 30;
g.clearRect(x, y2-50, x2, y2);
drawRejectArrow(xOff);
if (xOff > 160) return;
else setTimeout(swipeAnimation, 30);
}
swipeAnimation();
if (timeouts.timer) clearTimeout(timeouts.timer);
return Bangle.messageResponse(msg, false);
};
const rightHandler = function(dir) {
let xOff = 0;
const swipeAnimation = () => {
xOff += 30;
g.clearRect(x, y2-50, x2, y2);
drawAcceptArrow(xOff);
if (xOff > 160) return;
else setTimeout(swipeAnimation, 30);
}
swipeAnimation();
if (timeouts.timer) clearTimeout(timeouts.timer);
return Bangle.messageResponse(msg, true);
};
Bangle.setUI({
mode: "custom",
touch: () => {if (buzzing) return require("messages".stopBuzz())},
swipe: handler,
btn: () => {clearInterval(timerInt)}
btn: _e => goBack(),
remove: cleanup
});
};
let msg = {"t":"call","cmd":"start","name":"","number":"1306-7740297","id":"call","src":"Phone","positive":true,"negative":true,"title":"Hayley Thiessen, Wifey","body":"Incoming call\n13067740297","new":true,"show":true,"type":"call"}
let msg = {"t":"call","cmd":"incoming","name":"","number":"1306-7740297","id":"call","src":"Phone","positive":true,"negative":true,"title":"Hayley Thiessen, Wifey","body":"Incoming call\n13067740297","new":true,"show":true,"type":"call"}
g.reset();
showCall(msg);

View File

@ -7,7 +7,7 @@ exports.messageListener = function(type, msg) {
if (!Bangle.MESSAGES || !Bangle.MESSAGES.length) Bangle.MESSAGES = require("messages").getMessages(msg);
msg.show = true;
msg.type = type;
if (msg.id === "call" && msg.t === "remove" && msg.cmd != "end") {
if (msg.id === "call" && msg.t === "remove") {
msg.t = "modify"; // not sure why messages module puts everything as remove except for "incoming"
msg.new = true;
}