2026-03-24 14:21:31 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Expo Router 路径构建(单一事实来源,避免魔法字符串散落)
|
|
|
|
|
|
*/
|
|
|
|
|
|
import type { SystemMessageResponse } from '../types/dto';
|
2026-04-13 04:56:58 +08:00
|
|
|
|
import { routePayloadCache } from '../stores';
|
2026-03-24 14:21:31 +08:00
|
|
|
|
|
|
|
|
|
|
export function hrefPostDetail(postId: string, scrollToComments?: boolean): string {
|
|
|
|
|
|
const q = scrollToComments ? '?scrollToComments=1' : '';
|
|
|
|
|
|
return `/post/${encodeURIComponent(postId)}${q}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefUserProfile(userId: string): string {
|
|
|
|
|
|
return `/user/${encodeURIComponent(userId)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefHome(): string {
|
|
|
|
|
|
return '/home';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefHomeSearch(): string {
|
|
|
|
|
|
return '/home/search';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefMessages(): string {
|
|
|
|
|
|
return '/messages';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefNotifications(): string {
|
|
|
|
|
|
return '/messages/notifications';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-25 01:29:41 +08:00
|
|
|
|
export function hrefApps(): string {
|
|
|
|
|
|
return '/apps';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
|
export function hrefSchedule(): string {
|
2026-03-25 01:29:41 +08:00
|
|
|
|
return '/apps/schedule';
|
2026-03-24 14:21:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefScheduleCourse(courseId: string): string {
|
2026-03-25 01:29:41 +08:00
|
|
|
|
return `/apps/schedule/course?courseId=${encodeURIComponent(courseId)}`;
|
2026-03-24 14:21:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileSettings(): string {
|
|
|
|
|
|
return '/profile/settings';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileEdit(): string {
|
|
|
|
|
|
return '/profile/edit-profile';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileSecurity(): string {
|
|
|
|
|
|
return '/profile/account-security';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileNotifications(): string {
|
|
|
|
|
|
return '/profile/notification-settings';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileBlocked(): string {
|
|
|
|
|
|
return '/profile/blocked-users';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-01 02:17:36 +08:00
|
|
|
|
export function hrefProfileChatSettings(): string {
|
|
|
|
|
|
return '/profile/chat-settings';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-24 14:21:31 +08:00
|
|
|
|
export function hrefProfileMyPosts(): string {
|
|
|
|
|
|
return '/profile/my-posts';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileBookmarks(): string {
|
|
|
|
|
|
return '/profile/bookmarks';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefCreatePost(mode?: 'create' | 'edit', postId?: string): string {
|
|
|
|
|
|
if (mode === 'edit' && postId) {
|
|
|
|
|
|
return `/posts/create?mode=edit&postId=${encodeURIComponent(postId)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
return '/posts/create';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefChat(params: {
|
|
|
|
|
|
conversationId: string;
|
|
|
|
|
|
userId?: string;
|
|
|
|
|
|
isGroupChat?: boolean;
|
|
|
|
|
|
groupId?: string;
|
|
|
|
|
|
groupName?: string;
|
|
|
|
|
|
}): string {
|
|
|
|
|
|
const { conversationId, userId, isGroupChat, groupId, groupName } = params;
|
|
|
|
|
|
const q = new URLSearchParams();
|
|
|
|
|
|
if (userId) q.set('userId', userId);
|
|
|
|
|
|
if (isGroupChat) q.set('isGroupChat', '1');
|
|
|
|
|
|
if (groupId != null && groupId !== '') q.set('groupId', String(groupId));
|
|
|
|
|
|
if (groupName) q.set('groupName', groupName);
|
|
|
|
|
|
const qs = q.toString();
|
|
|
|
|
|
return `/chat/${encodeURIComponent(conversationId)}${qs ? `?${qs}` : ''}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefFollowList(userId: string, type: 'following' | 'followers'): string {
|
|
|
|
|
|
return `/users/${encodeURIComponent(userId)}/${type}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefGroupCreate(): string {
|
|
|
|
|
|
return '/group/create';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefGroupJoin(): string {
|
|
|
|
|
|
return '/group/join';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefGroupInfo(groupId: string, conversationId?: string): string {
|
|
|
|
|
|
const base = `/group/${encodeURIComponent(groupId)}`;
|
|
|
|
|
|
if (!conversationId) return base;
|
|
|
|
|
|
return `${base}?conversationId=${encodeURIComponent(conversationId)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefGroupMembers(groupId: string): string {
|
|
|
|
|
|
return `/group/${encodeURIComponent(groupId)}/members`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefPrivateChatInfo(params: {
|
|
|
|
|
|
conversationId: string;
|
|
|
|
|
|
userId: string;
|
|
|
|
|
|
userName?: string;
|
|
|
|
|
|
userAvatar?: string | null;
|
|
|
|
|
|
}): string {
|
|
|
|
|
|
const q = new URLSearchParams({
|
|
|
|
|
|
conversationId: params.conversationId,
|
|
|
|
|
|
userId: params.userId,
|
|
|
|
|
|
});
|
|
|
|
|
|
if (params.userName) q.set('userName', params.userName);
|
|
|
|
|
|
if (params.userAvatar != null) q.set('userAvatar', params.userAvatar ?? '');
|
|
|
|
|
|
return `/chat/private-info?${q.toString()}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefQrLoginConfirm(sessionId: string): string {
|
|
|
|
|
|
return `/qrcode/login/${encodeURIComponent(sessionId)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefAuthLogin(): string {
|
|
|
|
|
|
return '/login';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefAuthRegister(): string {
|
|
|
|
|
|
return '/register';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefAuthForgot(): string {
|
|
|
|
|
|
return '/forgot-password';
|
|
|
|
|
|
}
|
2026-03-25 21:17:17 +08:00
|
|
|
|
|
2026-04-01 00:50:38 +08:00
|
|
|
|
export function hrefAuthWelcome(): string {
|
|
|
|
|
|
return '/welcome';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-03-25 21:17:17 +08:00
|
|
|
|
// ==================== Materials (学习资料) ====================
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefMaterials(): string {
|
|
|
|
|
|
return '/apps/materials';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefMaterialSubject(subjectId: string): string {
|
|
|
|
|
|
return `/apps/materials/subject?subjectId=${encodeURIComponent(subjectId)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefMaterialDetail(materialId: string): string {
|
|
|
|
|
|
return `/apps/materials/detail?materialId=${encodeURIComponent(materialId)}`;
|
|
|
|
|
|
}
|
2026-04-04 08:01:45 +08:00
|
|
|
|
|
|
|
|
|
|
// ==================== Profile Settings (设置相关) ====================
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileAbout(): string {
|
|
|
|
|
|
return '/profile/about';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileTerms(): string {
|
2026-04-07 15:58:51 +08:00
|
|
|
|
return '/terms';
|
2026-04-04 08:01:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfilePrivacy(): string {
|
2026-04-07 15:58:51 +08:00
|
|
|
|
return '/privacy';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileVerification(): string {
|
|
|
|
|
|
return '/profile/verification';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefVerificationGuide(): string {
|
|
|
|
|
|
return '/verification-guide';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefVerificationForm(identity?: string): string {
|
|
|
|
|
|
if (identity) {
|
|
|
|
|
|
return `/verification-form?identity=${encodeURIComponent(identity)}`;
|
|
|
|
|
|
}
|
|
|
|
|
|
return '/verification-form';
|
2026-04-04 08:01:45 +08:00
|
|
|
|
}
|
2026-04-07 16:27:02 +08:00
|
|
|
|
|
|
|
|
|
|
export function hrefProfileDataStorage(): string {
|
|
|
|
|
|
return '/profile/data-storage';
|
|
|
|
|
|
}
|
<think>Let me analyze the staged changes to generate a proper conventional commit message.
Looking at the changes:
1. **New files**:
- `app/(app)/(tabs)/profile/account-deletion.tsx` - account deletion screen
- `app/(app)/(tabs)/profile/privacy-settings.tsx` - privacy settings screen
- `src/screens/profile/AccountDeletionScreen.tsx` - account deletion implementation
- `src/screens/profile/PrivacySettingsScreen.tsx` - privacy settings implementation
2. **Modified files**:
- Database changes: `LocalDataSource.ts`, `DatabaseManager.ts`, `DatabaseConfig.ts`, `MigrationManager.ts` - refactoring database layer (removing LockManager, simplified initialization, added retry logic)
- Auth store: `authStore.ts` - changed `initDatabase` to `switchDatabase`
- Auth service: `authService.ts` - added privacy settings and account deletion methods
- DTOs: `dto.ts` - added PrivacySettingsDTO, DeletionStatusDTO, VoteOptionDTO, VoteResultDTO types
- Navigation: `hrefs.ts` - added new href functions for privacy settings and account deletion
- Profile screens: `SettingsScreen.tsx`, `index.ts`, `_layout.tsx` - added new menu items and routes
- Various message screens - added keyboard handling props
- `app/_layout.tsx` - added CSS for mobile touch handling
- `CreatePostScreen.tsx` - fixed vote_options format
- `PostDetailScreen.tsx` - added type annotations for vote handling
- `MediaCacheManager.ts` - updated to use new expo-file-system API
- `VerificationSettingsScreen.tsx` - fixed type safety
- `AccountSecurityScreen.tsx` - styling refactoring
This is a multi-faceted change involving:
Database refactoring, new privacy/account deletion features, bug fixes, and UI improvements. The database changes appear to be refactoring without new functionality. The most significant changes are the privacy settings and account deletion features, plus bug fixes like the vote options format and mobile touch handling.
</think>
feat(profile): add privacy settings and account deletion screens
Add privacy settings and account deletion functionality with new screens and APIs. Refactor database initialization to use switchDatabase for user switching. Fix vote options format in post creation and add type safety to vote handling. Improve mobile touch handling in layout and message screens. Update media cache to use new expo-file-system API.
BREAKING CHANGE: Database initialization now uses switchDatabase instead of initDatabase for user switching
2026-04-08 16:48:19 +08:00
|
|
|
|
|
|
|
|
|
|
export function hrefProfilePrivacySettings(): string {
|
|
|
|
|
|
return '/profile/privacy-settings';
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function hrefProfileDeletion(): string {
|
|
|
|
|
|
return '/profile/account-deletion';
|
|
|
|
|
|
}
|
2026-04-26 17:13:43 +08:00
|
|
|
|
|
|
|
|
|
|
export function hrefEditTrade(tradeId: string): string {
|
|
|
|
|
|
return `/trade/edit/${encodeURIComponent(tradeId)}`;
|
|
|
|
|
|
}
|