refactor(navigation): consolidate navigation with href helpers and extract push device hook

- Migrate all navigation calls from magic strings to centralized href helpers
- Extract inline device registration logic into useRegisterPushDevice hook
- Remove unused terms and privacy policy routes from profile stack
- Add hrefTradeDetail helper for trade detail navigation
- Restore routePayloadCache.stashSystemMessage for group request/invite handling
- Change desktop shell tab navigation from replace to push
This commit is contained in:
lafay
2026-06-12 23:42:09 +08:00
parent 1f7e25349f
commit 1e05d2bd54
19 changed files with 312 additions and 473 deletions

View File

@@ -172,7 +172,7 @@ export function AppDesktopShell() {
const handleTabChange = useCallback(
(href: string) => {
router.replace(href);
router.push(href);
},
[router]
);

View File

@@ -6,6 +6,7 @@ import { useRouter } from 'expo-router';
import Text from '../common/Text';
import { useAppColors, spacing, borderRadius } from '../../theme';
import type { PostRefSegmentData } from '../../types';
import * as hrefs from '../../navigation/hrefs';
interface PostRefCardProps {
data: PostRefSegmentData;
@@ -21,7 +22,7 @@ const PostRefCard: React.FC<PostRefCardProps> = ({ data, compact = false, onPres
if (onPress) {
onPress(data.post_id);
} else {
router.push(`/post/${data.post_id}` as any);
router.push(hrefs.hrefPostDetail(data.post_id));
}
}, [data.post_id, onPress, router]);

View File

@@ -70,6 +70,9 @@ export { useMediaCache } from './useMediaCache';
export type { UseMediaCacheReturn } from './useMediaCache';
// ==================== 推送设备注册 Hook ====================
export { useRegisterPushDevice } from './useRegisterPushDevice';
// ==================== 差异更新 Hooks ====================
export { useDifferentialMessages } from './useDifferentialMessages';

View File

@@ -0,0 +1,29 @@
import { useEffect, useRef } from 'react';
import { Platform } from 'react-native';
import { jpushService } from '../services/notification/jpushService';
export function useRegisterPushDevice(isAuthenticated: boolean, userID?: string) {
const deviceRegistered = useRef(false);
useEffect(() => {
if (Platform.OS === 'web' || !isAuthenticated || !userID) return;
if (!deviceRegistered.current) {
deviceRegistered.current = true;
jpushService.initialize().then((ok) => {
if (ok && userID) {
jpushService.setAliasForUser(userID);
}
});
}
return () => {
if (!isAuthenticated) {
deviceRegistered.current = false;
jpushService.cleanup();
}
};
}, [isAuthenticated, userID]);
}

View File

@@ -2,13 +2,16 @@
* Expo Router 路径构建(单一事实来源,避免魔法字符串散落)
*/
import type { SystemMessageResponse } from '../types/dto';
import { routePayloadCache } from '../stores';
export function hrefPostDetail(postId: string, scrollToComments?: boolean): string {
const q = scrollToComments ? '?scrollToComments=1' : '';
return `/post/${encodeURIComponent(postId)}${q}`;
}
export function hrefTradeDetail(tradeId: string): string {
return `/trade/${encodeURIComponent(tradeId)}`;
}
export function hrefUserProfile(userId: string): string {
return `/user/${encodeURIComponent(userId)}`;
}
@@ -124,12 +127,10 @@ export function hrefGroupMembers(groupId: string): string {
}
export function hrefGroupRequestDetail(message: SystemMessageResponse): string {
routePayloadCache.stashSystemMessage(message);
return `/group/request?messageId=${encodeURIComponent(message.id)}`;
}
export function hrefGroupInviteDetail(message: SystemMessageResponse): string {
routePayloadCache.stashSystemMessage(message);
return `/group/invite?messageId=${encodeURIComponent(message.id)}`;
}

View File

@@ -716,7 +716,7 @@ export const HomeScreen: React.FC = () => {
// 跳转到发帖页面(使用 Modal 方式)
const handleCreatePost = () => {
if (!isAuthenticated) {
router.push('/login');
router.push(hrefs.hrefAuthLogin());
return;
}
if (!isVerified) {
@@ -1052,7 +1052,7 @@ export const HomeScreen: React.FC = () => {
floatingButtonBottom !== undefined && { bottom: floatingButtonBottom },
]}
onPress={homeTab === 'market' ? () => {
if (!isAuthenticated) { router.push('/login'); return; }
if (!isAuthenticated) { router.push(hrefs.hrefAuthLogin()); return; }
if (!isVerified) { router.push(hrefs.hrefVerificationGuide()); return; }
setShowCreateTrade(true);
} : handleCreatePost}

View File

@@ -14,6 +14,7 @@ import type {
} from '../../types/trade';
import { useRouter } from 'expo-router';
import { useResponsive, useResponsiveSpacing } from '../../hooks';
import * as hrefs from '../../navigation/hrefs';
type TradeFilterType = 'all' | 'sell' | 'buy';
@@ -137,7 +138,7 @@ export function MarketView({
}, [isLoadingMore, hasMore, cursor, filterType, selectedCategory]);
const handlePressItem = useCallback((id: string) => {
router.push(`/trade/${id}` as any);
router.push(hrefs.hrefTradeDetail(id));
}, [router]);
const handleFavorite = useCallback(async (id: string) => {

View File

@@ -472,7 +472,7 @@ export const SearchScreen: React.FC<SearchScreenProps> = ({ onBack, homeTab = 's
<TradeCard
item={item}
variant="list"
onPress={(id) => router.push(`/trade/${id}` as any)}
onPress={(id) => router.push(hrefs.hrefTradeDetail(id))}
/>
</View>
)}

View File

@@ -38,7 +38,7 @@ import { SystemMessageItem } from '../../components/business';
import { Text, ResponsiveContainer, AppBackButton } from '../../components/common';
import { useCursorPagination } from '../../hooks/useCursorPagination';
import * as hrefs from '../../navigation/hrefs';
import { useMessageManagerSystemUnreadCount } from '../../stores';
import { useMessageManagerSystemUnreadCount, routePayloadCache } from '../../stores';
import { messageManager } from '../../stores/message';
const MESSAGE_TYPES = [
@@ -331,8 +331,10 @@ export const NotificationsScreen: React.FC<{ onBack?: () => void }> = ({ onBack
router.push(hrefs.hrefUserProfile(extra_data.actor_id_str));
}
} else if (system_type === 'group_join_apply') {
routePayloadCache.stashSystemMessage(message);
router.push(hrefs.hrefGroupRequestDetail(message));
} else if (system_type === 'group_invite') {
routePayloadCache.stashSystemMessage(message);
router.push(hrefs.hrefGroupInviteDetail(message));
}
// 其他类型暂不处理跳转