feat(service): add foreground service for background message sync

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
This commit is contained in:
lafay
2026-04-11 04:27:22 +08:00
parent 9bbed8cf5e
commit 6f84e17772
22 changed files with 1271 additions and 394 deletions

View File

@@ -21,13 +21,6 @@ import * as hrefs from '../../navigation/hrefs';
const CONTENT_MAX_WIDTH = 720;
// 胡萝卜橙主题色
const THEME_COLORS = {
primary: '#FF6B35',
primaryLight: '#FF8C5A',
primaryDark: '#E55A2B',
};
function createAccountDeletionStyles(colors: AppColors) {
return StyleSheet.create({
container: {
@@ -114,7 +107,7 @@ function createAccountDeletionStyles(colors: AppColors) {
},
// 输入框 - 扁平化风格
input: {
backgroundColor: '#F5F5F7',
backgroundColor: colors.background.default,
borderRadius: 14,
padding: spacing.md,
fontSize: 16,
@@ -133,12 +126,12 @@ function createAccountDeletionStyles(colors: AppColors) {
flex: 1,
height: 56,
borderRadius: 14,
backgroundColor: THEME_COLORS.primary,
backgroundColor: colors.primary.main,
alignItems: 'center',
justifyContent: 'center',
},
primaryButtonText: {
color: '#fff',
color: colors.text.inverse,
fontSize: fontSizes.md,
fontWeight: '600',
},
@@ -166,7 +159,7 @@ function createAccountDeletionStyles(colors: AppColors) {
justifyContent: 'center',
},
dangerButtonText: {
color: '#fff',
color: colors.text.inverse,
fontSize: fontSizes.md,
fontWeight: '600',
},
@@ -392,9 +385,9 @@ export const AccountDeletionScreen: React.FC = () => {
onPress={handleRequestDeletion}
disabled={submitting || !password.trim()}
>
{submitting ? (
<ActivityIndicator size="small" color="#fff" />
) : (
{submitting ? (
<ActivityIndicator size="small" color={colors.text.inverse} />
) : (
<Text style={styles.dangerButtonText}></Text>
)}
</TouchableOpacity>