]> git.r.bdr.sh - rbdr/junction/blame - extension/junction.js
Ensure connections are closed
[rbdr/junction] / extension / junction.js
CommitLineData
1ed219c8 1const internals = {
b9a2baf2 2 promisesSupported: !!window.browser,
b0cbc085 3 injectedScript: {},
4757c461 4 port: null,
02071d8e 5 currentUrl: null,
1ed219c8
RBR
6
7 icons: {
8 call: {
b9a2baf2
RBR
9 16: "icons/action-16.png",
10 32: "icons/action-32.png",
1ed219c8
RBR
11 },
12
13 hangUp: {
b9a2baf2
RBR
14 16: "icons/hang_up-16.png",
15 32: "icons/hang_up-32.png",
16 },
1ed219c8
RBR
17 },
18
19 onClick() {
20 if (internals.isInCall()) {
21 return internals.hangUp();
22 }
23
5685e249 24 return internals.initializeContentScript();
1ed219c8
RBR
25 },
26
5685e249
RBR
27 joinAudioCall() {
28 internals.port.postMessage({
b9a2baf2 29 action: "joinAudioCall",
4757c461 30 data: {
02071d8e 31 currentUrl: internals.currentUrl,
b9a2baf2
RBR
32 tada: internals.getRoot().runtime.getURL("sounds/tada.wav"),
33 },
4757c461
RBR
34 });
35 internals.getRoot().browserAction.enable();
b9a2baf2 36 internals.setIcon("hangUp");
1ed219c8
RBR
37 },
38
5685e249
RBR
39 onConnect(port) {
40 internals.port = port;
41 port.onDisconnect.addListener(internals.onDisconnect);
42 port.onMessage.addListener(internals.onMessage);
43 internals.joinAudioCall();
44 },
45
4757c461 46 onMessage(message) {
b9a2baf2
RBR
47 if (message.action === "error") {
48 internals.getRoot().browserAction.setBadgeText({ text: "x" }, () => {});
4757c461
RBR
49 }
50 },
51
52 onDisconnect() {
b9a2baf2
RBR
53 internals.getRoot().browserAction.setBadgeText({ text: "" }, () => {});
54 internals.setIcon("call");
02071d8e 55 internals.currentUrl = null;
4757c461
RBR
56 internals.port = null;
57 internals.getRoot().browserAction.enable();
1ed219c8
RBR
58 },
59
5685e249 60 async initializeContentScript() {
4757c461
RBR
61 internals.getRoot().browserAction.disable();
62 const activeTabs = await internals.getActiveTabs();
4757c461 63
02071d8e 64 internals.currentUrl = activeTabs[0].url;
b0cbc085
RBR
65 const id = activeTabs[0].id;
66 if (!internals.injectedScript[id]) {
5685e249
RBR
67 const execution = await internals.getRoot().tabs.executeScript(
68 activeTabs[0].id,
69 {
70 file: "/build/content_script.js",
71 },
72 () => {
b0cbc085 73 internals.injectedScript[id] = true;
5685e249
RBR
74 },
75 );
02071d8e 76
bab26a4d
RBR
77 if (execution && !execution[0]) {
78 internals.onDisconnect();
79 }
80 } else {
81 internals.getRoot().tabs.connect(activeTabs[0].id);
02071d8e 82 }
b9a2baf2 83 },
bab26a4d 84
4757c461 85 hangUp() {
4757c461
RBR
86 internals.getRoot().browserAction.disable();
87 internals.port.postMessage({
b9a2baf2 88 action: "hangUp",
4757c461 89 });
1ed219c8
RBR
90 },
91
92 isInCall() {
b9a2baf2 93 return !!internals.port;
1ed219c8
RBR
94 },
95
96 setIcon(iconSet) {
a94a5407 97 internals.getRoot().browserAction.setIcon({
b9a2baf2 98 path: internals.icons[iconSet],
1ed219c8 99 });
a94a5407
RBR
100 },
101
102 getRoot() {
a94a5407
RBR
103 return window.browser || window.chrome;
104 },
105
106 // Chrome doesn't yet implement the promise based tabs.query :'(
107
108 getActiveTabs() {
a94a5407
RBR
109 const query = {
110 currentWindow: true,
b9a2baf2 111 active: true,
a94a5407
RBR
112 };
113
114 if (internals.promisesSupported) {
115 return internals.getRoot().tabs.query(query);
116 }
117
80172072 118 return new Promise((resolve) => {
a94a5407 119 internals.getRoot().tabs.query(query, (tabs) => {
a94a5407
RBR
120 return resolve(tabs);
121 });
122 });
123 },
1ed219c8
RBR
124};
125
a94a5407 126internals.getRoot().browserAction.onClicked.addListener(internals.onClick);
4757c461 127internals.getRoot().runtime.onConnect.addListener(internals.onConnect);