Skip to content

Commit

Permalink
feat(view): Add support for Giscus
Browse files Browse the repository at this point in the history
  • Loading branch information
PJ-568 committed Jun 2, 2024
1 parent 742346a commit 3ce75c0
Show file tree
Hide file tree
Showing 2 changed files with 271 additions and 0 deletions.
115 changes: 115 additions & 0 deletions src/schema/comment/giscus.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/comment/giscus.json",
"description": "Giscus comment plugin configurations",
"type": "object",
"properties": {
"type": {
"type": "string",
"const": "giscus"
},
"repo": {
"type": "string",
"description": "GitHub repository to which Giscus connects"
},
"repoId": {
"type": "string",
"description": "GitHub repository id to which Giscus connects"
},
"category": {
"type": "string",
"description": "The discussion category where new discussions will be created",
"default": "Announcements",
"nullable": true
},
"categoryId": {
"type": "string",
"description": "Id code of the category of Github discussions which Giscus will access to"
},
"mapping": {
"type": "string",
"description": "The mapping between the embedding page and the embedded discussion",
"enum": [
"pathname",
"url",
"title",
"og:title",
"specific",
"number"
],
"default": "pathname",
"nullable": true
},
"strict": {
"type": "boolean",
"description": "Avoid mismatches due to GitHub's fuzzy searching method when there are multiple discussions with similar titles",
"default": false,
"nullable": true
},
"reactionsEnabled": {
"type": "boolean",
"description": "Whether enable reactions",
"default": false,
"nullable": true
},
"emitMetadata": {
"type": "boolean",
"description": "Whether will discussion emit metadata",
"default": false,
"nullable": true
},
"inputPosition": {
"type": "string",
"description": "Where the input block will display",
"enum": [
"top",
"bottom"
],
"default": "top",
"nullable": true
},
"theme": {
"type": "string",
"description": "Giscus look and feel",
"enum": [
"light",
"light_high_contrast",
"light_protanopia",
"light_tritanopia",
"dark",
"dark_high_contrast",
"dark_protanopia",
"dark_tritanopia",
"dark_dimmed",
"preferred_color_scheme",
"transparent_dark",
"noborder_light",
"noborder_dark",
"noborder_gray",
"cobalt",
"purple_dark",
"custom"
],
"default": "noborder_light",
"nullable": true
},
"customThemeCss": {
"type": "string",
"description": "The url of custom Giscus theme css, only affect when theme is set to custom",
"nullable": true
},
"lang": {
"type": "string",
"description": "Language of Giscus",
"default": "en",
"nullable": true
},
"lazy": {
"type": "boolean",
"description": "Loading of the comments will be deferred until the user scrolls near the comments container",
"default": false,
"nullable": true
}
},
"required": ["repo", "repoId", "categoryId"]
}
156 changes: 156 additions & 0 deletions src/view/comment/giscus.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/**
* Giscus comment JSX component.
* @module view/comment/giscus
*/
const { Component } = require('inferno');
const { cacheComponent } = require('../../util/cache');

/**
* Giscus comment JSX component.
*
* @see https://giscus.app/
* @example
* <Giscus
* repo="usr/repo"
* repoId="X_xxxxxxxxxx"
* category="******"
* categoryId="XXX_xxxxxxxxxxxxxxxx"
* mapping="******"
* strict={0}
* reactionsEnabled={0}
* emitMetadata={0}
* inputPosition="******"
* theme="******"
* lang="******"
* lazy="******" />
*/
class Giscus extends Component {
render() {
const { repo, repoId, category, categoryId, mapping, term, strict, reactionsEnabled, emitMetadata, inputPosition, theme, customThemeCss, lang, lazy } = this.props;
if (!repo || !repoId || !categoryId) {
return (
<div class="notification is-danger">
You forgot to set the <code>repo</code>, <code>repoId</code>, or{' '}
<code>categoryId</code> for Giscus. Please set it in <code>_config.yml</code>.
</div>
);
}
if ((mapping == "specific" || mapping == "number") && !term) {
return (
<div class="notification is-danger">
You set <code>mapping</code> to <code>specific</code> or <code>number</code>, but did not set <code>term</code> for Giscus. Please set <code>term</code> in <code>_config.yml</code>.
</div>
);
}
const config = { repo };
if (category) {
config['data-category'] = category;
} else {
config['data-category'] = 'Announcements';
}
if(mapping) {
config['data-mapping'] = mapping;
} else {
config['data-mapping'] = 'pathname';
}
if(strict) {
config['data-strict'] = 1;
} else {
config['data-strict'] = 0;
}
if(reactionsEnabled) {
config['data-reactions-enabled'] = 1;
} else {
config['data-reactions-enabled'] = 0;
}
if(emitMetadata) {
config['data-emit-metadata'] = 1;
} else {
config['data-emit-metadata'] = 0;
}
if(inputPosition) {
config['data-input-position'] = inputPosition;
} else {
config['data-input-position'] = 'top'
}
if (theme) {
if (theme == "custom") {
if (customThemeCss) {
config['data-theme'] = customThemeCss;
} else {
return (
<div class="notification is-danger">
You set <code>theme</code> to <code>custom</code>, but did not apply a <code>customThemeCss</code> for Giscus. Please set it in <code>_config.yml</code>.
</div>
);
}
} else {
config['data-theme'] = theme;
}
} else {
config['data-theme'] = 'noborder_light';
}
if (lang) {
config['data-lang'] = lang;
} else {
config['data-lang'] = 'en';
}
if (lazy) {
config['data-loading'] = 'lazy';
}
return (
<script
src="https://giscus.app/client.js"
{...config}
crossorigin="anonymous"
async={true}></script>
);
}
}

/**
* Cacheable Giscus comment JSX component.
* <p>
* This class is supposed to be used in combination with the <code>locals</code> hexo filter
* ({@link module:hexo/filter/locals}).
*
* @see module:util/cache.cacheComponent
* @example
* <Giscus.Cacheable
* comment={{
* repo: "usr/repo"
* repoId: "X_xxxxxxxxxx"
* category: "******"
* categoryId: "XXX_xxxxxxxxxxxxxxxx"
* mapping: "******"
* strict: {false}
* reactionsEnabled: {false}
* emitMetadata: {false}
* inputPosition: "******"
* theme: "******"
* lang: "******"
* lazy: "******"
* }} />
*/
Giscus.Cacheable = cacheComponent(Giscus, 'comment.giscus', (props) => {
const { repo, repoId, category, categoryId, mapping, term, strict, reactionsEnabled, emitMetadata, inputPosition, theme, customThemeCss, lang, lazy } = props.comment;

return {
repo,
repoId,
category,
categoryId,
mapping,
term,
strict,
reactionsEnabled,
emitMetadata,
inputPosition,
theme,
customThemeCss,
lang,
lazy
};
});

module.exports = Giscus;

0 comments on commit 3ce75c0

Please sign in to comment.