msr-mod/src/stores/usePreferences.ts

193 lines
4.3 KiB
TypeScript

import { defineStore } from "pinia"
import { ref, watch } from "vue"
// 声明全局类型
declare global {
interface Window {
browser?: any
}
}
export const usePreferences = defineStore('preferences', () => {
const displayTimeLeft = ref<boolean>(false)
const presentLyrics = ref<boolean>(false)
const autoRedirect = ref<boolean>(true)
const isLoaded = ref(false)
const storageType = ref<'chrome' | 'localStorage' | 'memory'>('chrome')
// 默认偏好设置
const defaultPreferences = {
displayTimeLeft: false,
presentLyrics: false,
autoRedirect: true
}
// 检测可用的 API
const detectAvailableAPIs = () => {
// 检查原生 chrome API
try {
if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.sync) {
storageType.value = 'chrome'
return 'chrome'
}
} catch (error) {
// Silent fail
}
// 检查 window.chrome
try {
if (window.chrome && window.chrome.storage && window.chrome.storage.sync) {
storageType.value = 'chrome'
return 'chrome'
}
} catch (error) {
// Silent fail
}
// 检查 localStorage
try {
if (typeof localStorage !== 'undefined') {
localStorage.setItem('msr_test', 'test')
localStorage.removeItem('msr_test')
storageType.value = 'localStorage'
return 'localStorage'
}
} catch (error) {
// Silent fail
}
// 都不可用,使用内存存储
storageType.value = 'memory'
return 'memory'
}
// 通用的获取存储值函数
const getStoredValue = async (key: string, defaultValue: any) => {
const type = detectAvailableAPIs()
try {
switch (type) {
case 'chrome':
return await new Promise((resolve) => {
const api = chrome?.storage?.sync || window.chrome?.storage?.sync
if (api) {
api.get({ [key]: defaultValue }, (result) => {
if (chrome.runtime.lastError) {
resolve(defaultValue)
} else {
resolve(result[key])
}
})
} else {
resolve(defaultValue)
}
})
case 'localStorage':
const stored = localStorage.getItem(`msr_${key}`)
const value = stored ? JSON.parse(stored) : defaultValue
return value
case 'memory':
default:
return defaultValue
}
} catch (error) {
return defaultValue
}
}
// 通用的设置存储值函数
const setStoredValue = async (key: string, value: any) => {
const type = storageType.value
try {
switch (type) {
case 'chrome':
return await new Promise<void>((resolve, reject) => {
const api = chrome?.storage?.sync || window.chrome?.storage?.sync
if (api) {
api.set({ [key]: value }, () => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message))
} else {
resolve()
}
})
} else {
reject(new Error('Chrome storage API 不可用'))
}
})
case 'localStorage':
localStorage.setItem(`msr_${key}`, JSON.stringify(value))
break
case 'memory':
// 内存存储(不持久化)
break
}
} catch (error) {
throw error
}
}
// 获取所有偏好设置
const getPreferences = async () => {
return await getStoredValue('preferences', defaultPreferences)
}
// 保存所有偏好设置
const savePreferences = async () => {
const preferences = {
displayTimeLeft: displayTimeLeft.value,
presentLyrics: presentLyrics.value,
autoRedirect: autoRedirect.value
}
await setStoredValue('preferences', preferences)
}
// 异步初始化函数
const initializePreferences = async () => {
try {
const preferences = await getPreferences()
displayTimeLeft.value = preferences.displayTimeLeft
presentLyrics.value = preferences.presentLyrics
autoRedirect.value = preferences.autoRedirect
isLoaded.value = true
} catch (error) {
displayTimeLeft.value = false
presentLyrics.value = false
autoRedirect.value = true
isLoaded.value = true
}
}
// 监听变化并保存
watch([displayTimeLeft, presentLyrics, autoRedirect], async () => {
if (isLoaded.value) {
try {
await savePreferences()
} catch (error) {
// Silent fail
}
}
})
// 立即初始化
initializePreferences()
return {
displayTimeLeft,
presentLyrics,
autoRedirect,
isLoaded,
storageType,
initializePreferences,
getStoredValue,
setStoredValue,
getPreferences,
savePreferences
}
})