Add notification, allow watch boards / lists / cards

This commit is contained in:
Liming Xie 2016-01-05 23:26:02 +08:00
parent 9ef8ebaf09
commit 9bbdacc79a
24 changed files with 579 additions and 16 deletions

View file

@ -51,7 +51,7 @@ BlazeComponent.extendComponent({
cardLink() {
const card = this.currentData().card();
return card && Blaze.toHTML(HTML.A({
href: FlowRouter.path(card.absoluteUrl()),
href: card.absoluteUrl(),
'class': 'action-card',
}, card.title));
},

View file

@ -19,6 +19,17 @@ template(name="boardHeaderBar")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board
if $eq watchLevel "watching"
i.fa.fa-eye
span {{_ 'watching'}}
if $eq watchLevel "tracking"
i.fa.fa-user
span {{_ 'tracking'}}
if $eq watchLevel "muted"
i.fa.fa-times-circle
span {{_ 'muted'}}
.board-header-btns.right
if isMiniScreen
unless isSandstorm
@ -34,6 +45,17 @@ template(name="boardHeaderBar")
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board
if $eq watchLevel "watching"
i.fa.fa-eye
span {{_ 'watching'}}
if $eq watchLevel "tracking"
i.fa.fa-user
span {{_ 'tracking'}}
if $eq watchLevel "muted"
i.fa.fa-times-circle
span {{_ 'muted'}}
a.board-header-btn.js-open-filter-view(
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{/if}}"
class="{{#if Filter.isActive}}emphasis{{/if}}")
@ -97,6 +119,33 @@ template(name="boardVisibilityList")
template(name="boardChangeVisibilityPopup")
+boardVisibilityList
template(name="boardChangeWatchPopup")
ul.pop-over-list
li
with "watching"
a.js-select-watch
i.fa.fa-eye.colorful
| {{_ 'watching'}}
if watchCheck
i.fa.fa-check
span.sub-name {{_ 'watching-info'}}
li
with "tracking"
a.js-select-watch
i.fa.fa-user.colorful
| {{_ 'tracking'}}
if watchCheck
i.fa.fa-check
span.sub-name {{_ 'tracking-info'}}
li
with "muted"
a.js-select-watch
i.fa.fa-times-circle.colorful
| {{_ 'muted'}}
if watchCheck
i.fa.fa-check
span.sub-name {{_ 'muted-info'}}
template(name="boardChangeColorPopup")
.board-backgrounds-list.clearfix
each backgroundColors

View file

@ -41,6 +41,11 @@ Template.boardChangeTitlePopup.events({
});
BlazeComponent.extendComponent({
watchLevel() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.getWatchLevel(Meteor.userId());
},
isStarred() {
const boardId = Session.get('currentBoard');
const user = Meteor.user();
@ -65,6 +70,7 @@ BlazeComponent.extendComponent({
},
'click .js-open-board-menu': Popup.open('boardMenu'),
'click .js-change-visibility': Popup.open('boardChangeVisibility'),
'click .js-watch-board': Popup.open('boardChangeWatch'),
'click .js-open-filter-view'() {
Sidebar.setView('filter');
},
@ -176,3 +182,25 @@ BlazeComponent.extendComponent({
}];
},
}).register('boardChangeVisibilityPopup');
BlazeComponent.extendComponent({
watchLevel() {
const currentBoard = Boards.findOne(Session.get('currentBoard'));
return currentBoard.getWatchLevel(Meteor.userId());
},
watchCheck() {
return this.currentData() === this.watchLevel();
},
events() {
return [{
'click .js-select-watch'() {
const level = this.currentData();
Meteor.call('watch', 'board', Session.get('currentBoard'), level, (err, ret) => {
if (!err && ret) Popup.close();
});
},
}];
},
}).register('boardChangeWatchPopup');

View file

@ -10,6 +10,8 @@ template(name="cardDetails")
h2.card-details-title.js-card-title(
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= title
if isWatching
i.fa.fa-eye.card-details-watch
if archived
p.warning {{_ 'card-archived'}}
@ -82,6 +84,9 @@ template(name="editCardTitleForm")
a.fa.fa-times-thin.js-close-inlined-form
template(name="cardDetailsActionsPopup")
ul.pop-over-list
li: a.js-toggle-watch-card {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}}
hr
ul.pop-over-list
li: a.js-members {{_ 'card-edit-members'}}
li: a.js-labels {{_ 'card-edit-labels'}}

View file

@ -23,6 +23,11 @@ BlazeComponent.extendComponent({
this.calculateNextPeak();
},
isWatching() {
const card = this.currentData();
return card.findWatcher(Meteor.userId());
},
scrollParentContainer() {
const cardPanelWidth = 510;
const bodyBoardComponent = this.parentComponent();
@ -128,6 +133,12 @@ BlazeComponent.extendComponent({
}
}).register('inlinedCardDescription');
Template.cardDetailsActionsPopup.helpers({
isWatching() {
return this.findWatcher(Meteor.userId());
},
});
Template.cardDetailsActionsPopup.events({
'click .js-members': Popup.open('cardMembers'),
'click .js-labels': Popup.open('cardLabels'),
@ -139,6 +150,13 @@ Template.cardDetailsActionsPopup.events({
Popup.close();
},
'click .js-more': Popup.open('cardMore'),
'click .js-toggle-watch-card'() {
const currentCard = this;
const level = currentCard.findWatcher(Meteor.userId()) ? null : 'watching';
Meteor.call('watch', 'card', currentCard._id, level, (err, ret) => {
if (!err && ret) Popup.close();
});
},
});
Template.editCardTitleForm.onRendered(function() {

View file

@ -36,6 +36,11 @@
font-size: 17px
padding: 10px
.card-details-watch
font-size: 17px
padding-left: 7px
color: #a6a6a6
.card-details-title
font-weight: bold
font-size: 1.33em

View file

@ -65,6 +65,10 @@
text-overflow: ellipsis
word-wrap: break-word
.list-header-watch-icon
padding-left: 10px
color: #a6a6a6
.list-header-menu-icon
position: absolute
padding: 7px

View file

@ -7,6 +7,8 @@ template(name="listHeader")
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
= title
if currentUser.isBoardMember
if isWatching
i.list-header-watch-icon.fa.fa-eye
a.list-header-menu-icon.fa.fa-navicon.js-open-list-menu
template(name="editListTitleForm")
@ -17,6 +19,9 @@ template(name="editListTitleForm")
a.fa.fa-times-thin.js-close-inlined-form
template(name="listActionPopup")
ul.pop-over-list
li: a.js-toggle-watch-list {{#if isWatching}}{{_ 'unwatch'}}{{else}}{{_ 'watch'}}{{/if}}
hr
ul.pop-over-list
li: a.js-add-card {{_ 'add-card'}}
if cards.count

View file

@ -8,6 +8,11 @@ BlazeComponent.extendComponent({
}
},
isWatching() {
const list = this.currentData();
return list.findWatcher(Meteor.userId());
},
events() {
return [{
'click .js-open-list-menu': Popup.open('listAction'),
@ -16,6 +21,12 @@ BlazeComponent.extendComponent({
},
}).register('listHeader');
Template.listActionPopup.helpers({
isWatching() {
return this.findWatcher(Meteor.userId());
},
});
Template.listActionPopup.events({
'click .js-add-card'() {
const listDom = document.getElementById(`js-list-${this._id}`);
@ -29,6 +40,13 @@ Template.listActionPopup.events({
MultiSelection.add(cardIds);
Popup.close();
},
'click .js-toggle-watch-list'() {
const currentList = this;
const level = currentList.findWatcher(Meteor.userId()) ? null : 'watching';
Meteor.call('watch', 'list', currentList._id, level, (err, ret) => {
if (!err && ret) Popup.close();
});
},
'click .js-close-list'(evt) {
evt.preventDefault();
this.archive();

View file

@ -18,6 +18,9 @@
float: left
border-radius: 3px
.board-header-watch-icon
padding-left: 7px
a.fa, a i.fa
color: white

View file

@ -279,9 +279,12 @@ kbd
.fa.fa-globe.colorful
color: #4caf50
.fa.fa-lock.colorful
.fa.fa-lock.colorful, .fa.fa-times-circle.colorful
color: #f44336
.fa.fa-user.colorful, .fa.fa-eye.colorful, .fa.fa-circle.colorful
color: #4336f4
.pop-over .pop-over-list li a:not(.disabled):hover
.fa, .fa.colorful
color: white

View file

@ -15,6 +15,7 @@ template(name="memberMenuPopup")
li: a.js-change-avatar {{_ 'edit-avatar'}}
li: a.js-change-password {{_ 'changePasswordPopup-title'}}
li: a.js-change-language {{_ 'changeLanguagePopup-title'}}
li: a.js-edit-notification {{_ 'editNotificationPopup-title'}}
hr
ul.pop-over-list
li: a.js-logout {{_ 'log-out'}}
@ -32,6 +33,23 @@ template(name="editProfilePopup")
input.js-profile-initials(type="text" value=profile.initials)
input.primary.wide(type="submit" value="{{_ 'save'}}")
template(name="editNotificationPopup")
ul.pop-over-list
li
a.js-toggle-tag-notify-watch
i.fa.fa-eye.colorful
| {{_ 'watching'}}
if hasTag "notify-watch"
i.fa.fa-check
span.sub-name {{_ 'notify-watch'}}
li
a.js-toggle-tag-notify-participate
i.fa.fa-user.colorful
| {{_ 'tracking'}}
if hasTag "notify-participate"
i.fa.fa-check
span.sub-name {{_ 'notify-participate'}}
template(name="changePasswordPopup")
+atForm(state='changePwd')

View file

@ -8,6 +8,7 @@ Template.memberMenuPopup.events({
'click .js-change-avatar': Popup.open('changeAvatar'),
'click .js-change-password': Popup.open('changePassword'),
'click .js-change-language': Popup.open('changeLanguage'),
'click .js-edit-notification': Popup.open('editNotification'),
'click .js-logout'(evt) {
evt.preventDefault();
@ -33,6 +34,25 @@ Template.editProfilePopup.events({
},
});
Template.editNotificationPopup.helpers({
hasTag(tag) {
const user = Meteor.user();
return user && user.hasTag(tag);
},
});
// we defined github like rules, see: https://github.com/settings/notifications
Template.editNotificationPopup.events({
'click .js-toggle-tag-notify-participate'() {
const user = Meteor.user();
if (user) user.toggleTag('notify-participate');
},
'click .js-toggle-tag-notify-watch'() {
const user = Meteor.user();
if (user) user.toggleTag('notify-watch');
},
});
// XXX For some reason the useraccounts autofocus isnt working in this case.
// See https://github.com/meteor-useraccounts/core/issues/384
Template.changePasswordPopup.onRendered(function() {