Addon support

Addons are simple Angular modules with views, controllers, services etc. Addons can register
themselves in Copay using pluginManagerProvider. It allows them to add extra items to the bottom
menu and as well as extra tab-views:

````
  addonManagerProvider.registerAddon({
    menuItem: {
      'title': 'Assets',
      'icon': 'icon-pricetag',
      'link': 'assets'
    },
    view: {
      id: 'assets',
      'class': 'assets',
      template: 'colored-coins/views/assets.html'
    }
  });
````

Addons can consume core Copay services and listen for events to react on changes. For this very
first addon system inplementation Copay emits additional BalanceUpdated event so that interested
addons can react on new transactions (see plugin reference implementation below).

As bottom menu can accomodate only 6 items without sacrificing usability, so it was reworked to
have second layer of items. Now If menu has more than 6 items, toggle button will be added to
the menu allowing to reveal extra items in a sliding panel. Bottom menu in this case will show
only 5 items, the rest will be rendered on sliding panel.

This changes addresses issue #2949 and reference implementation of addon could be found here:
https://github.com/troggy/copay-colored-coins-plugin
This commit is contained in:
Kosta Korenkov 2015-07-04 13:02:46 +03:00
commit e6785335a9
9 changed files with 92 additions and 15 deletions

View file

@ -0,0 +1,5 @@
<div class="medium-2 small-2 columns text-center bottombar-item">
<a ng-click="showPlugins ? showPlugins = false : showPlugins = true" class="menu-toggle">
<i class="size-24 db" ng-class="{ 'icon-arrow-left': showPlugins, 'icon-arrow-right' : !showPlugins }"> </i>
</a>
</div>

View file

@ -1,5 +1,21 @@
<div class="bottom-bar row collapse">
<div class="medium-3 small-3 columns text-center bottombar-item" ng-repeat="item in index.menu">
<div class="bottom-bar second-bottom-bar row collapse animated slideInRight" ng-class="{ 'slideOutRight': !showPlugins }" ng-show="index.menu.length > 6">
<div class="medium-{{index.menuItemSize}} small-{{index.menuItemSize}} columns text-center bottombar-item" ng-repeat="item in index.menu | limitTo: 5 - index.menu.length">
<a ng-click="index.setTab(item.link)" ng-class="{'active': index.tab == item.link}" id="menu-{{item.link}}">
<i class="size-24 {{item.icon}} db"></i>
<div class="size-10 tu">
{{item.title|translate}}
</div>
</a>
</div>
<div class="medium-{{index.menuItemSize}} small-{{index.menuItemSize}} columns text-center bottombar-item" ng-repeat="n in index.menu | limitTo: 4 - index.menu.length % 6">
<a></a>
</div>
<menu-toggle ng-show="index.menu.length > 6"/>
</div>
<div class="bottom-bar row collapse">
<div class="medium-{{index.menuItemSize}} small-{{index.menuItemSize}} columns text-center bottombar-item" ng-repeat="item in index.menu | limitTo: (index.menu.length > 6 ? 5 : 6)">
<a ng-click="index.setTab(item.link)" ng-class="{'active': index.tab == item.link}" id="menu-{{item.link}}">
<i class="size-24 {{item.icon}} db"></i>
<div class="size-10 tu">
@ -10,4 +26,12 @@
</div>
</a>
</div>
<div class="medium-2 small-2 columns text-center bottombar-item" ng-show="index.menu.length == 5">
<a></a>
</div>
<menu-toggle ng-show="index.menu.length > 6"/>
</div>

View file

@ -505,6 +505,9 @@
<div class="extra-margin-bottom"></div>
</div> <!-- END History -->
<div id="{{view.id}}" class="{{view.class}} tab-view" ng-repeat="view in index.addonViews" ng-include="view.template">
</div>
</div>
</div>
<div class="extra-margin-bottom"></div>

View file

@ -151,6 +151,20 @@ _:-ms-fullscreen, :root .main {
background: #2C3E50;
}
.second-bottom-bar {
z-index: 6;
}
.second-bottom-bar.animated.slideInRight,
.second-bottom-bar.animated.slideInLeft {
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
}
.menu-toggle {
padding-top: 1rem !important;
}
.amount {
width: 100%;
text-align: center;

View file

@ -12,7 +12,8 @@ var modules = [
'copayApp.filters',
'copayApp.services',
'copayApp.controllers',
'copayApp.directives'
'copayApp.directives',
'copayApp.plugins'
];
var copayApp = window.copayApp = angular.module('copayApp', modules);
@ -21,3 +22,5 @@ angular.module('copayApp.filters', []);
angular.module('copayApp.services', []);
angular.module('copayApp.controllers', []);
angular.module('copayApp.directives', []);
angular.module('copayApp.plugins', []);

View file

@ -1,6 +1,6 @@
'use strict';
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettextCatalog, gettext, amMoment, nodeWebkit) {
angular.module('copayApp.controllers').controller('indexController', function($rootScope, $scope, $log, $filter, $timeout, lodash, go, profileService, configService, isCordova, rateService, storageService, addressService, gettextCatalog, gettext, amMoment, nodeWebkit, addonManager) {
var self = this;
self.isCordova = isCordova;
self.onGoingProcess = {};
@ -34,6 +34,10 @@ angular.module('copayApp.controllers').controller('indexController', function($r
'link': 'history'
}];
self.addonViews = addonManager.addonViews();
self.menu = self.menu.concat(addonManager.addonMenuItems());
self.menuItemSize = self.menu.length > 4 ? 2 : 3;
self.tab = 'walletHome';
self.availableLanguages = [{
@ -274,6 +278,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
self.walletScanStatus = walletStatus.wallet.scanStatus;
self.copayers = walletStatus.wallet.copayers;
self.preferences = walletStatus.preferences;
$rootScope.$emit('Local/BalanceUpdated', walletStatus.balance);
self.setBalance(walletStatus.balance);
self.otherWallets = lodash.filter(profileService.getWallets(self.network), function(w) {
return w.id != self.walletId;
@ -548,7 +553,7 @@ angular.module('copayApp.controllers').controller('indexController', function($r
}
});
}, false);
chooser.click();
chooser.click();
}
function formatDate(date) {

View file

@ -296,4 +296,11 @@ angular.module('copayApp.directives')
});
}
};
})
.directive('menuToggle', function() {
return {
restrict: 'E',
replace: true,
templateUrl: 'views/includes/menu-toggle.html'
}
});

View file

@ -0,0 +1,26 @@
'use strict';
angular.module('copayApp.services').provider('addonManager', function () {
var addonMenuItems = [];
var addonViews = [];
this.registerAddon = function(addonSpec) {
addonMenuItems.push(addonSpec.menuItem);
addonViews.push(addonSpec.view);
};
this.$get = function() {
var manager = {};
manager.addonMenuItems = function() {
return addonMenuItems;
};
manager.addonViews = function() {
return addonViews;
};
return manager;
}
});

View file

@ -1,10 +0,0 @@
'use strict';
angular.module('copayApp.services').factory('pluginManager', function() {
var root = {};
root.getInstance = function(config){
return new copay.PluginManager(config);
};
return root;
});