diff --git a/src/lib/haptics.ts b/src/lib/haptics.ts new file mode 100644 index 00000000..23a32179 --- /dev/null +++ b/src/lib/haptics.ts @@ -0,0 +1,24 @@ +import { isIOS } from 'platform/detection' +import ReactNativeHapticFeedback, { + HapticFeedbackTypes, +} from 'react-native-haptic-feedback' + + +const hapticImpact: HapticFeedbackTypes = isIOS ? 'impactMedium' : 'impactLight' // Users said the medium impact was too strong on Android; see APP-537s + + +export class Haptics { + static default = () => ReactNativeHapticFeedback.trigger(hapticImpact) + static impact = (type: HapticFeedbackTypes = hapticImpact) => ReactNativeHapticFeedback.trigger(type) + static selection = () => ReactNativeHapticFeedback.trigger('selection') + static notification = (type: 'success' | 'warning' | 'error') => { + switch (type) { + case 'success': + return ReactNativeHapticFeedback.trigger('notificationSuccess') + case 'warning': + return ReactNativeHapticFeedback.trigger('notificationWarning') + case 'error': + return ReactNativeHapticFeedback.trigger('notificationError') + } + } +} \ No newline at end of file diff --git a/src/view/com/util/post-ctrls/PostCtrls.tsx b/src/view/com/util/post-ctrls/PostCtrls.tsx index 9980e9de..0d2f83ce 100644 --- a/src/view/com/util/post-ctrls/PostCtrls.tsx +++ b/src/view/com/util/post-ctrls/PostCtrls.tsx @@ -10,9 +10,6 @@ import { FontAwesomeIcon, FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import ReactNativeHapticFeedback, { - HapticFeedbackTypes, -} from 'react-native-haptic-feedback' // DISABLED see #135 // import { // TriggerableAnimated, @@ -24,8 +21,9 @@ import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons' import {s, colors} from 'lib/styles' import {useTheme} from 'lib/ThemeContext' import {useStores} from 'state/index' -import {isIOS, isNative} from 'platform/detection' +import {isNative} from 'platform/detection' import {RepostButton} from './RepostButton' +import {Haptics} from 'lib/haptics' interface PostCtrlsOpts { itemUri: string @@ -58,7 +56,6 @@ interface PostCtrlsOpts { } const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5} -const hapticImpact: HapticFeedbackTypes = isIOS ? 'impactMedium' : 'impactLight' // Users said the medium impact was too strong on Android; see APP-537 // DISABLED see #135 /* @@ -112,7 +109,7 @@ export function PostCtrls(opts: PostCtrlsOpts) { store.shell.closeModal() if (!opts.isReposted) { if (isNative) { - ReactNativeHapticFeedback.trigger(hapticImpact) + Haptics.default() } opts.onPressToggleRepost().catch(_e => undefined) // DISABLED see #135 @@ -141,7 +138,7 @@ export function PostCtrls(opts: PostCtrlsOpts) { }) if (isNative) { - ReactNativeHapticFeedback.trigger(hapticImpact) + Haptics.default() } }, [ opts.author, @@ -154,7 +151,9 @@ export function PostCtrls(opts: PostCtrlsOpts) { const onPressToggleLikeWrapper = async () => { if (!opts.isLiked) { - ReactNativeHapticFeedback.trigger(hapticImpact) + if (isNative) { + Haptics.default() + } await opts.onPressToggleLike().catch(_e => undefined) // DISABLED see #135 // likeRef.current?.trigger( diff --git a/src/view/screens/CustomFeed.tsx b/src/view/screens/CustomFeed.tsx index 7ff22f7f..35399554 100644 --- a/src/view/screens/CustomFeed.tsx +++ b/src/view/screens/CustomFeed.tsx @@ -24,6 +24,9 @@ import {isDesktopWeb} from 'platform/detection' import {useSetTitle} from 'lib/hooks/useSetTitle' import {shareUrl} from 'lib/sharing' import {toShareUrl} from 'lib/strings/url-helpers' +import { Haptics } from 'lib/haptics' + +const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5} type Props = NativeStackScreenProps export const CustomFeedScreen = withAuthRequired( @@ -49,6 +52,7 @@ export const CustomFeedScreen = withAuthRequired( const onToggleSaved = React.useCallback(async () => { try { + Haptics.default() if (currentFeed?.isSaved) { await currentFeed?.unsave() } else { @@ -63,6 +67,7 @@ export const CustomFeedScreen = withAuthRequired( }, [store, currentFeed]) const onToggleLiked = React.useCallback(async () => { + Haptics.default() try { if (currentFeed?.isLiked) { await currentFeed?.unlike() diff --git a/src/view/screens/SavedFeeds.tsx b/src/view/screens/SavedFeeds.tsx index 613e42fb..0213b36a 100644 --- a/src/view/screens/SavedFeeds.tsx +++ b/src/view/screens/SavedFeeds.tsx @@ -28,6 +28,7 @@ import {CustomFeed} from 'view/com/feeds/CustomFeed' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {CustomFeedModel} from 'state/models/feeds/custom-feed' import * as Toast from 'view/com/util/Toast' +import {Haptics} from 'lib/haptics' type Props = NativeStackScreenProps @@ -128,14 +129,13 @@ const ListItem = observer( const savedFeeds = useMemo(() => store.me.savedFeeds, [store]) const isPinned = savedFeeds.isPinned(item) - const onTogglePinned = useCallback( - () => - savedFeeds.togglePinnedFeed(item).catch(e => { - Toast.show('There was an issue contacting the server') - store.log.error('Failed to toggle pinned feed', {e}) - }), - [savedFeeds, item, store], - ) + const onTogglePinned = useCallback(() => { + Haptics.default() + savedFeeds.togglePinnedFeed(item).catch(e => { + Toast.show('There was an issue contacting the server') + store.log.error('Failed to toggle pinned feed', {e}) + }) + }, [savedFeeds, item, store]) const onPressUp = useCallback( () => savedFeeds.movePinnedFeed(item, 'up').catch(e => {