diff --git a/README.md b/README.md index 4e851b4..793fd49 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ npm i hexo-theme-butterfly - [x] Related articles - [x] Displays outdated notice for a post - [x] Share (AddThis/Sharejs/Addtoany) -- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments/Twikoo) +- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo) - [x] Multiple Comment System Support - [x] Online Chats (Chatra/Tidio/Daovoice/Gitter/Crisp) - [x] Web analytics (Baidu Analytics/Google Analytics/Tencent Analytics/CNZZ Analytics) diff --git a/README_CN.md b/README_CN.md index 713e6f4..4a8e8c5 100644 --- a/README_CN.md +++ b/README_CN.md @@ -71,7 +71,7 @@ theme: butterfly - [x] 顯示相關文章 - [x] 過期文章提醒 - [x] 多種分享系統(AddThis/Sharejs/Addtoany) -- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments/Twikoo) +- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo) - [x] 支持雙評論部署 - [x] 多種在線聊天(Chatra/Tidio/Daovoice/Gitter/Crisp) - [x] 多種分析系統(百度分析/谷歌分析/騰訊分析/CNZZ分析) diff --git a/_config.yml b/_config.yml index 8515a5f..b161c23 100644 --- a/_config.yml +++ b/_config.yml @@ -240,7 +240,7 @@ addtoany: comments: # Up to two comments system, the first will be shown as default - # Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Utterances/Facebook Comments/Twikoo + # Choose: Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo use: # - Valine # - Disqus @@ -304,6 +304,14 @@ valine: requiredFields: nick,mail # required fields (nick/mail) option: +# waline - A simple comment system with backend support fork from Valine +# https://waline.js.org/ +waline: + serverURL: # Waline server address url + avatar: monsterid # gravatar style https://zh-tw.gravatar.com/site/implement/images/#default-image + bg: /image/comment_bg.png # waline background + option: + # utterances # https://utteranc.es/ utterances: @@ -656,12 +664,8 @@ newest_comments: enable: false limit: 6 avatar: true - leancloud: - enable: false - appId: # leancloud application app id - appKey: # leancloud application app key - serverURL: # This configuration is suitable for domestic custom domain name users, overseas version will be automatically detected (no need to manually fill in) - default_avatar: # mp/identicon/monsterid/wavatar/retro/robohash/blank + # You can only choose one, or neither + valine: false github_issues: enable: false repo: @@ -670,6 +674,7 @@ newest_comments: forum: api_key: twikoo: false + waline: false # Bottom right button (右下角按鈕) # -------------------------------------- @@ -848,6 +853,7 @@ CDN: disqusjs_css: https://cdn.jsdelivr.net/npm/disqusjs@1/dist/disqusjs.css utterances: https://utteranc.es/client.js twikoo: https://cdn.jsdelivr.net/npm/twikoo/dist/twikoo.all.min.js + waline: https://cdn.jsdelivr.net/npm/@waline/client/dist/Waline.min.js # share addtoany: https://static.addtoany.com/menu/page.js diff --git a/layout/includes/header/post-info.pug b/layout/includes/header/post-info.pug index 96f1e9b..687660c 100644 --- a/layout/includes/header/post-info.pug +++ b/layout/includes/header/post-info.pug @@ -65,24 +65,30 @@ span.post-meta-label= _p('post.comments') + ':' if block block - - if whichCount === 'Disqus' || whichCount === 'Disqusjs' - +countBlock - span.disqus-comment-count - a(href=full_url_for(page.path) + '#disqus_thread') - else if whichCount === 'Valine' - +countBlock - a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl") - span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount") - else if whichCount === 'Gitalk' - +countBlock - a(href=url_for(page.path) + '#post-comment') - span.gitalk-#card-toc - else if whichCount === 'Twikoo' - +countBlock - a(href=url_for(page.path) + '#post-comment') - span#twikoo-count - else if whichCount === 'Facebook Comments' - +countBlock - a(href=url_for(page.path) + '#post-comment') - span.fb-comments-count(data-href=urlNoIndex()) \ No newline at end of file + + case whichCount + when 'Disqus' + when 'Disqusjs' + +countBlock + span.disqus-comment-count + a(href=full_url_for(page.path) + '#disqus_thread') + when 'Valine' + +countBlock + a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl") + span.valine-comment-count(data-xid=url_for(page.path) itemprop="commentCount") + when 'Waline' + +countBlock + a(href=url_for(page.path) + '#post-comment') + span.waline-comment-count(id=url_for(page.path)) + when 'Gitalk' + +countBlock + a(href=url_for(page.path) + '#post-comment') + span.gitalk-#card-toc + when 'Twikoo' + +countBlock + a(href=url_for(page.path) + '#post-comment') + span#twikoo-count + when 'Facebook Comments' + +countBlock + a(href=url_for(page.path) + '#post-comment') + span.fb-comments-count(data-href=urlNoIndex()) \ No newline at end of file diff --git a/layout/includes/third-party/comments/index.pug b/layout/includes/third-party/comments/index.pug index 4514fce..d216be2 100644 --- a/layout/includes/third-party/comments/index.pug +++ b/layout/includes/third-party/comments/index.pug @@ -31,6 +31,8 @@ hr #utterances-wrap when 'Twikoo' #twikoo-wrap + when 'Waline' + #waline when 'Facebook Comments' .fb-comments(data-colorscheme = theme.display_mode === 'dark' ? 'dark' : 'light' data-numposts= theme.facebook_comments.pageSize || 10 diff --git a/layout/includes/third-party/comments/js.pug b/layout/includes/third-party/comments/js.pug index 07a6f12..404149b 100644 --- a/layout/includes/third-party/comments/js.pug +++ b/layout/includes/third-party/comments/js.pug @@ -14,5 +14,7 @@ each name in theme.comments.use !=partial('includes/third-party/comments/utterances', {}, {cache:theme.fragment_cache}) when 'Twikoo' !=partial('includes/third-party/comments/twikoo', {}, {cache:theme.fragment_cache}) + when 'Waline' + !=partial('includes/third-party/comments/waline', {}, {cache:theme.fragment_cache}) when 'Facebook Comments' !=partial('includes/third-party/comments/facebook_comments', {}, {cache:theme.fragment_cache}) diff --git a/layout/includes/third-party/comments/waline.pug b/layout/includes/third-party/comments/waline.pug new file mode 100644 index 0000000..82d131d --- /dev/null +++ b/layout/includes/third-party/comments/waline.pug @@ -0,0 +1,34 @@ +- let option = theme.waline.option ? JSON.stringify(theme.waline.option) : false + +script. + function loadWaline () { + function initWaline () { + let initData = { + el: '#waline', + serverURL: '!{theme.waline.serverURL}', + avatar: '#{theme.waline.avatar}', + path: location.pathname, + } + + if (!{Boolean(option)}) { + const otherData = !{option} + initData = Object.assign({}, initData, otherData) + } + + const waline = new Waline(initData) + } + + if (typeof Waline === 'function') initWaline() + else getScript('!{url_for(theme.CDN.waline)}').then(initWaline) + } + + if ('!{theme.comments.use[0]}' === 'Waline' || !!{theme.comments.lazyload}) { + if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#waline'),loadWaline) + else setTimeout(loadWaline, 0) + } else { + function loadOtherComment () { + loadWaline() + } + } + + diff --git a/layout/includes/third-party/newest-comments/index.pug b/layout/includes/third-party/newest-comments/index.pug index bf422c4..ac50aa7 100644 --- a/layout/includes/third-party/newest-comments/index.pug +++ b/layout/includes/third-party/newest-comments/index.pug @@ -1,8 +1,12 @@ -if theme.newest_comments.leancloud.enable - include ./leancloud.pug -else if theme.newest_comments.github_issues.enable +- let config = theme.newest_comments + +if config.valine + include ./valine.pug +else if config.waline + include ./waline.pug +else if config.github_issues.enable include ./github-issues.pug -else if theme.newest_comments.disqus.enable +else if config.disqus.enable include ./disqus-comment.pug -else if theme.newest_comments.twikoo +else if config.twikoo include ./twikoo-comment.pug \ No newline at end of file diff --git a/layout/includes/third-party/newest-comments/leancloud.pug b/layout/includes/third-party/newest-comments/valine.pug similarity index 87% rename from layout/includes/third-party/newest-comments/leancloud.pug rename to layout/includes/third-party/newest-comments/valine.pug index 2e53917..5006ef8 100644 --- a/layout/includes/third-party/newest-comments/leancloud.pug +++ b/layout/includes/third-party/newest-comments/valine.pug @@ -1,3 +1,5 @@ +- let default_avatar = theme.valine.avatar + script(src="https://cdn.jsdelivr.net/npm/blueimp-md5@2.17.0/js/md5.min.js") script. window.addEventListener('load', () => { @@ -17,7 +19,7 @@ script. const getIcon = (icon, mail) => { if (icon) return icon - let defaultIcon = '!{ theme.newest_comments.leancloud.default_avatar ? `?d=${theme.newest_comments.leancloud.default_avatar}` : ''}' + let defaultIcon = '!{ default_avatar ? `?d=${default_avatar}` : ''}' let iconUrl = `https://gravatar.loli.net/avatar/${md5(mail.toLowerCase()) + defaultIcon}` return iconUrl } @@ -54,17 +56,17 @@ script. const getComment = () => { let serverURL = '' - if (!{Boolean(theme.newest_comments.leancloud.serverURL)}) { - serverURL = '!{theme.newest_comments.leancloud.serverURL}' + if (!{Boolean(theme.valine.serverURLs)}) { + serverURL = '!{theme.valine.serverURLs}' } else { - serverURL = 'https://!{theme.newest_comments.leancloud.appId.substring(0,8)}.api.lncldglobal.com' + serverURL = 'https://!{theme.valine.appId.substring(0,8)}.api.lncldglobal.com' } var settings = { "method": "GET", "headers": { - "X-LC-Id": '!{theme.newest_comments.leancloud.appId}', - "X-LC-Key": '!{theme.newest_comments.leancloud.appKey}', + "X-LC-Id": '!{theme.valine.appId}', + "X-LC-Key": '!{theme.valine.appKey}', "Content-Type": "application/json" }, } diff --git a/layout/includes/third-party/newest-comments/waline.pug b/layout/includes/third-party/newest-comments/waline.pug new file mode 100644 index 0000000..49fb306 --- /dev/null +++ b/layout/includes/third-party/newest-comments/waline.pug @@ -0,0 +1,95 @@ +- let default_avatar = theme.waline.avatar + +script. + window.addEventListener('load', () => { + const changeContent = (content) => { + if (content === '') return content + + content = content.replace(/<[^>]+>/g,"") // remove html tag + content = content.replace(/(http(s?):)([/|.|\w|\s|-])*\.(?:jpg|jpeg|gif|png|webp)/g, '') // remove image link + content = content.replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gi, '') // remove url + + if (content.length > 150) { + content = content.substring(0,150) + '...' + } + return content + } + + const getIcon = (mail) => { + let defaultIcon = '!{ default_avatar ? `?d=${default_avatar}` : ''}' + let iconUrl = `https://gravatar.loli.net/avatar/${mail + defaultIcon}` + return iconUrl + } + + const generateHtml = array => { + let result = '' + + if (array.length) { + for (let i = 0; i < array.length; i++) { + result += '
' + + if (!{theme.newest_comments.avatar}) { + let name = 'src' + if(!{theme.lazyload.enable}) { + name = 'data-lazy-src' + } + result += `${array[i].nick}` + } + + result += `
+ ${array[i].content} +
${array[i].nick}
+
` + } + } else { + result += '!{_p("aside.card_newest_comments.zero")}' + } + + let $dom = document.querySelector('#card-newest-comments .aside-list') + $dom.innerHTML= result + window.lazyLoadInstance && window.lazyLoadInstance.update() + window.pjax && window.pjax.refresh($dom) + } + + const getComment = () => { + const loadWaline = () => { + Waline.Widget.RecentComments({ + el: '#card-newest-comments .aside-list', + serverURL: '!{theme.waline.serverURL}', + count: !{theme.newest_comments.limit} + }).then(comments => { + const walineArray = comments.map(function (e) { + return { + 'content': changeContent(e.comment), + 'mail': e.mail, + 'nick': e.nick, + 'url': e.url, + 'date': e.createdAt, + } + }) + saveToLocal.set('waline-newest-comments', JSON.stringify(walineArray), 10/(60*24)) + generateHtml(walineArray) + }).catch(e => { + const $dom = document.querySelector('#card-newest-comments .aside-list') + $dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" + }) + } + + if (typeof Waline === 'function') loadWaline() + else getScript('!{url_for(theme.CDN.waline)}').then(loadWaline) + } + + const newestCommentInit = () => { + if (document.querySelector('#card-newest-comments .aside-list')) { + const data = saveToLocal.get('waline-newest-comments') + if (data) { + generateHtml(JSON.parse(data)) + } else { + getComment() + } + } + } + + newestCommentInit() + document.addEventListener('pjax:complete', newestCommentInit) + }) diff --git a/package.json b/package.json index 3039164..5f69624 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-theme-butterfly", - "version": "3.4.1", + "version": "3.5.0-b1", "description": "A Simple and Card UI Design theme for Hexo", "main": "package.json", "scripts": { diff --git a/source/css/_layout/third-party.styl b/source/css/_layout/third-party.styl index 3ffd4aa..3c1ab6c 100644 --- a/source/css/_layout/third-party.styl +++ b/source/css/_layout/third-party.styl @@ -1,4 +1,5 @@ -#vcomment +#vcomment, +#waline font-size: 1.1em .vbtn @@ -9,12 +10,9 @@ &:hover background: var(--btn-hover-color) - if hexo-config('valine.bg') - textarea - background: url(hexo-config('valine.bg')) 100% 100% no-repeat - - &:focus - background-image: none + textarea + &:focus + background-image: none .vimg transition: all .3s @@ -27,6 +25,16 @@ &:after z-index: 22 +if hexo-config('valine.bg') + #vcomment + textarea + background: url(hexo-config('valine.bg')) 100% 100% no-repeat + +if hexo-config('waline.bg') + #waline + textarea + background: url(hexo-config('waline.bg')) 100% 100% no-repeat + .fireworks position: fixed top: 0 diff --git a/source/js/main.js b/source/js/main.js index 15a8081..e541bdd 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -288,15 +288,17 @@ document.addEventListener('DOMContentLoaded', function () { } const jqLoadAndRun = () => { - const isFancybox = GLOBAL_CONFIG.lightbox === 'fancybox' - const $fancyboxEle = isFancybox ? document.querySelectorAll('#article-container :not(a):not(.gallery-group) > img, #article-container > img') : null + const $fancyboxEle = GLOBAL_CONFIG.lightbox === 'fancybox' + ? document.querySelectorAll('#article-container :not(a):not(.gallery-group) > img, #article-container > img') + : [] + const fbLengthNoZero = $fancyboxEle.length > 0 const $jgEle = document.querySelectorAll('#article-container .justified-gallery') - const jgEleLength = $jgEle.length + const jgLengthNoZero = $jgEle.length > 0 - if (jgEleLength || $fancyboxEle !== null) { + if (jgLengthNoZero || fbLengthNoZero) { btf.isJqueryLoad(() => { - jgEleLength && runJustifiedGallery($jgEle) - isFancybox && addFancybox($fancyboxEle) + jgLengthNoZero && runJustifiedGallery($jgEle) + fbLengthNoZero && addFancybox($fancyboxEle) }) } }