diff --git a/media/js/base.js b/media/js/base.js
index cee4f4a47f..18d91738f4 100644
--- a/media/js/base.js
+++ b/media/js/base.js
@@ -17,6 +17,7 @@ if ($('.messages')[0]) {
}
$(function(){
+
var msg_ct = $("#msg-count");
$.ajax({
url: msg_ct.data('cturl'),
@@ -25,52 +26,105 @@ $(function(){
success: function(data) {
if (data['count'] > 0) {
$('.num', msg_ct).html(data['count']).removeClass('hide');
+ $('.num').data('count', data['count']);
}
}
});
-$('#notice-icon').click(function() {
- var popup = $('#notice-popup');
- popup.toggleClass('hide');
- if (!popup.hasClass('hide')) {
- $('.con', popup).css({'max-height':$(window).height() - $('#header').outerHeight() - $('#notice-popup .hd').outerHeight() - 3});
- }
-});
-$(window).resize(function() {
- var popup = $('#notice-popup');
- if (!popup.hasClass('hide')) {
- $('.con', popup).css({'max-height':$(window).height() - $('#header').outerHeight() - $('#notice-popup .hd').outerHeight() - 3});
- }
-});
+ $('#notice-icon').click(function() {
+ var popup = $('#notice-popup');
+ popup.toggleClass('hide');
-$('#notice-popup .close').click(function() {
- $('#notice-popup').addClass('hide');
-});
-
-(function () {
- var my_info = $('#my-info');
- var popup = $('#user-info-popup');
- my_info.click(function() {
- var loading_tip = $('.loading-tip', popup);
- if (popup.hasClass('hide')) {
- popup.removeClass('hide');
- loading_tip.removeClass('hide');
+ //to prevent duplicately send ajax
+ if ($('#notice-icon').data('ajax') != 1){
$.ajax({
- url: my_info.data('url'),
+ url: popup.data('pop_url'),
dataType: 'json',
cache: false,
success: function(data) {
- loading_tip.addClass('hide');
- $('#space-traffic').html(data['html']);
+ popup.find('.loading-tip').remove();
+ popup.html(data['notifications_popup_html']);
+ $('.con', popup).css({'max-height':$(window).height() - $('#header').outerHeight() - $('#notice-popup .hd').outerHeight() - 3});
+ $('#notice-icon').data('ajax', 1);
+
+
+ $('#notice-popup .close').click(function() {
+ if ($('.num').data('count') > 0){
+ $.ajax({
+ url: popup.data('seen_url'),
+ dataType: 'json',
+ cache: false,
+ success: function() {
+ popup.addClass('hide');
+ $('.num').data('count', 0);
+ $('.num').addClass('hide');
+ $('li').each(function() {
+ if ($(this).hasClass('unread')){
+ $(this).removeClass('unread');
+ $(this).addClass('read');
+ }
+ });
+ }
+ });
+ }else{
+ popup.addClass('hide');
+ }
+ });
+
+ $("a[id$='-notice']").click(function() {
+ var notice_id = $(this).data('notice_id');
+ var url = popup.data('seen_by_id_url');
+ var href = $(this).data('href');
+
+ if ($(this).parent().parent().hasClass('unread')){
+ $.ajax({
+ url: url + '?notice_id=' + notice_id,
+ type: 'GET',
+ dataType: 'json',
+ cache: false,
+ success: function() {
+ location.href = href;
+ }
+ });
+ }else{
+ location.href = href;
+ }
+ });
}
});
- } else {
- popup.addClass('hide');
}
- return false;
});
-})();
+ $(window).resize(function() {
+ var popup = $('#notice-popup');
+ if (!popup.hasClass('hide')) {
+ $('.con', popup).css({'max-height':$(window).height() - $('#header').outerHeight() - $('#notice-popup .hd').outerHeight() - 3});
+ }
+ });
+
+ (function () {
+ var my_info = $('#my-info');
+ var popup = $('#user-info-popup');
+ my_info.click(function() {
+ var loading_tip = $('.loading-tip', popup);
+ if (popup.hasClass('hide')) {
+ popup.removeClass('hide');
+ loading_tip.removeClass('hide');
+ $.ajax({
+ url: my_info.data('url'),
+ dataType: 'json',
+ cache: false,
+ success: function(data) {
+ loading_tip.addClass('hide');
+ $('#space-traffic').html(data['html']);
+ }
+ });
+ } else {
+ popup.addClass('hide');
+ }
+ return false;
+ });
+ })();
});
$(document).click(function(e) {
@@ -83,6 +137,15 @@ $(document).click(function(e) {
closePopup($('#user-info-popup'), $('#my-info'));
closePopup($('#top-nav-grp-info'), $('#top-nav-grp'));
closePopup($('#notice-popup'), $('#notice-icon'));
+
+ var closeNum = function(num, num_switch) {
+ if (num.hasClass('hide') && !num.is(target) && !num_switch.is(target) && !num_switch.find('*').is(target) ) {
+ if ($('.num').data('count') > 0){
+ num.removeClass('hide');
+ }
+ }
+ };
+ closeNum($('.num'), $('#msg-count'));
});
// search: disable submit when input nothing
diff --git a/seahub/group/signals.py b/seahub/group/signals.py
index 2e5500c455..804a1ff723 100644
--- a/seahub/group/signals.py
+++ b/seahub/group/signals.py
@@ -1,6 +1,6 @@
import django.dispatch
-grpmsg_added = django.dispatch.Signal(providing_args=["group_id", "from_email"])
-grpmsg_reply_added = django.dispatch.Signal(providing_args=["msg_id", "from_email"])
+grpmsg_added = django.dispatch.Signal(providing_args=["group_id", "from_email", "message"])
+grpmsg_reply_added = django.dispatch.Signal(providing_args=["msg_id", "from_email", "reply_msg"])
group_join_request = django.dispatch.Signal(providing_args=["staffs", "username", "group", "join_reqeust_msg"])
diff --git a/seahub/group/views.py b/seahub/group/views.py
index f6e970e952..a41db65774 100644
--- a/seahub/group/views.py
+++ b/seahub/group/views.py
@@ -442,7 +442,8 @@ def msg_reply(request, msg_id):
if group_msg.from_email != request.user.username:
grpmsg_reply_added.send(sender=MessageReply,
msg_id=msg_id,
- from_email=request.user.username)
+ from_email=request.user.username,
+ reply_msg=msg)
replies = MessageReply.objects.filter(reply_to=group_msg)
r_num = len(replies)
if r_num < 4 or r_status == 'show':
@@ -1192,7 +1193,7 @@ def group_add_discussion(request, group):
# send signal
grpmsg_added.send(sender=GroupMessage, group_id=group.id,
- from_email=username)
+ from_email=username, message=msg)
gm.attachments = []
if selected:
diff --git a/seahub/message/views.py b/seahub/message/views.py
index 90804dabc9..6def8468a6 100755
--- a/seahub/message/views.py
+++ b/seahub/message/views.py
@@ -20,6 +20,7 @@ from seahub.views import is_registered_user
from seahub.share.models import PrivateFileDirShare
from seahub.utils import is_valid_username
from seahub.utils.paginator import Paginator
+from seahub.notifications.models import UserNotification
@login_required
@user_mods_check
@@ -101,6 +102,7 @@ def user_msg_list(request, id_or_email):
person_msgs.page_range = paginator.get_page_range(person_msgs.number)
person_msgs.object_list = list(person_msgs.object_list)
+ UserNotification.objects.seen_user_msg_notices(username, to_email)
return render_to_response("message/user_msg_list.html", {
"person_msgs": person_msgs,
"to_email": to_email,
diff --git a/seahub/notifications/management/commands/send_notices.py b/seahub/notifications/management/commands/send_notices.py
index a25a865dee..5b9f402477 100644
--- a/seahub/notifications/management/commands/send_notices.py
+++ b/seahub/notifications/management/commands/send_notices.py
@@ -53,14 +53,20 @@ class Command(BaseCommand):
return notice
def format_user_message(self, notice):
- notice.user_msg_from = escape(email2nickname(notice.detail))
- notice.user_msg_from_avatar_url = self.get_avatar_url(notice.detail)
+ d = notice.user_message_detail_to_dict()
+ user_msg_from = d['msg_from']
+ message = d.get('message')
+
+ notice.user_msg_from = escape(email2nickname(user_msg_from))
+ notice.user_msg_from_avatar_url = self.get_avatar_url(user_msg_from)
notice.user_msg_url = reverse('user_msg_list', args=[notice.detail])
+ notice.user_msg = message
return notice
def format_group_message(self, notice):
- d = json.loads(notice.detail)
+ d = notice.group_message_detail_to_dict()
group_id = d['group_id']
+ message = d['message']
group = seaserv.get_group(int(group_id))
if group is None:
notice.delete()
@@ -69,14 +75,17 @@ class Command(BaseCommand):
notice.group_msg_from = escape(email2nickname(d['msg_from']))
notice.group_name = group.group_name
notice.group_msg_from_avatar_url = self.get_avatar_url(d['msg_from'])
+ notice.grp_msg = message
return notice
def format_grpmsg_reply(self, notice):
- d = json.loads(notice.detail)
+ d = notice.grpmsg_reply_detail_to_dict()
+ message = d.get['reply_msg']
notice.group_msg_reply_url = reverse('msg_reply_new')
notice.group_msg_reply_from = escape(email2nickname(d['reply_from']))
notice.group_msg_reply_from_avatar_url = self.get_avatar_url(d['reply_from'])
+ notice.grp_reply_msg = message
return notice
def format_repo_share_msg(self, notice):
diff --git a/seahub/notifications/models.py b/seahub/notifications/models.py
index 8b6ee24fbb..692dadd6ba 100644
--- a/seahub/notifications/models.py
+++ b/seahub/notifications/models.py
@@ -55,11 +55,14 @@ def priv_file_share_msg_to_json(share_from, file_name, priv_share_token):
return json.dumps({'share_from': share_from, 'file_name': file_name,
'priv_share_token': priv_share_token})
-def group_msg_to_json(group_id, msg_from):
- return json.dumps({'group_id': group_id, 'msg_from': msg_from})
+def group_msg_to_json(group_id, msg_from, message):
+ return json.dumps({'group_id': group_id, 'msg_from': msg_from, 'message': message})
-def grpmsg_reply_to_json(msg_id, reply_from):
- return json.dumps({'msg_id': msg_id, 'reply_from': reply_from})
+def grpmsg_reply_to_json(msg_id, reply_from, reply_msg):
+ return json.dumps({'msg_id': msg_id, 'reply_from': reply_from, 'reply_msg': reply_msg})
+
+def user_msg_to_json(message, msg_from):
+ return json.dumps({'message': message, 'msg_from': msg_from})
def group_join_request_to_json(username, group_id, join_request_msg):
return json.dumps({'username': username, 'group_id': group_id,
@@ -141,7 +144,6 @@ class UserNotificationManager(models.Manager):
) for m in to_users ]
UserNotification.objects.bulk_create(user_notices)
-
def seen_group_msg_notices(self, to_user, group_id):
"""Mark group message notices of a user as seen.
"""
@@ -157,13 +159,42 @@ class UserNotificationManager(models.Manager):
except UserNotification.InvalidDetailError:
continue
+ def seen_group_msg_reply_notice(self, to_user, msg_id=None):
+ """Mark all group message replies of a user as seen.
+
+ Arguments:
+ - `self`:
+ - `to_user`:
+ - `msg_id`:
+ """
+ if not msg_id:
+ super(UserNotificationManager, self).filter(
+ to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY,
+ seen=False).update(seen=True)
+ else:
+ notifs = super(UserNotificationManager, self).filter(
+ to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY,
+ seen=False)
+ for n in notifs:
+ d = n.grpmsg_reply_detail_to_dict()
+ if msg_id == d['msg_id']:
+ n.seen = True
+ n.save()
+
def seen_user_msg_notices(self, to_user, from_user):
- """Mark group message notices of a user as seen.
+ """Mark priv message notices of a user as seen.
"""
user_notices = super(UserNotificationManager, self).filter(
- detail=from_user, to_user=to_user, msg_type=MSG_TYPE_USER_MESSAGE)
+ to_user=to_user, seen=False, msg_type=MSG_TYPE_USER_MESSAGE)
for notice in user_notices:
- notice.is_seen()
+ try:
+ notice_from_user = notice.user_message_detail_to_dict().get('msg_from')
+ if from_user == notice_from_user:
+ if notice.seen is False:
+ notice.seen = True
+ notice.save()
+ except UserNotification.InvalidDetailError:
+ continue
def remove_group_msg_notices(self, to_user, group_id):
"""Remove group message notices of a user.
@@ -197,28 +228,6 @@ class UserNotificationManager(models.Manager):
qs = qs.filter(seen=seen)
return qs
- def seen_group_msg_reply_notice(self, to_user, msg_id=None):
- """Mark all group message replies of a user as seen.
-
- Arguments:
- - `self`:
- - `to_user`:
- - `msg_id`:
- """
- if not msg_id:
- super(UserNotificationManager, self).filter(
- to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY,
- seen=False).update(seen=True)
- else:
- notifs = super(UserNotificationManager, self).filter(
- to_user=to_user, msg_type=MSG_TYPE_GRPMSG_REPLY,
- seen=False)
- for n in notifs:
- d = n.grpmsg_reply_detail_to_dict()
- if msg_id == d['msg_id']:
- n.seen = True
- n.save()
-
def remove_group_msg_reply_notice(self, to_user):
"""Mark all group message replies of a user as seen.
@@ -373,7 +382,7 @@ class UserNotification(models.Model):
- `self`:
"""
return self.msg_type == MSG_TYPE_GROUP_JOIN_REQUEST
-
+
def group_message_detail_to_dict(self):
"""Parse group message detail, returns dict contains ``group_id`` and
``msg_from``.
@@ -395,12 +404,17 @@ class UserNotification(models.Model):
if isinstance(detail, int): # Compatible with existing records
group_id = detail
msg_from = None
+ return {'group_id': group_id, 'msg_from': msg_from}
elif isinstance(detail, dict):
group_id = detail['group_id']
msg_from = detail['msg_from']
+ if 'message' in detail:
+ message = detail['message']
+ return {'group_id': group_id, 'msg_from': msg_from, 'message': message}
+ else:
+ return {'group_id': group_id, 'msg_from': msg_from}
else:
raise self.InvalidDetailError, 'Wrong detail format of group message'
- return {'group_id': group_id, 'msg_from': msg_from}
def grpmsg_reply_detail_to_dict(self):
"""Parse group message reply detail, returns dict contains
@@ -423,13 +437,40 @@ class UserNotification(models.Model):
if isinstance(detail, int): # Compatible with existing records
msg_id = detail
reply_from = None
+ return {'msg_id': msg_id, 'reply_from': reply_from}
elif isinstance(detail, dict):
msg_id = detail['msg_id']
reply_from = detail['reply_from']
+ if 'reply_msg' in detail:
+ reply_msg = detail['reply_msg']
+ return {'msg_id': msg_id, 'reply_from': reply_from, 'reply_msg': reply_msg}
+ else:
+ return {'msg_id': msg_id, 'reply_from': reply_from}
else:
raise self.InvalidDetailError, 'Wrong detail format of group message reply'
- return {'msg_id': msg_id, 'reply_from': reply_from}
-
+
+ def user_message_detail_to_dict(self):
+ """Parse user message detail, returns dict contains ``message`` and
+ ``msg_from``.
+
+ Arguments:
+ - `self`:
+
+ Raises ``InvalidDetailError`` if detail field can not be parsed.
+ """
+ assert self.is_user_message()
+
+ try:
+ detail = json.loads(self.detail)
+ except json.JSONDecodeError:
+ msg_from = self.detail
+ message = None
+ return {'message': message, 'msg_from': msg_from}
+ else:
+ message = detail['message']
+ msg_from = detail['msg_from']
+ return {'message': message, 'msg_from': msg_from}
+
########## functions used in templates
def format_file_uploaded_msg(self):
"""
@@ -448,11 +489,12 @@ class UserNotification(models.Model):
folder_link = reverse('repo', args=[repo_id]) + '?p=' + urlquote(uploaded_to)
folder_name = os.path.basename(uploaded_to)
- msg = _(u"A file named %(file_name)s is uploaded to your folder %(folder)s") % {
+ msg = _(u"A file named %(file_name)s is uploaded to your folder %(folder)s") % {
'file_link': file_link,
'file_name': filename,
'folder_link': folder_link,
'folder': folder_name,
+ 'notice_id': self.id,
}
return msg
@@ -471,10 +513,11 @@ class UserNotification(models.Model):
self.delete()
return None
- msg = _(u"%(user)s has shared a library named %(repo_name)s to you.") % {
+ msg = _(u"%(user)s has shared a library named %(repo_name)s to you.") % {
'user': escape(share_from),
'href': reverse('repo', args=[repo.id]),
- 'repo_name': repo.name
+ 'repo_name': repo.name,
+ 'notice_id': self.id,
}
return msg
@@ -489,29 +532,54 @@ class UserNotification(models.Model):
file_name = d['file_name']
priv_share_token = d['priv_share_token']
- msg = _(u"%(user)s has shared a file named %(file_name)s to you.") % {
+ msg = _(u"%(user)s has shared a file named %(file_name)s to you.") % {
'user': escape(share_from),
'href': reverse('view_priv_shared_file', args=[priv_share_token]),
- 'file_name': file_name
+ 'file_name': file_name,
+ 'notice_id': self.id,
}
return msg
-
- def format_user_message(self):
+ def format_user_message_title(self):
"""
-
+
Arguments:
- `self`:
"""
- msg_from = self.detail
+ try:
+ d = self.user_message_detail_to_dict()
+ except self.InvalidDetailError as e:
+ return _(u"Internal error")
+
+ msg_from = d.get('msg_from')
nickname = email2nickname(msg_from)
- msg = _(u"You have received a new message from %(user)s.") % {
+ msg = _(u"You have received a new message from %(user)s.") % {
'user': escape(nickname),
'href': reverse('user_msg_list', args=[msg_from]),
}
return msg
- def format_group_message(self):
+ def format_user_message_detail(self):
+ """
+
+ Arguments:
+ - `self`:
+ """
+ try:
+ d = self.user_message_detail_to_dict()
+ except self.InvalidDetailError as e:
+ return _(u"Internal error")
+
+ message = d.get('message')
+ if message:
+ msg = _(u"
%(message)s") % {
+ 'message': message,
+ }
+ return msg
+ else:
+ return None
+
+ def format_group_message_title(self):
"""
Arguments:
@@ -531,18 +599,37 @@ class UserNotification(models.Model):
msg_from = d.get('msg_from')
if msg_from is None:
- msg = _(u"%(group_name)s has new discussion") % {
+ msg = _(u"%(group_name)s has new discussion.") % {
'href': reverse('group_discuss', args=[group.id]),
'group_name': group.group_name}
else:
- msg = _(u"%(user)s posted a new discussion in %(group_name)s") % {
+ msg = _(u"%(user)s posted a new discussion in %(group_name)s.") % {
'href': reverse('group_discuss', args=[group.id]),
'user': escape(email2nickname(msg_from)),
'group_name': group.group_name}
-
return msg
- def format_grpmsg_reply(self):
+ def format_group_message_detail(self):
+ """
+
+ Arguments:
+ - `self`:
+ """
+ try:
+ d = self.group_message_detail_to_dict()
+ except self.InvalidDetailError as e:
+ return _(u"Internal error")
+
+ message = d.get('message')
+
+ if message:
+ msg = _(u"
%(message)s") % {
+ 'message': message}
+ return msg
+ else:
+ return None
+
+ def format_grpmsg_reply_title(self):
"""
Arguments:
@@ -553,20 +640,39 @@ class UserNotification(models.Model):
except self.InvalidDetailError as e:
return _(u"Internal error")
- msg_id = d.get('msg_id')
reply_from = d.get('reply_from')
if reply_from is None:
- msg = _(u"One group discussion has new reply") % {
+ msg = _(u"One group discussion has new reply.") % {
'href': reverse('msg_reply_new'),
}
else:
- msg = _(u"%(user)s replied your group discussion") % {
+ msg = _(u"%(user)s replied your group discussion.") % {
'user': escape(email2nickname(reply_from)),
- 'href': reverse('msg_reply_new')
+ 'href': reverse('msg_reply_new'),
}
return msg
+ def format_grpmsg_reply_detail(self):
+ """
+
+ Arguments:
+ - `self`:
+ """
+ try:
+ d = self.grpmsg_reply_detail_to_dict()
+ except self.InvalidDetailError as e:
+ return _(u"Internal error")
+
+ reply_msg = d.get('reply_msg')
+
+ if reply_msg:
+ msg = _(u"
%(reply_msg)s") % {
+ 'reply_msg': reply_msg}
+ return msg
+ else:
+ return None
+
def format_group_join_request(self):
"""
@@ -583,13 +689,13 @@ class UserNotification(models.Model):
self.delete()
return None
- nickname = email2nickname(username)
- msg = _(u"User %(username)s has asked to join group %(group_name)s, verification message: %(join_request_msg)s") % {
+ msg = _(u"User %(username)s has asked to join group %(group_name)s, verification message: %(join_request_msg)s") % {
'user_profile': reverse('user_profile', args=[username]),
'username': username,
'href': reverse('group_members', args=[group_id]),
'group_name': group.group_name,
'join_request_msg': escape(join_request_msg),
+ 'notice_id': self.id,
}
return msg
@@ -654,24 +760,28 @@ def add_user_message_cb(sender, **kwargs):
msg = kwargs.get('msg')
msg_from = msg.from_email
msg_to = msg.to_email
+ message = msg.message
+ detail = user_msg_to_json(message, msg_from)
- UserNotification.objects.add_user_message(msg_to, detail=msg_from)
+ UserNotification.objects.add_user_message(msg_to, detail=detail)
@receiver(grpmsg_added)
def grpmsg_added_cb(sender, **kwargs):
group_id = kwargs['group_id']
from_email = kwargs['from_email']
+ message = kwargs['message']
group_members = seaserv.get_group_members(int(group_id))
notify_members = [ x.user_name for x in group_members if x.user_name != from_email ]
- detail = group_msg_to_json(group_id, from_email)
+ detail = group_msg_to_json(group_id, from_email, message)
UserNotification.objects.bulk_add_group_msg_notices(notify_members, detail)
@receiver(grpmsg_reply_added)
def grpmsg_reply_added_cb(sender, **kwargs):
msg_id = kwargs['msg_id']
reply_from_email = kwargs['from_email']
+ reply_msg = kwargs['reply_msg']
try:
group_msg = GroupMessage.objects.get(id=msg_id)
except GroupMessage.DoesNotExist:
@@ -685,7 +795,7 @@ def grpmsg_reply_added_cb(sender, **kwargs):
if x.from_email != reply_from_email])
notice_users.add(group_msg.from_email)
- detail = grpmsg_reply_to_json(msg_id, reply_from_email)
+ detail = grpmsg_reply_to_json(msg_id, reply_from_email, reply_msg)
for user in notice_users:
UserNotification.objects.add_group_msg_reply_notice(to_user=user,
diff --git a/seahub/notifications/templates/notifications/notice_email.html b/seahub/notifications/templates/notifications/notice_email.html
index 3ec1a79fe9..1ec3c7b684 100644
--- a/seahub/notifications/templates/notifications/notice_email.html
+++ b/seahub/notifications/templates/notifications/notice_email.html
@@ -5,7 +5,7 @@
{% block email_con %}
{% autoescape off %}
-
Hi, {{ avatar_url }} {% blocktrans with name=to_user|email2nickname %}{{ name }}{% endblocktrans %}
+Hi, {% blocktrans with name=to_user|email2nickname %}{{ name }}{% endblocktrans %}
{% blocktrans count num=notice_count %} @@ -25,27 +25,27 @@ You've got {{num}} new notices on {{ site_name }}: {% for notice in notices %} {% if notice.is_group_msg %}
{% blocktrans with author=request.user.username %}{{author}} posted a new discussion in seafile{% endblocktrans %}
-@lj 这个是德文站点 http://www.seafile-server.de 看看怎么在我们的 seafile.com 页面上加个链接
-10 hours ago
-{% blocktrans with author=request.user.username %}{{author}} posted a new discussion in seafile{% endblocktrans %}
-@lj 这个是德文站点 http://www.seafile-server.de 看看怎么在我们的 seafile.com 页面上加个链接
-10 hours ago
-{{ notice.format_group_message_title|safe }} + {% if notice.format_group_message_detail %} + {{ notice.format_group_message_detail|safe }} + {% endif %} +
+ + {% elif notice.is_grpmsg_reply %} +{{ notice.format_grpmsg_reply_title|safe }} + {% if notice.format_grpmsg_reply_detail %} + {{ notice.format_grpmsg_reply_detail|safe }} + {% endif %} +
+ + {% elif notice.is_file_uploaded_msg %} +{{ notice.format_file_uploaded_msg|safe }}
+ + {% elif notice.is_repo_share_msg %} +{{ notice.format_repo_share_msg|safe }}
+ + {% elif notice.is_priv_file_share_msg %} +{{ notice.format_priv_file_share_msg|safe }}
+ + {% elif notice.is_user_message %} +{{ notice.format_user_message_title|safe }} + {% if notice.format_user_message_detail %} + {{ notice.format_user_message_detail|safe }} + {% endif %} +
+ + {% elif notice.is_group_join_request %} +{{ notice.format_group_join_request|safe }}
+ + {% endif %} +{{ notice.timestamp|translate_seahub_time }}
+