feat(invitation): show invitations count badge in header menu

This commit is contained in:
OldHawk
2017-06-16 10:04:52 +08:00
parent 26fab54bac
commit 2cbc9f6c9c
10 changed files with 112 additions and 17 deletions

View File

@@ -19,7 +19,7 @@ module.exports = {
allow_social_sign: false
},
invite: {
open_invite: false,
open_invite: true,
score_exchange: 10000,
expires: 60 * 60 * 1000 * 24
},

View File

@@ -6,9 +6,10 @@
.controller('HeaderController', HeaderController);
HeaderController.$inject = ['$scope', '$state', '$stateParams', '$translate', 'Authentication', 'menuService', 'MeanTorrentConfig', 'localStorageService',
'ScoreLevelService'];
'ScoreLevelService', 'InvitationsService'];
function HeaderController($scope, $state, $stateParams, $translate, Authentication, menuService, MeanTorrentConfig, localStorageService, ScoreLevelService) {
function HeaderController($scope, $state, $stateParams, $translate, Authentication, menuService, MeanTorrentConfig, localStorageService, ScoreLevelService,
InvitationsService) {
var vm = this;
vm.user = Authentication.user;
vm.language = MeanTorrentConfig.meanTorrentConfig.language;
@@ -26,11 +27,34 @@
$scope.$on('$stateChangeSuccess', stateChangeSuccess);
$scope.$on('auth-user-changed', function(event, args) {
/**
* auth-user-changed
*/
$scope.$on('auth-user-changed', function (event, args) {
vm.user = Authentication.user;
vm.scoreLevelData = vm.user ? ScoreLevelService.getScoreLevelJson(vm.user.score) : undefined;
});
/**
* user-invitations-changed
*/
$scope.$on('user-invitations-changed', function (event, args) {
vm.getInvitationsCount();
});
/**
* getInvitationsCount
*/
vm.getInvitationsCount = function () {
InvitationsService.countInvitations({}, function (res) {
if (res.countMyInvitations > 0) {
vm.countMyInvitations = res.countMyInvitations;
} else {
vm.countMyInvitations = undefined;
}
});
};
function stateChangeSuccess() {
// Collapsing the menu after navigation
vm.isCollapsed = false;

View File

@@ -183,10 +183,20 @@ body {
top: 3px;
}
.menu-badge {
position: absolute;
right: 10px;
top: 3px;
}
.menu-score-parent {
position: relative;
}
.menu-invitation-parent {
position: relative;
}
.vip-flag {
color: #FF6600;
> kbd {

View File

@@ -1,4 +1,4 @@
<div class="container" ng-controller="HeaderController as vm">
<div class="container" ng-controller="HeaderController as vm" ng-init="vm.getInvitationsCount()">
<div class="navbar-header">
<button class="navbar-toggle" type="button" ng-click="vm.isCollapsed = !vm.isCollapsed">
<span class="sr-only">Toggle navigation</span>
@@ -51,8 +51,8 @@
<li ui-sref-active="active" ng-repeat="item in vm.scoreMenu.items" class="menu-score-parent">
<a ui-sref="{{item.state}}" ng-bind="item.title" menu-title="{{item.title}}"></a><span class="menu-score" score-level="vm.scoreLevelData.currLevel"></span>
</li>
<li ui-sref-active="active" ng-repeat="item in vm.inviteMenu.items">
<a ui-sref="{{item.state}}" ng-bind="item.title" menu-title="{{item.title}}"></a>
<li ui-sref-active="active" ng-repeat="item in vm.inviteMenu.items" class="menu-invitation-parent">
<a ui-sref="{{item.state}}" ng-bind="item.title" menu-title="{{item.title}}"></a><span class="badge menu-badge badge_danger">{{vm.countMyInvitations}}</span>
</li>
<li class="divider"></li>
<li ui-sref-active="active" ng-repeat="item in vm.accountMenu.items">

View File

@@ -6,10 +6,10 @@
.controller('InviteController', InviteController);
InviteController.$inject = ['$scope', '$state', '$translate', '$timeout', 'Authentication', '$window', 'MeanTorrentConfig', 'NotifycationService',
'InvitationsService'];
'InvitationsService', '$rootScope'];
function InviteController($scope, $state, $translate, $timeout, Authentication, $window, MeanTorrentConfig, NotifycationService,
InvitationsService) {
InvitationsService, $rootScope) {
var vm = this;
vm.inviteConfig = MeanTorrentConfig.meanTorrentConfig.invite;
vm.user = Authentication.user;
@@ -32,6 +32,13 @@
$state.go('authentication.signin');
}
/**
* user-invitations-changed
*/
$scope.$on('user-invitations-changed', function (event, args) {
vm.getMyInvitations();
});
/**
* getMyInvitations
*/
@@ -69,7 +76,7 @@
NotifycationService.showSuccessNotify('SEND_INVITE_SUCCESSFULLY');
vm.invitePopover.items[idx].isOpen = false;
vm.invitePopover.sending = false;
vm.getMyInvitations();
$rootScope.$broadcast('user-invitations-changed');
}, function (res) {
NotifycationService.showErrorNotify(res.data.message, 'SEND_INVITE_ERROR');
vm.invitePopover.sending = false;

View File

@@ -20,6 +20,10 @@
params: {
token: '@token'
}
},
countInvitations: {
method: 'GET',
url: '/api/invitations/count'
}
});
}

View File

@@ -107,8 +107,6 @@ exports.list = function (req, res) {
exports.update = function (req, res) {
var invitation = req.invitation;
console.log(req.query);
var countRegisteredEmail = function (callback) {
User.count({email: req.query.to_email}, function (err, count) {
if (err) {
@@ -225,6 +223,50 @@ exports.verifyToken = function (req, res) {
};
/**
* countInvitations
* @param req
* @param res
*/
exports.countInvitations = function (req, res) {
var countMyInvitations = function (callback) {
Invitation.count({
user: req.user._id,
status: 0,
expiresat: {$gt: Date.now()}
}, function (err, count) {
if (err) {
callback(err, null);
} else {
callback(null, count);
}
});
};
var countUsedInvitations = function (callback) {
Invitation.count({
user: req.user._id,
status: 2
}, function (err, count) {
if (err) {
callback(err, null);
} else {
callback(null, count);
}
});
};
async.parallel([countMyInvitations, countUsedInvitations], function (err, results) {
if (err) {
return res.status(422).send(err);
} else {
res.json({
countMyInvitations: results[0],
countUsedInvitations: results[1]
});
}
});
};
/**
* Invitation middleware
*/

View File

@@ -19,7 +19,8 @@ exports.invokeRolesPolicies = function () {
allows: [
{resources: '/api/invitations', permissions: '*'},
{resources: '/api/invitations/:invitationId', permissions: '*'},
{resources: '/api/invitations/token/:token', permissions: '*'}
{resources: '/api/invitations/token/:token', permissions: '*'},
{resources: '/api/invitations/count', permissions: '*'}
]
},
{

View File

@@ -11,12 +11,15 @@ module.exports = function (app) {
.get(invitations.list)
.post(invitations.create);
app.route('/api/invitations/token/:token').all(invitationsPolicy.isAllowed)
.get(invitations.verifyToken);
app.route('/api/invitations/count').all(invitationsPolicy.isAllowed)
.get(invitations.countInvitations);
app.route('/api/invitations/:invitationId').all(invitationsPolicy.isAllowed)
.put(invitations.update)
.delete(invitations.delete);
app.route('/api/invitations/token/:token').all(invitationsPolicy.isAllowed)
.get(invitations.verifyToken);
app.param('invitationId', invitations.invitationByID);
};

View File

@@ -23,7 +23,10 @@
$state.go('authentication.signin');
}
$scope.$on('auth-user-changed', function(event, args) {
/**
* auth-user-changed
*/
$scope.$on('auth-user-changed', function (event, args) {
vm.user = Authentication.user;
vm.scoreLevelData = vm.user ? ScoreLevelService.getScoreLevelJson(vm.user.score) : undefined;
});
@@ -60,6 +63,7 @@
if (res._id === vm.user._id) {
vm.user = Authentication.user = res;
$rootScope.$broadcast('auth-user-changed');
$rootScope.$broadcast('user-invitations-changed');
}
NotifycationService.showSuccessNotify('EXCHANGE_INVITATION_SUCCESSFULLY');
}