/*
This file is part of GNU Taler
(C) 2021 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
import { CoreApiResponse } from "@gnu-taler/taler-util";
import { MessageFromBackend, PlatformAPI } from "./api.js";
const frames = ["popup", "wallet"]
const api: PlatformAPI = ({
isFirefox: () => false,
findTalerUriInActiveTab: async () => undefined,
getPermissionsApi: () => ({
addPermissionsListener: () => undefined, contains: async () => true, remove: async () => false, request: async () => false
}),
getWalletVersion: () => ({
version: 'none'
}),
notifyWhenAppIsReady: (fn: () => void) => {
let total = frames.length
function waitAndNotify(): void {
total--
if (total < 1) {
console.log('done')
fn()
}
}
frames.forEach(f => {
const theFrame = window.frames[f as any]
if (theFrame.location.href === 'about:blank') {
waitAndNotify()
} else {
theFrame.addEventListener("load", waitAndNotify)
}
})
},
openWalletPage: (page: string) => {
window.frames['wallet' as any].location = `/wallet.html#${page}`
},
openWalletPageFromPopup: (page: string) => {
window.parent.frames['wallet' as any].location = `/wallet.html#${page}`
window.location.href = "about:blank"
},
openWalletURIFromPopup: (page: string) => {
alert('openWalletURIFromPopup not implemented yet')
},
redirectTabToWalletPage: (tabId: number, page: string) => {
alert('redirectTabToWalletPage not implemented yet')
},
registerAllIncomingConnections: () => undefined,
registerOnInstalled: (fn: () => void) => undefined,
registerReloadOnNewVersion: () => undefined,
registerTalerHeaderListener: () => undefined,
useServiceWorkerAsBackgroundProcess: () => false,
listenToAllChannels: (fn: (m: any, s: any, c: (r: CoreApiResponse) => void) => void) => {
window.addEventListener("message", (event: MessageEvent) => {
if (event.data.type !== 'command') return
const sender = event.data.header.replyMe
fn(event.data.body, sender, (resp: CoreApiResponse) => {
if (event.source) {
const msg: IframeMessageResponse = {
type: "response",
header: { responseId: sender },
body: resp
}
window.parent.postMessage(msg)
}
})
})
},
sendMessageToAllChannels: (message: MessageFromBackend) => {
Array.from(window.frames).forEach(w => {
try {
w.postMessage({
header: {}, body: message
});
} catch (e) {
console.error(e)
}
})
},
listenToWalletBackground: (onNewMessage: (m: MessageFromBackend) => void) => {
function listener(event: MessageEvent): void {
if (event.data.type !== 'notification') return
onNewMessage(event.data.body)
}
window.parent.addEventListener("message", listener)
return () => {
window.parent.removeEventListener("message", listener)
}
},
sendMessageToWalletBackground: async (operation: string, payload: any) => {
const replyMe = `reply-${Math.floor(Math.random() * 100000)}`
const message: IframeMessageCommand = {
type: 'command',
header: { replyMe },
body: { operation, payload, id: "(none)" }
}
window.parent.postMessage(message)
return new Promise((res, rej) => {
function listener(event: MessageEvent): void {
if (event.data.type !== "response" || event.data.header.responseId !== replyMe) {
return
}
res(event.data.body)
window.parent.removeEventListener("message", listener)
}
window.parent.addEventListener("message", listener, {
})
})
},
})
type IframeMessageType = IframeMessageNotification | IframeMessageResponse | IframeMessageCommand;
interface IframeMessageNotification {
type: "notification";
header: Record,
body: MessageFromBackend
}
interface IframeMessageResponse {
type: "response";
header: {
responseId: string;
},
body: CoreApiResponse
}
interface IframeMessageCommand {
type: "command";
header: {
replyMe: string;
},
body: {
operation: any, id: string, payload: any
}
}
export default api;