diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..f2e7f7d0
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,10 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+indent_style = tab
diff --git a/README.md b/README.md
index 49c18202..611c95eb 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@

-## Services available - 57
+## Services available - 72
@@ -68,7 +68,6 @@
-
@@ -94,8 +93,23 @@
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
## Features
@@ -122,6 +136,10 @@ Sessions will persist using the [partition:persist](http://electron.atom.io/docs
Sync feature use Auth0 for Single Sign On & Token Based Authentication with the integration with Firebase to store the services that user is using (and the configuration for each service). You are always welcome to check the code! ;)
+## Translations
+
+Help us translate Rambox on https://crowdin.com/project/rambox/invite.
+
## [Install on Linux - Steps](https://github.com/saenzramiro/rambox/wiki/Install-on-Linux)
## [To Do](https://github.com/saenzramiro/rambox/blob/master/TODO.md)
diff --git a/app.js b/app.js
index c0489dd6..a77c0ea4 100644
--- a/app.js
+++ b/app.js
@@ -130,3 +130,8 @@ ipc.on('setBadge', function(event, messageCount) {
ipc.send('setBadge', messageCount, canvas.toDataURL());
});
+// Reload Current Service
+ipc.on('reloadCurrentService', function(e) {
+ var tab = Ext.cq1('app-main').getActiveTab();
+ if ( tab.id !== 'ramboxTab' ) tab.reloadService();
+});
diff --git a/app.json b/app.json
index 8fac74ac..abef42a1 100644
--- a/app.json
+++ b/app.json
@@ -113,7 +113,10 @@
{
"path": "resources/js/GALocalStorage.js"
},
- {
+ {
+ "path": "resources/js/loadscreen.js"
+ },
+ {
"path": "env.js"
},
{
diff --git a/app/Application.js b/app/Application.js
index e3380485..43fdc2b3 100644
--- a/app/Application.js
+++ b/app/Application.js
@@ -29,9 +29,7 @@ Ext.define('Rambox.Application', {
// Set Google Analytics events
ga_storage._setAccount('UA-80680424-1');
ga_storage._trackPageview('/index.html', 'main');
-
- // Initialize Auth0
- Rambox.ux.Auth0.init();
+ ga_storage._trackEvent('Versions', require('electron').remote.app.getVersion());
// Add shortcuts to switch services using CTRL + Number
var map = new Ext.util.KeyMap({
@@ -45,9 +43,10 @@ Ext.define('Rambox.Application', {
,handler: function(key) {
var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
- if ( tabPanel.items.items[activeIndex + 1] && tabPanel.items.items[activeIndex + 1].id === 'tbfill' ) activeIndex++;
- if ( !tabPanel.items.items[activeIndex + 1] ) activeIndex = -1;
- tabPanel.setActiveTab( activeIndex + 1 );
+ var i = activeIndex + 1;
+ if ( i >= tabPanel.items.items.length - 1 ) i = 0;
+ while ( tabPanel.items.items[i].id === 'tbfill' ) i++;
+ tabPanel.setActiveTab( i );
}
}
,{
@@ -58,10 +57,38 @@ Ext.define('Rambox.Application', {
,handler: function(key) {
var tabPanel = Ext.cq1('app-main');
var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
- if ( tabPanel.items.items[activeIndex - 1] && tabPanel.items.items[activeIndex - 1].id === 'tbfill' ) activeIndex--;
- if ( !tabPanel.items.items[activeIndex - 1] && tabPanel.items.items.length !== 2 ) activeIndex = tabPanel.items.items.length;
- if ( tabPanel.items.items.length === 2 ) activeIndex = 1;
- tabPanel.setActiveTab( activeIndex - 1 );
+ var i = activeIndex - 1;
+ if ( i < 0 ) i = tabPanel.items.items.length - 1;
+ while ( tabPanel.items.items[i].id === 'tbfill' || i < 0 ) i--;
+ tabPanel.setActiveTab( i );
+ }
+ }
+ ,{
+ key: Ext.event.Event.PAGE_DOWN
+ ,ctrl: true
+ ,alt: false
+ ,shift: false
+ ,handler: function(key) {
+ var tabPanel = Ext.cq1('app-main');
+ var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
+ var i = activeIndex + 1;
+ if ( i >= tabPanel.items.items.length - 1 ) i = 0;
+ while ( tabPanel.items.items[i].id === 'tbfill' ) i++;
+ tabPanel.setActiveTab( i );
+ }
+ }
+ ,{
+ key: Ext.event.Event.PAGE_UP
+ ,ctrl: true
+ ,alt: false
+ ,shift: false
+ ,handler: function(key) {
+ var tabPanel = Ext.cq1('app-main');
+ var activeIndex = tabPanel.items.indexOf(tabPanel.getActiveTab());
+ var i = activeIndex - 1;
+ if ( i < 0 ) i = tabPanel.items.items.length - 1;
+ while ( tabPanel.items.items[i].id === 'tbfill' ) i--;
+ tabPanel.setActiveTab( i );
}
}
,{
@@ -93,7 +120,9 @@ Ext.define('Rambox.Application', {
,ctrl: true
,alt: false
,handler: function(key) {
- Ext.cq1('app-main').setActiveTab(key - 48);
+ key = key - 48;
+ if ( key >= Ext.cq1('app-main').items.indexOf(Ext.getCmp('tbfill')) ) key++;
+ Ext.cq1('app-main').setActiveTab(key);
}
}
,{
diff --git a/app/model/ServiceList.js b/app/model/ServiceList.js
index 77e47c4e..91153c4f 100644
--- a/app/model/ServiceList.js
+++ b/app/model/ServiceList.js
@@ -31,6 +31,10 @@ Ext.define('Rambox.model.ServiceList', {
name: 'allow_popups'
,type: 'boolean'
,defaultValue: false
+ },{
+ name: 'manual_notifications'
+ ,type: 'boolean'
+ ,defaultValue: false
},{
name: 'userAgent'
,type: 'string'
@@ -39,5 +43,9 @@ Ext.define('Rambox.model.ServiceList', {
name: 'note'
,type: 'string'
,defaultValue: ''
+ },{
+ name: 'custom_domain'
+ ,type: 'boolean'
+ ,defaultValue: false
}]
});
diff --git a/app/package.json b/app/package.json
index b6b54529..602caf51 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,7 +1,7 @@
{
"name": "Rambox",
"productName": "Rambox",
- "version": "0.4.2",
+ "version": "0.4.4",
"description": "Rambox",
"main": "electron/main.js",
"private": true,
diff --git a/app/store/ServicesList.js b/app/store/ServicesList.js
index e669e20c..4047e9b1 100644
--- a/app/store/ServicesList.js
+++ b/app/store/ServicesList.js
@@ -74,6 +74,7 @@ Ext.define('Rambox.store.ServicesList', {
,url: 'https://hangouts.google.com/'
,type: 'messaging'
,titleBlink: true
+ ,manual_notifications: true
,js_unread: 'function checkUnread(){updateBadge(document.getElementById("hangout-landing-chat").lastChild.contentWindow.document.body.getElementsByClassName("ee").length)}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
},
{
@@ -84,6 +85,7 @@ Ext.define('Rambox.store.ServicesList', {
,url: 'https://___.hipchat.com/chat'
,type: 'messaging'
,js_unread: 'function checkUnread(){var e=document.getElementsByClassName("hc-badge"),t=0;for(i=0;i=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
+ ,custom_domain: true
},
{
id: 'telegram'
@@ -121,7 +123,8 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Inbox by Gmail is a new app from the Gmail team. Inbox is an organized place to get things done and get back to what matters. Bundles keep emails organized.'
,url: 'http://inbox.google.com/?cid=imp'
,type: 'email'
- ,js_unread: 'function checkUnread(){updateBadge(document.getElementsByClassName("ss").length)}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle,checked&&a>oldUnread&&new Notification("Inbox",{body:"You have a new email",icon:"https://raw.githubusercontent.com/saenzramiro/rambox/master/resources/icons/inbox.png"}),checked=!0,oldUnread=a}var checked=!1,oldUnread,originalTitle=document.title;setInterval(checkUnread,3e3);'
+ ,manual_notifications: true
+ ,js_unread: 'function checkUnread(){updateBadge(document.getElementsByClassName("ss").length)}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3e3);'
},
{
id: 'chatwork'
@@ -186,7 +189,8 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Take control. Do more. Outlook is the free email and calendar service that helps you stay on top of what matters and get things done.'
,url: 'https://mail.live.com/'
,type: 'email'
- ,js_unread: 'function checkUnread(){var a=$(".subfolders [role=treeitem]:first .treeNodeRowElement").siblings().last().text();updateBadge(""===a?0:parseInt(a))}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle,checked&&a>oldUnread&&new Notification("Outlook",{body:"You have a new email",icon:"https://raw.githubusercontent.com/saenzramiro/rambox/master/resources/icons/outlook.png"}),checked=!0,oldUnread=a}var checked=!1,oldUnread,originalTitle=document.title;setInterval(checkUnread,3e3);'
+ ,manual_notifications: true
+ ,js_unread: 'function checkUnread(){var a=$(".subfolders [role=treeitem]:first .treeNodeRowElement").siblings().last().text();updateBadge(""===a?0:parseInt(a))}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3e3);'
},
{
id: 'outlook365'
@@ -195,7 +199,8 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Outlook for Business'
,url: 'https://outlook.office.com/owa/'
,type: 'email'
- ,js_unread: 'function checkUnread(){var a=$(".subfolders [role=treeitem]:first .treeNodeRowElement").siblings().last().text();updateBadge(""===a?0:parseInt(a))}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle,checked&&a>oldUnread&&new Notification("Outlook 365",{body:"You have a new email",icon:"https://raw.githubusercontent.com/saenzramiro/rambox/master/resources/icons/outlook365.png"}),checked=!0,oldUnread=a}var checked=!1,oldUnread,originalTitle=document.title;setInterval(checkUnread,3e3);'
+ ,manual_notifications: true
+ ,js_unread: 'function checkUnread(){var a=$(".subfolders [role=treeitem]:first .treeNodeRowElement").siblings().last().text();updateBadge(""===a?0:parseInt(a))}function updateBadge(a){a>=1?document.title="("+a+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3e3);'
},
{
id: 'yahoo'
@@ -204,6 +209,7 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Web-based email service offered by the American company Yahoo!. The service is free for personal use, and paid-for business email plans are available.'
,url: 'https://mail.yahoo.com/'
,type: 'email'
+ ,note: 'To enable desktop notifications, you have to go to Options inside Yahoo! Mail.'
},
{
id: 'protonmail'
@@ -311,6 +317,7 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Mattermost is an open source, self-hosted Slack-alternative. As an alternative to proprietary SaaS messaging, Mattermost brings all your team communication into one place, making it searchable and accessible anywhere.'
,url: '___'
,type: 'messaging'
+ ,js_unread: 'Object.defineProperty(document,"title",{configurable:!0,set:function(a){document.getElementsByTagName("title")[0].innerHTML=a[0]==="*"?"(•) Mattermost":a},get:function(){return document.getElementsByTagName("title")[0].innerHTML}});'
},
{
id: 'dingtalk'
@@ -352,6 +359,7 @@ Ext.define('Rambox.store.ServicesList', {
,logo: 'custom.png'
,name: '_Custom Service'
,description: 'Add a custom service if is not listed above.'
+ ,url: '___'
,type: 'custom'
,allow_popups: true
},
@@ -413,6 +421,8 @@ Ext.define('Rambox.store.ServicesList', {
,description: 'Ad-free business Email Hosting with a clean, minimalist interface. Integrated Calendar, Contacts, Notes, Tasks apps.'
,url: 'https://mail.zoho.com/'
,type: 'email'
+ ,js_unread: 'zmail.aInfo[zmail.accId].mailId = "a";'
+ ,note: 'To enable desktop notifications, you have to go to Settings inside Zoho Email.'
},
{
id: 'zohochat'
@@ -449,13 +459,14 @@ Ext.define('Rambox.store.ServicesList', {
,type: 'email'
},
{
- id:' irccloud'
+ id: ' irccloud'
,logo: 'irccloud.png'
,name: 'IRCCloud'
,description: 'IRCCloud is a modern IRC client that keeps you connected, with none of the baggage.'
,url: 'https://www.irccloud.com/'
,type: 'messaging'
,js_unread: 'function checkUnread(){var t=0;[].map.call(document.querySelectorAll(".bufferBadges > .badge"),n=>n.textContent?parseInt(n.textContent,10):0).reduce((x,y)=>x+y,0);updateBadge(t)}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
+ ,custom_domain: true
},
{
id: 'ryver'
@@ -481,6 +492,7 @@ Ext.define('Rambox.store.ServicesList', {
,url: 'https://kiwiirc.com/client'
,type: 'messaging'
,js_unread: 'function getUnreadCount(){var a=0;$(".activity").each(function(){a+=parseInt($(this).html())});var b=!1;return $(".panel[style*=display: block] .msg").each(function(){b?a++:$(this).hasClass("last_seen")&&(b=!0)}),a}function updateTitle(a){count=getUnreadCount(),cleanTitle=a.match(re),null!==cleanTitle&&cleanTitle.length>1?cleanTitle=cleanTitle[1]:cleanTitle=a,a=count>0?"("+getUnreadCount()+") "+cleanTitle:cleanTitle,$("title").text(a)}var re=/\(\d+\)[ ](.*)/;Object.defineProperty(document,"title",{configurable:!0,set:function(a){updateTitle(a)},get:function(){return $("title").text()}}),setInterval(function(){updateTitle(document.title)},3e3);'
+ ,custom_domain: true
},
{
id: 'icloud'
@@ -524,6 +536,130 @@ Ext.define('Rambox.store.ServicesList', {
,url: '___'
,type: 'email'
,js_unread: 'function check_unread(){update_badge(appCtxt.getById(ZmFolder.ID_INBOX).numUnread)}function update_badge(a){document.title=a>0?"("+a+") "+original_title:original_title}const original_title=document.title;setInterval(check_unread,3e3);'
+ },
+ {
+ id: 'kaiwa'
+ ,logo: 'kaiwa.png'
+ ,name: 'Kaiwa'
+ ,description: 'A modern and Open Source Web client for XMPP.'
+ ,url: '___'
+ ,type: 'messaging'
+ ,js_unread: 'function check_unread() { let count=0; for (let node of document.getElementsByClassName("unread")){ if (node.innerHTML){ count += parseInt(node.innerHTML); } } update_badge(count);}function update_badge(a) { document.title = a > 0 ? "(" + a + ") " + original_title : original_title}const original_title = document.title;setInterval(check_unread, 3e3);'
+ },
+ {
+ id: 'movim'
+ ,logo: 'movim.png'
+ ,name: 'Movim'
+ ,description: 'Movim is a decentralized social network, written in PHP and HTML5 and based on the XMPP standard protocol.'
+ ,url: 'https://___.movim.eu/'
+ ,type: 'messaging'
+ ,js_unread: 'function checkUnread(){var a=document.getElementsByClassName("color dark"),b=0;for(i=0;i=1?document.title="("+a+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3e3);'
+ ,custom_domain: true
+ },
+ {
+ id: 'pushbullet'
+ ,logo: 'pushbullet.png'
+ ,name: 'Pushbullet'
+ ,description: 'Pushbullet connects your devices, making them feel like one.'
+ ,url: 'https://www.pushbullet.com/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'riot'
+ ,logo: 'riot.png'
+ ,name: 'Riot'
+ ,description: 'Riot is a simple and elegant collaboration environment that gathers all of your different conversations and app integrations into one single app.'
+ ,url: 'https://riot.im/app/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'actor'
+ ,logo: 'actor.png'
+ ,name: 'Actor'
+ ,description: 'Free and Secure text, photo and voice messages over 2G/3G or Wi-Fi.'
+ ,url: 'https://app.actor.im/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'socialcast'
+ ,logo: 'socialcast.png'
+ ,name: 'Socialcast'
+ ,description: 'Socialcast is the premier enterprise social networking platform that connects people to the knowledge, ideas and resources they need to work more effectively.'
+ ,url: 'https://___.socialcast.com/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'fleep'
+ ,logo: 'fleep.png'
+ ,name: 'Fleep'
+ ,description: 'Fleep enables communication within and across organizations - be it your team chats, project communication or 1:1 conversations.'
+ ,url: 'https://fleep.io/chat'
+ ,type: 'messaging'
+ ,js_unread: 'document.getElementsByClassName("google-login-area")[0].remove();document.getElementsByClassName("microsoft-login-area")[0].remove();'
+ },
+ {
+ id: 'spark'
+ ,logo: 'spark.png'
+ ,name: 'Cisco Spark'
+ ,description: 'Cisco Spark is for group chat, video calling, and sharing documents with your team. It’s all backed by Cisco security and reliability.'
+ ,url: 'https://web.ciscospark.com/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'mmmelon'
+ ,logo: 'mmmelon.png'
+ ,name: 'mmmelon'
+ ,description: 'The ultimate tool for daily management of projects and teams. Cloud-based, web and mobile.'
+ ,url: '___'
+ ,type: 'messaging'
+ },
+ {
+ id: 'drift'
+ ,logo: 'drift.png'
+ ,name: 'Drift'
+ ,description: 'Drift is a messaging app that makes it easy for businesses to talk to their website visitors and customers in real-time, from anywhere.'
+ ,url: 'https://app.drift.com/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'typetalk'
+ ,logo: 'typetalk.png'
+ ,name: 'Typetalk'
+ ,description: 'Typetalk brings fun and ease to team discussions through instant messaging on desktop and mobile devices.'
+ ,url: 'https://typetalk.in/signin'
+ ,type: 'messaging'
+ },
+ {
+ id: 'openmailbox'
+ ,logo: 'openmailbox.png'
+ ,name: 'Openmailbox'
+ ,description: 'Free mail hosting. Respect your rights and your privacy.'
+ ,url: 'https://www.openmailbox.org/webmail/'
+ ,type: 'email'
+ },
+ {
+ id: 'flock'
+ ,logo: 'flock.png'
+ ,name: 'Flock'
+ ,description: 'Flock is a free enterprise tool for business communication. Packed with tons of productivity features, Flock drives efficiency and boosts speed of execution.'
+ ,url: 'https://web.flock.co/'
+ ,type: 'messaging'
+ },
+ {
+ id: 'crisp'
+ ,logo: 'crisp.png'
+ ,name: 'Crisp'
+ ,description: 'Connect your customers to your team.'
+ ,url: 'https://app.crisp.im/inbox'
+ ,type: 'messaging'
+ },
+ {
+ id: 'smooch'
+ ,logo: 'smooch.png'
+ ,name: 'Smooch'
+ ,description: 'Unified multi-channel messaging for businesses, bots and software makers.'
+ ,url: 'https://app.smooch.io/'
+ ,type: 'messaging'
}
- ]
+ ]
});
diff --git a/app/ux/Auth0.js b/app/ux/Auth0.js
index e7f40ce5..92c44b83 100644
--- a/app/ux/Auth0.js
+++ b/app/ux/Auth0.js
@@ -113,7 +113,7 @@ Ext.define('Rambox.ux.Auth0', {
} else {
Ext.Msg.confirm('Clear services', 'Do you want to remove all your current services to start over?
If NO, you will be logged out.', function(btnId) {
if ( btnId === 'yes' ) {
- me.removeAllServices(false);
+ Ext.cq1('app-main').getController().removeAllServices(false);
} else {
me.logout();
}
@@ -124,7 +124,7 @@ Ext.define('Rambox.ux.Auth0', {
} else if ( snapshot2.hasChildren() && Ext.getStore('Services').getCount() > 0 ) {
Ext.Msg.confirm('Confirm', 'To import your configuration, I need to remove all your current services. Do you want to continue?
If NO, you will be logged out.', function(btnId) {
if ( btnId === 'yes' ) {
- me.removeAllServices(false, function() {
+ Ext.cq1('app-main').getController().removeAllServices(false, function() {
importServices(snapshot2);
});
} else {
@@ -140,10 +140,10 @@ Ext.define('Rambox.ux.Auth0', {
localStorage.setItem('id_token', authResult.idToken);
}
});
- }).catch(function(error) {
+ })['catch'](function(error) {
Ext.Msg.hide();
Ext.Msg.show({
- title: 'Firebug Error'
+ title: 'Firebase Error'
,message: error.message+'
Code: '+error.code+'
Sorry, try again later.'
,icon: Ext.Msg.ERROR
,buttons: Ext.Msg.OK
@@ -164,6 +164,8 @@ Ext.define('Rambox.ux.Auth0', {
,login: function() {
var me = this;
+ if ( !me.auth0 ) Rambox.ux.Auth0.init();
+
me.lock.show();
}
diff --git a/app/ux/Firebase.js b/app/ux/Firebase.js
index cebf25f1..6fc3e008 100644
--- a/app/ux/Firebase.js
+++ b/app/ux/Firebase.js
@@ -14,14 +14,43 @@ Ext.define('Rambox.ux.Firebase', {
// Attach an asynchronous callback to read the data at our posts reference
ref.on("child_changed", function(snapshot, prevChildKey) {
+ // Disable duplicate actions when user edit a service
+ var rec = Ext.getStore('Services').findRecord('firebase_key', snapshot.key);
+ var recData = Ext.clone(rec.data);
+ delete recData.id;
+ delete recData.firebase_key;
+ if ( Ext.Object.equals(recData, snapshot.val()) ) return;
+
console.info('Firebase - Child Changed', snapshot.val(), snapshot.key, prevChildKey);
+ // Suspend events
Ext.getStore('Services').suspendEvent('update');
- var rec = Ext.getStore('Services').findRecord('firebase_key', snapshot.key);
-
+ // Change the title of the Tab
Ext.getCmp('tab_'+rec.get('id')).setTitle(snapshot.val().name);
-
+ // Change sound of the Tab
+ Ext.getCmp('tab_'+rec.get('id')).setAudioMuted(snapshot.val().muted);
+ // Change notifications of the Tab
+ Ext.getCmp('tab_'+rec.get('id')).setNotifications(snapshot.val().notifications);
+ // Change the icon of the Tab
+ if ( rec.get('type') === 'custom' && rec.get('logo') !== snapshot.val().logo ) Ext.getCmp('tab_'+rec.get('id')).setConfig('icon', snapshot.val().logo === '' ? 'resources/icons/custom.png' : snapshot.val().logo);
+ // Change the URL of the Tab
+ if ( rec.get('url') !== snapshot.val().url ) Ext.getCmp('tab_'+rec.get('id')).setURL(snapshot.val().url);
+
+ // Change the align of the Tab
+ if ( rec.get('align') !== snapshot.val().align ) {
+ if ( rec.get('align') === 'left' ) {
+ Ext.cq1('app-main').moveBefore(Ext.getCmp('tab_'+rec.get('id')), Ext.getCmp('tbfill'));
+ } else {
+ Ext.cq1('app-main').moveAfter(Ext.getCmp('tab_'+rec.get('id')), Ext.getCmp('tbfill'));
+ }
+ }
+ // Apply the JS Code of the Tab
+ if ( rec.get('js_unread') !== snapshot.val().js_unread ) {
+ Ext.Msg.confirm('CUSTOM CODE', 'Rambox needs to reload the service to execute the new JavaScript code. Do you want to do it now?', function( btnId ) {
+ if ( btnId === 'yes' ) Ext.getCmp('tab_'+rec.get('id')).reloadService();
+ });
+ }
// Position
if ( rec.get('position') !== snapshot.val().position ) {
var pos = parseInt(snapshot.val().position);
@@ -29,11 +58,14 @@ Ext.define('Rambox.ux.Firebase', {
Ext.cq1('app-main').move(Ext.getCmp('tab_'+rec.get('id')), pos);
}
- // Enable/Disable
- if ( rec.get('enable') !== snapshot.val().enable ) Ext.getCmp('tab_'+rec.get('id')).setEnabled(snapshot.val().enabled);
-
rec.set(snapshot.val());
rec.save();
+ Ext.getCmp('tab_'+rec.get('id')).record = rec;
+ Ext.getCmp('tab_'+rec.get('id')).tabConfig.service = rec;
+
+ // Enable/Disable
+ if ( recData.enabled !== snapshot.val().enabled ) Ext.getCmp('tab_'+rec.get('id')).setEnabled(snapshot.val().enabled);
+
Ext.getStore('Services').resumeEvent('update');
Ext.getStore('Services').load();
}, function (errorObject) {
diff --git a/app/ux/WebView.js b/app/ux/WebView.js
index b222c17d..e681b331 100644
--- a/app/ux/WebView.js
+++ b/app/ux/WebView.js
@@ -34,7 +34,14 @@ Ext.define('Rambox.ux.WebView',{
if ( me.record.get('trust') ) ipc.send('allowCertificate', me.src);
Ext.apply(me, {
- items: me.webViewConstructor(me.record.get('enabled'))
+ items: me.webViewConstructor()
+ ,title: me.record.get('name')
+ ,icon: me.record.get('type') === 'custom' ? (me.record.get('logo') === '' ? 'resources/icons/custom.png' : me.record.get('logo')) : 'resources/icons/'+me.record.get('logo')
+ ,src: me.record.get('url')
+ ,type: me.record.get('type')
+ ,align: me.record.get('align')
+ ,notifications: me.record.get('notifications')
+ ,muted: me.record.get('muted')
,tabConfig: {
listeners: {
badgetextchange: me.onBadgeTextChange
@@ -44,6 +51,7 @@ Ext.define('Rambox.ux.WebView',{
e.stopEvent();
});
}
+ ,scope: me
}
,clickEvent: ''
,style: !me.record.get('enabled') ? '-webkit-filter: grayscale(1)' : ''
@@ -121,10 +129,12 @@ Ext.define('Rambox.ux.WebView',{
me.callParent(config);
}
- ,webViewConstructor: function(enabled) {
+ ,webViewConstructor: function( enabled ) {
var me = this;
var cfg;
+ enabled = enabled || me.record.get('enabled');
+
if ( !enabled ) {
cfg = {
xtype: 'container'
@@ -140,25 +150,26 @@ Ext.define('Rambox.ux.WebView',{
,autoShow: true
,autoEl: {
tag: 'webview'
- ,src: me.src
+ ,src: me.record.get('url')
,style: 'width:100%;height:100%;'
- ,partition: 'persist:' + me.type + '_' + me.id.replace('tab_', '') + (localStorage.getItem('id_token') ? '_' + Ext.decode(localStorage.getItem('profile')).user_id : '')
+ ,partition: 'persist:' + me.record.get('type') + '_' + me.id.replace('tab_', '') + (localStorage.getItem('id_token') ? '_' + Ext.decode(localStorage.getItem('profile')).user_id : '')
,plugins: 'true'
,allowtransparency: 'on'
,autosize: 'on'
,disablewebsecurity: 'on'
,blinkfeatures: 'ApplicationCache,GlobalCacheStorage'
- ,useragent: Ext.getStore('ServicesList').getById(me.type).get('userAgent')
+ ,useragent: Ext.getStore('ServicesList').getById(me.record.get('type')).get('userAgent')
}
};
- if ( Ext.getStore('ServicesList').getById(me.type).get('allow_popups') ) cfg.autoEl.allowpopups = 'on';
+ if ( Ext.getStore('ServicesList').getById(me.record.get('type')).get('allow_popups') ) cfg.autoEl.allowpopups = 'on';
}
return cfg;
}
,onBadgeTextChange: function( tab, badgeText, oldBadgeText ) {
+ var me = this;
if ( oldBadgeText === null ) oldBadgeText = 0;
var actualNotifications = Rambox.app.getTotalNotifications();
@@ -166,6 +177,31 @@ Ext.define('Rambox.ux.WebView',{
badgeText = Rambox.util.Format.stripNumber(badgeText);
Rambox.app.setTotalNotifications(actualNotifications - oldBadgeText + badgeText);
+
+ // Some services dont have Desktop Notifications, so we add that functionality =)
+ if ( Ext.getStore('ServicesList').getById(me.type).get('manual_notifications') && oldBadgeText < badgeText && me.record.get('notifications') && !JSON.parse(localStorage.getItem('dontDisturb')) ) {
+ var text;
+ switch ( Ext.getStore('ServicesList').getById(me.type).get('type') ) {
+ case 'messaging':
+ text = 'You have ' + Ext.util.Format.plural(badgeText, 'new message', 'new messages') + '.';
+ break;
+ case 'email':
+ text = 'You have ' + Ext.util.Format.plural(badgeText, 'new email', 'new emails') + '.';
+ break;
+ default:
+ text = 'You have ' + Ext.util.Format.plural(badgeText, 'new activity', 'new activities') + '.';
+ break;
+ }
+ var not = new Notification(me.record.get('name'), {
+ body: text
+ ,icon: tab.icon
+ ,silent: me.record.get('muted')
+ });
+ not.onclick = function() {
+ require('electron').remote.getCurrentWindow().show();
+ Ext.cq1('app-main').setActiveTab(me);
+ };
+ }
}
,onAfterRender: function() {
@@ -198,7 +234,6 @@ Ext.define('Rambox.ux.WebView',{
// Open links in default browser
webview.addEventListener('new-window', function(e) {
- console.log('new-window', e);
switch ( me.type ) {
case 'skype':
// hack to fix multiple browser tabs on Skype link click, re #11
@@ -271,7 +306,7 @@ Ext.define('Rambox.ux.WebView',{
});
webview.addEventListener('did-get-redirect-request', function( e ) {
- if ( e.isMainFrame ) Ext.defer(function() { webview.loadURL(e.newURL); }, 1000);
+ if ( e.isMainFrame ) webview.loadURL(e.newURL);
});
}
@@ -279,7 +314,10 @@ Ext.define('Rambox.ux.WebView',{
var me = this;
var webview = me.down('component').el.dom;
- if ( me.record.get('enabled') ) webview.loadURL(me.src);
+ if ( me.record.get('enabled') ) {
+ me.tab.setBadgeText('');
+ webview.loadURL(me.src);
+ }
}
,toggleDevTools: function(btn) {
@@ -289,10 +327,21 @@ Ext.define('Rambox.ux.WebView',{
if ( me.record.get('enabled') ) webview.isDevToolsOpened() ? webview.closeDevTools() : webview.openDevTools();
}
+ ,setURL: function(url) {
+ var me = this;
+ var webview = me.down('component').el.dom;
+
+ me.src = url;
+
+ if ( me.record.get('enabled') ) webview.loadURL(url);
+ }
+
,setAudioMuted: function(muted, calledFromDisturb) {
var me = this;
var webview = me.down('component').el.dom;
+ me.muted = muted;
+
if ( !muted && !calledFromDisturb && JSON.parse(localStorage.getItem('dontDisturb')) ) return;
if ( me.record.get('enabled') ) webview.setAudioMuted(muted);
@@ -302,6 +351,8 @@ Ext.define('Rambox.ux.WebView',{
var me = this;
var webview = me.down('component').el.dom;
+ me.notifications = notification;
+
if ( notification && !calledFromDisturb && JSON.parse(localStorage.getItem('dontDisturb')) ) return;
if ( me.record.get('enabled') ) ipc.send('setServiceNotifications', webview.partition, notification);
@@ -310,12 +361,14 @@ Ext.define('Rambox.ux.WebView',{
,setEnabled: function(enabled) {
var me = this;
+ me.tab.setBadgeText('');
me.removeAll();
me.add(me.webViewConstructor(enabled));
if ( enabled ) {
me.resumeEvent('afterrender');
me.show();
me.tab.setStyle('-webkit-filter', 'grayscale(0)');
+ me.onAfterRender();
} else {
me.suspendEvent('afterrender');
me.tab.setStyle('-webkit-filter', 'grayscale(1)');
diff --git a/app/view/add/Add.js b/app/view/add/Add.js
new file mode 100644
index 00000000..8e32e81f
--- /dev/null
+++ b/app/view/add/Add.js
@@ -0,0 +1,219 @@
+Ext.define('Rambox.view.add.Add',{
+ extend: 'Ext.window.Window'
+
+ ,requires: [
+ 'Rambox.view.add.AddController'
+ ,'Rambox.view.add.AddModel'
+ ]
+
+ ,controller: 'add-add'
+ ,viewModel: {
+ type: 'add-add'
+ }
+
+ // private
+ ,record: null
+ ,service: null
+ ,edit: false
+
+ // defaults
+ ,modal: true
+ ,width: 500
+ ,autoShow: true
+ ,resizable: false
+ ,draggable: false
+ ,bodyPadding: 20
+
+ ,initComponent: function() {
+ var me = this;
+
+ me.title = (!me.edit ? 'Add ' : 'Edit ') + me.record.get('name');
+ me.icon = me.record.get('type') === 'custom' ? (!me.edit ? 'resources/icons/custom.png' : (me.record.get('logo') === '' ? 'resources/icons/custom.png' : me.record.get('logo'))) : 'resources/icons/'+me.record.get('logo');
+ me.items = [
+ {
+ xtype: 'form'
+ ,items: [
+ {
+ xtype: 'textfield'
+ ,fieldLabel: 'Name'
+ ,value: me.record.get('type') === 'custom' ? (me.edit ? me.record.get('name') : '') : me.record.get('name')
+ ,name: 'serviceName'
+ ,allowBlank: true
+ ,listeners: { specialkey: 'onEnter' }
+ }
+ ,{
+ xtype: 'container'
+ ,layout: 'column'
+ ,hidden: me.edit ? me.service.get('url').indexOf('___') === -1 && !me.service.get('custom_domain') : me.record.get('url').indexOf('___') === -1 && !me.record.get('custom_domain')
+ ,items: [
+ {
+ xtype: 'textfield'
+ ,fieldLabel: 'URL'
+ ,name: 'url'
+ ,value: me.edit && me.service.get('url').indexOf('___') >= 0 ? me.record.get('url').replace(me.service.get('url').split('___')[0], '').replace(me.service.get('url').split('___')[1], '') : (me.record.get('url').indexOf('___') === -1 ? me.record.get('url') : '')
+ ,readOnly: me.edit ? (me.service.get('custom_domain') && me.service.get('url') === me.record.get('url') ? true : me.service.get('url').indexOf('___') === -1 && !me.service.get('custom_domain')) : me.record.get('url').indexOf('___') === -1 && me.record.get('custom_domain')
+ ,allowBlank: false
+ ,submitEmptyText: false
+ ,emptyText: me.record.get('url') === '___' ? 'http://' : ''
+ ,vtype: me.record.get('url') === '___' ? 'url' : ''
+ ,width: 275
+ ,listeners: { specialkey: 'onEnter' }
+ }
+ ,{
+ xtype: 'cycle'
+ ,showText: true
+ ,style: 'border-top-left-radius:0;border-bottom-left-radius:0;'
+ ,hidden: me.edit ? me.service.get('type') === 'custom' || me.service.get('url') === '___' : me.record.get('type') === 'custom' || me.record.get('url') === '___'
+ ,arrowVisible: me.edit ? (me.service.get('url').indexOf('___') >= 0 && !me.service.get('custom_domain') ? false : me.service.get('custom_domain')) : (me.record.get('url').indexOf('___') >= 0 && !me.record.get('custom_domain') ? false : me.record.get('custom_domain'))
+ ,menu: {
+ items: [
+ {
+ text: me.edit ? (me.service.get('url').indexOf('___') === -1 ? 'Official Server' : Ext.String.endsWith(me.service.get('url'), '/') ? me.service.get('url').split('___')[1].slice(0, -1) : me.service.get('url').split('___')[1]) : (me.record.get('url').indexOf('___') === -1 ? 'Official Server' : Ext.String.endsWith(me.record.get('url'), '/') ? me.record.get('url').split('___')[1].slice(0, -1) : me.record.get('url').split('___')[1])
+ ,checked: me.edit ? (me.service.get('custom_domain') && me.service.get('url') === me.record.get('url') ? true : Ext.String.endsWith(me.record.get('url'), me.service.get('url').split('___')[1])) : true
+ ,disabled: me.edit ? me.service.get('url') === '___' : me.record.get('url') === '___'
+ }
+ ,{
+ text: 'Custom Server'
+ ,checked: me.edit ? (me.service.get('custom_domain') && me.service.get('url') === me.record.get('url') ? false : !Ext.String.endsWith(me.record.get('url'), me.service.get('url').split('___')[1])) : false
+ ,custom: true
+ ,disabled: me.edit ? !me.service.get('custom_domain') : !me.record.get('custom_domain')
+ }
+ ]
+ }
+ // Fixes bug EXTJS-20094 for version Ext JS 5
+ ,arrowHandler: function(cycleBtn, e) {
+ if ( !cycleBtn.arrowVisible ) cycleBtn.hideMenu();
+ }
+ ,changeHandler: function(cycleBtn, activeItem) {
+ Ext.apply(cycleBtn.previousSibling(), {
+ emptyText: activeItem.custom ? 'http://' : ' '
+ ,vtype: activeItem.custom ? 'url' : ''
+ });
+ cycleBtn.previousSibling().applyEmptyText();
+ cycleBtn.previousSibling().reset();
+
+ if ( me.edit && cycleBtn.nextSibling().originalValue !== '2' ) {
+ me.service.get('custom_domain') && !activeItem.custom ? cycleBtn.previousSibling().reset() : cycleBtn.previousSibling().setValue('');
+ } else if ( me.edit && cycleBtn.nextSibling().originalValue === '2' ) {
+ me.service.get('custom_domain') && !activeItem.custom ? cycleBtn.previousSibling().setValue( me.service.get('url').indexOf('___') === -1 && me.service.get('custom_domain') ? me.service.get('url') : '') : cycleBtn.previousSibling().reset();
+ } else if ( !me.edit && cycleBtn.nextSibling().originalValue === '1' ) {
+ activeItem.custom ? cycleBtn.previousSibling().setValue('') : cycleBtn.previousSibling().reset();
+ }
+
+ cycleBtn.previousSibling().setReadOnly( activeItem.custom ? false : (me.edit ? me.service.get('url').indexOf('___') === -1 : me.record.get('url').indexOf('___') === -1) );
+ cycleBtn.nextSibling().setValue( activeItem.custom ? 2 : 1 );
+ }
+ }
+ ,{
+ xtype: 'hiddenfield'
+ ,name: 'cycleValue'
+ ,value: me.edit ? (me.service.get('custom_domain') && me.service.get('url') === me.record.get('url') ? 1 : (!Ext.String.endsWith(me.record.get('url'), me.service.get('url').split('___')[1]) ? 2 : 1)) : 1
+ }
+ ]
+ }
+ ,{
+ xtype: 'textfield'
+ ,fieldLabel: 'Logo'
+ ,emptyText: 'http://url.com/image.png'
+ ,name: 'logo'
+ ,vtype: me.record.get('type') === 'custom' ? 'url' : ''
+ ,value: me.record.get('type') === 'custom' ? (me.edit ? me.record.get('logo') : '') : me.record.get('logo')
+ ,allowBlank: true
+ ,hidden: me.record.get('type') !== 'custom'
+ ,margin: '5 0 0 0'
+ ,listeners: { specialkey: 'onEnter' }
+ }
+ ,{
+ xtype: 'fieldset'
+ ,title: 'Options'
+ ,margin: '10 0 0 0'
+ ,items: [
+ {
+ xtype: 'checkbox'
+ ,boxLabel: 'Align to Right'
+ ,checked: me.edit ? (me.record.get('align') === 'right' ? true : false) : false
+ ,name: 'align'
+ ,uncheckedValue: 'left'
+ ,inputValue: 'right'
+ }
+ ,{
+ xtype: 'checkbox'
+ ,boxLabel: 'Show notifications'
+ ,name: 'notifications'
+ ,checked: me.edit ? me.record.get('notifications') : true
+ ,uncheckedValue: false
+ ,inputValue: true
+ }
+ ,{
+ xtype: 'checkbox'
+ ,boxLabel: 'Mute all sounds'
+ ,name: 'muted'
+ ,checked: me.edit ? me.record.get('muted') : false
+ ,uncheckedValue: false
+ ,inputValue: true
+ }
+ ,{
+ xtype: 'checkbox'
+ ,boxLabel: 'Trust invalid authority certificates'
+ ,name: 'trust'
+ ,hidden: me.record.get('type') !== 'custom'
+ ,checked: me.edit ? me.record.get('trust') : false
+ ,uncheckedValue: false
+ ,inputValue: true
+ }
+ ]
+ }
+ ,{
+ xtype: 'fieldset'
+ ,title: 'Advanced'
+ ,margin: '10 0 0 0'
+ ,collapsible: true
+ ,collapsed: true
+ ,items: [
+ {
+ xtype: 'textarea'
+ ,fieldLabel: 'Custom Code (read more)'
+ ,allowBlank: true
+ ,name: 'js_unread'
+ ,value: me.edit ? me.record.get('js_unread') : ''
+ ,anchor: '100%'
+ ,height: 120
+ }
+ ]
+ }
+ ,{
+ xtype: 'container'
+ ,hidden: (me.edit ? Ext.getStore('ServicesList').getById(me.record.get('type')).get('note') === '' : me.record.get('note') === '')
+ ,data: { note: (me.edit ? Ext.getStore('ServicesList').getById(me.record.get('type')).get('note') : me.record.get('note')) }
+ ,margin: '10 0 0 0'
+ ,style: 'background-color:#93CFE0;color:#053767;border-radius:6px;'
+ ,tpl: [
+ ''
+ ,'{note}'
+ ]
+ }
+ ]
+ }
+ ];
+
+ me.buttons = [
+ {
+ text: 'Cancel'
+ ,ui: 'decline'
+ ,handler: 'doCancel'
+ }
+ ,'->'
+ ,{
+ text: me.title
+ ,itemId: 'submit'
+ ,handler: 'doSave'
+ }
+ ];
+
+ this.callParent(this);
+ }
+
+ ,listeners: {
+ show: 'onShow'
+ }
+});
diff --git a/app/view/add/AddController.js b/app/view/add/AddController.js
new file mode 100644
index 00000000..97ce0a73
--- /dev/null
+++ b/app/view/add/AddController.js
@@ -0,0 +1,125 @@
+Ext.define('Rambox.view.add.AddController', {
+ extend: 'Ext.app.ViewController'
+ ,alias: 'controller.add-add'
+
+ ,doCancel: function( btn ) {
+ var me = this;
+
+ me.getView().close();
+ }
+
+ ,doSave: function( btn ) {
+ var me = this;
+
+ var win = me.getView();
+ if ( !win.down('form').isValid() ) return false;
+
+ var formValues = win.down('form').getValues();
+
+ if ( win.edit ) {
+ // Format data
+ if ( win.service.get('url').indexOf('___') >= 0 ) {
+ formValues.url = formValues.cycleValue === '1' ? win.service.get('url').replace('___', formValues.url) : formValues.url;
+ }
+
+ var oldData = win.record.getData();
+ win.record.set({
+ logo: formValues.logo
+ ,name: formValues.serviceName
+ ,url: formValues.url
+ ,align: formValues.align
+ ,notifications: formValues.notifications
+ ,muted: formValues.muted
+ ,trust: formValues.trust
+ ,js_unread: formValues.js_unread
+ });
+ // Change the title of the Tab
+ Ext.getCmp('tab_'+win.record.get('id')).setTitle(formValues.serviceName);
+ // Change sound of the Tab
+ Ext.getCmp('tab_'+win.record.get('id')).setAudioMuted(formValues.muted);
+ // Change notifications of the Tab
+ Ext.getCmp('tab_'+win.record.get('id')).setNotifications(formValues.notifications);
+ // Change the icon of the Tab
+ if ( win.record.get('type') === 'custom' && oldData.logo !== formValues.logo ) Ext.getCmp('tab_'+win.record.get('id')).setConfig('icon', formValues.logo === '' ? 'resources/icons/custom.png' : formValues.logo);
+ // Change the URL of the Tab
+ if ( oldData.url !== formValues.url ) Ext.getCmp('tab_'+win.record.get('id')).setURL(formValues.url);
+ // Change the align of the Tab
+ if ( oldData.align !== formValues.align ) {
+ if ( formValues.align === 'left' ) {
+ Ext.cq1('app-main').moveBefore(Ext.getCmp('tab_'+win.record.get('id')), Ext.getCmp('tbfill'));
+ } else {
+ Ext.cq1('app-main').moveAfter(Ext.getCmp('tab_'+win.record.get('id')), Ext.getCmp('tbfill'));
+ }
+ }
+ // Apply the JS Code of the Tab
+ if ( win.down('textarea').isDirty() ) {
+ Ext.Msg.confirm('CUSTOM CODE', 'Rambox needs to reload the service to execute the new JavaScript code. Do you want to do it now?', function( btnId ) {
+ if ( btnId === 'yes' ) Ext.getCmp('tab_'+win.record.get('id')).reloadService();
+ });
+ }
+
+ Ext.getCmp('tab_'+win.record.get('id')).record = win.record;
+ Ext.getCmp('tab_'+win.record.get('id')).tabConfig.service = win.record;
+ } else {
+ // Format data
+ if ( win.record.get('url').indexOf('___') >= 0 ) {
+ formValues.url = formValues.cycleValue === '1' ? win.record.get('url').replace('___', formValues.url) : formValues.url;
+ }
+
+ var service = Ext.create('Rambox.model.Service', {
+ type: win.record.get('id')
+ ,logo: formValues.logo
+ ,name: formValues.serviceName
+ ,url: formValues.url
+ ,align: formValues.align
+ ,notifications: formValues.notifications
+ ,muted: formValues.muted
+ ,trust: formValues.trust
+ ,js_unread: formValues.js_unread
+ });
+ service.save();
+ Ext.getStore('Services').add(service);
+
+ var tabData = {
+ xtype: 'webview'
+ ,id: 'tab_'+service.get('id')
+ /*
+ ,title: service.get('name')
+ ,icon: service.get('logo')
+ ,src: service.get('url')
+ ,type: service.get('type')
+ ,align: formValues.align
+ ,notifications: formValues.notifications
+ ,muted: formValues.muted
+ */
+ ,record: service
+ ,tabConfig: {
+ service: service
+ }
+ };
+
+ if ( formValues.align === 'left' ) {
+ var tbfill = Ext.cq1('app-main').getTabBar().down('tbfill');
+ Ext.cq1('app-main').insert(Ext.cq1('app-main').getTabBar().items.indexOf(tbfill), tabData).show();
+ } else {
+ Ext.cq1('app-main').add(tabData).show();
+ }
+ }
+
+ win.close();
+ }
+
+ ,onEnter: function(field, e) {
+ var me = this;
+
+ if ( e.getKey() == e.ENTER && field.up('form').isValid() ) me.doSave();
+ }
+
+ ,onShow: function(win) {
+ var me = this;
+
+ // Make focus to the name field
+ win.down('textfield[name="serviceName"]').focus(true, 100);
+ }
+
+});
diff --git a/app/view/add/AddModel.js b/app/view/add/AddModel.js
new file mode 100644
index 00000000..7dd56ad9
--- /dev/null
+++ b/app/view/add/AddModel.js
@@ -0,0 +1,4 @@
+Ext.define('Rambox.view.add.AddModel', {
+ extend: 'Ext.app.ViewModel'
+ ,alias: 'viewmodel.add-add'
+});
diff --git a/app/view/main/Main.js b/app/view/main/Main.js
index 82dcbc9b..7fc1f123 100644
--- a/app/view/main/Main.js
+++ b/app/view/main/Main.js
@@ -5,6 +5,7 @@ Ext.define('Rambox.view.main.Main', {
,'Rambox.view.main.MainModel'
,'Rambox.ux.WebView'
,'Rambox.ux.mixin.Badge'
+ ,'Rambox.view.add.Add'
,'Ext.ux.TabReorderer'
]
@@ -290,16 +291,18 @@ Ext.define('Rambox.view.main.Main', {
,allowToggle: false
,items: [
{
- text: 'Donate with'
- ,overCls: ''
+ text: 'Help us with'
+ ,pressed: true
}
,{
- glyph: 'xf1ed@FontAwesome'
- ,href: 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=WU75QWS7LH2CA'
+ text: 'Donation'
+ ,glyph: 'xf21e@FontAwesome'
+ ,handler: 'showDonate'
}
,{
- glyph: 'xf15a@FontAwesome'
- ,href: 'https://www.coinbase.com/saenzramiro'
+ text: 'Translation'
+ ,glyph: 'xf0ac@FontAwesome'
+ ,href: 'https://crowdin.com/project/rambox/invite'
}
]
}
@@ -310,19 +313,26 @@ Ext.define('Rambox.view.main.Main', {
}
,'->'
,{
- glyph: 'xf082@FontAwesome'
- ,tooltip: 'Facebook'
- ,href: 'https://www.facebook.com/ramboxapp'
- }
- ,{
- glyph: 'xf099@FontAwesome'
- ,tooltip: 'Twitter'
- ,href: 'https://www.twitter.com/ramboxapp'
- }
- ,{
- glyph: 'xf09b@FontAwesome'
- ,tooltip: 'GitHub'
- ,href: 'https://www.github.com/saenzramiro/rambox'
+ xtype: 'segmentedbutton'
+ ,allowToggle: false
+ ,items: [
+ {
+ text: 'Follow us'
+ ,pressed: true
+ }
+ ,{
+ glyph: 'xf082@FontAwesome'
+ ,href: 'https://www.facebook.com/ramboxapp'
+ }
+ ,{
+ glyph: 'xf099@FontAwesome'
+ ,href: 'https://www.twitter.com/ramboxapp'
+ }
+ ,{
+ glyph: 'xf09b@FontAwesome'
+ ,href: 'https://www.github.com/saenzramiro/rambox'
+ }
+ ]
}
]
}
diff --git a/app/view/main/MainController.js b/app/view/main/MainController.js
index 27adee6c..b4b6519d 100644
--- a/app/view/main/MainController.js
+++ b/app/view/main/MainController.js
@@ -45,395 +45,6 @@ Ext.define('Rambox.view.main.MainController', {
Ext.getCmp('tab_'+e.record.get('id')).setTitle(e.record.get('name'));
}
- ,showSimpleModal: function(record, edit) {
- var me = this;
-
- var win = Ext.create('Ext.window.Window', {
- title: (edit ? 'Edit ' : 'Add ') + record.get('name')
- ,modal: true
- ,width: 400
- ,resizable: false
- ,draggable: false
- ,bodyPadding: 20
- ,icon: 'resources/icons/' + record.get('logo')
- ,items: [
- {
- xtype: 'form'
- ,items: [
- {
- xtype: 'textfield'
- ,fieldLabel: 'Name'
- ,value: record.get('name')
- ,name: 'serviceName'
- ,allowBlank: true
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Options'
- ,margin: '10 0 0 0'
- ,items: [
- {
- xtype: 'checkbox'
- ,boxLabel: 'Align to Right'
- ,checked: edit ? (record.get('align') === 'right' ? true : false) : false
- ,name: 'align'
- ,uncheckedValue: 'left'
- ,inputValue: 'right'
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Show notifications'
- ,name: 'notifications'
- ,checked: edit ? record.get('notifications') : true
- ,uncheckedValue: false
- ,inputValue: true
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Mute all sounds'
- ,name: 'muted'
- ,checked: edit ? record.get('muted') : false
- ,uncheckedValue: false
- ,inputValue: true
- }
- ]
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Advanced'
- ,margin: '10 0 0 0'
- ,collapsible: true
- ,collapsed: true
- ,items: [
- {
- xtype: 'textarea'
- ,fieldLabel: 'Custom Code (read more)'
- ,allowBlank: true
- ,name: 'js_unread'
- ,value: edit ? record.get('js_unread') : ''
- ,anchor: '100%'
- ,height: 120
- }
- ]
- }
- ,{
- xtype: 'container'
- ,hidden: (edit ? Ext.getStore('ServicesList').getById(record.get('type')).get('note') === '' : record.get('note') === '')
- ,data: { note: (edit ? Ext.getStore('ServicesList').getById(record.get('type')).get('note') : record.get('note')) }
- ,margin: '10 0 0 0'
- ,style: 'background-color:#93CFE0;color:#053767;border-radius:6px;'
- ,tpl: [
- ''
- ,'{note}'
- ]
- }
- ]
- }
- ]
- ,buttons: [
- {
- text: 'Cancel'
- ,ui: 'decline'
- ,handler: function() {
- win.close();
- }
- }
- ,'->'
- ,{
- text: edit ? 'Save' : 'Add service'
- ,itemId: 'submit'
- ,handler: function() {
- if ( !win.down('form').isValid() ) return false;
-
- var formValues = win.down('form').getValues();
-
- if ( edit ) {
- var oldData = record.getData();
- record.set({
- name: formValues.serviceName
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,js_unread: formValues.js_unread
- });
- // Change the title of the Tab
- Ext.getCmp('tab_'+record.get('id')).setTitle(formValues.serviceName);
- // Change sound of the Tab
- Ext.getCmp('tab_'+record.get('id')).setAudioMuted(formValues.muted);
- // Change notifications of the Tab
- Ext.getCmp('tab_'+record.get('id')).setNotifications(formValues.notifications);
- // Change the align of the Tab
- if ( oldData.align !== formValues.align ) {
- if ( formValues.align === 'left' ) {
- me.getView().moveBefore(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- } else {
- me.getView().moveAfter(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- }
- }
-
- Ext.getCmp('tab_'+record.get('id')).record = record;
- } else {
- var service = Ext.create('Rambox.model.Service', {
- type: record.get('id')
- ,logo: record.get('logo')
- ,name: formValues.serviceName
- ,url: record.get('url')
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,js_unread: formValues.js_unread
- });
- service.save();
- Ext.getStore('Services').add(service);
-
- var tabData = {
- xtype: 'webview'
- ,id: 'tab_'+service.get('id')
- ,title: service.get('name')
- ,icon: 'resources/icons/'+service.get('logo')
- ,src: service.get('url')
- ,type: service.get('type')
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,record: service
- ,tabConfig: {
- service: service
- }
- };
-
- if ( formValues.align === 'left' ) {
- var tbfill = me.getView().getTabBar().down('tbfill');
- me.getView().insert(me.getView().getTabBar().items.indexOf(tbfill), tabData).show();
- } else {
- me.getView().add(tabData).show();
- }
- }
-
- win.close();
- }
- }
- ]
- }).show();
-
- // Make focus to the name field
- win.down('textfield[name="serviceName"]').focus(true, 100);
- }
-
- ,showCustomModal: function(record, edit) {
- var me = this;
-
- var win = Ext.create('Ext.window.Window', {
- title: (edit ? 'Edit ' : 'Add ') + record.get('name')
- ,modal: true
- ,width: 400
- ,resizable: false
- ,draggable: false
- ,bodyPadding: 20
- ,icon: 'resources/icons/' + record.get('logo')
- ,items: [
- {
- xtype: 'form'
- ,items: [
- {
- xtype: 'textfield'
- ,fieldLabel: 'Name'
- ,value: record.get('name')
- ,name: 'serviceName'
- ,allowBlank: true
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- }
- ,{
- xtype: 'container'
- ,layout: 'column'
- ,items: [{
- xtype: 'textfield'
- ,fieldLabel: record.get('name') + ' team'
- ,name: 'url'
- ,allowBlank: false
- ,submitEmptyText: false
- ,emptyText: record.get('url') === '___' ? 'http://' : ''
- ,vtype: record.get('url') === '___' ? 'url' : ''
- ,width: 220
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- },{
- xtype: 'displayfield'
- ,value: record.get('url').split('___')[1].slice(0, -1) // Get the URL and remove the final slash (/)
- ,submitValue: false // Prevent being submitted
- }]
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Options'
- ,margin: '10 0 0 0'
- ,items: [
- {
- xtype: 'checkbox'
- ,boxLabel: 'Align to Right'
- ,checked: edit ? (record.get('align') === 'right' ? true : false) : false
- ,name: 'align'
- ,uncheckedValue: 'left'
- ,inputValue: 'right'
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Show notifications'
- ,name: 'notifications'
- ,checked: edit ? record.get('notifications') : true
- ,uncheckedValue: false
- ,inputValue: true
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Mute all sounds'
- ,name: 'muted'
- ,checked: edit ? record.get('muted') : false
- ,uncheckedValue: false
- ,inputValue: true
- }
- ]
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Advanced'
- ,margin: '10 0 0 0'
- ,collapsible: true
- ,collapsed: true
- ,items: [
- {
- xtype: 'textarea'
- ,fieldLabel: 'Custom Code (read more)'
- ,allowBlank: true
- ,name: 'js_unread'
- ,value: edit ? record.get('js_unread') : ''
- ,anchor: '100%'
- ,height: 120
- }
- ]
- }
- ,{
- xtype: 'container'
- ,hidden: (edit ? Ext.getStore('ServicesList').getById(record.get('type')).get('note') === '' : record.get('note') === '')
- ,data: { note: (edit ? Ext.getStore('ServicesList').getById(record.get('type')).get('note') : record.get('note')) }
- ,margin: '10 0 0 0'
- ,style: 'background-color:#93CFE0;color:#053767;border-radius:6px;'
- ,tpl: [
- ''
- ,'{note}'
- ]
- }
- ]
- }
- ]
- ,buttons: [
- {
- text: 'Cancel'
- ,ui: 'decline'
- ,handler: function() {
- win.close();
- }
- }
- ,'->'
- ,{
- text: edit ? 'Save' : 'Add service'
- ,itemId: 'submit'
- ,handler: function() {
- if ( !win.down('form').isValid() ) return false;
-
- var formValues = win.down('form').getValues();
-
- if ( edit ) {
- var oldData = record.getData();
- record.set({
- name: formValues.serviceName
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,js_unread: formValues.js_unread
- });
- // Change the title of the Tab
- Ext.getCmp('tab_'+record.get('id')).setTitle(formValues.serviceName);
- // Change sound of the Tab
- Ext.getCmp('tab_'+record.get('id')).setAudioMuted(formValues.muted);
- // Change notifications of the Tab
- Ext.getCmp('tab_'+record.get('id')).setNotifications(formValues.notifications);
- // Change the align of the Tab
- if ( oldData.align !== formValues.align ) {
- if ( formValues.align === 'left' ) {
- me.getView().moveBefore(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- } else {
- me.getView().moveAfter(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- }
- }
-
- Ext.getCmp('tab_'+record.get('id')).record = record;
- } else {
- var service = Ext.create('Rambox.model.Service', {
- type: record.get('id')
- ,logo: record.get('logo')
- ,name: formValues.serviceName
- ,url: record.get('url').replace('___', formValues.url)
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,js_unread: formValues.js_unread
- });
- service.save();
- Ext.getStore('Services').add(service);
-
- var tabData = {
- xtype: 'webview'
- ,id: 'tab_'+service.get('id')
- ,title: service.get('name')
- ,icon: 'resources/icons/'+service.get('logo')
- ,src: service.get('url')
- ,type: service.get('type')
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,record: service
- ,tabConfig: {
- service: service
- }
- };
-
- if ( formValues.align === 'left' ) {
- var tbfill = me.getView().getTabBar().down('tbfill');
- me.getView().insert(me.getView().getTabBar().items.indexOf(tbfill), tabData).show();
- } else {
- me.getView().add(tabData).show();
- }
- }
-
- win.close();
- }
- }
- ]
- }).show();
-
- // Make focus to the name field
- win.down('textfield[name="serviceName"]').focus(true, 100);
- }
-
,onEnableDisableService: function(cc, rowIndex, checked) {
var rec = Ext.getStore('Services').getAt(rowIndex);
@@ -441,13 +52,9 @@ Ext.define('Rambox.view.main.MainController', {
}
,onNewServiceSelect: function( view, record, item, index, e ) {
- if ( record.get('url').indexOf('___') >= 0 ) {
- this.showCustomModal(record);
- } else if ( record.get('type') === 'custom' ) {
- this.addCustomService(record, false);
- } else {
- this.showSimpleModal(record, false);
- }
+ Ext.create('Rambox.view.add.Add', {
+ record: record
+ });
}
,removeServiceFn: function(serviceId) {
@@ -459,7 +66,7 @@ Ext.define('Rambox.view.main.MainController', {
var rec = Ext.getStore('Services').getById(serviceId);
// Clear all trash data
- if ( rec.get('enabled') ) {
+ if ( rec.get('enabled') && tab.down('component').el ) {
tab.down('component').el.dom.getWebContents().session.clearCache(Ext.emptyFn);
tab.down('component').el.dom.getWebContents().session.clearStorageData({}, Ext.emptyFn);
}
@@ -495,6 +102,7 @@ Ext.define('Rambox.view.main.MainController', {
Ext.getStore('Services').load();
if ( Ext.isFunction(callback) ) callback();
Ext.cq1('app-main').resumeEvent('remove');
+ document.title = 'Rambox';
}
});
} else {
@@ -505,236 +113,16 @@ Ext.define('Rambox.view.main.MainController', {
Ext.getStore('Services').load();
if ( Ext.isFunction(callback) ) callback();
Ext.cq1('app-main').resumeEvent('remove');
+ document.title = 'Rambox';
}
}
,configureService: function( gridView, rowIndex, colIndex, col, e, rec, rowEl ) {
- if ( rec.get('type') === 'custom' ) {
- this.addCustomService(rec, true);
- } else {
- this.showSimpleModal(rec, true);
- }
- }
-
- ,addCustomService: function( record, edit ) {
- var me = this;
-
- var win = Ext.create('Ext.window.Window', {
- title: (edit ? 'Edit ' : 'Add ') + 'Custom Service'
- ,modal: true
- ,width: 400
- ,resizable: false
- ,draggable: false
- ,bodyPadding: 20
- ,items: [
- {
- xtype: 'form'
- ,items: [
- {
- xtype: 'textfield'
- ,fieldLabel: 'Name'
- ,name: 'serviceName'
- ,value: (edit ? record.get('name') : '')
- ,allowBlank: true
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- }
- ,{
- xtype: 'textfield'
- ,fieldLabel: 'URL'
- ,emptyText: 'http://service.url.com'
- ,name: 'url'
- ,vtype: 'url'
- ,value: (edit ? record.get('url') : '')
- ,allowBlank: false
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- }
- ,{
- xtype: 'textfield'
- ,fieldLabel: 'Logo'
- ,emptyText: 'http://image.url.com/image.png'
- ,name: 'logo'
- ,vtype: 'url'
- ,value: (edit ? record.get('logo') : '')
- ,allowBlank: true
- ,listeners: {
- specialkey: function(field, e) {
- if(e.getKey() == e.ENTER && field.up('form').isValid()) {
- field.up('window').down('#submit').handler();
- }
- }
- }
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Options'
- ,margin: '10 0 0 0'
- ,items: [
- {
- xtype: 'checkbox'
- ,boxLabel: 'Align to Right'
- ,checked: edit ? (record.get('align') === 'right' ? true : false) : false
- ,name: 'align'
- ,uncheckedValue: 'left'
- ,inputValue: 'right'
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Show notifications'
- ,name: 'notifications'
- ,checked: edit ? record.get('notifications') : true
- ,uncheckedValue: false
- ,inputValue: true
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Mute all sounds'
- ,name: 'muted'
- ,checked: edit ? record.get('muted') : false
- ,uncheckedValue: false
- ,inputValue: true
- }
- ,{
- xtype: 'checkbox'
- ,boxLabel: 'Trust invalid authority certificates'
- ,name: 'trust'
- ,checked: edit ? record.get('trust') : false
- ,uncheckedValue: false
- ,inputValue: true
- }
- ]
- }
- ,{
- xtype: 'fieldset'
- ,title: 'Advanced'
- ,margin: '10 0 0 0'
- ,collapsible: true
- ,collapsed: true
- ,items: [
- {
- xtype: 'textarea'
- ,fieldLabel: 'Custom Code (read more)'
- ,allowBlank: true
- ,name: 'js_unread'
- ,value: (edit ? record.get('js_unread') : '')
- ,anchor: '100%'
- ,height: 120
- }
- ]
- }
- ]
- }
- ]
- ,buttons: [
- {
- text: 'Cancel'
- ,ui: 'decline'
- ,handler: function() {
- win.close();
- }
- }
- ,'->'
- ,{
- text: (edit ? 'Edit ' : 'Add ') + ' Service'
- ,itemId: 'submit'
- ,handler: function() {
- if ( !win.down('form').isValid() ) return false;
-
- var formValues = win.down('form').getValues();
-
- if ( edit ) {
- var oldData = record.getData();
- // If users change the URL, we change the URL of the Webview
- if ( record.get('url') !== formValues.url ) Ext.getCmp('tab_'+record.get('id')).down('component').el.dom.loadURL(formValues.url);
-
- // Save the service
- record.set({
- name: formValues.serviceName
- ,url: formValues.url
- ,logo: formValues.logo
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,trust: formValues.trust
- ,js_unread: formValues.js_unread
- });
-
- // Change the title of the Tab
- Ext.getCmp('tab_'+record.get('id')).setTitle(formValues.serviceName);
- // Change sound of the Tab
- Ext.getCmp('tab_'+record.get('id')).setAudioMuted(formValues.muted);
- // Change notifications of the Tab
- Ext.getCmp('tab_'+record.get('id')).setNotifications(formValues.notifications);
- // Change the icon of the Tab
- Ext.getCmp('tab_'+record.get('id')).setIcon(record.get('logo') === '' ? 'resources/icons/custom.png' : record.get('logo'));
- // Change the align of the Tab
- if ( oldData.align !== formValues.align ) {
- if ( formValues.align === 'left' ) {
- me.getView().moveBefore(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- } else {
- me.getView().moveAfter(Ext.getCmp('tab_'+record.get('id')), Ext.getCmp('tbfill'));
- }
- }
-
- Ext.getCmp('tab_'+record.get('id')).record = record;
- } else {
- var service = Ext.create('Rambox.model.Service', {
- type: 'custom'
- ,logo: formValues.logo
- ,name: formValues.serviceName
- ,url: formValues.url
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,trust: formValues.trust
- ,js_unread: formValues.js_unread
- });
- service.save();
- Ext.getStore('Services').add(service);
-
- var tabData = {
- xtype: 'webview'
- ,id: 'tab_'+service.get('id')
- ,title: service.get('name')
- ,icon: service.get('logo') === '' ? 'resources/icons/custom.png' : service.get('logo')
- ,src: service.get('url')
- ,type: service.get('type')
- ,align: formValues.align
- ,notifications: formValues.notifications
- ,muted: formValues.muted
- ,record: service
- ,tabConfig: {
- service: service
- }
- };
-
- if ( formValues.align === 'left' ) {
- var tbfill = me.getView().getTabBar().down('tbfill');
- me.getView().insert(me.getView().getTabBar().items.indexOf(tbfill), tabData).show();
- } else {
- me.getView().add(tabData).show();
- }
- }
-
- win.close();
- }
- }
- ]
- }).show();
-
- // Make focus to the name field
- win.down('textfield[name="serviceName"]').focus(true, 100);
+ Ext.create('Rambox.view.add.Add', {
+ record: rec
+ ,service: Ext.getStore('ServicesList').getById(rec.get('type'))
+ ,edit: true
+ });
}
,onSearchRender: function( field ) {
@@ -988,4 +376,8 @@ Ext.define('Rambox.view.main.MainController', {
logoutFn();
}
}
+
+ ,showDonate: function( btn ) {
+ Tooltip.API.show('zxzKWZfcmgRtHXgth');
+ }
});
diff --git a/app/view/preferences/Preferences.js b/app/view/preferences/Preferences.js
index bdb63b95..749340a1 100644
--- a/app/view/preferences/Preferences.js
+++ b/app/view/preferences/Preferences.js
@@ -59,7 +59,7 @@ Ext.define('Rambox.view.preferences.Preferences',{
,name: 'hide_menu_bar'
,boxLabel: 'Auto-hide Menu bar (Alt
key to display)'
,value: config.hide_menu_bar
- ,hidden: Ext.os.is.MacOS
+ ,hidden: process.platform !== 'win32'
}
,{
xtype: 'checkbox'
@@ -67,7 +67,7 @@ Ext.define('Rambox.view.preferences.Preferences',{
,boxLabel: 'Show in Taskbar'
,value: config.skip_taskbar
,reference: 'skipTaskbar'
- ,hidden: Ext.os.is.MacOS
+ ,hidden: process.platform !== 'win32'
}
,{
xtype: 'checkbox'
@@ -75,7 +75,7 @@ Ext.define('Rambox.view.preferences.Preferences',{
,boxLabel: 'Keep Rambox in the Taskbar when close it'
,value: config.keep_in_taskbar_on_close
,bind: { disabled: '{!skipTaskbar.checked}' }
- ,hidden: Ext.os.is.MacOS
+ ,hidden: process.platform !== 'win32'
}
,{
xtype: 'checkbox'
@@ -88,7 +88,13 @@ Ext.define('Rambox.view.preferences.Preferences',{
,name: 'systemtray_indicator'
,boxLabel: 'Show System Tray indicator on unread messages'
,value: config.systemtray_indicator
- ,hidden: Ext.os.is.MacOS
+ ,hidden: process.platform === 'darwin'
+ }
+ ,{
+ xtype: 'checkbox'
+ ,name: 'disable_gpu'
+ ,boxLabel: 'Disable Hardware Acceleration (needs to relaunch)'
+ ,value: config.disable_gpu
}
,{
xtype: 'fieldset'
diff --git a/appveyor.yml b/appveyor.yml
index 71d23b32..d30d971d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: 0.4.2
+version: 0.4.4
pull_requests:
do_not_increment_build_number: true
branches:
@@ -33,12 +33,13 @@ build_script:
npm --version
- node_modules/.bin/build --win --x64
+ node_modules/.bin/build --win --ia32 --x64
test: off
artifacts:
- path: dist\win\*.exe
- path: dist\win\*.nupkg
- path: dist\win\RELEASES
+- path: dist\win-ia32\*.exe
- path: dist\*.zip
deploy:
- provider: GitHub
diff --git a/electron/main.js b/electron/main.js
index 0a97b502..b066129a 100644
--- a/electron/main.js
+++ b/electron/main.js
@@ -24,10 +24,12 @@ const config = new Config({
,hide_menu_bar: false
,skip_taskbar: true
,auto_launch: !isDev
- ,keep_in_taskbar_on_close: getDefaultValueForkeep_in_taskbar_on_close()
+ // On Linux false because it's uncommon for apps on linux to stay in the taskbar on close
+ ,keep_in_taskbar_on_close: process.platform !== 'linux'
,start_minimized: false
,systemtray_indicator: true
,master_password: false
+ ,disable_gpu: process.platform === 'linux'
,proxy: false
,proxyHost: ''
,proxyPort: ''
@@ -40,15 +42,6 @@ const config = new Config({
}
});
-/**
- * Returns the default value for "keep_in_taskbar_on_close".
- * On all platforms except linux: true
- * On linux: false (because it's uncommon for apps on linux to stay in the taskbar on close)
- */
-function getDefaultValueForkeep_in_taskbar_on_close() {
- return process.platform !== 'linux';
-}
-
// Configure AutoLaunch
const appLauncher = new AutoLaunch({
name: 'Rambox'
@@ -232,6 +225,9 @@ function createMasterPasswordWindow() {
backgroundColor: '#0675A0'
,frame: false
});
+ // Open the DevTools.
+ if ( isDev ) mainMasterPasswordWindow.webContents.openDevTools();
+
mainMasterPasswordWindow.loadURL('file://' + __dirname + '/../masterpassword.html');
mainMasterPasswordWindow.on('close', function() { mainMasterPasswordWindow = null });
}
@@ -319,10 +315,10 @@ app.on('certificate-error', function(event, webContents, url, error, certificate
} else {
callback(false);
dialog.showMessageBox(mainWindow, {
- title: 'Certification Error'
+ title: 'Certification Warning'
,message: 'The service with the following URL has an invalid authority certification.\n\n'+url+'\n\nIf is a Custom Service, you have to remove it and add it again, enabling the "Trust invalid authority certificates" in the Options.'
,buttons: ['OK']
- ,type: 'error'
+ ,type: 'warning'
}, function() {
});
@@ -394,6 +390,12 @@ ipcMain.on('image:popup', function(event, url, partition) {
// Proxy
if ( config.get('proxy') ) app.commandLine.appendSwitch('proxy-server', config.get('proxyHost')+':'+config.get('proxyPort'));
+// Disable GPU Acceleration for Linux
+// to prevent White Page bug
+// https://github.com/electron/electron/issues/6139
+// https://github.com/saenzramiro/rambox/issues/181
+if ( config.get('disable_gpu') ) app.disableHardwareAcceleration();
+
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
app.on('ready', function() {
@@ -409,12 +411,14 @@ app.on('window-all-closed', function () {
}
});
+// Only macOS: On OS X it's common to re-create a window in the app when the
+// dock icon is clicked and there are no other windows open.
app.on('activate', function () {
- // On OS X it's common to re-create a window in the app when the
- // dock icon is clicked and there are no other windows open.
if (mainWindow === null && mainMasterPasswordWindow === null ) {
config.get('master_password') ? createMasterPasswordWindow() : createWindow();
}
+
+ if ( mainWindow !== null ) mainWindow.show();
});
app.on('before-quit', function () {
diff --git a/electron/menu.js b/electron/menu.js
index 8d6847b3..06f693b7 100644
--- a/electron/menu.js
+++ b/electron/menu.js
@@ -67,6 +67,29 @@ const helpSubmenu = [
shell.openExternal('https://gitter.im/saenzramiro/rambox');
}
},
+ {
+ label: `Tools`,
+ submenu: [
+ {
+ label: `Clear Cache`,
+ click(item, win) {
+ win.webContents.session.clearCache(function() {
+ win.reload();
+ });
+ }
+ },
+ {
+ label: `Clear Local Storage`,
+ click(item, win) {
+ win.webContents.session.clearStorageData({
+ storages: ['localstorage']
+ }, function() {
+ win.reload();
+ });
+ }
+ }
+ ]
+ },
{
type: 'separator'
},
@@ -121,6 +144,13 @@ let tpl = [
if (focusedWindow) focusedWindow.reload();
}
},
+ {
+ label: 'Reload current Service',
+ accelerator: 'CmdOrCtrl+Shift+R',
+ click() {
+ sendAction('reloadCurrentService');
+ }
+ },
{
type: 'separator'
},
diff --git a/electron/tray.js b/electron/tray.js
index 78547dc7..dbe0c69e 100644
--- a/electron/tray.js
+++ b/electron/tray.js
@@ -51,7 +51,7 @@ exports.create = function(win, config) {
appIcon.setToolTip('Rambox');
appIcon.setContextMenu(contextMenu);
appIcon.on('double-click', () => {
- win.isVisible() && config.get('maximized') ? win.maximize() : win.show();
+ if ( !win.isVisible() || win.isMinimized() ) config.get('maximized') ? win.maximize() : win.show();
});
};
diff --git a/index.html b/index.html
index 22c60550..f315b2d1 100644
--- a/index.html
+++ b/index.html
@@ -21,6 +21,14 @@
-
+