Add auto-start consent system that requires explicit user permission before enabling background sync services. Users can now choose between silent mode (no auto-start) or background mode (15-minute sync intervals).
- Add consent service with AutoStartMode enum and storage utilities
- Create withRemoveAutoStart Expo plugin to disable Android auto-start defaults
- Integrate consent checks into JPush service, background task manager, and foreground service
- Add auto-start consent UI in notification settings with descriptive dialog
- Update privacy policy with section 8 explaining auto-start scenarios and user controls
- Change default sync mode from BATTERY_SAVER to DISABLED
- Export reinitBackgroundService function for re-initializing after consent changes
- Merge OTA Android and iOS workflows into matrix build
- Add release signing config in withSigning plugin for Android
- Expand .dockerignore with native credential and build artifact exclusions
Update cache directory scanning to use platform-specific paths for iOS and Android.
Add a delay after clearing cache to ensure native deletion completes.
Correct the request body structure for sticker deletion API calls.
Refactor the image handling workflow to decouple image selection from the upload process. This improves user experience by allowing users to continue composing posts or trades while images are queued for upload, and increases reliability by using a centralized pending image utility.
- **Deferred Uploads**: Replaced immediate image uploads in `CreatePostScreen`, `PostDetailScreen`, and `CreateTradeScreen` with a "pending" state. Images are now uploaded in bulk during the final submission phase.
- **BlockEditor Enhancements**:
- Updated `useBlockEditor` to support asynchronous batch uploading of all pending images via a new `uploadPendingImages` method.
- Removed inline uploading overlays in favor of a more robust state-driven approach.
- Improved `BlockEditorHandle` to expose block retrieval and batch upload capabilities.
- **API Layer Improvements**:
- Migrated native image uploads from standard `FormData` to `expo-file-system`'s multipart upload to resolve compatibility issues with recent React Native versions.
- Maintained `fetch` + `Blob` logic for web platform compatibility.
- **New Utilities**: Introduced `src/utils/pendingImages.ts` to manage the lifecycle of local (pending) vs. remote (uploaded) images across the application.
Refactor the messaging subsystem to enhance data consistency, prevent race conditions during WebSocket reconnection, and ensure accurate unread counts.
- **WebSocket Reliability**: Implement `client_msg_id` for precise message ACK matching, preventing incorrect pending message resolution in high-frequency scenarios.
- **Sync Logic**: Update `WSMessageHandler` and `MessageManager` to use a bootstrapping state, ensuring buffered SSE events are flushed only after the initial synchronization is complete.
- **State Consistency**:
- Introduce atomic unread count increments to prevent lost updates.
- Implement conditional rollback for optimistic read receipts, ensuring that failed API calls do not overwrite newer, valid read states.
- **Resource Management**: Add reference counting to `useMessages` hook to prevent premature clearing of loading states during rapid conversation switching or React StrictMode double-invocations.
- **Data Integrity**: Update `UserCacheService` to re-read the latest message list before applying sender info enrichment, ensuring new messages arriving during the async process are correctly processed.
Refactor core services and components to prevent runtime errors on web platforms and optimize build environment.
- Update `Dockerfile.web` to use Node 25 for the build stage.
- Implement lazy loading for `expo-media-library` and `expo-file-system` in `ImageGallery` to prevent crashes on web where these native modules are unavailable.
- Refactor `CallKeepServiceImpl` to use dynamic imports for `expo-callkit-telecom`, ensuring the service remains compatible with web environments.
Integrate `expo-callkit-telecom` to support native system call handling (answering, ending, and muting via system UI). This includes a new `callKeepService` and a `CallKeepBootstrap` component to manage the lifecycle of system call events.
Additionally, improves the calling experience by:
- Adding support for group calls with participant tracking and UI indicators.
- Enhancing LiveKit integration by replacing polling with event-driven video track synchronization.
- Updating `WebSocketService` to prevent disconnection when the app enters the background during an active call.
- Adding new WebSocket message types for participant join/leave events and group invites.
- Refining call UI components (`CallScreen`, `FloatingCallWindow`, `IncomingCallModal`) for better visual feedback and safe area handling.
Refactor LiveKit service to use event-driven updates for local and remote tracks, improving performance and reliability.
Implement robust WebRTC polyfills and native audio session management for
LiveKit on mobile platforms. This includes configuring iOS audio sessions
to prevent issues during calls and implementing a delayed video
activation strategy to avoid main thread deadlocks on iOS.
- Add WebRTC and environment polyfills in `src/polyfills.ts`
- Implement iOS-specific `AudioSession` configuration in `LiveKitService`
- Add support for toggling speaker output on iOS
- Update `callStore` to handle video enablement after connection settles
- Fix `useUnreadCountQuery` to correctly handle async fetching
Migrate from @react-navigation/native to expo-router navigation hooks across all screens.
Add polyfills module and apply LiveKit VideoView optional loading for Expo Go compatibility.
Improve background sync to skip when user is not logged in.
Enhance fetchUnreadCount to return typed totalUnread and systemUnread values.
Replace the custom WebRTC implementation with LiveKit for improved
stability and feature support.
- Remove `react-native-webrtc` and custom `WebRTCManager`
- Implement `LiveKitService` for room and track management
- Update `callStore` to handle LiveKit events and connection states
- Refactor `CallScreen` (mobile and web) to use `@livekit/react-native`
and `VideoView`
- Update WebSocket protocol to use `call_ready` instead of manual SDP/ICE
exchanges
- Add necessary camera and microphone permissions to `app.json`
- Update Metro and Babel configurations for LiveKit compatibility
Implement a more efficient conversation synchronization mechanism using
version numbers instead of sequence numbers to reduce bandwidth usage.
This includes adding support for Gzip decompression on WebSocket
messages to optimize data transfer.
- Add `pako` for WebSocket message decompression
- Implement `getSyncByVersion` in `MessageService`
- Implement `syncByVersion` in `MessageSyncService` to handle incremental
updates and conversation state changes
- Update `WebSocketService` to support binary frames and Gzip inflation
- Add `syncVersion` to `MessageStore` for tracking synchronization state
Refactor the message module to streamline state management by removing the `MessageStateManager` and `SubscriptionManager` layers, relying instead on Zustand's built-in selector mechanism for reactive updates.
- Remove redundant `setConversations`, `addMessage`, and `updateMessage` actions from the Zustand store to favor more specialized update methods.
- Clean up `MessageService` by removing deprecated conversation and message sending convenience methods.
- Update service interfaces to support new synchronization capabilities including `syncBySeq` and `restartSources`.
- Simplify documentation and comments across the message store and its associated services.
Refactor the messaging system to improve synchronization efficiency and state consistency.
- Implement incremental message synchronization using sequence numbers (seq) to reduce payload size.
- Add `markAllAsRead` batch API support to optimize read receipt processing.
- Introduce atomic state updates in `useMessageStore` to prevent inconsistent UI rendering during unread count changes.
- Implement notification deduplication in `WSMessageHandler` to prevent duplicate unread increments during reconnection.
- Optimize `MessageSyncService` to prioritize incremental sync over full snapshots when local data exists.
- Refactor `ReadReceiptManager` to use optimistic updates with proper rollback mechanisms.
- Fix minor UI issues in `SettingsScreen` and `PrivacySettingsScreen` related to theme picker z-index and style application.
- Implement `segmentsToBlocks` utility to convert message segments into editable blocks.
- Update `BlockEditor` and `useBlockEditor` to support initial block loading and improved image upload handling.
- Add logic to `CreatePostScreen` to automatically switch to long-post mode when image segments are detected and preserve data when toggling modes.
- Update `AboutScreen` to make the ICP filing number clickable.
- Refactor mapper imports to use the updated data model paths.
- Add keyword highlighting in `PostCard` and `PostContentRenderer` using `HighlightText`.
- Implement smart excerpt logic in `PostCard` to show relevant context around search keywords.
- Update `SearchBar` styles for better visual feedback and consistency.
- Enhance `SearchScreen` with modern tab variants and improved tag styling.
- Add support for updating group descriptions in `GroupInfoScreen` and `GroupService`.
- Refactor various UI components for improved layout stability and typography.
This commit implements a major architectural refactor to improve modularity, type safety, and maintainability across the codebase.
Key changes include:
- **Responsive System Refactor**: Migrated from a monolithic `useResponsive` hook to a set of specialized, granular hooks (`useBreakpoint`, `useOrientation`, `usePlatform`, etc.) located in `src/presentation/hooks/responsive`. This reduces unnecessary re-renders and improves developer experience.
- **Core Service Restructuring**: Introduced a new directory structure for services, including dedicated folders for `datasources`, `mappers`, and domain-specific types (`message`, `post`).
- **Data Layer Improvements**:
- Centralized JSON parsing logic in `src/database/core/jsonUtils.ts`.
- Cleaned up repository implementations by removing redundant local utility functions.
- Refactored `MessageMapper` to use the new centralized JSON utility.
- **Type System Cleanup**:
- Decomposed the large `src/types/dto.ts` into a modular `src/types/dto/` directory.
- Simplified `src/types/index.ts` and introduced backward-compatible aliases for core entities.
- **Utility Consolidation**:
- Created a centralized `src/utils/formatTime.ts` to replace fragmented date formatting logic across various screens and components.
- Removed deprecated responsive utility files in favor of the new hook-based system.
- **Service Logic Refinement**: Refactored `ApiClient` and `WebSocketService` to use a centralized `showVerificationModal` service, removing duplicated state management for verification prompts.
Add support for a new `sync_required` WebSocket message type to trigger
incremental synchronization of conversations, unread counts, and active
messages. Also implement an `ack` mechanism to acknowledge received
messages.
- Add backend error_code support (INVALID_CREDENTIALS, USER_BANNED, etc.)
- Improve network error detection with code=0 fallback
- Add granular HTTP status code handling (400, 401, 403, 429, 5xx)
- Update LoginScreen to display authStore error or generic message
- Include notification service improvements:
- Keep JPush connection alive in background via setKeepLongConnInBackground
- Add manual sound/vibration for local notifications via preferences
- Fix SearchScreen layout by accounting for floating tab bar and safe area
- Add vibration feedback when app is in foreground and notification arrives
- Configure Android notification channel using expo-notifications
- Integrate notification handler to respect user push/sound preferences
- Add platform-specific local notification handling for Android
- Add expo-notifications dependency and configure with JPush plugin
- Request notification permission on app launch for iOS/Android
- Handle notification taps to navigate to chat or notifications screen
- Add UI to check and request system notification permission in settings
- Refactor background sync: WebSocket disconnects in background, JPush handles push
- Add checkNotificationPermission() and requestNotificationPermission() to jpushService
Replace expo-notifications with JPush for push notifications across the app.
This includes adding JPush native module dependencies, configuring the JPush
plugin in app.json, implementing jpushService wrapper, and updating notification
services to use JPush APIs. Also adds device registration on token refresh for
both mobile and web platforms.
BREAKING CHANGE: expo-notifications removed in favor of JPush for push notifications
Refactor SearchBar component to support compact mode with transparent styling,
reduced padding, and smaller icons. Add home screen tab navigation for switching
between home feed and market view with animated tab indicator. Also adjust
PostDetailScreen action button sizing and CommentItem margins for better spacing.
- 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
Add support for referencing/quoting other posts within post content. Includes:
- New `post_ref` segment type with `PostRefSegmentData` interface for post references
- New `PostRefCard` component to display referenced posts inline
- Post suggestion search triggered by `#` in `PostMentionInput`
- Updated `PostContentRenderer` to render post reference segments
- Add `suggestPosts` and `recordRefClick` API methods in postService
Additional improvements:
- Add image gallery preview for user profile covers and avatars
- Make text selectable across CommentItem, PostContentRenderer, and PostDetailScreen
- Migrate FlatList to FlashList in PostDetailScreen and UserProfileScreen
- Add nestedScrollEnabled to CreatePostScreen
- Add clickable member avatars in GroupMembersScreen
Add notification mute functionality for conversations with the following changes:
- Add notification_muted field to ConversationResponse and related DTOs
- Add notificationMutedMap to message store for tracking mute state
- Add setConversationNotificationMuted API method
- Integrate mute toggle in GroupInfoScreen and PrivateChatInfoScreen
- Skip system notifications for muted conversations
- Suppress vibration for muted conversations in WS handler
- Clean up selected mentions when @mentions are removed from text
Chore changes:
- Update PostCard bookmark icon from 'bookmark' to 'star'
- Refine card styles across AppsScreen, MaterialsScreen, and SubjectMaterialsScreen
- Improve week selector scrolling to center selected week in ScheduleScreen
Previously, the notification handler would process all notifications regardless of read status, and only accepted `extra_data` from the payload. Now it:
- Only calls systemNotificationService and increments unread count for unread notifications
- Falls back to `payload.extra` or `payload.data` when `extra_data` is not present
Add `updateItem` function to cursor pagination hook for updating single items
without full list refresh. Use this in NotificationsScreen to mark messages
as read locally instead of refetching. Also add `is_blocked` detection in
postService and userProfile to show blocked state in profile screen.
Redesign multiple screens and components from card-based responsive design to Twitter/X flat design:
- UserProfileHeader: adopt Twitter/X style with larger icons, simplified buttons, and block functionality
- AppBackButton: update to chevron-left icon with larger size, remove background styling
- Update SettingsScreen, EditProfileScreen, and UserProfileScreen with flat layout approach
- ConversationListRow: convert from bordered cards to flat list rows with updated typography
Improve message system with WebSocket notification handling:
- Add real-time system unread count updates via WebSocket
- Track lastSystemMessageAt for accurate system message timestamps
- Add notification deduplication and read-status filtering
- Combine system and conversation unread counts in background sync
- Clear system notifications from notification center on mark as read
- Add PostContentRenderer component for rendering posts/comments with segments
- Add PostMentionInput component for @mention support in post/comment creation
- Add VoteSegmentData and vote segment type for unified post creation API
- Update post and comment services to support segments in API requests
- Fix auth service to clear tokens before login/register
- Improve database initialization with proper close/retry logic
- Add verification check before allowing post creation
- Add metro web shims for react-native-webrtc full package and requireNativeComponent
- Update build config with git hash based version numbers
- Update app name, package name (skin.carrot.bbs → cn.qczlit.withyou), and bundle identifier
- Update API endpoints (bbs.littlelan.cn → withyou.littlelan.cn)
- Update URL scheme (carrotbbs:// → withyou://)
- Rename database from carrot_bbs to with_you
- Update CI/CD pipeline image names and artifact naming
- Add Android signing configuration for release builds
- Update all UI text and comments throughout the codebase
- Refactor registerStore to use in-memory state instead of AsyncStorage persistence
- Improve WebRTC track handling and call stream management
- Add metro platform resolution for native platform support
BREAKING app package, database, and URLs are no longer valid
- Replace ProcessPostUseCase with new PostSyncService in src/services/post/
- Add postListStore for state management in src/stores/post/
- Remove deprecated ProcessPostUseCase and ProcessMessageUseCase files
- Delete architecture documentation files (ARCHITECTURE_REFACTOR_PLAN.md, architecture-comparison-report.md)
- Update all consumers (HomeScreen, PostDetailScreen, SearchScreen, useUserProfile, useDifferentialPosts)
- Simplify postService to only contain API layer methods
- Remove unused type exports from message stores
BREAKING CHANGE: ProcessPostUseCase and ProcessMessageUseCase have been removed.
Use postSyncService for post operations instead.
- Add EventBus for decoupled event-driven communication between services
- Add EventSubscriber component for centralized event handling
- Add requestDedupe utility for shared request deduplication
- Refactor api/wsService to use eventBus instead of direct router navigation
- Extract MessageMapper.toCachedMessages for consistent message mapping
- Remove deprecated BaseManager and CacheBus classes
- Improve @mention rendering with memberMap support in segment rendering
- Update hooks to use useRef instead of useState for fetch tracking
Implement Android foreground service to keep app alive in background for real-time message sync:
- Add withForegroundService expo config plugin for notification channel setup
- Add BackgroundSyncManager with REALTIME, BATTERY_SAVER, and DISABLED modes
- Add ForegroundServiceModule for native Android foreground service binding
- Refactor backgroundService to integrate foreground service and expo-background-task
Also refactor auth and profile screens to use dynamic theme colors:
- Replace hardcoded THEME_COLORS with colors.primary.main, colors.background.paper, etc.
- Add useResolvedColorScheme for dynamic StatusBar styling
- Update NotificationSettingsScreen with sync mode selection UI
BREAKING CHANGE: Switched from expo-background-fetch to expo-background-task, minimum background sync interval changed from 900s to 15min in config
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
Replace custom gesture handling with PagerView component for smoother tab
switching on home screen. Add verification required redirects in API and
WebSocket services that automatically navigate users to the verification
guide when receiving VERIFICATION_REQUIRED error codes.
BREAKING CHANGE: API and WS services now require router to be set via
setExpoRouter/setRouter for navigation to work properly
Add comprehensive user verification feature including:
- VerificationGuideScreen: Guide screen explaining the verification process
- VerificationFormScreen: Form for submitting verification applications
- VerificationSettingsScreen: Settings page to view verification status
- verificationService: API service for verification operations
- verificationStore: State management for verification state
- DTOs: Types for verification records, status, and admin operations
The system supports multiple identity types (student, teacher, staff, alumni, external)
and includes both user-facing and admin-facing functionality.
- Remove legacy database.ts, LocalDataSource.ts, and MessageRepository.ts
- Create new src/database/ module with messageRepository, userCacheRepository, conversationRepository, and groupCacheRepository
- Update all consumers to import from @/database instead of services/database
- Add web platform blur handling for modal components to fix focus issues
- Flatten SystemMessageItem and NotificationsScreen styles for consistent design
- Add draggable slider in ChatSettingsScreen and dynamic font size support
- Introduce 9 new chat color themes
- Add profile screens for about, terms, and privacy policy with navigation routes
- Add policy links to login and registration screens
- Fix post share URL format from /posts/ to /post/
- Add pre-open check for web to release potentially stale OPFS handles
- Unify close logic across platforms instead of skipping for web
- Add proper logging for connection lifecycle operations
- Remove obsolete error check for "cannot create file" during retries
Refactor LocalDataSource to reuse the shared database connection from database.ts, avoiding OPFS file handle conflicts. Add retry logic with exponential backoff for database open operations, particularly important for Web/OPFS environments. Also add dynamic theme support to chat input and message bubble styles, using theme colors instead of hardcoded values for better light/dark mode support.
BREAKING CHANGE: Database initialization now requires userId to be passed explicitly for user-specific databases
- Updated RegisterScreen to support a multi-step registration flow with components for email input, verification, and profile setup.
- Added new components: VerificationCodeInput, StepIndicator, and corresponding types for step management.
- Enhanced background service to check authentication status before executing tasks, improving app reliability.
- Updated TypeScript configuration to include module resolution and JSON module support.
This update significantly improves the user registration experience and ensures background tasks are only executed for authenticated users.
- Introduced hrefProfileChatSettings() for navigation to chat settings.
- Updated SettingsScreen to include new settings items for chat settings, language selection, data storage, terms, and privacy policy.
- Enhanced user experience by providing alerts for language and data storage options.
This update improves the profile settings interface by adding more customization options for users.
- Updated call status messages to include 'calling', 'reconnecting', and 'failed' states for better user feedback.
- Improved video handling logic in CallScreen to use currentCall.isVideoEnabled for local video display.
- Enhanced callStore to manage new call statuses and ensure proper timeout handling during 'calling' state.
- Added a method in wsService to retrieve the active call state after WebSocket reconnections.
- Refactored FloatingCallWindow to reflect updated call status messages for consistency across components.
- Enhanced ontrack event handling to construct remote streams and avoid duplicate tracks during renegotiation.
- Updated negotiation logic to ensure it only occurs when the signaling state is stable and the instance is the initiator.
- Added diagnostic logging for offer and answer SDP to assist in debugging video track handling.
- Improved rollback logic in callStore to handle signaling state checks more robustly after rollback attempts.
- Added optional media_type to WSCallIncomingMessage for better call type differentiation.
- Updated call_type assignment in WebSocketService to prioritize media_type if available.
- Removed initialOfferCreated flag in WebRTCManager to simplify negotiation logic.
- Improved negotiation handling by releasing the negotiation lock after offer creation, ensuring smoother call setup.
- Integrated video call support by adding local and remote video stream handling.
- Implemented state management for video track detection in both local and peer streams.
- Updated UI to conditionally render video components based on the presence of video tracks.
- Added video toggle functionality to enable or disable local video during calls.
- Enhanced incoming call modal to display call type (voice or video).
- Refactored call store to manage call types and video state more effectively.
- Updated app.json to include microphone permissions and background audio support.
- Added call-related dependencies in package.json and package-lock.json.
- Enhanced ChatScreen to initiate calls and handle call actions.
- Introduced call components in the layout for incoming call handling.
- Expanded WebSocket service to manage call signaling messages and events.
- Refactored authStore to initialize call state on user authentication.