aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview/lib/RecipeWebview.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/webview/lib/RecipeWebview.ts')
-rw-r--r--src/webview/lib/RecipeWebview.ts177
1 files changed, 177 insertions, 0 deletions
diff --git a/src/webview/lib/RecipeWebview.ts b/src/webview/lib/RecipeWebview.ts
new file mode 100644
index 000000000..09dc462ed
--- /dev/null
+++ b/src/webview/lib/RecipeWebview.ts
@@ -0,0 +1,177 @@
1import { ipcRenderer } from 'electron';
2import { BrowserWindow } from '@electron/remote';
3import { pathExistsSync, readFileSync, existsSync } from 'fs-extra';
4
5const debug = require('debug')('Ferdi:Plugin:RecipeWebview');
6
7class RecipeWebview {
8 badgeHandler: any;
9
10 dialogTitleHandler: any;
11
12 notificationsHandler: any;
13
14 sessionHandler: any;
15
16 constructor(
17 badgeHandler,
18 dialogTitleHandler,
19 notificationsHandler,
20 sessionHandler,
21 ) {
22 this.badgeHandler = badgeHandler;
23 this.dialogTitleHandler = dialogTitleHandler;
24 this.notificationsHandler = notificationsHandler;
25 this.sessionHandler = sessionHandler;
26
27 ipcRenderer.on('poll', () => {
28 this.loopFunc();
29
30 debug('Poll event');
31
32 // This event is for checking if the service recipe is still actively
33 // communicating with the client
34 ipcRenderer.sendToHost('alive');
35 });
36 }
37
38 loopFunc = () => null;
39
40 darkModeHandler = false;
41
42 // TODO Remove this once we implement a proper wrapper.
43 get ipcRenderer() {
44 return ipcRenderer;
45 }
46
47 // TODO Remove this once we implement a proper wrapper.
48 get BrowserWindow() {
49 return BrowserWindow;
50 }
51
52 /**
53 * Initialize the loop
54 *
55 * @param {Function} Function that will be executed
56 */
57 loop(fn) {
58 this.loopFunc = fn;
59 }
60
61 /**
62 * Set the unread message badge
63 *
64 * @param {string | number | undefined | null} direct Set the count of direct messages
65 * eg. Slack direct mentions, or a
66 * message to @channel
67 * @param {string | number | undefined | null} indirect Set a badge that defines there are
68 * new messages but they do not involve
69 * me directly to me eg. in a channel
70 */
71 setBadge(direct = 0, indirect = 0) {
72 this.badgeHandler.setBadge(direct, indirect);
73 }
74
75 /**
76 * Set the active dialog title to the app title
77 *
78 * @param {string | undefined | null} title Set the active dialog title
79 * to the app title
80 * eg. WhatsApp contact name
81 */
82 setDialogTitle(title) {
83 this.dialogTitleHandler.setDialogTitle(title);
84 }
85
86 /**
87 * Safely parse the given text into an integer
88 *
89 * @param {string | number | undefined | null} text to be parsed
90 */
91 safeParseInt(text) {
92 return this.badgeHandler.safeParseInt(text);
93 }
94
95 /**
96 * Injects the contents of a CSS file into the current webview
97 *
98 * @param {Array} files CSS files that should be injected. This must
99 * be an absolute path to the file
100 */
101 injectCSS(...files) {
102 // eslint-disable-next-line unicorn/no-array-for-each
103 files.forEach(file => {
104 if (pathExistsSync(file)) {
105 const styles = document.createElement('style');
106 styles.innerHTML = readFileSync(file, 'utf8');
107
108 const head = document.querySelector('head');
109
110 if (head) {
111 head.append(styles);
112 debug('Append styles', styles);
113 }
114 }
115 });
116 }
117
118 injectJSUnsafe(...files) {
119 Promise.all(
120 files.map(file => {
121 if (existsSync(file)) {
122 return readFileSync(file, 'utf8');
123 }
124 debug('Script not found', file);
125 return null;
126 }),
127 ).then(scripts => {
128 const scriptsFound = scripts.filter(script => script !== null);
129 if (scriptsFound.length > 0) {
130 debug('Inject scripts to main world', scriptsFound);
131 ipcRenderer.sendToHost('inject-js-unsafe', ...scriptsFound);
132 }
133 });
134 }
135
136 /**
137 * Set a custom handler for turning on and off dark mode
138 *
139 * @param {function} handler
140 */
141 handleDarkMode(handler) {
142 this.darkModeHandler = handler;
143 }
144
145 onNotify(fn) {
146 if (typeof fn === 'function') {
147 this.notificationsHandler.onNotify = fn;
148 }
149 }
150
151 initialize(fn) {
152 if (typeof fn === 'function') {
153 fn();
154 }
155 }
156
157 clearStorageData(serviceId, targetsToClear) {
158 ipcRenderer.send('clear-storage-data', {
159 serviceId,
160 targetsToClear,
161 });
162 }
163
164 releaseServiceWorkers() {
165 this.sessionHandler.releaseServiceWorkers();
166 }
167
168 setAvatarImage(avatarUrl) {
169 ipcRenderer.sendToHost('avatar', avatarUrl);
170 }
171
172 openNewWindow(url) {
173 ipcRenderer.sendToHost('new-window', url);
174 }
175}
176
177export default RecipeWebview;