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:
@@ -172,7 +172,7 @@ export function AppDesktopShell() {
|
||||
|
||||
const handleTabChange = useCallback(
|
||||
(href: string) => {
|
||||
router.replace(href);
|
||||
router.push(href);
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
|
||||
@@ -70,6 +70,9 @@ export { useMediaCache } from './useMediaCache';
|
||||
|
||||
export type { UseMediaCacheReturn } from './useMediaCache';
|
||||
|
||||
// ==================== 推送设备注册 Hook ====================
|
||||
export { useRegisterPushDevice } from './useRegisterPushDevice';
|
||||
|
||||
// ==================== 差异更新 Hooks ====================
|
||||
export { useDifferentialMessages } from './useDifferentialMessages';
|
||||
|
||||
|
||||
29
src/hooks/useRegisterPushDevice.ts
Normal file
29
src/hooks/useRegisterPushDevice.ts
Normal 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]);
|
||||
}
|
||||
@@ -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)}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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>
|
||||
)}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
// 其他类型暂不处理跳转
|
||||
|
||||
Reference in New Issue
Block a user