mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-07-12 16:01:35 +08:00
Implement PWA state management for improved iOS background persistence
Co-authored-by: jxxghp <jxxghp@163.com>
This commit is contained in:
@@ -13,6 +13,10 @@ const options = {
|
||||
// 存储未读消息数量的键名
|
||||
const UNREAD_COUNT_KEY = 'mp_unread_count'
|
||||
|
||||
// 状态管理相关的缓存名称和端点
|
||||
const STATE_CACHE_NAME = 'mp-pwa-state-cache'
|
||||
const STATE_ENDPOINT = '/api/pwa-state'
|
||||
|
||||
// 从IndexedDB获取未读消息数量
|
||||
async function getStoredUnreadCount(): Promise<number> {
|
||||
try {
|
||||
@@ -33,6 +37,52 @@ async function setStoredUnreadCount(count: number): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// 保存PWA状态到缓存
|
||||
async function saveStateToCache(request: Request): Promise<Response> {
|
||||
try {
|
||||
const state = await request.json()
|
||||
const cache = await caches.open(STATE_CACHE_NAME)
|
||||
|
||||
await cache.put(STATE_ENDPOINT, new Response(JSON.stringify({
|
||||
...state,
|
||||
timestamp: Date.now()
|
||||
})))
|
||||
|
||||
return new Response(JSON.stringify({ success: true }))
|
||||
} catch (error) {
|
||||
console.error('Failed to save state to cache:', error)
|
||||
return new Response(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }), {
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 从缓存获取PWA状态
|
||||
async function getStateFromCache(): Promise<Response> {
|
||||
try {
|
||||
const cache = await caches.open(STATE_CACHE_NAME)
|
||||
const response = await cache.match(STATE_ENDPOINT)
|
||||
|
||||
if (response) {
|
||||
const state = await response.json()
|
||||
return new Response(JSON.stringify(state), {
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
return new Response(JSON.stringify({}), {
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Failed to get state from cache:', error)
|
||||
return new Response(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }), {
|
||||
status: 500,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 简单的IndexedDB包装器
|
||||
async function openDB(): Promise<IDBDatabase> {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -123,6 +173,18 @@ self.addEventListener('activate', event => {
|
||||
|
||||
// 处理API请求,当离线时发送消息到客户端
|
||||
self.addEventListener('fetch', event => {
|
||||
const url = new URL(event.request.url)
|
||||
|
||||
// 处理PWA状态管理请求
|
||||
if (url.pathname === STATE_ENDPOINT) {
|
||||
if (event.request.method === 'POST') {
|
||||
event.respondWith(saveStateToCache(event.request))
|
||||
} else if (event.request.method === 'GET') {
|
||||
event.respondWith(getStateFromCache())
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (event.request.url.includes('/api/v1/') && event.request.method === 'GET') {
|
||||
event.respondWith(
|
||||
(async () => {
|
||||
@@ -226,7 +288,7 @@ self.addEventListener('message', function (event) {
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to clear badge:', error)
|
||||
event.ports[0]?.postMessage({ success: false, error: error.message })
|
||||
event.ports[0]?.postMessage({ success: false, error: error instanceof Error ? error.message : String(error) })
|
||||
})
|
||||
} else if (event.data && event.data.type === 'UPDATE_BADGE') {
|
||||
// 更新徽章数量
|
||||
@@ -238,7 +300,7 @@ self.addEventListener('message', function (event) {
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to update badge:', error)
|
||||
event.ports[0]?.postMessage({ success: false, error: error.message })
|
||||
event.ports[0]?.postMessage({ success: false, error: error instanceof Error ? error.message : String(error) })
|
||||
})
|
||||
} else if (event.data && event.data.type === 'GET_UNREAD_COUNT') {
|
||||
// 获取未读消息数量
|
||||
@@ -250,5 +312,32 @@ self.addEventListener('message', function (event) {
|
||||
console.error('Failed to get unread count:', error)
|
||||
event.ports[0]?.postMessage({ count: 0 })
|
||||
})
|
||||
} else if (event.data && event.data.type === 'SAVE_PWA_STATE') {
|
||||
// 保存PWA状态
|
||||
const state = event.data.state || {}
|
||||
saveStateToCache(new Request(STATE_ENDPOINT, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(state)
|
||||
}))
|
||||
.then(response => response.json())
|
||||
.then(result => {
|
||||
event.ports[0]?.postMessage({ success: result.success })
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to save PWA state:', error)
|
||||
event.ports[0]?.postMessage({ success: false, error: error instanceof Error ? error.message : String(error) })
|
||||
})
|
||||
} else if (event.data && event.data.type === 'GET_PWA_STATE') {
|
||||
// 获取PWA状态
|
||||
getStateFromCache()
|
||||
.then(response => response.json())
|
||||
.then(state => {
|
||||
event.ports[0]?.postMessage({ state })
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Failed to get PWA state:', error)
|
||||
event.ports[0]?.postMessage({ state: {} })
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user