mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-03 07:55:36 +00:00
Init view text (#2936)
* init view file text * [add] view text frontend page * add some variables * add btn groups * fix code reviews
This commit is contained in:
@@ -94,6 +94,11 @@ module.exports = {
|
|||||||
require.resolve('react-dev-utils/webpackHotDevClient'),
|
require.resolve('react-dev-utils/webpackHotDevClient'),
|
||||||
paths.appSrc + "/shared-file-view-text.js",
|
paths.appSrc + "/shared-file-view-text.js",
|
||||||
],
|
],
|
||||||
|
viewFileText: [
|
||||||
|
require.resolve('./polyfills'),
|
||||||
|
require.resolve('react-dev-utils/webpackHotDevClient'),
|
||||||
|
paths.appSrc + "/view-file-text.js",
|
||||||
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
output: {
|
output: {
|
||||||
|
83
frontend/src/css/view-file-text.css
Normal file
83
frontend/src/css/view-file-text.css
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
#root {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view-header {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 15px;
|
||||||
|
border-bottom: 1px solid #c9c9c9;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view-body {
|
||||||
|
height: calc(100% - 60px);
|
||||||
|
width: 100%;
|
||||||
|
background: #f4f4f4;
|
||||||
|
border: 1px solid #ededed;
|
||||||
|
overflow: auto;
|
||||||
|
flex: auto;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view-body .txt-view {
|
||||||
|
min-height: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 950px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view-body .txt-view .CodeMirror,
|
||||||
|
.txt-file-view-body .txt-view-comment .CodeMirror {
|
||||||
|
box-shadow: 0 0 6px #ccc;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
height: auto;
|
||||||
|
min-height: 400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
line-height: 1.5em;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.txt-file-view-body .txt-view .CodeMirror-scroll {
|
||||||
|
min-height: 400px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-enc-cont {
|
||||||
|
width: 950px;
|
||||||
|
height: 24px;
|
||||||
|
margin: 10px auto;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-title {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-state {
|
||||||
|
font-size: 13px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-title .file-internal-link,
|
||||||
|
.file-title .file-star {
|
||||||
|
font-size: .875rem;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: .5rem;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-internal-link {
|
||||||
|
color: #585858;
|
||||||
|
}
|
316
frontend/src/view-file-text.js
Normal file
316
frontend/src/view-file-text.js
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import ReactDOM from 'react-dom';
|
||||||
|
import CodeMirror from 'react-codemirror';
|
||||||
|
import moment from 'moment';
|
||||||
|
import watermark from 'watermark-dom';
|
||||||
|
import { ButtonGroup, Tooltip } from 'reactstrap';
|
||||||
|
import { seafileAPI } from './utils/seafile-api';
|
||||||
|
import { Utils } from './utils/utils';
|
||||||
|
import { serviceURL, gettext, mediaUrl } from './utils/constants';
|
||||||
|
import InternalLinkDialog from './components/dialog/internal-link-dialog';
|
||||||
|
import 'codemirror/lib/codemirror.css';
|
||||||
|
import 'codemirror/mode/javascript/javascript';
|
||||||
|
import 'codemirror/mode/css/css';
|
||||||
|
import 'codemirror/mode/clike/clike';
|
||||||
|
import 'codemirror/mode/php/php';
|
||||||
|
import 'codemirror/mode/sql/sql';
|
||||||
|
import 'codemirror/mode/vue/vue';
|
||||||
|
import 'codemirror/mode/xml/xml';
|
||||||
|
import 'codemirror/mode/go/go';
|
||||||
|
import 'codemirror/mode/python/python';
|
||||||
|
import 'codemirror/mode/htmlmixed/htmlmixed';
|
||||||
|
import './assets/css/fa-solid.css';
|
||||||
|
import './assets/css/fa-regular.css';
|
||||||
|
import './assets/css/fontawesome.css';
|
||||||
|
import './css/view-file-text.css';
|
||||||
|
|
||||||
|
const { isPro, repoID, repoName, filePath, fileName, siteName, enableWatermark, encoding, fileEncodingList, fileExt, isLocked, fileContent, latestContributor, lastModified, isStarred } = window.app.pageOptions;
|
||||||
|
const options = {
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: Utils.chooseLanguage(fileExt.slice(3, fileExt.length -3)),
|
||||||
|
extraKeys: {'Ctrl': 'autocomplete'},
|
||||||
|
theme: 'default',
|
||||||
|
autoMatchParens: true,
|
||||||
|
textWrapping: true,
|
||||||
|
lineWrapping: true,
|
||||||
|
readOnly: 'nocursor',
|
||||||
|
};
|
||||||
|
|
||||||
|
class ViewFileText extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
isLocked: isLocked,
|
||||||
|
star: isStarred,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
changeEncode = (e) => {
|
||||||
|
window.location.href = serviceURL + '/lib/' + repoID + '/file/' + fileName +'/?file_enc=' + e.target.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileEncode = () => {
|
||||||
|
const list = fileEncodingList.substring(1, fileEncodingList.length - 1).replace(/\'*/g,'').replace(/\s*/g,'').split(',');
|
||||||
|
return (
|
||||||
|
<div className="file-enc-cont">
|
||||||
|
<label htmlFor="file-enc">{gettext('Encoding:')}</label>
|
||||||
|
<select id="file-enc" onChange={this.changeEncode} defaultValue={encoding}>
|
||||||
|
{ list && list.map((value, index) => {
|
||||||
|
if (value === 'auto') {
|
||||||
|
return (<option value={value} key={index}>{gettext('auto detect')}</option>);
|
||||||
|
} else {
|
||||||
|
return (<option value={value} key={index}>{value}</option>);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMouseDown = (option) => {
|
||||||
|
switch(option) {
|
||||||
|
case 'back':
|
||||||
|
window.location.href = serviceURL + '/library/' + repoID + '/' + repoName + '/';
|
||||||
|
break;
|
||||||
|
case 'lock':
|
||||||
|
this.toggleLockFile();
|
||||||
|
break;
|
||||||
|
case 'history':
|
||||||
|
window.location.href = serviceURL + '/repo/file_revisions/' + repoID + '/?p=' + filePath;
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
window.location.href = serviceURL + '/repo/' + repoID + '/file/edit/?p=' + filePath + '&file_enc=' + encoding;
|
||||||
|
break;
|
||||||
|
case 'download':
|
||||||
|
window.location.href = serviceURL + '/lib/' + repoID + '/file/' + filePath +'?dl=1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderToolbar() {
|
||||||
|
return (
|
||||||
|
<div className="txt-view-button-group" role="group">
|
||||||
|
<ButtonGroup>
|
||||||
|
<IconButton
|
||||||
|
text={gettext('Back to parent directory')}
|
||||||
|
id={'parentDirectory'}
|
||||||
|
icon={'fa fa-folder-open'}
|
||||||
|
onMouseDown={() => this.handleMouseDown('back')}
|
||||||
|
/>
|
||||||
|
{isPro === 'True' &&
|
||||||
|
<IconButton
|
||||||
|
id={'lockButton'}
|
||||||
|
text={gettext('Lock File')}
|
||||||
|
onMouseDown={() => this.handleMouseDown('lock')}
|
||||||
|
icon={'fa fa-lock'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{isPro === 'True' &&
|
||||||
|
<IconButton
|
||||||
|
id={'historyButton'}
|
||||||
|
text={gettext('File History')}
|
||||||
|
onMouseDown={() => this.handleMouseDown('history')}
|
||||||
|
icon={'fa fa-history'}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
<IconButton
|
||||||
|
id={'shareBtn'}
|
||||||
|
text={gettext('Edit')}
|
||||||
|
icon={'fa fa-edit'}
|
||||||
|
onMouseDown={() => this.handleMouseDown('edit')}
|
||||||
|
/>
|
||||||
|
<IconButton
|
||||||
|
id={'downloadButton'}
|
||||||
|
text={gettext('Download File')}
|
||||||
|
onMouseDown={() => this.handleMouseDown('download')}
|
||||||
|
icon={'fa fa-download'}
|
||||||
|
/>
|
||||||
|
{/*
|
||||||
|
<IconButton
|
||||||
|
id={'commentButton'}
|
||||||
|
text={gettext('Comment')}
|
||||||
|
onMouseDown={() => this.handleMouseDown('comment')}
|
||||||
|
icon={'sf-btn-group-btn op-icon sf2-icon-msgs sf-btn-group-btn-last'}
|
||||||
|
/>
|
||||||
|
*/}
|
||||||
|
</ButtonGroup>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleStar = () => {
|
||||||
|
if (this.state.star) {
|
||||||
|
seafileAPI.unStarFile(repoID, filePath).then((res) => {
|
||||||
|
if (res.data === 'success') {
|
||||||
|
this.setState({
|
||||||
|
star: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
seafileAPI.starFile(repoID, filePath).then((res) => {
|
||||||
|
if (res.data === 'success') {
|
||||||
|
this.setState({
|
||||||
|
star: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleLockFile = () => {
|
||||||
|
if (this.state.isLocked) {
|
||||||
|
seafileAPI.unlockfile(repoID, filePath).then((res) => {
|
||||||
|
this.setState({
|
||||||
|
isLocked: res.data.is_locked
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
seafileAPI.lockfile(repoID, filePath).then((res) => {
|
||||||
|
this.setState({
|
||||||
|
isLocked: res.data.is_locked
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="txt-file-view d-flex">
|
||||||
|
<div className="txt-file-view-header d-flex">
|
||||||
|
<FileInfo
|
||||||
|
toggleStar={this.toggleStar}
|
||||||
|
star={this.state.star}
|
||||||
|
serviceURL={serviceURL}
|
||||||
|
isLocked={this.state.isLocked}
|
||||||
|
/>
|
||||||
|
{this.renderToolbar()}
|
||||||
|
</div>
|
||||||
|
<div className="txt-file-view-body d-flex">
|
||||||
|
{this.fileEncode()}
|
||||||
|
<div className={'txt-view'}>
|
||||||
|
<CodeMirror
|
||||||
|
ref="code-mirror-editor"
|
||||||
|
value={fileContent}
|
||||||
|
options={options}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const IconButtonPropTypes = {
|
||||||
|
icon: PropTypes.string,
|
||||||
|
id: PropTypes.string,
|
||||||
|
onMouseDown: PropTypes.func,
|
||||||
|
isActive: PropTypes.bool,
|
||||||
|
disabled: PropTypes.bool,
|
||||||
|
text: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
class IconButton extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
tooltipOpen: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle = () => {
|
||||||
|
this.setState({
|
||||||
|
tooltipOpen: !this.state.tooltipOpen
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let className = 'btn btn-icon btn-secondary btn-active';
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
id={this.props.id}
|
||||||
|
type={'button'}
|
||||||
|
onMouseDown={this.props.onMouseDown}
|
||||||
|
className={className}
|
||||||
|
data-active={ this.props.isActive || false }>
|
||||||
|
<i className={this.props.icon}/>
|
||||||
|
<Tooltip
|
||||||
|
toggle={this.toggle}
|
||||||
|
delay={{show: 0, hide: 0}}
|
||||||
|
target={this.props.id}
|
||||||
|
placement='bottom'
|
||||||
|
isOpen={this.state.tooltipOpen}>
|
||||||
|
{this.props.text}
|
||||||
|
</Tooltip>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton.propTypes = IconButtonPropTypes;
|
||||||
|
|
||||||
|
const FileInfoPropTypes = {
|
||||||
|
serviceURL: PropTypes.string.isRequired,
|
||||||
|
toggleStar: PropTypes.func.isRequired,
|
||||||
|
isLocked: PropTypes.bool,
|
||||||
|
star: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileInfo extends React.PureComponent {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let modifyTime = moment(lastModified * 1000).format('YYYY-MM-DD HH:mm');
|
||||||
|
const modifierUrl = this.props.serviceURL + '/profile/' + latestContributor + '/';
|
||||||
|
return (
|
||||||
|
<div className={'file-info-wrapper'}>
|
||||||
|
<div className="topbar-file-info">
|
||||||
|
<h2 className="file-title d-flex">
|
||||||
|
<span className='file-name'>{fileName}</span>
|
||||||
|
<span className='file-star' title={this.props.star ? 'unstar' : 'star'}>
|
||||||
|
<i onClick={this.props.toggleStar} className={this.props.star ? 'fa fa-star star': 'far fa-star'}/>
|
||||||
|
</span>
|
||||||
|
<InternalLinkDialog repoID={repoID} path={filePath}/>
|
||||||
|
{this.props.isLocked &&
|
||||||
|
<img className="vam" width="16" src={ mediaUrl + 'img/file-locked-32.png' } alt="locked" title="locked"/>
|
||||||
|
}
|
||||||
|
</h2>
|
||||||
|
<div className="file-state">
|
||||||
|
<span className="file-modifier-name">
|
||||||
|
<a href={modifierUrl}>{latestContributor}</a>
|
||||||
|
</span>{' '}
|
||||||
|
<span className="file-modifier-time">{modifyTime}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileInfo.propTypes = FileInfoPropTypes;
|
||||||
|
|
||||||
|
if (enableWatermark) {
|
||||||
|
const loginUser = window.app.userInfo.name;
|
||||||
|
let watermark_txt;
|
||||||
|
if (loginUser) {
|
||||||
|
watermark_txt = siteName + ' ' + loginUser;
|
||||||
|
} else {
|
||||||
|
watermark_txt = gettext('Anonymous User');
|
||||||
|
}
|
||||||
|
watermark.init({
|
||||||
|
watermark_txt: watermark_txt,
|
||||||
|
watermark_alpha: 0.075
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render (
|
||||||
|
<ViewFileText />,
|
||||||
|
document.getElementById('root')
|
||||||
|
);
|
@@ -1,108 +1,62 @@
|
|||||||
{% extends 'view_file_base.html' %}
|
{% load render_bundle from webpack_loader %}
|
||||||
{% load i18n %}
|
{% load static seahub_tags i18n %}
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="{{ LANGUAGE_CODE }}">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||||
|
<title>{{ filename }}</title>
|
||||||
|
|
||||||
|
<link rel="shortcut icon" href="{{ MEDIA_URL }}{{ favicon_path }}" />
|
||||||
{% block extra_style %}{{block.super}}
|
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seafile-ui.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}codemirror/codemirror.css" />
|
<link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}css/seahub_react.css?t=1398068110" />
|
||||||
<style type="text/css">
|
</head>
|
||||||
{% if fileext == 'txt' or fileext == 'text' %}
|
<body>
|
||||||
.CodeMirror { width:816px; padding:40px 96px; }
|
<div id="root"></div>
|
||||||
{% endif %}
|
<div id="modal-wrapper"></div>
|
||||||
</style>
|
<script type="text/javascript">
|
||||||
{% endblock %}
|
window.app = {
|
||||||
|
config: {
|
||||||
{% block update_detail %}
|
mediaUrl: '{{ MEDIA_URL }}',
|
||||||
{% if last_commit_id %}
|
siteRoot: '{{ SITE_ROOT }}',
|
||||||
<span class="vam">{% trans "updated this file"%}, <a class="file-diff" href="{% url 'text_diff' repo.id %}?p={{path|urlencode}}&commit={{last_commit_id}}&file_enc={{file_enc}}">{% trans "Detail"%}</a>.</span>
|
serviceURL: '{{ service_url }}',
|
||||||
{% endif %}
|
seafileCollabServer: '{{ seafile_collab_server}}',
|
||||||
{% endblock %}
|
},
|
||||||
|
pageOptions: {
|
||||||
{% block edit_file %}
|
isPro: '{{ is_pro }}',
|
||||||
{% if not err %}
|
repoID: '{{ repo.id }}',
|
||||||
<a class="sf-btn-group-btn sf-btn-link op-icon sf2-icon-edit" href="{{ SITE_ROOT }}repo/{{ repo.id }}/file/edit/?p={{ path|urlencode }}&file_enc={{file_enc}}" id="edit" title="{% trans "Edit" %}"></a>
|
fileID: '{{ file_id }}',
|
||||||
{% endif %}
|
repoName: '{{ repo.name|escapejs }}',
|
||||||
{% endblock %}
|
filePath: '{{ path|escapejs }}',
|
||||||
|
fileName: '{{ filename|escapejs }}',
|
||||||
{% block file_view %}
|
filePerm: '{{ file_perm }}',
|
||||||
{% if encoding != None %}
|
enableFileComment: '{{ enable_file_comment }}' == 'True',
|
||||||
<div id="file-enc-cont">
|
parentDir: '{{ parent_dir|escapejs }}',
|
||||||
<label for="file-enc">{% trans "Encoding:" %}</label>
|
lastCommitId: '{{ last_commit_id }}',
|
||||||
<select id="file-enc">
|
fileEnc: '{{ file_enc }}',
|
||||||
{% for enc in file_encoding_list %}
|
fileExt: '{{ fileext|escapejs }}',
|
||||||
<option value="{{ enc }}" {% if encoding and encoding == enc %} selected="selected" {% endif %}>{% if enc == 'auto'%}{% trans "auto detect" %}{% else %}{{ enc }}{% endif %}</option>
|
siteName: '{{ site_name }}',
|
||||||
{% endfor %}
|
enableWatermark: '{{ enable_watermark }}' == 'True',
|
||||||
</select>
|
download: '{{ can_download_file }}' == 'True',
|
||||||
</div>
|
fileEncodingList: '{{ file_encoding_list|escapejs }}',
|
||||||
{% endif %}
|
encoding: '{{ encoding }}',
|
||||||
|
fileContent: '{{ file_content|escapejs }}',
|
||||||
{% ifnotequal file_content None %}
|
err: '{{ err }}',
|
||||||
<textarea id="docu-view" class="vh">{{ file_content|escape }}</textarea>
|
latestContributor: '{{ latest_contributor }}',
|
||||||
{% endifnotequal %}
|
lastModified: '{{ last_modified }}',
|
||||||
{% endblock %}
|
isLocked: '{{ file_locked }}' == 'True',
|
||||||
|
lockedByMe: '{{ locked_by_me }}' == 'True',
|
||||||
{% block extra_script %}{{ block.super }}
|
canLockUnlockFile: '{{ can_lock_unlock_file }}' == 'True',
|
||||||
{% if not err %}
|
isStarred: '{{ is_starred }}' == 'True',
|
||||||
{% ifnotequal file_content None %}
|
},
|
||||||
<script type="text/javascript" src="{{MEDIA_URL}}codemirror/codemirror-2.36.js"></script>
|
userInfo: {
|
||||||
<script type="text/javascript">
|
username: '{{ user.username }}',
|
||||||
var editor = CodeMirror.fromTextArea($('#docu-view')[0], {
|
name: '{{ user.username|email2nickname|escapejs }}',
|
||||||
{% include 'snippets/editor_set_mode.html' %}
|
contact_email: '{{ user.username|email2contact_email }}',
|
||||||
theme: 'default',
|
|
||||||
indentUnit: 4,
|
|
||||||
{% if fileext != 'txt' and fileext != 'text' %}
|
|
||||||
lineNumbers: true,
|
|
||||||
{% endif %}
|
|
||||||
lineWrapping: true,
|
|
||||||
readOnly: true
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
{% endifnotequal %}
|
|
||||||
{% endif %}
|
|
||||||
<script type="text/javascript">
|
|
||||||
// for 'go back'
|
|
||||||
var $fileDiff = $('.file-diff');
|
|
||||||
$fileDiff.attr('href', $fileDiff.attr('href') + '&referer=' + encodeURIComponent(location.href));
|
|
||||||
</script>
|
|
||||||
|
|
||||||
{% if seafile_collab_server %}
|
|
||||||
<script type="text/javascript" src="{{ seafile_collab_server }}socket.io/socket.io.js"></script>
|
|
||||||
<script type="text/javascript">
|
|
||||||
function check_file_update(cid) {
|
|
||||||
$.ajax({
|
|
||||||
url: "{% url 'FileMetaDataView' repo.id %}?p={{path|urlencode}}",
|
|
||||||
type: "GET",
|
|
||||||
cache: false,
|
|
||||||
success: function(data) {
|
|
||||||
if (data.id !== cid) {
|
|
||||||
// alert('File updated! Refresh.') //TODO
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
</script>
|
||||||
}
|
<script src="{{ STATIC_URL }}scripts/i18n/{{ LANGUAGE_CODE }}/djangojs.js"></script>
|
||||||
|
{% render_bundle 'viewFileText' %}
|
||||||
var socket = io('{{ seafile_collab_server }}');
|
</body>
|
||||||
|
</html>
|
||||||
socket.emit('repo_update', {
|
|
||||||
request: 'watch_update',
|
|
||||||
repo_id: '{{repo.id}}',
|
|
||||||
user: {
|
|
||||||
name: '{{user.username}}',
|
|
||||||
username: '{{user.username}}',
|
|
||||||
constact_email: ''
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('connect', function(){});
|
|
||||||
socket.on('repo_update', function(data){
|
|
||||||
/* alert('repo updated'); */
|
|
||||||
console.log(data);
|
|
||||||
|
|
||||||
var cid = '{{file_id}}';
|
|
||||||
check_file_update(cid);
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('disconnect', function(){});
|
|
||||||
</script>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock%}
|
|
||||||
|
Reference in New Issue
Block a user