refactor(HomeScreen): simplify capsule visibility logic and improve list rendering
Some checks failed
Frontend CI / ota-android (push) Has been cancelled
Frontend CI / build-and-push-web (push) Has been cancelled
Frontend CI / build-android-apk (push) Has been cancelled

- Removed unnecessary state and logic related to capsule visibility based on scroll position, streamlining the component's functionality.
- Adjusted FlatList properties to enhance rendering performance and layout consistency.
- Updated styles for the list header to ensure full-width display, improving the overall UI experience.
This commit is contained in:
lafay
2026-03-24 23:02:24 +08:00
parent 126e204592
commit 9e41871b91

View File

@@ -9,9 +9,7 @@ import {
View,
FlatList,
ScrollView,
LayoutAnimation,
Platform,
UIManager,
StyleSheet,
RefreshControl,
StatusBar,
@@ -48,7 +46,6 @@ const SWIPE_COOLDOWN_MS = 300;
const MOBILE_TAB_BAR_HEIGHT = 64;
const MOBILE_TAB_FLOATING_MARGIN = 12;
const MOBILE_FAB_GAP = 12;
const CAPSULE_HIDE_THRESHOLD = 24;
type ViewMode = 'list' | 'grid';
type PostType = 'follow' | 'hot' | 'latest';
@@ -77,7 +74,6 @@ export const HomeScreen: React.FC = () => {
const [viewMode, setViewMode] = useState<ViewMode>('list');
const [latestCapsules, setLatestCapsules] = useState<LatestCapsule[]>([{ id: '', name: '全部' }]);
const [activeCapsuleId, setActiveCapsuleId] = useState('');
const [showLatestCapsules, setShowLatestCapsules] = useState(true);
// 图片查看器状态
const [showImageViewer, setShowImageViewer] = useState(false);
@@ -94,15 +90,8 @@ export const HomeScreen: React.FC = () => {
const postIdsRef = useRef<Set<string>>(new Set());
const lastSwipeAtRef = useRef(0);
// 网格模式滚动位置检测
const gridScrollYRef = useRef(0);
const listScrollYRef = useRef(0);
const isLoadingMoreRef = useRef(false);
if (Platform.OS === 'android' && UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
// 构建一个以 postId 为 key 的 map用于快速查找
const postsMap = useMemo(() => {
const map = new Map<string, Post>();
@@ -125,21 +114,6 @@ export const HomeScreen: React.FC = () => {
const isLatestTab = activeIndex === 1;
const currentChannelId = isLatestTab && activeCapsuleId ? activeCapsuleId : undefined;
const updateCapsuleVisibilityByScroll = useCallback((nextY: number, previousY: number) => {
if (!isLatestTab) return;
const delta = nextY - previousY;
const isScrollingDown = delta > CAPSULE_HIDE_THRESHOLD;
const isScrollingUp = delta < -CAPSULE_HIDE_THRESHOLD;
if (isScrollingDown && showLatestCapsules) {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setShowLatestCapsules(false);
} else if (isScrollingUp && !showLatestCapsules) {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setShowLatestCapsules(true);
}
}, [isLatestTab, showLatestCapsules]);
// 使用差异更新 Hook 获取帖子列表
const listKey = useMemo(
() => `home_${getPostType()}_${currentChannelId || 'all'}`,
@@ -196,9 +170,7 @@ export const HomeScreen: React.FC = () => {
if (scrollY + visibleHeight >= contentHeight - 200) {
loadMore();
}
updateCapsuleVisibilityByScroll(scrollY, gridScrollYRef.current);
gridScrollYRef.current = scrollY;
}, [loadMore, updateCapsuleVisibilityByScroll]);
}, [loadMore]);
// 刷新方法 - 先获取正确类型的帖子,再刷新
const refresh = useCallback(async () => {
@@ -303,12 +275,6 @@ export const HomeScreen: React.FC = () => {
setActiveIndex(nextIndex);
}, [activeIndex]);
useEffect(() => {
setShowLatestCapsules(true);
listScrollYRef.current = 0;
gridScrollYRef.current = 0;
}, [activeIndex]);
useEffect(() => {
const loadChannels = async () => {
const list = await channelService.list();
@@ -481,7 +447,7 @@ export const HomeScreen: React.FC = () => {
};
const renderLatestCapsules = () => {
if (!isLatestTab || !showLatestCapsules) {
if (!isLatestTab) {
return null;
}
@@ -716,6 +682,7 @@ export const HomeScreen: React.FC = () => {
renderItem={renderPostList}
keyExtractor={keyExtractor}
ListHeaderComponent={renderLatestCapsules()}
ListHeaderComponentStyle={styles.listHeader}
contentContainerStyle={[
styles.listContent,
{
@@ -735,11 +702,6 @@ export const HomeScreen: React.FC = () => {
}
onEndReached={loadMore}
onEndReachedThreshold={0.3}
onScroll={(event) => {
const nextY = event.nativeEvent.contentOffset.y;
updateCapsuleVisibilityByScroll(nextY, listScrollYRef.current);
listScrollYRef.current = nextY;
}}
scrollEventThrottle={16}
ListEmptyComponent={renderEmpty}
ListFooterComponent={isLoadingMore ? <Loading size="sm" /> : null}
@@ -747,7 +709,7 @@ export const HomeScreen: React.FC = () => {
maxToRenderPerBatch={8}
updateCellsBatchingPeriod={60}
windowSize={7}
removeClippedSubviews
removeClippedSubviews={false}
/>
);
};
@@ -918,6 +880,9 @@ const styles = StyleSheet.create({
listContent: {
flexGrow: 1,
},
listHeader: {
width: '100%',
},
contentContainer: {
flex: 1,
},