Update mesajı çıkmadan gizli şekilde versiyon tazeleeme
This commit is contained in:
parent
5e94f2b572
commit
de76912929
4 changed files with 26 additions and 93 deletions
|
|
@ -15,7 +15,6 @@ import useLocale from '@/utils/hooks/useLocale'
|
||||||
import { useDynamicRoutes } from '@/routes/dynamicRoutesContext'
|
import { useDynamicRoutes } from '@/routes/dynamicRoutesContext'
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
import { hasSubdomain } from '@/utils/subdomain'
|
import { hasSubdomain } from '@/utils/subdomain'
|
||||||
import UpdateNotifier from '../../views/version/UpdateNotifier'
|
|
||||||
|
|
||||||
export type LayoutType =
|
export type LayoutType =
|
||||||
| typeof LAYOUT_TYPE_CLASSIC
|
| typeof LAYOUT_TYPE_CLASSIC
|
||||||
|
|
@ -90,9 +89,14 @@ const Layout = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<div className="flex flex-auto flex-col h-[100vh]"><Loading loading /></div>}>
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div className="flex flex-auto flex-col h-[100vh]">
|
||||||
|
<Loading loading />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
<AppLayout />
|
<AppLayout />
|
||||||
<UpdateNotifier />
|
|
||||||
</Suspense>
|
</Suspense>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,82 +0,0 @@
|
||||||
import { useState, useEffect } from 'react'
|
|
||||||
import { HiOutlineRefresh, HiX } from 'react-icons/hi'
|
|
||||||
import { useStoreActions } from '@/store'
|
|
||||||
|
|
||||||
const UpdateNotifier = () => {
|
|
||||||
const [updateAvailable, setUpdateAvailable] = useState(false)
|
|
||||||
const [newVersion, setNewVersion] = useState<string | null>(null)
|
|
||||||
|
|
||||||
const { setUiVersion } = useStoreActions((s) => s.locale)
|
|
||||||
|
|
||||||
// SW update olayını dinle
|
|
||||||
useEffect(() => {
|
|
||||||
const handler = async () => {
|
|
||||||
try {
|
|
||||||
const res = await fetch('/version.json?ts=' + Date.now())
|
|
||||||
const data = await res.json()
|
|
||||||
const latest = data?.releases?.[0]?.version
|
|
||||||
if (latest) {
|
|
||||||
setNewVersion(latest)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
console.warn('Yeni versiyon bilgisi alınamadı')
|
|
||||||
}
|
|
||||||
setUpdateAvailable(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('sw-update-available', handler)
|
|
||||||
return () => window.removeEventListener('sw-update-available', handler)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
if (!updateAvailable) return null
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="fixed bottom-5 right-5 z-50 flex items-center justify-between gap-4 rounded-lg bg-sky-500 p-4 text-white shadow-lg animate-bounce">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<HiOutlineRefresh className="h-8 w-8 animate-spin" />
|
|
||||||
<div>
|
|
||||||
<p className="font-semibold">
|
|
||||||
Yeni güncelleme mevcut {newVersion && `(v${newVersion})`}!
|
|
||||||
</p>
|
|
||||||
<p className="text-sm">En son özellikler için sayfayı yenileyin.</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<button
|
|
||||||
onClick={() => {
|
|
||||||
navigator.serviceWorker.getRegistration().then((reg) => {
|
|
||||||
if (reg?.waiting) {
|
|
||||||
reg.waiting.postMessage({ type: 'SKIP_WAITING' })
|
|
||||||
reg.waiting.addEventListener('statechange', (e: any) => {
|
|
||||||
if (e.target.state === 'activated') {
|
|
||||||
if (newVersion) {
|
|
||||||
setUiVersion(newVersion) // ✅ Store’daki versiyonu güncelle
|
|
||||||
}
|
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
if (newVersion) {
|
|
||||||
setUiVersion(newVersion) // ✅ Direkt güncelle
|
|
||||||
}
|
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
className="rounded bg-white px-4 py-2 text-sm font-bold text-sky-600 transition hover:bg-sky-100"
|
|
||||||
>
|
|
||||||
Yenile
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => setUpdateAvailable(false)}
|
|
||||||
className="rounded-full p-1 transition hover:bg-sky-600"
|
|
||||||
aria-label="Kapat"
|
|
||||||
>
|
|
||||||
<HiX className="h-5 w-5" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default UpdateNotifier
|
|
||||||
|
|
@ -1,15 +1,26 @@
|
||||||
// src/swRegistration.ts
|
|
||||||
import { registerSW } from 'virtual:pwa-register'
|
import { registerSW } from 'virtual:pwa-register'
|
||||||
|
import { store, useStoreActions } from '@/store'
|
||||||
|
|
||||||
export const registerServiceWorker = () => {
|
export const registerServiceWorker = () => {
|
||||||
|
const { setUiVersion } = useStoreActions((s) => s.locale)
|
||||||
registerSW({
|
registerSW({
|
||||||
onNeedRefresh() {
|
immediate: true,
|
||||||
console.log('New version available, please refresh.')
|
async onNeedRefresh() {
|
||||||
const event = new CustomEvent('sw-update-available')
|
try {
|
||||||
window.dispatchEvent(event)
|
const res = await fetch('/version.json?ts=' + Date.now())
|
||||||
|
const data = await res.json()
|
||||||
|
const latest = data?.releases?.[0]?.version
|
||||||
|
if (latest) {
|
||||||
|
setUiVersion(latest)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.warn('Yeni versiyon bilgisi alınamadı')
|
||||||
|
}
|
||||||
|
// Yeni SW aktif olacak
|
||||||
|
window.location.reload()
|
||||||
},
|
},
|
||||||
onOfflineReady() {
|
onOfflineReady() {
|
||||||
console.log('App offline ready')
|
console.log('📦 App offline ready')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ export default defineConfig(async ({ mode }) => {
|
||||||
mode === 'production'
|
mode === 'production'
|
||||||
? VitePWA({
|
? VitePWA({
|
||||||
// Deploy'dan sonra otomatik güncelle
|
// Deploy'dan sonra otomatik güncelle
|
||||||
registerType: 'prompt',
|
registerType: 'autoUpdate',
|
||||||
// Kayıt kodunu otomatik enjekte et (virtual:pwa-register yazmadan da çalışır)
|
// Kayıt kodunu otomatik enjekte et (virtual:pwa-register yazmadan da çalışır)
|
||||||
injectRegister: 'auto',
|
injectRegister: 'auto',
|
||||||
// Dev ortamında SW'yi aç, prod'da kapalı tut (build edilmiş SW prod'da zaten aktif olur)
|
// Dev ortamında SW'yi aç, prod'da kapalı tut (build edilmiş SW prod'da zaten aktif olur)
|
||||||
|
|
@ -37,7 +37,7 @@ export default defineConfig(async ({ mode }) => {
|
||||||
|
|
||||||
// EN KRİTİK: yeni SW beklemeden kontrolü alsın
|
// EN KRİTİK: yeni SW beklemeden kontrolü alsın
|
||||||
clientsClaim: true,
|
clientsClaim: true,
|
||||||
skipWaiting: false,
|
skipWaiting: true,
|
||||||
|
|
||||||
// Eski workbox cache'lerini temizle
|
// Eski workbox cache'lerini temizle
|
||||||
cleanupOutdatedCaches: true,
|
cleanupOutdatedCaches: true,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue