diff --git a/mobile/services/haptics/index.ts b/mobile/services/haptics/index.ts new file mode 100644 index 0000000..60094bb --- /dev/null +++ b/mobile/services/haptics/index.ts @@ -0,0 +1,44 @@ +import * as Haptics from 'expo-haptics'; +import { Platform } from 'react-native'; + +type ImpactLevel = 'light' | 'medium' | 'heavy'; + +function runImpact(level: ImpactLevel) { + if (Platform.OS === 'web') return; + try { + const styleMap = { + light: Haptics.ImpactFeedbackStyle.Light, + medium: Haptics.ImpactFeedbackStyle.Medium, + heavy: Haptics.ImpactFeedbackStyle.Heavy, + }; + Haptics.impactAsync(styleMap[level]); + } catch { + // Silently fail if haptics aren't supported (e.g., simulators). + } +} + +function runNotification(type: Haptics.NotificationFeedbackType) { + if (Platform.OS === 'web') return; + try { + Haptics.notificationAsync(type); + } catch { + // Silently fail if haptics aren't supported (e.g., simulators). + } +} + +export const triggerHapticFeedback = { + light: () => runImpact('light'), + medium: () => runImpact('medium'), + heavy: () => runImpact('heavy'), + selection: () => { + if (Platform.OS === 'web') return; + try { + Haptics.selectionAsync(); + } catch { + // Silently fail if haptics aren't supported (e.g., simulators). + } + }, + success: () => runNotification(Haptics.NotificationFeedbackType.Success), + warning: () => runNotification(Haptics.NotificationFeedbackType.Warning), + error: () => runNotification(Haptics.NotificationFeedbackType.Error), +}; diff --git a/mobile/utils/haptics.ts b/mobile/utils/haptics.ts index 6ab30f1..0032339 100644 --- a/mobile/utils/haptics.ts +++ b/mobile/utils/haptics.ts @@ -1,67 +1 @@ -import * as Haptics from 'expo-haptics'; -import { Platform } from 'react-native'; - -export const triggerHapticFeedback = { - light: () => { - if (Platform.OS === 'web') return; - try { - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - medium: () => { - if (Platform.OS === 'web') return; - try { - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Medium); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - heavy: () => { - if (Platform.OS === 'web') return; - try { - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Heavy); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - selection: () => { - if (Platform.OS === 'web') return; - try { - Haptics.selectionAsync(); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - success: () => { - if (Platform.OS === 'web') return; - try { - Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - error: () => { - if (Platform.OS === 'web') return; - try { - Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - }, - - warning: () => { - if (Platform.OS === 'web') return; - try { - Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning); - } catch (error) { - // Silently fail if haptics aren't available (e.g., simulator) - } - } -}; +export { triggerHapticFeedback } from '../services/haptics';