nodeclub/views/topic/index.html
2016-04-14 22:01:55 +08:00

508 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div id='sidebar'>
<div class='panel'>
<div class='header'>
<span class='col_fade'>作者</span>
</div>
<div class='inner'>
<%- partial('../user/card', { object: topic.author, as: 'user' }) %>
</div>
</div>
<% if (!current_user || !current_user.isAdvanced) { %>
<%- partial('../_ads') %>
<% } %>
<div class='panel'>
<div class='header'>
<span class='col_fade'>作者其它话题</span>
</div>
<div class='inner'>
<% if (typeof(author_other_topics) === 'undefined' || author_other_topics.length > 0) { %>
<ul class='unstyled'>
<%- partial('../topic/small', { collection: author_other_topics, as: 'topic' }) %>
</ul>
<% } else { %>
<p></p>
<% } %>
</div>
</div>
<div class='panel'>
<div class='header'>
<span class='col_fade'>无人回复的话题</span>
</div>
<div class='inner'>
<% if (typeof(no_reply_topics) !== 'undefined' && no_reply_topics.length > 0) { %>
<ul class='unstyled'>
<%- partial('../topic/small', { collection: no_reply_topics, as: 'topic' }) %>
</ul>
<% } else { %>
<p></p>
<% } %>
</div>
</div>
</div>
<div id='content'>
<div class='panel'>
<div class='header topic_header'>
<span class="topic_full_title">
<%- partial('./_top_good', {topic: topic}) %>
<%= topic.title %>
</span>
<div class="changes">
<span>
发布于 <%= topic.create_at_ago() %>
</span>
<span>
作者 <a href="/user/<%= topic.author.loginname %>"><%= topic.author.loginname %></a>
</span>
<span>
<%= topic.visit_count %> 次浏览
</span>
<% if (topic.create_at_ago() != topic.update_at_ago()) { %>
<span>
最后一次编辑是 <%= topic.update_at_ago() %>
</span>
<% } %>
<% if (topic.tab) { %>
<span> 来自 <%= topic.tabName %></span>
<%}%>
<% if (current_user) { %>
<input class="span-common <%= is_collect ? '' : 'span-success' %> pull-right collect_btn" type="submit" value="<%= is_collect ? '取消收藏' : '收藏' %>" action="<%= is_collect ? 'de_collect' : 'collect' %>">
<%}%>
</div>
<% if (current_user) { %>
<div id="manage_topic">
<% if (current_user.is_admin) { %>
<a href='/topic/<%= topic._id %>/top' data-method="post">
<% if (topic.top) { %>
<i class="fa fa-lg fa-star-o" title='取消置顶'></i>
<% } else { %>
<i class="fa fa-lg fa-star" title='置顶'/></i>
<% } %>
</a>
<a href='/topic/<%= topic._id %>/good' data-method="post">
<% if (topic.good) { %>
<i class="fa fa-lg fa-heart-o" title="取消精华"></i>
<% } else { %>
<i class="fa fa-lg fa-heart" title="加精华"></i>
<% } %>
</a>
<a href='/topic/<%= topic._id %>/lock' data-method="post">
<% if (topic.lock) { %>
<i class="fa fa-lg fa-unlock" title='取消锁定'></i>
<% } else { %>
<i class="fa fa-lg fa-lock" title='锁定(不可再回复)'/></i>
<% } %>
</a>
<a href='/topic/<%= topic._id %>/edit'>
<i class="fa fa-lg fa-pencil-square-o" title='编辑'></i></a>
<a href='javascript:;'
data-id="<%= topic._id %>"
class='delete_topic_btn'>
<i class="fa fa-lg fa-trash" title='删除'></i></a>
<% } else { %>
<% if (current_user._id.equals(topic.author_id)) { %>
<a href='/topic/<%= topic._id %>/edit'>
<i class="fa fa-lg fa-pencil-square-o" title='编辑'></i></a>
<a href='javascript:;'
data-id="<%= topic._id %>"
class='delete_topic_btn'>
<i class="fa fa-lg fa-trash" title='删除'></i></a>
<% } %>
<% } %>
</div>
<% } %>
</div>
<div class='inner topic'>
<div class='topic_content'>
<%- markdown(topic.linkedContent) %>
</div>
</div>
</div>
<% if (topic.replies && topic.replies.length > 0) { %>
<div class='panel'>
<div class='header'>
<span class='col_fade'><%= topic.replies.length %> 回复</span>
</div>
<%- partial('../reply/reply', topic.replies) %>
</div>
<% } %>
<% if (current_user && typeof(topic) !== 'undefined') { %>
<div class='panel'>
<div class='header'>
<span class='col_fade'>添加回复</span>
</div>
<div class='inner reply'>
<form id='reply_form' action='/<%= topic._id %>/reply' method='post'>
<div class='markdown_editor in_editor'>
<div class='markdown_in_editor'>
<textarea class='editor' name='r_content' rows='8'></textarea>
<div class='editor_buttons'>
<input class='span-primary submit_btn' type="submit" data-loading-text="回复中.." value="回复<%= topic.lock ? '(此主题已锁定)' : ''%>" <%= topic.lock ? 'disabled="disabled"' : ''%>>
</div>
</div>
</div>
<input type='hidden' name='_csrf' id="_csrf" value='<%= csrf %>'/>
</form>
</div>
</div>
<% } %>
</div>
<div class="replies_history">
<div class="inner_content"></div>
<div class="anchor"></div>
</div>
<!-- 预览模态对话框 -->
<div class="modal fade" id="preview-modal">
<div class="modal-body" style="max-height: initial;">
<img src="" alt="点击内容或者外部自动关闭图片预览" id="preview-image">
</div>
</div>
<% if (current_user && typeof(topic) !== 'undefined') { %>
<!-- markdown editor -->
<%- partial('../includes/editor') %>
<script>
$(document).ready(function () {
// 获取所有回复者name
var allNames = $('.reply_author').map(function (idx, ele) {
return $(ele).text().trim();
}).toArray();
allNames.push($('.user_card .user_name').text())
allNames = _.uniq(allNames);
// END 获取所有回复者name
// 编辑器相关
$('textarea.editor').each(function(){
var editor = new Editor({
status: []
});
var $el = $(this);
editor.render(this);
//绑定editor
$(this).data('editor', editor);
var $input = $(editor.codemirror.display.input);
$input.keydown(function(event){
if (event.keyCode === 13 && (event.ctrlKey || event.metaKey)) {
event.preventDefault();
$el.closest('form').submit();
}
});
// at.js 配置
var codeMirrorGoLineUp = CodeMirror.commands.goLineUp;
var codeMirrorGoLineDown = CodeMirror.commands.goLineDown;
var codeMirrorNewlineAndIndent = CodeMirror.commands.newlineAndIndent;
$input.atwho({
at: '@',
data: allNames
})
.on('shown.atwho', function () {
CodeMirror.commands.goLineUp = _.noop;
CodeMirror.commands.goLineDown = _.noop;
CodeMirror.commands.newlineAndIndent = _.noop;
})
.on('hidden.atwho', function () {
CodeMirror.commands.goLineUp = codeMirrorGoLineUp;
CodeMirror.commands.goLineDown = codeMirrorGoLineDown;
CodeMirror.commands.newlineAndIndent = codeMirrorNewlineAndIndent;
});
// END at.js 配置
});
// END 编辑器相关
// 评论回复
$('#content').on('click', '.reply2_btn', function (event) {
var $btn = $(event.currentTarget);
var parent = $btn.closest('.reply_area');
var editorWrap = parent.find('.reply2_form');
parent.find('.reply2_area').prepend(editorWrap);
var textarea = editorWrap.find('textarea.editor');
var user = $btn.closest('.author_content').find('.reply_author').text().trim();
var editor = textarea.data('editor');
editorWrap.show('fast', function () {
var cm = editor.codemirror;
cm.focus();
if(cm.getValue().indexOf('@' + user) < 0){
editor.push('@' + user + ' ');
}
});
});
$('#content').on('click', '.reply2_at_btn', function (event) {
var $btn = $(event.currentTarget);
var editorWrap = $btn.closest('.reply2_area').find('.reply2_form');
$btn.closest('.reply2_item').after(editorWrap);
var textarea = editorWrap.find('textarea.editor');
var user = $btn.closest('.reply2_item').find('.reply_author').text().trim();
var editor = textarea.data('editor');
editorWrap.show('fast', function () {
var cm = editor.codemirror;
cm.focus();
if(cm.getValue().indexOf('@' + user) < 0){
editor.push('@' + user + ' ');
}
});
});
// END 评论回复
// 加入收藏
$('.collect_btn').click(function () {
var $me = $(this);
var action = $me.attr('action');
var data = {
topic_id: '<%= topic._id %>',
_csrf: '<%= csrf %>'
};
var $countSpan = $('.collect-topic-count');
$.post('/topic/' + action, data, function (data) {
if (data.status === 'success') {
if (action == 'collect') {
$me.val('取消收藏');
$me.attr('action', 'de_collect');
} else {
$me.val('收藏');
$me.attr('action', 'collect');
}
$me.toggleClass('span-success');
}
}, 'json');
});
// END 加入收藏
// 删除回复
$('#content').on('click', '.delete_reply_btn, .delete_reply2_btn', function (event) {
var $me = $(event.currentTarget);
if (confirm('确定要删除此回复吗?')) {
var reply_id = null;
if ($me.hasClass('delete_reply_btn')) {
reply_id = $me.closest('.reply_item').attr('reply_id');
}
if ($me.hasClass('delete_reply2_btn')) {
reply_id = $me.closest('.reply2_item').attr('reply_id');
}
var data = {
reply_id: reply_id,
_csrf: "<%- csrf %>"
};
$.post('/reply/' + reply_id + '/delete', data, function (data) {
if (data.status === 'success') {
if ($me.hasClass('delete_reply_btn')) {
$me.closest('.reply_item').remove();
}
if ($me.hasClass('delete_reply2_btn')) {
$me.closest('.reply2_item').remove();
}
}
}, 'json');
}
return false;
});
// END 删除回复
// 删除话题
$('.delete_topic_btn').click(function () {
var topicId = $(this).data('id');
if (topicId && confirm('确定要删除此话题吗?')) {
$.post('/topic/' + topicId + '/delete', { _csrf: $('#_csrf').val() }, function (result) {
if (!result.success) {
alert(result.message);
} else {
location.href = '/';
}
});
}
return false;
});
// END 删除话题
// 用户 hover 在回复框时才显示点赞按钮
$('.reply_area').hover(
function () {
$(this).find('.up_btn').removeClass('invisible');
},
function () {
var $this = $(this);
if ($this.find('.up-count').text().trim() === '') {
$this.find('.up_btn').addClass('invisible');
}
});
// END 用户 hover 在回复框时才显示点赞按钮
});
</script>
<% } %>
<script type="text/javascript">
(function(){
var timer = null; //对话框延时定时器
// 初始化 $('.replies_history')
var $repliesHistory = $('.replies_history');
var $repliesHistoryContent = $repliesHistory.find('.inner_content');
$repliesHistory.hide();
// END
// 鼠标移入对话框清除隐藏定时器;移出时隐藏对话框
$repliesHistory.on('mouseenter', function(){
clearTimeout(timer);
}).on('mouseleave', function(){
$repliesHistory.fadeOut('fast');
});
// 显示被 at 用户的本页评论
if ($('.reply2_item').length === 0) {
// 只在流式评论布局中使用
$('#content').on('mouseenter', '.reply_content a', function (e) {
clearTimeout(timer);
var $this = $(this);
if ($this.text()[0] === '@') {
var thisText = $this.text().trim();
var loginname = thisText.slice(1);
var offset = $this.offset();
var width = $this.width();
var mainOffset = $('#main').offset();
$repliesHistory.css('left', offset.left-mainOffset.left+width+10); // magic number
$repliesHistory.css('top', offset.top-mainOffset.top-10); // magic number
$repliesHistory.css({
'z-index': 1,
});
$repliesHistoryContent.empty();
var chats = [];
var replyToId = $this.closest('.reply_item').attr('reply_to_id');
while (replyToId) {
var $replyItem = $('.reply_item[reply_id=' + replyToId + ']');
var replyContent = $replyItem.find('.reply_content').text().trim();
if (replyContent.length > 0) {
chats.push([
$($replyItem.find('.user_avatar').html()).attr({
height: '30px',
width: '30px',
}), // avatar
(replyContent.length>300?replyContent.substr(0,300)+'...':replyContent), // reply content
'<a href="#'+replyToId+'" class="scroll_to_original" title="查看原文">↑</a>'
]);
}
replyToId = $replyItem.attr('reply_to_id');
}
if(chats.length > 0) {
chats.reverse();
$repliesHistoryContent.append('<div class="title">查看对话</div>');
chats.forEach(function (pair, idx) {
var $chat = $repliesHistoryContent.append('<div class="item"></div>');
$chat.append(pair[0]); // 头像
$chat.append($('<span>').text(pair[1])); // 内容
$chat.append(pair[2]); // 查看原文 anchor
});
$repliesHistory.fadeIn('fast');
}else{
$repliesHistory.hide();
}
}
}).on('mouseleave', '.reply_content a', function (e) {
timer = setTimeout(function(){
$repliesHistory.fadeOut('fast');
}, 500);
});
}
// END 显示被 at 用户的本页评论
})();
// 点赞
$('.up_btn').click(function (e) {
var $this = $(this);
var replyId = $this.closest('.reply_area').attr('reply_id');
$.ajax({
url: '/reply/' + replyId + '/up',
method: 'POST',
}).done(function (data) {
if (data.success) {
$this.removeClass('invisible');
var currentCount = Number($this.next('.up-count').text().trim()) || 0;
if (data.action === 'up') {
$this.next('.up-count').text(currentCount + 1);
$this.addClass('uped');
} else {
if (data.action === 'down') {
$this.next('.up-count').text(currentCount - 1);
$this.removeClass('uped');
}
}
} else {
alert(data.message);
}
}).fail(function (xhr) {
if (xhr.status === 403) {
alert('请先登录,登陆后即可点赞。');
}
});
});
// END 点赞
// 图片预览
(function(){
var $previewModal = $('#preview-modal');
var $previewImage = $('#preview-image');
var $body = $('body'); // cache
$(document).on('click', '.markdown-text img', function(e) {
var $img = $(this);
// 图片被a标签包裹时不显示弹层
if ($img.parent('a').length > 0) {
return;
}
showModal($img.attr('src'));
});
$previewModal.on('click', hideModal);
$previewModal.on('hidden.bs.modal', function() {
// 在预览框消失之后恢复 body 的滚动能力
$body.css('overflow-y', 'scroll');
})
$previewModal.on('shown.bs.modal', function() {
// 修复上次滚动留下的痕迹,可能会导致短暂的闪烁,不过可以接受
// TODO: to be promote
$previewModal.scrollTop(0);
})
function showModal(src) {
$previewImage.attr('src', src);
$previewModal.modal('show');
// 禁止 body 滚动
$body.css('overflow-y', 'hidden');
}
function hideModal() {
$previewModal.modal('hide');
}
})()
// END 图片预览
</script>