tweak swipe animations, use UI swipe mode for left right swipes to try to make it feel snappier, fix scrolling issues
parent
df67d082fa
commit
136c73a85f
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
//{
|
||||
|
||||
//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 settings = require('Storage').readJSON("messages.settings.json", true) || {};
|
||||
// const settings = () => require("messagegui").settings();
|
||||
// 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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue