Skip to content
This repository was archived by the owner on Apr 22, 2022. It is now read-only.

Commit 3326447

Browse files
authored
Merge pull request #2628 from ramboxapp/0.7.4
v0.7.4
2 parents fb1ab0d + 313b29c commit 3326447

10 files changed

Lines changed: 225 additions & 9 deletions

File tree

app.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ ipc.on('showAbout', function(event, message) {
2828
ipc.on('showPreferences', function(event, message) {
2929
!Ext.cq1('preferences') ? Ext.create('Rambox.view.preferences.Preferences').show() : '';
3030
});
31+
ipc.on('grantPermissions', async function() {
32+
await require('electron').remote.systemPreferences.askForMediaAccess('microphone');
33+
await require('electron').remote.systemPreferences.askForMediaAccess('camera');
34+
});
3135
ipc.on('autoUpdater:check-update', function() {
3236
Rambox.app.checkUpdate();
3337
});

app/Application.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,48 @@ Ext.define('Rambox.Application', {
6060
})
6161
})();
6262

63+
if ( !localStorage.getItem('hideMacPermissions') && process.platform === 'darwin' && (require('electron').remote.systemPreferences.getMediaAccessStatus('microphone') !== 'granted' || require('electron').remote.systemPreferences.getMediaAccessStatus('camera') !== 'granted') ) {
64+
console.info('Checking mac permissions...');
65+
Ext.cq1('app-main').addDocked({
66+
xtype: 'toolbar'
67+
,dock: 'top'
68+
,style: {background: '#30BBF3'}
69+
,items: [
70+
'->'
71+
,{
72+
xtype: 'label'
73+
,html: '<b>Rambox CE needs permissions to use Microphone and Camera for the apps.</b>'
74+
}
75+
,{
76+
xtype: 'button'
77+
,text: 'Grant permissions'
78+
,ui: 'decline'
79+
,handler: async function(btn) {
80+
ipc.send('grantPermissions');
81+
Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true);
82+
}
83+
}
84+
,{
85+
xtype: 'button'
86+
,text: 'Never ask again'
87+
,ui: 'decline'
88+
,handler: function(btn) {
89+
Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true);
90+
localStorage.setItem('hideMacPermissions', true);
91+
}
92+
}
93+
,'->'
94+
,{
95+
glyph: 'xf00d@FontAwesome'
96+
,baseCls: ''
97+
,style: 'cursor:pointer;'
98+
,handler: function(btn) { Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true); }
99+
}
100+
]
101+
});
102+
}
103+
104+
63105
Ext.getStore('ServicesList').load(function (records, operations, success) {
64106

65107
if (!success) {

app/store/ServicesList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Ext.define('Rambox.store.ServicesList', {
1010

1111
,proxy: {
1212
type: 'ajax',
13-
url: 'https://us-central1-rambox-d1326.cloudfunctions.net/ceApps',
13+
url: 'https://raw.githubusercontent.com/saenzramiro/rambox/gh-pages/api/services.json',
1414
reader: {
1515
type: 'json',
1616
rootProperty: 'responseText'

app/ux/WebView.js

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ Ext.define('Rambox.ux.WebView',{
238238

239239
return {
240240
xtype: 'statusbar'
241+
,id: me.id+'statusbar'
241242
,hidden: !me.record.get('statusbar')
242243
,keep: me.record.get('statusbar')
243244
,y: floating ? '-18px' : 'auto'
@@ -275,7 +276,8 @@ Ext.define('Rambox.ux.WebView',{
275276
if ( !me.record.get('enabled') ) return;
276277

277278
var webview = me.getWebView();
278-
let googleLoginURLs = ['accounts.google.com/signin/oauth', 'accounts.google.com/ServiceLogin']
279+
let googleLoginURLs = ['accounts.google.com/signin', 'accounts.google.com/ServiceLogin', ]
280+
me.errorCodeLog = []
279281

280282
// Google Analytics Event
281283
ga_storage._trackEvent('Services', 'load', me.type, 1, true);
@@ -321,6 +323,60 @@ Ext.define('Rambox.ux.WebView',{
321323
me.onSearchText(e.result)
322324
});
323325

326+
// On search text
327+
webview.addEventListener('did-fail-load', function(e) {
328+
console.info('The service fail at loading', me.src, e);
329+
me.errorCodeLog.push(e.errorCode)
330+
331+
var attempt = me.errorCodeLog.filter(function(code) { return code === e.errorCode });
332+
333+
// Error codes: https://cs.chromium.org/chromium/src/net/base/net_error_list.h
334+
var msg = []
335+
msg[-2] = 'NET error: failed.'
336+
msg[-3] = 'An operation was aborted (due to user action)'
337+
msg[-7] = 'Connection timeout.'
338+
msg[-21] = 'Network change.'
339+
msg[-100] = 'The connection was reset. Check your internet connection.'
340+
msg[-101] = 'The connection was reset. Check your internet connection.'
341+
msg[-105] = 'Name not resolved. Check your internet connection.'
342+
msg[-106] = 'There is no active internet connection.'
343+
msg[-118] = 'Connection timed out. Check your internet connection.'
344+
msg[-130] = 'Proxy connection failed. Please, check the proxy configuration.'
345+
msg[-300] = 'The URL is invalid.'
346+
msg[-324] = 'Empty response. Check your internet connection.'
347+
348+
switch ( e.errorCode ) {
349+
case 0:
350+
break
351+
case -3: // An operation was aborted (due to user action) I think that gmail an other pages that use iframes stop some of them making this error fired
352+
if ( attempt.length <= 4 ) return
353+
setTimeout(() => me.reloadService(me), 200);
354+
me.errorCodeLog = []
355+
break;
356+
case -2:
357+
case -7:
358+
case -21:
359+
case -118:
360+
case -324:
361+
case -100:
362+
case -101:
363+
case -105:
364+
attempt.length > 4 ? me.onFailLoad(msg[e.errorCode]) : setTimeout(() => me.reloadService(me), 2000);
365+
break;
366+
case -106:
367+
me.onFailLoad(msg[e.errorCode])
368+
break;
369+
case -130:
370+
// Could not create a connection to the proxy server. An error occurred
371+
// either in resolving its name, or in connecting a socket to it.
372+
// Note that this does NOT include failures during the actual "CONNECT" method
373+
// of an HTTP proxy.
374+
case -300:
375+
attempt.length > 4 ? me.onFailLoad(msg[e.errorCode]) : me.reloadService(me);
376+
break;
377+
}
378+
});
379+
324380
// Open links in default browser
325381
webview.addEventListener('new-window', function(e) {
326382
switch ( me.type ) {
@@ -691,6 +747,12 @@ Ext.define('Rambox.ux.WebView',{
691747
}
692748
}
693749

750+
,onFailLoad: function(v) {
751+
let me = this
752+
me.errorCodeLog = []
753+
setTimeout(() => Ext.getCmp(me.id+'statusbar').setStatus({ text: '<i class="fa fa-warning fa-fw" aria-hidden="true"></i> The service failed at loading, Error: '+ v }), 1000);
754+
}
755+
694756
,showSearchBox: function(v) {
695757
var me = this;
696758
if ( !me.record.get('enabled') ) return;

app/view/add/Add.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ Ext.define('Rambox.view.add.Add',{
6868
,emptyText: me.record.get('url') === '___' ? 'https://' : ''
6969
,validator: function(v) {
7070
if ( !me.edit ? me.record.get('url') !== '___' : me.service.get('url').indexOf('https://___') === 0 ) return true
71-
if ( v.match(/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i) === null && v.match(/^http:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/) === null ) return false;
71+
if ( v.match(/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,}))\.?)(?::\d{2,5})?(?:[/?#]\S*)?$/i) === null && v.match(/^https:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/) === null && v.match(/^http:\/\/\w+(\.\w+)*(:[0-9]+)?\/?(\/[.\w]*)*$/) === null ) return false;
7272
return true;
7373
}
7474
,listeners: {

electron/menu.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22
const os = require('os');
33
const electron = require('electron');
4+
const { systemPreferences } = require('electron')
45
const app = electron.app;
56
const BrowserWindow = electron.BrowserWindow;
67
const shell = electron.shell;
@@ -229,7 +230,7 @@ module.exports = function(config) {
229230
}
230231
];
231232

232-
if (process.platform === 'darwin') {
233+
if ( process.platform === 'darwin' ) {
233234
tpl.unshift({
234235
label: appName,
235236
submenu: [
@@ -288,6 +289,18 @@ module.exports = function(config) {
288289
}
289290
]
290291
});
292+
helpSubmenu.push({
293+
type: 'separator'
294+
});
295+
helpSubmenu.push({
296+
label: 'Grant Microphone and Camera permissions',
297+
visible: systemPreferences.getMediaAccessStatus('microphone') !== 'granted' || systemPreferences.getMediaAccessStatus('camera') !== 'granted',
298+
click(item, win) {
299+
const webContents = win.webContents;
300+
const send = webContents.send.bind(win.webContents);
301+
send('grantPermissions');
302+
}
303+
});
291304
} else {
292305
tpl.unshift({
293306
label: '&'+locale['menu.file[0]'],

package-lock.json

Lines changed: 56 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "Rambox",
33
"productName": "Rambox",
4-
"version": "0.7.3",
4+
"version": "0.7.4",
55
"description": "Free and Open Source messaging and emailing app that combines common web applications into one.",
66
"main": "electron/main.js",
77
"repository": {
@@ -66,18 +66,27 @@
6666
"appId": "com.grupovrs.ramboxce",
6767
"asar": true,
6868
"electronDownload": {
69-
"version": "7.1.1"
69+
"version": "7.1.12"
7070
},
7171
"mac": {
7272
"category": "public.app-category.productivity",
7373
"artifactName": "Rambox-${version}-mac.${ext}",
7474
"target": [
7575
"default"
76-
]
76+
],
77+
"hardenedRuntime": true,
78+
"gatekeeperAssess": false,
79+
"entitlements": "resources/installer/entitlements.mac.plist",
80+
"entitlementsInherit": "resources/installer/entitlements.mac.plist",
81+
"extendInfo": {
82+
"NSMicrophoneUsageDescription": "Apps inside Rambox CE may need access to your microphone. Please, grant access to have a better experience.",
83+
"NSCameraUsageDescription": "Apps inside Rambox CE may need access to your camera. Please, grant access to have a better experience."
84+
}
7785
},
7886
"dmg": {
7987
"title": "Rambox",
8088
"iconSize": 128,
89+
"sign": false,
8190
"contents": [
8291
{
8392
"x": 355,
@@ -189,6 +198,7 @@
189198
"csvjson": "4.3.3",
190199
"electron": "7.1.12",
191200
"electron-builder": "21.2.0",
201+
"electron-notarize": "0.2.1",
192202
"electron-packager": "^12.1.0",
193203
"mocha": "^5.2.0",
194204
"spectron": "^3.8.0"
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
6+
<true/>
7+
<key>com.apple.security.device.microphone</key>
8+
<true/>
9+
<key>com.apple.security.device.camera</key>
10+
<true/>
11+
<key>com.apple.security.device.audio-input</key>
12+
<true/>
13+
</dict>
14+
</plist>

resources/installer/notarize.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
const { notarize } = require('electron-notarize');
2+
3+
exports.default = async function notarizing(context) {
4+
const { electronPlatformName, appOutDir } = context;
5+
if (electronPlatformName !== 'darwin') {
6+
return;
7+
}
8+
9+
const appName = context.packager.appInfo.productFilename;
10+
11+
return await notarize({
12+
appBundleId: 'com.grupovrs.ramboxce',
13+
appPath: `${appOutDir}/${appName}.app`,
14+
appleId: 'saenzramiro@gmail.com',
15+
appleIdPassword: process.env.APPLE_ID_PWD
16+
});
17+
};

0 commit comments

Comments
 (0)