hexo-theme-amane/layout/common/article.jsx

129 lines
7.7 KiB
React
Raw Normal View History

2019-12-23 21:18:59 +00:00
const moment = require('moment');
const { Component, Fragment } = require('inferno');
const { toMomentLocale } = require('hexo/lib/plugins/helper/date');
2019-12-23 21:18:59 +00:00
const Share = require('./share');
const Donates = require('./donates');
const Comment = require('./comment');
const ArticleLicensing = require('hexo-component-inferno/lib/view/misc/article_licensing');
2019-12-23 21:18:59 +00:00
/**
* Get the word count of text.
2019-12-23 21:18:59 +00:00
*/
function getWordCount(content) {
if (typeof content === 'undefined') {
return 0;
}
2019-12-23 21:18:59 +00:00
content = content.replace(/<\/?[a-z][^>]*>/gi, '');
content = content.trim();
return content ? (content.match(/[\u00ff-\uffff]|[a-zA-Z]+/g) || []).length : 0;
}
module.exports = class extends Component {
render() {
const { config, helper, page, index } = this.props;
const { article, plugins } = config;
const { url_for, date, date_xml, __, _p } = helper;
2019-12-23 21:18:59 +00:00
const indexLaunguage = toMomentLocale(config.language || 'en');
const language = toMomentLocale(page.lang || page.language || config.language || 'en');
const cover = page.cover ? url_for(page.cover) : null;
const updateTime = article && article.update_time !== undefined ? article.update_time : true;
const isUpdated = page.updated && !moment(page.date).isSame(moment(page.updated));
const shouldShowUpdated = page.updated && ((updateTime === 'auto' && isUpdated) || updateTime === true);
2019-12-23 21:18:59 +00:00
return <Fragment>
{/* Main content */}
<div class="card">
2019-12-23 21:18:59 +00:00
{/* Thumbnail */}
{cover ? <div class="card-image">
{index ? <a href={url_for(page.link || page.path)} class="image is-7by3">
2023-02-23 13:38:25 +00:00
<img class="fill lazy" data-src={cover} alt={page.title || cover} />
</a> : <span class="image is-7by3">
2023-02-23 13:38:25 +00:00
<img class="fill lazy" data-src={cover} alt={page.title || cover} />
2019-12-23 21:18:59 +00:00
</span>}
</div> : null}
<article class={`card-content article${'direction' in page ? ' ' + page.direction : ''}`} role="article">
{/* Metadata */}
{page.layout !== 'page' ? <div class="article-meta is-size-7 is-uppercase level is-mobile">
<div class="level-left">
2020-08-16 04:18:41 +00:00
{/* Creation Date */}
{page.date && <span class="level-item" dangerouslySetInnerHTML={{
__html: _p('article.created_at', `<time dateTime="${date_xml(page.date)}" title="${new Date(page.date).toLocaleString()}">${date(page.date)}</time>`)
2020-08-16 04:18:41 +00:00
}}></span>}
{/* Last Update Date */}
{shouldShowUpdated && <span class="level-item" dangerouslySetInnerHTML={{
__html: _p('article.updated_at', `<time dateTime="${date_xml(page.updated)}" title="${new Date(page.updated).toLocaleString()}">${date(page.updated)}</time>`)
2020-08-16 04:18:41 +00:00
}}></span>}
2020-05-04 23:46:33 +00:00
{/* author */}
{page.author ? <span class="level-item"> {page.author} </span> : null}
2019-12-23 21:18:59 +00:00
{/* Categories */}
{page.categories && page.categories.length ? <span class="level-item">
2019-12-23 21:18:59 +00:00
{(() => {
const categories = [];
page.categories.forEach((category, i) => {
categories.push(<a class="link-muted" href={url_for(category.path)}>{category.name}</a>);
2019-12-23 21:18:59 +00:00
if (i < page.categories.length - 1) {
categories.push(<span>&nbsp;/&nbsp;</span>);
2019-12-23 21:18:59 +00:00
}
});
return categories;
})()}
</span> : null}
2019-12-23 21:18:59 +00:00
{/* Read time */}
{article && article.readtime && article.readtime === true ? <span class="level-item">
2019-12-23 21:18:59 +00:00
{(() => {
const words = getWordCount(page._content);
const time = moment.duration((words / 150.0) * 60, 'seconds');
2020-08-16 04:18:41 +00:00
return `${_p('article.read_time', time.locale(index ? indexLaunguage : language).humanize())} (${_p('article.word_count', words)})`;
2019-12-23 21:18:59 +00:00
})()}
</span> : null}
{/* Visitor counter */}
{!index && plugins && plugins.busuanzi === true ? <span class="level-item" id="busuanzi_container_page_pv" dangerouslySetInnerHTML={{
2020-08-16 04:18:41 +00:00
__html: _p('plugin.visit_count', '<span id="busuanzi_value_page_pv">0</span>')
}}></span> : null}
2019-12-23 21:18:59 +00:00
</div>
</div> : null}
{/* Title */}
2023-02-18 14:00:46 +00:00
{page.title !== '' && index ? <p class="title is-3 is-size-4-mobile"><a class="link-muted" href={url_for(page.link || page.path)}>{page.title}</a></p> : null}
{page.title !== '' && !index ? <h1 class="title is-3 is-size-4-mobile">{page.title}</h1> : null}
2019-12-23 21:18:59 +00:00
{/* Content/Excerpt */}
<div class="content" dangerouslySetInnerHTML={{ __html: index && page.excerpt ? page.excerpt : page.content }}></div>
{/* Licensing block */}
{!index && article && article.licenses && Object.keys(article.licenses)
? <ArticleLicensing.Cacheable page={page} config={config} helper={helper} /> : null}
2019-12-23 21:18:59 +00:00
{/* Tags */}
{!index && page.tags && page.tags.length ? <div class="article-tags is-size-7 mb-4">
<span class="mr-2">#</span>
{page.tags.map(tag => {
return <a class="link-muted mr-2" rel="tag" href={url_for(tag.path)}>{tag.name}</a>;
})}
2019-12-23 21:18:59 +00:00
</div> : null}
{/* "Read more" button */}
{index && page.excerpt ? <a class="article-more button is-small is-size-7" href={`${url_for(page.link || page.path)}#more`}>{__('article.more')}</a> : null}
2019-12-23 21:18:59 +00:00
{/* Share button */}
{!index ? <Share config={config} page={page} helper={helper} /> : null}
</article>
2019-12-23 21:18:59 +00:00
</div>
{/* Donate button */}
{!index ? <Donates config={config} helper={helper} /> : null}
{/* Post navigation */}
{!index && (page.prev || page.next) ? <nav class="post-navigation mt-4 level is-mobile">
{page.prev ? <div class="level-start">
<a class={`article-nav-prev level level-item${!page.prev ? ' is-hidden-mobile' : ''} link-muted`} href={url_for(page.prev.path)}>
<i class="level-item fas fa-chevron-left"></i>
<span class="level-item">{page.prev.title}</span>
</a>
</div> : null}
{page.next ? <div class="level-end">
<a class={`article-nav-next level level-item${!page.next ? ' is-hidden-mobile' : ''} link-muted`} href={url_for(page.next.path)}>
<span class="level-item">{page.next.title}</span>
<i class="level-item fas fa-chevron-right"></i>
</a>
</div> : null}
</nav> : null}
2019-12-23 21:18:59 +00:00
{/* Comment */}
{!index ? <Comment config={config} page={page} helper={helper} /> : null}
</Fragment>;
}
};