Versiyon yenileme
This commit is contained in:
parent
d406d8956e
commit
f55b777a17
4 changed files with 50 additions and 22 deletions
|
|
@ -7,9 +7,12 @@ import { store } from './store'
|
||||||
import { DynamicRoutesProvider } from './routes/dynamicRoutesContext'
|
import { DynamicRoutesProvider } from './routes/dynamicRoutesContext'
|
||||||
import { ComponentProvider } from './contexts/ComponentContext'
|
import { ComponentProvider } from './contexts/ComponentContext'
|
||||||
import ComponentRegistryProvider from './contexts/ComponentRegistryContext'
|
import ComponentRegistryProvider from './contexts/ComponentRegistryContext'
|
||||||
|
import { registerServiceWorker } from './views/version/swRegistration'
|
||||||
|
|
||||||
const queryClient = new QueryClient()
|
const queryClient = new QueryClient()
|
||||||
|
|
||||||
|
registerServiceWorker()
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<StoreProvider store={store}>
|
<StoreProvider store={store}>
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,65 @@
|
||||||
import { ROUTES_ENUM } from '@/routes/route.constant'
|
import { ROUTES_ENUM } from '@/routes/route.constant'
|
||||||
import { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
|
||||||
import { HiOutlineRefresh, HiX } from 'react-icons/hi'
|
import { HiOutlineRefresh, HiX } from 'react-icons/hi'
|
||||||
import { useStoreState, useStoreActions } from '@/store'
|
import { useStoreActions } from '@/store'
|
||||||
|
|
||||||
const UpdateNotifier = () => {
|
const UpdateNotifier = () => {
|
||||||
const [lastUiVersion, setLastUiVersion] = useState('')
|
|
||||||
const [updateAvailable, setUpdateAvailable] = useState(false)
|
const [updateAvailable, setUpdateAvailable] = useState(false)
|
||||||
const navigate = useNavigate()
|
const [newVersion, setNewVersion] = useState<string | null>(null)
|
||||||
|
|
||||||
const { currentUiVersion } = useStoreState((s) => s.locale)
|
|
||||||
const { setUiVersion } = useStoreActions((s) => s.locale)
|
const { setUiVersion } = useStoreActions((s) => s.locale)
|
||||||
|
|
||||||
|
// SW update olayını dinle
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkVersion = async () => {
|
const handler = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/version.json?ts=' + Date.now())
|
const res = await fetch('/version.json?ts=' + Date.now())
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
const latestVersion = data?.releases?.[0]?.version
|
const latest = data?.releases?.[0]?.version
|
||||||
if (latestVersion && latestVersion !== currentUiVersion) {
|
if (latest) {
|
||||||
|
setNewVersion(latest)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
console.warn('Yeni versiyon bilgisi alınamadı')
|
||||||
|
}
|
||||||
setUpdateAvailable(true)
|
setUpdateAvailable(true)
|
||||||
setLastUiVersion(latestVersion)
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Version check failed', err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
checkVersion()
|
window.addEventListener('sw-update-available', handler)
|
||||||
const interval = setInterval(checkVersion, 30000) // 30s’de bir kontrol
|
return () => window.removeEventListener('sw-update-available', handler)
|
||||||
return () => clearInterval(interval)
|
}, [])
|
||||||
}, [currentUiVersion])
|
|
||||||
|
|
||||||
if (!updateAvailable) return null
|
if (!updateAvailable) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<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">
|
||||||
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">
|
<div className="flex items-center gap-3">
|
||||||
<HiOutlineRefresh className="h-8 w-8 animate-spin" />
|
<HiOutlineRefresh className="h-8 w-8 animate-spin" />
|
||||||
<div>
|
<div>
|
||||||
<p className="font-semibold">Yeni güncelleme mevcut! (v{lastUiVersion})</p>
|
<p className="font-semibold">
|
||||||
|
Yeni güncelleme mevcut {newVersion && `(v${newVersion})`}!
|
||||||
|
</p>
|
||||||
<p className="text-sm">En son özellikler için sayfayı yenileyin.</p>
|
<p className="text-sm">En son özellikler için sayfayı yenileyin.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setUiVersion(lastUiVersion)
|
navigator.serviceWorker.getRegistration().then((reg) => {
|
||||||
|
if (reg?.waiting) {
|
||||||
|
reg.waiting.postMessage({ type: 'SKIP_WAITING' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (newVersion) {
|
||||||
|
setUiVersion(newVersion)
|
||||||
|
window.location.href =
|
||||||
|
ROUTES_ENUM.protected.admin.changeLog + `?v=${newVersion}`
|
||||||
|
} else {
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
|
||||||
setUpdateAvailable(false)
|
setUpdateAvailable(false)
|
||||||
window.location.href = ROUTES_ENUM.protected.admin.changeLog + `?v=${lastUiVersion}`
|
|
||||||
}}
|
}}
|
||||||
className="rounded bg-white px-4 py-2 text-sm font-bold text-sky-600 transition hover:bg-sky-100"
|
className="rounded bg-white px-4 py-2 text-sm font-bold text-sky-600 transition hover:bg-sky-100"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
15
ui/src/views/version/swRegistration.ts
Normal file
15
ui/src/views/version/swRegistration.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
// src/swRegistration.ts
|
||||||
|
import { registerSW } from 'virtual:pwa-register'
|
||||||
|
|
||||||
|
export const registerServiceWorker = () => {
|
||||||
|
registerSW({
|
||||||
|
immediate: true, // Yeni SW hemen yüklensin
|
||||||
|
onNeedRefresh() {
|
||||||
|
const event = new CustomEvent('sw-update-available')
|
||||||
|
window.dispatchEvent(event)
|
||||||
|
},
|
||||||
|
onOfflineReady() {
|
||||||
|
console.log('App offline ready')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
1
ui/src/vite-env.d.ts
vendored
1
ui/src/vite-env.d.ts
vendored
|
|
@ -1,4 +1,5 @@
|
||||||
/// <reference types="vite/client" />
|
/// <reference types="vite/client" />
|
||||||
|
/// <reference types="vite-plugin-pwa/client" />
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
readonly VITE_API_URL: string
|
readonly VITE_API_URL: string
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue