From b444efd8558835b3149133c8bed7bd34d074995e Mon Sep 17 00:00:00 2001 From: XPoet Date: Thu, 4 Jul 2024 17:46:40 +0800 Subject: [PATCH 1/3] perf(home): optimize post updated time settings --- layout/_partial/scripts.ejs | 6 ++ source/js/main.js | 3 +- source/js/page/home-page.js | 102 +++++++++++++++++++ source/js/post/post-helper.js | 35 +------ source/js/utils.js | 182 +++++++++++++--------------------- 5 files changed, 180 insertions(+), 148 deletions(-) create mode 100644 source/js/page/home-page.js diff --git a/layout/_partial/scripts.ejs b/layout/_partial/scripts.ejs index 41a07b03..998c2c83 100644 --- a/layout/_partial/scripts.ejs +++ b/layout/_partial/scripts.ejs @@ -20,6 +20,12 @@ <% } %>
+ + <% if (is_home()) { %> + <%- __js('js/page/home-page.js') %> + <% } %> + + <% if (is_post()) { %> <%- __js('js/post/post-helper.js') %> diff --git a/source/js/main.js b/source/js/main.js index 832ccfbd..3a4986bc 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -13,7 +13,8 @@ window.addEventListener('DOMContentLoaded', () => { isDark: false, fontSizeLevel: 0, isShowToc: true - } + }, + defaultDatetimeFormat: 'YYYY-MM-DD HH:mm:ss' } // print theme base info diff --git a/source/js/page/home-page.js b/source/js/page/home-page.js new file mode 100644 index 00000000..ffe2fc40 --- /dev/null +++ b/source/js/page/home-page.js @@ -0,0 +1,102 @@ +/* global KEEP */ + +function homePageHandler() { + const { post_datetime, post_datetime_format, announcement } = KEEP.theme_config?.home || {} + const fsc = KEEP.theme_config?.first_screen || {} + + // reset home post update datetime + const resetHomePostUpdateDate = () => { + if (post_datetime === 'updated' && post_datetime_format) { + const datetimeDoms = document.querySelectorAll('.post-meta-info .home-post-history') + datetimeDoms.forEach((datetimeDom) => { + const updated = new Date(datetimeDom.dataset.updated).getTime() + const format = post_datetime_format || KEEP.themeInfo.defaultDatetimeFormat + datetimeDom.innerHTML = KEEP.utils.formatDatetime(format, updated) + }) + } + } + + // set how long age in home post block + const setHowLongAgoInHome = () => { + if (post_datetime_format && post_datetime_format !== 'ago') { + return + } + const datetimeDoms = document.querySelectorAll('.post-meta-info .home-post-history') + datetimeDoms.forEach((v) => { + const nowTimestamp = Date.now() + const updatedTimestamp = new Date(v.dataset.updated).getTime() + v.innerHTML = KEEP.utils.getHowLongAgo(Math.floor((nowTimestamp - updatedTimestamp) / 1000)) + }) + } + + // close website announcement + const closeWebsiteAnnouncement = () => { + if (announcement) { + const waDom = document.querySelector('.home-content-container .website-announcement') + if (waDom) { + const closeDom = waDom.querySelector('.close') + closeDom.addEventListener('click', () => { + waDom.style.display = 'none' + }) + } + } + } + + // first screen typewriter + const initTypewriter = () => { + const isHitokoto = fsc?.hitokoto === true + + if (fsc?.enable !== true) { + return + } + + if (fsc?.enable === true && !isHitokoto && !fsc?.description) { + return + } + + const descBox = document.querySelector('.first-screen-content .description') + if (descBox) { + descBox.style.opacity = '0' + + setTimeout( + () => { + descBox.style.opacity = '1' + const descItemList = descBox.querySelectorAll('.desc-item') + descItemList.forEach((descItem) => { + const desc = descItem.querySelector('.desc') + const cursor = descItem.querySelector('.cursor') + const text = desc.innerHTML + desc.innerHTML = '' + let charIndex = 0 + + if (text) { + const typewriter = () => { + if (charIndex < text.length) { + desc.textContent += text.charAt(charIndex) + charIndex++ + setTimeout(typewriter, 100) + } else { + cursor.style.display = 'none' + } + } + + typewriter() + } + }) + }, + isHitokoto ? 400 : 300 + ) + } + } + + resetHomePostUpdateDate() + setHowLongAgoInHome() + closeWebsiteAnnouncement() + initTypewriter() +} + +if (KEEP.theme_config?.pjax?.enable === true && KEEP.utils) { + homePageHandler() +} else { + window.addEventListener('DOMContentLoaded', homePageHandler) +} diff --git a/source/js/post/post-helper.js b/source/js/post/post-helper.js index c1579e4c..4be09020 100644 --- a/source/js/post/post-helper.js +++ b/source/js/post/post-helper.js @@ -143,43 +143,14 @@ async function initPostHelper() { } }, - formatDatetime(fmt = 'YYYY-MM-DD hh:mm:ss', timestamp = Date.now()) { - function padLeftZero(str) { - return `00${str}`.substr(str.length) - } - - const date = new Date(timestamp) - - if (/(y+)/.test(fmt) || /(Y+)/.test(fmt)) { - fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length)) - } - - const obj = { - 'M+': date.getMonth() + 1, - 'D+': date.getDate(), - 'd+': date.getDate(), - 'H+': date.getHours(), - 'h+': date.getHours(), - 'm+': date.getMinutes(), - 's+': date.getSeconds() - } - - for (const key in obj) { - if (new RegExp(`(${key})`).test(fmt)) { - const str = `${obj[key]}` - fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str)) - } - } - return fmt - }, - + // reset post update datetime resetPostUpdateDate() { const updateDateDom = document.querySelector( '.post-meta-info-container .post-update-date .datetime' ) const updated = new Date(updateDateDom.dataset.updated).getTime() - const format = KEEP.theme_config.post?.datetime_format || 'YYYY-MM-DD HH:mm:ss' - updateDateDom.innerHTML = this.formatDatetime(format, updated) + const format = KEEP.theme_config.post?.datetime_format || KEEP.themeInfo.defaultDatetimeFormat + updateDateDom.innerHTML = KEEP.utils.formatDatetime(format, updated) }, // enable full screen diff --git a/source/js/utils.js b/source/js/utils.js index b66b3a28..844abaa6 100644 --- a/source/js/utils.js +++ b/source/js/utils.js @@ -20,6 +20,72 @@ KEEP.initUtils = () => { isHideHeader: true, hasToc: false, + // ============== common utils ============== + + // formatting timestamp + formatDatetime(fmt = KEEP.themeInfo.defaultDatetimeFormat, timestamp = Date.now()) { + function padLeftZero(str) { + return `00${str}`.substring(str.length) + } + + const date = new Date(timestamp) + + if (/(y+)/.test(fmt) || /(Y+)/.test(fmt)) { + fmt = fmt.replace(RegExp.$1, `${date.getFullYear()}`.substr(4 - RegExp.$1.length)) + } + + const obj = { + 'M+': date.getMonth() + 1, + 'D+': date.getDate(), + 'd+': date.getDate(), + 'H+': date.getHours(), + 'h+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds() + } + + for (const key in obj) { + if (new RegExp(`(${key})`).test(fmt)) { + const str = `${obj[key]}` + fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str)) + } + } + return fmt + }, + + // set how long ago language + setHowLongAgoLanguage(p1, p2) { + return p2.replace(/%s/g, p1) + }, + + // get how long ago + getHowLongAgo(timestamp) { + const lang = KEEP.language_ago + 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.setHowLongAgoLanguage(__Y, lang.year) + } else if (__M > 0) { + return this.setHowLongAgoLanguage(__M, lang.month) + } else if (__W > 0) { + return this.setHowLongAgoLanguage(__W, lang.week) + } else if (__d > 0) { + return this.setHowLongAgoLanguage(__d, lang.day) + } else if (__h > 0) { + return this.setHowLongAgoLanguage(__h, lang.hour) + } else if (__m > 0) { + return this.setHowLongAgoLanguage(__m, lang.minute) + } else if (__s > 0) { + return this.setHowLongAgoLanguage(__s, lang.second) + } + }, + // initialization data initData() { const scroll = KEEP.theme_config?.scroll || {} @@ -302,56 +368,6 @@ KEEP.initUtils = () => { } }, - // set how long ago language - setHowLongAgoLanguage(p1, p2) { - return p2.replace(/%s/g, p1) - }, - - // get how long ago - getHowLongAgo(timestamp) { - const lang = KEEP.language_ago - 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.setHowLongAgoLanguage(__Y, lang.year) - } else if (__M > 0) { - return this.setHowLongAgoLanguage(__M, lang.month) - } else if (__W > 0) { - return this.setHowLongAgoLanguage(__W, lang.week) - } else if (__d > 0) { - return this.setHowLongAgoLanguage(__d, lang.day) - } else if (__h > 0) { - return this.setHowLongAgoLanguage(__h, lang.hour) - } else if (__m > 0) { - return this.setHowLongAgoLanguage(__m, lang.minute) - } else if (__s > 0) { - return this.setHowLongAgoLanguage(__s, lang.second) - } - }, - - // set how long age in home post block - setHowLongAgoInHome() { - const { post_datetime_format } = KEEP.theme_config?.home || {} - - if (post_datetime_format && post_datetime_format !== 'ago') { - return - } - - const post = document.querySelectorAll('.post-meta-info .home-post-history') - post && - post.forEach((v) => { - const nowTimestamp = Date.now() - const updatedTimestamp = new Date(v.dataset.updated).getTime() - v.innerHTML = this.getHowLongAgo(Math.floor((nowTimestamp - updatedTimestamp) / 1000)) - }) - }, - // loading progress bar start pjaxProgressBarStart() { this.pjaxProgressBarTimer && clearInterval(this.pjaxProgressBarTimer) @@ -627,54 +643,6 @@ KEEP.initUtils = () => { }) }, - // first screen typewriter - initTypewriter() { - const fsc = KEEP.theme_config?.first_screen || {} - const isHitokoto = fsc?.hitokoto === true - - if (fsc?.enable !== true) { - return - } - - if (fsc?.enable === true && !isHitokoto && !fsc?.description) { - return - } - - const descBox = document.querySelector('.first-screen-content .description') - if (descBox) { - descBox.style.opacity = '0' - - setTimeout( - () => { - descBox.style.opacity = '1' - const descItemList = descBox.querySelectorAll('.desc-item') - descItemList.forEach((descItem) => { - const desc = descItem.querySelector('.desc') - const cursor = descItem.querySelector('.cursor') - const text = desc.innerHTML - desc.innerHTML = '' - let charIndex = 0 - - if (text) { - const typewriter = () => { - if (charIndex < text.length) { - desc.textContent += text.charAt(charIndex) - charIndex++ - setTimeout(typewriter, 100) - } else { - cursor.style.display = 'none' - } - } - - typewriter() - } - }) - }, - isHitokoto ? 400 : 300 - ) - } - }, - // remove white space between children removeWhitespace(container) { if (!container) { @@ -701,19 +669,6 @@ KEEP.initUtils = () => { this.removeWhitespace(document.querySelector('.post-meta-info-container .post-tag-ul')) }, - // close website announcement - closeWebsiteAnnouncement() { - if (KEEP.theme_config?.home?.announcement) { - const waDom = document.querySelector('.home-content-container .website-announcement') - if (waDom) { - const closeDom = waDom.querySelector('.close') - closeDom.addEventListener('click', () => { - waDom.style.display = 'none' - }) - } - } - }, - // wrap table dom with div wrapTableWithBox() { document.querySelectorAll('table').forEach((element) => { @@ -777,10 +732,7 @@ KEEP.initUtils = () => { KEEP.utils.siteCountInitialize() KEEP.utils.pageNumberJump() - // home page - KEEP.utils.setHowLongAgoInHome() - KEEP.utils.initTypewriter() - KEEP.utils.closeWebsiteAnnouncement() + // home & post page KEEP.utils.trimPostMetaInfoBar() // post page From b189db5e7a10d31dd3f132520188ce4d3324ee51 Mon Sep 17 00:00:00 2001 From: XPoet Date: Thu, 4 Jul 2024 18:09:58 +0800 Subject: [PATCH 2/3] perf(post): optimize article encryption function --- languages/en.yml | 3 +- languages/zh-CN.yml | 3 +- languages/zh-TW.yml | 3 +- layout/_partial/post/post-tools.ejs | 4 ++- source/css/layout/_page/post.styl | 6 +++- .../css/layout/_partial/post/post-tools.styl | 30 ++++++++++++------- source/js/post/post-helper.js | 15 ++++++++-- 7 files changed, 45 insertions(+), 19 deletions(-) diff --git a/languages/en.yml b/languages/en.yml index 722c88f9..266e1917 100644 --- a/languages/en.yml +++ b/languages/en.yml @@ -107,5 +107,6 @@ comment: page_not_found: Page Not Found go_home: Take me home encryption: - excerpt: 🔒 The post has been encrypted, please enter the password to view it. + excerpt: 🔒 The post has been encrypted and can only be viewed after entering the password. input_password: Please enter password ... + re_encryption: Re-encryption diff --git a/languages/zh-CN.yml b/languages/zh-CN.yml index 5973b0ae..b5074c5f 100644 --- a/languages/zh-CN.yml +++ b/languages/zh-CN.yml @@ -107,5 +107,6 @@ comment: page_not_found: 页面找不到 go_home: 前往首页 encryption: - excerpt: 🔒 文章已加密,请在输入密码后查看。 + excerpt: 🔒 文章已加密,输入密码后才能查看。 input_password: 请输入密码... + re_encryption: 重新加密 diff --git a/languages/zh-TW.yml b/languages/zh-TW.yml index a9ceb6d3..1a1f54b8 100644 --- a/languages/zh-TW.yml +++ b/languages/zh-TW.yml @@ -107,5 +107,6 @@ comment: page_not_found: 頁面缺失 go_home: 前往首頁 encryption: - excerpt: 🔒 文章已加密,請在輸入密碼後查看。 + excerpt: 🔒 文章已加密,輸入密碼後才能查看。 input_password: 請輸入密碼... + re_encryption: 重新加密 diff --git a/layout/_partial/post/post-tools.ejs b/layout/_partial/post/post-tools.ejs index 972ff427..14f5974f 100644 --- a/layout/_partial/post/post-tools.ejs +++ b/layout/_partial/post/post-tools.ejs @@ -2,7 +2,9 @@
    <% if (page?.password) { %> -
  • +
  • diff --git a/source/css/layout/_page/post.styl b/source/css/layout/_page/post.styl index 0664d1ae..f039ccf5 100644 --- a/source/css/layout/_page/post.styl +++ b/source/css/layout/_page/post.styl @@ -278,7 +278,7 @@ $spacer-padding = 2rem padding 1rem 0 .password-input { - width 20rem + width 60% margin 0 padding 0.8rem 1.2rem color var(--text-color-3) @@ -290,6 +290,10 @@ $spacer-padding = 2rem border-bottom 0.2rem solid var(--border-color) outline none + +keep-tablet() { + width 80% + } + &.error { border 0.2rem solid var(--keep-danger-color) } diff --git a/source/css/layout/_partial/post/post-tools.styl b/source/css/layout/_partial/post/post-tools.styl index 00620b28..0f3e584a 100644 --- a/source/css/layout/_partial/post/post-tools.styl +++ b/source/css/layout/_partial/post/post-tools.styl @@ -5,13 +5,20 @@ $post-tool-button-width = 2.5rem padding-top var(--component-gap) .post-tools-list { - li { + margin-bottom $li-margin-bottom + + &:last-child { + margin-bottom 0 + } + } + + + li.tools-item { position relative box-sizing border-box width $post-tool-button-width height $post-tool-button-width - margin-bottom $li-margin-bottom color var(--text-color-3) font-size 1.2rem background var(--background-color-1) @@ -38,11 +45,6 @@ $post-tool-button-width = 2.5rem } - &:last-child { - margin-bottom 0 - } - - &.toggle-show-toc { display none } @@ -70,6 +72,16 @@ $post-tool-button-width = 2.5rem } } } + } + + + li.status-item { + width $post-tool-button-width + height $post-tool-button-width + color var(--text-color-3) + font-size 1.6rem + cursor pointer + &.post-lock { cursor default @@ -79,10 +91,6 @@ $post-tool-button-width = 2.5rem color var(--keep-success-color) } - .fa-lock { - color var(--keep-warning-color) - } - &.decrypt { cursor pointer diff --git a/source/js/post/post-helper.js b/source/js/post/post-helper.js index 4be09020..a891bb49 100644 --- a/source/js/post/post-helper.js +++ b/source/js/post/post-helper.js @@ -1,18 +1,22 @@ /* global KEEP */ async function initPostHelper() { + const encryptClassName = 'encrypt' + KEEP.utils.postHelper = { postPageContainerDom: document.querySelector('.post-page-container'), toggleShowTocBtn: document.querySelector('.toggle-show-toc'), toggleShowTocTabletBtn: document.querySelector('.toggle-show-toc-tablet'), mainContentDom: document.querySelector('.main-content'), postToolsDom: document.querySelector('.post-tools'), - isShowToc: false, initToggleToc() { this.toggleShowTocBtn && this.toggleShowTocBtn.addEventListener('click', () => { + if (this.postPageContainerDom.classList.contains(encryptClassName)) { + return + } this.isShowToc = !this.isShowToc KEEP.themeInfo.styleStatus.isShowToc = this.isShowToc KEEP.setStyleStatus() @@ -21,6 +25,10 @@ async function initPostHelper() { this.toggleShowTocTabletBtn && this.toggleShowTocTabletBtn.addEventListener('click', () => { + if (this.postPageContainerDom.classList.contains(encryptClassName)) { + return + } + const tabletTocMask = document.querySelector('.tablet-post-toc-mask') const tabletToc = tabletTocMask.querySelector('.tablet-post-toc') @@ -272,7 +280,7 @@ async function initPostHelper() { const dc = await this.decrypt({ iv, encryptedData: content }, secret) encryptBoxDom.style.display = 'none' postContentDom.removeChild(encryptBoxDom) - this.postPageContainerDom.classList.remove('encrypt') + this.postPageContainerDom.classList.remove(encryptClassName) this.encryptTocHandle(true) postContentDom.querySelector('.post').innerHTML = dc setTimeout(() => { @@ -286,6 +294,7 @@ async function initPostHelper() { KEEP.utils.aAnchorJump() }) lockIconDom.classList.add(lockClassName) + lockIconDom.classList.add('tooltip') sessionStorage.setItem(`${KEEP.themeInfo.encryptKey}#${location.pathname}`, '1') } @@ -340,7 +349,7 @@ async function initPostHelper() { KEEP.utils.postHelper.resetPostUpdateDate() KEEP.utils.postHelper.enableFullScreen() - if (KEEP.utils.postHelper.postPageContainerDom.classList.contains('encrypt')) { + if (KEEP.utils.postHelper.postPageContainerDom.classList.contains(encryptClassName)) { await KEEP.utils.postHelper.postEncryptHandle() } From 27ef552086d272df395322ccf181ec6a84eb1e8c Mon Sep 17 00:00:00 2001 From: XPoet Date: Fri, 5 Jul 2024 10:01:21 +0800 Subject: [PATCH 3/3] ci: update ISSUE_TEMPLATE --- .github/ISSUE_TEMPLATE/bug-report.yml | 2 +- .github/ISSUE_TEMPLATE/feature-request.yml | 2 +- .github/ISSUE_TEMPLATE/other.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index b15a2450..2825840b 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -20,7 +20,7 @@ body: I made sure I checked 我确认我已经检查过了 options: - - label: I am using Keep version `4.1.4` or later. (使用 Keep `4.1.4` 或更高版本) + - label: I am using Keep version `4.1.5` or later. (使用 Keep `4.1.5` 或更高版本) required: true - label: I have already read the [Troubleshooting page of Hexo](https://hexo.io/docs/troubleshooting) and [Keep documents](https://keep-docs.xpoet.cn). (已阅读 [Hexo 故障处理页面](https://hexo.io/docs/troubleshooting) 和 [Keep 文档](https://keep-docs.xpoet.cn)) required: true diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 7b638b9c..29393409 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -20,7 +20,7 @@ body: I made sure I checked 我确认我已经检查过了 options: - - label: I am using Keep version `4.1.4` or later. (使用 Keep `4.1.4` 或更高版本) + - label: I am using Keep version `4.1.5` or later. (使用 Keep `4.1.5` 或更高版本) required: true - label: I have already read the [Troubleshooting page of Hexo](https://hexo.io/docs/troubleshooting) and [Keep documents](https://keep-docs.xpoet.cn). (已阅读 [Hexo 故障处理页面](https://hexo.io/docs/troubleshooting) 和 [Keep 文档](https://keep-docs.xpoet.cn)) required: true diff --git a/.github/ISSUE_TEMPLATE/other.yml b/.github/ISSUE_TEMPLATE/other.yml index 142ba309..d7905f8b 100644 --- a/.github/ISSUE_TEMPLATE/other.yml +++ b/.github/ISSUE_TEMPLATE/other.yml @@ -20,7 +20,7 @@ body: I made sure I checked 我确认我已经检查过了 options: - - label: I am using Keep version `4.1.4` or later. (使用 Keep `4.1.4` 或更高版本) + - label: I am using Keep version `4.1.5` or later. (使用 Keep `4.1.5` 或更高版本) required: true - label: I have already read the [Troubleshooting page of Hexo](https://hexo.io/docs/troubleshooting) and [Keep documents](https://keep-docs.xpoet.cn). (已阅读 [Hexo 故障处理页面](https://hexo.io/docs/troubleshooting) 和 [Keep 文档](https://keep-docs.xpoet.cn)) required: true