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:
@@ -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>
|
||||
|
||||
@@ -16,13 +16,6 @@ import { useResponsive, useResponsiveSpacing } from '../../hooks';
|
||||
// 内容最大宽度
|
||||
const CONTENT_MAX_WIDTH = 720;
|
||||
|
||||
// 胡萝卜橙主题色
|
||||
const THEME_COLORS = {
|
||||
primary: '#FF6B35',
|
||||
primaryLight: '#FF8C5A',
|
||||
primaryDark: '#E55A2B',
|
||||
};
|
||||
|
||||
import { authService, resolveAuthApiError } from '../../services/authService';
|
||||
import { showPrompt } from '../../services/promptService';
|
||||
import { useAuthStore } from '../../stores';
|
||||
@@ -263,9 +256,9 @@ export const AccountSecurityScreen: React.FC = () => {
|
||||
onPress={handleSendCode}
|
||||
disabled={sendingCode || countdown > 0}
|
||||
>
|
||||
{sendingCode ? (
|
||||
<ActivityIndicator size="small" color="#fff" />
|
||||
) : (
|
||||
{sendingCode ? (
|
||||
<ActivityIndicator size="small" color={colors.text.inverse} />
|
||||
) : (
|
||||
<Text style={styles.sendCodeButtonText}>{countdown > 0 ? `${countdown}s` : '发送验证码'}</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
@@ -278,7 +271,7 @@ export const AccountSecurityScreen: React.FC = () => {
|
||||
disabled={verifyingEmail}
|
||||
>
|
||||
{verifyingEmail ? (
|
||||
<ActivityIndicator size="small" color="#fff" />
|
||||
<ActivityIndicator size="small" color={colors.text.inverse} />
|
||||
) : (
|
||||
<Text style={styles.primaryButtonText}>验证邮箱</Text>
|
||||
)}
|
||||
@@ -352,7 +345,7 @@ export const AccountSecurityScreen: React.FC = () => {
|
||||
disabled={sendingChangePwdCode || changePwdCountdown > 0}
|
||||
>
|
||||
{sendingChangePwdCode ? (
|
||||
<ActivityIndicator size="small" color="#fff" />
|
||||
<ActivityIndicator size="small" color={colors.text.inverse} />
|
||||
) : (
|
||||
<Text style={styles.sendCodeButtonText}>
|
||||
{changePwdCountdown > 0 ? `${changePwdCountdown}s` : '发送验证码'}
|
||||
@@ -368,7 +361,7 @@ export const AccountSecurityScreen: React.FC = () => {
|
||||
disabled={updatingPassword}
|
||||
>
|
||||
{updatingPassword ? (
|
||||
<ActivityIndicator size="small" color="#fff" />
|
||||
<ActivityIndicator size="small" color={colors.text.inverse} />
|
||||
) : (
|
||||
<Text style={styles.primaryButtonText}>更新密码</Text>
|
||||
)}
|
||||
@@ -432,26 +425,26 @@ function createAccountSecurityStyles(colors: AppColors) {
|
||||
borderRadius: borderRadius.sm,
|
||||
},
|
||||
statusVerified: {
|
||||
backgroundColor: '#E8F5E9',
|
||||
backgroundColor: colors.success.light + '30',
|
||||
},
|
||||
statusUnverified: {
|
||||
backgroundColor: '#FFF3E0',
|
||||
backgroundColor: colors.warning.light + '30',
|
||||
},
|
||||
statusText: {
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
},
|
||||
statusVerifiedText: {
|
||||
color: '#2E7D32',
|
||||
color: colors.success.dark,
|
||||
},
|
||||
statusUnverifiedText: {
|
||||
color: '#E65100',
|
||||
color: colors.warning.dark,
|
||||
},
|
||||
// 输入框样式 - 扁平化风格,与登录页一致
|
||||
inputWrapper: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#F5F5F7',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: 14,
|
||||
paddingHorizontal: spacing.lg,
|
||||
height: 56,
|
||||
@@ -485,13 +478,13 @@ function createAccountSecurityStyles(colors: AppColors) {
|
||||
height: 56,
|
||||
minWidth: 110,
|
||||
borderRadius: 14,
|
||||
backgroundColor: THEME_COLORS.primary,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
paddingHorizontal: spacing.sm,
|
||||
},
|
||||
sendCodeButtonText: {
|
||||
color: '#fff',
|
||||
color: colors.text.inverse,
|
||||
fontSize: fontSizes.sm,
|
||||
fontWeight: '600',
|
||||
},
|
||||
@@ -499,14 +492,14 @@ function createAccountSecurityStyles(colors: AppColors) {
|
||||
primaryButton: {
|
||||
height: 56,
|
||||
borderRadius: 14,
|
||||
backgroundColor: THEME_COLORS.primary,
|
||||
backgroundColor: colors.primary.main,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
marginTop: spacing.xs,
|
||||
marginHorizontal: spacing['2xl'],
|
||||
},
|
||||
primaryButtonText: {
|
||||
color: '#fff',
|
||||
color: colors.text.inverse,
|
||||
fontSize: fontSizes.md,
|
||||
fontWeight: '600',
|
||||
},
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
StyleSheet,
|
||||
Switch,
|
||||
ScrollView,
|
||||
Alert,
|
||||
TouchableOpacity,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
@@ -22,6 +24,7 @@ import {
|
||||
setVibrationPreference,
|
||||
} from '../../services/notificationPreferences';
|
||||
import { useResponsive, useResponsiveSpacing } from '../../hooks';
|
||||
import { backgroundSyncManager, BackgroundSyncMode } from '../../services/BackgroundSyncManager';
|
||||
|
||||
// 内容最大宽度
|
||||
const CONTENT_MAX_WIDTH = 720;
|
||||
@@ -41,6 +44,7 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
const [vibrationEnabled, setVibrationEnabledState] = useState(true);
|
||||
const [pushEnabled, setPushEnabled] = useState(true);
|
||||
const [soundEnabled, setSoundEnabled] = useState(true);
|
||||
const [syncMode, setSyncMode] = useState<BackgroundSyncMode>(BackgroundSyncMode.BATTERY_SAVER);
|
||||
const { isWideScreen, isMobile } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
@@ -55,6 +59,7 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
setVibrationEnabledState(prefs.vibrationEnabled);
|
||||
setPushEnabled(prefs.pushEnabled);
|
||||
setSoundEnabled(prefs.soundEnabled);
|
||||
setSyncMode(backgroundSyncManager.getMode());
|
||||
} catch (error) {
|
||||
console.error('加载通知设置失败:', error);
|
||||
}
|
||||
@@ -89,6 +94,51 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSyncModeChange = async (mode: BackgroundSyncMode) => {
|
||||
if (mode === BackgroundSyncMode.REALTIME) {
|
||||
Alert.alert(
|
||||
'实时模式',
|
||||
'实时模式会在通知栏显示常驻通知以保持应用后台运行,确保消息即时同步。\n\n' +
|
||||
'建议在系统设置中将应用加入电池优化白名单以获得最佳效果。\n\n' +
|
||||
'注意:此模式可能增加电池消耗。',
|
||||
[
|
||||
{ text: '取消', style: 'cancel' },
|
||||
{
|
||||
text: '开启',
|
||||
onPress: async () => {
|
||||
await backgroundSyncManager.setMode(mode);
|
||||
setSyncMode(mode);
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
} else {
|
||||
await backgroundSyncManager.setMode(mode);
|
||||
setSyncMode(mode);
|
||||
}
|
||||
};
|
||||
|
||||
const syncModeOptions: { mode: BackgroundSyncMode; title: string; subtitle: string; icon: string }[] = [
|
||||
{
|
||||
mode: BackgroundSyncMode.BATTERY_SAVER,
|
||||
title: '省电模式',
|
||||
subtitle: '系统后台任务,每 15 分钟检查一次',
|
||||
icon: 'leaf',
|
||||
},
|
||||
{
|
||||
mode: BackgroundSyncMode.REALTIME,
|
||||
title: '实时模式',
|
||||
subtitle: '通知栏常驻保活,即时同步消息',
|
||||
icon: 'lightning-bolt',
|
||||
},
|
||||
{
|
||||
mode: BackgroundSyncMode.DISABLED,
|
||||
title: '禁用',
|
||||
subtitle: '仅在应用打开时接收消息',
|
||||
icon: 'close-circle-outline',
|
||||
},
|
||||
];
|
||||
|
||||
const settings: NotificationSettingItem[] = [
|
||||
{
|
||||
key: 'push',
|
||||
@@ -164,6 +214,62 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
关闭推送通知后,您将不再收到任何消息提醒,但消息仍会在应用内显示。
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* 后台同步模式 */}
|
||||
<View style={styles.section}>
|
||||
<View style={styles.sectionHeader}>
|
||||
<Text variant="caption" style={styles.sectionTitle}>
|
||||
后台同步模式
|
||||
</Text>
|
||||
</View>
|
||||
{syncModeOptions.map((option) => (
|
||||
<TouchableOpacity
|
||||
key={option.mode}
|
||||
style={[
|
||||
styles.settingItem,
|
||||
syncMode === option.mode && styles.settingItemActive,
|
||||
]}
|
||||
onPress={() => handleSyncModeChange(option.mode)}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<View style={styles.iconContainer}>
|
||||
<MaterialCommunityIcons
|
||||
name={option.icon as any}
|
||||
size={22}
|
||||
color={syncMode === option.mode ? colors.primary.main : colors.text.secondary}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.settingContent}>
|
||||
<Text
|
||||
variant="body"
|
||||
color={syncMode === option.mode ? colors.primary.main : colors.text.primary}
|
||||
>
|
||||
{option.title}
|
||||
</Text>
|
||||
<Text variant="caption" color={colors.text.secondary} style={styles.subtitle}>
|
||||
{option.subtitle}
|
||||
</Text>
|
||||
</View>
|
||||
{syncMode === option.mode && (
|
||||
<MaterialCommunityIcons
|
||||
name="check"
|
||||
size={20}
|
||||
color={colors.primary.main}
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 实时模式说明 */}
|
||||
{syncMode === BackgroundSyncMode.REALTIME && (
|
||||
<View style={styles.tipContainer}>
|
||||
<MaterialCommunityIcons name="shield-check-outline" size={16} color={colors.text.hint} />
|
||||
<Text variant="caption" color={colors.text.hint} style={styles.tipText}>
|
||||
实时模式已开启,应用将在通知栏显示常驻通知以保持后台运行。如需更稳定的后台运行,请在系统设置中将本应用加入电池优化白名单。
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -210,6 +316,9 @@ function createNotificationSettingsStyles(colors: AppColors) {
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
borderBottomColor: colors.divider,
|
||||
},
|
||||
settingItemActive: {
|
||||
backgroundColor: colors.primary.main + '0D',
|
||||
},
|
||||
iconContainer: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
|
||||
@@ -18,13 +18,6 @@ import type { PrivacySettingsDTO, VisibilityLevel } from '../../types/dto';
|
||||
|
||||
const CONTENT_MAX_WIDTH = 720;
|
||||
|
||||
// 胡萝卜橙主题色
|
||||
const THEME_COLORS = {
|
||||
primary: '#FF6B35',
|
||||
primaryLight: '#FF8C5A',
|
||||
primaryDark: '#E55A2B',
|
||||
};
|
||||
|
||||
const VISIBILITY_OPTIONS: { value: VisibilityLevel; label: string; description: string }[] = [
|
||||
{ value: 'everyone', label: '所有人可见', description: '任何人都可查看' },
|
||||
{ value: 'following', label: '仅关注的人可见', description: '只有你关注的人可查看' },
|
||||
@@ -74,7 +67,7 @@ function createPrivacySettingsStyles(colors: AppColors) {
|
||||
},
|
||||
// 隐私设置项 - 扁平化卡片风格
|
||||
item: {
|
||||
backgroundColor: '#F5F5F7',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: 14,
|
||||
padding: spacing.lg,
|
||||
marginHorizontal: spacing['2xl'],
|
||||
@@ -111,15 +104,15 @@ function createPrivacySettingsStyles(colors: AppColors) {
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
optionButtonActive: {
|
||||
backgroundColor: THEME_COLORS.primary,
|
||||
borderColor: THEME_COLORS.primary,
|
||||
backgroundColor: colors.primary.main,
|
||||
borderColor: colors.primary.main,
|
||||
},
|
||||
optionText: {
|
||||
fontSize: 13,
|
||||
color: colors.text.primary,
|
||||
},
|
||||
optionTextActive: {
|
||||
color: '#fff',
|
||||
color: colors.text.inverse,
|
||||
fontWeight: '500',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -26,12 +26,6 @@ import {
|
||||
import { showPrompt } from '../../services/promptService';
|
||||
import * as hrefs from '../../navigation/hrefs';
|
||||
|
||||
const THEME_COLORS = {
|
||||
primary: '#FF6B35',
|
||||
primaryLight: '#FF8C5A',
|
||||
primaryDark: '#E55A2B',
|
||||
};
|
||||
|
||||
const STATUS_CONFIG = {
|
||||
not_submitted: {
|
||||
title: '未认证',
|
||||
@@ -99,7 +93,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={THEME_COLORS.primary} />
|
||||
<ActivityIndicator size="large" color={colors.primary.main} />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
@@ -110,10 +104,11 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
const identityText = IDENTITY_TEXT[status?.identity || 'general'];
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<SafeAreaView style={styles.container}>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
{/* 状态卡片 */}
|
||||
<View style={styles.statusCard}>
|
||||
<View style={[styles.statusIconContainer, { backgroundColor: statusConfig.color + '20' }]}>
|
||||
@@ -128,7 +123,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
|
||||
{status?.verification_status === 'approved' && (
|
||||
<View style={styles.identityBadge}>
|
||||
<MaterialCommunityIcons name="check-circle" size={16} color={THEME_COLORS.primary} />
|
||||
<MaterialCommunityIcons name="check-circle" size={16} color={colors.primary.main} />
|
||||
<Text style={styles.identityText}>{identityText}</Text>
|
||||
</View>
|
||||
)}
|
||||
@@ -153,7 +148,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
<MaterialCommunityIcons
|
||||
name="check-decagram"
|
||||
size={24}
|
||||
color={THEME_COLORS.primary}
|
||||
color={colors.primary.main}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.benefitContent}>
|
||||
@@ -169,7 +164,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
<MaterialCommunityIcons
|
||||
name="lock-open-outline"
|
||||
size={24}
|
||||
color={THEME_COLORS.primary}
|
||||
color={colors.primary.main}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.benefitContent}>
|
||||
@@ -185,7 +180,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
<MaterialCommunityIcons
|
||||
name="account-group-outline"
|
||||
size={24}
|
||||
color={THEME_COLORS.primary}
|
||||
color={colors.primary.main}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.benefitContent}>
|
||||
@@ -208,7 +203,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
onPress={handleStartVerification}
|
||||
activeOpacity={0.9}
|
||||
>
|
||||
<MaterialCommunityIcons name="shield-check-outline" size={20} color="#FFF" />
|
||||
<MaterialCommunityIcons name="shield-check-outline" size={20} color={colors.primary.contrast} />
|
||||
<Text style={styles.primaryButtonText}>
|
||||
{status?.verification_status === 'rejected' ? '重新认证' : '开始认证'}
|
||||
</Text>
|
||||
@@ -221,7 +216,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
onPress={handleViewRecords}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<MaterialCommunityIcons name="file-document-outline" size={20} color={THEME_COLORS.primary} />
|
||||
<MaterialCommunityIcons name="file-document-outline" size={20} color={colors.primary.main} />
|
||||
<Text style={styles.secondaryButtonText}>查看认证记录</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
@@ -262,6 +257,7 @@ export const VerificationSettingsScreen: React.FC = () => {
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -269,7 +265,7 @@ function createStyles(colors: AppColors) {
|
||||
return StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#fff',
|
||||
backgroundColor: colors.background.paper,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
@@ -307,7 +303,7 @@ function createStyles(colors: AppColors) {
|
||||
alignItems: 'center',
|
||||
paddingVertical: 32,
|
||||
paddingHorizontal: 24,
|
||||
backgroundColor: '#F9F9F9',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: 16,
|
||||
marginBottom: 24,
|
||||
},
|
||||
@@ -334,7 +330,7 @@ function createStyles(colors: AppColors) {
|
||||
identityBadge: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#FFF5F0',
|
||||
backgroundColor: colors.primary.main + '15',
|
||||
borderRadius: 20,
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
@@ -343,25 +339,25 @@ function createStyles(colors: AppColors) {
|
||||
identityText: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: THEME_COLORS.primary,
|
||||
color: colors.primary.main,
|
||||
marginLeft: 6,
|
||||
},
|
||||
rejectReasonContainer: {
|
||||
marginTop: 16,
|
||||
padding: 12,
|
||||
backgroundColor: '#FFF3F3',
|
||||
backgroundColor: colors.error.light + '20',
|
||||
borderRadius: 8,
|
||||
width: '100%',
|
||||
},
|
||||
rejectReasonLabel: {
|
||||
fontSize: 13,
|
||||
fontWeight: '600',
|
||||
color: '#F44336',
|
||||
color: colors.error.main,
|
||||
marginBottom: 4,
|
||||
},
|
||||
rejectReasonText: {
|
||||
fontSize: 13,
|
||||
color: '#D32F2F',
|
||||
color: colors.error.dark,
|
||||
lineHeight: 18,
|
||||
},
|
||||
benefitsSection: {
|
||||
@@ -379,7 +375,7 @@ function createStyles(colors: AppColors) {
|
||||
benefitItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
backgroundColor: '#F9F9F9',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
},
|
||||
@@ -387,7 +383,7 @@ function createStyles(colors: AppColors) {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 12,
|
||||
backgroundColor: '#FFF5F0',
|
||||
backgroundColor: colors.primary.main + '15',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
@@ -415,12 +411,12 @@ function createStyles(colors: AppColors) {
|
||||
justifyContent: 'center',
|
||||
height: 56,
|
||||
borderRadius: 14,
|
||||
backgroundColor: THEME_COLORS.primary,
|
||||
backgroundColor: colors.primary.main,
|
||||
},
|
||||
primaryButtonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '600',
|
||||
color: '#FFF',
|
||||
color: colors.text.inverse,
|
||||
marginLeft: 8,
|
||||
},
|
||||
secondaryButton: {
|
||||
@@ -429,18 +425,18 @@ function createStyles(colors: AppColors) {
|
||||
justifyContent: 'center',
|
||||
height: 56,
|
||||
borderRadius: 14,
|
||||
backgroundColor: '#FFF5F0',
|
||||
backgroundColor: colors.primary.main + '15',
|
||||
borderWidth: 1,
|
||||
borderColor: THEME_COLORS.primary,
|
||||
borderColor: colors.primary.main,
|
||||
},
|
||||
secondaryButtonText: {
|
||||
fontSize: 17,
|
||||
fontWeight: '600',
|
||||
color: THEME_COLORS.primary,
|
||||
color: colors.primary.main,
|
||||
marginLeft: 8,
|
||||
},
|
||||
verifiedInfo: {
|
||||
backgroundColor: '#F9F9F9',
|
||||
backgroundColor: colors.background.default,
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user