feat: add QR code login and enhance chat experience

- Add QR code login flow with scanner and confirmation screens
- Implement swipe-to-reply in chat with SwipeableMessageBubble
- Replace FlatList with FlashList for chat performance optimization
- Add Schedule stack navigator with CourseDetail screen support
- Configure deep linking for QR code login (carrotbbs://qrcode/login/:sessionId)
- Update branding from 胡萝卜 to 萝卜社区
- Display dynamic app version in settings
This commit is contained in:
lafay
2026-03-20 19:28:42 +08:00
parent 59877e6ae3
commit a005fb0a15
24 changed files with 2878 additions and 1859 deletions

View File

@@ -1,223 +0,0 @@
# useResponsive 拆分迁移指南
## 概述
原有的 `useResponsive.ts` (485行) 已被拆分为多个专注的 hooks以提高代码的可维护性和性能。
## 新目录结构
```
src/presentation/hooks/responsive/
├── types.ts # 共享类型定义
├── useBreakpoint.ts # 断点检测
├── useScreenSize.ts # 屏幕尺寸
├── useOrientation.ts # 方向检测
├── usePlatform.ts # 平台检测
├── useResponsiveValue.ts # 响应式值映射
├── useResponsiveSpacing.ts # 响应式间距
├── useColumnCount.ts # 列数计算
├── useMediaQuery.ts # 媒体查询
├── useBreakpointCheck.ts # 断点范围检查 (兼容层)
├── useResponsive.ts # 兼容层 (保持向后兼容)
└── index.ts # 统一导出
```
## 新 Hook API 说明
### useBreakpoint - 断点检测
```typescript
import { useBreakpoint, useFineBreakpoint } from '../presentation/hooks/responsive';
// 基础断点: 'mobile' | 'tablet' | 'desktop' | 'wide'
const breakpoint = useBreakpoint();
// 细粒度断点: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'
const fineBreakpoint = useFineBreakpoint();
```
### useScreenSize - 屏幕尺寸
```typescript
import { useScreenSize, useWindowDimensions } from '../presentation/hooks/responsive';
// 完整屏幕尺寸信息
const {
width, height,
breakpoint, fineBreakpoint,
isMobile, isTablet, isDesktop, isWide
} = useScreenSize();
// 仅获取窗口尺寸
const { width, height, scale, fontScale } = useWindowDimensions();
```
### useOrientation - 方向检测
```typescript
import { useOrientation } from '../presentation/hooks/responsive';
const { orientation, isPortrait, isLandscape } = useOrientation();
```
### usePlatform - 平台检测
```typescript
import { usePlatform } from '../presentation/hooks/responsive';
const { OS, isWeb, isIOS, isAndroid, isNative } = usePlatform();
```
### useResponsiveValue - 响应式值
```typescript
import { useResponsiveValue } from '../presentation/hooks/responsive';
// 根据断点返回不同值
const padding = useResponsiveValue({ xs: 8, md: 16, lg: 24 });
// 响应式样式
const style = useResponsiveStyle({
padding: { xs: 8, md: 16, lg: 24 },
fontSize: { xs: 14, lg: 16 }
});
```
### useResponsiveSpacing - 响应式间距
```typescript
import { useResponsiveSpacing } from '../presentation/hooks/responsive';
const gap = useResponsiveSpacing({ xs: 8, md: 16, lg: 24 });
```
### useColumnCount - 列数计算
```typescript
import { useColumnCount } from '../presentation/hooks/responsive';
const columns = useColumnCount({ xs: 1, sm: 2, md: 3, lg: 4 });
```
### useBreakpointGTE / useBreakpointLT - 断点范围检查
```typescript
import { useBreakpointGTE, useBreakpointLT, useBreakpointBetween } from '../presentation/hooks/responsive';
const isMediumUp = useBreakpointGTE('md');
const isMobileOnly = useBreakpointLT('lg');
const isTabletRange = useBreakpointBetween('md', 'lg');
```
### useMediaQuery - 媒体查询
```typescript
import { useMediaQuery } from '../presentation/hooks/responsive';
const isMinWidth768 = useMediaQuery({ minWidth: 768 });
const isPortrait = useMediaQuery({ orientation: 'portrait' });
```
## 迁移示例
### 示例 1: 使用 useResponsive (旧)
```typescript
import { useResponsive, useResponsiveValue, useResponsiveSpacing } from '../hooks';
function Component() {
const { width, isMobile, isTablet, isDesktop, isWide } = useResponsive();
const padding = useResponsiveSpacing({ xs: 8, md: 16 });
return <View style={{ padding }} />;
}
```
### 示例 2: 使用新专注 hooks (推荐)
```typescript
import {
useScreenSize,
useResponsiveSpacing
} from '../presentation/hooks/responsive';
function Component() {
const { width, isMobile, isTablet, isDesktop, isWide } = useScreenSize();
const padding = useResponsiveSpacing({ xs: 8, md: 16 });
return <View style={{ padding }} />;
}
```
### 示例 3: 仅使用部分功能 (性能优化)
```typescript
import { useBreakpoint, usePlatform } from '../presentation/hooks/responsive';
function Component() {
// 只订阅断点变化,不订阅尺寸变化
const breakpoint = useBreakpoint();
const { isIOS } = usePlatform(); // 平台不会变化,只计算一次
return <View />;
}
```
## 性能优势
1. **按需订阅**: 只使用需要的功能,避免不必要的重渲染
2. **细粒度更新**: 每个 hook 独立管理状态
3. **平台常量**: usePlatform 返回常量,不会触发重渲染
## 向后兼容
原有的 `useResponsive` 仍然可用,但标记为 `@deprecated`
```typescript
import { useResponsive } from '../hooks'; // 仍然可用
function Component() {
const { width, height, isMobile, platform } = useResponsive(); // 仍然可用
return <View />;
}
```
## 工具函数
```typescript
import {
getBreakpoint,
getFineBreakpoint,
isBreakpointGTE,
isBreakpointLT
} from '../presentation/hooks/responsive';
// 非 hooks 版本,用于工具函数
const breakpoint = getBreakpoint(800);
const fineBreakpoint = getFineBreakpoint(800);
const isGTE = isBreakpointGTE('md', 'sm');
```
## 类型导出
```typescript
import type {
BreakpointKey,
FineBreakpointKey,
ResponsiveValue,
Orientation,
PlatformInfo,
ScreenSize,
MediaQueryOptions,
ResponsiveInfo, // 兼容层
} from '../presentation/hooks/responsive';
```
## 常量
```typescript
import { BREAKPOINTS, FINE_BREAKPOINTS } from '../presentation/hooks/responsive';
// BREAKPOINTS = { mobile: 0, tablet: 768, desktop: 1024, wide: 1440 }
// FINE_BREAKPOINTS = { xs: 0, sm: 375, md: 414, lg: 768, xl: 1024, '2xl': 1280, '3xl': 1440, '4xl': 1920 }
```