mid coding commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
<div
|
||||
v-if="showUpdatePrompt"
|
||||
class="fixed bottom-4 left-4 right-4 md:left-auto md:right-4 md:w-96 z-[9999]"
|
||||
>
|
||||
<div class="glass-card p-4 flex items-center gap-4">
|
||||
<div class="flex-1">
|
||||
<p class="text-white/90 text-sm font-medium mb-1">Update Available</p>
|
||||
<p class="text-white/70 text-xs">A new version is available. Click to update.</p>
|
||||
</div>
|
||||
<button
|
||||
@click="handleUpdate"
|
||||
class="glass-button px-4 py-2 rounded-lg text-sm font-medium transition-all hover:bg-black/70 hover:border-white/30"
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
<button
|
||||
@click="dismissUpdate"
|
||||
class="text-white/50 hover:text-white/80 transition-colors p-2"
|
||||
aria-label="Dismiss"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
const showUpdatePrompt = ref(false)
|
||||
let updateCallback: (() => Promise<void>) | null = null
|
||||
|
||||
onMounted(() => {
|
||||
// Listen for service worker updates
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||
// Service worker updated, reload the page
|
||||
window.location.reload()
|
||||
})
|
||||
|
||||
// Check for updates periodically
|
||||
const checkForUpdates = async () => {
|
||||
const registration = await navigator.serviceWorker.getRegistration()
|
||||
if (registration) {
|
||||
await registration.update()
|
||||
}
|
||||
}
|
||||
|
||||
// Check for updates every 5 minutes
|
||||
setInterval(checkForUpdates, 5 * 60 * 1000)
|
||||
|
||||
// Listen for updatefound event
|
||||
navigator.serviceWorker.getRegistration().then((registration) => {
|
||||
if (registration) {
|
||||
registration.addEventListener('updatefound', () => {
|
||||
const newWorker = registration.installing
|
||||
if (newWorker) {
|
||||
newWorker.addEventListener('statechange', () => {
|
||||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||||
// New service worker installed, show update prompt
|
||||
showUpdatePrompt.value = true
|
||||
updateCallback = async () => {
|
||||
if (newWorker.state === 'installed' && registration.waiting) {
|
||||
// Skip waiting and activate the new service worker
|
||||
registration.waiting.postMessage({ type: 'SKIP_WAITING' })
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
function dismissUpdate() {
|
||||
showUpdatePrompt.value = false
|
||||
}
|
||||
|
||||
async function handleUpdate() {
|
||||
if (updateCallback) {
|
||||
await updateCallback()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user