fix: storage / network permission issue
This commit is contained in:
parent
c129b2dd1b
commit
145a2d2dbb
36
package-lock.json
generated
36
package-lock.json
generated
|
@ -19,6 +19,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "1.9.4",
|
||||||
|
"@types/chrome": "^0.0.323",
|
||||||
"@types/node": "^22.15.21",
|
"@types/node": "^22.15.21",
|
||||||
"@types/webextension-polyfill": "^0.12.3",
|
"@types/webextension-polyfill": "^0.12.3",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
@ -1232,12 +1233,47 @@
|
||||||
"vite": "^5.2.0 || ^6"
|
"vite": "^5.2.0 || ^6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/chrome": {
|
||||||
|
"version": "0.0.323",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.323.tgz",
|
||||||
|
"integrity": "sha512-ipiDwx41lmGeLnbiT6ENOayvWXdkqKqNwqDQWEuz6dujaX7slSkk1nbSt5Q5c6xnQ708+kuCFrC00VLltSbWVA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/filesystem": "*",
|
||||||
|
"@types/har-format": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
|
||||||
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
|
"integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/filesystem": {
|
||||||
|
"version": "0.0.36",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.36.tgz",
|
||||||
|
"integrity": "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/filewriter": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/filewriter": {
|
||||||
|
"version": "0.0.33",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.33.tgz",
|
||||||
|
"integrity": "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/har-format": {
|
||||||
|
"version": "1.2.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.16.tgz",
|
||||||
|
"integrity": "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.15.21",
|
"version": "22.15.21",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.21.tgz",
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.9.4",
|
"@biomejs/biome": "1.9.4",
|
||||||
|
"@types/chrome": "^0.0.323",
|
||||||
"@types/node": "^22.15.21",
|
"@types/node": "^22.15.21",
|
||||||
"@types/webextension-polyfill": "^0.12.3",
|
"@types/webextension-polyfill": "^0.12.3",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.1",
|
||||||
|
|
|
@ -17,7 +17,8 @@
|
||||||
"host_permissions": [
|
"host_permissions": [
|
||||||
"https://monster-siren.hypergryph.com/*",
|
"https://monster-siren.hypergryph.com/*",
|
||||||
"http://localhost:5173/*",
|
"http://localhost:5173/*",
|
||||||
"https://res01.hycdn.cn/*"
|
"https://res01.hycdn.cn/*",
|
||||||
|
"https://web.hycdn.cn/*"
|
||||||
],
|
],
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "vite.svg",
|
"16": "vite.svg",
|
||||||
|
@ -29,10 +30,11 @@
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"tabs",
|
"tabs",
|
||||||
"webRequest"
|
"webRequest",
|
||||||
|
"storage"
|
||||||
],
|
],
|
||||||
"content_security_policy": {
|
"content_security_policy": {
|
||||||
"extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173 https://monster-siren.hypergryph.com; img-src 'self' https://web.hycdn.cn; media-src 'self' https://res01.hycdn.cn;",
|
"extension_pages": "default-src 'self'; script-src 'self' http://localhost:5173; style-src 'self' 'unsafe-inline'; connect-src 'self' ws://localhost:5173 https://monster-siren.hypergryph.com https://web.hycdn.cn; img-src 'self' https://web.hycdn.cn; media-src 'self' https://res01.hycdn.cn;",
|
||||||
"sandbox": "sandbox"
|
"sandbox": "sandbox"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -511,6 +511,7 @@ watch(() => playQueueStore.currentTime, (time) => {
|
||||||
|
|
||||||
// 监听歌词源变化
|
// 监听歌词源变化
|
||||||
watch(() => props.lrcSrc, async (newSrc) => {
|
watch(() => props.lrcSrc, async (newSrc) => {
|
||||||
|
console.log('Loading new lyrics from:', newSrc)
|
||||||
// 重置状态
|
// 重置状态
|
||||||
currentLineIndex.value = -1
|
currentLineIndex.value = -1
|
||||||
lineRefs.value = []
|
lineRefs.value = []
|
||||||
|
|
|
@ -41,6 +41,7 @@ const songInfo = useTemplateRef('songInfo')
|
||||||
const playButton = useTemplateRef('playButton')
|
const playButton = useTemplateRef('playButton')
|
||||||
|
|
||||||
const presentQueueListDialog = ref(false)
|
const presentQueueListDialog = ref(false)
|
||||||
|
// const presentLyrics = ref(false)
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
Draggable.create(progressBarThumb.value, {
|
Draggable.create(progressBarThumb.value, {
|
||||||
|
|
|
@ -1,23 +1,164 @@
|
||||||
import { defineStore } from "pinia"
|
import { defineStore } from "pinia"
|
||||||
import { ref, watch } from "vue"
|
import { ref, watch } from "vue"
|
||||||
import browser from 'webextension-polyfill'
|
|
||||||
|
// 声明全局类型
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
browser?: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const usePreferences = defineStore('preferences', () => {
|
export const usePreferences = defineStore('preferences', () => {
|
||||||
const displayTimeLeft = ref<boolean>(false) // 设置默认值
|
const displayTimeLeft = ref<boolean>(false)
|
||||||
const isLoaded = ref(false) // 添加加载状态
|
const isLoaded = ref(false)
|
||||||
|
const storageType = ref<'chrome' | 'localStorage' | 'memory'>('chrome')
|
||||||
|
const debugInfo = ref<string[]>([])
|
||||||
|
|
||||||
|
// 添加调试日志
|
||||||
|
const addDebugInfo = (info: string) => {
|
||||||
|
debugInfo.value.push(`[${new Date().toISOString()}] ${info}`)
|
||||||
|
console.log(info)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测可用的 API
|
||||||
|
const detectAvailableAPIs = () => {
|
||||||
|
addDebugInfo('开始检测可用的存储 API...')
|
||||||
|
|
||||||
|
// 检查原生 chrome API
|
||||||
|
try {
|
||||||
|
if (typeof chrome !== 'undefined' && chrome.storage && chrome.storage.local) {
|
||||||
|
addDebugInfo('✅ 检测到 chrome.storage.local')
|
||||||
|
storageType.value = 'chrome'
|
||||||
|
return 'chrome'
|
||||||
|
} else {
|
||||||
|
addDebugInfo('❌ 未检测到原生 chrome.storage.local')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`❌ chrome API 检测失败: ${error}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 window.chrome
|
||||||
|
try {
|
||||||
|
if (window.chrome && window.chrome.storage && window.chrome.storage.local) {
|
||||||
|
addDebugInfo('✅ 检测到 window.chrome.storage.local')
|
||||||
|
storageType.value = 'chrome'
|
||||||
|
return 'chrome'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`❌ window.chrome API 检测失败: ${error}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查 localStorage
|
||||||
|
try {
|
||||||
|
if (typeof localStorage !== 'undefined') {
|
||||||
|
localStorage.setItem('msr_test', 'test')
|
||||||
|
localStorage.removeItem('msr_test')
|
||||||
|
addDebugInfo('✅ 检测到 localStorage')
|
||||||
|
storageType.value = 'localStorage'
|
||||||
|
return 'localStorage'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`❌ localStorage 检测失败: ${error}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 都不可用,使用内存存储
|
||||||
|
addDebugInfo('⚠️ 使用内存存储(不持久化)')
|
||||||
|
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?.local || window.chrome?.storage?.local
|
||||||
|
if (api) {
|
||||||
|
api.get({ [key]: defaultValue }, (result) => {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
addDebugInfo(`Chrome storage 错误: ${chrome.runtime.lastError.message}`)
|
||||||
|
resolve(defaultValue)
|
||||||
|
} else {
|
||||||
|
addDebugInfo(`从 Chrome storage 读取: ${key} = ${result[key]}`)
|
||||||
|
resolve(result[key])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
resolve(defaultValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
case 'localStorage':
|
||||||
|
const stored = localStorage.getItem(`msr_${key}`)
|
||||||
|
const value = stored ? JSON.parse(stored) : defaultValue
|
||||||
|
addDebugInfo(`从 localStorage 读取: ${key} = ${value}`)
|
||||||
|
return value
|
||||||
|
|
||||||
|
case 'memory':
|
||||||
|
default:
|
||||||
|
addDebugInfo(`从内存返回默认值: ${key} = ${defaultValue}`)
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`获取存储值失败 (${type}): ${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?.local || window.chrome?.storage?.local
|
||||||
|
if (api) {
|
||||||
|
api.set({ [key]: value }, () => {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
const error = `Chrome storage 保存错误: ${chrome.runtime.lastError.message}`
|
||||||
|
addDebugInfo(error)
|
||||||
|
reject(new Error(error))
|
||||||
|
} else {
|
||||||
|
addDebugInfo(`保存到 Chrome storage: ${key} = ${value}`)
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reject(new Error('Chrome storage API 不可用'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
case 'localStorage':
|
||||||
|
localStorage.setItem(`msr_${key}`, JSON.stringify(value))
|
||||||
|
addDebugInfo(`保存到 localStorage: ${key} = ${value}`)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'memory':
|
||||||
|
addDebugInfo(`内存存储(不持久化): ${key} = ${value}`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`保存设置失败 (${type}): ${error}`)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 异步初始化函数
|
// 异步初始化函数
|
||||||
const initializePreferences = async () => {
|
const initializePreferences = async () => {
|
||||||
try {
|
addDebugInfo('开始初始化偏好设置...')
|
||||||
// 指定默认值对象
|
|
||||||
const result = await browser.storage.local.get({
|
|
||||||
displayTimeLeft: false // 如果键不存在,使用这个默认值
|
|
||||||
})
|
|
||||||
|
|
||||||
displayTimeLeft.value = result.displayTimeLeft as boolean // 现在类型是安全的
|
try {
|
||||||
|
const value = await getStoredValue('displayTimeLeft', false)
|
||||||
|
displayTimeLeft.value = value as boolean
|
||||||
isLoaded.value = true
|
isLoaded.value = true
|
||||||
|
addDebugInfo(`✅ 偏好设置初始化完成: displayTimeLeft = ${value}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载偏好设置失败:', error)
|
addDebugInfo(`❌ 初始化失败: ${error}`)
|
||||||
displayTimeLeft.value = false
|
displayTimeLeft.value = false
|
||||||
isLoaded.value = true
|
isLoaded.value = true
|
||||||
}
|
}
|
||||||
|
@ -25,23 +166,51 @@ export const usePreferences = defineStore('preferences', () => {
|
||||||
|
|
||||||
// 监听变化并保存
|
// 监听变化并保存
|
||||||
watch(displayTimeLeft, async (val) => {
|
watch(displayTimeLeft, async (val) => {
|
||||||
if (isLoaded.value) { // 只有在初始化完成后才保存
|
if (isLoaded.value) {
|
||||||
try {
|
try {
|
||||||
await browser.storage.local.set({
|
await setStoredValue('displayTimeLeft', val)
|
||||||
displayTimeLeft: val
|
|
||||||
})
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('保存偏好设置失败:', error)
|
addDebugInfo(`❌ 监听器保存失败: ${error}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 手动保存函数(用于调试)
|
||||||
|
const manualSave = async () => {
|
||||||
|
try {
|
||||||
|
await setStoredValue('displayTimeLeft', displayTimeLeft.value)
|
||||||
|
addDebugInfo(`✅ 手动保存成功`)
|
||||||
|
} catch (error) {
|
||||||
|
addDebugInfo(`❌ 手动保存失败: ${error}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取调试信息
|
||||||
|
const getDebugInfo = () => {
|
||||||
|
return {
|
||||||
|
storageType: storageType.value,
|
||||||
|
isLoaded: isLoaded.value,
|
||||||
|
displayTimeLeft: displayTimeLeft.value,
|
||||||
|
logs: debugInfo.value,
|
||||||
|
chromeAvailable: typeof chrome !== 'undefined',
|
||||||
|
chromeStorageAvailable: !!(chrome?.storage?.local),
|
||||||
|
windowChromeAvailable: !!(window.chrome?.storage?.local),
|
||||||
|
localStorageAvailable: typeof localStorage !== 'undefined'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 立即初始化
|
// 立即初始化
|
||||||
initializePreferences()
|
initializePreferences()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
displayTimeLeft,
|
displayTimeLeft,
|
||||||
isLoaded,
|
isLoaded,
|
||||||
initializePreferences
|
storageType,
|
||||||
|
debugInfo,
|
||||||
|
initializePreferences,
|
||||||
|
getStoredValue,
|
||||||
|
setStoredValue,
|
||||||
|
manualSave,
|
||||||
|
getDebugInfo
|
||||||
}
|
}
|
||||||
})
|
})
|
Loading…
Reference in New Issue
Block a user