feat: display how long ago in home articles

This commit is contained in:
XPoet 2020-11-24 20:06:08 +08:00
parent 74aa953a41
commit 90f06b8940
9 changed files with 131 additions and 65 deletions

View File

@ -35,3 +35,11 @@ copyright:
create_time: Create time
license_title: Copyright Notice
license_content: "All articles in this blog are licensed under %s unless stating additionally."
ago:
second: "%s seconds ago"
minute: "%s minutes ago"
hour: "%s hours ago"
day: "%s days age"
week: "%s weeks age"
month: "%s months age"
year: "%s years age"

View File

@ -35,3 +35,11 @@ copyright:
create_time: 创建时间
license_title: 版权声明
license_content: "本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!"
ago:
second: "%s 秒前"
minute: "%s 分钟前"
hour: "%s 小时前"
day: "%s 天前"
week: "%s 周前"
month: "%s 月前"
year: "%s 年前"

View File

@ -29,11 +29,6 @@
author = author.toLocaleLowerCase();
}
let email = '<%= theme.base_info.email %>';
if (email) {
email = email.toLocaleLowerCase();
}
for (let vcard of vcards) {
const vnick = vcard.querySelector('.vhead .vnick');
if (vnick.innerHTML.toLocaleLowerCase() === author) {

View File

@ -1,6 +1,6 @@
<div class="home-article-meta-info-container">
<div class="home-article-meta-info">
<span><i class="fas fa-edit"></i> <%- moment(post.date, Date.now()).locale(config.language).fromNow() %></span>
<span><i class="fas fa-edit"></i> <span class="home-article-date" data-date="<%= post.date %>"><%= date(post.date, 'YYYY-MM-DD') %></span></span>
<% if (post.categories.length && theme.home_article.category.enable === true) { %>
<span class="home-article-category"><i class="fas fa-folder"></i>
<ul>

View File

@ -3,27 +3,51 @@
'use strict';
const url = require('url');
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
/**
* Export theme config to js
*/
hexo.extend.helper.register('export_config', function () {
let { config, theme } = this;
let exportConfig = {
// ------ export language to js ------
const languageDir = path.join(__dirname, '../../languages');
let file = fs.readdirSync(languageDir).find(v => v === `${config.language}.yml`);
file = languageDir + '/' + (file ? file : 'en.yml');
let languageContent = fs.readFileSync(file, 'utf8');
try {
languageContent = yaml.safeLoad(languageContent);
} catch (e) {
console.log(e);
}
// ---------------------------------
let hexo_config = {
hostname: url.parse(config.url).hostname || config.url,
root: config.root,
localsearch: theme.local_search,
codeblock: theme.codeblock,
toc: theme.toc,
back2top: theme.back2top,
side_tools: theme.side_tools,
style: theme.style
root: config.root
};
if (config.search) {
exportConfig.path = config.search.path;
hexo_config.path = config.search.path;
}
let theme_config = {
toc: theme.toc,
left_side_width: theme.left_side_width,
local_search: theme.local_search,
side_tools: theme.side_tools,
version: theme.version,
}
return `<script id="hexo-configurations">
let KEEP = window.KEEP || {};
let CONFIG = ${JSON.stringify(exportConfig)};
KEEP.hexo_config = ${JSON.stringify(hexo_config)};
KEEP.theme_config = ${JSON.stringify(theme_config)};
KEEP.language = ${JSON.stringify(languageContent)};
</script>`;
});

View File

@ -30,7 +30,7 @@ window.addEventListener('DOMContentLoaded', () => {
},
changePageLayoutWhenOpenToggle(isOpen) {
const pageAsideWidth = CONFIG.style.left_side_width || '260px';
const pageAsideWidth = KEEP.theme_config.left_side_width || '260px';
this.containerDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
this.pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
this.leftAsideDom.style.left = isOpen ? '0' : `-${pageAsideWidth}`;

View File

@ -5,7 +5,7 @@ window.addEventListener('DOMContentLoaded', () => {
let datas;
let isXml = true;
// Search DB path
let searchPath = CONFIG.path;
let searchPath = KEEP.hexo_config.path;
if (!searchPath) return false;
if (searchPath.length === 0) {
searchPath = 'search.xml';
@ -171,7 +171,7 @@ window.addEventListener('DOMContentLoaded', () => {
});
// Select top N slices in content
let upperBound = parseInt(CONFIG.localsearch.top_n_per_article ? CONFIG.localsearch.top_n_per_article : 1, 10);
let upperBound = parseInt(KEEP.theme_config.local_search.top_n_per_article ? KEEP.theme_config.local_search.top_n_per_article : 1, 10);
if (upperBound >= 0) {
slicesOfContent = slicesOfContent.slice(0, upperBound);
}
@ -222,7 +222,7 @@ window.addEventListener('DOMContentLoaded', () => {
};
const fetchData = () => {
fetch(CONFIG.root + searchPath)
fetch(KEEP.theme_config.root + searchPath)
.then(response => response.text())
.then(res => {
// Get the contents from search data
@ -238,7 +238,7 @@ window.addEventListener('DOMContentLoaded', () => {
datas = datas.filter(data => data.title).map(data => {
data.title = data.title.trim();
data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '';
if (CONFIG.localsearch.unescape) {
if (KEEP.theme_config.local_search.unescape) {
data.content = unescapeHtml(data.content);
}
data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/');
@ -249,11 +249,11 @@ window.addEventListener('DOMContentLoaded', () => {
});
};
if (CONFIG.localsearch.preload) {
if (KEEP.theme_config.local_search.preload) {
fetchData();
}
if (CONFIG.localsearch.trigger === 'auto') {
if (KEEP.theme_config.local_search.trigger === 'auto') {
if (input) {
input.addEventListener('input', inputEventFunction);
}

View File

@ -1,4 +1,12 @@
window.addEventListener('DOMContentLoaded', () => {
KEEP.themeInfo = {
author: 'XPoet',
name: 'Keep',
version: KEEP.theme_config.version,
repository: 'https://github.com/XPoet/hexo-theme-keep'
}
// print theme info
KEEP.utils.printThemeInfo();
@ -19,4 +27,7 @@ window.addEventListener('DOMContentLoaded', () => {
// big image viewer handle
KEEP.utils.imageViewer();
// set how long age in home article block
KEEP.utils.setHowLongAgoInHome();
});

View File

@ -1,32 +1,19 @@
KEEP.utils = {
themeInfo: {
author: 'XPoet',
name: 'Keep',
version: '3.0.0',
repository: 'https://github.com/XPoet/hexo-theme-keep'
},
printThemeInfo() {
const themeInfo = `${this.themeInfo.name} v${this.themeInfo.version}`;
console.info(themeInfo + '\n' + this.themeInfo.repository);
const footThemeInfoDom = document.querySelector('.footer .info-container .theme-info a.theme-version');
if (footThemeInfoDom) {
footThemeInfoDom.setAttribute('href', this.themeInfo.repository);
footThemeInfoDom.innerHTML = themeInfo;
}
}
}
KEEP.utils = {
...KEEP.utils,
headerProgress_dom: document.querySelector('.header-progress'),
pageTop_dom: document.querySelector('.page-main-content-top'),
firstScreen_dom: document.querySelector('.first-screen-container'),
printThemeInfo() {
const themeInfo = `${KEEP.themeInfo.name} v${KEEP.themeInfo.version}`;
console.info(themeInfo + '\n' + KEEP.themeInfo.repository);
const footThemeInfoDom = document.querySelector('.footer .info-container .theme-info a.theme-version');
if (footThemeInfoDom) {
footThemeInfoDom.setAttribute('href', KEEP.themeInfo.repository);
footThemeInfoDom.innerHTML = themeInfo;
}
},
// Scroll Style Handle
prevScrollValue: 0,
styleHandleWhenScroll() {
@ -57,7 +44,7 @@ KEEP.utils = {
this.styleHandleWhenScroll();
// TOC scroll handle
if (CONFIG.toc.enable && KEEP.utils.hasOwnProperty('findActiveIndexByTOC')) {
if (KEEP.theme_config.toc.enable && KEEP.utils.hasOwnProperty('findActiveIndexByTOC')) {
KEEP.utils.findActiveIndexByTOC();
}
@ -68,7 +55,7 @@ KEEP.utils = {
// tools
registerToolsButtonClick() {
if (!CONFIG.side_tools.enable) return;
if (!KEEP.theme_config.side_tools.enable) return;
let isOpen = false;
this.toolsMenuButton_dom = document.querySelector('.tools-button');
@ -99,22 +86,6 @@ KEEP.utils = {
});
},
// calculate transform value
calculateTransformValue(index) {
const x = 3;
const y = Math.floor(index / x) + 1;
const z = index % x + 1;
switch (z) {
case 1:
return `0, -${150 * y}%, 0`;
case 2:
return `-${150 * y}%, -${150 * y}%, 0`;
case 3:
return `-${150 * y}%, 0, 0`;
}
},
// go comment
goComment() {
this.goComment_dom = document.querySelector('.go-comment');
@ -178,5 +149,54 @@ KEEP.utils = {
targetImg.setAttribute('src', img.getAttribute('src'))
});
});
},
setLanguage(p1, p2) {
return p2.replace(/%s/g, p1)
},
getHowLongAgo(timestamp) {
let l = KEEP.language
timestamp /= 1000;
const __Y = Math.floor(timestamp / (60 * 60 * 24 * 30) / 12)
const __M = Math.floor(timestamp / (60 * 60 * 24 * 30))
const __W = Math.floor(timestamp / (60 * 60 * 24) / 7)
const __d = Math.floor(timestamp / (60 * 60 * 24))
const __h = Math.floor(timestamp / (60 * 60) % 24)
const __m = Math.floor(timestamp / 60 % 60)
const __s = Math.floor(timestamp % 60)
if (__Y > 0) {
return this.setLanguage(__Y, l.ago.year)
} else if (__M > 0) {
return this.setLanguage(__M, l.ago.month)
} else if (__W > 0) {
return this.setLanguage(__W, l.ago.week)
} else if (__d > 0) {
return this.setLanguage(__d, l.ago.day)
} else if (__h > 0) {
return this.setLanguage(__h, l.ago.hour)
} else if (__m > 0) {
return this.setLanguage(__m, l.ago.minute)
} else if (__s > 0) {
return this.setLanguage(__s, l.ago.second)
}
},
setHowLongAgoInHome() {
const post = document.querySelectorAll('.home-article-meta-info .home-article-date');
post && post.forEach(v => {
v.innerHTML = this.getHowLongAgo(Date.now() - new Date(v.dataset.date).getTime())
})
}
}