NarraLeaf

自定义 Notification

用自定义渲染组件替换默认 Notification,通过 Game 注册并由 liveGame.notify 触发

作用

通知(Notification)用于在游戏中显示短暂提示,如「已保存」「已解锁」等。通过 game.configurenotification 配置项,可替换默认的 Notification 组件,实现自定义样式和布局

触发通知使用 liveGame.notify 方法。自定义组件接收 notifications 数组(INotificationsProps),自行渲染每条通知

1. 创建自定义 Notification 组件

自定义组件接收 { notifications },类型为 INotificationsProps。每条通知包含 idmessage

import type { INotificationsProps } from "narraleaf-react";

function CustomNotification({ notifications }: INotificationsProps) {
  return (
    <div className="absolute top-4 left-0 right-0 flex flex-col items-center gap-2 pointer-events-none">
      {notifications.map(({ id, message }) => (
        <div
          key={id}
          className="bg-black/70 text-white px-4 py-2 rounded-lg shadow-lg text-sm"
        >
          {message}
        </div>
      ))}
    </div>
  );
}

2. 注册到游戏

import { Game, GameProviders, Player } from "narraleaf-react";

const game = new Game({ notification: CustomNotification });

function App() {
  return (
    <GameProviders game={game}>
      <Player story={story} onReady={({ liveGame }) => liveGame.newGame()} />
    </GameProviders>
  );
}

3. 触发通知

在任意可访问 LiveGame 的地方调用 notify

const liveGame = game.getLiveGame();

// 显示通知,默认 3000ms 后自动消失
liveGame.notify("已保存");

// 自定义时长(毫秒)
liveGame.notify("已解锁新成就", 5000);

// duration: null —— 不自动消失(需手动移除)
const notice = liveGame.notify("重要提示", null);

// 稍后移除常驻通知。
notice.cancel();

notify() 返回 NotificationToken,其中包含 cancel()promise。通知消失后,promise 会结束

4. 带动画的示例

使用 Motion 为通知添加淡入淡出:

import { motion, AnimatePresence } from "motion/react";
import type { INotificationsProps } from "narraleaf-react";

function AnimatedNotification({ notifications }: INotificationsProps) {
  return (
    <div className="absolute top-4 left-0 right-0 flex flex-col items-center gap-2 pointer-events-none">
      <AnimatePresence>
        {notifications.map(({ id, message }) => (
          <motion.div
            key={id}
            initial={{ opacity: 0, y: -10 }}
            animate={{ opacity: 1, y: 0 }}
            exit={{ opacity: 0, y: -10 }}
            transition={{ duration: 0.2 }}
            className="bg-amber-500/90 text-black px-4 py-2 rounded-lg"
          >
            {message}
          </motion.div>
        ))}
      </AnimatePresence>
    </div>
  );
}

5. 通知数据结构

type Notification = {
  id: string;    // 用于 React key 的唯一 id
  message: string;
  // duration 用于内部自动消失逻辑
};

参考

本页目录