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
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/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/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/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..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')
@@ -143,43 +151,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
@@ -301,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(() => {
@@ -315,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')
}
@@ -369,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()
}
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