Skip to content
Merged

0.8.7 #107

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a976f65
Merge pull request #73 from NarraLeaf/develop
helloyork Apr 30, 2025
4c5192c
Merge pull request #76 from NarraLeaf/develop
helloyork May 9, 2025
d158dce
Merge pull request #78 from NarraLeaf/develop
helloyork May 14, 2025
c56f9b8
Merge pull request #81 from NarraLeaf/develop
helloyork May 21, 2025
63e36fa
Merge pull request #84 from NarraLeaf/develop
helloyork Jun 9, 2025
42f8a95
Merge pull request #86 from NarraLeaf/develop
helloyork Jul 6, 2025
4a82682
Update README.zh-CN.md
helloyork Jul 6, 2025
b76c8ab
Update README.md
helloyork Jul 6, 2025
2498e25
Merge pull request #91 from NarraLeaf/dev_nomen
helloyork Sep 6, 2025
b72a770
Revert "narraleaf-react-0.8.0"
helloyork Sep 6, 2025
01d5dd4
Merge pull request #92 from NarraLeaf/revert-91-dev_nomen
helloyork Sep 6, 2025
f20b4c9
Merge pull request #94 from NarraLeaf/develop
helloyork Sep 6, 2025
a7f5bde
Merge pull request #96 from NarraLeaf/develop
helloyork Sep 6, 2025
65e3515
Merge pull request #101 from NarraLeaf/develop
helloyork Sep 9, 2025
8cd27e6
Merge pull request #104 from NarraLeaf/develop
helloyork Sep 10, 2025
c673c15
fix: Incorrect signature of `Menu.enableWhen` and `Menu.showWhen`
helloyork Sep 10, 2025
1ba1807
fix: Incorrect behavior of `Menu.enableWhen` and `Menu.showWhen`
helloyork Sep 10, 2025
9f6259f
update: DevTools
helloyork Jan 2, 2026
9a1db98
Merge branch 'master' of https://github.com/NarraLeaf/NarraLeaf-React…
helloyork Jan 4, 2026
864468f
update: Refactored Sound System: fixed offset handling and playback m…
helloyork Jan 4, 2026
a8f82ad
publish: 0.8.7
helloyork Jan 4, 2026
1222bd5
update: dependency @narraleaf/sound
helloyork Jan 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Changelog

## [0.8.7]

### Fixed

- Refactored Sound System: fixed offset handling and playback management.

## [0.8.6]

### Fixed

- Incorrect behavior of `Menu.enableWhen` and `Menu.showWhen`

## [0.8.5]

### Fixed

- Incorrect signature of `Menu.enableWhen` and `Menu.showWhen`

## [0.8.4]

### _Feature_
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,7 @@ npm install narraleaf-react
- [Player](https://react.narraleaf.com/documentation/player/player)
- [GameProviders](https://react.narraleaf.com/documentation/player/game-providers)
- Hooks
- [useGame](https://react.narraleaf.com/documentation/player/hooks/useGame)
- [usePreferences](https://react.narraleaf.com/documentation/player/hooks/usePreferences)
- [useRouter](https://react.narraleaf.com/documentation/player/hooks/useRouter)
- [useDialog](https://react.narraleaf.com/documentation/player/hooks/useDialog)
- [Page Router](https://react.narraleaf.com/documentation/player/page-router)
- [LayoutRouter](https://react.narraleaf.com/documentation/player/page-router)
- [Dialog](https://react.narraleaf.com/documentation/player/dialog)
- [Notification](https://react.narraleaf.com/documentation/player/notification)
- [Menu](https://react.narraleaf.com/documentation/player/menu)
Expand Down
6 changes: 1 addition & 5 deletions docs/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,7 @@ npm install narraleaf-react
- [Player](https://react.narraleaf.com/documentation/player/player)
- [GameProviders](https://react.narraleaf.com/documentation/player/game-providers)
- 钩子
- [useGame](https://react.narraleaf.com/documentation/player/hooks/useGame)
- [usePreferences](https://react.narraleaf.com/documentation/player/hooks/usePreferences)
- [useRouter](https://react.narraleaf.com/documentation/player/hooks/useRouter)
- [useDialog](https://react.narraleaf.com/documentation/player/hooks/useDialog)
- [页面路由](https://react.narraleaf.com/documentation/player/page-router)
- [布局路由](https://react.narraleaf.com/documentation/player/page-router)
- [对话框](https://react.narraleaf.com/documentation/player/dialog)
- [通知](https://react.narraleaf.com/documentation/player/notification)
- [选项框](https://react.narraleaf.com/documentation/player/menu)
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "narraleaf-react",
"version": "0.8.4",
"version": "0.8.7",
"description": "A React visual novel player framework",
"main": "./dist/main.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -96,6 +96,7 @@
"author": "helloyork@icloud.com",
"license": "MPL-2.0",
"dependencies": {
"@narraleaf/sound": "0.1.0",
"client-only": "^0.0.1",
"clsx": "^2.1.1",
"howler": "^2.2.4",
Expand Down
2 changes: 1 addition & 1 deletion src/game/nlcore/action/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export type SoundActionContentType = {
[K in typeof SoundActionTypes[keyof typeof SoundActionTypes]]:
K extends "sound:play" ? [FadeOptions] :
K extends "sound:stop" ? [FadeOptions] :
K extends "sound:setVolume" ? [volumn: number, duration: number] :
K extends "sound:setVolume" ? [volume: number, duration: number] :
K extends "sound:setRate" ? [number] :
K extends "sound:pause" ? [FadeOptions] :
K extends "sound:resume" ? [FadeOptions] :
Expand Down
19 changes: 14 additions & 5 deletions src/game/nlcore/action/actions/sceneAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
.flush();
scene.local.init(state.getStorable());

state.getExposedStateAsync<ExposedStateType.scene>(scene, (exposed) => {
SceneAction.initBackgroundMusic(scene, exposed);
state.getExposedStateAsync<ExposedStateType.scene>(scene, async (exposed) => {
await SceneAction.initBackgroundMusic(scene, exposed);
awaitable.resolve(next);

state.logger.debug("Scene Action", "Scene init");
Expand All @@ -49,10 +49,19 @@ export class SceneAction<T extends typeof SceneActionTypes[keyof typeof SceneAct
return awaitable;
}

static initBackgroundMusic(scene: Scene, exposed: ExposedState[ExposedStateType.scene]) {
if (scene.state.backgroundMusic) {
exposed.setBackgroundMusic(scene.state.backgroundMusic, scene.config.backgroundMusicFade);
/**
* Initialize background music for the target scene.
* Waits until the previous BGM has completely faded out (if any) before
* resolving, ensuring seamless audio transition when jumping between scenes.
*/
static async initBackgroundMusic(scene: Scene, exposed: ExposedState[ExposedStateType.scene]): Promise<void> {
if (!scene.state.backgroundMusic) {
return;
}
// `setBackgroundMusic` already handles fade-out of the previous track and
// fade-in of the new track. We simply await it so that the caller can
// chain subsequent actions after the transition finishes.
await exposed.setBackgroundMusic(scene.state.backgroundMusic, scene.config.backgroundMusicFade);
}

static createSceneSnapshot(scene: Scene, state: GameState): SceneSnapshot {
Expand Down
2 changes: 2 additions & 0 deletions src/game/nlcore/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GameConfig, SavedGame, NotificationToken, SavedGameMetaData } from "../
import type { LayoutRouter } from "@lib/game/player/lib/PageRouter/router";
import { KeyBindingType, WebKeyboardKey } from "../game/types";
import { KeyBindingValue } from "../game/keyMap";
import { SoundType } from "@core/elements/sound";

export * from "@core/elements/type";
export type {
Expand All @@ -25,4 +26,5 @@ export type {

export {
KeyBindingType,
SoundType,
};
25 changes: 25 additions & 0 deletions src/game/nlcore/elements/built-in/DevTools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ControlAction } from "../../action/actions/controlAction";
import { Chained, Proxied } from "../../action/chain";
import { LogicAction } from "../../game";
import { Control } from "../control";


export class DevTools {
public static getActionId(action: LogicAction.Actions): string {
return action.getId();
}

public static setActionId(action: LogicAction.Actions, id: string): LogicAction.Actions {
action.setId(id);
return action;
}

public static chainToActions(chain: Proxied<LogicAction.GameElement, Chained<LogicAction.Actions>>): LogicAction.Actions[] {
return chain.getActions();
}

public static wrapAction(action: LogicAction.Actions[] | Proxied<LogicAction.GameElement, Chained<LogicAction.Actions>>): ControlAction {
const actions = Chained.isChained(action) ? action.getActions() : action;
return Control.do(actions);
}
}
3 changes: 2 additions & 1 deletion src/game/nlcore/elements/built-in/built-in.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Gallery } from "./Gallery";
export { Gallery } from "./Gallery";
export { DevTools } from "./DevTools";
7 changes: 7 additions & 0 deletions src/game/nlcore/elements/condition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export class Lambda<T = any> {
return Lambda.isLambda(obj) ? obj : new Lambda(obj);
}

/**@internal */
public static not(lambda: Lambda<boolean>): Lambda<boolean> {
return new Lambda((ctx) => {
return !lambda.evaluate(ctx).value;
});
}

/**@internal */
handler: LambdaHandler<T>;

Expand Down
8 changes: 4 additions & 4 deletions src/game/nlcore/elements/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,12 @@ export class Menu extends Actionable<any, Menu> {
* ]);
* ```
*/
public enableWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
public enableWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence | SentencePrompt, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
return this.choose({
prompt,
action,
config: {
disabled: Lambda.from(condition)
disabled: Lambda.not(Lambda.from(condition))
}
});
}
Expand All @@ -182,12 +182,12 @@ export class Menu extends Actionable<any, Menu> {
* ]);
* ```
*/
public showWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
public showWhen(condition: Lambda<boolean> | LambdaHandler<boolean>, prompt: Sentence | SentencePrompt, action: ActionStatements): Proxied<Menu, Chained<LogicAction.Actions>> {
return this.choose({
prompt,
action,
config: {
hidden: Lambda.from(condition)
hidden: Lambda.not(Lambda.from(condition))
}
});
}
Expand Down
4 changes: 4 additions & 0 deletions src/game/player/elements/Player.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ export default function Player(
state.stage.update();
}

useEffect(() => {
state.audioManager.initialize();
}, []);

useEffect(() => {
game.getLiveGame().setGameState(state);
if (story && !game.getLiveGame().isPlaying()) {
Expand Down
8 changes: 1 addition & 7 deletions src/game/player/elements/scene/Scene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ export default function Scene(
return scene.events.depends([
scene.events.on(GameScene.EventTypes["event:scene.preUnmount"], () => {
if (scene.state.backgroundMusic) {
return state.audioManager.stop(scene.state.backgroundMusic).then(() => {
scene.state.backgroundMusic = null;
});
return state.audioManager.stop(scene.state.backgroundMusic, scene.config.backgroundMusicFade);
}
}),
]).cancel;
Expand All @@ -50,10 +48,6 @@ export default function Scene(
useExposeState<ExposedStateType.scene>(scene, {
setBackgroundMusic(music: Sound | null, fade: number) {
return new Promise<void>((resolve) => {
if (!scene.state.backgroundMusic) {
return;
}

(async function () {
if (scene.state.backgroundMusic && state.audioManager.isManaged(scene.state.backgroundMusic)) {
await state.audioManager.stop(scene.state.backgroundMusic, fade);
Expand Down
Loading
Loading