feat: display how long ago in home articles
This commit is contained in:
parent
74aa953a41
commit
90f06b8940
|
@ -35,3 +35,11 @@ copyright:
|
||||||
create_time: Create time
|
create_time: Create time
|
||||||
license_title: Copyright Notice
|
license_title: Copyright Notice
|
||||||
license_content: "All articles in this blog are licensed under %s unless stating additionally."
|
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"
|
||||||
|
|
|
@ -35,3 +35,11 @@ copyright:
|
||||||
create_time: 创建时间
|
create_time: 创建时间
|
||||||
license_title: 版权声明
|
license_title: 版权声明
|
||||||
license_content: "本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!"
|
license_content: "本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!"
|
||||||
|
ago:
|
||||||
|
second: "%s 秒前"
|
||||||
|
minute: "%s 分钟前"
|
||||||
|
hour: "%s 小时前"
|
||||||
|
day: "%s 天前"
|
||||||
|
week: "%s 周前"
|
||||||
|
month: "%s 月前"
|
||||||
|
year: "%s 年前"
|
||||||
|
|
|
@ -29,11 +29,6 @@
|
||||||
author = author.toLocaleLowerCase();
|
author = author.toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
let email = '<%= theme.base_info.email %>';
|
|
||||||
if (email) {
|
|
||||||
email = email.toLocaleLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let vcard of vcards) {
|
for (let vcard of vcards) {
|
||||||
const vnick = vcard.querySelector('.vhead .vnick');
|
const vnick = vcard.querySelector('.vhead .vnick');
|
||||||
if (vnick.innerHTML.toLocaleLowerCase() === author) {
|
if (vnick.innerHTML.toLocaleLowerCase() === author) {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div class="home-article-meta-info-container">
|
<div class="home-article-meta-info-container">
|
||||||
<div class="home-article-meta-info">
|
<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) { %>
|
<% if (post.categories.length && theme.home_article.category.enable === true) { %>
|
||||||
<span class="home-article-category"><i class="fas fa-folder"></i>
|
<span class="home-article-category"><i class="fas fa-folder"></i>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
|
@ -3,27 +3,51 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const url = require('url');
|
const url = require('url');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const yaml = require('js-yaml');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Export theme config to js
|
* Export theme config to js
|
||||||
*/
|
*/
|
||||||
hexo.extend.helper.register('export_config', function () {
|
hexo.extend.helper.register('export_config', function () {
|
||||||
let {config, theme} = this;
|
|
||||||
let exportConfig = {
|
let { config, theme } = this;
|
||||||
|
|
||||||
|
// ------ 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,
|
hostname: url.parse(config.url).hostname || config.url,
|
||||||
root: config.root,
|
root: config.root
|
||||||
localsearch: theme.local_search,
|
|
||||||
codeblock: theme.codeblock,
|
|
||||||
toc: theme.toc,
|
|
||||||
back2top: theme.back2top,
|
|
||||||
side_tools: theme.side_tools,
|
|
||||||
style: theme.style
|
|
||||||
};
|
};
|
||||||
if (config.search) {
|
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">
|
return `<script id="hexo-configurations">
|
||||||
let KEEP = window.KEEP || {};
|
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>`;
|
</script>`;
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,7 +30,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
},
|
},
|
||||||
|
|
||||||
changePageLayoutWhenOpenToggle(isOpen) {
|
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.containerDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
|
||||||
this.pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
|
this.pageTopDom.style.paddingLeft = isOpen ? pageAsideWidth : '0';
|
||||||
this.leftAsideDom.style.left = isOpen ? '0' : `-${pageAsideWidth}`;
|
this.leftAsideDom.style.left = isOpen ? '0' : `-${pageAsideWidth}`;
|
||||||
|
|
|
@ -5,7 +5,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
let datas;
|
let datas;
|
||||||
let isXml = true;
|
let isXml = true;
|
||||||
// Search DB path
|
// Search DB path
|
||||||
let searchPath = CONFIG.path;
|
let searchPath = KEEP.hexo_config.path;
|
||||||
if (!searchPath) return false;
|
if (!searchPath) return false;
|
||||||
if (searchPath.length === 0) {
|
if (searchPath.length === 0) {
|
||||||
searchPath = 'search.xml';
|
searchPath = 'search.xml';
|
||||||
|
@ -171,7 +171,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select top N slices in content
|
// 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) {
|
if (upperBound >= 0) {
|
||||||
slicesOfContent = slicesOfContent.slice(0, upperBound);
|
slicesOfContent = slicesOfContent.slice(0, upperBound);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +222,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchData = () => {
|
const fetchData = () => {
|
||||||
fetch(CONFIG.root + searchPath)
|
fetch(KEEP.theme_config.root + searchPath)
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(res => {
|
.then(res => {
|
||||||
// Get the contents from search data
|
// Get the contents from search data
|
||||||
|
@ -238,7 +238,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
datas = datas.filter(data => data.title).map(data => {
|
datas = datas.filter(data => data.title).map(data => {
|
||||||
data.title = data.title.trim();
|
data.title = data.title.trim();
|
||||||
data.content = data.content ? data.content.trim().replace(/<[^>]+>/g, '') : '';
|
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.content = unescapeHtml(data.content);
|
||||||
}
|
}
|
||||||
data.url = decodeURIComponent(data.url).replace(/\/{2,}/g, '/');
|
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();
|
fetchData();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CONFIG.localsearch.trigger === 'auto') {
|
if (KEEP.theme_config.local_search.trigger === 'auto') {
|
||||||
if (input) {
|
if (input) {
|
||||||
input.addEventListener('input', inputEventFunction);
|
input.addEventListener('input', inputEventFunction);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,12 @@
|
||||||
window.addEventListener('DOMContentLoaded', () => {
|
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
|
// print theme info
|
||||||
KEEP.utils.printThemeInfo();
|
KEEP.utils.printThemeInfo();
|
||||||
|
|
||||||
|
@ -19,4 +27,7 @@ window.addEventListener('DOMContentLoaded', () => {
|
||||||
|
|
||||||
// big image viewer handle
|
// big image viewer handle
|
||||||
KEEP.utils.imageViewer();
|
KEEP.utils.imageViewer();
|
||||||
|
|
||||||
|
// set how long age in home article block
|
||||||
|
KEEP.utils.setHowLongAgoInHome();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,32 +1,19 @@
|
||||||
KEEP.utils = {
|
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'),
|
headerProgress_dom: document.querySelector('.header-progress'),
|
||||||
pageTop_dom: document.querySelector('.page-main-content-top'),
|
pageTop_dom: document.querySelector('.page-main-content-top'),
|
||||||
firstScreen_dom: document.querySelector('.first-screen-container'),
|
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
|
// Scroll Style Handle
|
||||||
prevScrollValue: 0,
|
prevScrollValue: 0,
|
||||||
styleHandleWhenScroll() {
|
styleHandleWhenScroll() {
|
||||||
|
@ -57,7 +44,7 @@ KEEP.utils = {
|
||||||
this.styleHandleWhenScroll();
|
this.styleHandleWhenScroll();
|
||||||
|
|
||||||
// TOC scroll handle
|
// TOC scroll handle
|
||||||
if (CONFIG.toc.enable && KEEP.utils.hasOwnProperty('findActiveIndexByTOC')) {
|
if (KEEP.theme_config.toc.enable && KEEP.utils.hasOwnProperty('findActiveIndexByTOC')) {
|
||||||
KEEP.utils.findActiveIndexByTOC();
|
KEEP.utils.findActiveIndexByTOC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +55,7 @@ KEEP.utils = {
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
registerToolsButtonClick() {
|
registerToolsButtonClick() {
|
||||||
if (!CONFIG.side_tools.enable) return;
|
if (!KEEP.theme_config.side_tools.enable) return;
|
||||||
|
|
||||||
let isOpen = false;
|
let isOpen = false;
|
||||||
this.toolsMenuButton_dom = document.querySelector('.tools-button');
|
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
|
// go comment
|
||||||
goComment() {
|
goComment() {
|
||||||
this.goComment_dom = document.querySelector('.go-comment');
|
this.goComment_dom = document.querySelector('.go-comment');
|
||||||
|
@ -178,5 +149,54 @@ KEEP.utils = {
|
||||||
targetImg.setAttribute('src', img.getAttribute('src'))
|
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())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue