Skip to content

Commit

Permalink
增加更新提示刷新操作
Browse files Browse the repository at this point in the history
  • Loading branch information
onresize committed Apr 12, 2024
1 parent c7cf8a7 commit e173b60
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 6 deletions.
15 changes: 9 additions & 6 deletions docs/.vuepress/layouts/Layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ watch(
console.log('监听route.path:', decodeURI(val))
await nextTick()
state.showPageBottom = decodeURI(val).includes('/工具/') ? false : true
// loadScript('/web-blogs/static/js/busuanzi.pure.mini.js') // 加载计数统计脚本
if (val === '/') {
state.showHeaderNavBar = true
} else {
Expand Down Expand Up @@ -99,7 +98,9 @@ watch(
}
)
onMounted(() => {})
onMounted(() => {
loadScript('/web-blogs/static/js/auto-upgrade.js')
})
onUnmounted(() => {
popper?.unmount()
Expand Down Expand Up @@ -147,8 +148,10 @@ onUnmounted(() => {
.my-footer {
text-align: center;
width: var(--content-width);
height: 80px;
max-width: var(--content-width);
min-width: 366px;
width: 78%;
height: 60px;
margin: 10px auto;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.05);
border-radius: 10px;
Expand All @@ -166,8 +169,8 @@ onUnmounted(() => {
}
.icon-rss {
width: 30px;
height: 30px;
width: 25px;
height: 25px;
display: inline-block;
background: url('/RSS.png') no-repeat center center;
background-size: 100% 100%;
Expand Down
24 changes: 24 additions & 0 deletions docs/.vuepress/public/static/js/auto-upgrade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
;(function () {
var s, t
s = document.createElement('script')
s.type = 'text/javascript'
s.id = 'version-polling'
s.src = '/web-blogs/static/js/version-polling.js'
t = document.getElementsByTagName('script')[0]
t.parentNode.appendChild(s, t)
s.onload = function () {
VersionPolling.createVersionPolling({
appETagKey: '__APP_ETAG__',
pollingInterval: 5 * 1000,
silent: globalThis?.location?.port == '3080', // 3080端口下不检测
onUpdate: (self) => {
const result = confirm('页面有更新,点击确定刷新页面!')
if (result) {
self.onRefresh()
} else {
self.onCancel()
}
},
})
}
})()
190 changes: 190 additions & 0 deletions docs/.vuepress/public/static/js/version-polling.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/*!
* version-polling v1.1.7
*/
!(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? factory(exports)
: typeof define === 'function' && define.amd
? define(['exports'], factory)
: ((global =
typeof globalThis !== 'undefined' ? globalThis : global || self),
factory((global.VersionPolling = {})))
})(this, function (exports) {
'use strict'

function _defineProperty(obj, key, value) {
key = _toPropertyKey(key)
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
})
} else {
obj[key] = value
}
return obj
}
function _toPrimitive(input, hint) {
if (typeof input !== 'object' || input === null) return input
var prim = input[Symbol.toPrimitive]
if (prim !== undefined) {
var res = prim.call(input, hint || 'default')
if (typeof res !== 'object') return res
throw new TypeError('@@toPrimitive must return a primitive value.')
}
return (hint === 'string' ? String : Number)(input)
}
function _toPropertyKey(arg) {
var key = _toPrimitive(arg, 'string')
return typeof key === 'symbol' ? key : String(key)
}

/**
* 是否有值
* @param {*} val
*/
/**
* 创建一个 Web Work 实例
* @param func
*/
function createWorker(func) {
const blob = new Blob(['(' + func.toString() + ')()'])
const url = window.URL.createObjectURL(blob)
const worker = new Worker(url)
window.URL.revokeObjectURL(url)
return worker
}
function createWorkerFunc() {
let timer
let options
self.onmessage = (event) => {
let code = event.data['code']
options = Object.assign({}, options, event.data['data'])
const { htmlFileUrl, lastEtag, appETagKey, immediate, pollingInterval } =
options
const runReq = () => {
fetch(htmlFileUrl, {
method: 'HEAD',
cache: 'no-cache',
}).then((response) => {
const etag = response.headers.get('etag')
if (lastEtag !== etag) {
self.postMessage({
appETagKey,
lastEtag,
etag,
})
}
})
}
if (code === 'pause') {
clearInterval(timer)
timer = null
} else {
immediate && runReq()
timer = setInterval(runReq, pollingInterval)
}
}
return self
}
function closeWorker(worker) {
worker.terminate()
}

let APP_ETAG_KEY = '__APP_ETAG__'
let myWorker
const defaultOptions = {
appETagKey: APP_ETAG_KEY,
pollingInterval: 5 * 60 * 1000,
immediate: true,
htmlFileUrl: `${location.origin}${location.pathname}`,
silent: false,
}
/**
* 页面隐藏时停止轮询任务,页面再度可见时在继续
*/
function handleVisibilityChange() {
if (document.visibilityState === 'visible') {
myWorker.postMessage({
code: 'resume',
})
} else {
myWorker.postMessage({
code: 'pause',
})
}
}
class VersionPolling {
constructor(options) {
_defineProperty(this, 'options', void 0)
_defineProperty(this, 'appEtag', '')
this.options = Object.assign({}, defaultOptions, options)
this.init()
}
async init() {
const { htmlFileUrl } = this.options
const response = await fetch(htmlFileUrl, {
method: 'HEAD',
cache: 'no-cache',
})
const etag = response.headers.get('etag')
this.appEtag = etag
localStorage.setItem(`${this.options.appETagKey}`, etag)
this.start()
}
start() {
const { appETagKey, pollingInterval, immediate, htmlFileUrl, silent } =
this.options
// 安静模式
if (silent) {
return
}
myWorker = createWorker(createWorkerFunc)
myWorker.postMessage({
code: 'start',
data: {
appETagKey,
htmlFileUrl,
pollingInterval,
immediate,
lastEtag: localStorage.getItem(`${appETagKey}`),
},
})
myWorker.onmessage = (event) => {
const { lastEtag, etag } = event.data
this.appEtag = etag
if (lastEtag !== etag) {
var _this$options$onUpdat, _this$options
this.stop()
;(_this$options$onUpdat = (_this$options = this.options).onUpdate) ===
null || _this$options$onUpdat === void 0
? void 0
: _this$options$onUpdat.call(_this$options, this)
}
}
document.addEventListener('visibilitychange', handleVisibilityChange)
}
stop() {
if (myWorker) {
closeWorker(myWorker)
document.removeEventListener('visibilitychange', handleVisibilityChange)
}
}
onRefresh() {
localStorage.setItem(`${this.options.appETagKey}`, this.appEtag)
window.location.reload()
}
onCancel() {
localStorage.removeItem(`${this.options.appETagKey}`)
}
}
function createVersionPolling(options) {
const versionPolling = new VersionPolling(options)
return versionPolling
}

exports.VersionPolling = VersionPolling
exports.createVersionPolling = createVersionPolling
})

0 comments on commit e173b60

Please sign in to comment.