-
Notifications
You must be signed in to change notification settings - Fork 0
/
article.jsx
130 lines (125 loc) · 7.82 KB
/
article.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
const moment = require('moment');
const { Component, Fragment } = require('inferno');
const { toMomentLocale } = require('hexo/lib/plugins/helper/date');
const Share = require('./share');
const Donates = require('./donates');
const Comment = require('./comment');
const ArticleLicensing = require('hexo-component-inferno/lib/view/misc/article_licensing');
/**
* Get the word count of text.
*/
function getWordCount(content) {
if (typeof content === 'undefined') {
return 0;
}
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;
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);
return <Fragment>
{/* Main content */}
<div class="card">
{/* Thumbnail */}
{cover ? <div class="card-image">
{index ? <a href={url_for(page.link || page.path)} class="image is-7by3">
<img class="fill" src={cover} alt={page.title || cover} />
</a> : <span class="image is-7by3">
<img class="fill" src={cover} alt={page.title || cover} />
</span>}
</div> : null}
<article class={`card-content article${'direction' in page ? ' ' + page.direction : ''}`} role="article">
{/* Title */}
{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}
{/* Metadata */}
{page.layout !== 'page' ? <div class="article-meta is-size-7 is-uppercase level is-mobile">
<div class="level-left">
{/* Creation Date */}
<i class="far fa-calendar-alt"></i>
{page.date && <span class="level-item" dangerouslySetInnerHTML={{
__html: _p(`<time dateTime="${date_xml(page.date)}" title="${new Date(page.date).toLocaleString()}"> ${date(page.date)}</time>`)
}}></span>}
{/* Last Update Date */}
{shouldShowUpdated && <span class="level-item" dangerouslySetInnerHTML={{
__html: _p(`<time dateTime="${date_xml(page.updated)}" title="${new Date(page.updated).toLocaleString()}">${date(page.updated)}</time>`)
}}></span>}
{/* author */}
{page.author ? <span class="level-item"> {page.author} </span> : null}
{/* Categories */}
{page.categories && page.categories.length ? (<span class="level-item"><i class="far fa-folder-open has-text-grey"></i>
{(() => {
const categories = [];
page.categories.forEach((category, i) => {
categories.push(<a class="link-muted" href={url_for(category.path)}>{category.name}</a>);
if (i < page.categories.length - 1) {
categories.push(<span> / </span>);
}
});
return categories;
})()}
</span>) : null}
{/* Read time */}
{article && article.readtime && article.readtime === true ? (<span class="level-item"><i class="far fa-clock"></i>
{(() => {
const words = getWordCount(page._content);
const time = moment.duration((words / 150.0) * 60, 'seconds');
return ` ${_p(time.locale(index ? indexLaunguage : language).humanize())} read`;
})()}
</span>) : null}
{/* Visitor counter */}
{!index && plugins && plugins.busuanzi === true ? <span class="level-item" id="busuanzi_container_page_pv" dangerouslySetInnerHTML={{
__html: _p('plugin.visit_count', '<span id="busuanzi_value_page_pv">0</span>')
}}></span> : null}
</div>
</div> : null}
{/* 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}
{/* 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>;
})}
</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}
{/* Share button */}
{!index ? <Share config={config} page={page} helper={helper} /> : null}
</article>
</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}
{/* Comment */}
{!index ? <Comment config={config} page={page} helper={helper} /> : null}
</Fragment>;
}
};