update theme and user top

This commit is contained in:
2026-05-12 18:49:34 +08:00
parent ba8c1e3be3
commit 4dfd27c785
32 changed files with 777 additions and 78 deletions
+10 -15
View File
@@ -1,30 +1,25 @@
<#--jquery-->
<#--NProgress - page load progress bar (local first)-->
<link rel="stylesheet" type="text/css" href="/static/lib/nprogress.min.css"/>
<script src="/static/lib/nprogress.min.js"></script>
<script>if(typeof NProgress !== 'undefined') NProgress.start();</script>
<#--jquery (local first, CDN fallback)-->
<link rel="icon" type="image/png" href="/static/assets/images/logo.png">
<script crossorigin="anonymous" integrity="sha384-vk5WoKIaW/vJyUAd9n/wmopsmNhiy+L2Z+SBxGYnUkunIxVxAv/UtMOhba/xskxh"
src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"></script>
<script src="/static/lib/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="https://lib.baomitu.com/jquery/3.4.1/jquery.min.js"><\/script>')</script>
<#--semantic-ui-->
<link rel="stylesheet" type="text/css" href="/static/semanticui/semantic.css">
<#-- <script type="text/javascript" src="static/jquery/jquery-3.4.1.min.js"></script>-->
<script type="text/javascript" src="/static/semanticui/semantic.js"></script>
<#--<link crossorigin="anonymous" integrity="sha384-ATvSpJEmy1egycrmomcFxVn4Z0A6rfjwlzDQrts/1QRerQhR9EEpEYtdysLpQPuQ"-->
<#-- href="https://lib.baomitu.com/semantic-ui/2.4.1/semantic.min.css" rel="stylesheet">-->
<link rel="stylesheet" type="text/css" href="/static/semanticui/my.css">
<#--<script crossorigin="anonymous" integrity="sha384-6urqf2sgCGDfIXcoxTUOVIoQV+jFr/Zuc4O2wCRS6Rnd8w0OJ17C4Oo3PuXu8ZtF"-->
<#-- src="https://lib.baomitu.com/semantic-ui/2.4.1/semantic.min.js"></script>-->
<#--tinymce-->
<script crossorigin="anonymous" integrity="sha384-CpsBIlOAWHuSRRN235sCBzEeKN6hLT6SpOGRkGadKpYj0gDP7+s3Q8pC38z8uGHH"
src="https://lib.baomitu.com/tinymce/5.1.1/tinymce.min.js"></script>
<#--tinymce (CDN)-->
<script src="https://lib.baomitu.com/tinymce/5.1.1/tinymce.min.js"></script>
<#--layx-->
<link href="/static/layx/layx.min.css?b14794a8a3baf3e8b58e" rel="stylesheet">
<script type="text/javascript" src="/static/layx/layx.min.js?b14794a8a3baf3e8b58e"></script>
<script type="text/javascript" charset="UTF-8" src="/static/js/comm/util.js"></script>
@@ -45,4 +45,5 @@
</div>
</div>
</div>
<script>if(typeof NProgress !== 'undefined') NProgress.done();</script>
+34 -1
View File
@@ -24,6 +24,11 @@
<input type="text" placeholder="搜索">
</div>
</div>
<div class="item">
<a id="themeToggle" title="切换主题" style="cursor:pointer; font-size:1.2em; color:inherit;">
<i class="moon icon" id="themeIcon"></i> 主题
</a>
</div>
<div class="item" id="userlogin">
<#if username??>
<form class="ui large form" action="/logout" id="logoutForm" method="post" style="display: none;">
@@ -39,4 +44,32 @@
</div>
<script type="text/javascript" charset="UTF-8" src="/static/js/user/header.js"></script>
<script type="text/javascript" charset="UTF-8" src="/static/js/user/header.js"></script>
<script>
(function() {
var saved = localStorage.getItem('jiscuss-theme') || 'light';
if (saved === 'dark') { document.documentElement.setAttribute('data-theme', 'dark'); }
document.addEventListener('DOMContentLoaded', function() {
var btn = document.getElementById('themeToggle');
var icon = document.getElementById('themeIcon');
function applyTheme(t) {
if (t === 'dark') {
document.documentElement.setAttribute('data-theme', 'dark');
icon.className = 'sun icon';
} else {
document.documentElement.removeAttribute('data-theme');
icon.className = 'moon icon';
}
}
applyTheme(saved);
if (btn) {
btn.onclick = function() {
var current = localStorage.getItem('jiscuss-theme') || 'light';
var next = current === 'dark' ? 'light' : 'dark';
localStorage.setItem('jiscuss-theme', next);
applyTheme(next);
};
}
});
})();
</script>
+110 -26
View File
@@ -45,13 +45,21 @@
</div>
<div class="ui labeled button" tabindex="0" style=" margin-top: 30px;">
<div class="ui red button">
<div class="ui red button" id="likeBtn" onclick="voteDiscussion('like')">
<i class="heart icon"></i> 赞这个主题
</div>
<a class="ui basic red left pointing label">
<a class="ui basic red left pointing label" id="likeCount">
${discussions.likeCount!0}
</a>
</div>
<div class="ui labeled button" tabindex="0" style="margin-left:8px; margin-top: 30px;">
<div class="ui grey button" id="dislikeBtn" onclick="voteDiscussion('dislike')">
<i class="thumbs down icon"></i> 踩
</div>
<a class="ui basic grey left pointing label" id="dislikeCount">
${discussions.dislikeCount!0}
</a>
</div>
<span style="margin-left:12px; color:#888; font-size:0.9em;">
<i class="eye icon"></i> ${discussions.viewCount!0} 浏览
&nbsp;&nbsp;<i class="comment icon"></i> ${discussions.commentsCount!0} 回复
@@ -90,7 +98,14 @@
</div>
<div class="ui threaded comments">
<h3 class="ui dividing header">评论区</h3>
<h3 class="ui dividing header">
评论区
<div class="ui mini buttons" style="float:right; font-size:0.75em;">
<a class="ui button <#if sort == 'oldest'>active</#if>" href="?id=${discussions.id}&sort=oldest">最早</a>
<a class="ui button <#if sort == 'newest'>active</#if>" href="?id=${discussions.id}&sort=newest">最新</a>
<a class="ui button <#if sort == 'hot'>active</#if>" href="?id=${discussions.id}&sort=hot">最热</a>
</div>
</h3>
<input type="hidden" name="postId" id="postId" value=""/>
<!-- 定义遍历方法 -->
@@ -105,15 +120,20 @@
<img src="/static/assets/images/logo.png">
</a>
<div class="content">
<a class="author">${post.username}</a>
<a class="author user-card-trigger" data-user-id="${post.createId!''}">${post.username}</a>
<span style="color:#aaa; font-size:0.8em; margin-left:6px;">#${post.number!''}</span>
<div class="metadata">
<span class="date">${post.createTime}</span>
<#if post.ipRegion?? && post.ipRegion != ""><span style="margin-left:6px;"><i class="map marker alternate icon"></i>${post.ipRegion}</span></#if>
<#if post.browser?? && post.browser != ""><span style="margin-left:6px;"><i class="chrome icon"></i>${post.browser}</span></#if>
</div>
<div class="text">
${post.content}
</div>
<div class="actions">
<a class="reply" onclick="replyThis('${post.username}', '${post.id}')">回复</a>
<a onclick="votePost(${post.id}, 'like')" style="cursor:pointer;"><i class="thumbs up outline icon"></i>${(post.likeCount!0)?c}</a>
<a onclick="votePost(${post.id}, 'dislike')" style="cursor:pointer;"><i class="thumbs down outline icon"></i>${(post.dislikeCount!0)?c}</a>
</div>
</div>
<div class="comments">
@@ -127,15 +147,20 @@
<img src="/static/assets/images/logo.png">
</a>
<div class="content">
<a class="author">${post.username}</a>
<a class="author user-card-trigger" data-user-id="${post.createId!''}">${post.username}</a>
<span style="color:#aaa; font-size:0.8em; margin-left:6px;">#${post.number!''}</span>
<div class="metadata">
<span class="date">${post.createTime}</span>
<#if post.ipRegion?? && post.ipRegion != ""><span style="margin-left:6px;"><i class="map marker alternate icon"></i>${post.ipRegion}</span></#if>
<#if post.browser?? && post.browser != ""><span style="margin-left:6px;"><i class="chrome icon"></i>${post.browser}</span></#if>
</div>
<div class="text">
${post.content}
</div>
<div class="actions">
<a class="reply" onclick="replyThis('${post.username}', '${post.id}')">回复</a>
<a onclick="votePost(${post.id}, 'like')" style="cursor:pointer;"><i class="thumbs up outline icon"></i>${(post.likeCount!0)?c}</a>
<a onclick="votePost(${post.id}, 'dislike')" style="cursor:pointer;"><i class="thumbs down outline icon"></i>${(post.dislikeCount!0)?c}</a>
</div>
</div>
</div>
@@ -263,28 +288,23 @@
<div class="mobile only sixteen wide column">
<div class="ui segment">Jiscuss手机可见,内容正在编写中,pc端可正常访问</div>
<div class="ui pagination menu">
<a class="icon item">
<i class="left chevron icon"></i>
</a>
<a class="item">
1
</a>
<a class="item">
2
</a>
<div class="disabled item">
...
<div id="context2" style="padding: 1em; background: #fff; border-radius: 0.28571429rem; border: 1px solid rgba(34, 36, 38, 0.15);">
<h3 class="ui header"><i class="edit outline icon"></i>${discussions.title}</h3>
<div class="ui main text container">${discussions.content}</div>
<div style="margin-top:1em; color:#888; font-size:0.85em;">
<i class="eye icon"></i> ${discussions.viewCount!0} 浏览 &nbsp;
<i class="comment icon"></i> ${discussions.commentsCount!0} 回复
</div>
<div class="ui threaded comments" style="margin-top:1em;">
<h4 class="ui dividing header">评论区</h4>
<@bpTree posts=posts />
<form class="ui reply form" style="margin-top:1em;">
<div class="field"><textarea id="postContentMobile"></textarea></div>
<div class="ui blue labeled submit icon button" onclick="addPostMobile()">
<i class="icon edit"></i> 添加评论
</div>
</form>
</div>
<a class="item">
10
</a>
<a class="item">
11
</a>
<a class="icon item"> <i class="right chevron icon"></i>
</a>
</div>
</div>
@@ -303,8 +323,72 @@
console.log('已经登陆:' + username);
</#if>
setDiscussionsId('${discussions.id}');
// User card — custom fixed-position tooltip (more reliable than Semantic UI popup)
var cardCache = {};
var $card = $('<div id="jUserCard" style="position:fixed;background:#fff;border:1px solid #ddd;border-radius:6px;padding:12px 16px;box-shadow:0 4px 16px rgba(0,0,0,.15);z-index:9999;min-width:180px;display:none;pointer-events:none;"></div>').appendTo('body');
function showCard(u, x, y) {
$card.html(
'<div style="font-weight:700;font-size:1em;margin-bottom:4px;">' + (u.username || '') + '</div>' +
'<div style="color:#888;font-size:.88em;">发帖: ' + (u.discussionsCount || 0) +
'&nbsp;&nbsp;回复: ' + (u.commentsCount || 0) + '</div>'
).css({ left: x + 14, top: y + 14 }).show();
}
$(document).on('mouseenter', '.user-card-trigger', function(e) {
var userId = $(this).data('user-id');
if (!userId) return;
if (cardCache[userId]) { showCard(cardCache[userId], e.clientX, e.clientY); return; }
$.getJSON('/user_api/user/' + userId, function(res) {
if (res && res.code === 10000 && res.data) {
cardCache[userId] = res.data;
showCard(res.data, e.clientX, e.clientY);
}
});
}).on('mousemove', '.user-card-trigger', function(e) {
if ($card.is(':visible')) $card.css({ left: e.clientX + 14, top: e.clientY + 14 });
}).on('mouseleave', '.user-card-trigger', function() {
$card.hide();
});
});
function voteDiscussion(action) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$.ajax({
url: '/api/discussions/${discussions.id}/vote?action=' + action,
type: 'POST',
beforeSend: function(xhr) { xhr.setRequestHeader(header, token); },
success: function(res) {
if (res.code === 10000) {
location.reload();
} else {
alert(res.msg || '操作失败,请先登录');
}
},
error: function() { alert('请先登录'); }
});
}
function votePost(postId, action) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
$.ajax({
url: '/api/posts/' + postId + '/vote?action=' + action,
type: 'POST',
beforeSend: function(xhr) { xhr.setRequestHeader(header, token); },
success: function(res) {
if (res.code === 10000) {
location.reload();
} else {
alert(res.msg || '操作失败,请先登录');
}
},
error: function() { alert('请先登录'); }
});
}
</script>
<script type="text/javascript" charset="UTF-8" src="/static/js/user/discussions.js"></script>
</body>
+14 -20
View File
@@ -226,33 +226,27 @@
</div>
</div>
<div class="ui card black ">
<div class="ui card">
<div class="content">
<div class="header">预留功能</div>
<div class="header">🏆 活跃用户排行</div>
</div>
<div class="content">
<h4 class="ui sub header">Jiscuss</h4>
<div class="ui small feed">
<div class="event">
<div class="content">
<div class="summary">
<a>Jiscuss</a> 会持续更新, <a>Jiscuss</a> 将一直更新完善,感谢支持!
<div class="ui middle aligned divided list">
<#if topUsers?? && topUsers?size gt 0>
<#list topUsers as u>
<div class="item">
<img class="ui avatar image" src="/static/assets/images/logo.png">
<div class="content">
<a class="header">${u.username}</a>
<div class="description">${u.commentsCount!0} 回复</div>
</div>
</div>
</div>
<div class="event">
<div class="content">
<div class="summary">
<a>2019</a> 测试内容
</div>
</div>
</div>
</#list>
<#else>
<div class="item" style="color:#aaa;">暂无数据</div>
</#if>
</div>
</div>
<div class="extra content">
<button class="ui button">预留按钮</button>
</div>
</div>