fix: moved all avatar logic from editProfileDialog to DisplayPictureModal

pull/2765/head
William Grant 2 years ago
parent 3a0b7d1c72
commit 49b4a28ef5

@ -3,13 +3,14 @@ import { SessionWrapperModal } from '../SessionWrapperModal';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SpacerLG } from '../basic/Text'; import { SpacerLG } from '../basic/Text';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { updateDisplayPictureModel } from '../../state/ducks/modalDialog'; import { editProfileModal, updateDisplayPictureModel } from '../../state/ducks/modalDialog';
import { ProfileAvatar, ProfileAvatarProps } from './EditProfileDialog'; import { ProfileAvatar } from './EditProfileDialog';
import styled from 'styled-components'; import styled from 'styled-components';
import { clearOurAvatar, uploadOurAvatar } from '../../interactions/conversationInteractions'; import { clearOurAvatar, uploadOurAvatar } from '../../interactions/conversationInteractions';
import { ToastUtils } from '../../session/utils'; import { ToastUtils } from '../../session/utils';
import { SessionSpinner } from '../basic/SessionSpinner'; import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionIconButton } from '../icon'; import { SessionIconButton } from '../icon';
import { pickFileForAvatar } from '../../types/attachments/VisualAttachment';
const StyledAvatarContainer = styled.div` const StyledAvatarContainer = styled.div`
cursor: pointer; cursor: pointer;
@ -59,8 +60,10 @@ const uploadProfileAvatar = async (scaledAvatarUrl: string | null) => {
} }
}; };
export type DisplayPictureModalProps = ProfileAvatarProps & { export type DisplayPictureModalProps = {
avatarAction: () => Promise<string | null>; oldAvatarPath: string | null;
profileName: string | undefined;
ourId: string;
}; };
export const DisplayPictureModal = (props: DisplayPictureModalProps) => { export const DisplayPictureModal = (props: DisplayPictureModalProps) => {
@ -70,41 +73,41 @@ export const DisplayPictureModal = (props: DisplayPictureModalProps) => {
return null; return null;
} }
const { const { oldAvatarPath, profileName, ourId } = props;
newAvatarObjectUrl: _newAvatarObjectUrl,
oldAvatarPath: _oldAvatarPath,
profileName,
ourId,
avatarAction,
} = props;
const [newAvatarObjectUrl, setNewAvatarObjectUrl] = useState<string | null>(_newAvatarObjectUrl); const [newAvatarObjectUrl, setNewAvatarObjectUrl] = useState<string | null>(oldAvatarPath);
const [oldAvatarPath, setOldAvatarPath] = useState<string | null>(_oldAvatarPath);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const closeDialog = () => { const closeDialog = () => {
dispatch(updateDisplayPictureModel(null)); dispatch(updateDisplayPictureModel(null));
dispatch(editProfileModal({}));
};
const handleAvatarClick = async () => {
const updatedAvatarObjectUrl = await pickFileForAvatar();
if (updatedAvatarObjectUrl) {
setNewAvatarObjectUrl(updatedAvatarObjectUrl);
}
}; };
const handleUpload = async () => { const handleUpload = async () => {
setLoading(true); setLoading(true);
if (newAvatarObjectUrl === _newAvatarObjectUrl) { if (newAvatarObjectUrl === oldAvatarPath) {
window.log.debug(`Avatar Object URL has not changed!`); window.log.debug(`Avatar Object URL has not changed!`);
return; return;
} }
await uploadProfileAvatar(newAvatarObjectUrl); await uploadProfileAvatar(newAvatarObjectUrl);
setLoading(false); setLoading(false);
closeDialog(); dispatch(updateDisplayPictureModel(null));
}; };
const handleRemove = async () => { const handleRemove = async () => {
setLoading(true); setLoading(true);
await clearOurAvatar(); await clearOurAvatar();
setNewAvatarObjectUrl(null); setNewAvatarObjectUrl(null);
setOldAvatarPath(null);
setLoading(false); setLoading(false);
closeDialog(); dispatch(updateDisplayPictureModel(null));
}; };
return ( return (
@ -114,15 +117,7 @@ export const DisplayPictureModal = (props: DisplayPictureModalProps) => {
showHeader={true} showHeader={true}
showExitIcon={true} showExitIcon={true}
> >
<div <div className="avatar-center" onClick={handleAvatarClick}>
className="avatar-center"
onClick={async () => {
const updatedAvatarObjectUrl = await avatarAction();
if (updatedAvatarObjectUrl) {
setNewAvatarObjectUrl(updatedAvatarObjectUrl);
}
}}
>
<StyledAvatarContainer className="avatar-center-inner"> <StyledAvatarContainer className="avatar-center-inner">
{newAvatarObjectUrl || oldAvatarPath ? ( {newAvatarObjectUrl || oldAvatarPath ? (
<ProfileAvatar <ProfileAvatar
@ -145,7 +140,7 @@ export const DisplayPictureModal = (props: DisplayPictureModalProps) => {
text={window.i18n('save')} text={window.i18n('save')}
buttonType={SessionButtonType.Simple} buttonType={SessionButtonType.Simple}
onClick={handleUpload} onClick={handleUpload}
disabled={loading || _newAvatarObjectUrl === newAvatarObjectUrl} disabled={loading || newAvatarObjectUrl === oldAvatarPath}
/> />
<SessionButton <SessionButton
text={window.i18n('remove')} text={window.i18n('remove')}

@ -5,11 +5,9 @@ import { Avatar, AvatarSize } from '../avatar/Avatar';
import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils'; import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils';
import { YourSessionIDPill, YourSessionIDSelectable } from '../basic/YourSessionIDPill'; import { YourSessionIDPill, YourSessionIDSelectable } from '../basic/YourSessionIDPill';
import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils';
import { getConversationController } from '../../session/conversations'; import { getConversationController } from '../../session/conversations';
import { editProfileModal, updateDisplayPictureModel } from '../../state/ducks/modalDialog'; import { editProfileModal, updateDisplayPictureModel } from '../../state/ducks/modalDialog';
import { pickFileForAvatar } from '../../types/attachments/VisualAttachment';
import { saveQRCode } from '../../util/saveQRCode'; import { saveQRCode } from '../../util/saveQRCode';
import { setLastProfileUpdateTimestamp } from '../../util/storage'; import { setLastProfileUpdateTimestamp } from '../../util/storage';
import { SessionWrapperModal } from '../SessionWrapperModal'; import { SessionWrapperModal } from '../SessionWrapperModal';
@ -20,6 +18,9 @@ import { sanitizeSessionUsername } from '../../session/utils/String';
import { useOurConversationUsername } from '../../hooks/useParamSelector'; import { useOurConversationUsername } from '../../hooks/useParamSelector';
import { useOurAvatarPath } from '../../hooks/useParamSelector'; import { useOurAvatarPath } from '../../hooks/useParamSelector';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import styled from 'styled-components';
import { ConversationTypeEnum } from '../../models/conversationAttributes';
import { MAX_USERNAME_BYTES } from '../../session/constants';
const handleSaveQRCode = (event: MouseEvent) => { const handleSaveQRCode = (event: MouseEvent) => {
event.preventDefault(); event.preventDefault();
@ -48,32 +49,12 @@ const QRView = ({ sessionID }: { sessionID: string }) => {
); );
}; };
const commitProfileEdits = async (newName: string, scaledAvatarUrl: string | null) => { const updateDisplayName = async (newName: string) => {
const ourNumber = UserUtils.getOurPubKeyStrFromCache(); const ourNumber = UserUtils.getOurPubKeyStrFromCache();
const conversation = await getConversationController().getOrCreateAndWait( const conversation = await getConversationController().getOrCreateAndWait(
ourNumber, ourNumber,
ConversationTypeEnum.PRIVATE ConversationTypeEnum.PRIVATE
); );
if (scaledAvatarUrl?.length) {
try {
const blobContent = await (await fetch(scaledAvatarUrl)).blob();
if (!blobContent || !blobContent.size) {
throw new Error('Failed to fetch blob content from scaled avatar');
}
await uploadOurAvatar(await blobContent.arrayBuffer());
} catch (error) {
if (error.message && error.message.length) {
ToastUtils.pushToastError('edit-profile', error.message);
}
window.log.error(
'showEditProfileDialog Error ensuring that image is properly sized:',
error && error.stack ? error.stack : error
);
}
return;
}
// do not update the avatar if it did not change
conversation.setSessionDisplayNameNoCommit(newName); conversation.setSessionDisplayNameNoCommit(newName);
// might be good to not trigger a sync if the name did not change // might be good to not trigger a sync if the name did not change
@ -82,8 +63,8 @@ const commitProfileEdits = async (newName: string, scaledAvatarUrl: string | nul
await SyncUtils.forceSyncConfigurationNowIfNeeded(true); await SyncUtils.forceSyncConfigurationNowIfNeeded(true);
}; };
export type ProfileAvatarProps = { type ProfileAvatarProps = {
newAvatarObjectUrl: string | null; newAvatarObjectUrl?: string | null;
oldAvatarPath: string | null; oldAvatarPath: string | null;
profileName: string | undefined; profileName: string | undefined;
ourId: string; ourId: string;
@ -107,17 +88,12 @@ type ProfileHeaderProps = ProfileAvatarProps & {
}; };
const ProfileHeader = (props: ProfileHeaderProps): ReactElement => { const ProfileHeader = (props: ProfileHeaderProps): ReactElement => {
const { newAvatarObjectUrl, oldAvatarPath, profileName, ourId, onClick, setMode } = props; const { oldAvatarPath, profileName, ourId, onClick, setMode } = props;
return ( return (
<div className="avatar-center"> <div className="avatar-center">
<div className="avatar-center-inner"> <div className="avatar-center-inner">
<ProfileAvatar <ProfileAvatar oldAvatarPath={oldAvatarPath} profileName={profileName} ourId={ourId} />
newAvatarObjectUrl={newAvatarObjectUrl}
oldAvatarPath={oldAvatarPath}
profileName={profileName}
ourId={ourId}
/>
<div <div
className="image-upload-section" className="image-upload-section"
role="button" role="button"
@ -147,7 +123,6 @@ export const EditProfileDialog = (): ReactElement => {
const [profileName, setProfileName] = useState(_profileName); const [profileName, setProfileName] = useState(_profileName);
const [updatedProfileName, setUpdateProfileName] = useState(profileName); const [updatedProfileName, setUpdateProfileName] = useState(profileName);
const oldAvatarPath = useOurAvatarPath() || ''; const oldAvatarPath = useOurAvatarPath() || '';
const [newAvatarObjectUrl, setNewAvatarObjectUrl] = useState<string | null>(null);
const [mode, setMode] = useState<ProfileDialogModes>('default'); const [mode, setMode] = useState<ProfileDialogModes>('default');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -190,7 +165,7 @@ export const EditProfileDialog = (): ReactElement => {
setUpdateProfileName(trimName); setUpdateProfileName(trimName);
setLoading(true); setLoading(true);
await commitProfileEdits(newName, newAvatarObjectUrl); await updateDisplayName(newName);
setMode('default'); setMode('default');
setUpdateProfileName(profileName); setUpdateProfileName(profileName);
setLoading(false); setLoading(false);
@ -214,25 +189,13 @@ export const EditProfileDialog = (): ReactElement => {
} }
}; };
const fireInputEvent = async () => {
const scaledAvatarUrl = await pickFileForAvatar();
if (scaledAvatarUrl) {
setNewAvatarObjectUrl(scaledAvatarUrl);
setMode('edit');
}
return scaledAvatarUrl;
};
const handleProfileHeaderClick = () => { const handleProfileHeaderClick = () => {
closeDialog(); closeDialog();
dispatch( dispatch(
updateDisplayPictureModel({ updateDisplayPictureModel({
newAvatarObjectUrl,
oldAvatarPath, oldAvatarPath,
profileName, profileName,
ourId, ourId,
avatarAction: fireInputEvent,
}) })
); );
}; };
@ -260,7 +223,6 @@ export const EditProfileDialog = (): ReactElement => {
{mode === 'default' && ( {mode === 'default' && (
<> <>
<ProfileHeader <ProfileHeader
newAvatarObjectUrl={newAvatarObjectUrl}
oldAvatarPath={oldAvatarPath} oldAvatarPath={oldAvatarPath}
profileName={profileName} profileName={profileName}
ourId={ourId} ourId={ourId}
@ -283,7 +245,6 @@ export const EditProfileDialog = (): ReactElement => {
{mode === 'edit' && ( {mode === 'edit' && (
<> <>
<ProfileHeader <ProfileHeader
newAvatarObjectUrl={newAvatarObjectUrl}
oldAvatarPath={oldAvatarPath} oldAvatarPath={oldAvatarPath}
profileName={profileName} profileName={profileName}
ourId={ourId} ourId={ourId}

Loading…
Cancel
Save