diff --git a/cspell.config.yaml b/cspell.config.yaml index af525c997..1bf52c8a2 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -166,6 +166,7 @@ words: - qwen - rehype - reka + - Replayable - resampler - rlib - rmcp @@ -213,6 +214,7 @@ words: - Volcengine - vrma - vueuse + - waapi - wavefile - webgpu - weeb diff --git a/packages/stage-ui/src/components/Animations/Replayable.vue b/packages/stage-ui/src/components/Animations/Replayable.vue new file mode 100644 index 000000000..da6d44982 --- /dev/null +++ b/packages/stage-ui/src/components/Animations/Replayable.vue @@ -0,0 +1,190 @@ + + + diff --git a/packages/stage-ui/src/components/Animations/use-replayable.ts b/packages/stage-ui/src/components/Animations/use-replayable.ts new file mode 100644 index 000000000..5937aa9ea --- /dev/null +++ b/packages/stage-ui/src/components/Animations/use-replayable.ts @@ -0,0 +1,38 @@ +import { inject, onUnmounted } from 'vue' + +interface ReplayableContext { + registerReplayCallback: (callback: () => void | Promise) => () => void + isReplaying: () => boolean +} + +export function useReplayable(replayFn?: () => void | Promise) { + const context = inject('replayable') + + if (!context) { + console.warn('useReplayable must be used within a Replayable component') + + return { + registerReplay: () => () => {}, + isReplaying: () => false, + } + } + + const registerReplay = (callback: () => void | Promise) => { + return context.registerReplayCallback(callback) + } + + // Auto-register if callback provided + let unregister: (() => void) | undefined + if (replayFn) { + unregister = registerReplay(replayFn) + } + + onUnmounted(() => { + unregister?.() + }) + + return { + registerReplay, + isReplaying: context.isReplaying, + } +}