1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-18 00:00:00 +00:00
This commit is contained in:
孙永强
2024-11-21 17:11:02 +08:00
parent 27dcce694b
commit 0f77313761
8 changed files with 163 additions and 54 deletions

View File

@@ -4,6 +4,7 @@ import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { gettext, siteRoot } from '../../utils/constants';
import { Utils } from '../../utils/utils';
import { processor } from '@seafile/seafile-editor';
const propTypes = {
noticeItem: PropTypes.object.isRequired,
@@ -35,7 +36,7 @@ class NoticeItem extends React.Component {
let noticeItem = this.props.noticeItem;
let noticeType = noticeItem.type;
let detail = noticeItem.detail;
console.log(detail, noticeItem, noticeType)
if (noticeType === MSG_TYPE_ADD_USER_TO_GROUP) {
let avatar_url = detail.group_staff_avatar_url;
@@ -378,19 +379,23 @@ class NoticeItem extends React.Component {
}
if (noticeType === MSG_TYPE_SEADOC_COMMENT) {
let avatar_url = detail.share_from_user_avatar_url;
let notice = '';
console.log(111)
notice = Utils.HTMLescape(notice);
return { avatar_url, notice };
let avatar_url = detail.avatar_url;
let notice = detail.comment;
let username = detail.user_name;
processor.process(notice, (error, vfile) => {
notice = String(vfile);
});
return { avatar_url, username, notice };
}
if (noticeType === MSG_TYPE_SEADOC_REPLY) {
let avatar_url = detail.share_from_user_avatar_url;
let avatar_url = detail.avatar_url;
let notice = detail.reply;
notice = Utils.HTMLescape(notice);
console.log(notice)
return { avatar_url, notice };
let username = detail.user_name;
processor.process(notice, (error, vfile) => {
notice = String(vfile);
});
return { avatar_url, username, notice };
}
// if (noticeType === MSG_TYPE_GUEST_INVITATION_ACCEPTED) {
@@ -410,8 +415,7 @@ class NoticeItem extends React.Component {
render() {
let noticeItem = this.props.noticeItem;
let { avatar_url, notice } = this.generatorNoticeInfo();
let { avatar_url, username, notice } = this.generatorNoticeInfo();
if (!avatar_url && !notice) {
return '';
}
@@ -432,9 +436,14 @@ class NoticeItem extends React.Component {
<li onClick={this.onNoticeItemClick} className={noticeItem.seen ? 'read' : 'unread'}>
<div className="notice-item">
<div className="main-info">
<div className="auther-info">
<img src={avatar_url} width="32" height="32" className="avatar" alt=""/>
<p>{username}</p>
</div>
<div>
<p className="brief" dangerouslySetInnerHTML={{ __html: notice }}></p>
</div>
</div>
<p className="time">{dayjs(noticeItem.time).fromNow()}</p>
</div>
</li>

View File

@@ -82,12 +82,11 @@ export default class NotificationPopover extends React.Component {
<li className="nav-item" onClick={() => this.tabItemClick('discussion')}>
<span className={`nav-link ${currentTab === 'discussion' ? 'active' : ''}`}>
{gettext('Discussion')}
</span>
</li>
</ul>
<span className="mark-all-read" onClick={this.onMarkAllNotifications}>
{gettext('Mark all as read')}
<span className="mark-all-read" onClick={this.props.onMarkAllNotifications}>
{bodyText}
</span>
</div>
{currentTab === 'general' &&

View File

@@ -62,7 +62,6 @@ class Notification extends React.Component {
if (this.state.currentTab === 'discussion') {
seafileAPI.listSdocNotifications(page, perPage).then(res => {
let noticeList = res.data.notification_list;
console.log(noticeList)
this.setState({ noticeList: noticeList });
});
}
@@ -76,7 +75,14 @@ class Notification extends React.Component {
}
return item;
});
if (this.state.currentTab === 'general') {
seafileAPI.markNoticeAsRead(noticeItem.id);
}
if (this.state.currentTab === 'discussion') {
seafileAPI.markSdocNoticeAsRead(noticeItem.id);
}
let unseenCount = this.state.unseenCount === 0 ? 0 : this.state.unseenCount - 1;
this.setState({
noticeList: noticeList,

View File

@@ -1475,6 +1475,11 @@ class SeafileAPI {
return this.req.put(url);
}
updateSdocNotifications() {
const url = this.server + '/api/v2.1/sdoc-notifications/';
return this.req.put(url);
}
deleteNotifications() {
const url = this.server + '/api/v2.1/notifications/';
return this.req.delete(url);
@@ -1492,6 +1497,13 @@ class SeafileAPI {
return this.req.put(url, from);
}
markSdocNoticeAsRead(noticeId) {
const url = this.server + '/api/v2.1/sdoc-notification/';
let from = new FormData();
from.append('notice_id', noticeId);
return this.req.put(url, from);
}
// ---- Linked Devices API
listLinkedDevices() {
const url = this.server + '/api2/devices/';

View File

@@ -13,6 +13,7 @@ from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.notifications.models import UserNotification
from seahub.seadoc.models import get_cache_key_of_unseen_sdoc_notifications
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
@@ -166,18 +167,13 @@ class NotificationView(APIView):
return Response({'success': True})
class SdocNotificationView(APIView):
class SdocNotificationsView(APIView):
def get(self, request):
""" used for get sdoc notifications
Permission checking:
1. login user.
"""
notice_type = request.GET.get('type', 'general')
if notice_type not in NOTIF_TYPE:
error_msg = 'notice_type invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
result = {}
username = request.user.username
@@ -205,7 +201,7 @@ class SdocNotificationView(APIView):
notice['seen'] = i.seen
notification_list.append(notice)
cache_key = get_cache_key_of_unseen_notifications(username)
cache_key = get_cache_key_of_unseen_sdoc_notifications(username)
unseen_count_from_cache = cache.get(cache_key, None)
# for case of count value is `0`
@@ -222,3 +218,69 @@ class SdocNotificationView(APIView):
result['count'] = total_count
return Response(result)
def put(self, request):
""" currently only used for mark all notifications seen
Permission checking:
1. login user.
"""
username = request.user.username
unseen_notices = SeadocNotification.objects.filter(username, seen=False)
for notice in unseen_notices:
notice.seen = True
notice.save()
cache_key = get_cache_key_of_unseen_sdoc_notifications(username)
cache.delete(cache_key)
return Response({'success': True})
class SdocNotificationView(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle,)
def put(self, request):
""" currently only used for mark a sdoc notification seen
Permission checking:
1. login user.
"""
notice_id = request.data.get('notice_id')
# argument check
try:
int(notice_id)
except Exception as e:
error_msg = 'notice_id invalid.'
logger.error(e)
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
# resource check
try:
notice = SeadocNotification.objects.get(id=notice_id)
except SeadocNotification.DoesNotExist as e:
logger.error(e)
error_msg = 'Notification %s not found.' % notice_id
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# permission check
username = request.user.username
if notice.username != username:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if not notice.seen:
notice.seen = True
notice.save()
cache_key = get_cache_key_of_unseen_sdoc_notifications(username)
cache.delete(cache_key)
return Response({'success': True})

View File

@@ -2,6 +2,7 @@
import os
import json
import logging
import posixpath
from django.core.cache import cache
from django.utils.html import escape
from django.utils.translation import gettext as _
@@ -10,6 +11,7 @@ from seaserv import ccnet_api, seafile_api
from seahub.constants import CUSTOM_PERMISSION_PREFIX
from seahub.notifications.models import Notification
from seahub.tags.models import FileUUIDMap
from seahub.notifications.settings import NOTIFICATION_CACHE_TIMEOUT
from seahub.avatar.templatetags.avatar_tags import api_avatar_url
from seahub.base.templatetags.seahub_tags import email2nickname, email2contact_email
@@ -403,17 +405,30 @@ def update_notice_detail(request, notices):
def update_sdoc_notice_detail(request, notices):
repo_dict = {}
for notice in notices:
if notice.is_comment():
try:
d = json.loads(notice.detail)
uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(notice.doc_uuid)
origin_file_path = posixpath.join(uuid.parent_path, uuid.filename)
url, _, _ = api_avatar_url(d['author'])
d['avatar_url'] = url
d['sdoc_path'] = origin_file_path
d['sdoc_name'] = uuid.filename
d['repo_id'] = uuid.repo_id
notice.detail = d
except Exception as e:
logger.error(e)
elif notice.is_reply():
try:
d = json.loads(notice.detail)
uuid = FileUUIDMap.objects.get_fileuuidmap_by_uuid(notice.doc_uuid)
origin_file_path = posixpath.join(uuid.parent_path, uuid.filename)
url, _, _ = api_avatar_url(d['author'])
d['avatar_url'] = url
d['sdoc_path'] = origin_file_path
d['sdoc_name'] = uuid.filename
d['repo_id'] = uuid.repo_id
notice.detail = d
except Exception as e:
logger.error(e)

View File

@@ -7,7 +7,7 @@ from django.db import models
from seahub.utils.timeutils import datetime_to_isoformat_timestr
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.seadoc.settings import SDOC_REVISIONS_DIR
from seahub.utils import normalize_cache_key
class SeadocHistoryNameManager(models.Manager):
def update_name(self, doc_uuid, obj_id, name):
@@ -251,6 +251,11 @@ class SeadocCommentReply(models.Model):
### sdoc notification
MSG_TYPE_REPLY = 'reply'
MSG_TYPE_COMMENT = 'comment'
SDOC_NOTIFICATION_COUNT_CACHE_PREFIX = 'SDOC_NOTIFICATION_COUNT_'
def get_cache_key_of_unseen_sdoc_notifications(username):
return normalize_cache_key(username,
SDOC_NOTIFICATION_COUNT_CACHE_PREFIX)
class SeadocNotificationManager(models.Manager):
def total_count(self, doc_uuid, username):

View File

@@ -91,7 +91,7 @@ from seahub.api2.endpoints.invitations import InvitationsView, InvitationsBatchV
from seahub.api2.endpoints.invitation import InvitationView, InvitationRevokeView
from seahub.api2.endpoints.repo_share_invitations import RepoShareInvitationsView, RepoShareInvitationsBatchView
from seahub.api2.endpoints.repo_share_invitation import RepoShareInvitationView
from seahub.api2.endpoints.notifications import NotificationsView, NotificationView, SdocNotificationView
from seahub.api2.endpoints.notifications import NotificationsView, NotificationView, SdocNotificationView, SdocNotificationsView
from seahub.api2.endpoints.repo_file_uploaded_bytes import RepoFileUploadedBytesView
from seahub.api2.endpoints.user_avatar import UserAvatarView
from seahub.api2.endpoints.wikis import WikisView, WikiView
@@ -522,7 +522,8 @@ urlpatterns = [
re_path(r'^api/v2.1/notifications/$', NotificationsView.as_view(), name='api-v2.1-notifications'),
re_path(r'^api/v2.1/notification/$', NotificationView.as_view(), name='api-v2.1-notification'),
re_path(r'^api/v2.1/sdoc-notifications/$', SdocNotificationView.as_view(), name='api-v2.1-sdoc-notifications'),
re_path(r'^api/v2.1/sdoc-notifications/$', SdocNotificationsView.as_view(), name='api-v2.1-sdoc-notifications'),
re_path(r'^api/v2.1/sdoc-notification/$', SdocNotificationView.as_view(), name='api-v2.1-notification'),
## user::invitations
re_path(r'^api/v2.1/invitations/$', InvitationsView.as_view()),