refactor(home): redesign home screen with sort bar and add recommendation feed
- Replace PagerView-based tabs with modern sort bar navigation - Add "推荐" (recommended) feed option with "hot" sort type - Update tab icons and labels to match new sort paradigm - Optimize PostCard, MessageBubble conditional styles perf(chat): migrate FlatList to FlashList for emoji/sticker panels - Improve virtualized rendering performance for emoji and sticker grids - Fix jump-to-latest scroll behavior for inverted FlashList perf(profile): extract user header and tab bar into separate memoized renders - Prevent unnecessary re-renders when switching tabs feat(api): add channel_id filter support for post queries - Include channel_id in cursor pagination requests - Update CursorPaginationRequest type definition style(chat-info): redesign group and private chat info screens with flat layout - Remove card borders and shadows for cleaner appearance - Adjust avatar sizes and spacing for consistency
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
import React, { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { View, TouchableOpacity, ActivityIndicator, Modal, Alert, Dimensions, StyleSheet, FlatList, ListRenderItem, Platform } from 'react-native';
|
||||
import { View, TouchableOpacity, ActivityIndicator, Modal, Alert, Dimensions, StyleSheet, Platform } from 'react-native';
|
||||
import { FlashList, ListRenderItem } from '@shopify/flash-list';
|
||||
import { Image as ExpoImage } from 'expo-image';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
import * as ImagePicker from 'expo-image-picker';
|
||||
@@ -72,8 +73,7 @@ export const EmojiPanel: React.FC<EmojiPanelProps> = ({
|
||||
return StyleSheet.create({
|
||||
...baseStyles,
|
||||
emojiContainer: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
flex: 1,
|
||||
padding: spacing.sm,
|
||||
},
|
||||
emojiItem: {
|
||||
@@ -160,26 +160,19 @@ export const EmojiPanel: React.FC<EmojiPanelProps> = ({
|
||||
</View>
|
||||
), [styles.emojiItem, styles.emojiText, handleEmojiPress]);
|
||||
|
||||
// 渲染 Emoji 面板(使用 FlatList 虚拟化,只渲染可见行)
|
||||
// 渲染 Emoji 面板(使用 FlashList 虚拟化,只渲染可见行)
|
||||
const renderEmojiPanel = () => (
|
||||
<FlatList
|
||||
key="emoji-flatlist"
|
||||
data={emojiRows}
|
||||
keyExtractor={(item) => item.id}
|
||||
renderItem={renderEmojiRow}
|
||||
contentContainerStyle={styles.emojiContainer}
|
||||
showsVerticalScrollIndicator={true}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
initialNumToRender={12}
|
||||
maxToRenderPerBatch={12}
|
||||
windowSize={5}
|
||||
removeClippedSubviews={true}
|
||||
getItemLayout={(_data, index) => ({
|
||||
length: 60,
|
||||
offset: 60 * index,
|
||||
index,
|
||||
})}
|
||||
/>
|
||||
<View style={styles.emojiContainer}>
|
||||
<FlashList
|
||||
key="emoji-flatlist"
|
||||
data={emojiRows}
|
||||
keyExtractor={(item) => item.id}
|
||||
renderItem={renderEmojiRow}
|
||||
showsVerticalScrollIndicator={true}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
// 添加表情(从相册选择)
|
||||
@@ -347,20 +340,18 @@ export const EmojiPanel: React.FC<EmojiPanelProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<FlatList
|
||||
key="sticker-flatlist"
|
||||
data={stickerListData}
|
||||
numColumns={4}
|
||||
keyExtractor={(item) => item.type === 'manage' ? 'manage-button' : item.sticker.id}
|
||||
renderItem={renderStickerListItem}
|
||||
contentContainerStyle={styles.stickerGrid}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
initialNumToRender={16}
|
||||
maxToRenderPerBatch={16}
|
||||
windowSize={7}
|
||||
removeClippedSubviews={true}
|
||||
/>
|
||||
<View style={styles.stickerGrid}>
|
||||
<FlashList
|
||||
key="sticker-flatlist"
|
||||
data={stickerListData}
|
||||
numColumns={4}
|
||||
keyExtractor={(item) => item.type === 'manage' ? 'manage-button' : item.sticker.id}
|
||||
renderItem={renderStickerListItem}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -494,19 +485,17 @@ export const EmojiPanel: React.FC<EmojiPanelProps> = ({
|
||||
<ActivityIndicator size="large" color={colors.primary.main} />
|
||||
</View>
|
||||
) : (
|
||||
<FlatList
|
||||
data={manageListData}
|
||||
numColumns={4}
|
||||
keyExtractor={(item) => item.type === 'add' ? 'manage-add-button' : item.sticker.id}
|
||||
renderItem={renderManageListItem}
|
||||
contentContainerStyle={styles.manageStickerGrid}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
initialNumToRender={16}
|
||||
maxToRenderPerBatch={16}
|
||||
windowSize={7}
|
||||
removeClippedSubviews={true}
|
||||
/>
|
||||
<View style={styles.manageStickerGrid}>
|
||||
<FlashList
|
||||
data={manageListData}
|
||||
numColumns={4}
|
||||
keyExtractor={(item) => item.type === 'add' ? 'manage-add-button' : item.sticker.id}
|
||||
renderItem={renderManageListItem}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
style={{ flex: 1 }}
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* 底部操作栏(管理模式下显示) */}
|
||||
|
||||
Reference in New Issue
Block a user