Browse Source

Merge pull request #2628 from ramboxapp/0.7.4

v0.7.4
pull/2635/head
Ramiro Saenz 5 years ago committed by GitHub
parent
commit
3326447d0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app.js
  2. 42
      app/Application.js
  3. 2
      app/store/ServicesList.js
  4. 64
      app/ux/WebView.js
  5. 2
      app/view/add/Add.js
  6. 13
      electron/menu.js
  7. 58
      package-lock.json
  8. 16
      package.json
  9. 14
      resources/installer/entitlements.mac.plist
  10. 17
      resources/installer/notarize.js

4
app.js

@ -28,6 +28,10 @@ ipc.on('showAbout', function(event, message) {
ipc.on('showPreferences', function(event, message) { ipc.on('showPreferences', function(event, message) {
!Ext.cq1('preferences') ? Ext.create('Rambox.view.preferences.Preferences').show() : ''; !Ext.cq1('preferences') ? Ext.create('Rambox.view.preferences.Preferences').show() : '';
}); });
ipc.on('grantPermissions', async function() {
await require('electron').remote.systemPreferences.askForMediaAccess('microphone');
await require('electron').remote.systemPreferences.askForMediaAccess('camera');
});
ipc.on('autoUpdater:check-update', function() { ipc.on('autoUpdater:check-update', function() {
Rambox.app.checkUpdate(); Rambox.app.checkUpdate();
}); });

42
app/Application.js

@ -60,6 +60,48 @@ Ext.define('Rambox.Application', {
}) })
})(); })();
if ( !localStorage.getItem('hideMacPermissions') && process.platform === 'darwin' && (require('electron').remote.systemPreferences.getMediaAccessStatus('microphone') !== 'granted' || require('electron').remote.systemPreferences.getMediaAccessStatus('camera') !== 'granted') ) {
console.info('Checking mac permissions...');
Ext.cq1('app-main').addDocked({
xtype: 'toolbar'
,dock: 'top'
,style: {background: '#30BBF3'}
,items: [
'->'
,{
xtype: 'label'
,html: '<b>Rambox CE needs permissions to use Microphone and Camera for the apps.</b>'
}
,{
xtype: 'button'
,text: 'Grant permissions'
,ui: 'decline'
,handler: async function(btn) {
ipc.send('grantPermissions');
Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true);
}
}
,{
xtype: 'button'
,text: 'Never ask again'
,ui: 'decline'
,handler: function(btn) {
Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true);
localStorage.setItem('hideMacPermissions', true);
}
}
,'->'
,{
glyph: 'xf00d@FontAwesome'
,baseCls: ''
,style: 'cursor:pointer;'
,handler: function(btn) { Ext.cq1('app-main').removeDocked(btn.up('toolbar'), true); }
}
]
});
}
Ext.getStore('ServicesList').load(function (records, operations, success) { Ext.getStore('ServicesList').load(function (records, operations, success) {
if (!success) { if (!success) {

2
app/store/ServicesList.js

@ -10,7 +10,7 @@ Ext.define('Rambox.store.ServicesList', {
,proxy: { ,proxy: {
type: 'ajax', type: 'ajax',
url: 'https://us-central1-rambox-d1326.cloudfunctions.net/ceApps', url: 'https://raw.githubusercontent.com/saenzramiro/rambox/gh-pages/api/services.json',
reader: { reader: {
type: 'json', type: 'json',
rootProperty: 'responseText' rootProperty: 'responseText'

64
app/ux/WebView.js

@ -238,6 +238,7 @@ Ext.define('Rambox.ux.WebView',{
return { return {
xtype: 'statusbar' xtype: 'statusbar'
,id: me.id+'statusbar'
,hidden: !me.record.get('statusbar') ,hidden: !me.record.get('statusbar')
,keep: me.record.get('statusbar') ,keep: me.record.get('statusbar')
,y: floating ? '-18px' : 'auto' ,y: floating ? '-18px' : 'auto'
@ -275,7 +276,8 @@ Ext.define('Rambox.ux.WebView',{
if ( !me.record.get('enabled') ) return; if ( !me.record.get('enabled') ) return;
var webview = me.getWebView(); var webview = me.getWebView();
let googleLoginURLs = ['accounts.google.com/signin/oauth', 'accounts.google.com/ServiceLogin'] let googleLoginURLs = ['accounts.google.com/signin', 'accounts.google.com/ServiceLogin', ]
me.errorCodeLog = []
// Google Analytics Event // Google Analytics Event
ga_storage._trackEvent('Services', 'load', me.type, 1, true); ga_storage._trackEvent('Services', 'load', me.type, 1, true);
@ -321,6 +323,60 @@ Ext.define('Rambox.ux.WebView',{
me.onSearchText(e.result) me.onSearchText(e.result)
}); });
// On search text
webview.addEventListener('did-fail-load', function(e) {
console.info('The service fail at loading', me.src, e);
me.errorCodeLog.push(e.errorCode)
var attempt = me.errorCodeLog.filter(function(code) { return code === e.errorCode });
// Error codes: https://cs.chromium.org/chromium/src/net/base/net_error_list.h
var msg = []
msg[-2] = 'NET error: failed.'
msg[-3] = 'An operation was aborted (due to user action)'
msg[-7] = 'Connection timeout.'
msg[-21] = 'Network change.'
msg[-100] = 'The connection was reset. Check your internet connection.'
msg[-101] = 'The connection was reset. Check your internet connection.'
msg[-105] = 'Name not resolved. Check your internet connection.'
msg[-106] = 'There is no active internet connection.'
msg[-118] = 'Connection timed out. Check your internet connection.'
msg[-130] = 'Proxy connection failed. Please, check the proxy configuration.'
msg[-300] = 'The URL is invalid.'
msg[-324] = 'Empty response. Check your internet connection.'
switch ( e.errorCode ) {
case 0:
break
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
if ( attempt.length <= 4 ) return
setTimeout(() => me.reloadService(me), 200);
me.errorCodeLog = []
break;
case -2:
case -7:
case -21:
case -118:
case -324:
case -100:
case -101:
case -105:
attempt.length > 4 ? me.onFailLoad(msg[e.errorCode]) : setTimeout(() => me.reloadService(me), 2000);
break;
case -106:
me.onFailLoad(msg[e.errorCode])
break;
case -130:
// Could not create a connection to the proxy server. An error occurred
// either in resolving its name, or in connecting a socket to it.
// Note that this does NOT include failures during the actual "CONNECT" method
// of an HTTP proxy.
case -300:
attempt.length > 4 ? me.onFailLoad(msg[e.errorCode]) : me.reloadService(me);
break;
}
});
// Open links in default browser // Open links in default browser
webview.addEventListener('new-window', function(e) { webview.addEventListener('new-window', function(e) {
switch ( me.type ) { switch ( me.type ) {
@ -691,6 +747,12 @@ Ext.define('Rambox.ux.WebView',{
} }
} }
,onFailLoad: function(v) {
let me = this
me.errorCodeLog = []
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);
}
,showSearchBox: function(v) { ,showSearchBox: function(v) {
var me = this; var me = this;
if ( !me.record.get('enabled') ) return; if ( !me.record.get('enabled') ) return;

2
app/view/add/Add.js

@ -68,7 +68,7 @@ Ext.define('Rambox.view.add.Add',{
,emptyText: me.record.get('url') === '___' ? 'https://' : '' ,emptyText: me.record.get('url') === '___' ? 'https://' : ''
,validator: function(v) { ,validator: function(v) {
if ( !me.edit ? me.record.get('url') !== '___' : me.service.get('url').indexOf('https://___') === 0 ) return true if ( !me.edit ? me.record.get('url') !== '___' : me.service.get('url').indexOf('https://___') === 0 ) return true
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; 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;
return true; return true;
} }
,listeners: { ,listeners: {

13
electron/menu.js

@ -1,6 +1,7 @@
'use strict'; 'use strict';
const os = require('os'); const os = require('os');
const electron = require('electron'); const electron = require('electron');
const { systemPreferences } = require('electron')
const app = electron.app; const app = electron.app;
const BrowserWindow = electron.BrowserWindow; const BrowserWindow = electron.BrowserWindow;
const shell = electron.shell; const shell = electron.shell;
@ -288,6 +289,18 @@ module.exports = function(config) {
} }
] ]
}); });
helpSubmenu.push({
type: 'separator'
});
helpSubmenu.push({
label: 'Grant Microphone and Camera permissions',
visible: systemPreferences.getMediaAccessStatus('microphone') !== 'granted' || systemPreferences.getMediaAccessStatus('camera') !== 'granted',
click(item, win) {
const webContents = win.webContents;
const send = webContents.send.bind(win.webContents);
send('grantPermissions');
}
});
} else { } else {
tpl.unshift({ tpl.unshift({
label: '&'+locale['menu.file[0]'], label: '&'+locale['menu.file[0]'],

58
package-lock.json generated

@ -843,7 +843,8 @@
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz",
"integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==", "integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==",
"dev": true "dev": true,
"optional": true
}, },
"boxen": { "boxen": {
"version": "3.2.0", "version": "3.2.0",
@ -2280,6 +2281,59 @@
"resolved": "https://registry.npmjs.org/electron-log/-/electron-log-2.2.17.tgz", "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-2.2.17.tgz",
"integrity": "sha512-v+Af5W5z99ehhaLOfE9eTSXUwjzh2wFlQjz51dvkZ6ZIrET6OB/zAZPvsuwT6tm3t5x+M1r+Ed3U3xtPZYAyuQ==" "integrity": "sha512-v+Af5W5z99ehhaLOfE9eTSXUwjzh2wFlQjz51dvkZ6ZIrET6OB/zAZPvsuwT6tm3t5x+M1r+Ed3U3xtPZYAyuQ=="
}, },
"electron-notarize": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz",
"integrity": "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==",
"dev": true,
"requires": {
"debug": "^4.1.1",
"fs-extra": "^8.1.0"
},
"dependencies": {
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
}
},
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
}
}
},
"electron-osx-sign": { "electron-osx-sign": {
"version": "0.4.10", "version": "0.4.10",
"resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz", "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz",
@ -3613,7 +3667,7 @@
"dependencies": { "dependencies": {
"minimist": { "minimist": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true "dev": true
} }

16
package.json

@ -1,7 +1,7 @@
{ {
"name": "Rambox", "name": "Rambox",
"productName": "Rambox", "productName": "Rambox",
"version": "0.7.3", "version": "0.7.4",
"description": "Free and Open Source messaging and emailing app that combines common web applications into one.", "description": "Free and Open Source messaging and emailing app that combines common web applications into one.",
"main": "electron/main.js", "main": "electron/main.js",
"repository": { "repository": {
@ -66,18 +66,27 @@
"appId": "com.grupovrs.ramboxce", "appId": "com.grupovrs.ramboxce",
"asar": true, "asar": true,
"electronDownload": { "electronDownload": {
"version": "7.1.1" "version": "7.1.12"
}, },
"mac": { "mac": {
"category": "public.app-category.productivity", "category": "public.app-category.productivity",
"artifactName": "Rambox-${version}-mac.${ext}", "artifactName": "Rambox-${version}-mac.${ext}",
"target": [ "target": [
"default" "default"
] ],
"hardenedRuntime": true,
"gatekeeperAssess": false,
"entitlements": "resources/installer/entitlements.mac.plist",
"entitlementsInherit": "resources/installer/entitlements.mac.plist",
"extendInfo": {
"NSMicrophoneUsageDescription": "Apps inside Rambox CE may need access to your microphone. Please, grant access to have a better experience.",
"NSCameraUsageDescription": "Apps inside Rambox CE may need access to your camera. Please, grant access to have a better experience."
}
}, },
"dmg": { "dmg": {
"title": "Rambox", "title": "Rambox",
"iconSize": 128, "iconSize": 128,
"sign": false,
"contents": [ "contents": [
{ {
"x": 355, "x": 355,
@ -189,6 +198,7 @@
"csvjson": "4.3.3", "csvjson": "4.3.3",
"electron": "7.1.12", "electron": "7.1.12",
"electron-builder": "21.2.0", "electron-builder": "21.2.0",
"electron-notarize": "0.2.1",
"electron-packager": "^12.1.0", "electron-packager": "^12.1.0",
"mocha": "^5.2.0", "mocha": "^5.2.0",
"spectron": "^3.8.0" "spectron": "^3.8.0"

14
resources/installer/entitlements.mac.plist

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.device.microphone</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
</dict>
</plist>

17
resources/installer/notarize.js

@ -0,0 +1,17 @@
const { notarize } = require('electron-notarize');
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== 'darwin') {
return;
}
const appName = context.packager.appInfo.productFilename;
return await notarize({
appBundleId: 'com.grupovrs.ramboxce',
appPath: `${appOutDir}/${appName}.app`,
appleId: 'saenzramiro@gmail.com',
appleIdPassword: process.env.APPLE_ID_PWD
});
};
Loading…
Cancel
Save