diff --git a/frontend/package-lock.json b/frontend/package-lock.json index f506582759..2f365701e4 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15905,9 +15905,9 @@ } }, "seafile-js": { - "version": "0.2.96", - "resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.96.tgz", - "integrity": "sha512-SCZGVo+e8usxrzV6nWX3Qe3LKtpcuxFA78AY9KRbPic5V2ET2c0xmATIpKa2bT7Ji54t8MvVG0mt2D2AiCZ2Sw==", + "version": "0.2.97", + "resolved": "https://registry.npmjs.org/seafile-js/-/seafile-js-0.2.97.tgz", + "integrity": "sha512-a7nlJ4FadqPrsF83GkrKZQem6lQLwm/eDhQc5Ovl5UYw3b1VWz/RARhEO70WKVPtwfmShwKTeRyEZCYVW51edg==", "requires": { "axios": "^0.18.0", "form-data": "^2.3.2", diff --git a/frontend/package.json b/frontend/package.json index b3c935ee10..f90b3277e7 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,7 @@ "react-responsive": "^6.1.1", "react-select": "^2.4.1", "reactstrap": "^6.4.0", - "seafile-js": "^0.2.96", + "seafile-js": "^0.2.97", "socket.io-client": "^2.2.0", "sw-precache-webpack-plugin": "0.11.4", "unified": "^7.0.0", diff --git a/frontend/src/app.js b/frontend/src/app.js index 51afe7d6d2..fe8bec2338 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -76,7 +76,20 @@ class App extends Component { } } + navigateClientUrlToLib = () =>{ + if(window.location.hash && window.location.hash.indexOf('common/lib') != -1){ + let splitUrlArray = window.location.hash.split('/'); + let repoID = splitUrlArray[splitUrlArray.length - 2]; + let url = siteRoot + 'library/' + repoID + '/'; + navigate(url, {repalce: true}); + } + } + componentDidMount() { + // url from client e.g. http://127.0.0.1:8000/#common/lib/34e7fb92-e91d-499d-bcde-c30ea8af9828/ + // navigate to library page http://127.0.0.1:8000/library/34e7fb92-e91d-499d-bcde-c30ea8af9828/ + this.navigateClientUrlToLib(); + // e.g. from http://127.0.0.1:8000/drafts/reviews/ // get reviews // TODO: need refactor later diff --git a/frontend/src/components/cur-dir-path/dir-path.js b/frontend/src/components/cur-dir-path/dir-path.js index d201cbcc5c..ba86066c6d 100644 --- a/frontend/src/components/cur-dir-path/dir-path.js +++ b/frontend/src/components/cur-dir-path/dir-path.js @@ -86,7 +86,7 @@ class DirPath extends React.Component { / )} - {currentPath === '/' ? + {(currentPath === '/' || currentPath === '') ? {repoName}: {repoName} } diff --git a/frontend/src/components/user-settings/user-avatar-form.js b/frontend/src/components/user-settings/user-avatar-form.js index ec766bbd34..b3212e1695 100644 --- a/frontend/src/components/user-settings/user-avatar-form.js +++ b/frontend/src/components/user-settings/user-avatar-form.js @@ -1,5 +1,6 @@ import React from 'react'; import { gettext, siteRoot } from '../../utils/constants'; +import { seafileAPI } from '../../utils/seafile-api'; import toaster from '../toast'; const { avatarURL, csrfToken } = window.app.pageOptions; @@ -50,7 +51,25 @@ class UserAvatarForm extends React.Component { return false; } - this.form.current.submit(); + //this.form.current.submit(); + seafileAPI.updateUserAvatar(file, 160).then((res) => { + this.setState({ + avatarSrc: res.data.avatar_url + }); + toaster.success(gettext('Success')); + }).catch((error) => { + let errorMsg = ''; + if (error.response) { + if (error.response.data && error.response.data['error_msg']) { + errorMsg = error.response.data['error_msg']; + } else { + errorMsg = gettext('Error'); + } + } else { + errorMsg = gettext('Please check the network.'); + } + toaster.danger(errorMsg); + }); } openFileInput = () => { @@ -75,7 +94,7 @@ class UserAvatarForm extends React.Component {
- +
diff --git a/frontend/src/css/pdf-file-view.css b/frontend/src/css/pdf-file-view.css index ad9cc34cac..82b46bdf99 100644 --- a/frontend/src/css/pdf-file-view.css +++ b/frontend/src/css/pdf-file-view.css @@ -86,6 +86,30 @@ background: #ff0; box-shadow: 0px 2px 10px #ff0; } + +.annotationLayer .textAnnotation img { + position: absolute; + cursor: pointer; +} + +.annotationLayer .popupWrapper { + position: absolute; + width: 20em; +} + +.annotationLayer .popup { + position: absolute; + z-index: 200; + max-width: 20em; + background-color: #FFFF99; + box-shadow: 0px 2px 5px #333; + border-radius: 2px; + padding: 0.6em; + margin-left: 5px; + cursor: pointer; + font: message-box; + word-wrap: break-word; +} /* annotationLayer ends */ #fileInput { display:none; diff --git a/frontend/src/models/group.js b/frontend/src/models/group.js index c0dab049c4..9bc59c5c7c 100644 --- a/frontend/src/models/group.js +++ b/frontend/src/models/group.js @@ -9,6 +9,8 @@ class Group { this.parent_group_id = object.parent_group_id; this.wiki_enabled = object.wiki_enabled; this.repos = object.repos || []; + this.group_quota = object.group_quota; + this.group_quota_usage = object.group_quota_usage; } } diff --git a/frontend/src/pages/groups/group-view.js b/frontend/src/pages/groups/group-view.js index 840b327823..4b51917ce8 100644 --- a/frontend/src/pages/groups/group-view.js +++ b/frontend/src/pages/groups/group-view.js @@ -388,7 +388,10 @@ class GroupView extends React.Component { / {currentGroup.name} {currentGroup.parent_group_id !== 0 && ( - + + + {' '}{'('}{gettext('Used:')}{' '}{Utils.bytesToSize(currentGroup.group_quota_usage)}{'/'}{Utils.bytesToSize(currentGroup.group_quota)}{')'} + )}
diff --git a/frontend/src/view-file-image.js b/frontend/src/view-file-image.js index ed6c2dcf36..86a26ca8f9 100644 --- a/frontend/src/view-file-image.js +++ b/frontend/src/view-file-image.js @@ -9,7 +9,7 @@ import './css/image-file-view.css'; const { repoID, filePath, err, - fileName, previousImage, nextImage, rawPath + fileName, previousImage, nextImage, rawPath, thumbnailSizeForOriginal, } = window.app.pageOptions; let previousImageUrl, nextImageUrl; @@ -30,6 +30,14 @@ class ViewFileImage extends React.Component { class FileContent extends React.Component { + constructor(props) { + super(props); + this.state = { + thumbnailError: false, + }; + this.thumbnailSuffixList = ['tiff', 'eps', 'psd']; + } + componentDidMount() { document.addEventListener('keydown', (e) => { if (previousImage && e.keyCode == 37) { // press '<-' @@ -41,10 +49,20 @@ class FileContent extends React.Component { }); } + handleError = () => { + this.setState({ + thumbnailError: true + }); + }; + render() { - if (err) { + if (err || this.state.thumbnailError) { return ; } + let thumbnailUrl = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${Utils.encodePath(filePath)}`; + let imageSuffix = fileName.split('.').pop(); + let isPreviewThumbnail = this.thumbnailSuffixList.includes(imageSuffix); + return (
{previousImage && ( @@ -53,7 +71,10 @@ class FileContent extends React.Component { {nextImage && ( )} - {fileName} + {isPreviewThumbnail ? + {fileName} : + {fileName} + }
); } diff --git a/media/js/pdf/images/annotation-noicon.svg b/media/js/pdf/images/annotation-noicon.svg new file mode 100644 index 0000000000..c07d108083 --- /dev/null +++ b/media/js/pdf/images/annotation-noicon.svg @@ -0,0 +1,7 @@ + + + diff --git a/media/js/pdf/viewer.js b/media/js/pdf/viewer.js index cbc6b47ff4..1769ec17b8 100644 --- a/media/js/pdf/viewer.js +++ b/media/js/pdf/viewer.js @@ -4395,7 +4395,7 @@ var defaultOptions = { kind: OptionKind.VIEWER }, imageResourcesPath: { - value: './images/', + value: sf_pdf_images_path, kind: OptionKind.VIEWER }, maxCanvasPixels: { diff --git a/seahub/api2/endpoints/groups.py b/seahub/api2/endpoints/groups.py index 5e2ddc6f78..4251bddc56 100644 --- a/seahub/api2/endpoints/groups.py +++ b/seahub/api2/endpoints/groups.py @@ -68,6 +68,12 @@ def get_group_info(request, group_id, avatar_size=GROUP_AVATAR_DEFAULT_SIZE): "admins": get_group_admins(group.id), "wiki_enabled": is_wiki_mod_enabled_for_group(group_id) } + # parent_group_id = 0: non department group + # parent_group_id = -1: top department group + # parent_group_id = n(n > 0): sub department group, n is parent group's id + if group.parent_group_id != 0: + group_info['group_quota'] = seafile_api.get_group_quota(group_id) + group_info['group_quota_usage'] = seafile_api.get_group_quota_usage(group_id) return group_info diff --git a/seahub/api2/endpoints/user_avatar.py b/seahub/api2/endpoints/user_avatar.py index f0a3f896e3..053a0bb3e2 100644 --- a/seahub/api2/endpoints/user_avatar.py +++ b/seahub/api2/endpoints/user_avatar.py @@ -2,6 +2,7 @@ import os import logging +from rest_framework.authentication import SessionAuthentication from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView @@ -23,7 +24,7 @@ from seahub.avatar.templatetags.avatar_tags import api_avatar_url logger = logging.getLogger(__name__) class UserAvatarView(APIView): - authentication_classes = (TokenAuthentication,) + authentication_classes = (TokenAuthentication, SessionAuthentication) permission_classes = (IsAuthenticated,) throttle_classes = (UserRateThrottle,) diff --git a/seahub/templates/document_file_view_react.html b/seahub/templates/document_file_view_react.html index 0b31a7faa4..5b9ab67a26 100644 --- a/seahub/templates/document_file_view_react.html +++ b/seahub/templates/document_file_view_react.html @@ -17,6 +17,7 @@ var commit_id = '{{ current_commit.id }}' || '{{ repo.head_cmmt_id }}'; var sf_file_url = '{{ SITE_ROOT }}office-convert/static/{{ repo.id }}/' + commit_id + '{{ path|urlencode }}/fake.pdf'; var sf_pdfworkerjs_url = '{{MEDIA_URL}}js/pdf/pdf.worker.min.js'; +var sf_pdf_images_path = '{{MEDIA_URL}}js/pdf/images/'; {% endblock %} diff --git a/seahub/templates/file_view_react.html b/seahub/templates/file_view_react.html index c004dd5b2b..7cb21f5223 100644 --- a/seahub/templates/file_view_react.html +++ b/seahub/templates/file_view_react.html @@ -16,6 +16,7 @@ window.app.pageOptions = { shareLinkExpireDaysDefault: {{ share_link_expire_days_default }}, shareLinkExpireDaysMin: {{ share_link_expire_days_min }}, shareLinkExpireDaysMax: {{ share_link_expire_days_max }}, + thumbnailSizeForOriginal: {{ thumbnail_size_for_original }}, // for all types of files fileName: '{{ filename|escapejs }}', diff --git a/seahub/templates/history_file_view_react.html b/seahub/templates/history_file_view_react.html index 5652c4c98c..b4449b5414 100644 --- a/seahub/templates/history_file_view_react.html +++ b/seahub/templates/history_file_view_react.html @@ -40,6 +40,7 @@ window.app.pageOptions = { diff --git a/seahub/templates/pdf_file_view_react.html b/seahub/templates/pdf_file_view_react.html index f12324b0ea..156373e9d3 100644 --- a/seahub/templates/pdf_file_view_react.html +++ b/seahub/templates/pdf_file_view_react.html @@ -16,6 +16,7 @@ diff --git a/seahub/templates/shared_file_view_react.html b/seahub/templates/shared_file_view_react.html index b03c7be612..62f2812e5d 100644 --- a/seahub/templates/shared_file_view_react.html +++ b/seahub/templates/shared_file_view_react.html @@ -93,6 +93,7 @@ @@ -102,6 +103,7 @@ var commit_id = '{{ current_commit.id }}' || '{{ repo.head_cmmt_id }}'; var sf_file_url = '{{ SITE_ROOT }}office-convert/static/{{ repo.id }}/' + commit_id + '{{ path|urlencode }}/fake.pdf?token={{shared_token}}'; var sf_pdfworkerjs_url = '{{MEDIA_URL}}js/pdf/pdf.worker.min.js'; + var sf_pdf_images_path = '{{MEDIA_URL}}js/pdf/images/'; {% elif filetype == 'SpreadSheet' %} diff --git a/seahub/templates/snippets/document_file_viewer.html b/seahub/templates/snippets/document_file_viewer.html index 6a78a60a68..026f29c782 100644 --- a/seahub/templates/snippets/document_file_viewer.html +++ b/seahub/templates/snippets/document_file_viewer.html @@ -62,6 +62,7 @@ OfficePreviewer.prototype.check_status = function() { var commit_id = '{{ current_commit.id }}' || '{{ repo.head_cmmt_id }}'; var sf_file_url = '{{ SITE_ROOT }}office-convert/static/{{ repo.id }}/' + commit_id + '{{ path|urlencode }}/fake.pdf?token={{shared_token}}'; var sf_pdfworkerjs_url = '{{MEDIA_URL}}js/pdf/pdf.worker.min.js'; +var sf_pdf_images_path = '{{MEDIA_URL}}js/pdf/images/'; OfficePreviewer.prototype.load_page = function() { $.getScript('{{MEDIA_URL}}js/pdf/viewer.js'); }; diff --git a/seahub/templates/snippets/file_view_js.html b/seahub/templates/snippets/file_view_js.html index d469a19a12..8d01eb209c 100644 --- a/seahub/templates/snippets/file_view_js.html +++ b/seahub/templates/snippets/file_view_js.html @@ -10,6 +10,7 @@ diff --git a/seahub/templates/view_file_pdf.html b/seahub/templates/view_file_pdf.html index 28433beafd..eeba74de05 100644 --- a/seahub/templates/view_file_pdf.html +++ b/seahub/templates/view_file_pdf.html @@ -18,6 +18,7 @@ diff --git a/seahub/urls.py b/seahub/urls.py index 7ffd709d3a..067f92c10e 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -226,6 +226,7 @@ urlpatterns = [ url(r'^my-libs/$', react_fake_view, name="my_libs"), url(r'^groups/$', react_fake_view, name="groups"), url(r'^group/(?P\d+)/$', react_fake_view, name="group"), + url(r'^library/(?P[-0-9a-f]{36})/$', react_fake_view, name="library_view"), url(r'^library/(?P[-0-9a-f]{36})/(?P[^/]+)/(?P.*)$', react_fake_view, name="lib_view"), url(r'^my-libs/deleted/$', react_fake_view, name="my_libs_deleted"), url(r'^org/$', react_fake_view, name="org"), diff --git a/seahub/views/file.py b/seahub/views/file.py index c98ac00b60..6f21bbd27f 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -531,6 +531,7 @@ def view_lib_file(request, repo_id, path): 'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX, 'can_download_file': parse_repo_perm(permission).can_download, 'seafile_collab_server': SEAFILE_COLLAB_SERVER, + 'thumbnail_size_for_original': settings.THUMBNAIL_SIZE_FOR_ORIGINAL, } # check whether file is starred