Changeset View
Changeset View
Standalone View
Standalone View
native/avatars/edit-user-avatar-provider.react.js
// @flow | // @flow | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Alert } from 'react-native'; | import { Alert } from 'react-native'; | ||||
import { | import { | ||||
updateUserAvatar, | updateUserAvatar, | ||||
updateUserAvatarActionTypes, | updateUserAvatarActionTypes, | ||||
} from 'lib/actions/user-actions.js'; | } from 'lib/actions/user-actions.js'; | ||||
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; | import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; | ||||
import type { | import type { UpdateUserAvatarRequest } from 'lib/types/avatar-types.js'; | ||||
ENSAvatarDBContent, | |||||
UpdateUserAvatarRemoveRequest, | |||||
} from 'lib/types/avatar-types.js'; | |||||
import type { LoadingStatus } from 'lib/types/loading-types.js'; | import type { LoadingStatus } from 'lib/types/loading-types.js'; | ||||
import type { NativeMediaSelection } from 'lib/types/media-types.js'; | import type { NativeMediaSelection } from 'lib/types/media-types.js'; | ||||
import { | import { | ||||
useDispatchActionPromise, | useDispatchActionPromise, | ||||
useServerCall, | useServerCall, | ||||
} from 'lib/utils/action-utils.js'; | } from 'lib/utils/action-utils.js'; | ||||
import { selectFromGallery, useUploadSelectedMedia } from './avatar-hooks.js'; | import { selectFromGallery, useUploadSelectedMedia } from './avatar-hooks.js'; | ||||
import { useSelector } from '../redux/redux-utils.js'; | import { useSelector } from '../redux/redux-utils.js'; | ||||
export type EditUserAvatarContextType = { | export type EditUserAvatarContextType = { | ||||
+userAvatarSaveInProgress: boolean, | +userAvatarSaveInProgress: boolean, | ||||
+selectFromGalleryAndUpdateUserAvatar: () => Promise<void>, | +selectFromGalleryAndUpdateUserAvatar: () => Promise<void>, | ||||
+updateImageUserAvatar: (selection: NativeMediaSelection) => Promise<void>, | +updateImageUserAvatar: (selection: NativeMediaSelection) => Promise<void>, | ||||
+setENSUserAvatar: () => void, | +setUserAvatar: (avatarRequest: UpdateUserAvatarRequest) => Promise<void>, | ||||
+removeUserAvatar: () => void, | |||||
}; | }; | ||||
const EditUserAvatarContext: React.Context<?EditUserAvatarContextType> = | const EditUserAvatarContext: React.Context<?EditUserAvatarContextType> = | ||||
React.createContext<?EditUserAvatarContextType>(); | React.createContext<?EditUserAvatarContextType>(); | ||||
const updateUserAvatarLoadingStatusSelector = createLoadingStatusSelector( | const updateUserAvatarLoadingStatusSelector = createLoadingStatusSelector( | ||||
updateUserAvatarActionTypes, | updateUserAvatarActionTypes, | ||||
); | ); | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | function EditUserAvatarProvider(props: Props): React.Node { | ||||
const selectFromGalleryAndUpdateUserAvatar = React.useCallback(async () => { | const selectFromGalleryAndUpdateUserAvatar = React.useCallback(async () => { | ||||
const selection = await selectFromGallery(); | const selection = await selectFromGallery(); | ||||
if (!selection) { | if (!selection) { | ||||
return; | return; | ||||
} | } | ||||
await updateImageUserAvatar(selection); | await updateImageUserAvatar(selection); | ||||
}, [updateImageUserAvatar]); | }, [updateImageUserAvatar]); | ||||
const setENSUserAvatar = React.useCallback(() => { | const setUserAvatar = React.useCallback( | ||||
const ensAvatarRequest: ENSAvatarDBContent = { | async (avatarRequest: UpdateUserAvatarRequest) => { | ||||
type: 'ens', | const promise = (async () => { | ||||
}; | |||||
dispatchActionPromise( | |||||
updateUserAvatarActionTypes, | |||||
(async () => { | |||||
try { | |||||
return await updateUserAvatarCall(ensAvatarRequest); | |||||
} catch (e) { | |||||
Alert.alert('Avatar update failed', 'Unable to update avatar.'); | |||||
throw e; | |||||
} | |||||
})(), | |||||
); | |||||
}, [dispatchActionPromise, updateUserAvatarCall]); | |||||
const removeUserAvatar = React.useCallback(() => { | |||||
const removeAvatarRequest: UpdateUserAvatarRemoveRequest = { | |||||
type: 'remove', | |||||
}; | |||||
dispatchActionPromise( | |||||
updateUserAvatarActionTypes, | |||||
(async () => { | |||||
try { | try { | ||||
return await updateUserAvatarCall(removeAvatarRequest); | return await updateUserAvatarCall(avatarRequest); | ||||
} catch (e) { | } catch (e) { | ||||
Alert.alert('Avatar update failed', 'Unable to update avatar.'); | Alert.alert('Avatar update failed', 'Unable to update avatar.'); | ||||
throw e; | throw e; | ||||
} | } | ||||
})(), | })(); | ||||
dispatchActionPromise(updateUserAvatarActionTypes, promise); | |||||
await promise; | |||||
}, | |||||
[dispatchActionPromise, updateUserAvatarCall], | |||||
); | ); | ||||
}, [dispatchActionPromise, updateUserAvatarCall]); | |||||
const context = React.useMemo( | const context = React.useMemo( | ||||
() => ({ | () => ({ | ||||
userAvatarSaveInProgress, | userAvatarSaveInProgress, | ||||
selectFromGalleryAndUpdateUserAvatar, | selectFromGalleryAndUpdateUserAvatar, | ||||
updateImageUserAvatar, | updateImageUserAvatar, | ||||
setENSUserAvatar, | setUserAvatar, | ||||
removeUserAvatar, | |||||
}), | }), | ||||
[ | [ | ||||
removeUserAvatar, | userAvatarSaveInProgress, | ||||
selectFromGalleryAndUpdateUserAvatar, | selectFromGalleryAndUpdateUserAvatar, | ||||
updateImageUserAvatar, | updateImageUserAvatar, | ||||
setENSUserAvatar, | setUserAvatar, | ||||
userAvatarSaveInProgress, | |||||
], | ], | ||||
); | ); | ||||
return ( | return ( | ||||
<EditUserAvatarContext.Provider value={context}> | <EditUserAvatarContext.Provider value={context}> | ||||
{children} | {children} | ||||
</EditUserAvatarContext.Provider> | </EditUserAvatarContext.Provider> | ||||
); | ); | ||||
} | } | ||||
export { EditUserAvatarContext, EditUserAvatarProvider }; | export { EditUserAvatarContext, EditUserAvatarProvider }; |