feat(notification): integrate expo-notifications for permission handling and deep linking
- 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
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
ScrollView,
|
||||
Alert,
|
||||
TouchableOpacity,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||
import { MaterialCommunityIcons } from '@expo/vector-icons';
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
setPushNotificationsPreference,
|
||||
setSoundPreference,
|
||||
setVibrationPreference,
|
||||
jpushService,
|
||||
} from '@/services/notification';
|
||||
import { useResponsive, useResponsiveSpacing } from '../../hooks';
|
||||
import { backgroundSyncManager, BackgroundSyncMode } from '@/services/background';
|
||||
@@ -45,6 +47,7 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
const [pushEnabled, setPushEnabled] = useState(true);
|
||||
const [soundEnabled, setSoundEnabled] = useState(true);
|
||||
const [syncMode, setSyncMode] = useState<BackgroundSyncMode>(BackgroundSyncMode.BATTERY_SAVER);
|
||||
const [systemPushEnabled, setSystemPushEnabled] = useState<boolean | null>(null);
|
||||
const { isWideScreen, isMobile } = useResponsive();
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
@@ -60,6 +63,11 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
setPushEnabled(prefs.pushEnabled);
|
||||
setSoundEnabled(prefs.soundEnabled);
|
||||
setSyncMode(backgroundSyncManager.getMode());
|
||||
|
||||
if (Platform.OS !== 'web') {
|
||||
const enabled = await jpushService.checkNotificationPermission();
|
||||
setSystemPushEnabled(enabled);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载通知设置失败:', error);
|
||||
}
|
||||
@@ -139,6 +147,21 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
},
|
||||
];
|
||||
|
||||
const handleRequestSystemPermission = async () => {
|
||||
if (Platform.OS === 'web') return;
|
||||
const granted = await jpushService.requestNotificationPermission();
|
||||
setSystemPushEnabled(granted);
|
||||
if (!granted) {
|
||||
Alert.alert(
|
||||
'通知权限未开启',
|
||||
'请在系统设置中手动开启通知权限,以便及时接收消息提醒。',
|
||||
[
|
||||
{ text: '知道了', style: 'cancel' },
|
||||
]
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const settings: NotificationSettingItem[] = [
|
||||
{
|
||||
key: 'push',
|
||||
@@ -207,6 +230,23 @@ export const NotificationSettingsScreen: React.FC = () => {
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* 系统通知权限状态(仅移动端) */}
|
||||
{Platform.OS !== 'web' && systemPushEnabled === false && (
|
||||
<TouchableOpacity
|
||||
style={[styles.tipContainer, { backgroundColor: colors.error.main + '14' }]}
|
||||
onPress={handleRequestSystemPermission}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<MaterialCommunityIcons name="alert-circle-outline" size={16} color={colors.error.main} />
|
||||
<View style={{ flex: 1 }}>
|
||||
<Text variant="caption" color={colors.error.main} style={styles.tipText}>
|
||||
系统通知权限未开启,点击前往开启
|
||||
</Text>
|
||||
</View>
|
||||
<MaterialCommunityIcons name="chevron-right" size={16} color={colors.error.main} />
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
|
||||
{/* 提示信息 */}
|
||||
<View style={styles.tipContainer}>
|
||||
<MaterialCommunityIcons name="information-outline" size={16} color={colors.text.hint} />
|
||||
|
||||
Reference in New Issue
Block a user