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:
@@ -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 }
|
||||
```
|
||||
Reference in New Issue
Block a user