diff --git a/README.md b/README.md index 867d9be..3e9220f 100755 --- a/README.md +++ b/README.md @@ -2,11 +2,13 @@ > 基于原作者v1.2.5代码修改 -#### v1.2.5-8补丁 -1. 修复导航栏居中显示失效、分享海报高度、页码更新异常 +#### v1.2.5-9 +1. 修复导航栏居中显示失效、分享海报高度、页码更新、加载动画异常 2. 优化上一页动画效果 3. 新增页面底部页码跳转功能 -4. 重构课外书(依赖豆瓣插件v1.2.2-3,模板端处理) +4. 重构课外书(依赖豆瓣插件v1.2.2-3,模板端处理,支持换行) +5. 新增奇遇页面(依赖装备插件,支持换行) +6. 新增网易云音乐播放JS函数`play_netease_music(2639350114)` #### v1.2.5-8 1. 重写作文目录、置顶样式 diff --git a/templates/assets/css/anian.css b/templates/assets/css/anian.css index e9f47e2..933aa96 100644 --- a/templates/assets/css/anian.css +++ b/templates/assets/css/anian.css @@ -610,7 +610,7 @@ .douban_page #post_item .douban_card_item { width: 100%; margin: 0; - padding: 0 20px; + padding: 0 40px; border-right: 1px solid #e5e7eb; display: flex; align-items: flex-start; @@ -789,6 +789,7 @@ font-size: 14px; line-height: 1.6; color: #43584d; + white-space: pre-wrap; display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; @@ -815,27 +816,6 @@ line-height: 1.5; } -@media only screen and (max-width:1359px) { - .douban_page #post_item { - grid-template-columns: 1fr; - } - - .douban_page #post_item .douban_card_item { - border-right: none !important; - } -} - -@media only screen and (max-width:540px) { - .douban_page #post_item .douban_card_item { - padding: 0 10px; - } - - .douban_page #post_item .douban_card_inner { - column-gap: 11px; - row-gap: 0px; - } -} - .douban_detail_page #post_item { grid-template-columns: repeat(2, minmax(0, 1fr)); } @@ -843,6 +823,7 @@ .douban_detail_page #post_item .douban_card_item { grid-column: 1 / -1; border-right: none; + padding: 35px 58px; } .douban_detail_page #post_item .douban_detail_link { @@ -863,3 +844,144 @@ -webkit-line-clamp: unset; -webkit-box-orient: initial; } + +@media only screen and (max-width:1359px) { + .douban_page #post_item { + grid-template-columns: 1fr; + } + + .douban_page #post_item .douban_card_item { + border-right: none !important; + } +} + +@media only screen and (max-width:540px) { + .douban_page #post_item .douban_card_item { + padding: 0 20px; + } + + .douban_page #post_item .douban_card_inner { + column-gap: 11px; + row-gap: 0px; + } + + .douban_detail_page #post_item .douban_card_item { + padding: 0 20px; + } +} + +.equipments_page #post_item { + padding: 0; + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + column-gap: 0; + row-gap: 0; + align-items: stretch; +} + +.equipments_page #post_item .loading_box, +.equipments_page #post_item > .no-results, +.equipments_page #post_item > #prev_pagination { + grid-column: 1 / -1; +} + +.equipments_page #post_item .equipment_item { + width: 100%; + margin: 0; + padding: 20px 40px; + border: 0; + display: flex; + align-items: center; +} + +.equipments_page #post_item .equipment_card_inner { + width: 100%; + display: flex; + align-items: center; + justify-content: center; +} + +.equipments_page #post_item .equipment_visual { + position: relative; + display: block; + width: 100%; + aspect-ratio: 1; + padding: 0; + overflow: hidden; + border: 0; + border-radius: 50%; + background: transparent; + color: inherit; + cursor: pointer; + font: inherit; + line-height: 1; +} + +.equipments_page #post_item .equipment_visual > img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 50%; +} + +.equipments_page #post_item .equipment_overlay { + position: absolute; + inset: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + padding: 30px; + overflow: auto; + border-radius: 50%; + background: radial-gradient( + circle closest-side at center, + rgba(0, 0, 0, 0.5) 0%, + rgba(0, 0, 0, 0.5) 70%, + rgba(0, 0, 0, 0.3) 85%, + rgba(0, 0, 0, 0) 100% + ); + color: #fff; + text-align: center; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 0.2s ease, visibility 0.2s ease; +} + +.equipments_page #post_item .equipment_visual:hover .equipment_overlay { + opacity: 1; + visibility: visible; + pointer-events: auto; +} + +.equipments_page #post_item .equipment_description { + max-width: 100%; + max-height: 100%; + margin: 0; + overflow: auto; + color: #fff; + font-size: 14px; + line-height: 1.6; + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +@media only screen and (max-width:540px) { + .equipments_page #post_item { + grid-template-columns: 1fr; + } + + .equipments_page #post_item .equipment_item { + padding: 20px; + } + + .equipments_page #post_item .equipment_overlay { + padding: 24px; + } + + .equipments_page #post_item .equipment_description { + font-size: 14px; + } +} diff --git a/templates/assets/js/app.js b/templates/assets/js/app.js index 5b3031e..9b2decb 100644 --- a/templates/assets/js/app.js +++ b/templates/assets/js/app.js @@ -464,6 +464,10 @@ function showListLoading(selector, loadingHtml) { $(selector).html(loadingHtml || DEFAULT_LIST_LOADING_HTML); } +function hidePagination(selector) { + $(selector).hide(); +} + function setCategoryLinkActive($link, childSelector) { $link.addClass('active').parent().siblings().children(childSelector || 'a').removeClass('active'); if (window.pix && typeof pix.centerCategoryNavActive === 'function') { @@ -1203,12 +1207,8 @@ $(document).on('click', '.moment_cat_nav ul li a', function () { url: cat, headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - const $pagingArea = $('#t_pagination .post-paging'); - if ($pagingArea.length) { - $pagingArea.html('
'); - } else { - showListLoading('.moment_list'); - } + showListLoading('.moment_list'); + hidePagination('#t_pagination'); }, success: function (data) { setCategoryLinkActive($this); @@ -1271,12 +1271,8 @@ $(document).on('click', '.friends_cat_nav .cat-link', function () { url: url, headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - const $pagingArea = $('#t_pagination .post-paging'); - if ($pagingArea.length) { - $pagingArea.html('
'); - } else { - showListLoading('.moment_list'); - } + showListLoading('.moment_list'); + hidePagination('#t_pagination'); }, success: function (data) { setCategoryLinkActive($this); @@ -1556,12 +1552,8 @@ $(document).ready(function () { url: url, headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - const $pagingArea = $('#p_pagination .post-paging'); - if ($pagingArea.length) { - $pagingArea.html('
'); - } else { - showListLoading("#photos_item", PHOTO_LIST_LOADING_HTML); - } + showListLoading("#photos_item", PHOTO_LIST_LOADING_HTML); + hidePagination('#p_pagination'); }, success: function (data) { setCategoryLinkActive($this); @@ -1815,12 +1807,8 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) { url: cat, // 完全保留原有请求URL,不修改 headers: HTML_PAGE_AJAX_HEADERS, beforeSend: function () { - const $pagingArea = $('#pagination .post-paging'); - if ($pagingArea.length) { - $pagingArea.html('
'); - } else { - showListLoading('.norpost_list'); - } + showListLoading('.norpost_list'); + hidePagination('#pagination'); }, success: function (data) { setCategoryLinkActive($this); @@ -1831,7 +1819,7 @@ $(document).on('click', '.posts_cat_nav ul li a', function (e) { updateLoadMorePagination('#pagination', '.norpost_list', data, '.arc_pagenav'); - $('.loading_box').remove(); + $('.norpost_list .loading_box').remove(); initAgree(); lazyLoadInstance.update(); $('.posts_cat_nav ul li a').removeClass('disabled'); diff --git a/templates/assets/js/pixplayer.js b/templates/assets/js/pixplayer.js index 737e536..7c0bf0c 100644 --- a/templates/assets/js/pixplayer.js +++ b/templates/assets/js/pixplayer.js @@ -41,38 +41,108 @@ var playlist = []; var post_playlist = []; var Paused = true; var playLrc = ''; +var standaloneTrack = false; var m_cover = $('.player_mod .m_cover img'); var m_title = $('.player_mod .m_info h2'); var m_artist = $('.player_mod .m_info small'); +// 将歌曲数据交给主题播放器。source 用于同步文章或片刻中的播放按钮状态。 +function playPlayerTrack(data, options) { + options = options || {}; + var source = options.source ? $(options.source) : $(); + var player = source.closest('.pix_player'); + var audio = audiobox[0]; + var currentSource = audio.getAttribute('src') || ''; + + if (!data || !data.url) { + return false; + } -$(document).on('click', '.play_btn', function () { $('.player_box').append(audiobox); $('.pix_player').removeClass('playing'); - $(this).parents('.pix_player').addClass('playing'); - var url = $(this).attr('data'); - var lrc = $(this).attr('lrc'); - var audio_s = $('#pix_player').attr('src'); + if (player.length) { + player.addClass('playing'); + } - var meta = $(this).siblings('.player_meta').find('.title'); - playLrc = lrc; - m_title.text(meta.find('.name').text()); - m_artist.text(meta.find('.author').text()); - m_cover.attr('src', $('.pix_player.playing .player_thum img').attr('src')); + playLrc = data.lrc || ''; + m_title.text(data.title || data.name || '未知歌曲'); + m_artist.text(data.author || data.artist || '未知歌手'); + if (data.pic) { + m_cover.attr('src', data.pic); + } - if (audio_s == '' || audio_s !== url) { - $('#pix_player').attr('src', url); - audiobox[0].play(); - } else { + standaloneTrack = options.standalone === true; + initAudio(); + if (options.toggle && currentSource === data.url) { pasued(); + } else { + audio.setAttribute('src', data.url); + var playPromise = audio.play(); + if (playPromise && typeof playPromise.catch === 'function') { + playPromise.catch(function () { + // 浏览器阻止自动播放时,保留播放器状态并等待用户点击播放。 + }); + } } $(".play_btn").html(""); + return true; +} - initAudio(); +$(document).on('click', '.play_btn', function () { + var meta = $(this).siblings('.player_meta').find('.title'); + playPlayerTrack({ + url: $(this).attr('data'), + lrc: $(this).attr('lrc'), + title: meta.find('.name').text(), + author: meta.find('.author').text(), + pic: $(this).closest('.pix_player').find('.player_thum img').attr('src') + }, { + source: this, + toggle: true, + standalone: false + }); }); +function musicApiUrl(server, type, id) { + var api = Theme.play.pix_mu_api || 'https://api.i-meto.com/meting/api'; + var separator = api.indexOf('?') === -1 ? '?' : '&'; + return api + separator + 'server=' + encodeURIComponent(server) + + '&type=' + encodeURIComponent(type) + '&id=' + encodeURIComponent(id) + + '&r=' + Math.random(); +} + +// 通过网易云歌曲 ID 获取歌曲数据,并使用主题播放器播放。 +function play_netease_music(songId) { + var id = String(songId == null ? '' : songId).trim(); + if (!id) { + if (typeof cocoMessage !== 'undefined') cocoMessage.error('网易云歌曲ID不能为空'); + return false; + } + + $.ajax({ + type: 'get', + url: musicApiUrl('netease', 'song', id) + }).done(function (res) { + var data = Array.isArray(res) ? res[0] : res; + if (res && !Array.isArray(res) && Array.isArray(res.data)) { + data = res.data[0]; + } + if (!data || !data.url) { + if (typeof cocoMessage !== 'undefined') cocoMessage.error('网易云歌曲无法播放'); + return; + } + playPlayerTrack(data, { standalone: true }); + }).fail(function () { + if (typeof cocoMessage !== 'undefined') cocoMessage.error('网易云歌曲加载失败'); + }); +} + +function playNeteaseMusic(songId) { + play_netease_music(songId); +} + // 初始化函数 function initAudio() { audiobox[0].addEventListener("play", audioplay); @@ -85,6 +155,7 @@ function initAudio() { //音乐结束触发 function endplay() { + if (standaloneTrack || !playlist[0] || playlist[0].length === 0) return; var index = $('.musci_list_box li.active').index() + 1; var max = $('.musci_list_box li').length; var new_mid = 0; @@ -223,6 +294,7 @@ function autoload_music() { type: "get", url: url, success: function (res) { + if (standaloneTrack) return; if (res.length > 0) { var new_mid = 0; if (loop == "none") { @@ -255,6 +327,7 @@ function autoload_music() { //播放选中音乐 function mulist_play(index) { + standaloneTrack = false; audiobox[0].removeEventListener("play", audioplay); audiobox[0].removeEventListener("pause", audiopause); $(".pix_player.playing .play_btn").html(""); @@ -493,6 +566,7 @@ function autoload_posts_music() { $(document).on('click', '.s_play_btn', function () { mu_box_show(); // 1. 同步更新文章内播放列表选中状态 + standaloneTrack = false; $('.posts_mu_list li').removeClass('active'); $(this).parent().addClass('active'); // 2. 同步更新全局播放列表选中状态(避免后续操作信息混乱) diff --git a/templates/equipments.html b/templates/equipments.html index b723143..ee18eca 100644 --- a/templates/equipments.html +++ b/templates/equipments.html @@ -1,100 +1,39 @@ - - - - - -
- - - -
- -
-
- -
- -
- -
- -
-
- -
- -
- - - -
-
- -
-
-
- -
-
-
-
-
-
- - - - - - - - - -
-
-
-
-
-
- - -
- -
-
- -
- -
-
- -
- - - -
-
- - \ No newline at end of file + + + + + +
+ + + +
+ + + + + + + + + + + + + +
+ + + +
+
+ + diff --git a/templates/macro/equipment.html b/templates/macro/equipment.html new file mode 100644 index 0000000..1c98f13 --- /dev/null +++ b/templates/macro/equipment.html @@ -0,0 +1,87 @@ + + +
+
+ +
+ +
+ +
+
+ +
+
+ + + 描述 + +
+
+
+ + + + +
+ + +
+
+ + +
+ 转到 + + + + + + + / [[${equipmentPage.totalPages}]] + +
+
+
+
+ +
+ +
+
+
diff --git a/templates/modules/footer.html b/templates/modules/footer.html index 595c5fe..540f0f8 100644 --- a/templates/modules/footer.html +++ b/templates/modules/footer.html @@ -1,5 +1,5 @@ - +
diff --git a/templates/modules/head.html b/templates/modules/head.html index 890436e..78dc2b7 100644 --- a/templates/modules/head.html +++ b/templates/modules/head.html @@ -1,4 +1,4 @@ - + diff --git a/theme.yaml b/theme.yaml index 67e84db..50e4239 100644 --- a/theme.yaml +++ b/theme.yaml @@ -17,7 +17,7 @@ spec: issues: "https://github.com/chengzhongxue/halo-theme-pix/issues" settingName: "theme-pix-setting" configMapName: "theme-pix-configMap" - version: "1.2.5-8" + version: "1.2.5-9" require: ">=2.20.0" customTemplates: page: