@luna-editor/engine 0.5.4 → 0.5.5
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.
package/dist/Player.js
CHANGED
|
@@ -781,6 +781,19 @@ export const Player = ({ scenario: scenarioProp, settings, plugins = EMPTY_PLUGI
|
|
|
781
781
|
scenario.id,
|
|
782
782
|
scenario.name,
|
|
783
783
|
]);
|
|
784
|
+
// プラグインからAUTO再生を制御するためのコールバック
|
|
785
|
+
const toggleAutoPlay = useCallback(() => {
|
|
786
|
+
_togglePlay();
|
|
787
|
+
}, [_togglePlay]);
|
|
788
|
+
const setAutoPlay = useCallback((enabled) => {
|
|
789
|
+
if (enabled !== state.isPlaying) {
|
|
790
|
+
_togglePlay();
|
|
791
|
+
}
|
|
792
|
+
}, [state.isPlaying, _togglePlay]);
|
|
793
|
+
// プラグインから次のブロックへ進むためのコールバック
|
|
794
|
+
const skipToNext = useCallback(() => {
|
|
795
|
+
handleNext("click");
|
|
796
|
+
}, [handleNext]);
|
|
784
797
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
785
798
|
const _handlePrevious = useCallback(() => {
|
|
786
799
|
if (state.currentBlockIndex > 0) {
|
|
@@ -811,6 +824,7 @@ export const Player = ({ scenario: scenarioProp, settings, plugins = EMPTY_PLUGI
|
|
|
811
824
|
displayText: displayTextElement,
|
|
812
825
|
isTyping,
|
|
813
826
|
displayedCharacters,
|
|
827
|
+
isAutoPlaying: state.isPlaying,
|
|
814
828
|
},
|
|
815
829
|
backlog: {
|
|
816
830
|
entries: backlog.logs,
|
|
@@ -869,6 +883,7 @@ export const Player = ({ scenario: scenarioProp, settings, plugins = EMPTY_PLUGI
|
|
|
869
883
|
mergedSettings.selectedUIFontFamily,
|
|
870
884
|
currentBackground,
|
|
871
885
|
fontsLoaded,
|
|
886
|
+
state.isPlaying,
|
|
872
887
|
]);
|
|
873
888
|
// DataContextの参照を更新(プラグインがapi.data.get()を呼び出せるようにする)
|
|
874
889
|
useEffect(() => {
|
|
@@ -939,7 +954,7 @@ export const Player = ({ scenario: scenarioProp, settings, plugins = EMPTY_PLUGI
|
|
|
939
954
|
aspectRatio: getAspectRatio(),
|
|
940
955
|
width: `min(100vw, calc(100vh * ${getAspectRatioValue()}))`,
|
|
941
956
|
height: `min(100vh, calc(100vw / ${getAspectRatioValue()}))`,
|
|
942
|
-
}, children: _jsx(DataProvider, { data: dataContext, onSettingsUpdate: handleSettingsUpdate, onEmotionEffectUpdate: handleEmotionEffectUpdate, onCancelScenario: cancelScenario, children: _jsx(AudioProvider, { settings: {
|
|
957
|
+
}, children: _jsx(DataProvider, { data: dataContext, onSettingsUpdate: handleSettingsUpdate, onEmotionEffectUpdate: handleEmotionEffectUpdate, onCancelScenario: cancelScenario, onToggleAutoPlay: toggleAutoPlay, onSetAutoPlay: setAutoPlay, onSkipToNext: skipToNext, children: _jsx(AudioProvider, { settings: {
|
|
943
958
|
bgmVolume: mergedSettings.bgmVolume,
|
|
944
959
|
seVolume: mergedSettings.seVolume,
|
|
945
960
|
voiceVolume: mergedSettings.voiceVolume,
|
|
@@ -3,6 +3,9 @@ import type { DataAPI, DataContext, EmotionEffectState, PlayerSettingsData } fro
|
|
|
3
3
|
type SettingsUpdater = (settings: Partial<PlayerSettingsData>) => void;
|
|
4
4
|
type EmotionEffectUpdater = (state: EmotionEffectState | null) => void;
|
|
5
5
|
type ScenarioCanceller = () => void;
|
|
6
|
+
type AutoPlayToggler = () => void;
|
|
7
|
+
type AutoPlaySetter = (enabled: boolean) => void;
|
|
8
|
+
type SkipToNextHandler = () => void;
|
|
6
9
|
/**
|
|
7
10
|
* データプロバイダー
|
|
8
11
|
* プラグインがシナリオ情報にリアクティブにアクセスするためのProvider
|
|
@@ -21,6 +24,9 @@ export declare const DataProvider: React.FC<{
|
|
|
21
24
|
onSettingsUpdate?: SettingsUpdater;
|
|
22
25
|
onEmotionEffectUpdate?: EmotionEffectUpdater;
|
|
23
26
|
onCancelScenario?: ScenarioCanceller;
|
|
27
|
+
onToggleAutoPlay?: AutoPlayToggler;
|
|
28
|
+
onSetAutoPlay?: AutoPlaySetter;
|
|
29
|
+
onSkipToNext?: SkipToNextHandler;
|
|
24
30
|
children: ReactNode;
|
|
25
31
|
}>;
|
|
26
32
|
/**
|
|
@@ -7,6 +7,9 @@ const SubscribersContext = createContext(null);
|
|
|
7
7
|
const SettingsUpdaterContext = createContext(null);
|
|
8
8
|
const EmotionEffectUpdaterContext = createContext(null);
|
|
9
9
|
const ScenarioCancellerContext = createContext(null);
|
|
10
|
+
const AutoPlayTogglerContext = createContext(null);
|
|
11
|
+
const AutoPlaySetterContext = createContext(null);
|
|
12
|
+
const SkipToNextContext = createContext(null);
|
|
10
13
|
/**
|
|
11
14
|
* データプロバイダー
|
|
12
15
|
* プラグインがシナリオ情報にリアクティブにアクセスするためのProvider
|
|
@@ -20,7 +23,7 @@ const ScenarioCancellerContext = createContext(null);
|
|
|
20
23
|
* </DataProvider>
|
|
21
24
|
* ```
|
|
22
25
|
*/
|
|
23
|
-
export const DataProvider = ({ data, onSettingsUpdate, onEmotionEffectUpdate, onCancelScenario, children }) => {
|
|
26
|
+
export const DataProvider = ({ data, onSettingsUpdate, onEmotionEffectUpdate, onCancelScenario, onToggleAutoPlay, onSetAutoPlay, onSkipToNext, children }) => {
|
|
24
27
|
const subscribers = useMemo(() => new Map(), []);
|
|
25
28
|
const previousDataRef = useRef(data);
|
|
26
29
|
// 安定したデータ参照ホルダー(Context valueとして提供)
|
|
@@ -62,7 +65,7 @@ export const DataProvider = ({ data, onSettingsUpdate, onEmotionEffectUpdate, on
|
|
|
62
65
|
}
|
|
63
66
|
previousDataRef.current = data;
|
|
64
67
|
}, [data, subscribers]);
|
|
65
|
-
return (_jsx(SubscribersContext.Provider, { value: subscribers, children: _jsx(SettingsUpdaterContext.Provider, { value: onSettingsUpdate !== null && onSettingsUpdate !== void 0 ? onSettingsUpdate : null, children: _jsx(EmotionEffectUpdaterContext.Provider, { value: onEmotionEffectUpdate !== null && onEmotionEffectUpdate !== void 0 ? onEmotionEffectUpdate : null, children: _jsx(ScenarioCancellerContext.Provider, { value: onCancelScenario !== null && onCancelScenario !== void 0 ? onCancelScenario : null, children: _jsx(DataRefContext.Provider, { value: dataRefHolder, children: _jsx(DataContextInstance.Provider, { value: data, children: children }) }) }) }) }) }));
|
|
68
|
+
return (_jsx(SubscribersContext.Provider, { value: subscribers, children: _jsx(SettingsUpdaterContext.Provider, { value: onSettingsUpdate !== null && onSettingsUpdate !== void 0 ? onSettingsUpdate : null, children: _jsx(EmotionEffectUpdaterContext.Provider, { value: onEmotionEffectUpdate !== null && onEmotionEffectUpdate !== void 0 ? onEmotionEffectUpdate : null, children: _jsx(ScenarioCancellerContext.Provider, { value: onCancelScenario !== null && onCancelScenario !== void 0 ? onCancelScenario : null, children: _jsx(AutoPlayTogglerContext.Provider, { value: onToggleAutoPlay !== null && onToggleAutoPlay !== void 0 ? onToggleAutoPlay : null, children: _jsx(AutoPlaySetterContext.Provider, { value: onSetAutoPlay !== null && onSetAutoPlay !== void 0 ? onSetAutoPlay : null, children: _jsx(SkipToNextContext.Provider, { value: onSkipToNext !== null && onSkipToNext !== void 0 ? onSkipToNext : null, children: _jsx(DataRefContext.Provider, { value: dataRefHolder, children: _jsx(DataContextInstance.Provider, { value: data, children: children }) }) }) }) }) }) }) }) }));
|
|
66
69
|
};
|
|
67
70
|
/**
|
|
68
71
|
* DataAPI実装を提供するフック
|
|
@@ -77,6 +80,9 @@ export function useDataAPI() {
|
|
|
77
80
|
const settingsUpdater = useContext(SettingsUpdaterContext);
|
|
78
81
|
const emotionEffectUpdater = useContext(EmotionEffectUpdaterContext);
|
|
79
82
|
const scenarioCanceller = useContext(ScenarioCancellerContext);
|
|
83
|
+
const autoPlayToggler = useContext(AutoPlayTogglerContext);
|
|
84
|
+
const autoPlaySetter = useContext(AutoPlaySetterContext);
|
|
85
|
+
const skipToNextHandler = useContext(SkipToNextContext);
|
|
80
86
|
// 注意: usePlaybackTextOptional()をここで呼ぶと、PlaybackTextContextの更新で
|
|
81
87
|
// useDataAPIを使う全コンポーネントが再レンダリングされてしまう
|
|
82
88
|
// 代わりに、displayTextが必要なコンポーネントはusePlaybackText()を直接使う
|
|
@@ -183,6 +189,30 @@ export function useDataAPI() {
|
|
|
183
189
|
console.warn("cancelScenario called but no scenario canceller provided");
|
|
184
190
|
}
|
|
185
191
|
}, [scenarioCanceller]);
|
|
192
|
+
const toggleAutoPlay = useCallback(() => {
|
|
193
|
+
if (autoPlayToggler) {
|
|
194
|
+
autoPlayToggler();
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
console.warn("toggleAutoPlay called but no auto play toggler provided");
|
|
198
|
+
}
|
|
199
|
+
}, [autoPlayToggler]);
|
|
200
|
+
const setAutoPlay = useCallback((enabled) => {
|
|
201
|
+
if (autoPlaySetter) {
|
|
202
|
+
autoPlaySetter(enabled);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
console.warn("setAutoPlay called but no auto play setter provided");
|
|
206
|
+
}
|
|
207
|
+
}, [autoPlaySetter]);
|
|
208
|
+
const skipToNext = useCallback(() => {
|
|
209
|
+
if (skipToNextHandler) {
|
|
210
|
+
skipToNextHandler();
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
console.warn("skipToNext called but no skip handler provided");
|
|
214
|
+
}
|
|
215
|
+
}, [skipToNextHandler]);
|
|
186
216
|
return useMemo(() => ({
|
|
187
217
|
get,
|
|
188
218
|
subscribe,
|
|
@@ -195,6 +225,9 @@ export function useDataAPI() {
|
|
|
195
225
|
getBlockOption,
|
|
196
226
|
updateEmotionEffect,
|
|
197
227
|
cancelScenario,
|
|
228
|
+
toggleAutoPlay,
|
|
229
|
+
setAutoPlay,
|
|
230
|
+
skipToNext,
|
|
198
231
|
}), [
|
|
199
232
|
get,
|
|
200
233
|
subscribe,
|
|
@@ -207,5 +240,8 @@ export function useDataAPI() {
|
|
|
207
240
|
getBlockOption,
|
|
208
241
|
updateEmotionEffect,
|
|
209
242
|
cancelScenario,
|
|
243
|
+
toggleAutoPlay,
|
|
244
|
+
setAutoPlay,
|
|
245
|
+
skipToNext,
|
|
210
246
|
]);
|
|
211
247
|
}
|
package/dist/data-api-types.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export interface ScenarioPlaybackData {
|
|
|
21
21
|
isTyping?: boolean;
|
|
22
22
|
/** 表示中のキャラクター */
|
|
23
23
|
displayedCharacters?: DisplayedCharacter[];
|
|
24
|
+
/** AUTO再生中かどうか */
|
|
25
|
+
isAutoPlaying?: boolean;
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
28
|
* バックログデータ
|
|
@@ -254,4 +256,20 @@ export interface DataAPI {
|
|
|
254
256
|
* Player の onScenarioCancelled コールバックが発火される。
|
|
255
257
|
*/
|
|
256
258
|
cancelScenario(): void;
|
|
259
|
+
/**
|
|
260
|
+
* AUTO再生のON/OFFを切り替える
|
|
261
|
+
* isPlaying を反転させる。シナリオ終了時は無視される。
|
|
262
|
+
*/
|
|
263
|
+
toggleAutoPlay(): void;
|
|
264
|
+
/**
|
|
265
|
+
* AUTO再生の状態を設定する
|
|
266
|
+
* @param enabled - trueでAUTO ON、falseでOFF
|
|
267
|
+
*/
|
|
268
|
+
setAutoPlay(enabled: boolean): void;
|
|
269
|
+
/**
|
|
270
|
+
* 次のブロックへ進む(スキップ)
|
|
271
|
+
* テキストアニメーション中はアニメーションを完了させ、
|
|
272
|
+
* 完了済みの場合は次のブロックに遷移する。
|
|
273
|
+
*/
|
|
274
|
+
skipToNext(): void;
|
|
257
275
|
}
|
|
@@ -873,6 +873,15 @@ export class PluginManager {
|
|
|
873
873
|
cancelScenario: () => {
|
|
874
874
|
throw new Error("DataAPI.cancelScenario() can only be called from within DataProvider context");
|
|
875
875
|
},
|
|
876
|
+
toggleAutoPlay: () => {
|
|
877
|
+
throw new Error("DataAPI.toggleAutoPlay() can only be called from within DataProvider context");
|
|
878
|
+
},
|
|
879
|
+
setAutoPlay: () => {
|
|
880
|
+
throw new Error("DataAPI.setAutoPlay() can only be called from within DataProvider context");
|
|
881
|
+
},
|
|
882
|
+
skipToNext: () => {
|
|
883
|
+
throw new Error("DataAPI.skipToNext() can only be called from within DataProvider context");
|
|
884
|
+
},
|
|
876
885
|
},
|
|
877
886
|
};
|
|
878
887
|
}
|