mirror of
https://github.com/haiwen/seahub.git
synced 2025-04-28 03:10:45 +00:00
optimize notification (#7521)
* update * update --------- Co-authored-by: 孙永强 <11704063+s-yongqiang@user.noreply.gitee.com>
This commit is contained in:
parent
2fb65580e4
commit
3899577631
@ -12,7 +12,7 @@ class Notification extends React.Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
showNotice: false,
|
||||
unseenCount: 0,
|
||||
totalUnseenCount: 0,
|
||||
generalNoticeList: [],
|
||||
discussionNoticeList: [],
|
||||
currentTab: 'general',
|
||||
@ -22,8 +22,11 @@ class Notification extends React.Component {
|
||||
|
||||
componentDidMount() {
|
||||
seafileAPI.listAllNotifications().then(res => {
|
||||
let unseen_count = res.data.general.unseen_count + res.data.discussion.unseen_count;
|
||||
this.setState({ unseenCount: unseen_count });
|
||||
this.setState({
|
||||
totalUnseenCount: res.data.total_unseen_count,
|
||||
generalNoticeListUnseen: res.data.general.unseen_count,
|
||||
discussionNoticeListUnseen: res.data.discussion.unseen_count
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -33,7 +36,7 @@ class Notification extends React.Component {
|
||||
seafileAPI.updateNotifications();
|
||||
this.setState({
|
||||
showNotice: false,
|
||||
unseenCount: 0
|
||||
totalUnseenCount: 0
|
||||
});
|
||||
} else {
|
||||
this.loadNotices();
|
||||
@ -52,13 +55,17 @@ class Notification extends React.Component {
|
||||
|
||||
loadNotices = () => {
|
||||
let page = 1;
|
||||
let perPage = 5;
|
||||
let perPage = 25;
|
||||
seafileAPI.listAllNotifications(page, perPage).then(res => {
|
||||
let generalNoticeList = res.data.general.notification_list;
|
||||
let discussionNoticeList = res.data.discussion.notification_list;
|
||||
let generalNoticeListUnseen = res.data.general.unseen_count;
|
||||
let discussionNoticeListUnseen = res.data.discussion.unseen_count;
|
||||
this.setState({
|
||||
generalNoticeList: generalNoticeList,
|
||||
discussionNoticeList: discussionNoticeList
|
||||
discussionNoticeList: discussionNoticeList,
|
||||
generalNoticeListUnseen: generalNoticeListUnseen,
|
||||
discussionNoticeListUnseen: discussionNoticeListUnseen
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -71,10 +78,12 @@ class Notification extends React.Component {
|
||||
}
|
||||
return item;
|
||||
});
|
||||
let unseenCount = this.state.unseenCount === 0 ? 0 : this.state.unseenCount - 1;
|
||||
let totalUnseenCount = this.state.totalUnseenCount === 0 ? 0 : this.state.totalUnseenCount - 1;
|
||||
let generalNoticeListUnseen = this.state.generalNoticeListUnseen === 0 ? 0 : this.state.generalNoticeListUnseen - 1;
|
||||
this.setState({
|
||||
generalNoticeList: noticeList,
|
||||
unseenCount: unseenCount,
|
||||
totalUnseenCount: totalUnseenCount,
|
||||
generalNoticeListUnseen: generalNoticeListUnseen
|
||||
});
|
||||
seafileAPI.markNoticeAsRead(noticeItem.id);
|
||||
}
|
||||
@ -85,10 +94,12 @@ class Notification extends React.Component {
|
||||
}
|
||||
return item;
|
||||
});
|
||||
let unseenCount = this.state.unseenCount === 0 ? 0 : this.state.unseenCount - 1;
|
||||
let totalUnseenCount = this.state.totalUnseenCount === 0 ? 0 : this.state.totalUnseenCount - 1;
|
||||
let discussionNoticeListUnseen = this.state.discussionNoticeListUnseen === 0 ? 0 : this.state.discussionNoticeListUnseen - 1;
|
||||
this.setState({
|
||||
discussionNoticeList: noticeList,
|
||||
unseenCount: unseenCount,
|
||||
totalUnseenCount: totalUnseenCount,
|
||||
discussionNoticeListUnseen: discussionNoticeListUnseen
|
||||
});
|
||||
seafileAPI.markSdocNoticeAsRead(noticeItem.id);
|
||||
}
|
||||
@ -111,26 +122,62 @@ class Notification extends React.Component {
|
||||
};
|
||||
|
||||
onMarkAllNotifications = () => {
|
||||
seafileAPI.updateAllNotifications().then(() => {
|
||||
this.setState({
|
||||
unseenCount: 0,
|
||||
let generalNoticeListUnseen = this.state.generalNoticeListUnseen;
|
||||
let discussionNoticeListUnseen = this.state.discussionNoticeListUnseen;
|
||||
if (this.state.currentTab === 'general') {
|
||||
seafileAPI.updateNotifications().then((res) => {
|
||||
this.setState({
|
||||
generalNoticeList: this.state.generalNoticeList.map(item => {
|
||||
item.seen = true;
|
||||
return item;
|
||||
}),
|
||||
generalNoticeListUnseen: 0,
|
||||
totalUnseenCount: discussionNoticeListUnseen
|
||||
});
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
|
||||
});
|
||||
});
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
errorMsg: Utils.getErrorMsg(error, true)
|
||||
} else if (this.state.currentTab === 'discussion') {
|
||||
seafileAPI.updateSdocNotifications().then((res) => {
|
||||
this.setState({
|
||||
discussionNoticeList: this.state.discussionNoticeList.map(item => {
|
||||
item.seen = true;
|
||||
return item;
|
||||
}),
|
||||
discussionNoticeListUnseen: 0,
|
||||
totalUnseenCount: generalNoticeListUnseen
|
||||
});
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
errorMsg: Utils.getErrorMsg(error, true) // true: show login tip if 403
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
updateTotalUnseenCount = (noticeType) => {
|
||||
if (noticeType === 'general') {
|
||||
this.setState({
|
||||
generalNoticeListUnseen: 0,
|
||||
totalUnseenCount: this.state.discussionNoticeListUnseen
|
||||
});
|
||||
} else if (noticeType === 'discussion') {
|
||||
this.setState({
|
||||
discussionNoticeListUnseen: 0,
|
||||
totalUnseenCount: this.state.generalNoticeListUnseen
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { unseenCount, currentTab, generalNoticeList, discussionNoticeList } = this.state;
|
||||
const generalNoticeListUnseen = generalNoticeList.filter(item => !item.seen).length;
|
||||
const discussionNoticeListUnseen = discussionNoticeList.filter(item => !item.seen).length;
|
||||
const { totalUnseenCount, currentTab, generalNoticeList, discussionNoticeList, generalNoticeListUnseen, discussionNoticeListUnseen } = this.state;
|
||||
return (
|
||||
<div id="notifications">
|
||||
<a href="#" onClick={this.onClick} className="no-deco" id="notice-icon" title={gettext('Notifications')} aria-label={gettext('Notifications')}>
|
||||
<span className="sf2-icon-bell" id="notification-popover"></span>
|
||||
<span className={`num ${unseenCount ? '' : 'hide'}`}>{unseenCount}</span>
|
||||
<span className={`num ${totalUnseenCount ? '' : 'hide'}`}>{totalUnseenCount}</span>
|
||||
</a>
|
||||
{this.state.showNotice &&
|
||||
<NotificationPopover
|
||||
@ -170,6 +217,7 @@ class Notification extends React.Component {
|
||||
onNotificationDialogToggle={this.onNotificationDialogToggle}
|
||||
generalNoticeListUnseen={generalNoticeListUnseen}
|
||||
discussionNoticeListUnseen={discussionNoticeListUnseen}
|
||||
updateTotalUnseenCount={this.updateTotalUnseenCount}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
@ -101,6 +101,7 @@ class UserNotificationsDialog extends React.Component {
|
||||
return item;
|
||||
})
|
||||
});
|
||||
this.props.updateTotalUnseenCount('general');
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
@ -115,6 +116,7 @@ class UserNotificationsDialog extends React.Component {
|
||||
return item;
|
||||
})
|
||||
});
|
||||
this.props.updateTotalUnseenCount('discussion');
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
@ -131,6 +133,7 @@ class UserNotificationsDialog extends React.Component {
|
||||
this.setState({
|
||||
items: []
|
||||
});
|
||||
this.props.updateTotalUnseenCount('general');
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
@ -142,6 +145,7 @@ class UserNotificationsDialog extends React.Component {
|
||||
this.setState({
|
||||
items: []
|
||||
});
|
||||
this.props.updateTotalUnseenCount('discussion');
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
isLoading: false,
|
||||
|
@ -12,7 +12,6 @@ from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.notifications.models import UserNotification
|
||||
|
||||
from seahub.notifications.models import get_cache_key_of_unseen_notifications
|
||||
from seahub.notifications.utils import update_notice_detail
|
||||
from seahub.utils.timeutils import datetime_to_isoformat_timestr
|
||||
from seahub.api2.utils import api_error
|
||||
|
@ -7,13 +7,11 @@ from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import status
|
||||
|
||||
from django.core.cache import cache
|
||||
|
||||
from seahub.api2.authentication import TokenAuthentication
|
||||
from seahub.api2.throttling import UserRateThrottle
|
||||
from seahub.notifications.models import UserNotification
|
||||
|
||||
from seahub.notifications.models import get_cache_key_of_unseen_notifications
|
||||
from seahub.notifications.utils import update_notice_detail, update_sdoc_notice_detail
|
||||
from seahub.api2.utils import api_error
|
||||
from seahub.seadoc.models import SeadocNotification
|
||||
@ -66,16 +64,8 @@ class NotificationsView(APIView):
|
||||
|
||||
notification_list.append(notice)
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
unseen_count_from_cache = cache.get(cache_key, None)
|
||||
|
||||
# for case of count value is `0`
|
||||
if unseen_count_from_cache is not None:
|
||||
result['unseen_count'] = unseen_count_from_cache
|
||||
else:
|
||||
unseen_count = UserNotification.objects.filter(to_user=username, seen=False).count()
|
||||
result['unseen_count'] = unseen_count
|
||||
cache.set(cache_key, unseen_count)
|
||||
unseen_count = UserNotification.objects.filter(to_user=username, seen=False).count()
|
||||
result['unseen_count'] = unseen_count
|
||||
|
||||
total_count = UserNotification.objects.filter(to_user=username).count()
|
||||
|
||||
@ -98,9 +88,6 @@ class NotificationsView(APIView):
|
||||
notice.seen = True
|
||||
notice.save()
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
cache.delete(cache_key)
|
||||
|
||||
return Response({'success': True})
|
||||
|
||||
def delete(self, request):
|
||||
@ -113,9 +100,6 @@ class NotificationsView(APIView):
|
||||
|
||||
UserNotification.objects.remove_user_notifications(username)
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
cache.delete(cache_key)
|
||||
|
||||
return Response({'success': True})
|
||||
|
||||
|
||||
@ -160,9 +144,6 @@ class NotificationView(APIView):
|
||||
notice.seen = True
|
||||
notice.save()
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
cache.delete(cache_key)
|
||||
|
||||
return Response({'success': True})
|
||||
|
||||
|
||||
@ -310,10 +291,10 @@ class AllNotificationsView(APIView):
|
||||
username = request.user.username
|
||||
|
||||
try:
|
||||
per_page = int(request.GET.get('per_page', ''))
|
||||
page = int(request.GET.get('page', ''))
|
||||
per_page = int(request.GET.get('per_page', '25'))
|
||||
page = int(request.GET.get('page', '1'))
|
||||
except ValueError:
|
||||
per_page = 5
|
||||
per_page = 25
|
||||
page = 1
|
||||
|
||||
if page < 1:
|
||||
@ -353,16 +334,8 @@ class AllNotificationsView(APIView):
|
||||
|
||||
sdoc_notification_list.append(notice)
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
unseen_count_from_cache = cache.get(cache_key, None)
|
||||
|
||||
# for case of count value is `0`
|
||||
if unseen_count_from_cache is not None:
|
||||
result['general']['unseen_count'] = unseen_count_from_cache
|
||||
else:
|
||||
unseen_count = UserNotification.objects.filter(to_user=username, seen=False).count()
|
||||
result['general']['unseen_count'] = unseen_count
|
||||
cache.set(cache_key, unseen_count)
|
||||
unseen_count = UserNotification.objects.filter(to_user=username, seen=False).count()
|
||||
result['general']['unseen_count'] = unseen_count
|
||||
|
||||
sdoc_unseen_count = SeadocNotification.objects.filter(username=username, seen=False).count()
|
||||
result['discussion']['unseen_count'] = sdoc_unseen_count
|
||||
@ -374,6 +347,7 @@ class AllNotificationsView(APIView):
|
||||
result['discussion']['notification_list'] = sdoc_notification_list
|
||||
result['general']['count'] = total_count
|
||||
result['discussion']['count'] = sdoc_total_count
|
||||
result['total_unseen_count'] = result['general']['unseen_count'] + result['discussion']['unseen_count']
|
||||
|
||||
return Response(result)
|
||||
|
||||
@ -394,7 +368,5 @@ class AllNotificationsView(APIView):
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(username)
|
||||
cache.delete(cache_key)
|
||||
|
||||
return Response({'success': True})
|
||||
|
@ -81,7 +81,6 @@ MSG_TYPE_DELETED_FILES = 'deleted_files'
|
||||
MSG_TYPE_SAML_SSO_FAILED = 'saml_sso_failed'
|
||||
MSG_TYPE_FACE_CLUSTER = 'face_cluster'
|
||||
|
||||
USER_NOTIFICATION_COUNT_CACHE_PREFIX = 'USER_NOTIFICATION_COUNT_'
|
||||
|
||||
def file_uploaded_msg_to_json(file_name, repo_id, uploaded_to):
|
||||
"""Encode file uploaded message to json string.
|
||||
@ -156,11 +155,6 @@ def saml_sso_error_msg_to_json(error_msg):
|
||||
return json.dumps({'error_msg': error_msg})
|
||||
|
||||
|
||||
def get_cache_key_of_unseen_notifications(username):
|
||||
return normalize_cache_key(username,
|
||||
USER_NOTIFICATION_COUNT_CACHE_PREFIX)
|
||||
|
||||
|
||||
class UserNotificationManager(models.Manager):
|
||||
def _add_user_notification(self, to_user, msg_type, detail):
|
||||
"""Add generic user notification.
|
||||
@ -174,9 +168,6 @@ class UserNotificationManager(models.Manager):
|
||||
to_user=to_user, msg_type=msg_type, detail=detail)
|
||||
n.save()
|
||||
|
||||
cache_key = get_cache_key_of_unseen_notifications(to_user)
|
||||
cache.delete(cache_key)
|
||||
|
||||
return n
|
||||
|
||||
def get_all_notifications(self, seen=None, time_since=None):
|
||||
|
Loading…
Reference in New Issue
Block a user