mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-02 07:27:04 +00:00
[file_view]redesign comment feature;modified history_file_view
This commit is contained in:
@@ -956,7 +956,8 @@ ul.with-bg li {
|
||||
font-size:12px;
|
||||
color:#333;
|
||||
}
|
||||
#message {
|
||||
#message,
|
||||
#comment-input {
|
||||
font: 13px/1.5 Arial, Helvetica, sans-serif;
|
||||
word-wrap: break-word;
|
||||
width: 600px;
|
||||
@@ -985,7 +986,8 @@ ul.with-bg li {
|
||||
margin-bottom:2px;
|
||||
}
|
||||
.msg-hd .time,
|
||||
.msg-hd .group {
|
||||
.msg-hd .group,
|
||||
.comment-hd .time {
|
||||
color: #808080;
|
||||
}
|
||||
.msg-hd .group {
|
||||
@@ -1164,5 +1166,57 @@ ul.with-bg li {
|
||||
}
|
||||
/* File comment */
|
||||
#file-comment {
|
||||
margin-top: 60px;
|
||||
width:400px;
|
||||
position:fixed;
|
||||
right:10px;
|
||||
bottom:40px;
|
||||
border:1px solid #cbcbcb;
|
||||
padding:0 15px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,.2);
|
||||
-moz-box-shadow: -1px 1px 1px rgba(0,0,0,.2);
|
||||
-webkit-box-shadow: 0 2px 4px rgba(0,0,0,.2);
|
||||
background:#fff;
|
||||
overflow:auto;
|
||||
}
|
||||
#comment-input {
|
||||
width:315px;
|
||||
padding-left:1px;
|
||||
height:30px;
|
||||
margin:0;
|
||||
}
|
||||
.comment {
|
||||
width:380px;
|
||||
padding:15px 0;
|
||||
border-top:1px solid #e8e8e8;
|
||||
}
|
||||
.comment .txt {
|
||||
width:318px;
|
||||
}
|
||||
#file-comment-form {
|
||||
width:380px;
|
||||
margin:15px 0;
|
||||
}
|
||||
.comment-bd {
|
||||
word-wrap:break-word;
|
||||
}
|
||||
#comment-caret {
|
||||
position:fixed;
|
||||
right:27px;
|
||||
bottom:26px;
|
||||
}
|
||||
#comment-outer-caret,
|
||||
#comment-inner-caret {
|
||||
height:0;
|
||||
width:1px;
|
||||
border:14px solid;
|
||||
border-color:#CBCBCB transparent;
|
||||
border-bottom-width:0;
|
||||
z-index:100;
|
||||
margin:0 auto;
|
||||
}
|
||||
#comment-inner-caret {
|
||||
border-top-color:#fff;
|
||||
position:relative;
|
||||
top:-15px;
|
||||
left:-14px;
|
||||
}
|
||||
|
16
templates/file_comments.html
Normal file
16
templates/file_comments.html
Normal file
@@ -0,0 +1,16 @@
|
||||
{% load seahub_tags avatar_tags%}
|
||||
{% load url from future %}
|
||||
|
||||
{% for comment in comments %}
|
||||
<li class="comment ovhd">
|
||||
<a class="pic fleft" href="{% url 'user_profile' comment.from_email %}">{% avatar comment.from_email 48 %}</a>
|
||||
<div class="txt fright">
|
||||
<div class="comment-hd w100 ovhd">
|
||||
<a href="{% url 'user_profile' comment.from_email %}" title="{{ comment.from_email }}" class="fleft">{{ comment.from_email|email2nickname }}</a>
|
||||
<span class="time fright">{{ comment.timestamp|translate_commit_time }}</span>
|
||||
</div>
|
||||
<p class="comment-bd">{{ comment.message|seahub_urlize|find_at|linebreaksbr }}</p>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@@ -29,16 +29,17 @@
|
||||
{% endfor %}
|
||||
</p>
|
||||
|
||||
{% if not view_history %}
|
||||
<div class="file-op fright">
|
||||
{% if not view_history %}
|
||||
<input id="shared-link" class="hide" type="text" readonly="readonly" value="{{ file_shared_link }}" />
|
||||
<button data="{{ SITE_ROOT }}sharedlink/get/?repo_id={{ repo.id }}&p={{ path|urlencode }}&file_name={{ file_name }}" id="get-shared-link">获取分享地址</button>
|
||||
<button id="send-shared-link" class="hide">发送</button>
|
||||
<button data="{{ SITE_ROOT }}sharedlink/remove/?t={{ fileshare.token }}" id="rm-shared-link" class="hide">删除</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if not view_history %}
|
||||
<div id="file-commit-info">
|
||||
<p class="latest-commit">{% avatar latest_contributor 20 %} <a href="{% url 'user_profile' latest_contributor %}" class="name">{{ latest_contributor|email2nickname }}</a> <span>做了最新修改</span></p>
|
||||
<p class="contributors">
|
||||
@@ -48,16 +49,19 @@
|
||||
{% endfor %}
|
||||
</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="file">
|
||||
<div id="file-op">
|
||||
{% if not view_history and request.user.is_authenticated %}
|
||||
<button id="open-local" data="{{path}}{{dirent.obj_name}}">打开本地文件</button>
|
||||
{% if filetype == 'Text' or filetype == 'Markdown' %}
|
||||
{% if filetype == 'Text' or filetype == 'Markdown' %}
|
||||
<button data="{{ SITE_ROOT }}repo/{{ repo.id }}/file/edit/?p={{ path }}" id="edit">编辑</button>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if not view_history %}
|
||||
<button data="{{ SITE_ROOT }}repo/file_revisions/{{ repo.id }}/?p={{ path }}" id="history">历史</button>
|
||||
{% endif %}
|
||||
{% if filetype == 'Text' or filetype == 'Image' or filetype == 'SVG' or filetype == 'Markdown' %}
|
||||
<button data="{{ SITE_ROOT }}repo/{{ repo.id }}/{{ obj_id }}/?file_name={{ file_name }}&op=view" id="view-original">原始文件</button>
|
||||
{% endif %}
|
||||
@@ -74,7 +78,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if not view_history %}
|
||||
{% if not view_history %}
|
||||
<form id="link-send-form" action="" method="post" name="link-send-form" class="hide">
|
||||
<label>邮箱(多个邮箱以,分隔):</label><br />
|
||||
<textarea id="email" name="email"></textarea><br />
|
||||
@@ -96,56 +100,43 @@
|
||||
{% with attach_type='file' %}
|
||||
{% include "snippets/group_recommend_form.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<div id="file-comment">
|
||||
<h3>评论</h3>
|
||||
<form id="file-comment-form" action="" method="post">
|
||||
<input name="repo_id" type="hidden" value="{{ repo.id }}"/>
|
||||
<input name="file_path" type="hidden" value="{{ path|urlencode }}" />
|
||||
<textarea name="message" id="message">{{ form.data.message }}</textarea><br />
|
||||
{% for error in form.message.errors %}
|
||||
<p class="error">{{ error|escape }}</p>
|
||||
{% endfor %}
|
||||
<input type="submit" value="提交" class="submit" />
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if comments %}
|
||||
<!-- file comments list -->
|
||||
<ul class="msg-list">
|
||||
{% for comment in comments %}
|
||||
<li class="msg w100 ovhd">
|
||||
<div class="pic fleft">
|
||||
<a href="{% url 'user_profile' comment.from_email %}">{% avatar comment.from_email 48 %}</a>
|
||||
{% if request.user.is_authenticated %}
|
||||
<div id="file-comment" class="hide">
|
||||
<form id="file-comment-form" action="" method="post">
|
||||
<div class="ovhd">
|
||||
<a class="pic fleft" href="{% url 'user_profile' request.user.username %}">{% avatar request.user.username 48 %}</a>
|
||||
<div class="txt fright">
|
||||
<textarea name="message" id="comment-input">评论一下~</textarea><br />
|
||||
<p class="error"></p>
|
||||
<input type="submit" value="提交" class="submit hide" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% if comments %}
|
||||
<ul id="comment-list">
|
||||
{% for comment in comments %}
|
||||
<li class="comment ovhd">
|
||||
<a class="pic fleft" href="{% url 'user_profile' comment.from_email %}">{% avatar comment.from_email 48 %}</a>
|
||||
<div class="txt fright">
|
||||
<div class="comment-hd w100 ovhd">
|
||||
<a href="{% url 'user_profile' comment.from_email %}" title="{{ comment.from_email }}" class="fleft">{{ comment.from_email|email2nickname }}</a>
|
||||
<span class="time fright">{{ comment.timestamp|translate_commit_time }}</span>
|
||||
</div>
|
||||
<p class="comment-bd">{{ comment.message|seahub_urlize|find_at|linebreaksbr }}</p>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div id="filecomment-{{comment.id}}" class="txt fright">
|
||||
<div class="msg-hd">
|
||||
<span class="time">{{ comment.timestamp|translate_commit_time }}</span>
|
||||
<a href="{% url 'user_profile' comment.from_email %}" title="{{ comment.from_email }}">{{ comment.from_email|email2nickname }}</a>
|
||||
</div>
|
||||
<div class="msg-bd">
|
||||
<p>
|
||||
{{ comment.message|seahub_urlize|find_at|linebreaksbr }}
|
||||
</p>
|
||||
</div>
|
||||
<div id="comment-caret" class="hide">
|
||||
<div id="comment-outer-caret">
|
||||
<div id="comment-inner-caret"></div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<div id="paginator">
|
||||
{% if current_page != 1 %}
|
||||
<a href="{% url 'repo_view_file' repo.id %}?p={{ path|urlencode }}&page={{ prev_page }}&per_page={{ per_page }}">上一页</a>
|
||||
{% endif %}
|
||||
{% if page_next %}
|
||||
<a href="{% url 'repo_view_file' repo.id %}?p={{ path|urlencode }}&page={{ next_page }}&per_page={{ per_page }}">下一页</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
@@ -275,6 +266,54 @@ $('#shared-link').click(function() {
|
||||
});
|
||||
|
||||
{% include "snippets/bottom_bar.html" %}
|
||||
{% if request.user.is_authenticated %}
|
||||
$('#bottom-bar').append(' <button id="comment">评论</button>');
|
||||
$('#file-comment').css('max-height', $(window).height() - parseInt($('#file-comment').css('bottom')));
|
||||
$('#comment').click(function() {
|
||||
if ($('#file-comment').hasClass('hide')) {
|
||||
$('#file-comment, #comment-caret').removeClass('hide');
|
||||
} else {
|
||||
$('#file-comment, #comment-caret').addClass('hide');
|
||||
}
|
||||
});
|
||||
|
||||
var comment_input_pre_text = $('#comment-input').val();
|
||||
$('#comment-input').css('color', '#999').click(function() {
|
||||
$(this).val('').css('color', '#000');
|
||||
$('#file-comment-form .submit').removeClass('hide');
|
||||
});
|
||||
$('#file-comment-form .submit').click(function() {
|
||||
if (!$.trim($('#comment-input').val())) {
|
||||
$('#file-comment-form .error').html('请先输入您的评论').removeClass('hide');
|
||||
return false;
|
||||
}
|
||||
$.ajax({
|
||||
url: '{% url 'views.file_comment' %}' + '?p={{path}}',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
beforeSend: prepareCSRFToken,
|
||||
data: {
|
||||
'repo_id': '{{ repo.id }}',
|
||||
'file_path': '{{ path|urlencode }}',
|
||||
'message': $('#comment-input').val()
|
||||
},
|
||||
success: function(data) {
|
||||
$('#comment-input').val(comment_input_pre_text).css('color', '#999');
|
||||
$('#file-comment-form .submit, #file-comment-form .error').addClass('hide');
|
||||
$('#comment-list').html(data.html);
|
||||
},
|
||||
error: function(data, textStatus, jqXHR) {
|
||||
var errors = $.parseJSON(data.responseText);
|
||||
$.each(errors, function(index, value) {
|
||||
$('#file-comment-form .error').html(value[0]).removeClass('hide');
|
||||
});
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
function send_open_local_file_request(path) {
|
||||
|
1
urls.py
1
urls.py
@@ -66,6 +66,7 @@ urlpatterns = patterns('',
|
||||
# (r'^repo/setap/(?P<repo_id>[^/]+)/$', repo_set_access_property),
|
||||
url(r'^repo/(?P<repo_id>[^/]+)/files/$', repo_view_file, name="repo_view_file"),
|
||||
(r'^repo/(?P<repo_id>[^/]+)/file/edit/$', repo_file_edit),
|
||||
(r'^file_comment/$', file_comment),
|
||||
(r'^pdf_full_view/$', pdf_full_view),
|
||||
url(r'^repo/(?P<repo_id>[^/]+)/(?P<obj_id>[^/]+)/$', repo_access_file, name='repo_access_file'),
|
||||
|
||||
|
96
views.py
96
views.py
@@ -972,42 +972,6 @@ def repo_view_file(request, repo_id):
|
||||
"""
|
||||
Preview file on web, including files in current worktree and history.
|
||||
"""
|
||||
if request.method == 'POST':
|
||||
# handle post request to leave comment on file
|
||||
path = request.GET.get('p', '/')
|
||||
next = reverse('repo_view_file', args=[repo_id]) + '?p=' + \
|
||||
urllib2.quote(path.encode('utf-8'))
|
||||
|
||||
f = FileCommentForm(request.POST)
|
||||
if f.is_valid():
|
||||
repo_id = f.cleaned_data['repo_id']
|
||||
file_path = f.cleaned_data['file_path']
|
||||
file_path_hash = md5_constructor(file_path).hexdigest()[:12]
|
||||
message = f.cleaned_data['message']
|
||||
fc = FileComment(repo_id=repo_id, file_path=file_path,
|
||||
file_path_hash=file_path_hash,
|
||||
from_email=request.user.username, message=message)
|
||||
fc.save()
|
||||
# send a group message if the repo shared to any groups
|
||||
repo_shared_groups = get_shared_groups_by_repo(repo_id)
|
||||
|
||||
for group in repo_shared_groups:
|
||||
# save group message, and length should be less than 500
|
||||
gm = GroupMessage(group_id=group.id,
|
||||
from_email=request.user.username,
|
||||
message=message[:500])
|
||||
gm.save()
|
||||
# send signal
|
||||
grpmsg_added.send(sender=GroupMessage, group_id=group.id,
|
||||
from_email=request.user.username)
|
||||
|
||||
# save attachment
|
||||
ma = MessageAttachment(group_message=gm, repo_id=repo_id,
|
||||
attach_type='file', path=path,
|
||||
src='filecomment')
|
||||
ma.save()
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
http_server_root = get_httpserver_root()
|
||||
path = request.GET.get('p', '/')
|
||||
u_filename = os.path.basename(path)
|
||||
@@ -1092,22 +1056,9 @@ def repo_view_file(request, repo_id):
|
||||
|
||||
"""file comments"""
|
||||
# Make sure page request is an int. If not, deliver first page.
|
||||
try:
|
||||
current_page = int(request.GET.get('page', '1'))
|
||||
per_page= int(request.GET.get('per_page', '15'))
|
||||
except ValueError:
|
||||
current_page = 1
|
||||
per_page = 15
|
||||
|
||||
file_path_hash = md5_constructor(urllib2.quote(path.encode('utf-8'))).hexdigest()[:12]
|
||||
comments_plus_one = FileComment.objects.filter(
|
||||
file_path_hash=file_path_hash,
|
||||
repo_id=repo_id)[per_page*(current_page-1) : per_page*current_page+1]
|
||||
if comments_plus_one.count() == per_page + 1:
|
||||
page_next = True
|
||||
else:
|
||||
page_next = False
|
||||
comments = comments_plus_one[:per_page]
|
||||
comments = FileComment.objects.filter(file_path_hash=file_path_hash, repo_id=repo_id)
|
||||
|
||||
contributors = get_file_contributors(repo_id, path.encode('utf-8'), file_path_hash, obj_id)
|
||||
latest_contributor = contributors[0]
|
||||
@@ -1135,17 +1086,52 @@ def repo_view_file(request, repo_id):
|
||||
"applet_root": get_ccnetapplet_root(),
|
||||
'groups': groups,
|
||||
'comments': comments,
|
||||
'current_page': current_page,
|
||||
'prev_page': current_page-1,
|
||||
'next_page': current_page+1,
|
||||
'per_page': per_page,
|
||||
'page_next': page_next,
|
||||
'document_swf_exists': document_swf_exists,
|
||||
'DOCUMENT_CONVERTOR_ROOT': DOCUMENT_CONVERTOR_ROOT,
|
||||
'contributors': contributors,
|
||||
'latest_contributor': latest_contributor,
|
||||
}, context_instance=RequestContext(request))
|
||||
|
||||
def file_comment(request):
|
||||
if request.method == 'POST':
|
||||
# handle post request to leave comment on a file
|
||||
content_type = 'application/json; charset=utf-8'
|
||||
path = request.GET.get('p', '');
|
||||
|
||||
f = FileCommentForm(request.POST)
|
||||
if f.is_valid():
|
||||
repo_id = f.cleaned_data['repo_id']
|
||||
file_path = f.cleaned_data['file_path']
|
||||
file_path_hash = md5_constructor(file_path).hexdigest()[:12]
|
||||
message = f.cleaned_data['message']
|
||||
fc = FileComment(repo_id=repo_id, file_path=file_path,
|
||||
file_path_hash=file_path_hash,
|
||||
from_email=request.user.username, message=message)
|
||||
fc.save()
|
||||
# send a group message if the repo shared to any groups
|
||||
repo_shared_groups = get_shared_groups_by_repo(repo_id)
|
||||
|
||||
for group in repo_shared_groups:
|
||||
# save group message, and length should be less than 500
|
||||
gm = GroupMessage(group_id=group.id,
|
||||
from_email=request.user.username,
|
||||
message=message[:500])
|
||||
gm.save()
|
||||
# send signal
|
||||
grpmsg_added.send(sender=GroupMessage, group_id=group.id,
|
||||
from_email=request.user.username)
|
||||
|
||||
# save attachment
|
||||
ma = MessageAttachment(group_message=gm, repo_id=repo_id,
|
||||
attach_type='file', path=path,
|
||||
src='filecomment')
|
||||
ma.save()
|
||||
|
||||
comments = FileComment.objects.filter(file_path_hash=file_path_hash, repo_id=repo_id)
|
||||
html = render_to_string("file_comments.html", {'comments':comments})
|
||||
return HttpResponse(json.dumps({'html': html}), content_type=content_type)
|
||||
|
||||
|
||||
def repo_file_get(raw_path):
|
||||
err = ''
|
||||
file_content = ''
|
||||
|
Reference in New Issue
Block a user