feat(偏好设置): 添加浏览器扩展存储支持及时间显示偏好功能

添加 webextension-polyfill 依赖以支持浏览器扩展存储 API
创建 usePreferences store 管理用户偏好设置
将 Playroom 页面的时间显示切换功能迁移至偏好设置 store
This commit is contained in:
Astrian Zheng 2025-05-26 14:50:53 +10:00
parent 4a8f68346a
commit 32ab4574dd
Signed by: Astrian
SSH Key Fingerprint: SHA256:rVnhx3DAKjujCwWE13aDl7uV6+9U1MvydLkNRXJrBiA
4 changed files with 72 additions and 7 deletions

17
package-lock.json generated
View File

@ -14,11 +14,13 @@
"pinia": "^3.0.2",
"tailwindcss": "^4.1.7",
"vue": "^3.5.13",
"vue-router": "^4.5.1"
"vue-router": "^4.5.1",
"webextension-polyfill": "^0.12.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^22.15.21",
"@types/webextension-polyfill": "^0.12.3",
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "~5.6.2",
"vite": "^6.0.1",
@ -1246,6 +1248,13 @@
"undici-types": "~6.21.0"
}
},
"node_modules/@types/webextension-polyfill": {
"version": "0.12.3",
"resolved": "https://registry.npmjs.org/@types/webextension-polyfill/-/webextension-polyfill-0.12.3.tgz",
"integrity": "sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg==",
"dev": true,
"license": "MIT"
},
"node_modules/@vitejs/plugin-vue": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz",
@ -2647,6 +2656,12 @@
"typescript": ">=5.0.0"
}
},
"node_modules/webextension-polyfill": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.12.0.tgz",
"integrity": "sha512-97TBmpoWJEE+3nFBQ4VocyCdLKfw54rFaJ6EVQYLBCXqCIpLSZkwGgASpv4oPt9gdKCJ80RJlcmNzNn008Ag6Q==",
"license": "MPL-2.0"
},
"node_modules/yallist": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz",

View File

@ -19,11 +19,13 @@
"pinia": "^3.0.2",
"tailwindcss": "^4.1.7",
"vue": "^3.5.13",
"vue-router": "^4.5.1"
"vue-router": "^4.5.1",
"webextension-polyfill": "^0.12.0"
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"@types/node": "^22.15.21",
"@types/webextension-polyfill": "^0.12.3",
"@vitejs/plugin-vue": "^5.2.1",
"typescript": "~5.6.2",
"vite": "^6.0.1",

View File

@ -6,6 +6,7 @@ import { Draggable } from "gsap/Draggable"
import { onMounted } from 'vue'
import { useTemplateRef } from 'vue'
import { ref, watch } from 'vue'
import { usePreferences } from '../stores/usePreferences'
import RewindIcon from '../assets/icons/rewind.vue'
import ForwardIcon from '../assets/icons/forward.vue'
@ -23,6 +24,7 @@ import CycleTwoArrowsWithNumOneIcon from '../assets/icons/cycletwoarrowswithnumo
import SpeakerIcon from '../assets/icons/speaker.vue'
const playQueueStore = usePlayQueueStore()
const preferences = usePreferences()
gsap.registerPlugin(Draggable)
const progressBarThumb = useTemplateRef('progressBarThumb')
@ -30,10 +32,9 @@ const progressBarContainer = useTemplateRef('progressBarContainer')
const playQueueDialogContainer = useTemplateRef('playQueueDialogContainer')
const playQueueDialog = useTemplateRef('playQueueDialog')
const displayTimeLeft = ref(false)
const presentQueueListDialog = ref(false)
onMounted(() => {
onMounted(async () => {
Draggable.create(progressBarThumb.value, {
type: 'x',
bounds: progressBarContainer.value,
@ -204,10 +205,10 @@ function getCurrentTrack() {
</div>
<div class="flex flex-1">
<div class="flex-1" />
<button class="text-white/90 font-medium text-right relative" @click="displayTimeLeft = !displayTimeLeft">
<button class="text-white/90 font-medium text-right relative" @click="preferences.displayTimeLeft = !preferences.displayTimeLeft">
<span
class="text-black blur-lg absolute top-0">{{ `${displayTimeLeft ? '-' : ''}${timeFormatter(displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
<span>{{ `${displayTimeLeft ? '-' : ''}${timeFormatter(displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
class="text-black blur-lg absolute top-0">{{ `${preferences.displayTimeLeft ? '-' : ''}${timeFormatter(preferences.displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
<span>{{ `${preferences.displayTimeLeft ? '-' : ''}${timeFormatter(preferences.displayTimeLeft ? Math.floor(playQueueStore.duration) - Math.floor(playQueueStore.currentTime) : playQueueStore.duration)}` }}</span>
</button>
</div>
</div>

View File

@ -0,0 +1,47 @@
import { defineStore } from "pinia"
import { ref, watch } from "vue"
import browser from 'webextension-polyfill'
export const usePreferences = defineStore('preferences', () => {
const displayTimeLeft = ref<boolean>(false) // 设置默认值
const isLoaded = ref(false) // 添加加载状态
// 异步初始化函数
const initializePreferences = async () => {
try {
// 指定默认值对象
const result = await browser.storage.local.get({
displayTimeLeft: false // 如果键不存在,使用这个默认值
})
displayTimeLeft.value = result.displayTimeLeft as boolean // 现在类型是安全的
isLoaded.value = true
} catch (error) {
console.error('加载偏好设置失败:', error)
displayTimeLeft.value = false
isLoaded.value = true
}
}
// 监听变化并保存
watch(displayTimeLeft, async (val) => {
if (isLoaded.value) { // 只有在初始化完成后才保存
try {
await browser.storage.local.set({
displayTimeLeft: val
})
} catch (error) {
console.error('保存偏好设置失败:', error)
}
}
})
// 立即初始化
initializePreferences()
return {
displayTimeLeft,
isLoaded,
initializePreferences
}
})