# useRedDot Hook 使用指南

## 概述

`useRedDot` 是一个用于管理应用中红点提示的 React Hook。它提供了完整的红点状态管理功能，**默认显示红点，查看后消失**。

## 特性

- ✅ **默认显示逻辑**：localStorage 不存在记录时显示红点
- ✅ **自动持久化**：使用 localStorage 存储已查看状态
- ✅ **一次性显示**：查看后自动消失
- ✅ **命名空间隔离**：通过前缀避免键名冲突
- ✅ **批量操作**：支持批量标记已读和清除
- ✅ **TypeScript 支持**：完整的类型定义

## 基本用法

### 1. 导入 Hook

```typescript
import { useRedDot, RED_DOT_KEYS } from '@/hooks/useRedDot'
```

### 2. 在组件中使用

```typescript
const MyComponent = () => {
  const { hasRedDot, markAsViewed, showRedDot } = useRedDot({
    prefix: 'my_feature_' // 可选，默认为 'red_dot_'
  });

  return (
    <div>
      <div className="flex items-center gap-2">
        <span>设置</span>
        {hasRedDot('settings') && <Badge variant="dot" />}
      </div>
      <button onClick={() => markAsViewed('settings')}>
        查看设置
      </button>
    </div>
  );
};
```

## API 参考

### 参数

```typescript
interface UseRedDotOptions {
  prefix?: string // localStorage 键名前缀，默认 'red_dot_'
}
```

### 返回值

```typescript
interface UseRedDotReturn {
  // 检查是否显示红点
  hasRedDot: (key: string) => boolean

  // 标记为已查看（消除红点）
  markAsViewed: (key: string) => void

  // 显示红点
  showRedDot: (key: string) => void

  // 批量标记已查看
  markMultipleAsViewed: (keys: string[]) => void

  // 清除所有红点
  clearAllRedDots: () => void

  // 获取所有有红点的功能键
  getAllRedDotKeys: () => string[]
}
```

## 预定义常量

为了避免硬编码字符串，提供了预定义的红点键：

```typescript
export const RED_DOT_KEYS = {
  CHAT_BUBBLE: 'chat_bubble',
  CHAT_BACKGROUND: 'chat_background',
  CHAT_MODEL: 'chat_model',
  PROFILE_SETTING: 'profile_setting',
} as const
```

## 完整示例

### 聊天设置页面

```typescript
import { useRedDot, RED_DOT_KEYS } from '@/hooks/useRedDot';
import { Badge } from '@/components/ui/badge';

const ChatSettingsPage = () => {
  const { hasRedDot, markAsViewed } = useRedDot({
    prefix: `chat_${chatId}_`
  });

  const handleBubbleSettingClick = () => {
    // 点击时标记为已查看
    markAsViewed(RED_DOT_KEYS.CHAT_BUBBLE);
    // 打开设置页面
    openBubbleSettings();
  };

  return (
    <div>
      <div className="setting-item" onClick={handleBubbleSettingClick}>
        <div className="flex items-center gap-2">
          <span>聊天气泡</span>
          {hasRedDot(RED_DOT_KEYS.CHAT_BUBBLE) && <Badge variant="dot" />}
        </div>
      </div>

      <div className="setting-item" onClick={() => {
        markAsViewed(RED_DOT_KEYS.CHAT_BACKGROUND);
        openBackgroundSettings();
      }}>
        <div className="flex items-center gap-2">
          <span>聊天背景</span>
          {hasRedDot(RED_DOT_KEYS.CHAT_BACKGROUND) && <Badge variant="dot" />}
        </div>
      </div>
    </div>
  );
};
```

### 管理页面（显示红点）

```typescript
const AdminPage = () => {
  const { showRedDot } = useRedDot();

  const handleNewFeatureRelease = () => {
    // 发布新功能时显示红点
    showRedDot(RED_DOT_KEYS.CHAT_BUBBLE);
    showRedDot(RED_DOT_KEYS.CHAT_BACKGROUND);
  };

  return (
    <button onClick={handleNewFeatureRelease}>
      发布聊天新功能
    </button>
  );
};
```

## 高级用法

### 1. 不同用户/场景的隔离

```typescript
// 为不同用户使用不同前缀
const userARedDot = useRedDot({ prefix: `user_${userA.id}_` })
const userBRedDot = useRedDot({ prefix: `user_${userB.id}_` })

// 为不同功能模块使用不同前缀
const chatRedDot = useRedDot({ prefix: 'chat_' })
const profileRedDot = useRedDot({ prefix: 'profile_' })
```

### 2. 批量操作

```typescript
const { markMultipleAsViewed, clearAllRedDots } = useRedDot()

// 用户查看了整个设置页面，标记多个功能为已读
const handleSettingsPageVisit = () => {
  markMultipleAsViewed([
    RED_DOT_KEYS.CHAT_BUBBLE,
    RED_DOT_KEYS.CHAT_BACKGROUND,
    RED_DOT_KEYS.CHAT_MODEL,
  ])
}

// 重置所有红点（比如用户重新登录）
const handleUserLogin = () => {
  clearAllRedDots()
}
```

### 3. 状态监控

```typescript
const { getAllRedDotKeys, hasRedDot } = useRedDot()

// 获取当前所有未读功能
const unreadFeatures = getAllRedDotKeys()
console.log('用户有', unreadFeatures.length, '个未读功能')

// 检查是否有任何未读
const hasAnyUnread = unreadFeatures.length > 0
```

## 注意事项

1. **localStorage 限制**：确保浏览器支持 localStorage
2. **前缀命名**：使用有意义的前缀避免冲突
3. **性能考虑**：避免在 render 方法中频繁调用 showRedDot
4. **错误处理**：Hook 内部已处理 localStorage 异常

## 存储格式

红点状态在 localStorage 中的存储格式：

```
键名: ${prefix}${redDotKey}
值: 'viewed' | undefined (删除)
```

**重要逻辑**：

- **不存在记录** = 显示红点（默认状态）
- **存在 'viewed' 记录** = 不显示红点（已查看）

例如：

- 无记录 -> 显示红点
- `chat_123_chat_bubble: 'viewed'` -> 不显示红点
- `profile_settings: 'viewed'` -> 不显示红点
