From ebeaec20809ab7f7bf6235713627de32f49ced48 Mon Sep 17 00:00:00 2001 From: William Grant Date: Mon, 22 May 2023 17:49:54 +1000 Subject: [PATCH] feat: initial work for set display picture modal done still need to do logic and handle multiple modals on screen --- _locales/en/messages.json | 4 +- ts/components/dialog/DisplayPictureModal.tsx | 50 ++++++++++++++++++++ ts/components/dialog/EditProfileDialog.tsx | 14 +++--- ts/components/dialog/ModalContainer.tsx | 4 ++ ts/state/ducks/modalDialog.tsx | 8 ++++ ts/state/selectors/modal.ts | 6 +++ ts/types/LocalizerKeys.ts | 32 ++++++++++++- 7 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 ts/components/dialog/DisplayPictureModal.tsx diff --git a/_locales/en/messages.json b/_locales/en/messages.json index e79bc63df..ec19331bd 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -507,5 +507,7 @@ "reactionPopupThree": "$name$, $name2$ & $name3$", "reactionPopupMany": "$name$, $name2$, $name3$ &", "reactionListCountSingular": "And $otherSingular$ has reacted $emoji$ to this message", - "reactionListCountPlural": "And $otherPlural$ have reacted $emoji$ to this message" + "reactionListCountPlural": "And $otherPlural$ have reacted $emoji$ to this message", + "setDisplayPicture": "Set Display Picture", + "upload": "Upload" } diff --git a/ts/components/dialog/DisplayPictureModal.tsx b/ts/components/dialog/DisplayPictureModal.tsx new file mode 100644 index 000000000..4da383a0a --- /dev/null +++ b/ts/components/dialog/DisplayPictureModal.tsx @@ -0,0 +1,50 @@ +import React, { ReactElement } from 'react'; +import { SessionWrapperModal } from '../SessionWrapperModal'; +import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; +import { Avatar, AvatarSize } from '../avatar/Avatar'; +import { SpacerLG } from '../basic/Text'; +import { UserUtils } from '../../session/utils'; +import { useDispatch } from 'react-redux'; +import { updateDisplayPictureModel } from '../../state/ducks/modalDialog'; + +type Props = {}; + +export const DisplayPictureModal = (props: Props): ReactElement => { + const {} = props; + const dispatch = useDispatch(); + + const onClickClose = () => { + dispatch(updateDisplayPictureModel(null)); + }; + + return ( + +
+
+ +
+
+ + + +
+ {}} + /> + {}} + /> +
+
+ ); +}; diff --git a/ts/components/dialog/EditProfileDialog.tsx b/ts/components/dialog/EditProfileDialog.tsx index 0f664633f..a076ca746 100644 --- a/ts/components/dialog/EditProfileDialog.tsx +++ b/ts/components/dialog/EditProfileDialog.tsx @@ -5,12 +5,10 @@ import { Avatar, AvatarSize } from '../avatar/Avatar'; import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils'; import { YourSessionIDPill, YourSessionIDSelectable } from '../basic/YourSessionIDPill'; -import styled from 'styled-components'; -import { uploadOurAvatar } from '../../interactions/conversationInteractions'; -import { ConversationTypeEnum } from '../../models/conversationAttributes'; -import { MAX_USERNAME_BYTES } from '../../session/constants'; +import { SyncUtils, ToastUtils, UserUtils } from '../../session/utils'; + import { getConversationController } from '../../session/conversations'; -import { editProfileModal } from '../../state/ducks/modalDialog'; +import { editProfileModal, updateDisplayPictureModel } from '../../state/ducks/modalDialog'; import { pickFileForAvatar } from '../../types/attachments/VisualAttachment'; import { saveQRCode } from '../../util/saveQRCode'; import { setLastProfileUpdateTimestamp } from '../../util/storage'; @@ -21,6 +19,7 @@ import { SessionIconButton } from '../icon'; import { sanitizeSessionUsername } from '../../session/utils/String'; import { useOurConversationUsername } from '../../hooks/useParamSelector'; import { useOurAvatarPath } from '../../hooks/useParamSelector'; +import { useDispatch } from 'react-redux'; const handleSaveQRCode = (event: MouseEvent) => { event.preventDefault(); @@ -110,6 +109,8 @@ type ProfileHeaderProps = ProfileAvatarProps & { const ProfileHeader = (props: ProfileHeaderProps): ReactElement => { const { newAvatarObjectUrl, oldAvatarPath, profileName, ourId, fireInputEvent, setMode } = props; + const dispatch = useDispatch(); + return (
@@ -123,7 +124,8 @@ const ProfileHeader = (props: ProfileHeaderProps): ReactElement => { className="image-upload-section" role="button" onClick={async () => { - void fireInputEvent(); + // void fireInputEvent(); + dispatch(updateDisplayPictureModel({})); }} data-testid="image-upload-section" /> diff --git a/ts/components/dialog/ModalContainer.tsx b/ts/components/dialog/ModalContainer.tsx index d54bbe7e8..131f81495 100644 --- a/ts/components/dialog/ModalContainer.tsx +++ b/ts/components/dialog/ModalContainer.tsx @@ -7,6 +7,7 @@ import { getChangeNickNameDialog, getConfirmModal, getDeleteAccountModalState, + getDisplayPictureModalState, getEditProfileDialog, getInviteContactModal, getOnionPathDialog, @@ -36,6 +37,7 @@ import { SessionNicknameDialog } from './SessionNicknameDialog'; import { BanOrUnBanUserDialog } from './BanOrUnbanUserDialog'; import { ReactListModal } from './ReactListModal'; import { ReactClearAllModal } from './ReactClearAllModal'; +import { DisplayPictureModal } from './DisplayPictureModal'; export const ModalContainer = () => { const confirmModalState = useSelector(getConfirmModal); @@ -55,6 +57,7 @@ export const ModalContainer = () => { const banOrUnbanUserModalState = useSelector(getBanOrUnbanUserModalState); const reactListModalState = useSelector(getReactListDialog); const reactClearAllModalState = useSelector(getReactClearAllDialog); + const DisplayPictureModalState = useSelector(getDisplayPictureModalState); return ( <> @@ -79,6 +82,7 @@ export const ModalContainer = () => { {confirmModalState && } {reactListModalState && } {reactClearAllModalState && } + {DisplayPictureModalState && } ); }; diff --git a/ts/state/ducks/modalDialog.tsx b/ts/state/ducks/modalDialog.tsx index ea8428b70..53ba355d6 100644 --- a/ts/state/ducks/modalDialog.tsx +++ b/ts/state/ducks/modalDialog.tsx @@ -34,6 +34,8 @@ export type ReactModalsState = { messageId: string; } | null; +export type DisplayPictureModalState = {} | null; + export type ModalState = { confirmModal: ConfirmModalState; inviteContactModal: InviteContactModalState; @@ -52,6 +54,7 @@ export type ModalState = { deleteAccountModal: DeleteAccountModalState; reactListModalState: ReactModalsState; reactClearAllModalState: ReactModalsState; + displayPictureModalState: DisplayPictureModalState; }; export const initialModalState: ModalState = { @@ -72,6 +75,7 @@ export const initialModalState: ModalState = { deleteAccountModal: null, reactListModalState: null, reactClearAllModalState: null, + displayPictureModalState: null, }; const ModalSlice = createSlice({ @@ -129,6 +133,9 @@ const ModalSlice = createSlice({ updateReactClearAllModal(state, action: PayloadAction) { return { ...state, reactClearAllModalState: action.payload }; }, + updateDisplayPictureModel(state, action: PayloadAction) { + return { ...state, displayPictureModalState: action.payload }; + }, }, }); @@ -151,5 +158,6 @@ export const { updateBanOrUnbanUserModal, updateReactListModal, updateReactClearAllModal, + updateDisplayPictureModel, } = actions; export const modalReducer = reducer; diff --git a/ts/state/selectors/modal.ts b/ts/state/selectors/modal.ts index f959bc243..efb38e1a5 100644 --- a/ts/state/selectors/modal.ts +++ b/ts/state/selectors/modal.ts @@ -8,6 +8,7 @@ import { ChangeNickNameModalState, ConfirmModalState, DeleteAccountModalState, + DisplayPictureModalState, EditProfileModalState, InviteContactModalState, ModalState, @@ -109,3 +110,8 @@ export const getReactClearAllDialog = createSelector( getModal, (state: ModalState): ReactModalsState => state.reactClearAllModalState ); + +export const getDisplayPictureModalState = createSelector( + getModal, + (state: ModalState): DisplayPictureModalState => state.displayPictureModalState +); diff --git a/ts/types/LocalizerKeys.ts b/ts/types/LocalizerKeys.ts index d7a9cb14b..e8d58a0c5 100644 --- a/ts/types/LocalizerKeys.ts +++ b/ts/types/LocalizerKeys.ts @@ -506,5 +506,33 @@ export type LocalizerKeys = | 'reactionPopupTwo' | 'reactionPopupThree' | 'reactionPopupMany' - | 'reactionListCountSingular' - | 'reactionListCountPlural'; + | 'timerSetTo' + | 'iAmSure' + | 'primaryColorRed' + | 'selectMessage' + | 'enterAnOpenGroupURL' + | 'delete' + | 'changePasswordInvalid' + | 'themesSettingTitle' + | 'timerOption_6_hours' + | 'confirmPassword' + | 'downloadAttachment' + | 'trimDatabaseDescription' + | 'showUserDetails' + | 'titleIsNow' + | 'removePasswordToastDescription' + | 'recoveryPhrase' + | 'deleteAccountFromLogin' + | 'newMessages' + | 'you' + | 'pruneSettingTitle' + | 'unbanUser' + | 'notificationForConvo_mentions_only' + | 'trustThisContactDialogDescription' + | 'unknownCountry' + | 'searchFor...' + | 'displayNameTooLong' + | 'joinedTheGroup' + | 'editGroupName' + | 'reportIssue' + | 'setDisplayPicture';