aboutsummaryrefslogtreecommitdiffstats
path: root/src/models/Service.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/models/Service.js')
-rw-r--r--src/models/Service.js59
1 files changed, 50 insertions, 9 deletions
diff --git a/src/models/Service.js b/src/models/Service.js
index 12a2d4af9..dc8febe0b 100644
--- a/src/models/Service.js
+++ b/src/models/Service.js
@@ -2,6 +2,8 @@ import { autorun, computed, observable } from 'mobx';
2import normalizeUrl from 'normalize-url'; 2import normalizeUrl from 'normalize-url';
3import path from 'path'; 3import path from 'path';
4 4
5import userAgent from '../helpers/userAgent-helpers';
6
5const debug = require('debug')('Ferdi:Service'); 7const debug = require('debug')('Ferdi:Service');
6 8
7export const RESTRICTION_TYPES = { 9export const RESTRICTION_TYPES = {
@@ -56,6 +58,8 @@ export default class Service {
56 58
57 @observable isDarkModeEnabled = false; 59 @observable isDarkModeEnabled = false;
58 60
61 @observable darkReaderSettings = { brightness: 100, contrast: 90, sepia: 10 };
62
59 @observable spellcheckerLanguage = null; 63 @observable spellcheckerLanguage = null;
60 64
61 @observable isFirstLoad = true; 65 @observable isFirstLoad = true;
@@ -72,6 +76,20 @@ export default class Service {
72 76
73 @observable restrictionType = null; 77 @observable restrictionType = null;
74 78
79 @observable isHibernationEnabled = false;
80
81 @observable lastUsed = Date.now(); // timestamp
82
83 @observable lastPoll = null;
84
85 @observable lastPollAnswer = null;
86
87 @observable lostRecipeConnection = false;
88
89 @observable lostRecipeReloadAttempt = 0;
90
91 @observable chromelessUserAgent = false;
92
75 constructor(data, recipe) { 93 constructor(data, recipe) {
76 if (!data) { 94 if (!data) {
77 console.error('Service config not valid'); 95 console.error('Service config not valid');
@@ -109,12 +127,16 @@ export default class Service {
109 127
110 this.isDarkModeEnabled = data.isDarkModeEnabled !== undefined ? data.isDarkModeEnabled : this.isDarkModeEnabled; 128 this.isDarkModeEnabled = data.isDarkModeEnabled !== undefined ? data.isDarkModeEnabled : this.isDarkModeEnabled;
111 129
130 this.darkReaderSettings = data.darkReaderSettings !== undefined ? data.darkReaderSettings : this.darkReaderSettings;
131
112 this.hasCustomUploadedIcon = data.hasCustomIcon !== undefined ? data.hasCustomIcon : this.hasCustomUploadedIcon; 132 this.hasCustomUploadedIcon = data.hasCustomIcon !== undefined ? data.hasCustomIcon : this.hasCustomUploadedIcon;
113 133
114 this.proxy = data.proxy !== undefined ? data.proxy : this.proxy; 134 this.proxy = data.proxy !== undefined ? data.proxy : this.proxy;
115 135
116 this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage; 136 this.spellcheckerLanguage = data.spellcheckerLanguage !== undefined ? data.spellcheckerLanguage : this.spellcheckerLanguage;
117 137
138 this.isHibernationEnabled = data.isHibernationEnabled !== undefined ? data.isHibernationEnabled : this.isHibernationEnabled;
139
118 this.recipe = recipe; 140 this.recipe = recipe;
119 141
120 autorun(() => { 142 autorun(() => {
@@ -136,6 +158,7 @@ export default class Service {
136 id: this.id, 158 id: this.id,
137 spellcheckerLanguage: this.spellcheckerLanguage, 159 spellcheckerLanguage: this.spellcheckerLanguage,
138 isDarkModeEnabled: this.isDarkModeEnabled, 160 isDarkModeEnabled: this.isDarkModeEnabled,
161 darkReaderSettings: this.darkReaderSettings,
139 team: this.team, 162 team: this.team,
140 url: this.url, 163 url: this.url,
141 hasCustomIcon: this.hasCustomIcon, 164 hasCustomIcon: this.hasCustomIcon,
@@ -182,21 +205,34 @@ export default class Service {
182 } 205 }
183 206
184 @computed get userAgent() { 207 @computed get userAgent() {
185 let { userAgent } = window.navigator; 208 let ua = userAgent(this.chromelessUserAgent);
186 if (typeof this.recipe.overrideUserAgent === 'function') { 209 if (typeof this.recipe.overrideUserAgent === 'function') {
187 userAgent = this.recipe.overrideUserAgent(); 210 ua = this.recipe.overrideUserAgent();
188 } 211 }
189 212
190 // Remove Ferdi as it can cause incompatabilities with services. 213 return ua;
191 // This way, Ferdi will look like a normal Chrome instance
192 userAgent = userAgent.replace(/(Ferdi|Electron)([^\s]+\s)/g, '');
193
194 return userAgent;
195 } 214 }
196 215
197 initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { 216 initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) {
198 const webContents = this.webview.getWebContents(); 217 const webContents = this.webview.getWebContents();
199 218
219 const handleUserAgent = (url, forwardingHack = false) => {
220 if (url.startsWith('https://accounts.google.com')) {
221 if (!this.chromelessUserAgent) {
222 debug('Setting user agent to chromeless for url', url);
223 this.webview.setUserAgent(userAgent(true));
224 if (forwardingHack) {
225 this.webview.loadURL(url);
226 }
227 this.chromelessUserAgent = true;
228 }
229 } else if (this.chromelessUserAgent) {
230 debug('Setting user agent to contain chrome');
231 this.webview.setUserAgent(this.userAgent);
232 this.chromelessUserAgent = false;
233 }
234 };
235
200 this.webview.addEventListener('ipc-message', e => handleIPCMessage({ 236 this.webview.addEventListener('ipc-message', e => handleIPCMessage({
201 serviceId: this.id, 237 serviceId: this.id,
202 channel: e.channel, 238 channel: e.channel,
@@ -204,7 +240,6 @@ export default class Service {
204 })); 240 }));
205 241
206 this.webview.addEventListener('new-window', (event, url, frameName, options) => { 242 this.webview.addEventListener('new-window', (event, url, frameName, options) => {
207 console.log('open window', event, url, frameName, options);
208 openWindow({ 243 openWindow({
209 event, 244 event,
210 url, 245 url,
@@ -213,6 +248,9 @@ export default class Service {
213 }); 248 });
214 }); 249 });
215 250
251
252 this.webview.addEventListener('will-navigate', event => handleUserAgent(event.url, true));
253
216 this.webview.addEventListener('did-start-loading', (event) => { 254 this.webview.addEventListener('did-start-loading', (event) => {
217 debug('Did start load', this.name, event); 255 debug('Did start load', this.name, event);
218 256
@@ -230,7 +268,10 @@ export default class Service {
230 }; 268 };
231 269
232 this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); 270 this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this));
233 this.webview.addEventListener('did-navigate', didLoad.bind(this)); 271 this.webview.addEventListener('did-navigate', (event) => {
272 handleUserAgent(event.url);
273 didLoad();
274 });
234 275
235 this.webview.addEventListener('did-fail-load', (event) => { 276 this.webview.addEventListener('did-fail-load', (event) => {
236 debug('Service failed to load', this.name, event); 277 debug('Service failed to load', this.name, event);