Changeset View
Changeset View
Standalone View
Standalone View
native/avatars/edit-user-avatar-provider.react.js
Show All 30 Lines | |||||
const registrationModeOff = { registrationMode: 'off' }; | const registrationModeOff = { registrationMode: 'off' }; | ||||
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>, | ||||
+setUserAvatar: (avatarRequest: UpdateUserAvatarRequest) => Promise<void>, | +setUserAvatar: (avatarRequest: UpdateUserAvatarRequest) => Promise<void>, | ||||
+setRegistrationMode: (registrationMode: RegistrationMode) => void, | +setRegistrationMode: (registrationMode: RegistrationMode) => void, | ||||
+registrationModeEnabled: boolean, | +getRegistrationModeEnabled: () => boolean, | ||||
}; | }; | ||||
const EditUserAvatarContext: React.Context<?EditUserAvatarContextType> = | const EditUserAvatarContext: React.Context<?EditUserAvatarContextType> = | ||||
React.createContext<?EditUserAvatarContextType>(); | React.createContext<?EditUserAvatarContextType>(); | ||||
const updateUserAvatarLoadingStatusSelector = createLoadingStatusSelector( | const updateUserAvatarLoadingStatusSelector = createLoadingStatusSelector( | ||||
updateUserAvatarActionTypes, | updateUserAvatarActionTypes, | ||||
); | ); | ||||
const displayFailureAlert = () => | const displayFailureAlert = () => | ||||
Alert.alert( | Alert.alert( | ||||
'Couldn’t save avatar', | 'Couldn’t save avatar', | ||||
'Please try again later', | 'Please try again later', | ||||
[{ text: 'OK' }], | [{ text: 'OK' }], | ||||
{ cancelable: true }, | { cancelable: true }, | ||||
); | ); | ||||
type Props = { | type Props = { | ||||
+children: React.Node, | +children: React.Node, | ||||
}; | }; | ||||
function EditUserAvatarProvider(props: Props): React.Node { | function EditUserAvatarProvider(props: Props): React.Node { | ||||
const { children } = props; | const { children } = props; | ||||
const [registrationMode, setRegistrationMode] = | const registrationModeRef = | ||||
React.useState<RegistrationMode>(registrationModeOff); | React.useRef<RegistrationMode>(registrationModeOff); | ||||
const dispatchActionPromise = useDispatchActionPromise(); | const dispatchActionPromise = useDispatchActionPromise(); | ||||
const updateUserAvatarCall = useServerCall(updateUserAvatar); | const updateUserAvatarCall = useServerCall(updateUserAvatar); | ||||
const [userAvatarMediaUploadInProgress, setUserAvatarMediaUploadInProgress] = | const [userAvatarMediaUploadInProgress, setUserAvatarMediaUploadInProgress] = | ||||
React.useState(false); | React.useState(false); | ||||
const updateUserAvatarLoadingStatus: LoadingStatus = useSelector( | const updateUserAvatarLoadingStatus: LoadingStatus = useSelector( | ||||
updateUserAvatarLoadingStatusSelector, | updateUserAvatarLoadingStatusSelector, | ||||
); | ); | ||||
const userAvatarSaveInProgress = | const userAvatarSaveInProgress = | ||||
userAvatarMediaUploadInProgress || | userAvatarMediaUploadInProgress || | ||||
updateUserAvatarLoadingStatus === 'loading'; | updateUserAvatarLoadingStatus === 'loading'; | ||||
const uploadSelectedMedia = useUploadSelectedMedia( | const uploadSelectedMedia = useUploadSelectedMedia( | ||||
setUserAvatarMediaUploadInProgress, | setUserAvatarMediaUploadInProgress, | ||||
); | ); | ||||
const updateImageUserAvatar = React.useCallback( | const updateImageUserAvatar = React.useCallback( | ||||
async (selection: NativeMediaSelection) => { | async (selection: NativeMediaSelection) => { | ||||
if (registrationMode.registrationMode === 'on') { | if (registrationModeRef.current.registrationMode === 'on') { | ||||
registrationMode.successCallback({ | registrationModeRef.current.successCallback({ | ||||
needsUpload: true, | needsUpload: true, | ||||
mediaSelection: selection, | mediaSelection: selection, | ||||
}); | }); | ||||
return; | return; | ||||
} | } | ||||
const imageAvatarUpdateRequest = await uploadSelectedMedia(selection); | const imageAvatarUpdateRequest = await uploadSelectedMedia(selection); | ||||
if (!imageAvatarUpdateRequest) { | if (!imageAvatarUpdateRequest) { | ||||
return; | return; | ||||
} | } | ||||
const promise = (async () => { | const promise = (async () => { | ||||
setUserAvatarMediaUploadInProgress(false); | setUserAvatarMediaUploadInProgress(false); | ||||
try { | try { | ||||
return await updateUserAvatarCall(imageAvatarUpdateRequest); | return await updateUserAvatarCall(imageAvatarUpdateRequest); | ||||
} catch (e) { | } catch (e) { | ||||
displayFailureAlert(); | displayFailureAlert(); | ||||
throw e; | throw e; | ||||
} | } | ||||
})(); | })(); | ||||
dispatchActionPromise(updateUserAvatarActionTypes, promise); | dispatchActionPromise(updateUserAvatarActionTypes, promise); | ||||
await promise; | await promise; | ||||
}, | }, | ||||
[ | [uploadSelectedMedia, updateUserAvatarCall, dispatchActionPromise], | ||||
registrationMode, | |||||
uploadSelectedMedia, | |||||
updateUserAvatarCall, | |||||
dispatchActionPromise, | |||||
], | |||||
); | ); | ||||
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 setUserAvatar = React.useCallback( | const setUserAvatar = React.useCallback( | ||||
async (request: UpdateUserAvatarRequest) => { | async (request: UpdateUserAvatarRequest) => { | ||||
if (registrationMode.registrationMode === 'on') { | const regMode = registrationModeRef.current; | ||||
registrationMode.successCallback({ | if (regMode.registrationMode === 'on') { | ||||
regMode.successCallback({ | |||||
needsUpload: false, | needsUpload: false, | ||||
updateUserAvatarRequest: request, | updateUserAvatarRequest: request, | ||||
}); | }); | ||||
return; | return; | ||||
} | } | ||||
const promise = (async () => { | const promise = (async () => { | ||||
try { | try { | ||||
return await updateUserAvatarCall(request); | return await updateUserAvatarCall(request); | ||||
} catch (e) { | } catch (e) { | ||||
displayFailureAlert(); | displayFailureAlert(); | ||||
throw e; | throw e; | ||||
} | } | ||||
})(); | })(); | ||||
dispatchActionPromise(updateUserAvatarActionTypes, promise); | dispatchActionPromise(updateUserAvatarActionTypes, promise); | ||||
await promise; | await promise; | ||||
}, | }, | ||||
[registrationMode, updateUserAvatarCall, dispatchActionPromise], | [updateUserAvatarCall, dispatchActionPromise], | ||||
); | |||||
const setRegistrationMode = React.useCallback((mode: RegistrationMode) => { | |||||
registrationModeRef.current = mode; | |||||
}, []); | |||||
const getRegistrationModeEnabled = React.useCallback( | |||||
() => registrationModeRef.current.registrationMode === 'on', | |||||
[], | |||||
); | ); | ||||
const registrationModeEnabled = registrationMode.registrationMode === 'on'; | |||||
const context = React.useMemo( | const context = React.useMemo( | ||||
() => ({ | () => ({ | ||||
userAvatarSaveInProgress, | userAvatarSaveInProgress, | ||||
selectFromGalleryAndUpdateUserAvatar, | selectFromGalleryAndUpdateUserAvatar, | ||||
updateImageUserAvatar, | updateImageUserAvatar, | ||||
setUserAvatar, | setUserAvatar, | ||||
setRegistrationMode, | setRegistrationMode, | ||||
registrationModeEnabled, | getRegistrationModeEnabled, | ||||
}), | }), | ||||
[ | [ | ||||
userAvatarSaveInProgress, | userAvatarSaveInProgress, | ||||
selectFromGalleryAndUpdateUserAvatar, | selectFromGalleryAndUpdateUserAvatar, | ||||
updateImageUserAvatar, | updateImageUserAvatar, | ||||
setUserAvatar, | setUserAvatar, | ||||
setRegistrationMode, | setRegistrationMode, | ||||
registrationModeEnabled, | getRegistrationModeEnabled, | ||||
], | ], | ||||
); | ); | ||||
return ( | return ( | ||||
<EditUserAvatarContext.Provider value={context}> | <EditUserAvatarContext.Provider value={context}> | ||||
{children} | {children} | ||||
</EditUserAvatarContext.Provider> | </EditUserAvatarContext.Provider> | ||||
); | ); | ||||
} | } | ||||
export { EditUserAvatarContext, EditUserAvatarProvider }; | export { EditUserAvatarContext, EditUserAvatarProvider }; |