diff --git a/_config.yml b/_config.yml index 0d31829167..5ec03f156a 100644 --- a/_config.yml +++ b/_config.yml @@ -610,6 +610,21 @@ reading_progress: # See: https://theme-next.org/docs/third-party-services/comments-and-widgets # --------------------------------------------------------------- +# Multiple Comment System Support +comments: + # Available values: tabs | buttons + style: tabs + # Choose a comment system to be displayed by default + # Available values: changyan | disqus | disqusjs | facebook_comments_plugin | gitalk | livere | valine | vkontakte + active: + # Setting `true` means remembering the comment system selected by the visitor + storage: true + # Modify icons and texts for any style, here are some examples + nav: + #disqus: disqus + #facebook_comments_plugin: facebook + #gitalk: Load Gitalk + # Disqus disqus: enable: false @@ -907,7 +922,6 @@ note: # Tabs tag tabs: - enable: true transition: tabs: false labels: true diff --git a/languages/en.yml b/languages/en.yml index ed25551727..b1fae2bc93 100644 --- a/languages/en.yml +++ b/languages/en.yml @@ -32,7 +32,6 @@ post: sticky: Sticky toc_empty: This post does not have a Table of Contents views: Views - comments_count: Comments related_posts: Related Posts copy_button: Copy copy_success: Copied diff --git a/layout/_partials/comments.swig b/layout/_partials/comments.swig index 3250cf4451..e47f6ac369 100644 --- a/layout/_partials/comments.swig +++ b/layout/_partials/comments.swig @@ -2,8 +2,80 @@ {%- if theme.injects.comment.length == 1 %} {%- set inject_item = theme.injects.comment[0] %} {{ partial(inject_item.layout, inject_item.locals, inject_item.options) }} + {%- elif theme.injects.comment.length > 1 %} + {%- if theme.comments.style == 'buttons' %} +
+ {%- for inject_item in theme.injects.comment %} + {{ inject_item.locals.button }} + {%- endfor %} +
+ {%- for inject_item in theme.injects.comment %} +
+ {{ partial(inject_item.layout, inject_item.locals, inject_item.options) }} +
+ {%- endfor %} + + (function() { + let commentButton = document.querySelectorAll('.comment-button'); + commentButton.forEach(item => { + let commentClass = item.classList[2]; + item.addEventListener('click', () => { + commentButton.forEach(rmActive => rmActive.classList.remove('active')); + item.classList.add('active'); + document.querySelectorAll('.comment-position').forEach(rmActive => rmActive.classList.remove('active')); + document.querySelector(`.comment-position.${commentClass}`).classList.add('active'); + {%- if theme.comments.storage %} + localStorage.setItem('comments_active', commentClass); + {%- endif %} + }); + }); + let activeClass = '{{ theme.comments.activeClass }}'; + {%- if theme.comments.storage %} + activeClass = localStorage.getItem('comments_active') || activeClass; + {%- endif %} + if (activeClass) { + let activeButton = document.querySelector(`.comment-button.${activeClass}`); + if (activeButton) { + activeButton.click(); + } + } + })(); + + {%- elif theme.comments.style == 'tabs' %} +
+ +
+ {%- for inject_item in theme.injects.comment %} +
+ {{ partial(inject_item.layout, inject_item.locals, inject_item.options) }} +
+ {%- endfor %} +
+
+ + {%- endif %} {%- endif %} -{# {%- for inject_item in theme.injects.comment %} - {{ partial(inject_item.layout, inject_item.locals, inject_item.options) }} -{%- endfor %} #} {%- endif %} diff --git a/layout/_partials/head/head.swig b/layout/_partials/head/head.swig index 3310789cc4..63679ff2c4 100644 --- a/layout/_partials/head/head.swig +++ b/layout/_partials/head/head.swig @@ -116,7 +116,6 @@ }, localsearch: {{ theme.local_search | json_encode }}, path: '{{ config.search.path }}', - tabs: {{ theme.tabs.enable }}, motion: {{ theme.motion | json_encode }}, translation: { copy_button: '{{__("post.copy_button")}}', diff --git a/scripts/filters/comment/changyan.js b/scripts/filters/comment/changyan.js index a49a1780c2..3101fbb977 100644 --- a/scripts/filters/comment/changyan.js +++ b/scripts/filters/comment/changyan.js @@ -29,13 +29,13 @@ hexo.extend.filter.register('theme_inject', injects => { injects.postMeta.raw('changyan', ` {% if post.comments %} - ${iconText} + ${iconText('comment-o', 'changyan')} {% if is_post() %} - + {% else %} - + {% endif %} diff --git a/scripts/filters/comment/common.js b/scripts/filters/comment/common.js index e48b387bc5..53ab5afbc8 100644 --- a/scripts/filters/comment/common.js +++ b/scripts/filters/comment/common.js @@ -1,10 +1,23 @@ 'use strict'; +function capitalize(input) { + return input.toString().charAt(0).toUpperCase() + input.toString().substr(1); +} + module.exports = { - iconText: ` - - - ` + iconText(icon, key, defaultValue) { + if (!defaultValue) { + defaultValue = capitalize(key); + } + return ` + + {%- set post_meta_comment = __('post.comments.${key}') %} + {%- if post_meta_comment == 'post.comments.${key}' %} + {%- set post_meta_comment = '${defaultValue}' %} + {%- endif %} + + `; + } }; diff --git a/scripts/filters/comment/default-config.js b/scripts/filters/comment/default-config.js new file mode 100644 index 0000000000..b8e115b9e8 --- /dev/null +++ b/scripts/filters/comment/default-config.js @@ -0,0 +1,31 @@ +/* global hexo */ + +'use strict'; + +const path = require('path'); + +hexo.extend.filter.register('theme_inject', injects => { + injects.comment.raws.forEach(element => { + // Set default button content + let injectName = path.basename(element.name, path.extname(element.name)); + element.args[0] = Object.assign({ + configKey: injectName, + class: injectName, + button: injectName + }, element.args[0]); + // Get locals and config + let locals = element.args[0]; + let config = hexo.theme.config.comments; + // Set activeClass + if (config.active === locals.configKey) { + config.activeClass = locals.class; + } + // Set custom button content + if (config.nav) { + let customButton = config.nav[locals.configKey]; + if (customButton) { + locals.button = customButton; + } + } + }); +}, 99999); diff --git a/scripts/filters/comment/disqus.js b/scripts/filters/comment/disqus.js index e44cc95bdb..2d24ab098a 100644 --- a/scripts/filters/comment/disqus.js +++ b/scripts/filters/comment/disqus.js @@ -33,8 +33,8 @@ hexo.extend.filter.register('theme_inject', injects => { injects.postMeta.raw('disqus', ` {% if post.comments %} diff --git a/scripts/filters/comment/facebook-comments-plugin.js b/scripts/filters/comment/facebook-comments-plugin.js index 7f34b8a79c..7e191f639e 100644 --- a/scripts/filters/comment/facebook-comments-plugin.js +++ b/scripts/filters/comment/facebook-comments-plugin.js @@ -19,7 +19,10 @@ hexo.extend.filter.register('theme_inject', injects => { data-colorscheme="{{ theme.facebook_comments_plugin.scheme }}"> - `); + `, { + configKey: 'facebook_comments_plugin', + button: ' facebook' + }); }, priority.facebook_comments_plugin); @@ -31,8 +34,8 @@ hexo.extend.filter.register('theme_inject', injects => { injects.postMeta.raw('facebook-comments-plugin', ` {% if post.comments %} diff --git a/scripts/filters/comment/valine.js b/scripts/filters/comment/valine.js index b71dd5462b..b60aa7b379 100644 --- a/scripts/filters/comment/valine.js +++ b/scripts/filters/comment/valine.js @@ -25,8 +25,8 @@ hexo.extend.filter.register('theme_inject', injects => { injects.postMeta.raw('valine', ` {% if post.comments and (is_post() or theme.valine.comment_count) %} diff --git a/scripts/filters/comment/vkontakte.js b/scripts/filters/comment/vkontakte.js index d8c19e0773..b608eaf6e1 100644 --- a/scripts/filters/comment/vkontakte.js +++ b/scripts/filters/comment/vkontakte.js @@ -9,6 +9,9 @@ hexo.extend.filter.register('theme_inject', injects => { let theme = hexo.theme.config; if (!theme.vkontakte_api.enable || !theme.vkontakte_api.comments) return; - injects.comment.raw('vkontakte-comments', '
', {}, {cache: true}); + injects.comment.raw('vkontakte-comments', '
', { + configKey: 'vkontakte', + button: ' vkontakte' + }, {cache: true}); }, priority.vkontakte_comments_plugin); diff --git a/scripts/filters/comment/warn.js b/scripts/filters/comment/warn.js deleted file mode 100644 index f040d90d9b..0000000000 --- a/scripts/filters/comment/warn.js +++ /dev/null @@ -1,19 +0,0 @@ -/* global hexo */ - -'use strict'; - -hexo.extend.filter.register('theme_inject', injects => { - if (injects.comment.raws.length > 1) { - hexo.log.warn('It is currently not supported to launch mutli-comments systems at the same time, so stay tuned for subsequent versions of iteration.'); - hexo.log.warn('Please keep one of the following.'); - injects.comment.raws.forEach(element => { - let commentName = element.name; - // List comment system - hexo.log.warn(' - ' + commentName); - // Close comment system - injects.postMeta.raw(commentName, '', {disableDefaultLayout: true}, {cache: true}); - injects.comment.raw(commentName, '', {}, {cache: true}); - injects.bodyEnd.raw(commentName, '', {}, {cache: true}); - }); - } -}, 999); diff --git a/source/css/_common/components/comments.styl b/source/css/_common/components/comments.styl index 9c8a2a0a54..402a417e98 100644 --- a/source/css/_common/components/comments.styl +++ b/source/css/_common/components/comments.styl @@ -2,3 +2,41 @@ margin: 60px 20px 0; overflow: hidden; } + +.comment-button-group { + display: flex; + flex-wrap: wrap-reverse; + justify-content: center; + margin: 1em 0; + + .comment-button { + margin: 0.1em 0.2em; + + &.active { + background: $btn-default-hover-bg; + border-color: $btn-default-hover-border-color; + color: $btn-default-hover-color; + } + } +} + +.comment-position { + display: none; + + &.active { + display: block; + } +} + +.tabs-comment { + background: white; + margin-top: 4em; + padding-top: 0; + + .comments { + border: 0; + box-shadow: none; + margin-top: 0; + padding-top: 0; + } +} diff --git a/source/css/_common/components/tags/tabs.styl b/source/css/_common/components/tags/tabs.styl index 6bcd90083a..8a25257d72 100644 --- a/source/css/_common/components/tags/tabs.styl +++ b/source/css/_common/components/tags/tabs.styl @@ -1,6 +1,9 @@ .post-body .tabs { - display: block; margin-bottom: 20px; +} + +.post-body .tabs, .tabs-comment { + display: block; padding-top: 10px; position: relative; // Read tabs border_radius from NexT config and set in "$tbr px" to use it as string variable in this CSS section. diff --git a/source/css/_common/components/tags/tags.styl b/source/css/_common/components/tags/tags.styl index edd0438f37..56cc2c9728 100644 --- a/source/css/_common/components/tags/tags.styl +++ b/source/css/_common/components/tags/tags.styl @@ -1,9 +1,8 @@ @import 'blockquote-center'; @import 'group-pictures'; @import 'label'; +@import 'tabs'; @import 'note' if (hexo-config('note.style') != 'disabled'); -@import 'tabs' if (hexo-config('tabs.enable')); - @import 'pdf' if (hexo-config('pdf.enable')); diff --git a/source/css/_schemes/Gemini/index.styl b/source/css/_schemes/Gemini/index.styl index d3231896fd..a05ca5553e 100644 --- a/source/css/_schemes/Gemini/index.styl +++ b/source/css/_schemes/Gemini/index.styl @@ -62,6 +62,10 @@ $use-seo = hexo-config('seo'); padding: $content-desktop-padding; } +.tabs-comment { + margin-top: 1em; +} + // Top main padding from header to posts (default 40px). .posts-expand { padding-top: initial; @@ -239,7 +243,7 @@ $use-seo = hexo-config('seo'); .comments { margin-top: $content-mobile-padding; - padding: 10 $sidebar-offset; + padding: 10px $sidebar-offset; } .pagination { diff --git a/source/js/next-boot.js b/source/js/next-boot.js index 58ae2635b7..f257daa4df 100644 --- a/source/js/next-boot.js +++ b/source/js/next-boot.js @@ -53,7 +53,7 @@ $(document).on('DOMContentLoaded pjax:success', function() { CONFIG.pangu && window.pangu.spacingPage(); CONFIG.copycode.enable && NexT.utils.registerCopyCode(); - CONFIG.tabs && NexT.utils.registerTabsTag(); + NexT.utils.registerTabsTag(); NexT.utils.registerActiveMenuItem(); NexT.utils.embeddedVideoTransformer(); diff --git a/source/js/utils.js b/source/js/utils.js index 3f3f1f25bd..83f6969753 100644 --- a/source/js/utils.js +++ b/source/js/utils.js @@ -129,8 +129,14 @@ NexT.utils = { $(this).addClass('active').siblings().removeClass('active'); var tActive = $(this).find('a').attr('href'); $(tActive).addClass('active').siblings().removeClass('active'); + // Trigger event + document.querySelector(tActive).dispatchEvent(new Event('tabs:click', { + bubbles: true + })); } }); + + window.dispatchEvent(new Event('tabs:register')); }, registerCanIUseTag: function() {