优化阅读体验、前台编辑、播放器等

This commit is contained in:
anian
2026-07-22 01:54:46 +08:00
parent 041fd0f7cf
commit 32bf39f733
20 changed files with 896 additions and 653 deletions
+6 -1
View File
@@ -4,11 +4,16 @@
#### v1.2.5-7补丁 #### v1.2.5-7补丁
1. 重写作文目录、置顶样式 1. 重写作文目录、置顶样式
2. 更换域名(修正通知书错误链接) 2. 更换(通知书等)域名
3. 修复搜索结果无法PJAX跳转(依赖搜索插件v1.7.1-1 3. 修复搜索结果无法PJAX跳转(依赖搜索插件v1.7.1-1
4. 修复日记过多时无法搜索(依赖瞬间插件v1.13.1-1,基于源仓库) 4. 修复日记过多时无法搜索(依赖瞬间插件v1.13.1-1,基于源仓库)
5. 朋友圈内容支持搜索与跳转(依赖朋友圈插件v1.4.3-5) 5. 朋友圈内容支持搜索与跳转(依赖朋友圈插件v1.4.3-5)
6. 压缩、更换图片 6. 压缩、更换图片
7. 模板端全面支持page与tag参数(常驻显示,同步新增向上翻阅功能)
8. 取消自动恢复源内容功能
9. 前台编辑、发布日记将采用PJAX更新
10. 手机端播放器新增进度条
11. 清除无效代码
#### v1.2.5-7 #### v1.2.5-7
1. 适配新接口(基于新版API-Python) 1. 适配新接口(基于新版API-Python)
+20 -13
View File
@@ -2,90 +2,97 @@
<div class="anian-feed-grid"> <div class="anian-feed-grid">
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-theme-pix/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-theme-pix/rss/branch/master">
<h3 class="anian-feed-caption">日记簿更新</h3> <h3 class="anian-feed-caption">日记簿更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-friends/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-friends/rss/branch/master">
<h3 class="anian-feed-caption">朋友圈功能更新</h3> <h3 class="anian-feed-caption">朋友圈功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-comment/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-comment/rss/branch/master">
<h3 class="anian-feed-caption">评论功能更新</h3> <h3 class="anian-feed-caption">评论功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-photos/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-photos/rss/branch/master">
<h3 class="anian-feed-caption">图库功能更新</h3> <h3 class="anian-feed-caption">图库功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-douban/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-douban/rss/branch/master">
<h3 class="anian-feed-caption">课外书功能更新</h3> <h3 class="anian-feed-caption">课外书功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-dever/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-dever/rss/branch/master">
<h3 class="anian-feed-caption">插件开发容器更新</h3> <h3 class="anian-feed-caption">插件开发容器更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/api-python/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/api-python/rss/branch/master">
<h3 class="anian-feed-caption">应用接口更新</h3> <h3 class="anian-feed-caption">应用接口更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/anian-tool/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/anian-tool/rss/branch/master">
<h3 class="anian-feed-caption">小工具更新</h3> <h3 class="anian-feed-caption">小工具更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/memos/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/memos/rss/branch/master">
<h3 class="anian-feed-caption">备忘录更新</h3> <h3 class="anian-feed-caption">备忘录更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-moments/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-moments/rss/branch/master">
<h3 class="anian-feed-caption">日记功能更新</h3> <h3 class="anian-feed-caption">日记功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-search/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-search/rss/branch/master">
<h3 class="anian-feed-caption">搜索功能更新</h3> <h3 class="anian-feed-caption">搜索功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/weibo-rss/releases.rss"> <div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/weibo-rss/rss/branch/master">
<h3 class="anian-feed-caption">RSS功能更新</h3> <h3 class="anian-feed-caption">RSS功能更新</h3>
<div class="anian-feed-list-box"> <div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div> <div class="anian-loading">加载中...</div>
</div> </div>
</div> </div>
<div class="anian-feed-card" data-rss-url="https://git.anian.net/anian/halo-plugin-equipments/rss/branch/master">
<h3 class="anian-feed-caption">奇遇功能更新</h3>
<div class="anian-feed-list-box">
<div class="anian-loading">加载中...</div>
</div>
</div>
</div> </div>
</div> </div>
@@ -335,7 +342,7 @@
listBox.innerHTML = htmlContent || '<div style="color:#999;">暂无更新内容</div>'; listBox.innerHTML = htmlContent || '<div style="color:#999;">暂无更新内容</div>';
} catch (error) { } catch (error) {
listBox.innerHTML = `<div style="color:#f56c6c;font-size:14px;">请求失败: ${error.message}</div>`; listBox.innerHTML = `<div style="color:#f56c6c;font-size:14px;">失败:超时或发生错误</div>`;
} }
} }
+13 -2
View File
@@ -8,9 +8,20 @@
<th:block th:replace="~{modules/header}"/> <th:block th:replace="~{modules/header}"/>
<div id="pjax-container" th:with="page = ${#strings.isEmpty(param.page) ? 1 : param.page}"> <div id="pjax-container" th:with="
page = ${#lists.isEmpty(param.page) or #strings.isEmpty(param.page[0]) ? 1 : param.page[0]},
tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]}
">
<th:block th:replace="~{macro/home-blog :: home-blog(${postFinder.list(page,site.post.postPageSize)},'/archives')}"></th:block> <th:block th:if="${#strings.isEmpty(tag)}">
<th:block th:replace="~{macro/home-blog :: home-blog(${postFinder.list(page,site.post.postPageSize)},'/archives',null,null)}"></th:block>
</th:block>
<th:block th:unless="${#strings.isEmpty(tag)}" th:each="categoryItem : ${categoryFinder.listAll()}">
<th:block th:if="${#strings.equals(tag, categoryItem.spec.displayName) or #strings.equals(tag, categoryItem.metadata.name)}">
<th:block th:replace="~{macro/home-blog :: home-blog(${postFinder.listByCategory(page,site.post.postPageSize,categoryItem.metadata.name)},'/archives',${categoryItem.spec.displayName},${categoryItem.metadata.name})}"></th:block>
</th:block>
</th:block>
</div> </div>
+30 -12
View File
@@ -1444,7 +1444,8 @@ a.close_local {
#t_pagination, #t_pagination,
#pagination, #pagination,
#p_pagination { #p_pagination,
#prev_pagination {
padding: 30px; padding: 30px;
text-align: center; text-align: center;
display: flex; display: flex;
@@ -1454,7 +1455,8 @@ a.close_local {
#t_pagination a, #t_pagination a,
#pagination a, #pagination a,
#p_pagination a { #p_pagination a,
#prev_pagination a {
padding: 10px 15px; padding: 10px 15px;
background: var(--pix-theme); background: var(--pix-theme);
color: #fff; color: #fff;
@@ -1462,6 +1464,28 @@ a.close_local {
display: flex; display: flex;
} }
#prev_pagination {
overflow: hidden;
max-height: 0;
opacity: 0;
transform: translateY(-12px);
padding-top: 0;
padding-bottom: 0;
border-top: 0;
border-bottom: 0;
pointer-events: none;
transition: max-height 0.35s ease, opacity 0.3s ease, transform 0.35s ease, padding 0.35s ease, border-color 0.35s ease;
}
#prev_pagination.is-visible {
max-height: 140px;
opacity: 1;
transform: translateY(0);
padding: 30px;
border-bottom: 1px solid var(--pix-background);
pointer-events: auto;
}
.p_item { .p_item {
padding: 40px 0; padding: 40px 0;
border-bottom: 1px solid var(--pix-background); border-bottom: 1px solid var(--pix-background);
@@ -3837,7 +3861,7 @@ a.play_btn i {
} }
.player_bar { .player_bar {
height: 3px; height: 6px;
width: 100%; width: 100%;
background: #ddd; background: #ddd;
position: relative; position: relative;
@@ -3847,7 +3871,7 @@ a.play_btn i {
.player_bar .progress { .player_bar .progress {
position: absolute; position: absolute;
height: 3px; height: 6px;
background: linear-gradient(90deg, #00b34a, #00e0c7); background: linear-gradient(90deg, #00b34a, #00e0c7);
left: 0; left: 0;
top: 0; top: 0;
@@ -5269,7 +5293,7 @@ a.read-less-btn:hover {
} }
a.m_play i { a.m_play i {
font-size: 32px; font-size: 28px;
color: var(--pix-theme); color: var(--pix-theme);
} }
@@ -5763,8 +5787,7 @@ span.edit_post a {
background: rgba(235, 242, 237, 0.8); background: rgba(235, 242, 237, 0.8);
border-top: 1px solid #eaeaea; border-top: 1px solid #eaeaea;
align-items: center; align-items: center;
border-top-left-radius: 20px; border-radius: 0;
border-top-right-radius: 20px;
height: 50px; height: 50px;
} }
@@ -5985,11 +6008,6 @@ a.change i.ri-refresh-line {
.not_mobile { .not_mobile {
display: none; display: none;
} }
.footer_nav_box {
border-radius: 50px;
}
} }
.single_wrap .comments-area, .single_wrap .comments-area,
+55 -3
View File
@@ -481,7 +481,7 @@
backdrop-filter: blur(0.5rem); backdrop-filter: blur(0.5rem);
-webkit-backdrop-filter: blur(0.5rem); -webkit-backdrop-filter: blur(0.5rem);
background: rgb(235 242 237 / 80%); background: rgb(235 242 237 / 80%);
border-radius: 0 0 20px 20px; border-radius: 0;
height: 50px; height: 50px;
} }
@@ -655,7 +655,6 @@
color: #fff; color: #fff;
} }
.player_mod .tool,
a.m_prev, a.m_prev,
a.m_next, a.m_next,
.timer, .timer,
@@ -664,6 +663,59 @@
display: none; display: none;
} }
.player_mod .tool {
display: block;
width: 100%;
margin: 4px 0;
position: relative;
z-index: 5;
}
.player_mod .top {
position: relative;
z-index: 1;
}
.player_mod .player_bar {
height: 20px;
background: transparent;
overflow: visible;
touch-action: none;
}
.player_mod .player_bar::before {
content: "";
position: absolute;
top: 50%;
left: 0;
right: 0;
height: 6px;
background: #ddd;
border-radius: 6px;
transform: translateY(-50%);
z-index: 1;
}
.dark .player_mod .player_bar::before {
background: #585858;
}
.player_mod .player_bar .progress {
height: 6px;
top: 50%;
z-index: 2;
transform: translateY(-50%);
}
.player_mod .player_dot {
display: block;
width: 13px;
height: 13px;
margin-right: -9px;
z-index: 9;
box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}
.player_mod .m_cover { .player_mod .m_cover {
width: 32px; width: 32px;
height: 32px; height: 32px;
@@ -704,7 +756,7 @@
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
max-width: 100px; max-width: 90px;
} }
.single_music_header .mu_img { .single_music_header .mu_img {
-22
View File
@@ -9,22 +9,6 @@ function modify_m_bottom_music_button_link() {
}); });
} }
// 视频默认正方形,播放恢复比例(接入灯箱后已无用)
// function modify_moment_video_size() {
// const videos = document.querySelectorAll('.pix_video');
// videos.forEach(video => {
// if (!video.hasAttribute('data-video-events-bound')) {
// video.addEventListener('play', () => {
// video.classList.add('is-playing');
// });
// video.addEventListener('ended', () => {
// video.classList.remove('is-playing');
// });
// video.setAttribute('data-video-events-bound', 'true');
// }
// });
// }
// 登录逻辑 // 登录逻辑
let csrfToken = ''; let csrfToken = '';
let publicKey = ''; let publicKey = '';
@@ -160,9 +144,6 @@ login_loginBtn.addEventListener('click', async () => {
cocoMessage.success('署名成功,正在跳转...'); cocoMessage.success('署名成功,正在跳转...');
login_loginBtn.textContent = '跳转中...'; login_loginBtn.textContent = '跳转中...';
const currentScrollTop = window.scrollY || document.documentElement.scrollTop; const currentScrollTop = window.scrollY || document.documentElement.scrollTop;
// $.cookie('scrollParam', currentScrollTop, { path: '/', domain: 'anian.cc' });
// $.cookie('load_type', 'login', { path: '/', domain: 'anian.cc' });
$.cookie('scrollParam', currentScrollTop, { path: '/' });
$.cookie('load_type', 'login', { path: '/' }); $.cookie('load_type', 'login', { path: '/' });
window.location.reload(); window.location.reload();
} else if (finalUrl.includes('error=invalid-credential')) { } else if (finalUrl.includes('error=invalid-credential')) {
@@ -236,9 +217,6 @@ async function customLogout() {
closeLoading(); closeLoading();
cocoMessage.success('您已成功退出登录'); cocoMessage.success('您已成功退出登录');
const currentScrollTop = window.scrollY || document.documentElement.scrollTop; const currentScrollTop = window.scrollY || document.documentElement.scrollTop;
// $.cookie('scrollParam', currentScrollTop, { path: '/', domain: 'anian.cc' });
// $.cookie('load_type', 'logout', { path: '/', domain: 'anian.cc' });
$.cookie('scrollParam', currentScrollTop, { path: '/' });
$.cookie('load_type', 'logout', { path: '/' }); $.cookie('load_type', 'logout', { path: '/' });
window.location.reload(); window.location.reload();
} else { } else {
+421 -311
View File
@@ -3,17 +3,6 @@ var storage = window.localStorage;
var lazyLoadInstance = new LazyLoad({}); var lazyLoadInstance = new LazyLoad({});
// $(document).on('click', '.left_menu_box ul li a , .widget_nav_menu ul li a, .menu-top-container ul li a', function () {
// var t = $(this);
// t.siblings("ul").slideToggle(200);
// t.parent().siblings().find("ul").hide(200);
// if (t.parent().hasClass('has_children')) {
// t.find('.drop_icon').toggleClass('up');
// }
// $('.left_menu_box ul li').removeClass('current-pjax-item current-menu-item current-menu-parent current-menu-ancestor');
// t.parent().addClass('current-pjax-item');
// });
function highlightMenu() { function highlightMenu() {
$('.left_menu_box ul li').removeClass('current-pjax-item') $('.left_menu_box ul li').removeClass('current-pjax-item')
// 路径映射表 // 路径映射表
@@ -85,6 +74,253 @@ function loading_done(target) {
target.children('.loader').remove(); target.children('.loader').remove();
} }
function closeMomentPushModal() {
const modal = document.getElementById('create_post_box');
if (!modal || !window.UIkit || typeof UIkit.modal !== 'function') return;
try {
UIkit.modal(modal).hide();
} catch (e) { }
}
function reloadCurrentPageByPjax(loadType) {
if (window.pjax && typeof window.pjax.loadUrl === 'function') {
try {
$.removeCookie('load_type', { path: '/' });
window.pjax.loadUrl(window.location.href, {
history: false,
scrollTo: false
});
return;
} catch (e) { }
}
if (loadType) $.cookie('load_type', loadType, { path: '/' });
location.reload();
}
function buildRelativeUrl(url) {
const relativeUrl = url.pathname + url.search + url.hash;
try {
return decodeURI(relativeUrl);
} catch (e) {
return relativeUrl;
}
}
function removePageParamFromUrl(url) {
try {
const targetUrl = new URL(url || window.location.href, window.location.origin);
targetUrl.searchParams.delete('page');
return buildRelativeUrl(targetUrl);
} catch (e) {
return url || window.location.pathname;
}
}
function syncPageParamToUrl(page) {
const pageNumber = parseInt(page, 10);
if (!pageNumber || pageNumber < 1) return;
const url = new URL(window.location.href);
url.pathname = url.pathname.replace(/\/page\/\d+\/?$/, '') || '/';
if (url.pathname !== '/' && url.pathname.endsWith('/')) {
url.pathname = url.pathname.slice(0, -1);
}
if (pageNumber > 1) {
url.searchParams.set('page', pageNumber);
} else {
url.searchParams.delete('page');
}
const currentState = history.state && typeof history.state === 'object' ? history.state : {};
history.replaceState(Object.assign({}, currentState, { page: pageNumber }), '', buildRelativeUrl(url));
}
function getPageNumberFromUrl(urlValue) {
try {
const targetUrl = new URL(urlValue || window.location.href, window.location.origin);
const pageParam = parseInt(targetUrl.searchParams.get('page'), 10);
if (pageParam && pageParam > 0) return pageParam;
const pathPage = targetUrl.pathname.match(/\/page\/(\d+)\/?$/);
return pathPage ? parseInt(pathPage[1], 10) : 1;
} catch (e) {
const pageMatch = String(urlValue || '').match(/[?&]page=(\d+)|\/page\/(\d+)\/?$/);
return pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1;
}
}
function buildPageUrlFromCurrent(page) {
const pageNumber = parseInt(page, 10);
if (!pageNumber || pageNumber < 1) return buildRelativeUrl(new URL(window.location.href));
const url = new URL(window.location.href);
const pathPageReg = /\/page\/\d+\/?$/;
const usesPathPage = !url.searchParams.has('page') && pathPageReg.test(url.pathname);
if (usesPathPage) {
if (pageNumber > 1) {
url.pathname = url.pathname.replace(pathPageReg, '/page/' + pageNumber);
} else {
url.pathname = url.pathname.replace(pathPageReg, '') || '/';
}
} else {
url.pathname = url.pathname.replace(pathPageReg, '') || '/';
if (pageNumber > 1) {
url.searchParams.set('page', pageNumber);
} else {
url.searchParams.delete('page');
}
}
if (url.pathname !== '/' && url.pathname.endsWith('/')) {
url.pathname = url.pathname.slice(0, -1);
}
return buildRelativeUrl(url);
}
function getPreviousPageContext() {
const $photosList = $('#photos_item');
if ($photosList.length) {
return {
type: 'photos',
$list: $photosList,
extract: function (data) {
return $(data).find('#photos_item .gallery-photo, .norpost_list .gallery-photo');
},
insert: function ($items, data) {
const $gallery = $('#photos_item .gallery-photos').first();
if ($gallery.length) {
$gallery.prepend($items.hide().fadeIn(300));
return $items.last();
}
const previousPhotosHtml = $(data).find('#photos_item').html();
if (previousPhotosHtml) {
this.$list.html(previousPhotosHtml);
return this.$list.find('.gallery-photo').last();
}
return $();
},
afterLoad: function () {
if (typeof pix !== 'undefined' && pix.initGalleryPhotos) pix.initGalleryPhotos();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
if ($('.gallery-photos').length > 0 && typeof waterfall === 'function') {
waterfall('.gallery-photos');
}
}
};
}
const $momentList = $('#post_item.moment_list');
if ($momentList.length) {
return {
type: 'moment',
$list: $momentList,
extract: function (data) {
return $(data).find('.moment_list .p_item');
},
insert: function ($items) {
this.$list.prepend($items.hide().fadeIn(300));
return $items.last();
},
afterLoad: function () {
const postListElement = document.getElementById("post_item");
window.pjax && window.pjax.refresh(postListElement);
getMomentAudio();
initAgree();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
initializeMomentFold();
}
};
}
const $postList = $('#post_item.norpost_list');
if ($postList.length) {
return {
type: 'post',
$list: $postList,
extract: function (data) {
return $(data).find('.norpost_list').children();
},
insert: function ($items) {
this.$list.prepend($items.hide().fadeIn(400));
return $items.last();
},
afterLoad: function () {
const postListElement = document.getElementById("post_item");
window.pjax && window.pjax.refresh(postListElement);
initAgree();
if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
}
};
}
return null;
}
function initPreviousPageButton() {
const currentPage = getPageNumberFromUrl(window.location.href);
const context = getPreviousPageContext();
const $oldButton = $('#prev_pagination');
if (!context || currentPage <= 1) {
$oldButton.remove();
return;
}
const previousPage = currentPage - 1;
const previousUrl = buildPageUrlFromCurrent(previousPage);
const buttonText = (window.Theme && Theme.prev_page) ? Theme.prev_page : '翻阅更多';
if ($oldButton.length) {
$oldButton.find('a').attr('data', previousUrl).attr('data-page', previousPage).text(buttonText).show();
if (!$oldButton.next().is(context.$list)) {
context.$list.before($oldButton);
}
animatePreviousPageButton($oldButton);
return;
}
const $button = $('<div/>', {
id: 'prev_pagination',
class: 'prev-pagination'
});
const $paging = $('<div/>', { class: 'post-paging' });
const $link = $('<a/>', {
class: 'prev-page-btn',
text: buttonText
}).attr('data', previousUrl).attr('data-page', previousPage);
$button.append($paging.append($link));
context.$list.before($button);
animatePreviousPageButton($button);
}
function restorePreviousPageState($list, oldListHtml, oldButtonHtml) {
$list.html(oldListHtml);
if ($('#prev_pagination').length) {
$('#prev_pagination').replaceWith(oldButtonHtml);
} else if (oldButtonHtml) {
$list.before(oldButtonHtml);
}
}
function animatePreviousPageButton($button) {
if (!$button || !$button.length) return;
if ($button.hasClass('is-visible')) return;
requestAnimationFrame(() => {
requestAnimationFrame(() => {
$button.addClass('is-visible');
});
});
}
//话题表情添加 //话题表情添加
$(document).on('click', 'a.smile_btn', function () { $(document).on('click', 'a.smile_btn', function () {
@@ -556,7 +792,8 @@ $(document).on('click', '.push_item', function () {
function release() { function release() {
isSubmittingMoment = false; isSubmittingMoment = false;
$btn.removeAttr('disabled').removeClass('disabled'); $('.push_close, .push_item').prop('disabled', false);
$btn.removeClass('disabled');
} }
if (act === 'push') { if (act === 'push') {
@@ -593,11 +830,9 @@ $(document).on('click', '.push_item', function () {
closeLoading?.() closeLoading?.()
cocoMessage.success('发布成功!'); cocoMessage.success('发布成功!');
const currentScrollTop = window.scrollY || document.documentElement.scrollTop; const currentScrollTop = window.scrollY || document.documentElement.scrollTop;
// $.cookie('scrollParam', currentScrollTop, { path: '/', domain: 'anian.cc' }); release();
// $.cookie('load_type', 'create', { path: '/', domain: 'anian.cc' }); closeMomentPushModal();
$.cookie('scrollParam', currentScrollTop, { path: '/' }); reloadCurrentPageByPjax('create');
$.cookie('load_type', 'create', { path: '/' });
location.reload();
}, },
error() { error() {
$('.push_close, .push_item').prop('disabled', false); $('.push_close, .push_item').prop('disabled', false);
@@ -650,11 +885,9 @@ $(document).on('click', '.push_item', function () {
closeLoading?.() closeLoading?.()
cocoMessage.success('更新成功!'); cocoMessage.success('更新成功!');
const currentScrollTop = window.scrollY || document.documentElement.scrollTop; const currentScrollTop = window.scrollY || document.documentElement.scrollTop;
// $.cookie('scrollParam', currentScrollTop, { path: '/', domain: 'anian.cc' }); release();
// $.cookie('load_type', 'update', { path: '/', domain: 'anian.cc' }); closeMomentPushModal();
$.cookie('scrollParam', currentScrollTop, { path: '/' }); reloadCurrentPageByPjax('update');
$.cookie('load_type', 'update', { path: '/' });
location.reload();
}, },
error() { error() {
closeLoading?.() closeLoading?.()
@@ -775,7 +1008,6 @@ function get_moment_error(type) {
case "video": case "video":
var vi_type = $('.video_choose li.uk-active a').attr('vi_type'); var vi_type = $('.video_choose li.uk-active a').attr('vi_type');
var url = $('input#moment_video_url').val(); var url = $('input#moment_video_url').val();
//var cover = $('.m_media_left img').length;
if (vi_type == 'local') { if (vi_type == 'local') {
if (url == '') { if (url == '') {
return false; return false;
@@ -847,14 +1079,12 @@ $(document).on('click', '.moment_cat_nav ul li a', function () {
initializeMomentFold(); initializeMomentFold();
// if (typeof modify_moment_video_size === 'function') modify_moment_video_size(); // if (typeof modify_moment_video_size === 'function') modify_moment_video_size();
if (cat.indexOf('tag=') !== -1) { if (cat.indexOf('tag=') !== -1) {
history.pushState({ url: cat }, '', cat); const displayUrl = removePageParamFromUrl(cat);
history.pushState({ url: displayUrl }, '', displayUrl);
} else { } else {
history.pushState({ url: cat }, '', '/'); history.pushState({ url: cat }, '', '/');
} }
if (!$.cookie('scrollParam')) { initPreviousPageButton();
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
$.removeCookie('page', { path: '/' });
}
if (window._tagSwitchCallback) { if (window._tagSwitchCallback) {
window._tagSwitchCallback.resolve(); // 标记成功 window._tagSwitchCallback.resolve(); // 标记成功
window._tagSwitchCallback = null; // 清理临时变量 window._tagSwitchCallback = null; // 清理临时变量
@@ -952,16 +1182,10 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () {
// 更新浏览器历史状态 // 更新浏览器历史状态
if (typeof url === 'string') { if (typeof url === 'string') {
url = url.replace('author', 'tag'); const displayUrl = removePageParamFromUrl(url.replace('author', 'tag'));
history.pushState({ url: url }, '', url); history.pushState({ url: displayUrl }, '', displayUrl);
} }
initPreviousPageButton();
// 清除分页 cookie(保持原样)
if (!$.cookie('scrollParam')) {
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
$.removeCookie('page', { path: '/' });
}
if (window._tagSwitchCallback) { if (window._tagSwitchCallback) {
window._tagSwitchCallback.resolve(); // 标记成功 window._tagSwitchCallback.resolve(); // 标记成功
window._tagSwitchCallback = null; // 清理临时变量 window._tagSwitchCallback = null; // 清理临时变量
@@ -986,11 +1210,74 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () {
}); });
}); });
//ajax加载上一页
$(document).on('click', '#prev_pagination a', function () {
const $btn = $(this);
if ($btn.hasClass('disabled')) return false;
const href = $btn.attr('data');
const context = getPreviousPageContext();
if (!href || !context) return false;
const previousPage = parseInt($btn.attr('data-page'), 10) || Math.max(getPageNumberFromUrl(window.location.href) - 1, 1);
const $pagingArea = $('#prev_pagination .post-paging');
const oldPagingHtml = $pagingArea.html();
const oldButtonHtml = $('#prev_pagination').prop('outerHTML');
const oldListHtml = context.$list.html();
const scrollTopBeforeLoad = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
const listHeightBeforeLoad = context.$list[0] ? context.$list[0].scrollHeight : 0;
$.ajax({
type: "GET",
url: href,
headers: {
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7"
},
beforeSend: function () {
$btn.addClass('disabled').attr('aria-disabled', 'true');
$pagingArea.html('<div uk-spinner></div>');
},
success: function (data) {
const $items = context.extract(data);
if (!$items.length) {
restorePreviousPageState(context.$list, oldListHtml, oldButtonHtml);
cocoMessage.error('内容获取失败');
return;
}
$pagingArea.html(oldPagingHtml);
context.insert($items, data);
context.afterLoad();
initPreviousPageButton();
const listHeightAfterLoad = context.$list[0] ? context.$list[0].scrollHeight : listHeightBeforeLoad;
const heightDelta = Math.max(0, listHeightAfterLoad - listHeightBeforeLoad);
window.scrollTo(0, scrollTopBeforeLoad + heightDelta);
$body.animate({ scrollTop: '-=100' }, 500);
},
error: function () {
restorePreviousPageState(context.$list, oldListHtml, oldButtonHtml);
cocoMessage.error('内容获取失败');
}
});
return false;
});
//ajax加载片刻 //ajax加载片刻
$(document).on('click', '#t_pagination a', function () { $(document).on('click', '#t_pagination a', function () {
const postListElement = document.getElementById("post_item"); const postListElement = document.getElementById("post_item");
var href = $(this).attr('data'); var href = $(this).attr('data');
const currentPage = parseInt(href.match(/\d+/)[0]); let currentPage = 1;
try {
const url = new URL(href, window.location.origin);
const pageParam = parseInt(url.searchParams.get('page'), 10);
const pathPage = url.pathname.match(/\/page\/(\d+)/);
currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1);
} catch (e) {
const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/);
currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1;
}
const $pagingArea = $('#t_pagination .post-paging'); const $pagingArea = $('#t_pagination .post-paging');
const originalPagingHtml = $pagingArea.html(); const originalPagingHtml = $pagingArea.html();
@@ -1014,15 +1301,12 @@ $(document).on('click', '#t_pagination a', function () {
} else { } else {
$("#t_pagination a").hide(); $("#t_pagination a").hide();
} }
if (!window.scroll_param || (!window.loadMoreTimeout && window.scroll_param > result.offset().top - 58)) {
$body.animate({ scrollTop: result.offset().top - 58 }, 500); $body.animate({ scrollTop: result.offset().top - 58 }, 500);
} else window.forceStopLoading = true;
getMomentAudio(); getMomentAudio();
initAgree(); initAgree();
lazyLoadInstance.update(); lazyLoadInstance.update();
initializeMomentFold(); initializeMomentFold();
// $.cookie('page', currentPage, { path: '/', domain: 'anian.cc' }); syncPageParamToUrl(currentPage);
$.cookie('page', currentPage, { path: '/' });
} else { } else {
$('#t_pagination a').hide(); $('#t_pagination a').hide();
} }
@@ -1050,16 +1334,17 @@ $(document).ready(function () {
return false; return false;
} }
var tagText = $this.clone().find('span').remove().end().text().trim(); var displayUrl = removePageParamFromUrl(url);
// page 参数现在统一通过 removePageParamFromUrl 清理。
/*
try {
var photoUrl = new URL(url, window.location.origin);
photoUrl.searchParams.delete('page');
displayUrl = decodeURI(photoUrl.pathname + photoUrl.search + photoUrl.hash);
} catch (e) { }
*/
var displayUrl; $('.photos_cat_nav ul li a').addClass('disabled');
if (tagText === '全部') {
displayUrl = '/photos';
} else {
displayUrl = '/photos?tag=' + encodeURIComponent(tagText);
}
$('.posts_cat_nav ul li a').addClass('disabled');
// --- 1. 保存旧内容 (关键修改) --- // --- 1. 保存旧内容 (关键修改) ---
var $photosItem = $("#photos_item"); var $photosItem = $("#photos_item");
@@ -1102,18 +1387,17 @@ $(document).ready(function () {
if (typeof pix !== 'undefined' && pix.initGalleryPhotos) { if (typeof pix !== 'undefined' && pix.initGalleryPhotos) {
pix.initGalleryPhotos(); pix.initGalleryPhotos();
} }
if (typeof lazyLoadInstance !== 'undefined') {
lazyLoadInstance.update();
}
if ($('.gallery-photos').length > 0 && typeof waterfall === 'function') { if ($('.gallery-photos').length > 0 && typeof waterfall === 'function') {
waterfall('.gallery-photos'); waterfall('.gallery-photos');
} }
$('.posts_cat_nav ul li a').removeClass('disabled'); $('.photos_cat_nav ul li a').removeClass('disabled');
history.pushState({ path: displayUrl }, '', displayUrl); history.pushState({ path: displayUrl }, '', displayUrl);
initPreviousPageButton();
if (!$.cookie('scrollParam')) {
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
$.removeCookie('page', { path: '/' });
}
if (window._tagSwitchCallback) { if (window._tagSwitchCallback) {
window._tagSwitchCallback.resolve(); // 标记成功 window._tagSwitchCallback.resolve(); // 标记成功
window._tagSwitchCallback = null; // 清理临时变量 window._tagSwitchCallback = null; // 清理临时变量
@@ -1131,7 +1415,7 @@ $(document).ready(function () {
$photosItem.after(oldPagination); $photosItem.after(oldPagination);
} }
} }
$('.posts_cat_nav ul li a').removeClass('disabled'); $('.photos_cat_nav ul li a').removeClass('disabled');
cocoMessage.error('内容获取失败'); cocoMessage.error('内容获取失败');
if (window._tagSwitchCallback) { if (window._tagSwitchCallback) {
window._tagSwitchCallback.reject(); // 标记失败 window._tagSwitchCallback.reject(); // 标记失败
@@ -1147,7 +1431,16 @@ $(document).ready(function () {
//ajax加载图库 //ajax加载图库
$(document).on('click', '#p_pagination a', function () { $(document).on('click', '#p_pagination a', function () {
var href = $(this).attr('data'); var href = $(this).attr('data');
const currentPage = parseInt(href.match(/\d+/)[0]); let currentPage = 1;
try {
const url = new URL(href, window.location.origin);
const pageParam = parseInt(url.searchParams.get('page'), 10);
const pathPage = url.pathname.match(/\/page\/(\d+)/);
currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1);
} catch (e) {
const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/);
currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1;
}
const $pagingArea = $('#p_pagination .post-paging'); const $pagingArea = $('#p_pagination .post-paging');
const originalPagingHtml = $pagingArea.html(); const originalPagingHtml = $pagingArea.html();
const targetOffsetTop = $('#p_pagination a').offset().top; const targetOffsetTop = $('#p_pagination a').offset().top;
@@ -1169,12 +1462,10 @@ $(document).on('click', '#p_pagination a', function () {
} else { } else {
$("#p_pagination a").hide(); //如果没有下一页了,隐藏 $("#p_pagination a").hide(); //如果没有下一页了,隐藏
} }
if (!window.scroll_param || (!window.loadMoreTimeout && window.scroll_param > targetOffsetTop - 358)) {
$body.animate({ scrollTop: targetOffsetTop - 358 }, 500); $body.animate({ scrollTop: targetOffsetTop - 358 }, 500);
} else window.forceStopLoading = true;
pix.initGalleryPhotos(); pix.initGalleryPhotos();
// $.cookie('page', currentPage, { path: '/', domain: 'anian.cc' }); if (typeof lazyLoadInstance !== 'undefined') lazyLoadInstance.update();
$.cookie('page', currentPage, { path: '/' }); syncPageParamToUrl(currentPage);
} else { } else {
$('#p_pagination a').hide(); $('#p_pagination a').hide();
} }
@@ -1351,6 +1642,21 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) {
var cat = $(this).attr('data'); var cat = $(this).attr('data');
// 替换:获取a标签内的中文文本并去除空格 // 替换:获取a标签内的中文文本并去除空格
var tag = $(this).text().trim(); var tag = $(this).text().trim();
var displayUrl = '/archives';
try {
const archiveUrl = new URL(cat, window.location.origin);
archiveUrl.searchParams.delete('page');
if (archiveUrl.pathname === '/archives') {
displayUrl = decodeURI(archiveUrl.pathname + archiveUrl.search + archiveUrl.hash);
} else if (tag !== '全部' && tag !== '') {
displayUrl = '/archives?tag=' + encodeURIComponent(tag);
}
} catch (e) {
if (tag !== '全部' && tag !== '') {
displayUrl = '/archives?tag=' + encodeURIComponent(tag);
}
}
displayUrl = removePageParamFromUrl(displayUrl);
$.ajax({ $.ajax({
type: "GET", type: "GET",
@@ -1368,10 +1674,18 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) {
$(".norpost_list").append(result.fadeIn(300)); $(".norpost_list").append(result.fadeIn(300));
window.pjax && window.pjax.refresh(postListElement); window.pjax && window.pjax.refresh(postListElement);
let newhref = $(data).find("#pagination a").attr("data") || $(data).find(".arc_pagenav a").attr("data"); const $newPagination = $(data).find("#pagination");
let newhref = $newPagination.find("a").attr("data") || $(data).find(".arc_pagenav a").attr("data");
if ($('#pagination').length === 0 && $newPagination.length > 0) {
$(".norpost_list").after($newPagination.prop('outerHTML'));
}
if (newhref != undefined) { if (newhref != undefined) {
$("#pagination a").attr("data", newhref); $("#pagination a").attr("data", newhref);
$('#pagination a').text(Theme.site_page);
$('#pagination a').show(); $('#pagination a').show();
$('#pagination').show();
} else { } else {
$('#pagination a').hide(); $('#pagination a').hide();
} }
@@ -1381,19 +1695,8 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) {
lazyLoadInstance.update(); lazyLoadInstance.update();
$('.posts_cat_nav ul li a').removeClass('disabled'); $('.posts_cat_nav ul li a').removeClass('disabled');
// 仅新增:基于中文tag构造URL并更新(不影响请求逻辑) history.pushState({ url: displayUrl }, '', displayUrl);
const urlParams = new URLSearchParams(); initPreviousPageButton();
let newUrl = '/archives';
// 替换:判断是否为"全部",非全部则追加中文tag参数
if (tag !== '全部' && tag !== '') {
urlParams.append('tag', tag);
newUrl = `${newUrl}?${urlParams.toString()}`;
}
history.pushState({ url: newUrl }, '', newUrl);
if (!$.cookie('scrollParam')) {
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
$.removeCookie('page', { path: '/'});
}
if (window._tagSwitchCallback) { if (window._tagSwitchCallback) {
window._tagSwitchCallback.resolve(); // 标记成功 window._tagSwitchCallback.resolve(); // 标记成功
window._tagSwitchCallback = null; // 清理临时变量 window._tagSwitchCallback = null; // 清理临时变量
@@ -1424,7 +1727,16 @@ $('body').on('click', '#pagination a', function () {
const $pagingArea = $('#pagination .post-paging'); const $pagingArea = $('#pagination .post-paging');
const originalPagingHtml = $pagingArea.html(); const originalPagingHtml = $pagingArea.html();
var href = $(this).attr('data'); var href = $(this).attr('data');
const currentPage = parseInt(href.match(/\d+/)[0]); let currentPage = 1;
try {
const url = new URL(href, window.location.origin);
const pageParam = parseInt(url.searchParams.get('page'), 10);
const pathPage = url.pathname.match(/\/page\/(\d+)/);
currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1);
} catch (e) {
const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/);
currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1;
}
$.ajax({ $.ajax({
type: "GET", type: "GET",
url: href, url: href,
@@ -1450,13 +1762,10 @@ $('body').on('click', '#pagination a', function () {
} else { } else {
$("#pagination a").hide(); //如果没有下一页了,隐藏 $("#pagination a").hide(); //如果没有下一页了,隐藏
} }
if (!window.scroll_param || (!window.loadMoreTimeout && window.scroll_param > result.offset().top - 58)) {
$body.animate({ scrollTop: result.offset().top - 58 }, 500); $body.animate({ scrollTop: result.offset().top - 58 }, 500);
} else window.forceStopLoading = true;
initAgree() initAgree()
lazyLoadInstance.update(); lazyLoadInstance.update();
// $.cookie('page', currentPage, { path: '/', domain: 'anian.cc' }); syncPageParamToUrl(currentPage);
$.cookie('page', currentPage, { path: '/' });
} else { } else {
$("#pagination a").hide(); $("#pagination a").hide();
} }
@@ -1477,7 +1786,16 @@ $('body').on('click', '.arc_pagenav a', function () {
const originalPagingHtml = $pagingArea.html(); const originalPagingHtml = $pagingArea.html();
const postListElement = document.getElementById("post_item"); const postListElement = document.getElementById("post_item");
var href = $(this).attr('data'); var href = $(this).attr('data');
const currentPage = parseInt(href.match(/\d+/)[0]); let currentPage = 1;
try {
const url = new URL(href, window.location.origin);
const pageParam = parseInt(url.searchParams.get('page'), 10);
const pathPage = url.pathname.match(/\/page\/(\d+)/);
currentPage = pageParam || (pathPage ? parseInt(pathPage[1], 10) : 1);
} catch (e) {
const pageMatch = href.match(/[?&]page=(\d+)|\/page\/(\d+)/);
currentPage = pageMatch ? parseInt(pageMatch[1] || pageMatch[2], 10) : 1;
}
$(this).hide(); $(this).hide();
var content = $('.norpost_list'); var content = $('.norpost_list');
@@ -1506,13 +1824,10 @@ $('body').on('click', '.arc_pagenav a', function () {
$(".arc_pagenav a").hide(); //如果没有下一页了,隐藏 $(".arc_pagenav a").hide(); //如果没有下一页了,隐藏
} }
$('.arc_pagenav .uk-spinner').remove(); $('.arc_pagenav .uk-spinner').remove();
if (!window.scroll_param || (!window.loadMoreTimeout && window.scroll_param > post.offset().top - 58)) {
$body.animate({ scrollTop: post.offset().top - 58 }, 500); $body.animate({ scrollTop: post.offset().top - 58 }, 500);
} else window.forceStopLoading = true;
initAgree() initAgree()
lazyLoadInstance.update(); lazyLoadInstance.update();
// $.cookie('page', currentPage, { path: '/', domain: 'anian.cc' }); syncPageParamToUrl(currentPage);
$.cookie('page', currentPage, { path: '/' });
}, },
error: function () { error: function () {
$pagingArea.html(originalPagingHtml); $pagingArea.html(originalPagingHtml);
@@ -1620,7 +1935,6 @@ $('body').on('click', '.s_set_box a', function () {
var type = $(this).attr('data'); var type = $(this).attr('data');
$(this).addClass('active').siblings('a').removeClass('active'); $(this).addClass('active').siblings('a').removeClass('active');
$('form#index_search input[type="hidden"]').val(type); $('form#index_search input[type="hidden"]').val(type);
// $.cookie('s_type', type, { expires: 30, path: '/', domain: 'anian.cc' });
$.cookie('s_type', type, { expires: 30, path: '/' }); $.cookie('s_type', type, { expires: 30, path: '/' });
}); });
@@ -1636,10 +1950,8 @@ $('body').on('click', '.top_s_box a', function () {
$('body').on('click', '.t_dark a', function () { $('body').on('click', '.t_dark a', function () {
var t = $('html'); var t = $('html');
if (t.hasClass('dark')) { if (t.hasClass('dark')) {
// $.cookie('dark', 'normal', { path: '/', domain: 'anian.cc', expires: 30 });
$.cookie('dark', 'normal', { path: '/', expires: 30 }); $.cookie('dark', 'normal', { path: '/', expires: 30 });
} else { } else {
// $.cookie('dark', 'dark', { path: '/', domain: 'anian.cc', expires: 30 });
$.cookie('dark', 'dark', { path: '/', expires: 30 }); $.cookie('dark', 'dark', { path: '/', expires: 30 });
} }
t.toggleClass('dark'); t.toggleClass('dark');
@@ -1742,8 +2054,6 @@ if (Theme.pjax) {
initBlog(); initBlog();
refreshCommentWidget(); refreshCommentWidget();
NProgress.done(); NProgress.done();
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
$.removeCookie('page', { path: '/' });
}) })
} }
@@ -2142,67 +2452,6 @@ function initializeMomentFold() {
}); });
} }
// // 更换banner函数封装(PJAX触发)
// const bg1 = document.querySelector('.bg1');
// const bg2 = document.querySelector('.bg2');
// let bannerIndex = 0;
// let isBg1Active = true;
// let hasSingleBannerShown = false;
// let bannerImages = [];
// function preloadImage(url) {
// return new Promise((resolve, reject) => {
// const img = new Image();
// img.onload = () => resolve(url);
// img.onerror = reject;
// img.src = url;
// });
// }
// function changeBanner(url) {
// const show = isBg1Active ? bg2 : bg1;
// const hide = isBg1Active ? bg1 : bg2;
// show.style.backgroundImage = `url(${url})`;
// show.style.opacity = 1;
// hide.style.opacity = 0;
// isBg1Active = !isBg1Active;
// }
// async function safeChangeBanner(url) {
// await preloadImage(url);
// changeBanner(url);
// }
// function nextBanner() {
// if (bannerImages.length < 1) return;
// if (bannerImages.length === 1) {
// // 第一次调用:显示图片并标记为已显示
// if (!hasSingleBannerShown) {
// safeChangeBanner(bannerImages[bannerIndex]);
// hasSingleBannerShown = true;
// }
// // 非第一次调用:直接返回,不触发切换
// return;
// }
// safeChangeBanner(bannerImages[bannerIndex]);
// bannerIndex = (bannerIndex + 1) % bannerImages.length;
// }
// // 重置状态函数
// function resetBannerState() {
// bannerIndex = 0;
// isBg1Active = true;
// hasSingleBannerShown = false;
// }
// 更换背景函数封装 // 更换背景函数封装
function setFixedBackground(bgImageUrl) { function setFixedBackground(bgImageUrl) {
const body = document.body; const body = document.body;
@@ -2462,7 +2711,7 @@ function initGreenDigitalClock() {
const COOKIE_EXPIRE_YEARS = 10; const COOKIE_EXPIRE_YEARS = 10;
const NOTICE_DETAIL_PATH = '/notice'; const NOTICE_DETAIL_PATH = '/notice';
const RSS_URLS = [ const RSS_URLS = [
'https://git.anian.net/anian/halo-theme-pix/releases.rss', 'https://git.anian.net/anian/halo-theme-pix/rss/branch/master',
]; ];
async function getAllLatestNoticeDatesFromRSS() { async function getAllLatestNoticeDatesFromRSS() {
@@ -2505,8 +2754,6 @@ function markAsRead(combinedDateStr) {
const noticeBubble = document.getElementById('noticeBubble'); const noticeBubble = document.getElementById('noticeBubble');
const noticeBtn = document.getElementById('noticeBtn'); const noticeBtn = document.getElementById('noticeBtn');
if (!noticeBubble || !noticeBtn) return; if (!noticeBubble || !noticeBtn) return;
// $.cookie('latest_notice_date', combinedDateStr, { path: '/', domain: 'anian.cc', expires: 365 });
$.cookie('latest_notice_date', combinedDateStr, { path: '/', expires: 365 }); $.cookie('latest_notice_date', combinedDateStr, { path: '/', expires: 365 });
noticeBubble.classList.remove('show'); noticeBubble.classList.remove('show');
noticeBtn.classList.remove('has-notice'); noticeBtn.classList.remove('has-notice');
@@ -2790,163 +3037,32 @@ function anianxSpeedFetchXiehouyuWithTimeout(timeout) {
}); });
} }
function initjump() {
function initTagSwitch() { // 功能1:自定义页面tag接管(后续在自定义测实现,当前为过度)
return new Promise((resolve, reject) => { const targetPaths = ['/douban'];
const pathname = window.location.pathname; const pathname = window.location.pathname;
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const activeTag = urlParams.get('tag'); const activeTag = urlParams.get('tag')?.trim();
// 同时存在tag、且当前路径在集合内,才执行点击逻辑,不满足直接跳过
if (!activeTag || activeTag.trim() === '') { if (activeTag && targetPaths.includes(pathname)) {
resolve(); // 统一导航按钮选择器
return; const navSelector = '.douban_cat_nav ul li a';
} const targetLink = $(navSelector).filter(function () {
let targetLink = $();
if (pathname === '/archives') {
targetLink = $('.posts_cat_nav ul li a').filter(function () {
const linkText = $(this).contents().filter(function () {
return this.nodeType === 3;
}).text().trim();
return linkText === activeTag;
});
} else if (pathname === '/photos') {
targetLink = $('.photos_cat_nav ul li a').filter(function () {
const linkText = $(this).clone().find('span').remove().end().text().trim();
return linkText === activeTag;
});
} else if (pathname === '/friends') {
targetLink = $('.friends_cat_nav ul li a').filter(function () {
const linkText = $(this).clone().find('span').remove().end().text().trim();
return linkText === activeTag;
});
} else if (pathname === '/douban') {
targetLink = $('.douban_cat_nav ul li a').filter(function () {
const linkText = $(this).clone().find('span').remove().end().text().trim(); const linkText = $(this).clone().find('span').remove().end().text().trim();
return linkText === activeTag; return linkText === activeTag;
}); });
// 匹配到元素则模拟点击
if (targetLink.length) {
targetLink.trigger('click');
} }
if (targetLink.length > 0) {
window._tagSwitchCallback = { resolve, reject };
targetLink.click();
} else {
resolve();
}
});
} }
initPreviousPageButton();
// 1. 定义一个全局标志位,用于外部强制终止 // 功能2:登录登出、发布更新等操作后,显示提示信息
window.forceStopLoading = false;
window.loadMoreTimeout = false;
function loadMultiplePages(pageCount) {
return new Promise((resolve) => {
let loadedCount = 0;
const bootstrapStartTime = Date.now();
const bootstrapTimeout = 10000;
window.forceStopLoading = false; // 每次启动重置标志位
const getCurrentBtn = () => {
const $allBtns = $('.post-paging a:visible');
return $allBtns.filter(function () {
const dataAttr = $(this).attr('data');
return dataAttr !== undefined && dataAttr !== "" && dataAttr !== "无data属性";
}).first();
};
const loadNext = () => {
if (loadedCount >= pageCount || window.forceStopLoading) {
resolve();
return;
}
const $btn = getCurrentBtn();
if (!$btn || !$btn.length) {
// 慢网下分页按钮可能尚未渲染,短暂等待后再尝试
if (Date.now() - bootstrapStartTime < bootstrapTimeout) {
setTimeout(loadNext, 120);
return;
}
resolve();
return;
}
const $pager = $btn.closest('.post-paging');
const oldHref = $btn.attr('data');
const pageStartTime = Date.now();
$btn.trigger('click'); // 加载更多
// console.log(`正在加载第 ${loadedCount + 1} 页,URL: ${oldHref}`);
const waitInterval = setInterval(() => {
const now = Date.now();
if (window.forceStopLoading) {
clearInterval(waitInterval);
resolve();
return;
}
if (now - pageStartTime > 3000) {
clearInterval(waitInterval);
window.loadMoreTimeout = true;
resolve(); // 解决 Promise,触发后续滚动
return;
}
const isLoading = $pager.find('[uk-spinner]').length > 0;
if (isLoading) return; // 还在转圈,继续等待
clearInterval(waitInterval);
const $newBtn = getCurrentBtn();
const newHref = $newBtn.length ? $newBtn.attr('data') : null;
if (newHref && newHref !== oldHref) {
loadedCount++;
setTimeout(loadNext, 50);
} else {
resolve();
}
}, 50);
};
loadNext();
});
}
function initjump() {
let closeLoading = null; let closeLoading = null;
const page = $.cookie('page'); const loadType = $.cookie('load_type');
const scrollParam = $.cookie('scrollParam'); if (loadType) {
const loadType = $.cookie('load_type')
const hasValidPage = page && !isNaN(page);
const hasValidScroll = scrollParam && !isNaN(scrollParam);
const shouldLoadAndScroll = hasValidPage && hasValidScroll;
// $.removeCookie('scrollParam', { path: '/', domain: 'anian.cc' });
// $.removeCookie('page', { path: '/', domain: 'anian.cc' });
// $.removeCookie('load_type', { path: '/', domain: 'anian.cc' });
$.removeCookie('scrollParam', { path: '/' });
$.removeCookie('page', { path: '/' });
$.removeCookie('load_type', { path: '/' }); $.removeCookie('load_type', { path: '/' });
window.scroll_param = scrollParam;
if (hasValidScroll) {
closeLoading = cocoMessage.loading('自动恢复原内容中...');
}
initTagSwitch().then(() => {
const loadPageTask = () => {
if (shouldLoadAndScroll) {
const targetPage = Number(page) - 1;
return loadMultiplePages(targetPage);
}
return Promise.resolve();
};
loadPageTask().then(() => {
closeLoading?.()
if (hasValidScroll) {
const recordScroll = Number(scrollParam);
const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
const scrollDistance = Math.min(recordScroll, maxScroll);
$('html, body').animate({ scrollTop: scrollDistance }, 500);
switch (loadType) { switch (loadType) {
case 'create': case 'create':
cocoMessage.success('发布成功!'); cocoMessage.success('发布成功!');
@@ -2960,14 +3076,8 @@ function initjump() {
case 'logout': case 'logout':
cocoMessage.success('登出成功!'); cocoMessage.success('登出成功!');
break; break;
// default:
// const line_msg = location.hostname === "anian.cc" ? '主线路' : (location.hostname === "www.anian.cc" ? '副线路' : '测试线路');
// cocoMessage.success('已成功切换至' + line_msg);
} }
if (recordScroll > maxScroll && (recordScroll - maxScroll) > 200) { cocoMessage.warning('请手动加载原内容'); }
} }
}).catch(() => closeLoading?.());
}).catch(() => closeLoading?.());
} }
@@ -3044,7 +3154,8 @@ function initBlog() {
highlightActiveMenu(), highlightActiveMenu(),
syncFooterWithAudioState(), syncFooterWithAudioState(),
highlightMenu(), highlightMenu(),
initializeMomentFold() initializeMomentFold(),
initPreviousPageButton()
// nextBanner() // nextBanner()
} }
@@ -3061,4 +3172,3 @@ $(document).ready(function () {
initNoticeTip(); initNoticeTip();
initjump(); initjump();
}); });
+44 -12
View File
@@ -384,20 +384,52 @@ $(document).on('mouseleave', '.footer_nav_box .right_inner', function (event) {
}, 2000); }, 2000);
}); });
//音乐进度条跳转 //音乐进度条跳转/拖动
function getMousePosition(e) { var draggingPlayerBar = null;
var e = e || window.event;
var x = e.pageX; function getProgressPointerX(event) {
var y = e.pageY; var originalEvent = event.originalEvent || event;
return { 'left': x, 'top': y } if (originalEvent.touches && originalEvent.touches.length > 0) {
return originalEvent.touches[0].pageX;
}
if (originalEvent.changedTouches && originalEvent.changedTouches.length > 0) {
return originalEvent.changedTouches[0].pageX;
}
return event.pageX || originalEvent.pageX || 0;
} }
$(document).on('click', '.player_bar', function () { function seekPlayerByEvent(event, playerBar) {
var long = (getMousePosition().left) - ($('.progress').offset().left); var duration = audiobox[0].duration;
$('.progress').width(long); if (!duration || !isFinite(duration)) return;
allTime = parseInt(audiobox[0].duration);
var nowtime = (long / $('.player_bar').width()) * allTime; var $playerBar = $(playerBar);
audiobox[0].currentTime = nowtime; var barWidth = $playerBar.width();
if (!barWidth) return;
var long = getProgressPointerX(event) - $playerBar.offset().left;
long = Math.max(0, Math.min(long, barWidth));
$playerBar.find('.progress').width(long);
audiobox[0].currentTime = (long / barWidth) * duration;
}
$(document).on('mousedown touchstart', '.player_bar', function (event) {
event.preventDefault();
event.stopPropagation();
draggingPlayerBar = this;
seekPlayerByEvent(event, draggingPlayerBar);
});
$(document).on('mousemove touchmove', function (event) {
if (!draggingPlayerBar) return;
event.preventDefault();
seekPlayerByEvent(event, draggingPlayerBar);
});
$(document).on('mouseup touchend touchcancel', function (event) {
if (!draggingPlayerBar) return;
event.preventDefault();
draggingPlayerBar = null;
}); });
//音量调节 m_volume //音量调节 m_volume
+100
View File
@@ -0,0 +1,100 @@
<!DOCTYPE html>
<html xmlns:th="https://www.thymeleaf.org"
th:replace="~{modules/layouts/layout :: layout(_head = null,_content = ~{::content},_title = ${title + ' - ' + site.title})}">
<th:block th:fragment="content">
<div class="page_main uk-width-2-3@m">
<th:block th:replace="~{modules/header}" />
<div id="pjax-container">
<div class="blog_list">
<div class="blog_list_inner" uk-height-viewport="offset-top: true">
<div id="post_item" class="moment_list">
<!-- 作者姓名不为空才渲染朋友圈动态 -->
<div th:id="${'post-'+friend.metadata.name}"
class="loop_content p_item moment_item uk-animation-slide-bottom-small"
th:if="${friend.spec != null and not #strings.isEmpty(friend.spec.author)}"
th:with="postInfo = ${friend}, spec = ${friend.spec}">
<div class="p_item_inner">
<div class="list_user_meta">
<div class="avatar">
<img th:src="@{${spec.logo}}">
</div>
<div class="name">
<div class="avatar_title">
<a target="_blank" th:href="${spec.authorUrl}">
[[${spec.author}]]
</a>
</div>
<time itemprop="datePublished"
th:datetime="${#dates.format(spec.pubDate, 'yyyy-MM-dd HH:mm')}">
<th:block th:replace="~{modules/widgets/time :: time(${spec.pubDate})}">
</th:block>
</time>
</div>
</div>
<div class="blog_content">
<div class="entry-content">
<div class="p_title moment-collapse-container">
<a th:if="${not #strings.isEmpty(spec.postLink)}"
target="_blank" th:href="${spec.postLink}">
<div th:utext="${spec.description ?: '无内容'}"></div>
</a>
<div th:unless="${not #strings.isEmpty(spec.postLink)}"
th:utext="${spec.description ?: '无内容'}"></div>
</div>
<div class="img_list img-dynamic-container">
<div class="list_inner"
th:with="imgRaw=${spec.imageFiles},isImgList=${not #strings.isEmpty(imgRaw)}"
th:attr="num=${isImgList ? #arrays.length(imgRaw.split(',')) : 0}">
<th:block th:if="${isImgList}">
<th:block th:with="imgArray=${imgRaw.split(',')}">
<th:block th:each="url : ${imgArray}"
th:with="cleanUrl=${#strings.trim(url)}">
<span class="fancybox mo_img"
th:if="${not #strings.isEmpty(cleanUrl)}"
th:href="|/upload/image-host/${cleanUrl}|"
th:data-fancybox="${'post-' + postInfo.metadata.name}">
<img class="lazy"
src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
th:data-src="|/upload/image-host/${cleanUrl}|"
alt="">
</span>
</th:block>
</th:block>
</th:block>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 作者姓名为空:只展示404图片 -->
<div th:if="${friend.spec == null or #strings.isEmpty(friend.spec.author)}" style="text-align:center;padding:80px 0;">
<img src="/themes/theme-pix/assets/img/no-data.webp"style="max-width:400px;width:100%;">
</div>
</div>
<div id="comment_form_reset"></div>
</div>
</div>
</div>
<th:block th:replace="~{modules/footer-main}" />
</div>
</th:block>
</html>
+20 -10
View File
@@ -8,7 +8,11 @@
<th:block th:replace="~{modules/header}" /> <th:block th:replace="~{modules/header}" />
<div id="pjax-container"> <div id="pjax-container" th:with="
page = ${#lists.isEmpty(param.page) ? 1 : param.page[0]},
tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]},
friendPage = ${#strings.isEmpty(tag) ? (#lists.isEmpty(param.page) ? friends : friendFinder.list(page, friends.size)) : friendFinder.list({'page': page, 'size': friends.size, 'author': tag})}
">
<div class="blog_list"> <div class="blog_list">
<div class="blog_list_inner" uk-height-viewport="offset-top: true"> <div class="blog_list_inner" uk-height-viewport="offset-top: true">
@@ -19,15 +23,15 @@
<li> <li>
<!-- 全部按钮 --> <!-- 全部按钮 -->
<a th:attr="data-href=@{/friends}" <a th:attr="data-href=@{/friends}"
th:classappend="${#lists.isEmpty(param.author) ? 'active' : ''}" class="cat-link"> th:classappend="${#strings.isEmpty(tag) ? 'active' : ''}" class="cat-link">
全部<span></span> 全部<span></span>
</a> </a>
</li> </li>
<!-- 遍历所有作者 --> <!-- 遍历所有作者 -->
<th:block th:each="author : ${authors}"> <th:block th:each="author : ${authors}">
<li> <li>
<a th:attr="data-href=@{|/friends?author=${author}|}" <a th:attr="data-href=@{/friends(tag=${author})}"
th:classappend="${#strings.equals(param.author, author) ? 'active' : ''}" th:classappend="${#strings.equals(tag, author) ? 'active' : ''}"
th:text="${author}" class="cat-link"> th:text="${author}" class="cat-link">
<span></span> <span></span>
</a> </a>
@@ -38,7 +42,7 @@
<div id="post_item" class="moment_list"> <div id="post_item" class="moment_list">
<div th:each="postInfo, iterstat: ${friends.items}" th:id="${'post-'+postInfo.metadata.name}" <div th:each="postInfo, iterstat: ${friendPage.items}" th:id="${'post-'+postInfo.metadata.name}"
class="loop_content p_item moment_item uk-animation-slide-bottom-small" class="loop_content p_item moment_item uk-animation-slide-bottom-small"
th:if="${postInfo.spec != null and not #strings.isEmpty(postInfo.spec.description)}" th:if="${postInfo.spec != null and not #strings.isEmpty(postInfo.spec.description)}"
th:with="spec = ${postInfo.spec}"> th:with="spec = ${postInfo.spec}">
@@ -102,18 +106,24 @@
</div> </div>
<!-- 空数据 --> <!-- 空数据 -->
<th:block th:if="${#lists.isEmpty(friends.items)}"> <th:block th:if="${#lists.isEmpty(friendPage.items)}">
<th:block th:replace="~{macro/tpl/content-none}" /> <th:block th:replace="~{macro/tpl/content-none}" />
</th:block> </th:block>
</div> </div>
<!-- 分页:必须保持在 blog_list_inner 里面 --> <!-- 分页:必须保持在 blog_list_inner 里面 -->
<th:block th:if="${friends.totalPages>1}"> <th:block th:if="${friendPage.totalPages>1}">
<div id="t_pagination"> <div id="t_pagination">
<div class="post-paging" th:if="${friends.hasNext()}"> <div class="post-paging" th:if="${friendPage.hasNext()}"
<!-- 直接使用后端生成的完整 nextUrl --> th:with="_page = ${friendPage.page+1}">
<a th:data="${friends.nextUrl}" th:text="${theme.config.base_set.site_page}"> <a th:if="${#strings.isEmpty(tag)}"
th:data="@{/friends(page=${_page})}"
th:text="${theme.config.base_set.site_page}">
</a>
<a th:unless="${#strings.isEmpty(tag)}"
th:data="@{/friends(tag=${tag},page=${_page})}"
th:text="${theme.config.base_set.site_page}">
</a> </a>
</div> </div>
</div> </div>
+8 -4
View File
@@ -10,16 +10,20 @@
<div id="pjax-container" th:with="page = ${#strings.isEmpty(param.page) ? 1 : param.page}"> <div id="pjax-container" th:with="
page = ${#lists.isEmpty(param.page) ? 1 : param.page[0]},
tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]}
">
<th:block th:if="${theme.config.style.home_post_type=='moment' && pluginFinder.available('PluginMoments')}"> <th:block th:if="${theme.config.style.home_post_type=='moment' && pluginFinder.available('PluginMoments')}"
th:with="momentPage = ${#strings.isEmpty(tag) ? momentFinder.list(page, site.post.postPageSize) : momentFinder.listByTag(page, site.post.postPageSize, tag)}">
<th:block <th:block
th:replace="~{macro/home-moment :: home-moment(${momentFinder.list(page, site.post.postPageSize)},${momentFinder.listAllTags()})}"> th:replace="~{macro/home-moment :: home-moment(${momentPage},${momentFinder.listAllTags()},'/')}">
</th:block> </th:block>
</th:block> </th:block>
<th:block th:if="${theme.config.style.home_post_type=='post' || (not (theme.config.style.home_post_type=='moment' && pluginFinder.available('PluginMoments'))) }"> <th:block th:if="${theme.config.style.home_post_type=='post' || (not (theme.config.style.home_post_type=='moment' && pluginFinder.available('PluginMoments'))) }">
<th:block th:replace="~{macro/home-blog :: home-blog(${posts},'/')}"></th:block> <th:block th:replace="~{macro/home-blog :: home-blog(${posts},'/',null,null)}"></th:block>
</th:block> </th:block>
</div> </div>
+21 -8
View File
@@ -1,22 +1,28 @@
<th:block th:fragment="home-blog(_posts,path)"> <th:block th:fragment="home-blog(_posts,path,tag,selectedCategory)">
<div class="normal_list"> <div class="normal_list">
<div class="normal_list_inner" uk-height-viewport="offset-top: true"> <div class="normal_list_inner" uk-height-viewport="offset-top: true">
<div class="posts_cat_nav"> <div class="posts_cat_nav">
<ul id="cat_nav_items"> <ul id="cat_nav_items">
<li><a th:data="${path}" class="active">全部<span></span></a> <li><a th:data="${path}" th:classappend="${#strings.isEmpty(tag) ? 'active' : ''}">全部<span></span></a>
</li> </li>
<li th:if="${theme.config.post.post_nav == 'category'}" th:each="categoryItem,iStat : ${categoryFinder.listAll()}"> <li th:if="${theme.config.post.post_nav == 'category'}" th:each="categoryItem,iStat : ${categoryFinder.listAll()}">
<a th:data="${categoryItem.status.permalink}" <a th:if="${path == '/archives'}" th:data="@{/archives(tag=${categoryItem.spec.displayName})}"
class="">[[${categoryItem.spec.displayName}]]<span></span></a> th:classappend="${#strings.equals(tag, categoryItem.spec.displayName) or #strings.equals(selectedCategory, categoryItem.metadata.name) ? 'active' : ''}">[[${categoryItem.spec.displayName}]]<span></span></a>
<a th:unless="${path == '/archives'}" th:data="${categoryItem.status.permalink}"
th:classappend="${#strings.equals(tag, categoryItem.spec.displayName) or #strings.equals(selectedCategory, categoryItem.metadata.name) ? 'active' : ''}">[[${categoryItem.spec.displayName}]]<span></span></a>
</li> </li>
<li th:if="${theme.config.post.post_nav == 'custom_category'}" <li th:if="${theme.config.post.post_nav == 'custom_category'}"
th:each="category : ${theme.config.post.nav_category}"> th:each="category : ${theme.config.post.nav_category}">
<th:block th:with="categoryItem = ${categoryFinder.getByName(category)}"> <th:block th:with="categoryItem = ${categoryFinder.getByName(category)}">
<a th:if="${categoryItem!=null}" <a th:if="${categoryItem!=null and path == '/archives'}"
th:data="@{/archives(tag=${categoryItem.spec.displayName})}"
th:classappend="${#strings.equals(tag, categoryItem.spec.displayName) or #strings.equals(selectedCategory, categoryItem.metadata.name) ? 'active' : ''}">[[${categoryItem.spec.displayName}]]<span></span>
</a>
<a th:if="${categoryItem!=null and path != '/archives'}"
th:data="${categoryItem.status.permalink}" th:data="${categoryItem.status.permalink}"
class="">[[${categoryItem.spec.displayName}]]<span></span> th:classappend="${#strings.equals(tag, categoryItem.spec.displayName) or #strings.equals(selectedCategory, categoryItem.metadata.name) ? 'active' : ''}">[[${categoryItem.spec.displayName}]]<span></span>
</a> </a>
</th:block> </th:block>
</li> </li>
@@ -26,13 +32,20 @@
<div id="post_item" class="norpost_list " th:with='postItems=${_posts.items}' <div id="post_item" class="norpost_list " th:with='postItems=${_posts.items}'
th:classappend="${theme.config.post.post_list_type == 'grid' ? 'uk-grid-small uk-grid' : ''}"> th:classappend="${theme.config.post.post_list_type == 'grid' ? 'uk-grid-small uk-grid' : ''}">
<th:block th:replace="~{'macro/tpl/content-post'}"></th:block> <th:block th:replace="~{'macro/tpl/content-post'}"></th:block>
<th:block th:if="${#lists.isEmpty(postItems)}">
<th:block th:replace="~{macro/tpl/content-none}"/>
</th:block>
</div> </div>
<th:block th:if="${_posts.totalPages>1}"> <th:block th:if="${_posts.totalPages>1}">
<div id="pagination"> <div id="pagination">
<div class="post-paging" th:if="${_posts.hasNext()}" <div class="post-paging" th:if="${_posts.hasNext()}"
th:with="_page = ${_posts.page+1},_path = ${path == '/archives' ? path+'?page='+_page : path +'page/'+_page }"> th:with="_page = ${_posts.page+1},_path = ${path +'page/'+_page }">
<a th:data="${_path}" th:text="${theme.config.base_set.site_page}"></a> <a th:if="${path == '/archives' and #strings.isEmpty(tag)}"
th:data="@{/archives(page=${_page})}" th:text="${theme.config.base_set.site_page}"></a>
<a th:if="${path == '/archives' and not #strings.isEmpty(tag)}"
th:data="@{/archives(tag=${tag},page=${_page})}" th:text="${theme.config.base_set.site_page}"></a>
<a th:if="${path != '/archives'}" th:data="${_path}" th:text="${theme.config.base_set.site_page}"></a>
</div> </div>
</div> </div>
</th:block> </th:block>
+10 -5
View File
@@ -1,14 +1,14 @@
<th:block th:fragment="home-moment(_moments,tags)"> <th:block th:fragment="home-moment(_moments,tags,path)" th:with="_path = ${#strings.isEmpty(path) ? '/moments' : path}">
<div class="blog_list"> <div class="blog_list">
<div class="blog_list_inner" uk-height-viewport="offset-top: true"> <div class="blog_list_inner" uk-height-viewport="offset-top: true">
<div class="moment_cat_nav"> <div class="moment_cat_nav">
<ul id="cat_nav_items"> <ul id="cat_nav_items">
<li><a data="/moments" class="" th:classappend="${#lists.isEmpty(param.tag) ? 'active' : ''}" <li><a th:data="@{${_path}}" class="" th:classappend="${#lists.isEmpty(param.tag) ? 'active' : ''}"
><span>全部</span></a> ><span>全部</span></a>
</li> </li>
<li th:each="tag,iStat : ${tags}"> <li th:each="tag,iStat : ${tags}">
<a th:data="|/moments?tag=${tag.name}|" class="" <a th:data="@{${_path}(tag=${tag.name})}" class=""
th:classappend="${#lists.contains(param.tag, tag.name) ? 'active' : ''}" th:classappend="${#lists.contains(param.tag, tag.name) ? 'active' : ''}"
><span>[[${tag.name}]]</span></a> ><span>[[${tag.name}]]</span></a>
</li> </li>
@@ -27,8 +27,13 @@
<th:block th:if="${_moments.totalPages>1}"> <th:block th:if="${_moments.totalPages>1}">
<div id="t_pagination"> <div id="t_pagination">
<div class="post-paging" th:if="${_moments.hasNext()}" <div class="post-paging" th:if="${_moments.hasNext()}"
th:with="tag = ${not #lists.isEmpty(param.tag) ? '?tag='+param.tag : ''},_page = ${_moments.page+1}"> th:with="tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]},_page = ${_moments.page+1}">
<a th:data="${'/moments/page/'+_page+tag}" th:text="${theme.config.base_set.site_page}"></a> <a th:if="${#strings.isEmpty(tag)}"
th:data="@{${_path}(page=${_page})}"
th:text="${theme.config.base_set.site_page}"></a>
<a th:unless="${#strings.isEmpty(tag)}"
th:data="@{${_path}(tag=${tag},page=${_page})}"
th:text="${theme.config.base_set.site_page}"></a>
</div> </div>
</div> </div>
</th:block> </th:block>
+87
View File
@@ -0,0 +1,87 @@
<th:block th:fragment="home-photos(photoPage,groups,tag,selectedGroup)">
<div class="normal_list">
<div class="normal_list_inner" uk-height-viewport="offset-top: true">
<!-- 分类导航 -->
<div class="photos_cat_nav">
<ul id="cat_nav_items">
<li>
<!-- 修改:href 改为 data-href,并添加一个通用 class 如 'cat-link' -->
<a th:attr="data-href=@{/photos}"
th:classappend="${#strings.isEmpty(tag) and #strings.isEmpty(selectedGroup) ? 'active' : ''}"
class="cat-link">
全部<span></span>
</a>
</li>
<th:block th:each="photoGroup : ${groups}">
<li>
<!-- 修改:这里也改为 data-href -->
<a th:attr="data-href=@{/photos(tag=${photoGroup.spec.displayName})}"
th:classappend="${#strings.equals(tag, photoGroup.spec.displayName) or #strings.equals(selectedGroup, photoGroup.metadata.name) ? 'active' : ''}"
th:text="${photoGroup.spec.displayName}" class="cat-link">
<span></span>
</a>
</li>
</th:block>
</ul>
</div>
<!-- 相册列表 -->
<div id="photos_item" class="norpost_list">
<div th:unless="${#lists.isEmpty(photoPage.items)}" class="gallery-photos page">
<div th:each="photo : ${photoPage.items}" class="gallery-photo">
<th:block th:with="
img = ${!#strings.isEmpty(photo.spec.cover) ? photo.spec.cover : photo.spec.url},
isVideo = ${#strings.endsWith(img, '.mp4') or #strings.endsWith(img, '.webm') or #strings.endsWith(img, '.ogg')}
">
<span th:if="${isVideo}" th:href="${img}" data-fancybox="gallery"
class="fancybox video-fancybox"
style="position: relative; display: block; cursor: pointer;">
<video class="photo-img" preload="metadata" muted playsinline>
<source th:src="${img}" th:type="${#strings.endsWith(img, '.mp4') ? 'video/mp4' :
(#strings.endsWith(img, '.webm') ? 'video/webm' : 'video/ogg')}" />
</video>
<div
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); pointer-events: none;">
<i class="ri-play-circle-line play-icon"
style="color: #41b87e; font-size: 40px; background-color: rgba(255, 255, 255, 0.8); border-radius: 50%;"></i>
</div>
</span>
<span th:unless="${isVideo}" th:href="${img}" data-fancybox="gallery"
class="fancybox" th:data-thumb="${img}"
style="position: relative; display: block;">
<img class="photo-img" loading="lazy" th:src="${img}" />
</span>
</th:block>
</div>
</div>
<!-- 空数据 -->
<th:block th:if="${#lists.isEmpty(photoPage.items)}">
<th:block th:replace="~{macro/tpl/content-none}" />
</th:block>
</div>
<!-- 分页 -->
<th:block th:if="${photoPage.hasPrevious()} or ${photoPage.hasNext()}">
<div id="p_pagination">
<div class="post-paging" th:if="${photoPage.hasNext()}"
th:with="_page = ${photoPage.page+1}">
<a th:if="${#strings.isEmpty(tag)}"
th:data="@{/photos(page=${_page})}"
th:text="${theme.config.base_set.site_page}"></a>
<a th:unless="${#strings.isEmpty(tag)}"
th:data="@{/photos(tag=${tag},page=${_page})}"
th:text="${theme.config.base_set.site_page}"></a>
</div>
</div>
</th:block>
</div>
</div>
</th:block>
+1 -1
View File
@@ -1,5 +1,5 @@
<th:block th:fragment="footer"> <th:block th:fragment="footer">
<th:block th:with="customJsVersion='1.2.5-7'"> <th:block th:with="customJsVersion='1.2.5-7-TYIL'">
<!-- 奇遇容器 --> <!-- 奇遇容器 -->
<div class="center-img-container" id="centerImgContainer"> <div class="center-img-container" id="centerImgContainer">
+1 -56
View File
@@ -1,4 +1,4 @@
<th:block th:fragment="head" th:with="customJsVersion=${'1.2.5-7'}"> <th:block th:fragment="head" th:with="customJsVersion=${'1.2.5-7-DFQP'}">
<th:block th:replace="~{'modules/variables/msg'}" /> <th:block th:replace="~{'modules/variables/msg'}" />
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no">
@@ -6,61 +6,6 @@
<link rel="shortcut icon" th:href="@{${theme.config.base_set.favicon}}" title="Favicon"> <link rel="shortcut icon" th:href="@{${theme.config.base_set.favicon}}" title="Favicon">
<meta name="robots" content="max-image-preview:large"> <meta name="robots" content="max-image-preview:large">
<!-- <style>
.dl-warning-card { overflow: hidden; position: fixed; bottom: 1rem; left: 0; right: 0; margin: 0 auto; background-color: #ffffff; border-radius: 0.5rem; max-width: 720px; width: calc(100% - 2rem); box-shadow: 0 4px 12px rgba(0,0,0,0.1); z-index: 9999; display: none; opacity: 0; transform: translateY(20px); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-sizing: border-box; border-left: 4px solid #f59e0b; }
.dl-warning-header { display: flex; align-items: center; padding: 1rem; gap: 1rem; }
.dl-warning-image { flex-shrink: 0; background-color: #fef3c7; justify-content: center; align-items: center; width: 2.5rem; height: 2.5rem; border-radius: 9999px; display: flex; }
.dl-warning-image svg { color: #f59e0b; width: 1.25rem; height: 1.25rem; }
.dl-warning-content { flex: 1; text-align: left; word-wrap: break-word; word-break: break-all; min-width: 0; }
.dl-warning-title { color: #F59E0B; font-size: 0.95rem; font-weight: 600; line-height: 1.3rem; display: block; margin-bottom: 0.25rem; }
.dl-warning-message { color: #6b7280; font-size: 0.875rem; line-height: 1.25rem; margin: 0; }
.dl-warning-actions { display: flex; flex-direction: row; gap: 0.75rem; align-items: center; flex-shrink: 0; }
.dl-warning-desactivate { padding: 0.375rem 0.75rem; background-color: #f59e0b; color: #ffffff; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; justify-content: center; align-items: center; display: inline-flex; border-radius: 0.375rem; border: none; box-shadow: 0 1px 2px 0 rgba(0,0,0,0.05); cursor: pointer; white-space: nowrap; }
.dl-warning-desactivate.loading { background-color: #d97706; cursor: not-allowed; opacity: 0.8; pointer-events: none; }
.dl-warning-desactivate.loading::after { content: ""; width: 0.75rem; height: 0.75rem; border: 2px solid rgba(255,255,255,0.5); border-top-color: #ffffff; border-radius: 50%; margin-left: 0.5rem; margin-right: 0.25rem; animation: spin 1s linear infinite; flex-shrink: 0; }
.dl-warning-desactivate:not(.loading):hover { background-color: #fbbf24; box-shadow: 0 2px 3px 0 rgba(0,0,0,0.06); transition: all 0.2s ease-in-out; }
.dl-warning-cancel { padding: 0.375rem 0.75rem; background-color: #ffffff; color: #374151; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; justify-content: center; align-items: center; display: inline-flex; border-radius: 0.375rem; border: 1px solid #d1d5db; box-shadow: 0 1px 2px 0 rgba(0,0,0,0.05); cursor: pointer; white-space: nowrap; }
.dl-warning-cancel:hover { background-color: #ededed; border-color: #e5e7eb; box-shadow: 0 2px 3px 0 rgba(0,0,0,0.06); transition: all 0.2s ease-in-out; }
@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@media (max-width: 480px) {
.dl-warning-card { bottom: 1rem; width: calc(100% - 1rem); max-width: 100%; }
.dl-warning-header { padding: 0.75rem; gap: 0.75rem; align-items: center; }
.dl-warning-image { width: 2rem; height: 2rem; }
.dl-warning-image svg { width: 1rem; height: 1rem; }
.dl-warning-title { font-size: 0.9rem; }
.dl-warning-message { font-size: 0.85rem; }
.dl-warning-actions { flex-direction: column; gap: 0.375rem; align-items: stretch; flex-shrink: 0; width: auto; margin-top: 0; }
.dl-warning-desactivate, .dl-warning-cancel { font-size: 0.75rem; padding: 0.25rem 0.5rem; width: 100%; }
.dl-warning-content { min-width: 0; word-wrap: break-word; word-break: break-all; }
}
</style>
<div class="dl-warning-card" id="lineCard">
<div class="dl-warning-header">
<div class="dl-warning-image"><svg aria-hidden="true" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24" fill="none"><path d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" stroke-linejoin="round" stroke-linecap="round"></path></svg></div>
<div class="dl-warning-content"><span class="dl-warning-title" id="cardHeading"></span><p class="dl-warning-message" id="cardPara"></p></div>
<div class="dl-warning-actions"><button class="dl-warning-desactivate" id="switchBtn"></button><button class="dl-warning-cancel" id="cancelBtn">取消</button></div>
</div>
</div>
<script>
(function () {
const lineCardEl = document.getElementById('lineCard'), cardHeadingEl = document.getElementById('cardHeading'), cardParaEl = document.getElementById('cardPara'), switchLineBtn = document.getElementById('switchBtn'), cancelLineBtn = document.getElementById('cancelBtn');
const getCookie = (name) => document.cookie.split('; ').find(row => row.startsWith(`${name}=`))?.split('=')[1];
const setSessionCookie = (name, value, domain = 'anian.cc') => document.cookie = `${name}=${value}; path=/; domain=${domain}; SameSite=Lax`;
const showLineCard = () => { lineCardEl.style.display = 'block'; setTimeout(() => { lineCardEl.style.opacity = '1'; lineCardEl.style.transform = 'translateY(0)'; }, 10) };
const hideLineCard = (setNoPrompt = false, setNoSpeedTest = false) => { lineCardEl.style.opacity = '0'; lineCardEl.style.transform = 'translateY(20px)'; setTimeout(() => { lineCardEl.style.display = 'none'; if (setNoPrompt) setSessionCookie('noPrompt_anian_cc', 'true'); if (setNoSpeedTest) setSessionCookie('noSpeedTest_anian_cc', 'true'); }, 300) };
const handleLineSwitch = (baseUrl) => { switchLineBtn.classList.add('loading'); switchLineBtn.textContent = '切换中'; switchLineBtn.disabled = true; const currentScrollTop = window.scrollY || document.documentElement.scrollTop; document.cookie = `scrollParam=${currentScrollTop}; path=/; domain=anian.cc`; let finalUrl = baseUrl + location.pathname + location.search + location.hash; setTimeout(() => location.href = finalUrl, 500) };
let isResourceLoaded = false, pageLoadTimeoutTimer = null, isLoadTimeoutAborted = false;
const currentHost = location.hostname, isMainDomain = currentHost === 'anian.cc', isSubDomain = currentHost === 'www.anian.cc', isTestDomain = !isMainDomain && !isSubDomain;
const scrollParam = getCookie('scrollParam'), noPromptCookie = getCookie('noPrompt_anian_cc'), noSpeedTestCookie = getCookie('noSpeedTest_anian_cc');
cancelLineBtn.addEventListener('click', () => { hideLineCard(!isMainDomain, isMainDomain); });
if (isSubDomain) { if (!scrollParam && !noPromptCookie) { cardHeadingEl.textContent = '温馨提示'; cardParaEl.textContent = '当前为备用线路,若主线路正常,请优先选择主线路'; switchLineBtn.textContent = '切换主线路'; switchLineBtn.onclick = () => handleLineSwitch('https://anian.cc'); showLineCard(); } }
if (isMainDomain) { if (!noSpeedTestCookie) { pageLoadTimeoutTimer = setTimeout(() => { if (!isResourceLoaded) { isLoadTimeoutAborted = true; cardHeadingEl.textContent = '线路异常'; cardParaEl.textContent = '当前线路拥塞,若本地网络正常,可尝试切换至备用线路'; switchLineBtn.textContent = '切换副线路'; switchLineBtn.onclick = () => handleLineSwitch('https://www.anian.cc'); showLineCard(); } }, 15000); window.onload = () => { isResourceLoaded = true; clearTimeout(pageLoadTimeoutTimer); if (isLoadTimeoutAborted) return; const xhr = new XMLHttpRequest(); xhr.open('GET', `/upload/%E4%B8%8B%E8%BD%BD%20(9).mp4?_t=${Date.now()}`, true); let t = setTimeout(() => { xhr.abort(); cardHeadingEl.textContent = '线路异常'; cardParaEl.textContent = '当前线路拥塞,若本地网络正常,可尝试切换至备用线路'; switchLineBtn.textContent = '切换副线路'; switchLineBtn.onclick = () => handleLineSwitch('https://www.anian.cc'); showLineCard() }, 7500); xhr.onload = xhr.onerror = xhr.onabort = () => clearTimeout(t); xhr.send(); } } }
if (isTestDomain) { if (!noPromptCookie) { cardHeadingEl.textContent = '线路警告'; cardParaEl.textContent = '当前为测试线路,若非开发所需,请优先选择主线路'; switchLineBtn.textContent = '切换主线路'; switchLineBtn.onclick = () => handleLineSwitch('https://anian.cc'); showLineCard(); } }
})();
</script> -->
<link rel="stylesheet" id="wp-block-library-css" th:href="@{/assets/css/style.min.css(v=${customJsVersion})}" media="all"> <link rel="stylesheet" id="wp-block-library-css" th:href="@{/assets/css/style.min.css(v=${customJsVersion})}" media="all">
<link rel="stylesheet" id="pix-style-css" th:href="@{/assets/css/style.css(v=${customJsVersion})}" media="all"> <link rel="stylesheet" id="pix-style-css" th:href="@{/assets/css/style.css(v=${customJsVersion})}" media="all">
<link rel="stylesheet" id="fancybox.css-css" th:href="@{/assets/libs/fancybox/jquery.fancybox.min.css(v=${customJsVersion})}" media="all"> <link rel="stylesheet" id="fancybox.css-css" th:href="@{/assets/libs/fancybox/jquery.fancybox.min.css(v=${customJsVersion})}" media="all">
-13
View File
@@ -20,19 +20,6 @@
</header><!-- #masthead --> </header><!-- #masthead -->
<!-- <div class="index_banner">
<div class="bg bg1"></div>
<div class="bg bg2"></div>
<div class="user_info">
<div class="top">
<div class="left">
<div class="name">[[${theme.config.base_set.nice_name}]]</div>
<div class="des">[[${theme.config.base_set.admin_des}]]</div>
</div>
<div class="avatar"><img th:src="${theme.config.base_set.default_avatar}"></div>
</div>
</div>
</div> -->
<div class="index_banner" id="banner" uk-img="loading: eager"> <div class="index_banner" id="banner" uk-img="loading: eager">
<div class="user_info"> <div class="user_info">
<div class="top"> <div class="top">
@@ -28,70 +28,6 @@
</a> </a>
</div> </div>
<!-- <div class="m_top_nav top_tool is_mobile">
<a class="top_nav_btn" uk-toggle="target: #m_offcanvas"><i class="ri-menu-2-line"></i></a>
<div id="m_offcanvas" class="m_offcanvas uk-animation-fast"
uk-offcanvas="overlay: true;mode: push;container:.main_wrap">
<div class="uk-offcanvas-bar inner"
th:with="topMenu = ${#strings.isEmpty(theme.config.base_set.left_nav) ? menuFinder.getPrimary() : menuFinder.getByName(theme.config.base_set.left_nav)}">
<div class="m_logo"><a href="/"><img th:src="${theme.config.base_top_set.mobile_logo}"></a></div>
<div class="menu-top-container" th:if="${not #lists.isEmpty(topMenu)}">
<ul id="top_menu" class="menu">
<th:block th:each="menuItem : ${topMenu.menuItems}">
<li th:unless="${not #lists.isEmpty(menuItem.children)}"
class="menu-item menu-item-type-post_type menu-item-object-page">
<a th:target="${menuItem.spec.target?.value}" th:href="@{${menuItem.status.href}}"
th:with="icon = ${#annotations.getOrDefault(menuItem, 'icon', '')}">
<th:block th:if="${not #strings.isEmpty(icon)}"
th:with="index = ${icon.lastIndexOf('.')}">
<i th:unless="${index!=-1}" th:class="${icon}"></i>
<img th:if="${index!=-1}" th:src="${icon}">
</th:block>
<span class="nav_title" th:text="${menuItem.status.displayName}"></span>
</a>
</li>
<li th:if="${not #lists.isEmpty(menuItem.children)}"
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children has_children"
th:classappend="${'menu-item-'+iterStat.index}">
<a href="#" th:with="icon = ${#annotations.getOrDefault(menuItem, 'icon', '')}">
<th:block th:if="${not #strings.isEmpty(icon)}"
th:with="index = ${icon.lastIndexOf('.')}">
<i th:unless="${index!=-1}" th:class="${icon}"></i>
<img th:if="${index!=-1}" th:src="${icon}">
</th:block>
<span class="nav_title">[[${menuItem.status.displayName}]]</span>
<i class="ri-arrow-down-s-line drop_icon"></i>
</a>
<ul class="sub-menu">
<li th:each="childMenu,iterStat : ${menuItem.children}"
th:id="${'menu-item-'+iterStat.index}"
class="menu-item menu-item-type-custom menu-item-object-custom"
th:classappend="${'menu-item-'+iterStat.index}">
<a th:href="@{${childMenu.status.href}}"
th:with="icon = ${#annotations.getOrDefault(childMenu, 'icon', '')}"
th:target="${childMenu.spec.target?.value}">
<th:block th:if="${not #strings.isEmpty(icon)}"
th:with="index = ${icon.lastIndexOf('.')}">
<i th:unless="${index!=-1}" th:class="${icon}"></i>
<img th:if="${index!=-1}" th:src="${icon}">
</th:block>
<span class="nav_title">[[${childMenu.status.displayName}]]</span>
</a>
</li>
</ul>
</li>
</th:block>
</ul>
</div>
<div th:unless="${not #lists.isEmpty(topMenu)}" class="nav_tips">请前往后台设置左侧菜单/移动端菜单</div>
</div>
</div>
</div> -->
<!-- 搜索区域 --> <!-- 搜索区域 -->
<div class="search_mod"> <div class="search_mod">
<div th:if="${pluginFinder.available('PluginSearchWidget')}" class="t_search_on top_tool icon_color"> <div th:if="${pluginFinder.available('PluginSearchWidget')}" class="t_search_on top_tool icon_color">
+6 -2
View File
@@ -8,9 +8,13 @@
<th:block th:replace="~{modules/header}"/> <th:block th:replace="~{modules/header}"/>
<div id="pjax-container"> <div id="pjax-container" th:with="
page = ${#lists.isEmpty(param.page) ? 1 : param.page[0]},
tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]},
momentPage = ${#lists.isEmpty(param.page) ? moments : (#strings.isEmpty(tag) ? momentFinder.list(page, moments.size) : momentFinder.listByTag(page, moments.size, tag))}
">
<th:block th:replace="~{macro/home-moment :: home-moment(${moments},${tags})}"></th:block> <th:block th:replace="~{macro/home-moment :: home-moment(${momentPage},${tags},'/moments')}"></th:block>
</div> </div>
+14 -75
View File
@@ -7,85 +7,24 @@
<div class="page_main uk-width-2-3@m"> <div class="page_main uk-width-2-3@m">
<th:block th:replace="~{modules/header}" /> <th:block th:replace="~{modules/header}" />
<div id="pjax-container"> <div id="pjax-container" th:with="
<div class="normal_list"> page = ${#lists.isEmpty(param.page) or #strings.isEmpty(param.page[0]) ? 1 : param.page[0]},
<div class="normal_list_inner" uk-height-viewport="offset-top: true"> tag = ${#lists.isEmpty(param.tag) ? null : param.tag[0]},
groupParam = ${#lists.isEmpty(param.group) ? null : param.group[0]},
<!-- 分类导航 --> requestTag = ${not #strings.isEmpty(tag) ? tag : groupParam}
<div class="photos_cat_nav">
<ul id="cat_nav_items">
<li>
<!-- 修改:href 改为 data-href,并添加一个通用 class 如 'cat-link' -->
<a th:attr="data-href=@{/photos}"
th:classappend="${#lists.isEmpty(param.group) ? 'active' : ''}" class="cat-link">
全部<span></span>
</a>
</li>
<th:block th:each="group : ${groups}">
<li>
<!-- 修改:这里也改为 data-href -->
<a th:attr="data-href=@{|/photos?group=${group.metadata.name}|}"
th:classappend="${#lists.contains(param.group, group.metadata.name) ? 'active' : ''}"
th:text="${group.spec.displayName}" class="cat-link">
<span></span>
</a>
</li>
</th:block>
</ul>
</div>
<!-- 相册列表 -->
<div id="photos_item" class="norpost_list">
<div th:unless="${#lists.isEmpty(photos.items)}" class="gallery-photos page">
<div th:each="photo : ${photos.items}" class="gallery-photo">
<th:block th:with="
img = ${!#strings.isEmpty(photo.spec.cover) ? photo.spec.cover : photo.spec.url},
isVideo = ${#strings.endsWith(img, '.mp4') or #strings.endsWith(img, '.webm') or #strings.endsWith(img, '.ogg')}
"> ">
<th:block th:if="${#strings.isEmpty(requestTag)}">
<span th:if="${isVideo}" th:href="${img}" data-fancybox="gallery" <th:block th:with="photoPage = ${#lists.isEmpty(param.page) ? photos : photoFinder.list(page, photos.size)}">
class="fancybox video-fancybox" <th:block th:replace="~{macro/home-photos :: home-photos(${photoPage},${groups},null,null)}"></th:block>
style="position: relative; display: block; cursor: pointer;">
<video class="photo-img" preload="metadata" muted playsinline>
<source th:src="${img}" th:type="${#strings.endsWith(img, '.mp4') ? 'video/mp4' :
(#strings.endsWith(img, '.webm') ? 'video/webm' : 'video/ogg')}" />
</video>
<div
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); pointer-events: none;">
<i class="ri-play-circle-line play-icon"
style="color: #41b87e; font-size: 40px; background-color: rgba(255, 255, 255, 0.8); border-radius: 50%;"></i>
</div>
</span>
<span th:unless="${isVideo}" th:href="${img}" data-fancybox="gallery"
class="fancybox" th:data-thumb="${img}"
style="position: relative; display: block;">
<img class="photo-img" loading="lazy" th:src="${img}" />
</span>
</th:block> </th:block>
</div>
</div>
<!-- 空数据 -->
<th:block th:if="${#lists.isEmpty(photos.items)}">
<th:block th:replace="~{macro/tpl/content-none}" />
</th:block>
</div>
<!-- 分页 -->
<th:block th:if="${photos.hasPrevious()} or ${photos.hasNext()}">
<div id="p_pagination">
<div class="post-paging" th:if="${photos.hasNext()}">
<a th:data="@{${photos.nextUrl}}" th:text="${theme.config.base_set.site_page}"></a>
</div>
</div>
</th:block> </th:block>
</div> <th:block th:unless="${#strings.isEmpty(requestTag)}" th:each="photoGroup : ${groups}">
</div> <th:block th:if="${#strings.equals(requestTag, photoGroup.spec.displayName) or #strings.equals(requestTag, photoGroup.metadata.name)}"
th:with="photoPage = ${photoFinder.list(page, photos.size, photoGroup.metadata.name)}">
<th:block th:replace="~{macro/home-photos :: home-photos(${photoPage},${groups},${photoGroup.spec.displayName},${photoGroup.metadata.name})}"></th:block>
</th:block>
</th:block>
</div> </div>
<!-- 瀑布流自适应 --> <!-- 瀑布流自适应 -->