feat: starting work on new input

added into test region of right panel
pull/3056/head
William Grant 1 year ago
parent 59c8b6b95e
commit ccd127de44

@ -15,16 +15,15 @@ import { useIsRightPanelShowing } from '../../../../hooks/useUI';
import { import {
ConversationInteractionStatus, ConversationInteractionStatus,
ConversationInteractionType, ConversationInteractionType,
showAddModeratorsByConvoId,
showInviteContactByConvoId, showInviteContactByConvoId,
showLeaveGroupByConvoId, showLeaveGroupByConvoId,
showRemoveModeratorsByConvoId,
showUpdateGroupMembersByConvoId,
showUpdateGroupNameByConvoId,
} from '../../../../interactions/conversationInteractions'; } from '../../../../interactions/conversationInteractions';
import { Constants } from '../../../../session'; import { Constants } from '../../../../session';
import { MAX_USERNAME_BYTES } from '../../../../session/constants';
import { ToastUtils } from '../../../../session/utils';
import { sanitizeSessionUsername } from '../../../../session/utils/String';
import { closeRightPanel } from '../../../../state/ducks/conversations'; import { closeRightPanel } from '../../../../state/ducks/conversations';
import { resetRightOverlayMode, setRightOverlayMode } from '../../../../state/ducks/section'; import { resetRightOverlayMode } from '../../../../state/ducks/section';
import { import {
useSelectedConversationKey, useSelectedConversationKey,
useSelectedDisplayNameInProfile, useSelectedDisplayNameInProfile,
@ -43,10 +42,9 @@ import { getAbsoluteAttachmentPath } from '../../../../types/MessageAttachment';
import { Avatar, AvatarSize } from '../../../avatar/Avatar'; import { Avatar, AvatarSize } from '../../../avatar/Avatar';
import { Flex } from '../../../basic/Flex'; import { Flex } from '../../../basic/Flex';
import { SpacerLG, SpacerMD, SpacerXL } from '../../../basic/Text'; import { SpacerLG, SpacerMD, SpacerXL } from '../../../basic/Text';
import { PanelButtonGroup, PanelIconButton } from '../../../buttons'; import { SessionInput2 } from '../../../inputs';
import { MediaItemType } from '../../../lightbox/LightboxGallery'; import { MediaItemType } from '../../../lightbox/LightboxGallery';
import { SessionProgressBar } from '../../../loading'; import { SessionProgressBar } from '../../../loading';
import { MediaGallery } from '../../media-gallery/MediaGallery';
import { Header, StyledScrollContainer } from './components'; import { Header, StyledScrollContainer } from './components';
async function getMediaGalleryProps( async function getMediaGalleryProps(
@ -214,6 +212,33 @@ export const OverlayRightPanelSettings = () => {
// TODO[epic=ses-50] move this into already have an account screen // TODO[epic=ses-50] move this into already have an account screen
// #region for testing // #region for testing
const [progress, setProgress] = useState(0); const [progress, setProgress] = useState(0);
const [inputValue, setInputValue] = useState('');
const [inputError, setInputError] = useState<string | undefined>(undefined);
function sanitizeDisplayNameOrToast(
displayName: string,
setDisplayName: (sanitized: string) => void,
setDisplayNameError: (error: string | undefined) => void
) {
try {
const sanitizedName = sanitizeSessionUsername(displayName);
const trimName = sanitizedName.trim();
setDisplayName(sanitizedName);
setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined);
} catch (e) {
setDisplayName(displayName);
setDisplayNameError(window.i18n('displayNameTooLong'));
ToastUtils.pushToastError('toolong', window.i18n('displayNameTooLong'));
}
}
const handleInputChanged = (name: string) => {
sanitizeDisplayNameOrToast(name, setInputValue, setInputError);
};
const handleEnterPressed = () => {
ToastUtils.pushToastSuccess('success', window.i18n('done'));
};
useEffect(() => { useEffect(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
@ -308,7 +333,17 @@ export const OverlayRightPanelSettings = () => {
subtitle={window.i18n('loadAccountProgressMessage')} subtitle={window.i18n('loadAccountProgressMessage')}
showPercentage={true} showPercentage={true}
/> />
<HeaderItem /> <SpacerLG />
<SessionInput2
label={window.i18n('displayName')}
type="text"
placeholder={window.i18n('enterDisplayName')}
value={inputValue}
maxLength={MAX_USERNAME_BYTES}
onValueChanged={handleInputChanged}
onEnterPressed={handleEnterPressed}
/>
{/* <HeaderItem />
<PanelButtonGroup style={{ margin: '0 var(--margins-lg)' }}> <PanelButtonGroup style={{ margin: '0 var(--margins-lg)' }}>
{showUpdateGroupNameButton && ( {showUpdateGroupNameButton && (
<PanelIconButton <PanelIconButton
@ -377,7 +412,7 @@ export const OverlayRightPanelSettings = () => {
iconType={'delete'} iconType={'delete'}
/> />
)} )}
</PanelButtonGroup> </PanelButtonGroup> */}
<SpacerLG /> <SpacerLG />
<SpacerXL /> <SpacerXL />
</Flex> </Flex>

@ -0,0 +1,173 @@
import { ChangeEvent, useState } from 'react';
import classNames from 'classnames';
import styled from 'styled-components';
import { Noop } from '../../types/Util';
import { useHTMLDirection } from '../../util/i18n';
import { SessionIconButton } from '../icon';
type Props = {
label?: string;
error?: string;
type?: string;
value?: string;
placeholder: string;
maxLength?: number;
enableShowHide?: boolean;
onValueChanged?: (value: string) => any;
onEnterPressed?: any;
autoFocus?: boolean;
ref?: any;
inputDataTestId?: string;
};
const StyledInputWithLabelContainer = styled.label`
height: 46.5px;
width: 280px;
font-family: var(--font-default);
color: var(--text-primary-color);
padding: 2px 0 2px 0;
transition: opacity var(--default-duration);
opacity: 1;
position: relative;
label {
line-height: 14px;
opacity: 0;
color: var(--text-primary-color);
font-size: 10px;
line-height: 11px;
position: absolute;
top: 0px;
}
&.filled {
opacity: 1;
}
&.error {
color: var(--danger-color);
}
input {
border: none;
outline: 0;
height: 14px;
width: 280px;
background: transparent;
color: var(--input-text-color);
font-family: var(--font-default);
font-size: 12px;
line-height: 14px;
position: absolute;
top: 50%;
transform: translateY(-50%);
&::placeholder {
color: var(--input-text-placeholder-color);
}
}
`;
const LabelItem = (props: { inputValue: string; label?: string }) => {
return (
<StyledInputWithLabelContainer
htmlFor="session-input-floating-label"
className={classNames(props.inputValue !== '' ? 'filled' : '')}
>
{props.label}
</StyledInputWithLabelContainer>
);
};
const ErrorItem = (props: { error: string | undefined }) => {
return (
<StyledInputWithLabelContainer
htmlFor="session-input-floating-label"
className={classNames('filled error')}
>
{props.error}
</StyledInputWithLabelContainer>
);
};
const ShowHideButton = (props: { toggleForceShow: Noop }) => {
const htmlDirection = useHTMLDirection();
const position = htmlDirection === 'ltr' ? { right: '0px' } : { left: '0px' };
return (
<SessionIconButton
iconType="eye"
iconSize="medium"
onClick={props.toggleForceShow}
style={{ position: 'absolute', top: '50%', transform: 'translateY(-50%)', ...position }}
/>
);
};
export const SessionInput2 = (props: Props) => {
const {
autoFocus,
placeholder,
type,
value,
maxLength,
enableShowHide,
error,
label,
onValueChanged,
inputDataTestId,
} = props;
const [inputValue, setInputValue] = useState('');
const [forceShow, setForceShow] = useState(false);
const correctType = forceShow ? 'text' : type;
const updateInputValue = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault();
const val = e.target.value;
setInputValue(val);
if (onValueChanged) {
onValueChanged(val);
}
};
return (
<StyledInputWithLabelContainer>
{error ? (
<ErrorItem error={props.error} />
) : (
<LabelItem inputValue={inputValue} label={label} />
)}
<input
id="session-input-floating-label"
type={correctType}
placeholder={placeholder}
value={value}
maxLength={maxLength}
autoFocus={autoFocus}
data-testid={inputDataTestId}
onChange={updateInputValue}
style={{ paddingInlineEnd: enableShowHide ? '30px' : undefined }}
// just in case onChange isn't triggered
onBlur={updateInputValue}
onKeyDown={event => {
if (event.key === 'Enter' && props.onEnterPressed) {
props.onEnterPressed();
}
}}
/>
{enableShowHide && (
<ShowHideButton
toggleForceShow={() => {
setForceShow(!forceShow);
}}
/>
)}
</StyledInputWithLabelContainer>
);
};

@ -0,0 +1,3 @@
import { SessionInput2 } from './SessionInput2';
export { SessionInput2 };
Loading…
Cancel
Save