From 09e2090da2ccb0bb4d84019febf8347c6e57e9a5 Mon Sep 17 00:00:00 2001 From: Neko Ayaka Date: Sun, 6 Jul 2025 18:03:23 +0800 Subject: [PATCH] feat(stage-ui): replayable helper for histoire --- cspell.config.yaml | 2 + .../src/components/Animations/Replayable.vue | 190 ++++++++++++++++++ .../components/Animations/use-replayable.ts | 38 ++++ 3 files changed, 230 insertions(+) create mode 100644 packages/stage-ui/src/components/Animations/Replayable.vue create mode 100644 packages/stage-ui/src/components/Animations/use-replayable.ts 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, + } +}