Page MenuHomePhabricator

D7643.id25799.diff
No OneTemporary

D7643.id25799.diff

diff --git a/native/avatars/avatar-hooks.js b/native/avatars/avatar-hooks.js
--- a/native/avatars/avatar-hooks.js
+++ b/native/avatars/avatar-hooks.js
@@ -7,30 +7,19 @@
import Alert from 'react-native/Libraries/Alert/Alert.js';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
-import {
- changeThreadSettings,
- changeThreadSettingsActionTypes,
-} from 'lib/actions/thread-actions.js';
import { uploadMultimedia } from 'lib/actions/upload-actions.js';
import {
extensionFromFilename,
filenameFromPathOrURI,
} from 'lib/media/file-utils.js';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { ImageAvatarDBContent } from 'lib/types/avatar-types.js';
-import type { SetState } from 'lib/types/hook-types.js';
-import type { LoadingStatus } from 'lib/types/loading-types.js';
import type {
NativeMediaSelection,
MediaLibrarySelection,
MediaMissionFailure,
UploadMultimediaResult,
} from 'lib/types/media-types.js';
-import type { UpdateThreadRequest } from 'lib/types/thread-types.js';
-import {
- useDispatchActionPromise,
- useServerCall,
-} from 'lib/utils/action-utils.js';
+import { useServerCall } from 'lib/utils/action-utils.js';
import CommIcon from '../components/comm-icon.react.js';
import SWMansionIcon from '../components/swmansion-icon.react.js';
@@ -124,7 +113,7 @@
}
function useUploadSelectedMedia(
- setProcessingOrUploadInProgress: SetState<boolean>,
+ setProcessingOrUploadInProgress: (inProgress: boolean) => void,
): (selection: ?NativeMediaSelection) => Promise<?ImageAvatarDBContent> {
const processSelectedMedia = useProcessSelectedMedia();
const uploadProcessedMedia = useUploadProcessedMedia();
@@ -191,76 +180,6 @@
);
}
-const threadAvatarLoadingStatusSelector = createLoadingStatusSelector(
- changeThreadSettingsActionTypes,
- `${changeThreadSettingsActionTypes.started}:avatar`,
-);
-function useSelectFromGalleryAndUpdateThreadAvatar(
- threadID: string,
-): [() => Promise<void>, boolean] {
- const dispatchActionPromise = useDispatchActionPromise();
- const changeThreadSettingsCall = useServerCall(changeThreadSettings);
-
- const [processingOrUploadInProgress, setProcessingOrUploadInProgress] =
- React.useState(false);
-
- const updateThreadAvatarLoadingStatus: LoadingStatus = useSelector(
- threadAvatarLoadingStatusSelector,
- );
-
- const inProgress = React.useMemo(
- () =>
- processingOrUploadInProgress ||
- updateThreadAvatarLoadingStatus === 'loading',
- [processingOrUploadInProgress, updateThreadAvatarLoadingStatus],
- );
-
- const uploadSelectedMedia = useUploadSelectedMedia(
- setProcessingOrUploadInProgress,
- );
-
- const selectFromGalleryAndUpdateThreadAvatar = React.useCallback(async () => {
- const selection: ?MediaLibrarySelection = await selectFromGallery();
-
- const imageAvatarUpdateRequest = await uploadSelectedMedia(selection);
-
- if (!imageAvatarUpdateRequest) {
- return;
- }
-
- const updateThreadRequest: UpdateThreadRequest = {
- threadID,
- changes: {
- avatar: imageAvatarUpdateRequest,
- },
- };
-
- dispatchActionPromise(
- changeThreadSettingsActionTypes,
- (async () => {
- setProcessingOrUploadInProgress(false);
- try {
- return await changeThreadSettingsCall(updateThreadRequest);
- } catch (e) {
- Alert.alert('Avatar update failed', 'Unable to update avatar.');
- throw e;
- }
- })(),
- { customKeyName: `${changeThreadSettingsActionTypes.started}:avatar` },
- );
- }, [
- changeThreadSettingsCall,
- dispatchActionPromise,
- threadID,
- uploadSelectedMedia,
- ]);
-
- return React.useMemo(
- () => [selectFromGalleryAndUpdateThreadAvatar, inProgress],
- [inProgress, selectFromGalleryAndUpdateThreadAvatar],
- );
-}
-
type ShowAvatarActionSheetOptions = {
+id: 'emoji' | 'image' | 'camera' | 'ens' | 'cancel' | 'remove',
+onPress?: () => mixed,
@@ -390,5 +309,4 @@
useUploadProcessedMedia,
useProcessSelectedMedia,
useShowAvatarActionSheet,
- useSelectFromGalleryAndUpdateThreadAvatar,
};
diff --git a/native/avatars/edit-thread-avatar-provider.react.js b/native/avatars/edit-thread-avatar-provider.react.js
--- a/native/avatars/edit-thread-avatar-provider.react.js
+++ b/native/avatars/edit-thread-avatar-provider.react.js
@@ -10,18 +10,21 @@
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { UpdateUserAvatarRemoveRequest } from 'lib/types/avatar-types.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { MediaLibrarySelection } from 'lib/types/media-types.js';
import type { UpdateThreadRequest } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
} from 'lib/utils/action-utils.js';
+import { selectFromGallery, useUploadSelectedMedia } from './avatar-hooks.js';
import { activeThreadSelector } from '../navigation/nav-selectors.js';
import { NavContext } from '../navigation/navigation-context.js';
import { useSelector } from '../redux/redux-utils.js';
export type EditThreadAvatarContextType = {
+threadAvatarSaveInProgress: boolean,
+ +selectFromGalleryAndUpdateThreadAvatar: () => Promise<void>,
+removeThreadAvatar: () => void,
};
@@ -47,12 +50,77 @@
),
);
+ const [
+ threadAvatarMediaUploadInProgress,
+ setThreadAvatarMediaUploadInProgress,
+ ] = React.useState<$ReadOnlySet<string>>(new Set<string>());
+
const threadAvatarSaveInProgress =
+ threadAvatarMediaUploadInProgress.has(activeThreadID) ||
updateThreadAvatarLoadingStatus === 'loading';
const dispatchActionPromise = useDispatchActionPromise();
const changeThreadSettingsCall = useServerCall(changeThreadSettings);
+ const updateThreadAvatarMediaUploadInProgress = React.useCallback(
+ (inProgress: boolean) =>
+ setThreadAvatarMediaUploadInProgress(prevState => {
+ const updatedSet = new Set(prevState);
+ if (inProgress) {
+ updatedSet.add(activeThreadID);
+ } else {
+ updatedSet.delete(activeThreadID);
+ }
+ return updatedSet;
+ }),
+ [activeThreadID],
+ );
+
+ const uploadThreadAvatarSelectedMedia = useUploadSelectedMedia(
+ updateThreadAvatarMediaUploadInProgress,
+ );
+
+ const selectFromGalleryAndUpdateThreadAvatar = React.useCallback(async () => {
+ const selection: ?MediaLibrarySelection = await selectFromGallery();
+ const imageAvatarUpdateRequest = await uploadThreadAvatarSelectedMedia(
+ selection,
+ );
+
+ if (!imageAvatarUpdateRequest) {
+ return;
+ }
+
+ const updateThreadRequest: UpdateThreadRequest = {
+ threadID: activeThreadID,
+ changes: {
+ avatar: imageAvatarUpdateRequest,
+ },
+ };
+
+ const action = changeThreadSettingsActionTypes.started;
+ dispatchActionPromise(
+ changeThreadSettingsActionTypes,
+ (async () => {
+ updateThreadAvatarMediaUploadInProgress(false);
+ try {
+ return await changeThreadSettingsCall(updateThreadRequest);
+ } catch (e) {
+ Alert.alert('Avatar update failed', 'Unable to update avatar.');
+ throw e;
+ }
+ })(),
+ {
+ customKeyName: `${action}:${activeThreadID}:avatar`,
+ },
+ );
+ }, [
+ activeThreadID,
+ changeThreadSettingsCall,
+ dispatchActionPromise,
+ updateThreadAvatarMediaUploadInProgress,
+ uploadThreadAvatarSelectedMedia,
+ ]);
+
const removeThreadAvatar = React.useCallback(() => {
const removeAvatarRequest: UpdateUserAvatarRemoveRequest = {
type: 'remove',
@@ -83,9 +151,14 @@
const context = React.useMemo(
() => ({
threadAvatarSaveInProgress,
+ selectFromGalleryAndUpdateThreadAvatar,
removeThreadAvatar,
}),
- [removeThreadAvatar, threadAvatarSaveInProgress],
+ [
+ removeThreadAvatar,
+ selectFromGalleryAndUpdateThreadAvatar,
+ threadAvatarSaveInProgress,
+ ],
);
return (
diff --git a/native/avatars/edit-thread-avatar.react.js b/native/avatars/edit-thread-avatar.react.js
--- a/native/avatars/edit-thread-avatar.react.js
+++ b/native/avatars/edit-thread-avatar.react.js
@@ -6,10 +6,7 @@
import type { RawThreadInfo, ThreadInfo } from 'lib/types/thread-types.js';
-import {
- useSelectFromGalleryAndUpdateThreadAvatar,
- useShowAvatarActionSheet,
-} from './avatar-hooks.js';
+import { useShowAvatarActionSheet } from './avatar-hooks.js';
import EditAvatarBadge from './edit-avatar-badge.react.js';
import { EditThreadAvatarContext } from './edit-thread-avatar-provider.react.js';
import ThreadAvatar from './thread-avatar.react.js';
@@ -26,14 +23,11 @@
const editThreadAvatarContext = React.useContext(EditThreadAvatarContext);
invariant(editThreadAvatarContext, 'editThreadAvatarContext should be set');
- const { threadAvatarSaveInProgress, removeThreadAvatar } =
- editThreadAvatarContext;
-
- const [selectFromGalleryAndUpdateThreadAvatar, isGalleryAvatarUpdateLoading] =
- useSelectFromGalleryAndUpdateThreadAvatar(threadInfo.id);
-
- const isAvatarUpdateInProgress =
- isGalleryAvatarUpdateLoading || threadAvatarSaveInProgress;
+ const {
+ threadAvatarSaveInProgress,
+ selectFromGalleryAndUpdateThreadAvatar,
+ removeThreadAvatar,
+ } = editThreadAvatarContext;
const actionSheetConfig = React.useMemo(() => {
const configOptions = [
@@ -56,7 +50,7 @@
const showAvatarActionSheet = useShowAvatarActionSheet(actionSheetConfig);
let spinner;
- if (isAvatarUpdateInProgress) {
+ if (threadAvatarSaveInProgress) {
spinner = (
<View style={styles.spinnerContainer}>
<ActivityIndicator color="white" size="large" />
diff --git a/native/avatars/edit-user-avatar-provider.react.js b/native/avatars/edit-user-avatar-provider.react.js
--- a/native/avatars/edit-user-avatar-provider.react.js
+++ b/native/avatars/edit-user-avatar-provider.react.js
@@ -57,8 +57,13 @@
userAvatarMediaUploadInProgress ||
updateUserAvatarLoadingStatus === 'loading';
+ const updateUserAvatarMediaUploadInProgress = React.useCallback(
+ (inProgress: boolean) => setUserAvatarMediaUploadInProgress(inProgress),
+ [],
+ );
+
const uploadUserAvatarSelectedMedia = useUploadSelectedMedia(
- setUserAvatarMediaUploadInProgress,
+ updateUserAvatarMediaUploadInProgress,
);
const updateImageUserAvatar = React.useCallback(

File Metadata

Mime Type
text/plain
Expires
Sun, Dec 29, 7:39 AM (8 h, 50 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2731210
Default Alt Text
D7643.id25799.diff (10 KB)

Event Timeline