Browse Source

Improved UI and fixed some bugs

- Autofocus on tab change.
- Injected JS in model.
- Added search field in available services.
pull/3/head
Ramiro Saenz 9 years ago
parent
commit
4e4ab0aeed
  1. 4
      app/model/Service.js
  2. 4
      app/model/ServiceList.js
  3. 1
      app/store/Services.js
  4. 3
      app/store/ServicesList.js
  5. 28
      app/ux/WebView.js
  6. 155
      app/view/main/Main.js
  7. 117
      app/view/main/MainController.js
  8. 19
      packages/local/rambox-default-theme/sass/etc/all.scss

4
app/model/Service.js

@ -43,5 +43,9 @@ Ext.define('Rambox.model.Service', {
name: 'muted'
,type: 'boolean'
,defaultValue: false
},{
name: 'js_unread'
,type: 'string'
,defaultValue: ''
}]
});

4
app/model/ServiceList.js

@ -16,5 +16,9 @@ Ext.define('Rambox.model.ServiceList', {
},{
name: 'type'
,type: 'string'
},{
name: 'js_unread'
,type: 'string'
,defaultValue: ''
}]
});

1
app/store/Services.js

@ -37,6 +37,7 @@ Ext.define('Rambox.store.Services', {
,src: service.get('url')
,type: service.get('type')
,muted: service.get('muted')
,record: service
,tabConfig: {
service: service
}

3
app/store/ServicesList.js

@ -29,6 +29,7 @@ Ext.define('Rambox.store.ServicesList', {
,name: 'Slack'
,url: 'https://___.slack.com/'
,type: 'messaging'
,js_unread: 'function checkUnread(){var e=document.getElementsByClassName("unread_highlight"),t=0;for(i=0;i<e.length;i++)t+=parseInt(e[i].innerHTML.trim());updateBadge(t)}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
},
{
id: 'noysi'
@ -57,6 +58,7 @@ Ext.define('Rambox.store.ServicesList', {
,name: 'Hangouts'
,url: 'https://hangouts.google.com/'
,type: 'messaging'
,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);'
},
{
id: 'hipchat'
@ -92,6 +94,7 @@ Ext.define('Rambox.store.ServicesList', {
,name: 'Inbox'
,url: 'http://inbox.google.com/?cid=imp'
,type: 'email'
,js_unread: 'function checkUnread(){updateBadge(document.getElementsByClassName("qG").length)}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
},
{
id: 'chatwork'

28
app/ux/WebView.js

@ -74,7 +74,7 @@ Ext.define('Rambox.ux.WebView',{
webview.addEventListener("did-finish-load", function(e) {
Rambox.app.setTotalServicesLoaded( Rambox.app.getTotalServicesLoaded() + 1 );
if ( Rambox.app.getTotalServicesLoaded() === Ext.getStore('Services').getCount() ) {
if ( Rambox.app.getTotalServicesLoaded() === Ext.getStore('Services').getCount() && Ext.get('spinner') !== null ) {
Ext.get('spinner').destroy();
}
});
@ -89,20 +89,17 @@ Ext.define('Rambox.ux.WebView',{
});
// Injected code to detect new messages
switch ( me.type ) {
case 'inbox':
webview.executeJavaScript('function checkUnread(){updateBadge(document.getElementsByClassName("qG").length)}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);');
break;
case 'hangouts':
webview.executeJavaScript('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);');
break;
default:
break;
if ( me.record && me.record.get('js_unread') !== '' ) {
console.info('JS Injected', me.src);
console.log(me.record.get('js_unread'));
webview.executeJavaScript(me.record.get('js_unread'));
}
// Scroll always to top (bug)
webview.executeJavaScript('document.body.scrollTop=0;');
});
webview.addEventListener("page-title-updated", function(e) {
var ipc = require('electron').ipcRenderer;
var count = e.title.match(/\((\d+)\)/);
count = count ? parseInt(count[1]) : 0;
@ -125,15 +122,6 @@ Ext.define('Rambox.ux.WebView',{
}
if ( e.title === 'Google Hangouts' ) me.notifications = 0;
break;
case 'slack':
if ( e.title.indexOf('! ') >= 0 ) {
me.tab.setBadgeText(1);
me.notifications = 1;
} else {
me.tab.setBadgeText(0);
me.notifications = 0;
}
break;
default:
me.tab.setBadgeText(count);
me.notifications = count;

155
app/view/main/Main.js

@ -45,18 +45,97 @@ Ext.define('Rambox.view.main.Main', {
,closable: false
,reorderable: false
,autoScroll: true
,layout: 'center'
,layout: 'hbox'
,items: [
{
xtype: 'container'
xtype: 'panel'
,title: 'Add a new Service'
,margin: '0 5 0 0'
,flex: 1
,header: { height: 50 }
,tools: [
{
xtype: 'checkboxgroup'
,items: [
{
xtype: 'checkbox'
,boxLabel: 'Messaging'
,name: 'messaging'
,checked: true
,uncheckedValue: false
,inputValue: true
}
,{
xtype: 'checkbox'
,boxLabel: 'Email'
,margin: '0 10 0 10'
,name: 'email'
,checked: true
,uncheckedValue: false
,inputValue: true
}
]
,listeners: {
change: 'doTypeFilter'
}
}
,{
xtype: 'textfield'
,grow: true
,growMin: 120
,growMax: 170
,triggers: {
clear: {
weight: 0
,cls: Ext.baseCSSPrefix + 'form-clear-trigger'
,hidden: true
,handler: 'onClearClick'
}
,search: {
weight: 1
,cls: Ext.baseCSSPrefix + 'form-search-trigger search-trigger'
}
}
,listeners: {
change: 'onSearchServiceChange'
,afterrender: 'onSearchRender'
,specialkey: 'onSearchEnter'
}
}
,{
type: 'plus'
,tooltip: 'Add a custom service'
,handler: 'addCustomService'
}
]
,items: [
{
xtype: 'dataview'
,store: 'ServicesList'
,itemSelector: 'div.service'
,tpl: [
'<tpl for=".">'
,'<div class="service">'
,'<img src="resources/icons/{logo}" width="48" />'
,'<span>{name}</span>'
,'</div>'
,'</tpl>'
]
,emptyText: '<div style="padding: 20px;">No services found... Try another search.</div>'
,listeners: {
itemclick: 'onNewServiceSelect'
}
}
]
}
,{
xtype: 'grid'
,title: 'Enabled Services'
,store: 'Services'
,margin: '50 0 0 0'
,hideHeaders: true
,width: 500
,margin: '0 0 0 5'
,flex: 1
,header: { height: 50 }
,columns: [
{
xtype: 'templatecolumn'
@ -111,67 +190,10 @@ Ext.define('Rambox.view.main.Main', {
,forceFit: true
}
}
,{
xtype: 'panel'
,title: 'Add a new Service'
,width: 500
,margin: '50 0 0 0'
,tools: [
{
xtype: 'checkboxgroup'
,items: [
{
xtype: 'checkbox'
,boxLabel: 'Messaging'
,name: 'messaging'
,checked: true
,uncheckedValue: false
,inputValue: true
}
,{
xtype: 'checkbox'
,boxLabel: 'Email'
,margin: '0 10 0 10'
,name: 'email'
,checked: true
,uncheckedValue: false
,inputValue: true
}
]
,listeners: {
change: 'doFilter'
}
}
,{
type: 'plus'
,tooltip: 'Add a custom service'
,handler: 'addCustomService'
}
]
,items: [
{
xtype: 'dataview'
,store: 'ServicesList'
,itemSelector: 'div.service'
,tpl: [
'<tpl for=".">'
,'<div class="service">'
,'<img src="resources/icons/{logo}" width="48" />'
,'<span>{name}</span>'
,'</div>'
,'</tpl>'
]
,listeners: {
itemclick: 'onNewServiceSelect'
}
}
]
}
,bbar: [
'->'
,{
xtype: 'toolbar'
,margin: '50 0 0 0'
,items: [
{
xtype: 'label'
,html: '<span class="fa fa-code" style="color:black;"></span> with <span class="fa fa-heart" style="color:red;"></span> from Argentina as an Open Source project.'
}
@ -179,11 +201,12 @@ Ext.define('Rambox.view.main.Main', {
text: 'www.rambox.io'
,href: 'http://www.rambox.io'
}
,'->'
]
}
]
,listeners: {
tabchange: 'onTabChange'
}
]
}
]
});

117
app/view/main/MainController.js

@ -6,6 +6,14 @@ Ext.define('Rambox.view.main.MainController', {
,alias: 'controller.main'
// Make focus on webview every time the user change tabs, to enable the autofocus in websites
,onTabChange: function( tabPanel, newTab, oldTab ) {
var me = this;
var webview = newTab.down('component').el.dom;
if ( webview ) webview.focus();
}
,showSimpleModal: function(record, edit) {
var me = this;
@ -100,8 +108,10 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,js_unread: record.get('js_unread')
});
service.save();
Ext.getStore('Services').add(service);
var tabData = {
xtype: 'webview'
@ -113,6 +123,7 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,record: service
,tabConfig: {
service: service
}
@ -242,8 +253,10 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,js_unread: record.get('js_unread')
});
service.save();
Ext.getStore('Services').add(service);
var tabData = {
xtype: 'webview'
@ -255,6 +268,7 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,record: service
,tabConfig: {
service: service
}
@ -286,11 +300,19 @@ Ext.define('Rambox.view.main.MainController', {
}
,removeService: function( gridView, rowIndex, colIndex, col, e, rec, rowEl ) {
Ext.Msg.confirm('Please confirm...', 'Are you sure you want to remove '+rec.get('name')+'?', function(btnId) {
Ext.Msg.confirm('Please confirm...', 'Are you sure you want to remove <b>'+rec.get('name')+'</b>?', function(btnId) {
if ( btnId === 'yes' ) {
var tab = Ext.getCmp('tab_'+rec.get('id'));
// Remove record from localStorage
gridView.getStore().remove(rec);
//webview.webContents.session.clearCache();
Ext.getCmp('tab_'+rec.get('id')).close();
// Clear all trash data
tab.down('component').el.dom.getWebContents().session.clearCache(Ext.emptyFn);
tab.down('component').el.dom.getWebContents().session.clearStorageData({}, Ext.emptyFn);
// Close tab
tab.close();
}
});
}
@ -299,15 +321,6 @@ Ext.define('Rambox.view.main.MainController', {
this.showSimpleModal(rec, true);
}
,doFilter: function( cg, newValue, oldValue ) {
var values = Ext.cq1('checkboxgroup').getValue();
Ext.getStore('ServicesList').getFilters().replaceAll({
fn: function(record) {
return Ext.Array.contains(Ext.Object.getKeys(values), record.get('type'));
}
});
}
,addCustomService: function( event, toolEl, owner, tool ) {
var me = this;
@ -341,6 +354,7 @@ Ext.define('Rambox.view.main.MainController', {
,emptyText: 'http://service.url.com'
,name: 'url'
,vtype: 'url'
,allowBlank: false
,listeners: {
specialkey: function(field, e) {
if(e.getKey() == e.ENTER && field.up('form').isValid()) {
@ -355,6 +369,7 @@ Ext.define('Rambox.view.main.MainController', {
,emptyText: 'http://image.url.com/image.png'
,name: 'logo'
,vtype: 'url'
,allowBlank: true
,listeners: {
specialkey: function(field, e) {
if(e.getKey() == e.ENTER && field.up('form').isValid()) {
@ -394,6 +409,24 @@ Ext.define('Rambox.view.main.MainController', {
}
]
}
,{
xtype: 'fieldset'
,title: 'Advanced'
,margin: '10 0 0 0'
,collapsible: true
,collapsed: true
,items: [
{
xtype: 'textarea'
,fieldLabel: 'Unread Code'
,allowBlank: true
,name: 'js_unread'
,anchor: '100%'
,emptyText: 'Write code here if the service don\'t update the page title when have new activity. The code needs to return an integer, for example: document.body.getElementsByClassName("ee").length;'
,height: 120
}
]
}
]
}
]
@ -420,8 +453,10 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,js_unread: 'function checkUnread(){updateBadge(' + formValues.js_unread + ')}function updateBadge(e){e>=1?document.title="("+e+") "+originalTitle:document.title=originalTitle}var originalTitle=document.title;setInterval(checkUnread,3000);'
});
service.save();
Ext.getStore('Services').add(service);
var tabData = {
xtype: 'webview'
@ -433,6 +468,7 @@ Ext.define('Rambox.view.main.MainController', {
,align: formValues.align
,notifications: formValues.notifications
,muted: formValues.muted
,record: service
,tabConfig: {
service: service
}
@ -454,4 +490,61 @@ Ext.define('Rambox.view.main.MainController', {
// Make focus to the name field
win.down('textfield[name="serviceName"]').focus(true, 100);
}
,onSearchRender: function( field ) {
field.focus(false, 1000);
}
,onSearchEnter: function( field, e ) {
var me = this;
if ( e.getKey() == e.ENTER && Ext.getStore('ServicesList').getCount() === 1 ) {
me.onNewServiceSelect(field.up().down('dataview'), Ext.getStore('ServicesList').getAt(0));
me.onClearClick(field);
}
}
,doTypeFilter: function( cg, newValue, oldValue ) {
var me = this;
Ext.getStore('ServicesList').getFilters().replaceAll({
fn: function(record) {
return Ext.Array.contains(Ext.Object.getKeys(cg.getValue()), record.get('type'));
}
});
}
,onSearchServiceChange: function(field, newValue, oldValue) {
var me = this;
var cg = field.up().down('checkboxgroup');
if ( !Ext.isEmpty(newValue) && newValue.length > 0 ) {
field.getTrigger('clear').show();
Ext.getStore('ServicesList').getFilters().replaceAll({
fn: function(record) {
if ( !Ext.Array.contains(Ext.Object.getKeys(cg.getValue()), record.get('type')) ) return false;
return record.get('name').toLowerCase().indexOf(newValue.toLowerCase()) > -1 ? true : false;
}
});
} else {
field.getTrigger('clear').hide();
Ext.getStore('ServicesList').getFilters().removeAll();
me.doTypeFilter(cg);
}
field.updateLayout();
}
,onClearClick: function(field, trigger, e) {
var me = this;
var cg = field.up().down('checkboxgroup');
field.reset();
field.getTrigger('clear').hide();
field.updateLayout();
Ext.getStore('ServicesList').getFilters().removeAll();
me.doTypeFilter(cg);
}
});

19
packages/local/rambox-default-theme/sass/etc/all.scss

@ -184,19 +184,22 @@ body {
.x-title-icon { background-size: 16px; }
// Fix for scroller tab bar
.x-box-scroller-body-horizontal { width: auto !important; margin-right: 18px;}
.x-box-scroller-tab-bar { z-index: 9999; }
//.x-box-scroller-body-horizontal { width: auto !important; margin-right: 18px; padding-right: 18px; }
//.x-box-scroller-tab-bar { z-index: 9999; }
.service {
width:250px;
display:inline-block;
padding:10px;
cursor:pointer;
width: 230px;
display: inline-block;
padding: 10px;
cursor: pointer;
img {
float: left;
}
span {
margin-left:10px;
line-height:48px;
margin-left: 10px;
line-height: 48px;
}
&:hover {
background-color: lighten($base-color, 55%);
}
}

Loading…
Cancel
Save