aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview/lib/Userscript.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/webview/lib/Userscript.ts')
-rw-r--r--src/webview/lib/Userscript.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/webview/lib/Userscript.ts b/src/webview/lib/Userscript.ts
new file mode 100644
index 000000000..c50941dc7
--- /dev/null
+++ b/src/webview/lib/Userscript.ts
@@ -0,0 +1,107 @@
1type Recipe = {
2 setBadge: (direct: number, indirect: number) => void;
3 setDialogTitle: (title: string) => void;
4 injectCSS: (css: string | string[]) => void;
5};
6
7export default class Userscript {
8 // Current ./lib/RecipeWebview instance
9 recipe: Recipe | null = null;
10
11 // Current ./recipe.js instance
12 controller = null;
13
14 // Service configuration
15 config = {};
16
17 // Ferdi and service settings
18 settings = {};
19
20 constructor(recipe, controller, config) {
21 this.recipe = recipe;
22 this.controller = controller;
23 this.internal_setSettings(controller.settings);
24 this.config = config;
25 }
26
27 /**
28 * Set internal copy of Ferdi's settings.
29 * This is only used internally and can not be used to change any settings
30 *
31 * @param {*} settings
32 */
33 // eslint-disable-next-line camelcase
34 internal_setSettings(settings: any) {
35 // This is needed to get a clean JS object from the settings itself to provide better accessibility
36 // Otherwise this will be a mobX instance
37 this.settings = JSON.parse(JSON.stringify(settings));
38 }
39
40 /**
41 * Set badge count for the current service
42 * @param {number} direct Direct messages
43 * @param {number} indirect Indirect messages
44 */
45 setBadge(direct: number = 0, indirect: number = 0) {
46 if (this.recipe && this.recipe.setBadge) {
47 this.recipe.setBadge(direct, indirect);
48 }
49 }
50
51 /**
52 * Set active dialog title to the app title
53 * @param {*} title Dialog title
54 */
55 setDialogTitle(title: string) {
56 if (this.recipe && this.recipe.setDialogTitle) {
57 this.recipe.setDialogTitle(title);
58 }
59 }
60
61 /**
62 * Inject CSS files into the current page
63 *
64 * @param {...string} files
65 */
66 injectCSSFiles(...files: string[]) {
67 if (this.recipe && this.recipe.injectCSS) {
68 // @ts-expect-error A spread argument must either have a tuple type or be passed to a rest parameter.
69 this.recipe.injectCSS(...files);
70 }
71 }
72
73 /**
74 * Inject a CSS string into the page
75 *
76 * @param {string} css
77 */
78 injectCSS(css: string) {
79 const style = document.createElement('style');
80 style.textContent = css;
81 document.head.append(style);
82 }
83
84 /**
85 * Set or update value in storage
86 *
87 * @param {string} key
88 * @param {any} value
89 */
90 set(key: string, value: string) {
91 window.localStorage.setItem(`ferdi-user-${key}`, JSON.stringify(value));
92 }
93
94 /**
95 * Get value from storage
96 *
97 * @param {string} key
98 * @return Value of the key
99 */
100 get(key: string) {
101 const ferdiUserKey = window.localStorage.getItem(`ferdi-user-${key}`);
102
103 if (ferdiUserKey) {
104 return JSON.parse(ferdiUserKey);
105 }
106 }
107}