add haptics to save, like, and pin actions on feed

zio/stable
Ansh Nanda 2023-05-22 18:46:36 -07:00
parent 64e303d911
commit dfcdd37087
4 changed files with 44 additions and 16 deletions

24
src/lib/haptics.ts 100644
View File

@ -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')
}
}
}

View File

@ -10,9 +10,6 @@ import {
FontAwesomeIcon, FontAwesomeIcon,
FontAwesomeIconStyle, FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import ReactNativeHapticFeedback, {
HapticFeedbackTypes,
} from 'react-native-haptic-feedback'
// DISABLED see #135 // DISABLED see #135
// import { // import {
// TriggerableAnimated, // TriggerableAnimated,
@ -24,8 +21,9 @@ import {HeartIcon, HeartIconSolid, CommentBottomArrow} from 'lib/icons'
import {s, colors} from 'lib/styles' import {s, colors} from 'lib/styles'
import {useTheme} from 'lib/ThemeContext' import {useTheme} from 'lib/ThemeContext'
import {useStores} from 'state/index' import {useStores} from 'state/index'
import {isIOS, isNative} from 'platform/detection' import {isNative} from 'platform/detection'
import {RepostButton} from './RepostButton' import {RepostButton} from './RepostButton'
import {Haptics} from 'lib/haptics'
interface PostCtrlsOpts { interface PostCtrlsOpts {
itemUri: string itemUri: string
@ -58,7 +56,6 @@ interface PostCtrlsOpts {
} }
const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5} 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 // DISABLED see #135
/* /*
@ -112,7 +109,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
store.shell.closeModal() store.shell.closeModal()
if (!opts.isReposted) { if (!opts.isReposted) {
if (isNative) { if (isNative) {
ReactNativeHapticFeedback.trigger(hapticImpact) Haptics.default()
} }
opts.onPressToggleRepost().catch(_e => undefined) opts.onPressToggleRepost().catch(_e => undefined)
// DISABLED see #135 // DISABLED see #135
@ -141,7 +138,7 @@ export function PostCtrls(opts: PostCtrlsOpts) {
}) })
if (isNative) { if (isNative) {
ReactNativeHapticFeedback.trigger(hapticImpact) Haptics.default()
} }
}, [ }, [
opts.author, opts.author,
@ -154,7 +151,9 @@ export function PostCtrls(opts: PostCtrlsOpts) {
const onPressToggleLikeWrapper = async () => { const onPressToggleLikeWrapper = async () => {
if (!opts.isLiked) { if (!opts.isLiked) {
ReactNativeHapticFeedback.trigger(hapticImpact) if (isNative) {
Haptics.default()
}
await opts.onPressToggleLike().catch(_e => undefined) await opts.onPressToggleLike().catch(_e => undefined)
// DISABLED see #135 // DISABLED see #135
// likeRef.current?.trigger( // likeRef.current?.trigger(

View File

@ -24,6 +24,9 @@ import {isDesktopWeb} from 'platform/detection'
import {useSetTitle} from 'lib/hooks/useSetTitle' import {useSetTitle} from 'lib/hooks/useSetTitle'
import {shareUrl} from 'lib/sharing' import {shareUrl} from 'lib/sharing'
import {toShareUrl} from 'lib/strings/url-helpers' 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<CommonNavigatorParams, 'CustomFeed'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'CustomFeed'>
export const CustomFeedScreen = withAuthRequired( export const CustomFeedScreen = withAuthRequired(
@ -49,6 +52,7 @@ export const CustomFeedScreen = withAuthRequired(
const onToggleSaved = React.useCallback(async () => { const onToggleSaved = React.useCallback(async () => {
try { try {
Haptics.default()
if (currentFeed?.isSaved) { if (currentFeed?.isSaved) {
await currentFeed?.unsave() await currentFeed?.unsave()
} else { } else {
@ -63,6 +67,7 @@ export const CustomFeedScreen = withAuthRequired(
}, [store, currentFeed]) }, [store, currentFeed])
const onToggleLiked = React.useCallback(async () => { const onToggleLiked = React.useCallback(async () => {
Haptics.default()
try { try {
if (currentFeed?.isLiked) { if (currentFeed?.isLiked) {
await currentFeed?.unlike() await currentFeed?.unlike()

View File

@ -28,6 +28,7 @@ import {CustomFeed} from 'view/com/feeds/CustomFeed'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {CustomFeedModel} from 'state/models/feeds/custom-feed' import {CustomFeedModel} from 'state/models/feeds/custom-feed'
import * as Toast from 'view/com/util/Toast' import * as Toast from 'view/com/util/Toast'
import {Haptics} from 'lib/haptics'
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'> type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
@ -128,14 +129,13 @@ const ListItem = observer(
const savedFeeds = useMemo(() => store.me.savedFeeds, [store]) const savedFeeds = useMemo(() => store.me.savedFeeds, [store])
const isPinned = savedFeeds.isPinned(item) const isPinned = savedFeeds.isPinned(item)
const onTogglePinned = useCallback( const onTogglePinned = useCallback(() => {
() => Haptics.default()
savedFeeds.togglePinnedFeed(item).catch(e => { savedFeeds.togglePinnedFeed(item).catch(e => {
Toast.show('There was an issue contacting the server') Toast.show('There was an issue contacting the server')
store.log.error('Failed to toggle pinned feed', {e}) store.log.error('Failed to toggle pinned feed', {e})
}), })
[savedFeeds, item, store], }, [savedFeeds, item, store])
)
const onPressUp = useCallback( const onPressUp = useCallback(
() => () =>
savedFeeds.movePinnedFeed(item, 'up').catch(e => { savedFeeds.movePinnedFeed(item, 'up').catch(e => {