@eternalheart/vue-file-preview 1.5.2 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/lib/chunks/{index-mhQw2-sq.mjs → index-BA78ONnG.mjs} +2 -2
  2. package/lib/chunks/{index-mhQw2-sq.mjs.map → index-BA78ONnG.mjs.map} +1 -1
  3. package/lib/chunks/{index-C9fAHdS1.mjs → index-BNub3BMM.mjs} +2 -2
  4. package/lib/chunks/{index-C9fAHdS1.mjs.map → index-BNub3BMM.mjs.map} +1 -1
  5. package/lib/chunks/{index-BqwsrkwV.mjs → index-BOqceW1a.mjs} +2 -2
  6. package/lib/chunks/{index-BqwsrkwV.mjs.map → index-BOqceW1a.mjs.map} +1 -1
  7. package/lib/chunks/{index-CD5kjM5X.mjs → index-C3LVlj74.mjs} +2 -2
  8. package/lib/chunks/{index-CD5kjM5X.mjs.map → index-C3LVlj74.mjs.map} +1 -1
  9. package/lib/chunks/{index-CYQ10J1C.mjs → index-CeQ3X5A0.mjs} +2 -2
  10. package/lib/chunks/{index-CYQ10J1C.mjs.map → index-CeQ3X5A0.mjs.map} +1 -1
  11. package/lib/chunks/{index-8qeRD8iW.mjs → index-CftjnCD3.mjs} +2 -2
  12. package/lib/chunks/{index-8qeRD8iW.mjs.map → index-CftjnCD3.mjs.map} +1 -1
  13. package/lib/chunks/{index-CF0R95Pi.mjs → index-CiNV11PZ.mjs} +2 -2
  14. package/lib/chunks/{index-CF0R95Pi.mjs.map → index-CiNV11PZ.mjs.map} +1 -1
  15. package/lib/chunks/{index-Ca2I4ZBD.mjs → index-Cknc_5FD.mjs} +3 -3
  16. package/lib/chunks/{index-Ca2I4ZBD.mjs.map → index-Cknc_5FD.mjs.map} +1 -1
  17. package/lib/chunks/{index-BmFY1Qva.mjs → index-ClxPMbSW.mjs} +2 -2
  18. package/lib/chunks/{index-BmFY1Qva.mjs.map → index-ClxPMbSW.mjs.map} +1 -1
  19. package/lib/chunks/{index-BlPq3HPF.mjs → index-D6e4OqEP.mjs} +400 -398
  20. package/lib/chunks/{index-BlPq3HPF.mjs.map → index-D6e4OqEP.mjs.map} +1 -1
  21. package/lib/chunks/{index-M8aNDlWF.mjs → index-DFgOIsmL.mjs} +2 -2
  22. package/lib/chunks/{index-M8aNDlWF.mjs.map → index-DFgOIsmL.mjs.map} +1 -1
  23. package/lib/chunks/{index-BeV59hG7.mjs → index-DJuJHCEr.mjs} +2 -2
  24. package/lib/chunks/{index-BeV59hG7.mjs.map → index-DJuJHCEr.mjs.map} +1 -1
  25. package/lib/chunks/{index-2cWRGn9r.mjs → index-DX_csr-A.mjs} +3 -3
  26. package/lib/chunks/{index-2cWRGn9r.mjs.map → index-DX_csr-A.mjs.map} +1 -1
  27. package/lib/chunks/{index-CHSHO4_E.mjs → index-IMsmPEyV.mjs} +2 -2
  28. package/lib/chunks/{index-CHSHO4_E.mjs.map → index-IMsmPEyV.mjs.map} +1 -1
  29. package/lib/chunks/{index-DMeFrZmR.mjs → index-JukJdgu9.mjs} +2 -2
  30. package/lib/chunks/{index-DMeFrZmR.mjs.map → index-JukJdgu9.mjs.map} +1 -1
  31. package/lib/chunks/{index-2_-gWmf5.mjs → index-MpkzsEnQ.mjs} +3 -3
  32. package/lib/chunks/{index-2_-gWmf5.mjs.map → index-MpkzsEnQ.mjs.map} +1 -1
  33. package/lib/chunks/{index-Bk1Ehxrn.mjs → index-_LiTOnzg.mjs} +2 -2
  34. package/lib/chunks/{index-Bk1Ehxrn.mjs.map → index-_LiTOnzg.mjs.map} +1 -1
  35. package/lib/chunks/{index-Cq-Wmksy.mjs → index-vAawymJZ.mjs} +2 -2
  36. package/lib/chunks/{index-Cq-Wmksy.mjs.map → index-vAawymJZ.mjs.map} +1 -1
  37. package/lib/chunks/{index-Dt-64Xh8.mjs → index-y-o-uhN7.mjs} +2 -2
  38. package/lib/chunks/{index-Dt-64Xh8.mjs.map → index-y-o-uhN7.mjs.map} +1 -1
  39. package/lib/chunks/{useShikiHighlight-htXC5ybJ.mjs → useShikiHighlight-P6H6Zwbu.mjs} +2 -2
  40. package/lib/chunks/{useShikiHighlight-htXC5ybJ.mjs.map → useShikiHighlight-P6H6Zwbu.mjs.map} +1 -1
  41. package/lib/index.cjs +54 -41
  42. package/lib/index.cjs.map +1 -1
  43. package/lib/index.css +1 -1
  44. package/lib/index.d.ts.map +1 -1
  45. package/lib/index.mjs +13 -12
  46. package/lib/index.mjs.map +1 -1
  47. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  import { ref as v, watch as J, onUnmounted as ae, defineComponent as re, toRef as le, computed as C, onMounted as ne, onBeforeUnmount as oe, unref as t, openBlock as _, createBlock as R, createElementBlock as K, normalizeClass as s, createElementVNode as a, normalizeStyle as w, createStaticVNode as se, toDisplayString as j, createVNode as B, resolveDynamicComponent as ie, Transition as ve, withCtx as fe, createCommentVNode as pe } from "vue";
2
2
  import { VolumeX as de, Volume1 as ue, Volume2 as ce, Repeat as me, SkipBack as ge, Pause as xe, Play as be, SkipForward as he } from "lucide-vue-next";
3
- import { k as ye, u as we, _ as ke } from "./index-BlPq3HPF.mjs";
3
+ import { k as ye, u as we, _ as ke } from "./index-D6e4OqEP.mjs";
4
4
  import { _ as Le } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
5
5
  function Ee(S) {
6
6
  const d = v(null), k = v(!1), m = v(!0), p = v(0), $ = v(0), c = v(1), L = v(!1), E = v(!1), u = v(null);
@@ -464,4 +464,4 @@ const Ge = { class: "vfp-w-full vfp-flex vfp-justify-center vfp-flex-shrink-0" }
464
464
  export {
465
465
  qe as default
466
466
  };
467
- //# sourceMappingURL=index-mhQw2-sq.mjs.map
467
+ //# sourceMappingURL=index-BA78ONnG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-mhQw2-sq.mjs","sources":["../../src/composables/useAudioPlayer.ts","../../src/renderers/Audio/index.vue"],"sourcesContent":["import { ref, watch, onUnmounted, type Ref } from 'vue';\nimport { formatTime } from '@eternalheart/file-preview-core';\n\n/**\n * Vue 3 版本的音频播放器 composable\n * 与 React 版的 useAudioPlayer 行为对齐\n */\nexport function useAudioPlayer(url: Ref<string>) {\n const audioRef = ref<HTMLAudioElement | null>(null);\n const isPlaying = ref(false);\n const isLoading = ref(true);\n const currentTime = ref(0);\n const duration = ref(0);\n const volume = ref(1);\n const isMuted = ref(false);\n const isLoop = ref(false);\n const error = ref<string | null>(null);\n\n let cleanup: (() => void) | null = null;\n\n const bindEvents = () => {\n const audio = audioRef.value;\n if (!audio) return;\n\n isLoading.value = true;\n error.value = null;\n\n const onTimeUpdate = () => {\n if (!isNaN(audio.currentTime)) {\n currentTime.value = audio.currentTime;\n }\n };\n\n const onDurationChange = () => {\n if (!isNaN(audio.duration) && isFinite(audio.duration)) {\n duration.value = audio.duration;\n }\n };\n\n const onCanPlay = () => {\n isLoading.value = false;\n onDurationChange();\n };\n\n const onWaiting = () => {\n isLoading.value = true;\n };\n const onPlaying = () => {\n isLoading.value = false;\n isPlaying.value = true;\n };\n\n const onPlay = () => {\n isPlaying.value = true;\n };\n const onPause = () => {\n isPlaying.value = false;\n };\n const onEnded = () => {\n isPlaying.value = false;\n };\n\n const onError = () => {\n error.value = '音频加载失败';\n isLoading.value = false;\n };\n\n audio.addEventListener('timeupdate', onTimeUpdate);\n audio.addEventListener('loadedmetadata', onDurationChange);\n audio.addEventListener('durationchange', onDurationChange);\n audio.addEventListener('canplay', onCanPlay);\n audio.addEventListener('waiting', onWaiting);\n audio.addEventListener('playing', onPlaying);\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('error', onError);\n\n if (audio.readyState >= 3) {\n isLoading.value = false;\n onDurationChange();\n } else if (audio.readyState >= 1) {\n onDurationChange();\n }\n\n cleanup = () => {\n audio.removeEventListener('timeupdate', onTimeUpdate);\n audio.removeEventListener('loadedmetadata', onDurationChange);\n audio.removeEventListener('durationchange', onDurationChange);\n audio.removeEventListener('canplay', onCanPlay);\n audio.removeEventListener('waiting', onWaiting);\n audio.removeEventListener('playing', onPlaying);\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('error', onError);\n };\n };\n\n // url 变化时重新绑定\n watch(\n url,\n () => {\n cleanup?.();\n cleanup = null;\n // 等待 DOM 更新(audio src 变化)\n requestAnimationFrame(() => bindEvents());\n },\n { flush: 'post' }\n );\n\n // 在 audioRef 挂载后首次绑定\n watch(\n audioRef,\n (el) => {\n if (el) bindEvents();\n },\n { flush: 'post' }\n );\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n const togglePlay = () => {\n const audio = audioRef.value;\n if (!audio) return;\n if (audio.paused) {\n audio.play().catch(() => {});\n } else {\n audio.pause();\n }\n };\n\n const seek = (time: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.currentTime = time;\n currentTime.value = time;\n };\n\n const skip = (seconds: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.currentTime = Math.max(\n 0,\n Math.min(audio.currentTime + seconds, audio.duration || Infinity)\n );\n };\n\n const setVolume = (vol: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n const clamped = Math.max(0, Math.min(1, vol));\n audio.volume = clamped;\n volume.value = clamped;\n if (clamped > 0) {\n audio.muted = false;\n isMuted.value = false;\n }\n };\n\n const toggleMute = () => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.muted = !audio.muted;\n isMuted.value = audio.muted;\n };\n\n const toggleLoop = () => {\n const audio = audioRef.value;\n if (!audio) return;\n const next = !audio.loop;\n audio.loop = next;\n isLoop.value = next;\n };\n\n return {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n };\n}\n","<script setup lang=\"ts\">\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nimport { ref, computed, onMounted, onBeforeUnmount, toRef } from 'vue';\nimport { Play, Pause, Volume2, VolumeX, Volume1, SkipBack, SkipForward, Repeat } from 'lucide-vue-next';\nimport { useAudioPlayer } from '../../composables/useAudioPlayer';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n fileName: string;\n}>();\n\nconst urlRef = toRef(props, 'url');\n\nconst { t } = useTranslator();\n\nconst {\n audioRef,\n isPlaying,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n} = useAudioPlayer(urlRef);\n\nconst showVolume = ref(false);\nconst isCompact = ref(false);\nconst controlScale = ref(1);\nconst isDragging = ref(false);\nconst dragTime = ref(0);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet volumeHideTimer: number | null = null;\nconst volumeRef = ref<HTMLDivElement | null>(null);\n\nconst displayTime = computed(() => (isDragging.value ? dragTime.value : currentTime.value));\nconst progress = computed(() => (duration.value > 0 ? displayTime.value / duration.value : 0));\n\n// 动态计算尺寸\nconst vinylScale = computed(() => (isCompact.value ? 0.72 : 1));\n// 唱片跟随控制面板同步缩放,避免头重脚轻\nconst finalVinylScale = computed(() => vinylScale.value * controlScale.value);\nconst vinylBase = 260;\nconst vinylHeightBase = 240;\n\nconst VolumeIcon = computed(() => {\n if (isMuted.value || volume.value === 0) return VolumeX;\n if (volume.value < 0.5) return Volume1;\n return Volume2;\n});\n\nconst handleClickOutside = (e: MouseEvent) => {\n if (volumeRef.value && !volumeRef.value.contains(e.target as Node)) {\n showVolume.value = false;\n }\n};\n\nlet resizeObserver: ResizeObserver | null = null;\n\nonMounted(() => {\n document.addEventListener('mousedown', handleClickOutside);\n const checkSize = () => {\n if (containerRef.value) {\n isCompact.value = containerRef.value.clientHeight < 580;\n // 控制面板宽度自适应缩放\n // 基础宽度 464px,最小视觉宽度 320px,即最小 scale ≈ 0.714\n const width = containerRef.value.clientWidth;\n const baseWidth = 464;\n const minVisualWidth = 320;\n const minScale = minVisualWidth / baseWidth;\n const scale = width >= baseWidth\n ? 1\n : Math.max(minScale, width / baseWidth);\n controlScale.value = scale;\n }\n };\n checkSize();\n if (containerRef.value) {\n resizeObserver = new ResizeObserver(checkSize);\n resizeObserver.observe(containerRef.value);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', handleClickOutside);\n if (volumeHideTimer !== null) clearTimeout(volumeHideTimer);\n if (resizeObserver) {\n resizeObserver.disconnect();\n resizeObserver = null;\n }\n});\n\nconst handleVolumeEnter = () => {\n if (volumeHideTimer !== null) clearTimeout(volumeHideTimer);\n showVolume.value = true;\n};\n\nconst handleVolumeLeave = () => {\n volumeHideTimer = window.setTimeout(() => {\n showVolume.value = false;\n }, 300);\n};\n\nconst getToolbarGroups = (): ToolbarGroup[] => [];\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n});\n\n</script>\n\n<template>\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <div\n v-else\n ref=\"containerRef\"\n :class=\"[\n 'vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-select-none vfp-overflow-auto',\n isCompact ? 'vfp-p-3 vfp-gap-3' : 'vfp-p-6 vfp-gap-6'\n ]\"\n >\n <!-- 唱片机 -->\n <div\n class=\"vfp-relative vfp-flex-shrink-0\"\n :style=\"{\n width: `${vinylBase}px`,\n height: `${vinylHeightBase}px`,\n transform: `scale(${finalVinylScale})`,\n transformOrigin: 'center center',\n marginTop: isCompact ? `${-(vinylHeightBase * (1 - finalVinylScale)) / 2}px` : 0,\n marginBottom: isCompact ? `${-(vinylHeightBase * (1 - finalVinylScale)) / 2}px` : 0,\n }\"\n >\n <!-- 外圈光晕 -->\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '220px',\n height: '220px',\n top: '18px',\n left: '8px',\n background: 'radial-gradient(circle, rgba(129,140,248,0.12) 0%, transparent 70%)',\n opacity: isPlaying ? 0.7 : 0.2,\n transition: 'opacity 0.5s',\n }\"\n />\n\n <!-- 唱片主体 -->\n <div\n class=\"vfp-absolute vfp-rounded-full vfp-overflow-hidden\"\n :style=\"{\n width: '200px',\n height: '200px',\n top: '28px',\n left: '18px',\n background: `\n radial-gradient(circle at center, transparent 95%, rgba(30,30,30,0.8) 95.5%, #111 97%),\n radial-gradient(circle at center, transparent 38%, rgba(50,50,50,0.5) 38.15%, transparent 38.4%),\n radial-gradient(circle at center, transparent 45%, rgba(50,50,50,0.3) 45.15%, transparent 45.4%),\n radial-gradient(circle at center, transparent 52%, rgba(50,50,50,0.5) 52.15%, transparent 52.4%),\n radial-gradient(circle at center, transparent 59%, rgba(50,50,50,0.3) 59.15%, transparent 59.4%),\n radial-gradient(circle at center, transparent 66%, rgba(50,50,50,0.5) 66.15%, transparent 66.4%),\n radial-gradient(circle at center, transparent 73%, rgba(50,50,50,0.3) 73.15%, transparent 73.4%),\n radial-gradient(circle at center, transparent 80%, rgba(50,50,50,0.4) 80.15%, transparent 80.4%),\n radial-gradient(circle at center, transparent 87%, rgba(50,50,50,0.3) 87.15%, transparent 87.4%),\n conic-gradient(from 0deg, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c, #212121, #1a1a1a, #252525, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c)\n `,\n boxShadow: isPlaying\n ? '0 0 36px rgba(129,140,248,0.1), 0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)'\n : '0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)',\n animation: 'vfp-vinyl-spin 8s linear infinite',\n animationPlayState: isPlaying ? 'running' : 'paused',\n }\"\n >\n <!-- 中心标签 -->\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '34%',\n height: '34%',\n top: '33%',\n left: '33%',\n background: 'radial-gradient(circle at 40% 38%, #818cf8, #6366f1, #4f46e5, #4338ca)',\n boxShadow: 'inset 0 1px 3px rgba(255,255,255,0.25), inset 0 -1px 3px rgba(0,0,0,0.3), 0 0 8px rgba(0,0,0,0.3)',\n }\"\n >\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '14%',\n height: '14%',\n top: '43%',\n left: '43%',\n background: 'radial-gradient(circle at 40% 40%, #333, #0d0d0d)',\n boxShadow: 'inset 0 1px 3px rgba(0,0,0,0.9), 0 0 2px rgba(0,0,0,0.5)',\n }\"\n />\n </div>\n </div>\n\n <!-- 唱臂 -->\n <div\n class=\"vfp-absolute\"\n :style=\"{\n top: '-6px',\n right: '2px',\n width: '100px',\n height: '120px',\n transformOrigin: '76px 16px',\n zIndex: 5,\n transform: isPlaying ? 'rotate(16deg)' : 'rotate(0deg)',\n transition: 'transform 0.8s cubic-bezier(0.4, 0, 0.2, 1)',\n }\"\n >\n <svg width=\"100\" height=\"120\" viewBox=\"0 0 100 120\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"76\" cy=\"16\" r=\"13\" fill=\"rgba(0,0,0,0.3)\" />\n <circle cx=\"76\" cy=\"16\" r=\"11\" fill=\"url(#vfp-baseGrad)\" />\n <circle cx=\"76\" cy=\"16\" r=\"6\" fill=\"url(#vfp-baseInnerGrad)\" />\n <circle cx=\"76\" cy=\"16\" r=\"2.5\" fill=\"#222\" stroke=\"#555\" stroke-width=\"0.5\" />\n <path d=\"M74 22 L56 88\" stroke=\"url(#vfp-armGrad)\" stroke-width=\"3.5\" stroke-linecap=\"round\" />\n <rect x=\"50\" y=\"86\" width=\"12\" height=\"7\" rx=\"1.5\" fill=\"url(#vfp-headGrad)\" />\n <rect x=\"52.5\" y=\"92\" width=\"7\" height=\"9\" rx=\"1\" fill=\"url(#vfp-cartridgeGrad)\" />\n <line x1=\"56\" y1=\"101\" x2=\"56\" y2=\"105\" stroke=\"#bbb\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n <circle cx=\"56\" cy=\"105.5\" r=\"0.8\" fill=\"#ddd\" />\n\n <defs>\n <radialGradient id=\"vfp-baseGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"100%\" stop-color=\"#1a1a1a\" />\n </radialGradient>\n <radialGradient id=\"vfp-baseInnerGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stop-color=\"#666\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </radialGradient>\n <linearGradient id=\"vfp-armGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"50%\" stop-color=\"#444\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </linearGradient>\n <linearGradient id=\"vfp-headGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </linearGradient>\n <linearGradient id=\"vfp-cartridgeGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#444\" />\n <stop offset=\"100%\" stop-color=\"#222\" />\n </linearGradient>\n </defs>\n </svg>\n </div>\n </div>\n\n <!-- 文件名 -->\n <div :class=\"['vfp-text-center vfp-max-w-md vfp-flex-shrink-0', isCompact ? 'vfp-px-2' : 'vfp-px-4']\">\n <div\n :class=\"[\n 'vfp-font-medium vfp-truncate vfp-text-fg-primary',\n isCompact ? 'vfp-text-sm' : 'vfp-text-lg'\n ]\"\n >\n {{ fileName }}\n </div>\n </div>\n\n <!-- 控制面板 wrapper:按容器宽度整体缩放,保底视觉宽度 320px -->\n <div class=\"vfp-w-full vfp-flex vfp-justify-center vfp-flex-shrink-0\">\n <div\n :class=\"[\n 'vfp-rounded-2xl vfp-border vfp-bg-surface-1 vfp-border-line-weak',\n isCompact ? 'vfp-p-3' : 'vfp-p-5'\n ]\"\n :style=\"{\n width: '448px',\n backdropFilter: 'blur(16px)',\n transform: controlScale < 1 ? `scale(${controlScale})` : undefined,\n transformOrigin: 'top center',\n marginBottom: controlScale < 1 ? `${-(1 - controlScale) * 100}px` : undefined,\n }\"\n >\n <!-- 进度条 -->\n <div :class=\"isCompact ? 'vfp-mb-3' : 'vfp-mb-5'\">\n <div class=\"vfp-relative vfp-h-4 vfp-flex vfp-items-center\">\n <div\n class=\"vfp-absolute vfp-w-full vfp-h-[5px] vfp-rounded-full vfp-bg-surface-2\"\n />\n <div\n class=\"vfp-absolute vfp-h-[5px] vfp-rounded-full vfp-pointer-events-none\"\n :style=\"{\n width: `${progress * 100}%`,\n background: 'linear-gradient(90deg, var(--fp-accent), var(--fp-accent-hover))',\n boxShadow: isPlaying ? '0 0 8px rgba(129,140,248,0.4)' : 'none',\n transition: isDragging ? 'none' : 'width 0.1s linear',\n }\"\n />\n <input\n type=\"range\"\n min=\"0\"\n :max=\"duration > 0 ? duration : currentTime || 100\"\n step=\"any\"\n :value=\"displayTime\"\n :disabled=\"duration <= 0\"\n :aria-label=\"t('audio.aria.progress')\"\n class=\"audio-slider vfp-absolute vfp-w-full\"\n @pointerdown=\"() => { dragTime = currentTime; isDragging = true; }\"\n @input=\"(e) => {\n const value = parseFloat((e.target as HTMLInputElement).value);\n if (isDragging) {\n dragTime = value;\n } else {\n seek(value);\n }\n }\"\n @pointerup=\"(e) => {\n const value = parseFloat((e.target as HTMLInputElement).value);\n seek(value);\n isDragging = false;\n }\"\n @pointercancel=\"isDragging = false\"\n />\n </div>\n <div\n :class=\"[\n 'vfp-flex vfp-justify-between vfp-text-fg-tertiary',\n isCompact ? 'vfp-text-[10px] vfp-mt-1.5' : 'vfp-text-xs vfp-mt-2.5'\n ]\"\n >\n <span style=\"font-variant-numeric: tabular-nums\">{{ formatTime(displayTime) }}</span>\n <span style=\"font-variant-numeric: tabular-nums\">{{ duration > 0 ? formatTime(duration) : '--:--' }}</span>\n </div>\n </div>\n\n <!-- 控制按钮 -->\n <div :class=\"['vfp-flex vfp-items-center vfp-justify-center', isCompact ? 'vfp-gap-2' : 'vfp-gap-3']\">\n <!-- 循环 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-8 vfp-h-8' : 'vfp-w-9 vfp-h-9',\n isLoop ? 'vfp-bg-accent-soft vfp-text-accent' : 'vfp-bg-surface-2 vfp-text-fg-tertiary',\n ]\"\n :aria-label=\"isLoop ? t('audio.aria.loop_off') : t('audio.aria.loop_on')\"\n @click=\"toggleLoop\"\n >\n <Repeat :class=\"isCompact ? 'vfp-w-3.5 vfp-h-3.5' : 'vfp-w-4 vfp-h-4'\" />\n </button>\n\n <!-- 后退 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-bg-surface-2 vfp-text-fg-secondary vfp-flex-shrink-0',\n isCompact ? 'vfp-w-9 vfp-h-9' : 'vfp-w-10 vfp-h-10'\n ]\"\n :aria-label=\"t('audio.aria.backward_10')\"\n @click=\"skip(-10)\"\n >\n <SkipBack :class=\"isCompact ? 'vfp-w-4 vfp-h-4' : 'vfp-w-[18px] vfp-h-[18px]'\" />\n </button>\n\n <!-- 播放/暂停 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-12 vfp-h-12' : 'vfp-w-14 vfp-h-14'\n ]\"\n :style=\"{\n background: 'linear-gradient(135deg, var(--fp-accent-hover), var(--fp-accent))',\n color: '#fff',\n boxShadow: '0 4px 20px rgba(99,102,241,0.35)',\n }\"\n :aria-label=\"isPlaying ? t('audio.aria.pause') : t('audio.aria.play')\"\n @click=\"togglePlay\"\n >\n <Pause v-if=\"isPlaying\" :class=\"isCompact ? 'vfp-w-5 vfp-h-5' : 'vfp-w-6 vfp-h-6'\" />\n <Play v-else :class=\"isCompact ? 'vfp-w-5 vfp-h-5 vfp-ml-0.5' : 'vfp-w-6 vfp-h-6 vfp-ml-0.5'\" />\n </button>\n\n <!-- 前进 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-bg-surface-2 vfp-text-fg-secondary vfp-flex-shrink-0',\n isCompact ? 'vfp-w-9 vfp-h-9' : 'vfp-w-10 vfp-h-10'\n ]\"\n :aria-label=\"t('audio.aria.forward_10')\"\n @click=\"skip(10)\"\n >\n <SkipForward :class=\"isCompact ? 'vfp-w-4 vfp-h-4' : 'vfp-w-[18px] vfp-h-[18px]'\" />\n </button>\n\n <!-- 音量 -->\n <div ref=\"volumeRef\" class=\"vfp-relative\" @mouseenter=\"handleVolumeEnter\" @mouseleave=\"handleVolumeLeave\">\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-8 vfp-h-8' : 'vfp-w-9 vfp-h-9',\n showVolume ? 'vfp-bg-accent-soft vfp-text-accent' : 'vfp-bg-surface-2 vfp-text-fg-secondary',\n ]\"\n :aria-label=\"isMuted ? t('audio.aria.unmute') : t('audio.aria.mute')\"\n @click=\"toggleMute\"\n >\n <component :is=\"VolumeIcon\" :class=\"isCompact ? 'vfp-w-3.5 vfp-h-3.5' : 'vfp-w-4 vfp-h-4'\" />\n </button>\n\n <Transition name=\"vfp-fade\">\n <div\n v-if=\"showVolume\"\n class=\"vfp-absolute vfp-bottom-full vfp-mb-2 vfp-rounded-xl vfp-p-3 vfp-border vfp-bg-surface-3 vfp-border-line\"\n :style=\"{\n left: '50%',\n marginLeft: '-27px',\n backdropFilter: 'blur(16px)',\n }\"\n @mouseenter=\"handleVolumeEnter\"\n @mouseleave=\"handleVolumeLeave\"\n >\n <div class=\"vfp-flex vfp-flex-col vfp-items-center vfp-gap-2\" style=\"height: 100px\">\n <div\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center\"\n style=\"width: 24px; height: 80px\"\n >\n <div\n class=\"vfp-absolute vfp-rounded-full vfp-bg-surface-2\"\n style=\"width: 3px; height: 100%\"\n />\n <div\n class=\"vfp-absolute vfp-bottom-0 vfp-rounded-full vfp-pointer-events-none\"\n :style=\"{\n width: '3px',\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: 'var(--fp-accent-hover)',\n transition: 'height 0.1s linear',\n }\"\n />\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n :value=\"isMuted ? 0 : volume\"\n :aria-label=\"t('audio.aria.volume')\"\n class=\"volume-slider-vertical vfp-absolute\"\n style=\"width: 80px; height: 24px; transform: rotate(-90deg); transform-origin: center center\"\n @input=\"(e) => setVolume(parseFloat((e.target as HTMLInputElement).value))\"\n />\n </div>\n <span class=\"vfp-text-[10px] vfp-tabular-nums vfp-text-fg-tertiary\">\n {{ Math.round((isMuted ? 0 : volume) * 100) }}\n </span>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n </div>\n <!-- wrapper 闭合 -->\n </div>\n\n <audio ref=\"audioRef\" :src=\"url\" class=\"vfp-hidden\" />\n </div>\n</template>\n\n<style scoped>\n.audio-ctrl-btn {\n border: 0;\n cursor: pointer;\n}\n</style>\n"],"names":["useAudioPlayer","url","audioRef","ref","isPlaying","isLoading","currentTime","duration","volume","isMuted","isLoop","error","cleanup","bindEvents","audio","onTimeUpdate","onDurationChange","onCanPlay","onWaiting","onPlaying","onPlay","onPause","onEnded","onError","watch","el","onUnmounted","time","seconds","vol","clamped","next","formatTime","vinylBase","vinylHeightBase","urlRef","toRef","__props","t","useTranslator","togglePlay","seek","skip","setVolume","toggleMute","toggleLoop","showVolume","isCompact","controlScale","isDragging","dragTime","containerRef","volumeHideTimer","volumeRef","displayTime","computed","progress","vinylScale","finalVinylScale","VolumeIcon","VolumeX","Volume1","Volume2","handleClickOutside","e","resizeObserver","onMounted","checkSize","width","baseWidth","minScale","scale","onBeforeUnmount","handleVolumeEnter","handleVolumeLeave","__expose","_unref","_createBlock","RendererError","_createElementBlock","_normalizeClass","_createElementVNode","_normalizeStyle","_hoisted_1","_hoisted_2","_cache","value","_hoisted_4","_toDisplayString","_hoisted_5","args","_createVNode","Repeat","SkipBack","Pause","Play","SkipForward","_openBlock","_resolveDynamicComponent","_Transition","_hoisted_11","_hoisted_12","_hoisted_14"],"mappings":"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"}
1
+ {"version":3,"file":"index-BA78ONnG.mjs","sources":["../../src/composables/useAudioPlayer.ts","../../src/renderers/Audio/index.vue"],"sourcesContent":["import { ref, watch, onUnmounted, type Ref } from 'vue';\nimport { formatTime } from '@eternalheart/file-preview-core';\n\n/**\n * Vue 3 版本的音频播放器 composable\n * 与 React 版的 useAudioPlayer 行为对齐\n */\nexport function useAudioPlayer(url: Ref<string>) {\n const audioRef = ref<HTMLAudioElement | null>(null);\n const isPlaying = ref(false);\n const isLoading = ref(true);\n const currentTime = ref(0);\n const duration = ref(0);\n const volume = ref(1);\n const isMuted = ref(false);\n const isLoop = ref(false);\n const error = ref<string | null>(null);\n\n let cleanup: (() => void) | null = null;\n\n const bindEvents = () => {\n const audio = audioRef.value;\n if (!audio) return;\n\n isLoading.value = true;\n error.value = null;\n\n const onTimeUpdate = () => {\n if (!isNaN(audio.currentTime)) {\n currentTime.value = audio.currentTime;\n }\n };\n\n const onDurationChange = () => {\n if (!isNaN(audio.duration) && isFinite(audio.duration)) {\n duration.value = audio.duration;\n }\n };\n\n const onCanPlay = () => {\n isLoading.value = false;\n onDurationChange();\n };\n\n const onWaiting = () => {\n isLoading.value = true;\n };\n const onPlaying = () => {\n isLoading.value = false;\n isPlaying.value = true;\n };\n\n const onPlay = () => {\n isPlaying.value = true;\n };\n const onPause = () => {\n isPlaying.value = false;\n };\n const onEnded = () => {\n isPlaying.value = false;\n };\n\n const onError = () => {\n error.value = '音频加载失败';\n isLoading.value = false;\n };\n\n audio.addEventListener('timeupdate', onTimeUpdate);\n audio.addEventListener('loadedmetadata', onDurationChange);\n audio.addEventListener('durationchange', onDurationChange);\n audio.addEventListener('canplay', onCanPlay);\n audio.addEventListener('waiting', onWaiting);\n audio.addEventListener('playing', onPlaying);\n audio.addEventListener('play', onPlay);\n audio.addEventListener('pause', onPause);\n audio.addEventListener('ended', onEnded);\n audio.addEventListener('error', onError);\n\n if (audio.readyState >= 3) {\n isLoading.value = false;\n onDurationChange();\n } else if (audio.readyState >= 1) {\n onDurationChange();\n }\n\n cleanup = () => {\n audio.removeEventListener('timeupdate', onTimeUpdate);\n audio.removeEventListener('loadedmetadata', onDurationChange);\n audio.removeEventListener('durationchange', onDurationChange);\n audio.removeEventListener('canplay', onCanPlay);\n audio.removeEventListener('waiting', onWaiting);\n audio.removeEventListener('playing', onPlaying);\n audio.removeEventListener('play', onPlay);\n audio.removeEventListener('pause', onPause);\n audio.removeEventListener('ended', onEnded);\n audio.removeEventListener('error', onError);\n };\n };\n\n // url 变化时重新绑定\n watch(\n url,\n () => {\n cleanup?.();\n cleanup = null;\n // 等待 DOM 更新(audio src 变化)\n requestAnimationFrame(() => bindEvents());\n },\n { flush: 'post' }\n );\n\n // 在 audioRef 挂载后首次绑定\n watch(\n audioRef,\n (el) => {\n if (el) bindEvents();\n },\n { flush: 'post' }\n );\n\n onUnmounted(() => {\n cleanup?.();\n cleanup = null;\n });\n\n const togglePlay = () => {\n const audio = audioRef.value;\n if (!audio) return;\n if (audio.paused) {\n audio.play().catch(() => {});\n } else {\n audio.pause();\n }\n };\n\n const seek = (time: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.currentTime = time;\n currentTime.value = time;\n };\n\n const skip = (seconds: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.currentTime = Math.max(\n 0,\n Math.min(audio.currentTime + seconds, audio.duration || Infinity)\n );\n };\n\n const setVolume = (vol: number) => {\n const audio = audioRef.value;\n if (!audio) return;\n const clamped = Math.max(0, Math.min(1, vol));\n audio.volume = clamped;\n volume.value = clamped;\n if (clamped > 0) {\n audio.muted = false;\n isMuted.value = false;\n }\n };\n\n const toggleMute = () => {\n const audio = audioRef.value;\n if (!audio) return;\n audio.muted = !audio.muted;\n isMuted.value = audio.muted;\n };\n\n const toggleLoop = () => {\n const audio = audioRef.value;\n if (!audio) return;\n const next = !audio.loop;\n audio.loop = next;\n isLoop.value = next;\n };\n\n return {\n audioRef,\n isPlaying,\n isLoading,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n };\n}\n","<script setup lang=\"ts\">\nimport type { RendererHandle } from '../base.types';\nimport type { ToolbarGroup } from '../toolbar.types';\n\nimport { ref, computed, onMounted, onBeforeUnmount, toRef } from 'vue';\nimport { Play, Pause, Volume2, VolumeX, Volume1, SkipBack, SkipForward, Repeat } from 'lucide-vue-next';\nimport { useAudioPlayer } from '../../composables/useAudioPlayer';\nimport { useTranslator } from '../../composables/useTranslator';\nimport RendererError from '../RendererError.vue';\n\nconst props = defineProps<{\n url: string;\n fileName: string;\n}>();\n\nconst urlRef = toRef(props, 'url');\n\nconst { t } = useTranslator();\n\nconst {\n audioRef,\n isPlaying,\n isLoop,\n currentTime,\n duration,\n volume,\n isMuted,\n error,\n togglePlay,\n seek,\n skip,\n setVolume,\n toggleMute,\n toggleLoop,\n formatTime,\n} = useAudioPlayer(urlRef);\n\nconst showVolume = ref(false);\nconst isCompact = ref(false);\nconst controlScale = ref(1);\nconst isDragging = ref(false);\nconst dragTime = ref(0);\nconst containerRef = ref<HTMLDivElement | null>(null);\nlet volumeHideTimer: number | null = null;\nconst volumeRef = ref<HTMLDivElement | null>(null);\n\nconst displayTime = computed(() => (isDragging.value ? dragTime.value : currentTime.value));\nconst progress = computed(() => (duration.value > 0 ? displayTime.value / duration.value : 0));\n\n// 动态计算尺寸\nconst vinylScale = computed(() => (isCompact.value ? 0.72 : 1));\n// 唱片跟随控制面板同步缩放,避免头重脚轻\nconst finalVinylScale = computed(() => vinylScale.value * controlScale.value);\nconst vinylBase = 260;\nconst vinylHeightBase = 240;\n\nconst VolumeIcon = computed(() => {\n if (isMuted.value || volume.value === 0) return VolumeX;\n if (volume.value < 0.5) return Volume1;\n return Volume2;\n});\n\nconst handleClickOutside = (e: MouseEvent) => {\n if (volumeRef.value && !volumeRef.value.contains(e.target as Node)) {\n showVolume.value = false;\n }\n};\n\nlet resizeObserver: ResizeObserver | null = null;\n\nonMounted(() => {\n document.addEventListener('mousedown', handleClickOutside);\n const checkSize = () => {\n if (containerRef.value) {\n isCompact.value = containerRef.value.clientHeight < 580;\n // 控制面板宽度自适应缩放\n // 基础宽度 464px,最小视觉宽度 320px,即最小 scale ≈ 0.714\n const width = containerRef.value.clientWidth;\n const baseWidth = 464;\n const minVisualWidth = 320;\n const minScale = minVisualWidth / baseWidth;\n const scale = width >= baseWidth\n ? 1\n : Math.max(minScale, width / baseWidth);\n controlScale.value = scale;\n }\n };\n checkSize();\n if (containerRef.value) {\n resizeObserver = new ResizeObserver(checkSize);\n resizeObserver.observe(containerRef.value);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('mousedown', handleClickOutside);\n if (volumeHideTimer !== null) clearTimeout(volumeHideTimer);\n if (resizeObserver) {\n resizeObserver.disconnect();\n resizeObserver = null;\n }\n});\n\nconst handleVolumeEnter = () => {\n if (volumeHideTimer !== null) clearTimeout(volumeHideTimer);\n showVolume.value = true;\n};\n\nconst handleVolumeLeave = () => {\n volumeHideTimer = window.setTimeout(() => {\n showVolume.value = false;\n }, 300);\n};\n\nconst getToolbarGroups = (): ToolbarGroup[] => [];\n\ndefineExpose<RendererHandle>({\n getToolbarGroups,\n});\n\n</script>\n\n<template>\n <RendererError v-if=\"error\" :message=\"error\" />\n\n <div\n v-else\n ref=\"containerRef\"\n :class=\"[\n 'vfp-flex vfp-flex-col vfp-items-center vfp-justify-center vfp-w-full vfp-h-full vfp-select-none vfp-overflow-auto',\n isCompact ? 'vfp-p-3 vfp-gap-3' : 'vfp-p-6 vfp-gap-6'\n ]\"\n >\n <!-- 唱片机 -->\n <div\n class=\"vfp-relative vfp-flex-shrink-0\"\n :style=\"{\n width: `${vinylBase}px`,\n height: `${vinylHeightBase}px`,\n transform: `scale(${finalVinylScale})`,\n transformOrigin: 'center center',\n marginTop: isCompact ? `${-(vinylHeightBase * (1 - finalVinylScale)) / 2}px` : 0,\n marginBottom: isCompact ? `${-(vinylHeightBase * (1 - finalVinylScale)) / 2}px` : 0,\n }\"\n >\n <!-- 外圈光晕 -->\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '220px',\n height: '220px',\n top: '18px',\n left: '8px',\n background: 'radial-gradient(circle, rgba(129,140,248,0.12) 0%, transparent 70%)',\n opacity: isPlaying ? 0.7 : 0.2,\n transition: 'opacity 0.5s',\n }\"\n />\n\n <!-- 唱片主体 -->\n <div\n class=\"vfp-absolute vfp-rounded-full vfp-overflow-hidden\"\n :style=\"{\n width: '200px',\n height: '200px',\n top: '28px',\n left: '18px',\n background: `\n radial-gradient(circle at center, transparent 95%, rgba(30,30,30,0.8) 95.5%, #111 97%),\n radial-gradient(circle at center, transparent 38%, rgba(50,50,50,0.5) 38.15%, transparent 38.4%),\n radial-gradient(circle at center, transparent 45%, rgba(50,50,50,0.3) 45.15%, transparent 45.4%),\n radial-gradient(circle at center, transparent 52%, rgba(50,50,50,0.5) 52.15%, transparent 52.4%),\n radial-gradient(circle at center, transparent 59%, rgba(50,50,50,0.3) 59.15%, transparent 59.4%),\n radial-gradient(circle at center, transparent 66%, rgba(50,50,50,0.5) 66.15%, transparent 66.4%),\n radial-gradient(circle at center, transparent 73%, rgba(50,50,50,0.3) 73.15%, transparent 73.4%),\n radial-gradient(circle at center, transparent 80%, rgba(50,50,50,0.4) 80.15%, transparent 80.4%),\n radial-gradient(circle at center, transparent 87%, rgba(50,50,50,0.3) 87.15%, transparent 87.4%),\n conic-gradient(from 0deg, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c, #212121, #1a1a1a, #252525, #1c1c1c, #232323, #1a1a1a, #262626, #1c1c1c)\n `,\n boxShadow: isPlaying\n ? '0 0 36px rgba(129,140,248,0.1), 0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)'\n : '0 8px 32px rgba(0,0,0,0.4), inset 0 0 20px rgba(0,0,0,0.4)',\n animation: 'vfp-vinyl-spin 8s linear infinite',\n animationPlayState: isPlaying ? 'running' : 'paused',\n }\"\n >\n <!-- 中心标签 -->\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '34%',\n height: '34%',\n top: '33%',\n left: '33%',\n background: 'radial-gradient(circle at 40% 38%, #818cf8, #6366f1, #4f46e5, #4338ca)',\n boxShadow: 'inset 0 1px 3px rgba(255,255,255,0.25), inset 0 -1px 3px rgba(0,0,0,0.3), 0 0 8px rgba(0,0,0,0.3)',\n }\"\n >\n <div\n class=\"vfp-absolute vfp-rounded-full\"\n :style=\"{\n width: '14%',\n height: '14%',\n top: '43%',\n left: '43%',\n background: 'radial-gradient(circle at 40% 40%, #333, #0d0d0d)',\n boxShadow: 'inset 0 1px 3px rgba(0,0,0,0.9), 0 0 2px rgba(0,0,0,0.5)',\n }\"\n />\n </div>\n </div>\n\n <!-- 唱臂 -->\n <div\n class=\"vfp-absolute\"\n :style=\"{\n top: '-6px',\n right: '2px',\n width: '100px',\n height: '120px',\n transformOrigin: '76px 16px',\n zIndex: 5,\n transform: isPlaying ? 'rotate(16deg)' : 'rotate(0deg)',\n transition: 'transform 0.8s cubic-bezier(0.4, 0, 0.2, 1)',\n }\"\n >\n <svg width=\"100\" height=\"120\" viewBox=\"0 0 100 120\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"76\" cy=\"16\" r=\"13\" fill=\"rgba(0,0,0,0.3)\" />\n <circle cx=\"76\" cy=\"16\" r=\"11\" fill=\"url(#vfp-baseGrad)\" />\n <circle cx=\"76\" cy=\"16\" r=\"6\" fill=\"url(#vfp-baseInnerGrad)\" />\n <circle cx=\"76\" cy=\"16\" r=\"2.5\" fill=\"#222\" stroke=\"#555\" stroke-width=\"0.5\" />\n <path d=\"M74 22 L56 88\" stroke=\"url(#vfp-armGrad)\" stroke-width=\"3.5\" stroke-linecap=\"round\" />\n <rect x=\"50\" y=\"86\" width=\"12\" height=\"7\" rx=\"1.5\" fill=\"url(#vfp-headGrad)\" />\n <rect x=\"52.5\" y=\"92\" width=\"7\" height=\"9\" rx=\"1\" fill=\"url(#vfp-cartridgeGrad)\" />\n <line x1=\"56\" y1=\"101\" x2=\"56\" y2=\"105\" stroke=\"#bbb\" stroke-width=\"1.2\" stroke-linecap=\"round\" />\n <circle cx=\"56\" cy=\"105.5\" r=\"0.8\" fill=\"#ddd\" />\n\n <defs>\n <radialGradient id=\"vfp-baseGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"100%\" stop-color=\"#1a1a1a\" />\n </radialGradient>\n <radialGradient id=\"vfp-baseInnerGrad\" cx=\"40%\" cy=\"35%\">\n <stop offset=\"0%\" stop-color=\"#666\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </radialGradient>\n <linearGradient id=\"vfp-armGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"50%\" stop-color=\"#444\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </linearGradient>\n <linearGradient id=\"vfp-headGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#555\" />\n <stop offset=\"100%\" stop-color=\"#333\" />\n </linearGradient>\n <linearGradient id=\"vfp-cartridgeGrad\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stop-color=\"#444\" />\n <stop offset=\"100%\" stop-color=\"#222\" />\n </linearGradient>\n </defs>\n </svg>\n </div>\n </div>\n\n <!-- 文件名 -->\n <div :class=\"['vfp-text-center vfp-max-w-md vfp-flex-shrink-0', isCompact ? 'vfp-px-2' : 'vfp-px-4']\">\n <div\n :class=\"[\n 'vfp-font-medium vfp-truncate vfp-text-fg-primary',\n isCompact ? 'vfp-text-sm' : 'vfp-text-lg'\n ]\"\n >\n {{ fileName }}\n </div>\n </div>\n\n <!-- 控制面板 wrapper:按容器宽度整体缩放,保底视觉宽度 320px -->\n <div class=\"vfp-w-full vfp-flex vfp-justify-center vfp-flex-shrink-0\">\n <div\n :class=\"[\n 'vfp-rounded-2xl vfp-border vfp-bg-surface-1 vfp-border-line-weak',\n isCompact ? 'vfp-p-3' : 'vfp-p-5'\n ]\"\n :style=\"{\n width: '448px',\n backdropFilter: 'blur(16px)',\n transform: controlScale < 1 ? `scale(${controlScale})` : undefined,\n transformOrigin: 'top center',\n marginBottom: controlScale < 1 ? `${-(1 - controlScale) * 100}px` : undefined,\n }\"\n >\n <!-- 进度条 -->\n <div :class=\"isCompact ? 'vfp-mb-3' : 'vfp-mb-5'\">\n <div class=\"vfp-relative vfp-h-4 vfp-flex vfp-items-center\">\n <div\n class=\"vfp-absolute vfp-w-full vfp-h-[5px] vfp-rounded-full vfp-bg-surface-2\"\n />\n <div\n class=\"vfp-absolute vfp-h-[5px] vfp-rounded-full vfp-pointer-events-none\"\n :style=\"{\n width: `${progress * 100}%`,\n background: 'linear-gradient(90deg, var(--fp-accent), var(--fp-accent-hover))',\n boxShadow: isPlaying ? '0 0 8px rgba(129,140,248,0.4)' : 'none',\n transition: isDragging ? 'none' : 'width 0.1s linear',\n }\"\n />\n <input\n type=\"range\"\n min=\"0\"\n :max=\"duration > 0 ? duration : currentTime || 100\"\n step=\"any\"\n :value=\"displayTime\"\n :disabled=\"duration <= 0\"\n :aria-label=\"t('audio.aria.progress')\"\n class=\"audio-slider vfp-absolute vfp-w-full\"\n @pointerdown=\"() => { dragTime = currentTime; isDragging = true; }\"\n @input=\"(e) => {\n const value = parseFloat((e.target as HTMLInputElement).value);\n if (isDragging) {\n dragTime = value;\n } else {\n seek(value);\n }\n }\"\n @pointerup=\"(e) => {\n const value = parseFloat((e.target as HTMLInputElement).value);\n seek(value);\n isDragging = false;\n }\"\n @pointercancel=\"isDragging = false\"\n />\n </div>\n <div\n :class=\"[\n 'vfp-flex vfp-justify-between vfp-text-fg-tertiary',\n isCompact ? 'vfp-text-[10px] vfp-mt-1.5' : 'vfp-text-xs vfp-mt-2.5'\n ]\"\n >\n <span style=\"font-variant-numeric: tabular-nums\">{{ formatTime(displayTime) }}</span>\n <span style=\"font-variant-numeric: tabular-nums\">{{ duration > 0 ? formatTime(duration) : '--:--' }}</span>\n </div>\n </div>\n\n <!-- 控制按钮 -->\n <div :class=\"['vfp-flex vfp-items-center vfp-justify-center', isCompact ? 'vfp-gap-2' : 'vfp-gap-3']\">\n <!-- 循环 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-8 vfp-h-8' : 'vfp-w-9 vfp-h-9',\n isLoop ? 'vfp-bg-accent-soft vfp-text-accent' : 'vfp-bg-surface-2 vfp-text-fg-tertiary',\n ]\"\n :aria-label=\"isLoop ? t('audio.aria.loop_off') : t('audio.aria.loop_on')\"\n @click=\"toggleLoop\"\n >\n <Repeat :class=\"isCompact ? 'vfp-w-3.5 vfp-h-3.5' : 'vfp-w-4 vfp-h-4'\" />\n </button>\n\n <!-- 后退 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-bg-surface-2 vfp-text-fg-secondary vfp-flex-shrink-0',\n isCompact ? 'vfp-w-9 vfp-h-9' : 'vfp-w-10 vfp-h-10'\n ]\"\n :aria-label=\"t('audio.aria.backward_10')\"\n @click=\"skip(-10)\"\n >\n <SkipBack :class=\"isCompact ? 'vfp-w-4 vfp-h-4' : 'vfp-w-[18px] vfp-h-[18px]'\" />\n </button>\n\n <!-- 播放/暂停 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-12 vfp-h-12' : 'vfp-w-14 vfp-h-14'\n ]\"\n :style=\"{\n background: 'linear-gradient(135deg, var(--fp-accent-hover), var(--fp-accent))',\n color: '#fff',\n boxShadow: '0 4px 20px rgba(99,102,241,0.35)',\n }\"\n :aria-label=\"isPlaying ? t('audio.aria.pause') : t('audio.aria.play')\"\n @click=\"togglePlay\"\n >\n <Pause v-if=\"isPlaying\" :class=\"isCompact ? 'vfp-w-5 vfp-h-5' : 'vfp-w-6 vfp-h-6'\" />\n <Play v-else :class=\"isCompact ? 'vfp-w-5 vfp-h-5 vfp-ml-0.5' : 'vfp-w-6 vfp-h-6 vfp-ml-0.5'\" />\n </button>\n\n <!-- 前进 -->\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-bg-surface-2 vfp-text-fg-secondary vfp-flex-shrink-0',\n isCompact ? 'vfp-w-9 vfp-h-9' : 'vfp-w-10 vfp-h-10'\n ]\"\n :aria-label=\"t('audio.aria.forward_10')\"\n @click=\"skip(10)\"\n >\n <SkipForward :class=\"isCompact ? 'vfp-w-4 vfp-h-4' : 'vfp-w-[18px] vfp-h-[18px]'\" />\n </button>\n\n <!-- 音量 -->\n <div ref=\"volumeRef\" class=\"vfp-relative\" @mouseenter=\"handleVolumeEnter\" @mouseleave=\"handleVolumeLeave\">\n <button\n :class=\"[\n 'vfp-rounded-full vfp-flex vfp-items-center vfp-justify-center vfp-transition-colors audio-ctrl-btn vfp-flex-shrink-0',\n isCompact ? 'vfp-w-8 vfp-h-8' : 'vfp-w-9 vfp-h-9',\n showVolume ? 'vfp-bg-accent-soft vfp-text-accent' : 'vfp-bg-surface-2 vfp-text-fg-secondary',\n ]\"\n :aria-label=\"isMuted ? t('audio.aria.unmute') : t('audio.aria.mute')\"\n @click=\"toggleMute\"\n >\n <component :is=\"VolumeIcon\" :class=\"isCompact ? 'vfp-w-3.5 vfp-h-3.5' : 'vfp-w-4 vfp-h-4'\" />\n </button>\n\n <Transition name=\"vfp-fade\">\n <div\n v-if=\"showVolume\"\n class=\"vfp-absolute vfp-bottom-full vfp-mb-2 vfp-rounded-xl vfp-p-3 vfp-border vfp-bg-surface-3 vfp-border-line\"\n :style=\"{\n left: '50%',\n marginLeft: '-27px',\n backdropFilter: 'blur(16px)',\n }\"\n @mouseenter=\"handleVolumeEnter\"\n @mouseleave=\"handleVolumeLeave\"\n >\n <div class=\"vfp-flex vfp-flex-col vfp-items-center vfp-gap-2\" style=\"height: 100px\">\n <div\n class=\"vfp-relative vfp-flex vfp-items-center vfp-justify-center\"\n style=\"width: 24px; height: 80px\"\n >\n <div\n class=\"vfp-absolute vfp-rounded-full vfp-bg-surface-2\"\n style=\"width: 3px; height: 100%\"\n />\n <div\n class=\"vfp-absolute vfp-bottom-0 vfp-rounded-full vfp-pointer-events-none\"\n :style=\"{\n width: '3px',\n height: `${(isMuted ? 0 : volume) * 100}%`,\n background: 'var(--fp-accent-hover)',\n transition: 'height 0.1s linear',\n }\"\n />\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n :value=\"isMuted ? 0 : volume\"\n :aria-label=\"t('audio.aria.volume')\"\n class=\"volume-slider-vertical vfp-absolute\"\n style=\"width: 80px; height: 24px; transform: rotate(-90deg); transform-origin: center center\"\n @input=\"(e) => setVolume(parseFloat((e.target as HTMLInputElement).value))\"\n />\n </div>\n <span class=\"vfp-text-[10px] vfp-tabular-nums vfp-text-fg-tertiary\">\n {{ Math.round((isMuted ? 0 : volume) * 100) }}\n </span>\n </div>\n </div>\n </Transition>\n </div>\n </div>\n </div>\n <!-- wrapper 闭合 -->\n </div>\n\n <audio ref=\"audioRef\" :src=\"url\" class=\"vfp-hidden\" />\n </div>\n</template>\n\n<style scoped>\n.audio-ctrl-btn {\n border: 0;\n cursor: pointer;\n}\n</style>\n"],"names":["useAudioPlayer","url","audioRef","ref","isPlaying","isLoading","currentTime","duration","volume","isMuted","isLoop","error","cleanup","bindEvents","audio","onTimeUpdate","onDurationChange","onCanPlay","onWaiting","onPlaying","onPlay","onPause","onEnded","onError","watch","el","onUnmounted","time","seconds","vol","clamped","next","formatTime","vinylBase","vinylHeightBase","urlRef","toRef","__props","t","useTranslator","togglePlay","seek","skip","setVolume","toggleMute","toggleLoop","showVolume","isCompact","controlScale","isDragging","dragTime","containerRef","volumeHideTimer","volumeRef","displayTime","computed","progress","vinylScale","finalVinylScale","VolumeIcon","VolumeX","Volume1","Volume2","handleClickOutside","e","resizeObserver","onMounted","checkSize","width","baseWidth","minScale","scale","onBeforeUnmount","handleVolumeEnter","handleVolumeLeave","__expose","_unref","_createBlock","RendererError","_createElementBlock","_normalizeClass","_createElementVNode","_normalizeStyle","_hoisted_1","_hoisted_2","_cache","value","_hoisted_4","_toDisplayString","_hoisted_5","args","_createVNode","Repeat","SkipBack","Pause","Play","SkipForward","_openBlock","_resolveDynamicComponent","_Transition","_hoisted_11","_hoisted_12","_hoisted_14"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { defineComponent as d, ref as U, watch as h, openBlock as $, createElementBlock as G, createElementVNode as x, createBlock as K, createVNode as C, unref as ee, h as g, inject as ne, computed as q } from "vue";
2
- import { u as le, a as te, z as ie, L as ue, B as fe, c as oe } from "./index-BlPq3HPF.mjs";
2
+ import { u as le, a as te, z as ie, L as ue, B as fe, c as oe } from "./index-D6e4OqEP.mjs";
3
3
  import { _ as se } from "./RendererError.vue_vue_type_script_setup_true_lang-BNoENOWX.mjs";
4
4
  import { ChevronDown as ce, ChevronRight as pe } from "lucide-vue-next";
5
5
  function ke(e, f = !1) {
@@ -616,4 +616,4 @@ const D = d({
616
616
  export {
617
617
  Ne as default
618
618
  };
619
- //# sourceMappingURL=index-C9fAHdS1.mjs.map
619
+ //# sourceMappingURL=index-BNub3BMM.mjs.map