mirror of
https://github.com/taobataoma/meanTorrent.git
synced 2026-03-04 03:01:02 +01:00
feat(messages): load message replies data
This commit is contained in:
@@ -261,6 +261,7 @@
|
||||
EDIT_COMMENT: 'Edit Comment',
|
||||
REPLY_COMMENT: 'Reply Comment',
|
||||
SUBMIT_COMMENT: 'Submit Comment',
|
||||
SUBMIT_REPLY: 'Submit Reply',
|
||||
SUBMIT_CANCEL: 'Cancel',
|
||||
MARKDOWN_LINK: 'Styling with Markdown is supported',
|
||||
COMMENT_REPLY_BUTTON: '@ & reply',
|
||||
@@ -465,6 +466,7 @@
|
||||
BUTTON_SEARCH: 'Search',
|
||||
BUTTON_DELETE: ' Delete ',
|
||||
BUTTON_CLOSE: ' Close ',
|
||||
BUTTON_REPLY: ' Reply ',
|
||||
INPUT_EMAIL: 'email',
|
||||
SEND_INVITE_SUCCESSFULLY: 'Send invitation successfully',
|
||||
SEND_INVITE_ERROR: 'Send invitation failed',
|
||||
@@ -484,6 +486,7 @@
|
||||
TT_REQUIRED: 'Please enter message title',
|
||||
CT_REQUIRED: 'Please enter message content',
|
||||
LIST_TITLE: 'Title',
|
||||
LIST_REPLIES: 'Replies',
|
||||
LIST_TYPE: 'Type',
|
||||
LIST_SENDAT: 'SendedAt',
|
||||
LIST_SELECT: 'Select',
|
||||
|
||||
@@ -261,6 +261,7 @@
|
||||
EDIT_COMMENT: '编辑评论',
|
||||
REPLY_COMMENT: '回复评论',
|
||||
SUBMIT_COMMENT: '提交评论',
|
||||
SUBMIT_REPLY: '提交回复',
|
||||
SUBMIT_CANCEL: '取消',
|
||||
MARKDOWN_LINK: '排版支持 Markdown 全部格式',
|
||||
COMMENT_REPLY_BUTTON: '@ 楼主并回复',
|
||||
@@ -465,6 +466,7 @@
|
||||
BUTTON_SEARCH: '搜索',
|
||||
BUTTON_DELETE: ' 删除 ',
|
||||
BUTTON_CLOSE: ' 关闭 ',
|
||||
BUTTON_REPLY: ' 回复 ',
|
||||
INPUT_EMAIL: '邮箱地址',
|
||||
SEND_INVITE_SUCCESSFULLY: '发送邀请成功',
|
||||
SEND_INVITE_ERROR: '发送邀请失败',
|
||||
@@ -484,6 +486,7 @@
|
||||
TT_REQUIRED: '请输入消息标题',
|
||||
CT_REQUIRED: '请输入消息内容',
|
||||
LIST_TITLE: '标题',
|
||||
LIST_REPLIES: '回复',
|
||||
LIST_TYPE: '类型',
|
||||
LIST_SENDAT: '发送时间',
|
||||
LIST_SELECT: '选择',
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
.controller('MessageController', MessageController);
|
||||
|
||||
MessageController.$inject = ['$scope', '$state', '$translate', '$timeout', 'Authentication', '$filter', 'NotifycationService', '$stateParams', 'MessagesService',
|
||||
'MeanTorrentConfig', 'ModalConfirmService'];
|
||||
'MeanTorrentConfig', 'ModalConfirmService', 'marked'];
|
||||
|
||||
function MessageController($scope, $state, $translate, $timeout, Authentication, $filter, NotifycationService, $stateParams, MessagesService,
|
||||
MeanTorrentConfig, ModalConfirmService) {
|
||||
MeanTorrentConfig, ModalConfirmService, marked) {
|
||||
var vm = this;
|
||||
vm.messageConfig = MeanTorrentConfig.meanTorrentConfig.messages;
|
||||
vm.user = Authentication.user;
|
||||
@@ -23,7 +23,9 @@
|
||||
$state.go('authentication.signin');
|
||||
}
|
||||
|
||||
document.getElementById('popupSlide').addEventListener('transitionend', onTransitionEnd, false);
|
||||
if (document.getElementById('popupSlide')) {
|
||||
document.getElementById('popupSlide').addEventListener('transitionend', onTransitionEnd, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* checkSendTo
|
||||
@@ -108,6 +110,8 @@
|
||||
* pageChanged
|
||||
*/
|
||||
vm.pageChanged = function () {
|
||||
vm.selectedMessage = undefined;
|
||||
vm.hideMessage();
|
||||
vm.figureOutItemsToDisplay();
|
||||
};
|
||||
|
||||
@@ -161,8 +165,6 @@
|
||||
* @param event
|
||||
*/
|
||||
function onTransitionEnd(event) {
|
||||
console.log('end');
|
||||
|
||||
var e = $('.popup-overlay');
|
||||
if (vm.selectedMessage) {
|
||||
if (!e.hasClass('popup-visible')) {
|
||||
@@ -176,8 +178,8 @@
|
||||
* @param msg
|
||||
*/
|
||||
vm.showMessage = function (msg) {
|
||||
console.log(msg);
|
||||
vm.selectedMessage = msg;
|
||||
|
||||
var e = $('.popup-overlay');
|
||||
if (e.hasClass('popup-visible')) {
|
||||
e.removeClass('popup-visible');
|
||||
@@ -197,5 +199,92 @@
|
||||
e.removeClass('popup-visible');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* getMessageClass
|
||||
* @param m
|
||||
* @returns {*}
|
||||
*/
|
||||
vm.getMessageClass = function (m) {
|
||||
if (m) {
|
||||
if (m.from_user._id === vm.user._id) {
|
||||
if (m.from_status === 0) {
|
||||
return 'unread';
|
||||
}
|
||||
}
|
||||
if (m.to_user._id === vm.user._id) {
|
||||
if (m.to_status === 0) {
|
||||
return 'unread';
|
||||
}
|
||||
}
|
||||
}
|
||||
return 'read';
|
||||
};
|
||||
|
||||
/**
|
||||
* getContentMarked
|
||||
* @param m
|
||||
* @returns {*}
|
||||
*/
|
||||
vm.getContentMarked = function (m) {
|
||||
if (m) {
|
||||
return marked(m.content, {sanitize: true});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* replyMessage
|
||||
*/
|
||||
vm.replyMessage = function (m) {
|
||||
var rmsg = new MessagesService({
|
||||
_messageId: m._id,
|
||||
title: '',
|
||||
content: vm.replyContent,
|
||||
type: 'user',
|
||||
from_user: vm.user._id,
|
||||
to_user: fromIsMe(m) ? m.to_user._id : m.from_user._id
|
||||
});
|
||||
|
||||
rmsg.$save(function (response) {
|
||||
successCallback(response);
|
||||
}, function (errorResponse) {
|
||||
errorCallback(errorResponse);
|
||||
});
|
||||
|
||||
function successCallback(res) {
|
||||
console.log(res);
|
||||
vm.selectedMessage = res;
|
||||
|
||||
vm.messages.splice(vm.messages.indexOf(m), 0, res);
|
||||
vm.messages.splice(vm.messages.indexOf(m), 1);
|
||||
vm.figureOutItemsToDisplay();
|
||||
|
||||
vm.replyContent = undefined;
|
||||
NotifycationService.showSuccessNotify('MESSAGE_SEND_SUCCESSFULLY');
|
||||
}
|
||||
|
||||
function errorCallback(res) {
|
||||
NotifycationService.showErrorNotify(res.data.message, 'MESSAGE_SEND_FAILED');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* fromIsMe
|
||||
* @param m
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function fromIsMe(m) {
|
||||
return (m.from_user._id === vm.user._id) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* toIsMe
|
||||
* @param m
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function toIsMe(m) {
|
||||
return (m.to_user._id === vm.user._id) ? true : false;
|
||||
}
|
||||
}
|
||||
}());
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
height: 38px;
|
||||
width: 38px;
|
||||
}
|
||||
.reply-avatar {
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
border-radius: 3px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
.message-title {
|
||||
font-weight: bold;
|
||||
font-size: 14px;
|
||||
@@ -45,6 +52,25 @@
|
||||
color: #999;
|
||||
margin: 0 0;
|
||||
}
|
||||
.read {
|
||||
color: #999;
|
||||
}
|
||||
.unread {
|
||||
color: #333;
|
||||
}
|
||||
.title-info {
|
||||
margin-left: 48px;
|
||||
}
|
||||
.reply-info {
|
||||
margin-left: 40px;
|
||||
.message-info {
|
||||
margin-top: -10px;
|
||||
}
|
||||
}
|
||||
.message-reply {
|
||||
margin-left: 50px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.popup-overlay {
|
||||
@@ -55,16 +81,16 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
overflow: auto;
|
||||
z-index: 10000;
|
||||
z-index: 999;
|
||||
transition: all 0.3s ease-out;
|
||||
/* csslint ignore:start */
|
||||
transform: translateX(101%) translateY(0);
|
||||
/* csslint ignore:end */
|
||||
@media (min-width: @screen-sm-min) {
|
||||
min-width: 450px;
|
||||
width: 450px;
|
||||
}
|
||||
@media (max-width: @screen-xs-max) {
|
||||
min-width: ~"calc(100% - 50px)";
|
||||
min-width: ~"calc(100% - 150px)";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,20 +101,28 @@
|
||||
}
|
||||
|
||||
.bottom-control {
|
||||
background-color: #eee;
|
||||
background-color: #fdfdfd;
|
||||
border-top: solid 1px #e6e6e6;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
height: 150px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
padding: 7px 10px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.message-popup {
|
||||
background-color: #fafafa;
|
||||
background-color: #fdfdfd;
|
||||
width: 100%;
|
||||
height: ~"calc(100% - 50px)";
|
||||
overflow: auto;
|
||||
padding: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.reply-textarea {
|
||||
resize: none;
|
||||
width: 100%;
|
||||
min-height: 90px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
function MessagesService($resource) {
|
||||
return $resource('/api/messages/:messageId', {
|
||||
messageId: '@_id'
|
||||
messageId: '@_messageId'
|
||||
}, {
|
||||
update: {
|
||||
method: 'PUT'
|
||||
|
||||
@@ -33,28 +33,32 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'MESSAGES_FIELD.LIST_TITLE' | translate}}</th>
|
||||
<th class="text-center">{{ 'MESSAGES_FIELD.LIST_REPLIES' | translate}}</th>
|
||||
<th class="text-center">{{ 'MESSAGES_FIELD.LIST_TYPE' | translate}}</th>
|
||||
<th class="text-center">{{ 'MESSAGES_FIELD.LIST_SENDAT' | translate}}</th>
|
||||
<th class="text-center">{{ 'MESSAGES_FIELD.LIST_SELECT' | translate}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="message-item" ng-repeat="m in vm.pagedItems">
|
||||
<td ng-click="vm.showMessage(m);">
|
||||
<tr class="message-item" ng-repeat="m in vm.pagedItems" ng-click="vm.showMessage(m);">
|
||||
<td>
|
||||
<img class="message-avatar" ng-src="/{{m.from_user.profileImageURL}}">
|
||||
<span class="message-title" ng-bind="m.title"></span>
|
||||
<span class="message-title" ng-class="vm.getMessageClass(m);" ng-bind="m.title"></span>
|
||||
|
||||
<p class="message-info">
|
||||
{{m.from_user.displayName}} {{'MESSAGES_FIELD.INFO_SEND_TO' | translate}} {{m.to_user.displayName}} {{'MESSAGES_FIELD.INFO_SEND_AT' | translate}} {{m.createdat | date: 'yyyy-MM-dd HH:mm:ss' }}
|
||||
</p>
|
||||
</td>
|
||||
<td class="td-v-middle text-center">
|
||||
{{'MESSAGE_TYPE_' + m.type.toUpperCase() | translate}}
|
||||
<span ng-class="vm.getMessageClass(m);">{{m._replies.length}}</span>
|
||||
</td>
|
||||
<td class="td-v-middle text-center">
|
||||
{{m.createdat | life}}
|
||||
<span ng-class="vm.getMessageClass(m);">{{'MESSAGE_TYPE_' + m.type.toUpperCase() | translate}}</span>
|
||||
</td>
|
||||
<td class="td-v-middle text-center">
|
||||
<span ng-class="vm.getMessageClass(m);">{{m.createdat | life}}</span>
|
||||
</td>
|
||||
<td class="td-v-middle text-center" ng-click="$event.stopPropagation();">
|
||||
<input type="checkbox" class="tcheckbox" ng-model="vm.selected[m._id]"
|
||||
id="checkbox_{{m._id}}">
|
||||
</label>
|
||||
@@ -79,12 +83,42 @@
|
||||
</div>
|
||||
|
||||
<div id="popupSlide" class="popup-overlay">
|
||||
<div class="message-popup">
|
||||
<div class="message-popup message-item">
|
||||
<div>
|
||||
<img class="message-avatar" ng-src="/{{vm.selectedMessage.from_user.profileImageURL}}">
|
||||
|
||||
<div class="title-info">
|
||||
<span class="message-title" ng-class="vm.getMessageClass(vm.selectedMessage);" ng-bind="vm.selectedMessage.title"></span>
|
||||
|
||||
<p class="message-info">
|
||||
{{vm.selectedMessage.from_user.displayName}} {{'MESSAGES_FIELD.INFO_SEND_TO' | translate}} {{vm.selectedMessage.to_user.displayName}} {{'MESSAGES_FIELD.INFO_SEND_AT' | translate}} {{vm.selectedMessage.createdat | date: 'yyyy-MM-dd HH:mm:ss' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<li class="status-divider"></li>
|
||||
<div class="message-content" ng-bind-html="vm.getContentMarked(vm.selectedMessage);"></div>
|
||||
<li class="status-divider" ng-show="vm.selectedMessage._replies.length>0"></li>
|
||||
|
||||
<div class="message-reply" ng-repeat="r in vm.selectedMessage._replies">
|
||||
<img class="reply-avatar" ng-src="/{{r.from_user.profileImageURL}}">
|
||||
|
||||
<div class="reply-info">
|
||||
<div class="message-content" ng-bind-html="vm.getContentMarked(r);"></div>
|
||||
|
||||
<p class="message-info">
|
||||
{{r.from_user.displayName}} | {{r.createdat | date: 'yyyy-MM-dd HH:mm:ss' }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-control">
|
||||
<textarea class="form-control reply-textarea" id="reply-content" name="reply-content"
|
||||
ng-model="vm.replyContent" autofocus></textarea>
|
||||
<button class="btn btn-default" ng-click="vm.hideMessage();">{{ 'BUTTON_CLOSE' | translate }}</button>
|
||||
<button class="btn btn-success pull-right">{{ 'BUTTON_DELETE' | translate }}</button>
|
||||
<button class="btn btn-default">{{ 'BUTTON_DELETE' | translate }}</button>
|
||||
<button class="btn btn-success pull-right" ng-disabled="!vm.replyContent" ng-click="vm.replyMessage(vm.selectedMessage);">{{ 'BUTTON_REPLY' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -52,8 +52,18 @@ exports.list = function (req, res) {
|
||||
]
|
||||
})
|
||||
.sort('-updatedat, -createdat')
|
||||
.populate('from_user')
|
||||
.populate('to_user')
|
||||
.populate('from_user', 'displayName profileImageURL uploaded downloaded')
|
||||
.populate('to_user', 'displayName profileImageURL uploaded downloaded')
|
||||
.populate({
|
||||
path: '_replies.from_user',
|
||||
select: 'displayName profileImageURL uploaded downloaded',
|
||||
model: 'User'
|
||||
})
|
||||
.populate({
|
||||
path: '_replies.to_user',
|
||||
select: 'displayName profileImageURL uploaded downloaded',
|
||||
model: 'User'
|
||||
})
|
||||
.exec(function (err, messages) {
|
||||
if (err) {
|
||||
return res.status(422).send({
|
||||
@@ -107,16 +117,38 @@ exports.delete = function (req, res) {
|
||||
* @param res
|
||||
*/
|
||||
exports.createReply = function (req, res) {
|
||||
var reply = new Message(req.body);
|
||||
|
||||
};
|
||||
var message = req.message;
|
||||
message._replies.push(reply);
|
||||
message.updatedat = Date.now();
|
||||
|
||||
/**
|
||||
* deleteReply
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
exports.deleteReply = function (req, res) {
|
||||
if (message.from_user._id.equals(req.user._id)) {
|
||||
message.to_status = 0;
|
||||
} else {
|
||||
message.from_status = 0;
|
||||
}
|
||||
|
||||
message.save(function (err) {
|
||||
if (err) {
|
||||
return res.status(422).send({
|
||||
message: errorHandler.getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
Message.populate(message._replies, {
|
||||
path: 'from_user to_user',
|
||||
select: 'displayName profileImageURL uploaded downloaded'
|
||||
}, function (err, t) {
|
||||
if (err) {
|
||||
return res.status(422).send({
|
||||
message: errorHandler.getErrorMessage(err)
|
||||
});
|
||||
} else {
|
||||
res.json(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -131,8 +163,18 @@ exports.messageByID = function (req, res, next, id) {
|
||||
}
|
||||
|
||||
Message.findById(id)
|
||||
.populate('from_user')
|
||||
.populate('to_user')
|
||||
.populate('from_user', 'displayName profileImageURL uploaded downloaded')
|
||||
.populate('to_user', 'displayName profileImageURL uploaded downloaded')
|
||||
.populate({
|
||||
path: '_replies.from_user',
|
||||
select: 'displayName profileImageURL uploaded downloaded',
|
||||
model: 'User'
|
||||
})
|
||||
.populate({
|
||||
path: '_replies.to_user',
|
||||
select: 'displayName profileImageURL uploaded downloaded',
|
||||
model: 'User'
|
||||
})
|
||||
.exec(function (err, message) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
|
||||
@@ -18,8 +18,7 @@ exports.invokeRolesPolicies = function () {
|
||||
roles: ['admin', 'oper', 'user'],
|
||||
allows: [
|
||||
{resources: '/api/messages', permissions: '*'},
|
||||
{resources: '/api/messages/:messageId', permissions: '*'},
|
||||
{resources: '/api/messages/:messageId/:replyId', permissions: '*'}
|
||||
{resources: '/api/messages/:messageId', permissions: '*'}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -16,8 +16,5 @@ module.exports = function (app) {
|
||||
.delete(messages.delete)
|
||||
.post(messages.createReply);
|
||||
|
||||
app.route('/api/messages/:messageId/:replyId').all(messagesPolicy.isAllowed)
|
||||
.delete(messages.deleteReply);
|
||||
|
||||
app.param('messageId', messages.messageByID);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user