show notification dot when balance changes (#5214)
This commit is contained in:
parent
1bcc5022c2
commit
b5a4bcb247
@ -247,6 +247,16 @@ export interface Badge {
|
|||||||
* Stop indicating background activity.
|
* Stop indicating background activity.
|
||||||
*/
|
*/
|
||||||
stopBusy(): void;
|
stopBusy(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the notification in the badge.
|
||||||
|
*/
|
||||||
|
showNotification(): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop showing the notification.
|
||||||
|
*/
|
||||||
|
clearNotification(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -982,7 +992,7 @@ export class Wallet {
|
|||||||
.put(Stores.purchases, t)
|
.put(Stores.purchases, t)
|
||||||
.putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
|
.putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
|
||||||
.finish();
|
.finish();
|
||||||
|
this.badge.showNotification();
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1198,7 +1208,11 @@ export class Wallet {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
await this.q().mutate(Stores.coins, coin.coinPub, mutateCoin)
|
await this.q().mutate(Stores.coins, coin.coinPub, mutateCoin)
|
||||||
|
// Show notifications only for accepted tips
|
||||||
|
this.badge.showNotification();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.badge.showNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
@ -1720,6 +1734,7 @@ export class Wallet {
|
|||||||
console.log("suspending coin", c);
|
console.log("suspending coin", c);
|
||||||
c.suspended = true;
|
c.suspended = true;
|
||||||
q.put(Stores.coins, c);
|
q.put(Stores.coins, c);
|
||||||
|
this.badge.showNotification();
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
});
|
});
|
||||||
await q.finish();
|
await q.finish();
|
||||||
@ -2673,6 +2688,7 @@ export class Wallet {
|
|||||||
.put(Stores.coinsReturns, coinsReturnRecord)
|
.put(Stores.coinsReturns, coinsReturnRecord)
|
||||||
.putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
|
.putAll(Stores.coins, payCoinInfo.map((pci) => pci.updatedCoin))
|
||||||
.finish();
|
.finish();
|
||||||
|
this.badge.showNotification();
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
|
|
||||||
this.depositReturnedCoins(coinsReturnRecord);
|
this.depositReturnedCoins(coinsReturnRecord);
|
||||||
@ -2835,6 +2851,7 @@ export class Wallet {
|
|||||||
this.refresh(perm.coin_pub);
|
this.refresh(perm.coin_pub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.badge.showNotification();
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2968,6 +2985,7 @@ export class Wallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await q.finish();
|
await q.finish();
|
||||||
|
this.badge.showNotification();
|
||||||
this.notifier.notify();
|
this.notifier.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3047,4 +3065,8 @@ export class Wallet {
|
|||||||
|
|
||||||
// FIXME(#5210) also GC coins
|
// FIXME(#5210) also GC coins
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearNotification(): void {
|
||||||
|
this.badge.clearNotification();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,11 @@ export class ChromeBadge implements Badge {
|
|||||||
*/
|
*/
|
||||||
private gapWidth: number = 0;
|
private gapWidth: number = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should we show the notification dot?
|
||||||
|
*/
|
||||||
|
private hasNotification = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum value for our rotationAngle, corresponds to 2 Pi.
|
* Maximum value for our rotationAngle, corresponds to 2 Pi.
|
||||||
*/
|
*/
|
||||||
@ -150,6 +155,21 @@ export class ChromeBadge implements Badge {
|
|||||||
// go back to the origin
|
// go back to the origin
|
||||||
this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);
|
this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2);
|
||||||
|
|
||||||
|
if (this.hasNotification) {
|
||||||
|
// We draw a circle with a soft border in the
|
||||||
|
// lower right corner.
|
||||||
|
const r = 8;
|
||||||
|
const cw = this.canvas.width;
|
||||||
|
const ch = this.canvas.height;
|
||||||
|
this.ctx.beginPath();
|
||||||
|
this.ctx.arc(cw - r, ch - r, r, 0, 2 * Math.PI, false);
|
||||||
|
const gradient = this.ctx.createRadialGradient(cw - r, ch - r, r, cw - r, ch - r, 5);
|
||||||
|
gradient.addColorStop(0, "rgba(255, 255, 255, 1)");
|
||||||
|
gradient.addColorStop(1, "blue");
|
||||||
|
this.ctx.fillStyle = gradient;
|
||||||
|
this.ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
// Allow running outside the extension for testing
|
// Allow running outside the extension for testing
|
||||||
// tslint:disable-next-line:no-string-literal
|
// tslint:disable-next-line:no-string-literal
|
||||||
if (window["chrome"] && window.chrome["browserAction"]) {
|
if (window["chrome"] && window.chrome["browserAction"]) {
|
||||||
@ -211,6 +231,23 @@ export class ChromeBadge implements Badge {
|
|||||||
rAF(step);
|
rAF(step);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the badge such that it shows the
|
||||||
|
* user that something happened (balance changed).
|
||||||
|
*/
|
||||||
|
showNotification() {
|
||||||
|
this.hasNotification = true;
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the badge without the notification mark.
|
||||||
|
*/
|
||||||
|
clearNotification() {
|
||||||
|
this.hasNotification = false;
|
||||||
|
this.draw();
|
||||||
|
}
|
||||||
|
|
||||||
startBusy() {
|
startBusy() {
|
||||||
if (this.isBusy) {
|
if (this.isBusy) {
|
||||||
return;
|
return;
|
||||||
|
@ -208,6 +208,10 @@ export interface MessageMap {
|
|||||||
request: types.TipStatusRequest;
|
request: types.TipStatusRequest;
|
||||||
response: void;
|
response: void;
|
||||||
};
|
};
|
||||||
|
"clear-notification": {
|
||||||
|
request: { };
|
||||||
|
response: void;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -566,4 +566,7 @@ const el = (
|
|||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", () => {
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
ReactDOM.render(el, document.getElementById("content")!);
|
ReactDOM.render(el, document.getElementById("content")!);
|
||||||
|
// Will be used by the backend to detect when the popup gets closed,
|
||||||
|
// so we can clear notifications
|
||||||
|
chrome.runtime.connect({name: "popup"});
|
||||||
});
|
});
|
||||||
|
@ -381,3 +381,7 @@ export function acceptTip(merchantDomain: string, tipId: string): Promise<TipSta
|
|||||||
export function processTipResponse(merchantDomain: string, tipId: string, tipResponse: TipResponse): Promise<void> {
|
export function processTipResponse(merchantDomain: string, tipId: string, tipResponse: TipResponse): Promise<void> {
|
||||||
return callBackend("process-tip-response", { merchantDomain, tipId, tipResponse });
|
return callBackend("process-tip-response", { merchantDomain, tipId, tipResponse });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function clearNotification(): Promise<void> {
|
||||||
|
return callBackend("clear-notification", { });
|
||||||
|
}
|
||||||
|
@ -337,6 +337,9 @@ function handleMessage(sender: MessageSender,
|
|||||||
const req = GetTipPlanchetsRequest.checked(detail);
|
const req = GetTipPlanchetsRequest.checked(detail);
|
||||||
return needsWallet().getTipPlanchets(req.merchantDomain, req.tipId, req.amount, req.deadline, req.exchangeUrl, req.nextUrl);
|
return needsWallet().getTipPlanchets(req.merchantDomain, req.tipId, req.amount, req.deadline, req.exchangeUrl, req.nextUrl);
|
||||||
}
|
}
|
||||||
|
case "clear-notification": {
|
||||||
|
return needsWallet().clearNotification();
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// Exhaustiveness check.
|
// Exhaustiveness check.
|
||||||
// See https://www.typescriptlang.org/docs/handbook/advanced-types.html
|
// See https://www.typescriptlang.org/docs/handbook/advanced-types.html
|
||||||
@ -698,6 +701,23 @@ export async function wxMain() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Clear notifications both when the popop opens,
|
||||||
|
// as well when it closes.
|
||||||
|
chrome.runtime.onConnect.addListener((port) => {
|
||||||
|
if (port.name == "popup") {
|
||||||
|
if (currentWallet) {
|
||||||
|
currentWallet.clearNotification();
|
||||||
|
}
|
||||||
|
port.onDisconnect.addListener(() => {
|
||||||
|
if (currentWallet) {
|
||||||
|
currentWallet.clearNotification();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Handlers for catching HTTP requests
|
// Handlers for catching HTTP requests
|
||||||
chrome.webRequest.onHeadersReceived.addListener((details) => {
|
chrome.webRequest.onHeadersReceived.addListener((details) => {
|
||||||
const wallet = currentWallet;
|
const wallet = currentWallet;
|
||||||
|
Loading…
Reference in New Issue
Block a user